Orchestrata Ultimate › Gates › requirement-corpus

Gate: requirement-corpus

At a glance

Purpose Refuse a @traces citation in src/ naming a requirement id the RTM loader cannot grade (DANGLING).
Where it runs The scripts/gates.py battery (registered as requirement-corpus); scripts/health_check.py.
Trigger A battery run whose specs/, src/ or scripts/generate_rtm_evidence.py fingerprint changed; a health check.
Exact command python scripts/check_requirement_corpus.py
Blocks Exit 1 on a DANGLING citation; exit 2 INVALID when zero ids or zero citations were examined; 0 pass. Spec/checklist drift is advisory.
Ruling / ADR RUL-013 — specs are authoritative, RUL-031 — requirement ids have one spelling, RUL-028 — traceability is a query; RTM regeneration is part of the Definition of Done in ADR-0069 / RUL-034. The module docstring names no ruling.
Last recorded verdict ok: true in the primary checkout's .cache/gates.json (file last written 2026-09-22 10:01 local). wt-MAP-PRECOMMIT has no .cache/gates.json.

What it refuses

A @traces citation in src/ naming a requirement id the RTM's loader cannot grade — DANGLING: "either the decorator is wrong, or the loader has been narrowed again. Both are defects, and this gate fails on either without needing to know which."

Why it exists

Module docstring, the drift it closes:

"This repo had two things deciding 'what requirements exist': serialize_codebase_ast._requirement_source_files — the RATIFIED corpus … and generate_rtm_evidence.load_requirements — what the RTM actually grades against.

They drifted, and the drift was invisible for as long as nobody compared them. The toolkit widened its scan after finding that a checklist-only glob made 43 real @traces look dangling; the RTM generator never received that fix. So trace-lint called those citations clean while the RTM graded them GHOST, and 68 requirement ids across 6 files — all of SPEC-033 and SPEC-034, 22 of SPEC-110, the 001-kernel and 097 addenda — sat outside the matrix's universe. Not UNLINKED. Not GHOST. Absent from the denominator, so every coverage percentage was computed against the wrong total.

The defect was never a missing checklist. It was two readers of one corpus with nobody asserting they agree."

Why it is shaped the way it is:

"The obvious gate — compare load_requirements() against the corpus function it calls — is a TAUTOLOGY. It can never fail, which is the same false green as a checker that never looked. So the load-bearing comparison is against @traces decorators harvested from the AST of src/, which know nothing about how requirements are loaded and can therefore genuinely disagree."

Documentation drift (spec.md vs its checklist) is an ADVISORY, not a failure — "a gate that fails on documentation cadence gets switched off, which costs more than the drift it catches" (the docstring's example: "SPEC-110's checklist asserts '29/29 requirements implemented' against a spec.md defining 51").

How it runs

Typical failures and how to fix them

Wiring