Zum Inhalt springen

Requirements

Track requirements as .req.md files in your repository, link them to code with traceability anchors, and organize them into documents with documents.yml.

CodeCharter lets you track requirements right next to the code that implements them. Each requirement is one Markdown file with a YAML frontmatter block under .codecharter/req (the legacy .codeguard/req location is still read). There is no database and no external tool: the requirement corpus is just files in your repository, so it reviews, diffs, and merges like everything else.

The .req.md file

A requirement file has YAML frontmatter between --- fences, followed by a Markdown body:

---
id: REQ-1
title: Users can reset their password
priority: must
contractual: true
status: implemented
kind: functional
section: Account management
source: spec.md#3.2
relations:
  refines:
    - REQ-0
  conflicts:
    - REQ-9
criteria:
  - id: C1-1
    rule: some.dsl.expression()
    status: open
    blocked_by:
      - C1-2
    confidence: needs-predicate
  - id: C1-2
    test: Tests.Auth.PasswordReset_Should_SendEmail
anchors:
  - symbol_id: MyApp.Auth.PasswordResetService
---
Describe the requirement in prose here. Full sentences, not bullet fragments —
this is what a reviewer or auditor reads to understand the "why".

## Out of Scope

Single sign-on providers are not covered by this requirement.

All keys are snake_case. Value tokens (priority, status, kind, and the criterion/anchor keys below) are English and kebab-case, so a requirement file reads the same regardless of the team's spoken language.

Frontmatter fields

Key Required Value Meaning
id yes <Prefix>-<Number>, e.g. REQ-1 Stable identifier. Referenced by refines, conflicts, and documents.yml.
title yes free text Short, human-readable summary.
priority yes must / should / could MoSCoW priority.
contractual yes true / false Whether this requirement is part of a binding agreement (a contract, an SLA) rather than an internal goal.
status yes open / in-progress / implemented / partial Current delivery state.
kind yes functional / security / legal / performance / usability / infrastructure Category.
section no free text Where this requirement lives in a source specification document.
source no free text A pointer back to that source, e.g. a file and section reference.
relations.refines no list of ids Requirements this one narrows or specializes.
relations.conflicts no list of ids Requirements this one is documented to be in tension with.
criteria no list See below.
anchors no list See below.

Every top-level key not in this table is rejected — but only with a warning, not an error, because an unknown key is more likely a field from a newer CodeCharter version than a typo. codecharter req check still tells you about it, though, so it does not pass unnoticed.

Criteria

A criterion is one acceptance check for the requirement. Each needs an id and exactly one of five carrier keys, which say how the criterion is verified:

Carrier Meaning
rule: A CodeGuard rule DSL expression that must hold.
test: A specific automated test that exercises this criterion.
manual: A step a human verifies (e.g. in a manual QA pass).
integration: An integration or contract test suite.
external: Verified by something outside this repository (an audit, a third party).

A criterion with zero carriers, more than one carrier, or an empty carrier value is invalid — codecharter req check reports it.

Optional criterion keys:

  • status: open marks a criterion not yet satisfied. Omit the key for a satisfied criterion — there is no explicit "closed" token.
  • blocked_by: lists the ids of other criteria (in this or another requirement) that must land first.
  • confidence: needs-predicate flags a criterion whose rule: expression is a placeholder, not yet backed by a real, checkable predicate.

A requirement marked status: implemented while one of its criteria is still status: open is a contradiction codecharter req check catches — you cannot claim a requirement is done while its own acceptance check says otherwise.

Anchors

An anchor links a requirement to the code that satisfies it. Three kinds exist today, all declaration-only (no runtime verification yet):

Anchor Keys Meaning
Attribute-expected attribute_expected: Names a fully-qualified type; the requirement is satisfied by any symbol carrying [Satisfies("REQ-1")] from the CodeCharter.Annotations package on a member assignable to that type.
File selector file: + selector: Points at a file path and a textual selector (e.g. a class declaration) inside it.
Symbol id symbol_id: Names a fully-qualified symbol directly.

A requirement with status: implemented or status: partial and no anchor at all is an error — an "implemented" requirement with nothing pointing at the code that implements it cannot be traced. The same gap on an open or in-progress requirement is only a warning: it is normal for work not yet started to have no anchor yet.

## Out of Scope

A ## Out of Scope heading in the body (case-insensitive, any amount of whitespace) starts a delimitation section: everything after it is read as the boundary of the requirement — what it deliberately does not cover. Keeping this in the same file as the requirement itself means the boundary travels with the requirement instead of living in a separate, easily-forgotten note.

documents.yml: organizing requirements into documents

Alongside the .req.md files, an optional .codecharter/req/documents.yml groups requirements into documents and chapters — a requirements specification, a functional specification, an acceptance protocol:

title_page:
  title: Sample Product — Requirements
  subtitle: Volume 1
  customer: ACME Corp
  project: Sample Product
  version: "1.0"
  issued_on: "2026-01-01"
documents:
  - slug: requirements-specification
    kind: requirements-specification
    title: Requirements Specification
    chapters:
      - slug: account-management
        title: Account management
        requirements:
          - REQ-1
          - REQ-2

kind is one of requirements-specification, functional-specification, or acceptance-protocol. codecharter req check cross-references the chapter requirements lists against the corpus: an id that does not exist anywhere is an error, and a requirement that exists but appears in no chapter is a warning, so nothing quietly falls out of the published document set.

Checking the corpus

Run codecharter req check to validate everything described on this page — duplicate ids, dangling refines/conflicts references, criteria without a usable carrier, the implemented-with-open-criteria contradiction, missing anchors, and the documents.yml cross-references. See codecharter req check for the full list of codes, exit codes, and output formats.

Reading requirements from an AI coding tool

An agent working in your codebase can read this same corpus over MCP without ever touching a .req.md file directly: see Requirements over MCP for the three read-only tools (req_context, req_search, req_justify).