registry-hygiene
Use when the traceability registries (SN/SR/LLR/TC and the off-spine PB/PART/ASSET/REPO/CMP) need checking or fixing — run trace.py/check.py with the right flags for the current gate, read the orphan/
Files1
View on GitHubSKILL.mdproject-trajectory/skills/registry-hygiene/SKILL.md
GitHubRegistry hygiene (any repo built from this kit)
Keep the SN → SR → LLR → TC spine (and the off-spine PB/PART/ASSET/REPO/CMP
registries) clean: zero orphans, no duplicate/malformed ids, valid schema. Run
the right check for where you are, then read and fix the findings.
Which command, when
# Always-valid floor (pre-commit + check.py at G1): duplicate/malformed ids
# and CSV structure (every registry data row parses to the header's column count).
python scripts/trace.py --strict-integrity
# Full orphan check (aim for orphans=0 before any gate).
python scripts/trace.py --strict
# G2+: also reject leftover template example rows (ids ending -000).
python scripts/trace.py --strict --no-placeholders
# G3: required fields non-empty + closed Verification/Tier vocabularies + Verified.
python scripts/trace.py --strict --no-placeholders --strict-schema --require-verified
scripts/check.py (or scripts/check.{sh,ps1}) runs the gate-appropriate set
automatically from the active gate in docs/gate — prefer it for a full gate run;
call trace.py directly to iterate on a specific finding.
Reading findings
- orphan — a row not joined end-to-end. Common causes: an SR with no LLR/TC
yet (fine early; a real orphan at G2+), a
Refs/SN-Refs/SR-Refsid that points at nothing, a TC that verifies no real id. Fix the back-link, don't delete the evidence. - integrity (duplicate/malformed id, or a CSV structure break) — two rows
share an id, an id doesn't match the
PREFIX-###shape, or a data row parses to more/fewer columns than its header (almost always an unquoted comma in aPermutationsset or free-text cell — quote the cell). Renumber the duplicate; fix the malformed id; quote the offending cell. The structure sweep covers every*.csvunderdocs/requirements/anddocs/test/, including registriestrace.pynever joins (interfaces, project-added ones). - schema (
--strict-schema) — a required field is empty, or aVerification/Tiervalue is outside the closed vocabulary (Test|Demonstration|Inspection|Analysis|Manual|Attest|Critique;Smoke|Full|Release). Fill the field or correct the value. - placeholder (
--no-placeholders) — a template-000example row survived; delete it once real rows exist. - AC advisory (
WARNING (advisory), warn-only — never fails a run) — anAcceptanceCriteriauses a comparative term (identical / indistinguishable / equivalent / "same as" / matches) without naming its predicate. Pin it: say identical in what, judged how — or accept the wording knowingly at the G1 consistency review (process.md §4). - LLR status-coherence advisory (
WARNING (advisory), warn-only — never fails a run) — an LLR reads belowVerifiedwhile every TC that cites it isVerified, so the evidence to lift it already exists. Fix: edit the LLR'sStatuscell toVerified(registries are hand-owned — no generator writes them back). It never gates: LLR status is non-gating under the derived-gate model (the SR'sVerifieddrives G2→G3), so a lagging LLR is a readout drift, not a coverage hole.
Verify the fix
Re-run the same command; it must print orphans=0 (and exit 0). trace.py
regenerates docs/test/report.md — the readable matrix — so review that too.
Off-spine registries (PB/PART/ASSET/REPO/CMP; legacy MOD read too) are
integrity-checked only plus their declared joins (PB Refs, REPO DelegatedSRs,
CMP PartOf/SupersededBy + the primitives' Component tags); a valid
inert -000 placeholder there never blocks a gate.