Orchestrata Ultimate › Gates › feature-loss
Gate: feature-loss
At a glance
| Purpose | Refuse a requirement that silently lost its implementation, a deleted src/ file whose @traces id no current symbol declares, and a deleted spec/ADR whose id living code still cites. |
| Where it runs | The scripts/gates.py battery (registered as feature-loss). |
| Trigger | A battery run whose fingerprint changed, or whose last cached verdict was not ok. |
| Exact command | python scripts/check_feature_loss.py [--repo-root PATH] [--json] |
| Blocks | Exit 1 on an ORPHANED-REQUIREMENT, DELETED-SYMBOL or DELETED-SPEC finding; exit 2 (INVALID) when history or the corpus cannot be read; 0 clean. No waiver. |
| Ruling / ADR | User ruling 2026-08-19 (quoted below; no RUL page names this gate). Neighbouring rulings: RUL-023, RUL-030. |
| Last recorded verdict | ok: false in the primary checkout's .cache/gates.json (file last written 2026-09-22 10:01 local; the cause is not recorded there). wt-MAP-PRECOMMIT has no .cache/gates.json. |
What it refuses
Git-evidenced loss: a requirement whose every historical implementation has been
deleted with nothing surviving to cover it; a deleted src/ file whose @traces
citation no current symbol declares; a deleted spec/ADR document whose requirement id
is still cited by living code or tests.
Why it exists
Module docstring, quoting the ruling verbatim:
"User ruling, 2026-08-19, verbatim: 'add checks at the gates so we never face the lost code and features again and make them non negotiable, make them all reference the specs and report loudly any deleted features and loss.'"
Two recorded losses motivate it: commit 6a186c9d (2026-07-09, the deleted testgen
generator — owned by generated-artifacts;
"this gate is the OTHER half: the SPEC/REQUIREMENT half"), and a dead-code triage
that found "37 UNWIRED" symbols (RUL-023's territory — background for "why the
project now treats 'quietly lost' as a first-class defect class").
Its distinctive capability: "walks GIT HISTORY (not just the current tree) for
evidence that a requirement's implementation, or the document that defines a
requirement, USED TO EXIST and is now gone. Every other traceability gate in this
repo answers questions about the CURRENT tree only." The docstring demarcates it
against check_requirement_corpus ("complementary, not duplicated"),
check_spec_authority (fabrication in tests), trace_intel untraced-reqs
(advisory, no history), history_intel ("this gate answers whether something
was lost; history_intel answers what / when / how / why"), and
generate_rtm_evidence (current-tree grading).
The four checks
- ORPHANED-REQUIREMENT — still defined in the ratified corpus, every historical implementation deleted, no survivor. Fails the gate.
- NEVER-IMPLEMENTED-REQUIREMENT — zero current implementation AND no git evidence it ever had one. Printed, counted, NEVER fails — a deliberate, disclosed precision decision: UNLINKED is "the honest majority" of a 5,500+-id corpus, and "failing on every requirement that was simply never built would make this gate permanently red from the day it lands … exactly the 'noisy gate gets bypassed' failure mode."
- DELETED-SYMBOL — a deleted
src/orchestrata_ultimate/**/*.pyfile whose last committed content carried an@tracessymbol citing an id no current symbol declares. "Reports the deleting commit sha and date — the exact information a 2026-08-19 session spent hours reconstructing by hand for a single incident." Fails the gate. - DELETED-SPEC — a deleted
specs/**ordocs/adr/**document defining an id STILL cited by living src or tests. Fails the gate. ("If nobody currently cites the id, this is ordinary spec housekeeping, not a loss.")
Plus a fifth, SURFACE-LOSS (heuristic, info-only) — a different evidence grade
for capabilities that were never traced at all (motivated by commit 2883703a…,
which deleted an untraced twin).
How it runs
- Command:
python scripts/check_feature_loss.py [--repo-root PATH] [--json]— those are the ONLY flags: "There is likewise no--max/severity/env-var downgrade anywhere in this file." - When it fires: the
scripts/gates.pybattery (registered asfeature-loss). - Polyglot scan scope (2026-08-19 fix): "a requirement whose only implementation
is TypeScript/JavaScript reads, to a Python-only scan, as 'no current
implementation anywhere' — full confidence, completely wrong" (two real false
positives: REQ-021-195..198, an OpenCode TS tool; REQ-016-290..294, VizInt
gadgets). Current implementation is now the union of Python
@tracesundersrc/and TS/JS@tracescomment tags under everyWEB_SOURCE_ROOTSentry (opencode,vizint-ui) — and every run discloses its own scan scope ("aSCAN SCOPEline… never conflated with 'scanned, found nothing'"). - Disclosed detection boundary: whole-file deletions only
(
git log --diff-filter=D— "well under a second" on 3,300+ commits); a stripped decorator in a surviving file is out of scope, with the docstring explaining why a historical AST diff is neither git-cheap nor reviewable. - Inputs: fingerprint roots
("specs", "src", "tests", "plans/feature-loss-invalid-citations.json", "scripts/check_feature_loss.py")(theGATESentry inscripts/gates.py, read through the AST toolkit on 2026-10-23). An earlier version of this page listed three more roots (docs/adr,opencode,vizint-ui); the registry onorigin/master(a4cbc2bdf) does not carry them. - Caching — no git state in the fingerprint. An earlier version of this page
described a suffix mask plus a
GATE_GIT_STATEHEAD/master/merge-base string mixed into the fingerprint. Neither exists:git log --all -S GATE_GIT_STATEandgit log --all -S GATE_MASKSoverscripts/gates.pyfind no commit that ever contained them (checked 2026-10-23)._fingerprint()hashes only file paths and bytes with suffixes.py,.toml,.pl,.json,.md,.shunder the roots above. Consequences, derived from the code and not measured by a run: after a PASS is cached, a new commit, a fetch or a master advance does not re-run this gate (its primary evidence is deletion history), and neither does a change underdocs/adr/or a.ts/.tsx/.jsfile underopencode/orvizint-ui/.
Typical failures and how to fix them
- Fail-closed, deliberately the opposite of check_wiring's SKIP: "This gate grades HISTORY, and 'I could not read history' is not 'nothing to grade' — it is exactly the situation where a loss could be hiding. Not-a-repo, git-unavailable, or an empty ratified corpus … all return INVALID (exit 2), never PASS. Unknown is not clean."
- No waiver path — deliberate: "This repo has a
# gate-ok:waiver convention… This gate does NOT read it, does not import it, and never will: a waivable loss-detector is how the loss happens." - Reclassification — evidence-gated, not a waiver (2026-08-19 ruling): most
DELETED-SYMBOL findings turned out to be citations "INVALID WHEN WRITTEN" (a
2026-04 bulk-annotation pass — an FR-group off-by-one, one requirement stamped on
all 30 functions of a file, 86 rows citing a superseded spec). A finding is
reclassified into the non-failing bucket only on an exact
(req_id, deleted_symbol)pair recorded inplans/feature-loss-invalid-citations.json— "No pattern, prefix, wildcard,--max, or env override… A malformed or unreadable evidence file makes the WHOLE gate INVALID… Every run reports how many citations were reclassified and how many evidence records matched nothing current." - Un-blocking: restore the implementation, get sign-off to retire the requirement, or — where the citation was provably invalid when written — add the exact-pair evidence record.
- A deletion committed after the last PASS that the battery does not see.
Because git state is not in the fingerprint, re-run fresh after commits land or
master moves:
python scripts/gates.py --only feature-loss --all.
Wiring
- Invokers:
scripts/gates.py(battery). - Hand-off: "When a finding here needs a rationale, run
history_intel.py why <symbol>instead of reconstructing one from memory — that reconstruction has already produced a confidently-wrong feature-loss claim once." - Tests:
tests/scripts/test_check_feature_loss.py.
Related
- Gates master index
- Development workflow
- RUL-023 — A feature request means the thing is WIRED
- RUL-030 — Generated artifacts belong in git
- RUL-013 — Specs are authoritative
- generated-artifacts — the generator-provenance half of the same defect class
- requirement-corpus — the current-tree DANGLING sweep this gate supplies the "why" for
- wiring — deleted vs. never-connected