Development record
Eight typed cross-references point at targets absent from the tree — adr-22 supersedes adr-14, adr-15 and adr-17; adr-25 supersedes adr-8; adr-27 supersedes adr-16; adr-28 supersedes adr-18; adr-35 supersedes adr-4 (all retired under retire-the-name); itd-3 names spec_id spc-1 which has no file — and nothing checks supersedes targets today. The 2026-08-21 site investigation counted six; the in-session grep found eight. The planned site build arms the detector via the .abcd/site-baseline.json ratchet, seeded with what the build finds, and the tombstones-or-stubs question (itd-136/itd-137) decides how they render
Press Release
Seeded by promotion from iss-2608220150157498. Expand into the full press-release narrative before planning.
Why This Matters
Graduated from iss-2608220150157498: Eight typed cross-references point at targets absent from the tree — adr-22 supersedes adr-14, adr-15 and adr-17; adr-25 supersedes adr-8; adr-27 supersedes adr-16; adr-28 supersedes adr-18; adr-35 supersedes adr-4 (all retired under retire-the-name); itd-3 names spec_id spc-1 which has no file — and nothing checks supersedes targets today. The 2026-08-21 site investigation counted six; the in-session grep found eight. The planned site build arms the detector via the .abcd/site-baseline.json ratchet, seeded with what the build finds, and the tombstones-or-stubs question (itd-136/itd-137) decides how they render. Read that issue record for the source observation.
Scope Conditions
None stated.
Acceptance Criteria
- Given a record that introduces a new
supersedesreference naming a record absent from the tree, when the site-baseline reference detector runs, then it fails as a red gate. - Given a record whose
spec_idnames aspc-Nthat has no file, when the reference detector runs, then it fails as a red gate. - Given the existing backlog of dangling supersedes and spec-target references, when it is seeded into
.abcd/site-baseline.json, then those references are baselined and do not newly fail the gate. - Given a dangling reference that has been baselined, when its target is later added to the tree, then the detector still passes and the reference no longer counts as dangling.
Open Questions
None recorded yet.
Audit Notes
Fidelity review — receipt rcp-80f5e908a6e3 (verifier intent-auditor claude-fable-5-1).
Provenance: intent-auditor@claude-fable-5-1 · rubric_hash sha256:effa65b3e9e88ff29433b443ec2be159522a8b0b71cf1434526514aa61edb13e · prompt_hash sha256:151a233b1a269fb92a1dfffcc83626d1a1a4863ae9fe7d9338089d204d8042fa Input attestations: diff:328a6755^1..328a6755 (PR #555, commit 34429a7f) -- internal/core/site check/recordjson/tests and .abcd/site-baseline.json, judged against the tree at 0ab2ad02@sha256:044fdbb79bee531c54777ef22799255016bfa2c069ea04bcf1d08472efe0054a;
Acceptance rollup: MET 4 · MET_WITH_CONCERNS 0 · NOT_MET 0 · INCONCLUSIVE 0
Per-criterion verdicts:
- ac-1 — MET: measureHealth counts a supersedes dangle even when its target reads as pruned, checkBaseline fails any live unresolved reference outside the committed baseline, and TestCheckRefusesANewSupersedesDangle asserts a CheckBaseline finding for a new supersedes naming an absent adr while the admitted backlog entry does not fail; site check is the site-render gate in make preflight evidence: internal/core/site/recordjson.go:429 — "if e.Field != "supersedes" && retired[e.To] {" evidence: internal/core/site/check.go:1401 — "c.fail(CheckBaseline, where, ""," evidence: internal/core/site/check_test.go:660 — "func TestCheckRefusesANewSupersedesDangle" evidence: internal/core/site/check_test.go:708 — "func TestSupersedesToAPrunedRecordStillCounts"
- ac-2 — MET: a spec_id graph-field dangle reaches Health.Unresolved through the same walk and fails through the same c.fail; TestCheckRefusesADanglingSpecTarget writes an intent whose spec_id names a spec no file answers to and asserts the CheckBaseline finding on that id evidence: internal/core/site/check_test.go:674 — "func TestCheckRefusesADanglingSpecTarget" evidence: internal/core/site/recordjson.go:425 — "for _, e := range graph.Dangling {" evidence: internal/core/site/check.go:1401 — "c.fail(CheckBaseline, where, "","
- ac-3 — MET: the committed .abcd/site-baseline.json carries the eight backlog entries (adr-22 to adr-14/15/17, adr-25 to adr-8, adr-27 to adr-16, adr-28 to adr-18, adr-35 to adr-4, itd-3 to spc-1); checkBaseline skips a live reference the baseline admits, and TestCheckPassesABaselinedBacklog asserts a clean CheckBaseline over both field kinds when admitted evidence: .abcd/site-baseline.json:3 — ""unresolved_references": [" evidence: .abcd/site-baseline.json:11 — "{"from": "itd-3", "to": "spc-1"}" evidence: internal/core/site/check.go:1391 — "if admitted[key] {" evidence: internal/core/site/check_test.go:686 — "func TestCheckPassesABaselinedBacklog"
- ac-4 — MET: a baseline entry whose reference now resolves is a c.note inviting the baseline to shrink, never a failure; TestCheckPassesWhenABaselinedTargetArrives writes the missing adr-2 back and asserts the gate passes evidence: internal/core/site/check.go:1415 — "c.note(CheckBaseline, where," evidence: internal/core/site/check_test.go:773 — "func TestCheckPassesWhenABaselinedTargetArrives" evidence: internal/core/site/check_test.go:570 — "func TestCheckInvitesAShrinkingBaseline"
Gap audit:
- honoured:
- a dangling supersedes or spec target fails the site build as a red gate, ratcheted against a committed baseline evidence: internal/core/site/check.go:1401 — "c.fail(CheckBaseline, where, ""," evidence: internal/core/site/check_test.go:660 — "func TestCheckRefusesANewSupersedesDangle"
- the existing backlog is seeded into the baseline and does not newly fail evidence: .abcd/site-baseline.json:3 — ""unresolved_references": [" evidence: internal/core/site/check_test.go:686 — "func TestCheckPassesABaselinedBacklog"
- the detector is armed by tests for all four ratchet behaviours; the detector itself and the seeded baseline predate PR #555 (baseline landed in 2f8fd254), so the delivery is the arming, not a new mechanism evidence: internal/core/site/check_test.go:708 — "func TestSupersedesToAPrunedRecordStillCounts" evidence: internal/core/site/check_test.go:773 — "func TestCheckPassesWhenABaselinedTargetArrives"
- diverged: (none)
- missing: (none)
Frontmatter
| id | itd-160 |
|---|---|
| type | intent |
| lifecycle | shipped |
| kind | standalone |
| severity | minor |
.abcd/development/intents/shipped/itd-160-dangling-supersedes-and-spec-targets.md
open on GitHub ↗ · commit history ↗
Referenced by2
- iss-2608220150157498Eight typed cross-references point at targets absent from the tree — adr-22 supersedes adr-14, adr-15 and adr-17; adr-25 supersedes adr-8; adr-27 supersedes adr-16; adr-28 supersedes adr-18; adr-35 supersedes adr-4 (all retired under retire-the-name); itd-3 names spec_id spc-1 which has no file — and nothing checks supersedes targets today. The 2026-08-21 site investigation counted six; the in-session grep found eight. The planned site build arms the detector via the .abcd/site-baseline.json ratchet, seeded with what the build finds, and the tombstones-or-stubs question (itd-136/itd-137) decides how they renderrelated
- spc-52dangling-supersedes-and-spec-targets-nothing-checks-themimplemented by
mentions10
- adr-2Three intent kinds (standalone / bundle-member / discipline)
- adr-22Bundled dependencies become pluggable adapters over a native default
- adr-25The LLM is host-delegated by default; oracles are opt-in adapters
- adr-27The autonomous run is a pluggable seam, not a Ralph port
- adr-28One repository, a curated release artifact — no dev→public mirror
- adr-35The lifeboat is a coverage experiment — read-only, out-of-tree, and proven before it is packed (supersedes adr-4)
- iss-2609290448510918The predecessor-store qualifier sweep reaches past the six intents iss-2609261536147903 named: outside drafts/ and those six, 192 citation sites across about forty intents name a spc-N at or below spc-70 that is not the citing intent's own spec, with no '(predecessor store)' on the line. Some are live cross-references (the cold-reading family's intents cite each other's live specs), and some are the predecessor store's (itd-4, itd-6, itd-29, itd-47 and itd-49 describe pre-rebuild work in its terms), so each site needs the same reading against the live spec it collides with; the specs charter's Two spc-N Namespaces section is the rule. Found while sweeping the pattern of iss-2609261536147903 in lane drainDrift3; a census script over intents/{planned,shipped,disciplines} reproduces the count.
- itd-3abcd Loads Its Own Rules On Demand
- itd-136Alice opens the record explorer and reads the whole development record — every decision, intent, spec and issue as a page, with contributors and references — without reading YAML on GitHub
- itd-137Maya sees how every decision connects — one relationship chart with a date coil and a links-only layout, and a five-lane genealogy of the record over time