DEV Community

Cover image for Make AI Generated Code Traceable with Requirement IDs
Israel Vásquez for Monogram

Posted on with Isaac Harper Originally published at monogram.io

Make AI Generated Code Traceable with Requirement IDs

A numbered requirement can connect a product decision to the task, test, and code that implement it. In our spec driven workflow, IDs such as 1.1 and 1.3 give engineers and AI agents a durable path from a feature’s intent to its implementation.

That link matters because an AI coding session can leave behind code without the reasoning that produced it. When requirements and decisions live only in a prompt or an agent’s temporary plan, future changes have to reconstruct the original intent from the implementation.

Put feature intent in the repository

For non trivial features, we write a specification before implementation. It lives in a dedicated specs/ folder, usually as Markdown, and describes expected behavior, relevant interactions, edge cases, technical decisions, and how to verify the result.

The spec is a shared source of truth for the team and the agent. It is not documentation added after the work, or a place to collect every engineering convention. The goal is to make feature intent available while the work is being designed, tested, and changed.

This approach is especially useful when a brief leaves product behavior unresolved. For example, free tier limits require decisions about what happens when a user reaches a storage limit, attempts an upload, or upgrades. Turning those scenarios into testable requirements gives the agent something more precise to follow than a broad request to “add limits.”

Use IDs to connect intent to code

Each requirement receives an identifier, such as 1.1. That same ID can appear in the task list, tests, implementation comments, and relevant code paths. A developer who encounters a behavior later can follow the reference back to the spec instead of inferring its purpose from code alone.

IDs also help keep tests tied to expected behavior. In the workflow, the agent reads the approved spec, writes tests first, and implements until they pass. The tests are grounded in identified requirements, so they can express which behavior they verify rather than merely showing that a particular implementation runs.

Keep the references lightweight. The ID points to the explanation; it does not need to carry the whole requirement into every comment or test name. That keeps code readable while preserving a route back to the decision.

Approve decisions before implementation

The process has four phases: requirements, design, tasks, and implementation. A person approves each phase before the next begins.

Requirements turn the feature brief into acceptance criteria. Design makes technical choices explicit, including API shape, database design, data model changes, product behavior, and architectural constraints. Tasks break the approved plan into implementation steps. Only then does implementation start.

This sequence gives an agent reviewed context before it changes code. It also creates checkpoints where a person can correct a misunderstanding before it spreads into design, tasks, tests, and implementation. After implementation, automated reviewers such as Gemini or Cursor Bug Bot can review the code before local testing.

The workflow is still evolving. In particular, tasks can drift or become harder to keep aligned as features grow. Mapping each task to a commit can make the connection between the spec, work performed, and code history cleaner, but teams should watch whether their task structure stays useful over time.

Keep feature specs separate from repo rules

A feature spec should describe that feature’s behavior and decisions. General engineering conventions belong elsewhere, such as repository instruction files, agent rules, or skills. Templates can keep requirements, design, and task files consistent.

This boundary prevents every new spec from repeating coding preferences or carrying unrelated architectural policy. It also helps an agent find the right context: feature behavior in the spec, durable project conventions in repository rules, and repeatable procedures in skills.

Broader architecture changes need the same care. A notifications feature, for instance, raises questions about delivery timing, triggering events, persistence, and channels. Those are feature decisions to resolve. Introducing a message queue or a new data store is a broader architectural shift, and may require repo level rules or skills rather than being smuggled into one feature spec.

A practical starting point is to create one spec for a feature with several meaningful edge cases. Number the acceptance criteria, reference them in tasks and tests, and keep the implementation tied to the approved design. Then review whether someone joining later can trace a behavior back to the requirement that explains it.

Specs should ship with the code because future engineers and agents need the intent alongside the implementation.

Top comments (0)