[doc->WHY-TRACEABLE-REQS]

Requirements, with receipts.

traceable-reqs is a small, deterministic CLI that proves every requirement in your manifest has evidence in your tree — docs, implementation, and tests — and compiles exact working context for whatever coding agent you already use. No orchestrator required.

deterministic — no model calls, works offline one binary — a manifest, tags, and a shell agent-agnostic — Claude Code, Codex, Cursor, CI, or by hand
[doc->HOW-IT-WORKS]

A manifest, a tag grammar, and a gate

The manifest declares what must exist. Tags in comments declare where it exists. check tells you — with a stable exit code — whether the two agree.

traceable-reqs.toml — the contract
[[requirements]]
id = "REQ-LOGIN-001"
title = "User can sign in"
required_stages = ["doc", "impl", "unit", "int"]
src/auth.rs — the evidence
// Combined sign-in and audit logging.
// [impl->REQ-LOGIN-001] [impl->REQ-AUDIT-001]
pub fn authenticate(email: &str, ...) {
$ traceable-reqs check
[OK] REQ-LOGIN-001   required: [doc, impl, unit, int]   stages: +doc +impl +unit +int
[!!] REQ-LOGOUT-001  required: [doc, impl, unit]        stages: +doc -impl +unit
     missing_stage: Requirement is missing implementation evidence  (exit 1)
[doc->VERDICTS]

“Tests passed” is not the question

A green test run proves your code does something. It doesn't prove the requested behavior got built, or that nothing else quietly changed. Tracing turns the verdict from a feeling into a report addressed by requirement.

What CI tells you

 161 tests passed

What the trace tells you

 REQ-LOGIN-001  every required stage has evidence
 REQ-AUDIT-001  preserved — evidence untouched
 REQ-LOGOUT-001 missing_stage: impl
 src/typos.py:3 undeclared_id REQ-LOGNI-001 (typo?)
[doc->BENEFITS]

What you get, orchestrator or not

[benefit->DETERMINISM]

A gate you can trust in CI

check is a pure function of your manifest and your tree: no network, no model calls, no clock, no flakiness. Same input, same verdict, byte-stable JSON. Finding codes (missing_stage, undeclared_id, parse_error) are stable, so CI and scripts match on codes, not prose.

MoSCoW priorities are built in: check --fail-on must blocks on must-haves while could-haves stay warnings.

[benefit->CONTEXT]

Compiled context for any coding agent

change compile REQ-LOGIN-001 --json turns requirement IDs into a Change Contract: the exact files to read, the tags co-located in them, the requirements you must not break, and the proof obligations that define done. Paste it into Claude Code, Cursor, a CI bot, or read it yourself — the agent starts from a compiled brief instead of wandering the repo.

$ traceable-reqs change compile REQ-LOGIN-001 --json
{
  "kind": "changeContract",
  "obligations":  [ one per required stage — the definition of done ],
  "related":      [ { "id": "REQ-AUDIT-001", "sharedFiles": [...] } ],
  "contextFiles": [ { "path": "src/auth.rs", "resolution": "syntactic",
      "tags": [ { "requirementId": "REQ-LOGIN-001", "line": 4,
                  "enclosingSymbol": "authenticate" } ] } ]
}
[benefit->SYMBOLS]

Evidence anchored to functions, not line numbers

A built-in tree-sitter pass resolves every tag to its enclosing symbol — authenticate, C::m, jobs.build — so obligations read as “prove test_logout_clears_session,” survive line drift, and a tag attached to nothing surfaces as a stranded-tag signal instead of silently counting.

RustPythonC/C++JavaScript TypeScriptTSXBashPowerShell YAMLCMakeMarkdown (tags)
[benefit->IMPACT]

Undeclared impact, caught mechanically

The contract's related section lists every requirement sharing evidence files with your targets — the do-not-break list. If your diff touches lines carrying another requirement's tags, that requirement was affected without being declared. The response is one move: promote it into the target set and recompile. A wrong promotion costs one extra verification; a missed one is silent breakage.

[benefit->HONESTY]

Facts and judgment never blur

Every claim in the output wears its epistemic rung. Agent opinions can be appended — but only into a reserved annotations array, marked basis: "inference". A model's “looks fine to me” can never impersonate a graph fact.

RungSourceGuarantee
Tags scanned [stage->REQ-ID] comments sound — the evidence exists at that line
Syntactic tree-sitter enclosing symbols deterministic, pinned grammars
Semantic your compiler index, declared in the manifest (reserved) resolved references, provenance recorded
Inference agent judgment best effort — always labeled
[benefit->AGENT-IO]

Built for agent consumption

Output is pyramid-shaped — summary counts, then per-requirement status, then findings, then line-level evidence — so an agent inspects a hundred requirements cheaply and drills into three. lint and review emit fixed-shape prompts an agent can evaluate (is this title testable? does this tag sit on code that really implements it?) while the tool itself stays deterministic.

External evidence works too: a QC signoff living in a GitHub issue comment is declared once in the manifest and counts like a tag.

[doc->NO-ORCHESTRATOR]

About Attractor

You may know traceable-reqs alongside Attractor, the DOT-graph workflow engine that ships a canonical encoding of the change loop. The dependency points one way: Attractor consumes traceable-reqs; traceable-reqs knows nothing about Attractor.

Every step of the loop — resolve targets, compile the contract, implement, verify, review impact — needs only a shell and this CLI. Drive it from a Makefile, a CI job, whatever agent harness you already run, or a terminal. If you ever want an unattended, human-gated version of the loop, Attractor's traceable-change-loop workflow is there — as a downstream consumer, never a requirement.

[doc->GETTING-STARTED]

Adopt it in an afternoon

1 — declare what must exist
# traceable-reqs.toml
[scan]
roots = ["src", "docs", "tests"]

[[requirements]]
id = "REQ-LOGIN-001"
title = "User can sign in"
2 — tag the evidence where it lives
# [unit->REQ-LOGIN-001]
def test_rejects_empty_password():
3 — gate on it, trace it, compile from it
traceable-reqs check --json          # the CI gate
traceable-reqs trace REQ-LOGIN-001   # one requirement, end to end
traceable-reqs change compile REQ-LOGIN-001 --json   # the agent brief

Start with five requirements you actually care about, not five hundred. The gap report is the point — it tracks what's unproven until it isn't.