Current chapter · Six-part field guide
Part 2 of 6 Building an AI-first development system
Functional requirements are the control plane
AI-assisted delivery stays aligned when functional behavior, constraints, exceptions, and acceptance evidence are treated as durable engineering inputs.
If a requirement exists only in a conversation, the automation does not have a control plane. It has a rumor.
A ticket is not a contract
A ticket title usually describes desire: add bulk approval, redesign the alert panel, make the workflow responsive, migrate the page. It rarely describes the complete behavior that must survive implementation. The missing details are where most product regressions live: permissions, partial data, stale state, retry behavior, navigation, timezones, accessibility, and what must happen when only half of an operation succeeds.
I treat functional requirements as the control plane for AI-assisted work. They describe actors, preconditions, visible states, allowed actions, exceptions, invariants, and acceptance evidence. They give the implementation loop something more durable than a prompt to optimize against.
This does not mean turning every task into a legal document. It means naming enough behavior that the system can distinguish a correct implementation from a plausible one. Without that distinction, AI can generate impressive output while the team quietly loses the product contract.
A sanitized failure at the edge of the happy path
Consider a sanitized bulk-action workflow. The visible request was simple: let a user select several records and approve them together. The generated implementation rendered the selection controls, called the API, and showed a success message. Focused tests covered the all-selected, all-successful path.
The actual workflow also allowed mixed permissions and partial failures. Some selected records could be approved, some were read-only, and the backend could accept part of the request while rejecting the rest. The first implementation cleared the entire selection and announced success whenever the request returned. It looked complete while hiding the records that still needed attention.
The artifact that prevents this class of failure is a functional requirement contract paired with a trace matrix. Each requirement has a stable identifier, actor, preconditions, expected behavior, exceptions, invariants, and required evidence. The trace then connects that requirement to implementation areas, tests, browser scenarios, and release proof. The artifact is deliberately boring. Its value is that missing behavior becomes visible before a user discovers it.
What I automate
I automate the conversion of scattered inputs into a reviewable requirement set. The system can extract behavior from product notes, designs, existing tests, support evidence, and repository rules. It can group duplicates, flag contradictions, identify undefined states, and turn accepted requirements into an implementation packet.
Once the requirements are stable enough to build against, automation can propose test cases, browser paths, and risk areas. It can track which requirements are touched by a change, which have supporting evidence, and which remain assumptions. A changed requirement can trigger targeted impact analysis instead of relying on someone to remember every consumer.
I also want the system to refuse false certainty. If two sources disagree about a permission rule or an empty state is undefined, that should become an explicit question. An assumption queue is more useful than a confident implementation of whichever document happened to be read last.
What remains a human decision
Humans decide which requirement is authoritative when sources conflict. They decide whether an old behavior is an invariant, accidental history, or something the product is intentionally replacing. They determine which exceptions matter enough to block release and which can be handled in a later iteration.
Product judgment is especially important when the requirement is socially or operationally sensitive. The correct behavior for a destructive action, a permissions boundary, an uncertain recommendation, or a partial failure cannot be derived from visual similarity. Someone has to understand the consequence for the user and the business.
Human acceptance should be based on evidence rather than memory. The reviewer should be able to see what changed, which requirements were exercised, what failed during verification, and what remains unproved. The decision stays human, but the information required to make it should not depend on manual reconstruction.
Precision without pretending the future is fixed
The trade-off is that precise requirements take effort, and precision can create its own illusion of certainty. Products change. Feedback reveals missing states. APIs evolve. A requirement system becomes harmful if it treats every sentence as permanent law or makes necessary change feel like a documentation violation.
I separate invariants from current decisions and current decisions from hypotheses. An invariant might say that unauthorized users can never perform an action. A current decision might describe where the action appears. A hypothesis might predict that grouping several actions will reduce effort. Those statements should not have the same authority or lifecycle.
Preserving functional requirements does not mean freezing the product. It means changing the product explicitly. When a requirement moves, the system should show what it affects, which evidence must be refreshed, and which invariants remain intact. That is how automation adapts without turning adaptation into drift.
Continue the system
Building an AI-first development system
Part 2 of 6