Natural language isn't a contract. It's ambiguous by nature. Same prompt, different code, every time. There's no determinism.
Cost is asymmetric. AI generates at zero cost with zero responsibility. You review at high cost with full responsibility.
These compound. Ambiguous input produces unpredictable output. Unpredictable output demands expensive review. And if no one designed the code, no one can defend the architecture, no one can maintain it, and no one owns it.
DisC (Design is Code) applies London-school TDD to AI code generation. You draw a sequence diagram. Each arrow becomes one verify() in a mockist test. The tests leave exactly one valid implementation. The AI doesn't interpret — it types what the tests require.
It ships as a Claude Code skill. Works best with Opus, should be fine with Sonnet.
Here's a real example. This diagram:
@startuml
InvoiceService -> OrderRepository: findAllByCustomerId(customerId)
InvoiceService <-- OrderRepository: orders: List<Order>
InvoiceService -> InvoiceBuilderFactory: create()
InvoiceService <-- InvoiceBuilderFactory: invoiceBuilder: InvoiceBuilder
loop for each order in orders
InvoiceService -> InvoiceBuilder: addLine(order)
end
InvoiceService -> InvoiceBuilder: build()
InvoiceService <-- InvoiceBuilder: invoice: Invoice
@enduml
Generates these tests: @Test void shouldFindAllOrdersByCustomerId() { verify(orderRepository).findAllByCustomerId(customerId); }
@Test void shouldCreateInvoiceBuilder() { verify(invoiceBuilderFactory).create(); }
@Test void shouldAddLineForOrder() { verify(invoiceBuilder).addLine(order); }
@Test void shouldBuildInvoice() { verify(invoiceBuilder).build(); }
@Test void shouldReturnInvoice() { assertThat(result).isEqualTo(invoice); }
AI implements the only thing that passes: public Invoice generateInvoice(UUID customerId) {
List<Order> orders = orderRepository.findAllByCustomerId(customerId);
InvoiceBuilder invoiceBuilder = invoiceBuilderFactory.create();
orders.forEach(invoiceBuilder::addLine);
return invoiceBuilder.build();
}
4 arrows + 1 loop → 5 tests → 1 possible implementation.Java + Spring only for now. Orchestration code only (not algorithms). PlantUML format. The mockist coupling tradeoff is real — but when AI writes the implementation, refactoring cost moves from code to the diagram.
Try it without installing anything — clone the demo repo and run in a Claude Code session:
git clone https://github.com/mossgreen/design-is-code-demo
cd design-is-code-demo
/disc 01_hello-world.puml
Blog: https://mossgreen.github.io/introducing-design-is-code/Plugin: https://github.com/mossgreen/design-is-code-plugin
Happy to hear what breaks, what's missing, and whether this is worth expanding to other languages.