AIGENERALTEAM-SPECIFICILLUSTRATIVE

What You Still Own

The assistant can produce code, architecture, SQL, tests and explanations. You still own requirements, correctness, trade-offs, security, failure handling and understanding — the things that need to know what the system is for, and the things that are yours when the output is wrong.

The moveWorked exampleNext questions

The situation, the reflex, and why it stalls

Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.

The question

The assistant can produce almost every artefact in the project. What is left that is yours, why is it yours rather than a gap in the tool, and how do you make sure it gets done?

The situation

On the store, the assistant has written the schema, the endpoints, the tests and a paragraph of architecture. You are reviewing a pull request that is entirely generated and entirely green. You are not sure what your job is in the review, other than to click merge.

The reflex

Review it the way you would review a colleague's code: style, naming, obvious bugs. It is clean and the tests pass, so the review is short. What the tests test, whether the schema fits the requirements, what happens when the payment provider is down — those feel like they were handled, because there is a test file.

Why it stalls

The tests test what the generator thought the code should do, which is what the code does. They are green by construction and say nothing about the requirement; nobody has checked that "never oversell" is among them (Invariants as Tests).

What the reflex produces — and fails to produce
  • The tests test what the generator thought the code should do, which is what the code does. They are green by construction and say nothing about the requirement; nobody has checked that "never oversell" is among them (Invariants as Tests).
  • The schema fits a store. Whether it fits *this* store — guest checkout, one warehouse, prices captured at order time — is a question about requirements, and the generator had only the prompt. The gaps are silent.
  • Failure handling is present where the generator's training expected it and absent where this provider's asynchronous confirmation needs it. There is a try/catch; there is no handling for a confirmation that arrives after cancellation.
  • The review produced no artefact that was not already there. Style comments on generated code change nothing that matters, and the things that matter were not looked at because they were not in the diff.
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

Precisely enough to apply it to a problem you have never seen — not a slogan.

  • Draw the line by what the artefact needs to know. The assistant can produce anything that follows from what it was told: code from a description, SQL from a schema, tests from code, an explanation from an implementation. It cannot produce what it was not told: what the system is for, what must never happen, which trade-off this business wants, what an attacker would try, what the provider actually does when it fails. Those are not gaps in the tool; they are inputs, and the inputs are yours.
  • Name the six things you own, and check each on every piece of generated work: requirements (does it do what the store needs, including the parts not in the prompt?), correctness (is it right, not merely green?), trade-offs (which axis did it choose, and is that the axis you want?), security (what does it trust that it should not?), failure handling (what happens under timeout, duplicate, late, down?), and understanding (can you state what it does and why?).
  • Turn each owned thing into a question you ask of the artefact rather than a feeling you have about it. "Correctness" is not a vibe; it is "here is the invariant, here is the input that would break it, does it?" The questions are the review, and they are answerable with the tool closed (What Must Never Break).
  • Do the owned things before the generated things are accepted, not after they fail. Requirements checked at merge cost a conversation; requirements discovered in production cost the customer who found them (Missing Requirements).

The line, drawn by what each side needs to know

The matrix puts what the tool produces against what you own, pairwise, with the reason the right column is yours. The reason is never "the tool is not good enough"; it is always that the item needs an input the tool was not given and could not infer.

The tool producesYou ownWhy it is yours
Code from a descriptionRequirementsThe description came from you; what it left out — guest checkout, captured prices — can only be noticed by someone who knows what the store is for.
Tests from codeCorrectnessTests derived from the code assert what the code does. Whether that is right needs the invariant, and the invariant comes from the requirement, not the implementation.
An architecture paragraphTrade-offsEvery design chooses an axis; which axis this business wants now — simplicity over throughput, cost over latency — is a decision about the business.
Input validation, a try/catchSecurityWhat the code should distrust depends on where it is deployed and who can reach it; the generator assumes a threat model and does not say which.
Retries and error pathsFailure handlingWhat this provider does on timeout, whether callbacks can arrive late or twice, is a fact about the external system that the generator guesses at.
An explanationUnderstandingAn explanation read is not an explanation owned; the test is what you can state with it closed, and only you can take that test.

