Skip to content

Integrity Checks

spec check runs cross-repo integrity, coverage, and drift diagnostics. Error-severity diagnostics drive exit 1; warnings alone exit 0. --ci forces a cold rebuild (deletes the DB first — correctness never trusts a warm index).

CodeSeverityCondition
INVALID_DOMAIN_FILEerrorA SPEC.json fails the structural schema (bad JSON, malformed key/id, missing statement, unknown envelope key) — loud, never a silent zero
DUP_IDerrorThe same requirement ID appears twice
BROKEN_SUPERSEDEerrorsupersededBy points at a missing ID
CYCLIC_SUPERSEDEerrorA circular supersession chain (A → B → A) — the chain is the change history, so a cycle is corrupt history
BAD_STATUSerrorEntry status outside active / draft / superseded / retired
DANGLING_TAGerrorA @spec tag references no requirement
SUPERSEDED_REFERENCEDerrorCode still tags a superseded requirement (retag to the successor)
ORPHAN_REQerrorAn active requirement has no implementing @spec tag
UNVERIFIED_REQerrorAn active requirement is implemented but has no verifying test tag
DRIFTerrorA member is pinned behind the version at which a requirement it references changed
NO_SPEC_CONFIGwarningA sibling repo-root under the platform has no spec-engine.member.json
BROKEN_FILE_REFwarningAn @<path> reference in requirement text does not resolve
BROKEN_RELATESwarningA relates entry points at a nonexistent requirement ID
RELATES_SUPERSEDEDwarningA relates entry points at a superseded requirement
SELF_RELATESwarningA relates entry names its own requirement (dropped, but surfaced)
UNKNOWN_ROLEwarningAn issues entry uses a role outside created / supersedes-via / amends-via — surfaced and dropped, never stored
CodeSeverityCondition
UNDEFINED_TERMerrorA requirement’s cites entry resolves to no glossary TERM
SUPERSEDED_TERM_REFERENCEDerrorA citation points at a superseded term ID — re-point with spec term confirm
TERM_DRIFTwarningA citation’s pin lags the cited term’s current version after spec term revise — a re-confirmation prompt, not a build-breaker
ORPHAN_TERMwarningAn active TERM no requirement cites — glossary rot, deliberately non-fatal

Trusted-red proof gate (--results <junit.xml>)

Section titled “Trusted-red proof gate (--results <junit.xml>)”

Pass your test runner’s JUnit XML and check enforces proof of passing — a verifying tag only counts when its test actually passed:

CodeSeverityCondition
UNPROVEN_REQerrorAn active requirement has verifying tags but no passing correlated test
PROOFS_UNCONFIRMEDwarningNo --results supplied — the gate falls back to presence-only mode (this warning is the reminder; routed to stderr under --json)
Terminal window
bun test --reporter=junit --reporter-outfile=.spec-engine/results.xml
spec check . --ci --results .spec-engine/results.xml

With a git base ref, check also diffs the requirement set against that ref:

CodeSeverityCondition
REQUIREMENT_REMOVEDerrorA requirement present at the base ref is gone with no approved supersession
UNAPPROVED_STATUS_FLIPwarning†A flip to superseded/retired whose CODEOWNERS domain owner is absent from --approved-by — †error under --require-owner-approval
PARTIAL_PROPAGATIONerrorNeeds --base and --results: a changed requirement where some bound tests pass and some fail — one site migrated, another still red

See also spec guard, the pre-commit loss gate that reports REQUIREMENT_REMOVED / IMPL_LOST / VERIFY_LOST / SPEC_FILE_DELETED against the working tree — Commands.

CodeSeverityCondition
UNSOURCED_CHANGEwarningA superseded requirement carries no supersedes-via issue. Emitted only under spec check --unsourced-change