This page explains what the requirements in CodeCharter are good for and what they feel like day to day. The file format with all fields comes after that, under Requirements.
The problem
The requirements for a product almost always live somewhere other than the code that implements them: in a specification document, in Confluence, in Jira tickets, in the minutes of a workshop. On the day of sign-off, both sides match. After that, the code keeps evolving, and the link between the promise and the place in the code that fulfills it survives only in the memory of the people involved.
This shows up in three places. At acceptance, someone has to manually piece together which promise is fulfilled where. At an audit or a certification, the same evidence gets demanded again, this time in writing. And six months later, someone changes a method without knowing that a contractually promised property depends on it.
The approach
In CodeCharter, a requirement is a file in the repository, right next to the
code. It is reviewed in the same pull request, inspected with the same
git blame, and travels with the same branch. An anchor in this file names
the place in the code that fulfills the requirement, and the command
codecharter req check reports when the file and the code no longer match.
What matters here is what the tool claims and what it does not. CodeCharter does not decide whether your code substantively satisfies a requirement. It records that you claimed it does, who accepted it and when, and what evidence that acceptance rested on, and it reports as soon as that evidence no longer holds.
Concretely, the tool checks the structure of the corpus, that is duplicate
ids, references pointing into the void, criteria without a usable carrier,
and the contradiction of carrying a requirement as implemented while its own
acceptance check is still open. With --with-code it additionally checks
whether the anchored symbols still exist at all and whether an acceptance
that was once pinned still matches the code. What it does not check is the
content: whether the requirement's text describes the right thing and
whether the bound test tests the right thing remains human judgment. That is
exactly why acceptance via
codecharter req accept is deliberately not
an MCP tool — an agent can prepare everything, but it can accept nothing.
Who on the team gets what out of it
Developers see, when changing a method, whether a promised property
depends on it. The MCP tool req_context answers exactly this question for
a symbol, without anyone having to search a specification document.
Reviewers get the requirement change in the same diff as the code
change. A new [Satisfies] attribute lands as a line in the diff and is read
there like any other code change.
Project leads and clients have, with documents.yml, an outline over
the corpus from which a specification document, a requirements document, or
an acceptance protocol can be assembled, and, with the rollup per
requirement, a statement of what currently holds and what does not.
Auditors and QA do not read the code, they read the acceptances: who approved which criterion when, on what evidence, and whether that evidence still holds today. All of that is stored, versioned, in the repository.
AI coding agents read the same corpus through ten MCP tools, instead of parsing the files themselves. They may research, draft, bind, and ask for approval, but they cannot accept anything.
The lifecycle of a requirement
The following example follows a single requirement through every stage. It is the same one that reappears on the following pages.
1. The promise is made. In a workshop with the client, the sentence falls that users must be able to reset their own password. Until now, this would have been one line in the minutes.
2. The promise gets a file. Under .codecharter/req, REQ-12.req.md is
created with an id, title, priority, and a statement of whether the promise
is contractually binding. The prose in the body is what a reviewer or
auditor later reads to understand the why.
3. The promise becomes checkable. A requirement that nobody can verify is a statement of intent. So it gets criteria, and each criterion states, through its carrier, how it is verified: by a rule, by a named test, by a manual step, by an integration suite, or by something outside the repository.
4. The promise is bound to code. An anchor names the symbol that
fulfills the requirement, or expects a [Satisfies("REQ-12")] from the
CodeCharter.Annotations package on the implementing member. Without an
anchor, the check rejects the status implemented with an error.
5. The promise is checked continuously. codecharter req check runs in
CI without a solution and without the .NET SDK, and is therefore fast enough
for every pull request. With --with-code, the check against the analyzed
code model is added.
6. The promise is accepted. A human runs
codecharter req accept REQ-12 AC-1 --by <name>. This pins the approver,
the date, and the evidence the approval rests on into the file.
7. The promise survives changes. If the accepted test or the anchored
code region changes, the pin no longer matches, and the requirement renders
as Stale instead of silently continuing to count as satisfied. The
acceptance is then deliberately repeated.
8. The state becomes measurable. codecharter req coverage answers both
directions: does the evidence for each requirement still hold, and which
code carries no justification at all. Details under
Requirements coverage.
Do we need this?
The effort pays off if at least one of these points applies to you: you work against a specification document or a fixed price, someone external formally accepts your delivery, you have to prove to an auditor where a property is implemented, or you let AI agents work on a codebase where certain promises must not break.
The effort tends not to pay off if you are building an internal product without formal acceptance, your requirements arise as tickets anyway and are done once merged, and nobody later demands proof. What speaks against the tool in that case is described in detail under Scope and effort.
Next steps
- First requirement: create, anchor, and check a requirement
- Requirements: the file format with all fields
- Scope and effort: what the tool is not and what maintenance costs
- Requirements coverage: how the state is measured
- Requirements over MCP: what an AI agent is allowed to do with it