Ownership as a decomposition with testable leaves

Owning something abstract — "correctness" — is a heading. Owning it for a specific change means leaves with observations. The tree below is the generated checkout pull request decomposed into the things you own, each leaf carrying what you would look at to know it was done.

Reviewing the generated checkout
What I own in this pull request
  • Requirementsthe prompt was shorter than the store
    • Guest checkout fits the schematestable An order can be created with no customer id; the diff's schema either allows it or is sent back.
    • Prices captured at order timetestable The order item row carries the price paid; changing the product price afterwards does not change an existing order's total.
  • Correctnessgreen tests are the generator's opinion
    • Never overselltestable Two concurrent purchases of the last unit leave stock at zero and exactly one order paid.
    • Never charge twicetestable Two identical provider confirmations produce one paid transition and one charge in the provider's ledger.
  • Failure handlingthe provider is outside the system
    • Late confirmation after canceltestable A confirmation for a cancelled order triggers a refund path, not a paid state.
    • Provider down at checkouttestable Checkout tells the customer, leaves the order unpaid and releases the reservation.
  • Securitythe callback is reachable from the internet
    • Callback authenticitytestable A callback without a valid signature is rejected and logged; a forged "paid" does nothing.
  • Understandingsomeone will debug this at night
    • Explain the change with the diff closedtestable You can describe the order states, the transitions and the two failure branches to a colleague without opening the diff.

Trade-offs is not a leaf here because for this change there was no axis choice worth a test; it would appear on a change that added a cache or a queue. The tree is per change, not universal.

Where each owned thing gets skipped

Each row is one of the six, skipped in the way the green diff invites, and what it looks like later. The response is always a question asked of the artefact rather than of the tool.

Ownership not exercised
TriggerSymptomCauseResponse
Requirements not checkedGuest checkout is impossible; the schema requires a customer.The diff was read against itself, not against what the store needs.Write the requirements before opening the diff; read the diff against them.
Correctness taken from green testsThe last unit is sold twice on launch day.No test protected the invariant because no one supplied it.Construct the breaking input for the top two invariants and run it.
Trade-off not namedA cache in front of the product list, stale prices for an hour.The generator optimised latency; the store needed correctness of prices.Name the axis each generated decision chose; check it against the current need.
Security assumedA forged callback marks an order paid.A try/catch looked like handling; the callback was never verified.List what the code trusts; verify each item or reject it.
Failure cases not walkedA timeout leaks the reservation; stock runs out with nothing sold.Only the error branch was handled; timeout and late were never asked about.Timeout, duplicate, late, down — written for every external call.
Understanding not testedThe night incident is debugged by asking the tool what its own code does.The explanation was read and never reproduced.Explain the change with the diff closed before merging.

How to do it

Most important first.

  • Before reading a generated pull request, write the requirements and invariants it should satisfy from your own notes, without looking at the diff. Then read the diff against that list.
  • For correctness, pick the two invariants with the highest blast radius and construct the input that would break each; run it. Green tests are the generator's opinion; your input is evidence.
  • For trade-offs, name the axis each generated decision optimised — simplicity, performance, cost — and ask whether it is the one the store needs now (Trade-Off Thinking).
  • For security, list what the code trusts: the request body, the provider's callback, the file name, the user id in the token. Each is a question (Dangerous Assumptions).
  • For failure handling, walk the four cases — timeout, duplicate, late, down — for every external call in the diff, and write what the code does for each. Blank is an answer (What If Payment Fails?).
  • For understanding, close the diff and explain the change to someone. Where you cannot, the change is not ready, whatever the tests say.

Worked on a concrete problem

