Deterministic AI code generation.
Human review architecture design. AI does the typing. DisC turns UML sequence diagrams into mockist tests that leave AI zero room to interpret.
See it in action
Watch how DisC turns a UML sequence diagram into tests and working code.
Where it broke
Every step had a contract. Natural language broke it. DisC restores it with tests.
Design is Code restores the contract.
How it works
Four steps. From verified truth to guaranteed implementation.
Establish truth
Before you design, verify your assumptions. If you don’t know how an API behaves — spike it. If you’re guessing about data formats — test them. Design based on facts, not assumptions.
Output: verified facts that justify the diagram you’re about to draw.
Draw the interaction
Each arrow is a decision you’re making about how components talk to each other.
design/greeting.puml
@startuml GreetingService -> GreetingFactory: create(userName) GreetingService <-- GreetingFactory: greeting: Greeting @enduml
preview
Each arrow becomes a verify()
The solid arrow became a verify(greetingFactory).create(userName) assertion. Deterministic.
public interface Greeting {}
public interface GreetingService { Greeting greet(String userName); }
public interface GreetingFactory { Greeting create(String userName); }
@MockitoSettings(strictness = Strictness.LENIENT)
class DefaultGreetingServiceTest {
@Mock private GreetingFactory greetingFactory;
@Mock private String userName;
@Mock private Greeting greeting;
private Greeting result;
DefaultGreetingService defaultGreetingService;
@BeforeEach
void setUp() {
defaultGreetingService = new DefaultGreetingService(greetingFactory);
}
@Nested
class WhenGreet {
@BeforeEach
void setUp() {
when(greetingFactory.create(any())).thenReturn(greeting);
result = defaultGreetingService.greet(userName);
}
@Test
void shouldCreateGreeting() {
verify(greetingFactory).create(userName);
}
@Test
void shouldReturnGreeting() {
assertThat(result).isEqualTo(greeting);
}
}
} AI writes code to pass the tests
No interpretation, no creative freedom. The test suite is the contract.
@Component
public class DefaultGreetingService implements GreetingService {
private final GreetingFactory greetingFactory;
public DefaultGreetingService(GreetingFactory greetingFactory) {
this.greetingFactory = greetingFactory;
}
@Override
public Greeting greet(String userName) {
return greetingFactory.create(userName);
}
}
1 solid arrow = 1 verify() test = 1
method call
Why Design is Code
AI coding tools promise speed. They create three structural problems that Design is Code solves.
No design, no ownership
When AI writes the code, you get the output without the journey. You can’t defend the architecture, adapt when requirements change, or spot when the reasoning was wrong.
DisC keeps the design artifact as the source of truth.
Prompt in, mystery out
Same prompt, different architecture every time. No guarantee of quality, no guarantee of consistency. If no one designed it, no one can maintain it.
One design, one possible implementation.
Cost asymmetry
AI generates at zero cost and pays nothing when it’s wrong. You review at high cost and pay for everything it missed. That’s not collaboration — that’s a broken feedback loop.
Tests generated from design — review is spot-checking, not archaeology.
Try it now — Claude Code + Java
DisC ships as a Claude Code plugin. Install it in seconds and start generating tests from your UML sequence diagrams.
Requires Claude Code and a Java 17+ project (JUnit 5 + Mockito).
Don’t use Java or Claude Code? The methodology works for any language and any AI coding tool. Draw the sequence diagram, generate mockist tests from it, then let AI implement against the tests. The plugin automates this for Java. The thinking applies everywhere.
Install Design-Is-Code plugin for Claude Code
- 1.
Install the plugin for Claude Code (plugin docs):
terminalclaude plugin marketplace add mossgreen/design-is-code-plugin claude plugin install design-is-code@mossgreen-design-is-code --scope user - 2.
Put your UML sequence diagram in your project's
design/folder - 3.
Start a Claude Code session, then run
/design-is-code:disc <sequence-diagram-filename>
DisC vs. alternatives
| Criteria | Vibe Coding | Spec-Driven | DisC |
|---|---|---|---|
| Input | Prompt | Natural language spec | UML diagram |
| AI interprets? | Yes | Yes (less) | No |
| Same output every time? | No | No | Yes |
| Tests generated from design? | No | Sometimes (AI-written) | Mechanically from diagram |
| Design artifact survives? | None | Markdown docs | Formal spec + tests |
| Upstream verification? | None | None | Human review architecture design |
Frequently asked questions
Why UML? Isn't that outdated? +
UML sequence diagrams aren't about ceremony — they're the most compact formal notation for expressing object interactions. Unlike class diagrams or activity diagrams, sequence diagrams map 1:1 to method calls and test assertions. We're not using UML for documentation; we're using it as a specification language that both humans and AI can execute deterministically.
Does this scale beyond simple CRUD? +
DisC is designed for interaction-heavy code: services calling other services, orchestration logic, workflows with branching and loops. The more complex the interaction structure, the more value you get from formal specification. Pure algorithmic code (sorting, math, parsing) is explicitly out of scope — use traditional TDD for that.
What about existing code? +
You can adopt DisC incrementally. Start with new features: draw the sequence diagram, generate tests, then implementation. Existing code doesn't need to be rewritten. As you add new interactions, the formally specified portion grows naturally.
Is this suitable for regulated environments? +
Yes. Every method call traces back to an arrow in the sequence diagram, and every arrow generates a test. The formal specification serves as living documentation — design decisions are captured in a reviewable artifact before any code is written. For teams in banking, insurance, healthcare, or any domain where traceability and auditability matter, this is design you can point to.
What about languages other than Java? +
The DisC methodology is language-agnostic, but the current Claude Code skill generates Java (JUnit + Mockito). Support for additional languages and test frameworks is on the roadmap. The UML diagrams themselves don't change — only the code generation templates.
How is this different from normal TDD? +
TDD has you write tests first, but the tests are still code — you're making implementation decisions while writing them. DisC separates design (UML) from implementation entirely. The tests are generated mechanically from the diagram, ensuring they test the specified interactions and nothing more. There's no temptation to test implementation details.
How is this different from Kiro or Spec Kit? +
Kiro and Spec Kit use natural language specifications — structured requirements, acceptance criteria, technical plans. This is better than vibe coding, but the spec is still English, and English is ambiguous. The same spec can produce different architectures on different runs. DisC uses formal notation (UML sequence diagrams) that maps 1:1 to test assertions. Tests are generated mechanically from the diagram, not written by hand or by AI. The result: one diagram, one set of tests, one possible implementation. Deterministic, not interpreted. Spec-driven development organized the input. DisC made the output deterministic.
What is Step 0? Why do I need it? +
Step 0 is the discipline of verifying your assumptions before you design. If you don't know how an external API behaves, you spike it. If you're guessing about data formats, you test them. You design based on verified facts, not guesses. DisC guarantees your code matches your design. Step 0 ensures your design matches reality. Without it, you can have a perfectly implemented wrong design. No other spec-driven tool addresses this. They all assume you already know what you want. DisC assumes you should prove it first.