Lesson 0010 · Core Designer · Module 2
Guiding AI Toward Better Structure
Lesson 0005 taught you to review AI output. This lesson teaches you to steer it before it writes: specify the seams, then let the AI fill them in.
Mission tie-in: "guide AI toward better structure instead of patching bad outputs" — the exact skill that separates developers who stay in control from developers whose codebase becomes the AI's drafting table.
Knowledge: you are the architect, AI is the drafter
A drafter draws what the architect specifies. Ask an AI to "build a checkout" and you will get a god function with SDK calls inside — because you specified a feature, not a structure. Ask it to implement a structure you already designed and the output inherits your design.
The recipe — specify the seams first:
- Name the boundary. Which parts are domain, which are infrastructure? State it in the prompt: "domain code must not import the SDK."
- Declare the ports. Give the interfaces:
PaymentGateway,OrderRepository. "Implement the adapter, not the port." - State the invariants. "An order can never be confirmed twice." AI will encode what you tell it to protect.
- Ask for the tests. "Write the tests first, with an in-memory fake adapter." The tests document the structure as much as they verify it.
# prompt shape (paraphrased):
# Implement checkout for the CheckoutService below. Do NOT modify this
# class or the PaymentGateway port. Domain code must not import Stripe.
# Write StripeAdapter in infrastructure/, plus tests using a FakeGateway.
class PaymentGateway(Protocol):
def charge(self, amount: Money, token: str) -> str: ...
class CheckoutService:
def __init__(self, gateway: PaymentGateway, orders: OrderRepository): ...
Now the AI's freedom is bounded by your structure. Bad output is still possible — AI loves a helper explosion — but the defects are now in the filling, not the frame.
† The review loop stays: even with a boundary spec, run the five-point checklist from lesson 0005 on the result. Steering reduces defects; it doesn't eliminate them.| Put this in the prompt | What it pins down | What you get without it |
|---|---|---|
| “domain/ must not import stripe” | Dependency direction (lesson 0009). | SDK calls inside the business rule. |
| “implement the adapter, not the port” | The interface stays yours. | A port quietly reshaped to match the SDK. |
| “an order cannot be confirmed twice” | The invariant lives in the object. | A status flag every caller must remember. |
| “tests first, with an in-memory fake” | The seam is proven by a test. | Tests that patch requests and freeze the defect. |
| “no parameters beyond this case” | Speculative generality is blocked. | A configurable framework for one use. |
Skill: prompt with the design first
The best prompt for generating a feature specifies:
"Domain code must not import the SDK" is an instruction about:
Asking AI to write tests with a fake adapter serves to:
Practice on your own code
Pick a small feature you'd normally hand to AI. Write the boundary spec first — ports, invariants, file layout — then generate. Compare the output with the five-point checklist from lesson 0005: how many defects did the spec prevent?
Reveal: a before/after comparison
Before: "Write a function to sync inventory from the supplier API." Result: one function doing HTTP, parsing, merging, and saving, with requests imported throughout.
After: "Implement InventorySyncService using the SupplierFeed port below; adapters in infrastructure/; tests with a canned feed." Result: domain service with two injectable ports, thin adapter, and tests that run offline. Same feature, opposite structure.
Your win
You can now treat AI as a drafter with a brief: structure specified up front, defects reviewed after. The combination is the Core Designer's AI workflow.
Read and watch deeper
- A Philosophy of Software Design, Ousterhout — ch. 16 "Modifying Existing Code": the same discipline — define the design, then make the change.
- Architecture Patterns with Python, Percival & Gregory — ch. 2–4: the seams (repository, service layer) this lesson's prompts encode.
- Study the official sdm example code — structure worth imitating in your prompts.
- Watch: ArjanCodes YouTube — search "AI code generation" for Arjan's guidance videos.
- Next: lesson 0011 starts Module 3, protecting the domain core.
- Reference: Patterns — Ports & Adapters and composition root: the two shapes worth naming in every prompt.
Draft a boundary spec with your agent-teacher for a feature you're about to generate — then compare the spec you'd have written alone.