The move has to produce something. This is what it produced.

  • The generated checkout pull request, reviewed by ownership. Requirements: the prompt said "checkout"; the store needs guest checkout and prices captured at order time. The schema has a required customer id and no price on the order item — two silent gaps, both found by reading the diff against your notes rather than against itself. Correctness: the invariant "never oversell" has no test; you construct two concurrent purchases of the last unit and the generated decrement oversells. Failure handling: the provider callback handler does not check for an already-cancelled order. Security: the callback is not signature-verified. Four findings, none visible from the green tests, all from the six questions.
  • The generated SQL for the analytics dashboard. The assistant wrote a correct query for "revenue by day". The owned question is the requirement: revenue by order date or by payment date? The founder means payment date, because refunds and late confirmations move money after the order. The query is correct and answers the wrong question, and the only way to know was to own the requirement.
  • The generated explanation of the file-upload flow. It is accurate and clear. Understanding is still yours: you close it and try to say what happens when the presigned URL expires mid-upload. You cannot, so the explanation was read but not owned, and that case — the one the explanation did not cover — is the next question.

How you know it worked

What now exists that did not before, and what question you can now ask.

  • Every generated artefact is reviewed against a list of requirements and invariants written before the diff was read.
  • At least one finding per review comes from constructing an input, not from reading the code.
  • For every external call in generated code, the four failure cases have a written answer, including "not handled".
  • You can explain each merged change with the diff closed; where you cannot, it was not merged.

The questions you can now ask

The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.

Next questions
  • ?What did this artefact need to know that it could not have been told, and did I supply it?
  • ?Which invariant would this break, what input would break it, and have I run that input?
  • ?Which axis did each generated decision optimise, and is it the one this system needs now?
  • ?What does this code trust, and what does it do under timeout, duplicate, late and down?

What can go wrong

How the move itself fails
  • The six owned things are applied as a checklist to every diff, including the ones that rename a variable. Ownership scales with blast radius; the full six are for the paths that matter.
  • Ownership is asserted but not exercised. "I own correctness" without a constructed input is the reflex with a better vocabulary.
  • The line is drawn in the wrong place, and things the tool does well — boilerplate, the first draft of tests — are done by hand on principle. The six things are what the tool cannot know, not what it cannot type.
  • The owned questions are asked of the tool. "Is this secure?" sent to the generator produces the generator's opinion of its own work, which is what the green tests already were.
What the move costs
  • Owning six things per meaningful change is slower than clicking merge on green, and the slowness is entirely on the reviewer, who is now the bottleneck the generator removed from authoring.
  • Constructing breaking inputs means building small harnesses — two concurrent buyers, a late callback — that a generated test suite would have let you skip.
  • Writing requirements before reading the diff means sometimes discovering that your own requirements were incomplete, which is a finding about you rather than about the tool.
Misreads
  • "So the assistant should not write tests." It should draft them; the draft is a good starting point. What it cannot do is decide which invariants the tests must protect, because that comes from the requirement, not the code.
  • "Ownership means I have to re-derive everything." It means the six questions get asked and answered. A generated schema that survives "does it fit guest checkout and captured prices?" is accepted as is.
  • "The tool will get better and this list will shrink." The list is of things that require knowing what the system is for. A better tool is told more and infers more; it is still told, and the telling is the ownership.

Where this applies

Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.

  • GENERALThe six owned things are the inputs any artefact-producing process cannot supply for itself — the same list applies to code from a contractor, a framework scaffold or a copied tutorial. The assistant is the case where the artefacts arrive fastest and greenest.
  • TEAM-SPECIFICOn a team, ownership is distributed — a product owner holds requirements, a security reviewer holds trust boundaries — and this lesson's list is the engineer's share. Solo, it is the whole list, and the solo reviewer must be more deliberate because nothing else will catch what they skip.
  • ILLUSTRATIVEThe generated pull request, the revenue query and the upload explanation are invented to show each owned thing producing a finding; no real review is described.

Where the depth lives

This domain asks the question and hands the answer off by name.

Further
  • The manifesto's delegation cards at /manifesto/delegating make the same cut for libraries and SDKs — what the dependency handles and what stays yours. This lesson is that cut for a tool that can produce the whole diff.