Development record
Know What a Repo Can and Cannot Tell You — Before You Trust the Lifeboat
Press Release
abcd ships
/abcd:disembark probe <repo>— point it at any repository and get back an honest account of what can be rescued from it. The probe reads a repo without touching it and reports, section by section, what a lifeboat could actually ground: which parts of the project's theory are written down somewhere, which are only half there, and which are simply absent. Every grounded claim cites the file it came from. Every blank carries what abcd searched and the question a human has to answer instead. Run it across several repos and/abcd:disembark coverageputs them in one table — so you can see, in a number, what keeping a record is worth."I inherited a repository and three sentences of context," said Iris, product lead. "The probe gave me a list of exactly what the repo could not tell me — and a question for each one. That list is my first week. I stopped guessing what I didn't know."
"I mine dead projects for a living, and the danger is always the confident summary that turns out to be invented," said Jack, consultant. "This one refuses to fill a section it can't cite. When it says blank, it means blank — and it shows me where it looked."
Why This Matters
The lifeboat is what abcd's press release says abcd is — the surface that makes a project survivable. It is also the only major surface with zero code, and it has no owning intent: itd-7, itd-8, itd-9, itd-11, itd-16, itd-23 and itd-35 are all satellites orbiting an intent that was never written. This is it.
It matters now, and as an experiment rather than a feature, because the brief's structure is an assumption nobody has tested. The brief asserts that a project's theory decomposes into these sections. Build the packer first and you have assumed the answer — you will get a lifeboat shaped like the brief whether or not the brief is a shape reality fits.
So invert the build. Probe before pack. Run the same probe over a repo with a rich record and a repo with nothing but git, and the delta in section coverage is what the record is worth. That number is the point. If it is large, abcd's premise — that writing things down is the thing worth doing — survives contact with reality. If half the brief comes back permanently blank on every repository, the structure is wrong, and we have learned that for the cost of one milestone instead of a whole phase.
The honesty discipline is the other half. A rescue tool that invents a plausible section is worse than one that leaves it empty, because the reader cannot tell the difference. A blank is therefore a first-class result, not a failure: it names what is missing, what was searched for it, and the question a human must answer.
What's In Scope
abcd disembark probe <repo>— read-only, out-of-tree. Reports per-section coverage:grounded/partial/blank, with confidence, the tier it was grounded from, and the evidence cited.- Tiered source adapters that degrade: Tier 0 git (every repo), Tier 1 conventions (
README,docs/,CHANGELOG,LICENSE,CONTRIBUTING, ADRs wherever they live), Tier 2 abcd-native (.abcd/). abcd disembark coverage <coverage.json>...— the cross-repo aggregate: one table, section × repo. This table is the artefact that answers whether the brief structure is sound.- A stable, aggregatable coverage schema —
schema_version, per-section status, evidence, what was searched, and the question a blank raises. - The graveyard as a first-class section — archaeology (Tier 0), recorded abandonment (Tier 1/2), then interpretation that must cite the evidence beneath it or be dropped by the validator.
- The packer (
disembark <repo> to <dest>), embark, and the round-trip — built after the aggregate settles the section list.
What's Out of Scope
- Greenfield scaffolding — starting a new project with abcd conventions and no lifeboat to embark from is itd-21's (
/abcd:init-project scaffold). This intent never scaffolds; it only reads existing repositories. - Mining chat transcripts for unrecorded rationale (Pass B) — there is no corpus. It ships as a declared exemption in
_provenance.json, never a silent gap, until the transcript store has data. - The hostile-lifeboat threat battery, the Merkle chain (itd-16),
--with-code(itd-8), schema migrators beyond the version stamp (itd-9), RepoPrompt portability (itd-7), and backgrounded execution — all deliberately deferred. - Writing anything into the source repository, ever.
Acceptance Criteria
BDD format, per
itd-1-acceptance-gates. These gates are checked byintent-fidelity-reviewerwhen this intent moves toshipped/.
- Given a repository with no abcd record at all (git and nothing else), when the user runs
abcd disembark probe <repo>, then a coverage report is produced naming every brief section it cannot fill, each blank carrying what was searched and the question a human must answer — and the run never fails merely because the repo is poor. - Given any repository, when
proberuns against it, then the source tree is byte-identical afterwards — a test hashes it before and after — and abcd writes nothing inside it. - Given a section reported
grounded, when the report is read, then every claim in it cites the source file it came from; a claim with no citation is a defect, not a stylistic lapse. - Given coverage reports from several repositories of mixed record quality, when the user runs
abcd disembark coverage <coverage.json>..., then one table renders section × repo, and the delta between a rich-record repo and a git-only repo is legible as a number. - Given the same repository probed twice with no changes between runs, when the two reports are compared, then they are identical — the probe is deterministic, so a delta in the aggregate means a delta in the repos, never in the tool.
- Given a repository whose richest tier is Tier 0, when it is probed, then the
graveyardsection is stillgrounded— what a project abandoned is recoverable from git history alone (reverts, branches abandoned unmerged, files deleted after substantial history, dependencies added then removed). - Given an interpreted graveyard entry that cites no layer-1 or layer-2 evidence id, when the Go validator runs, then the entry is dropped — cite-or-be-dropped is enforced by code, not by the model's good intentions.
- Given the packer exists (a later milestone), when
dry-runandto <dest>are compared, then they report the same planned writes — one code path, sodry-runcannot lie about whattowill do, and a test asserts exactly that.
Prior Art
- adr-35 ratifies this intent's shape: probe before pack, read-only and out-of-tree, coverage as a first-class output, the graveyard as a new section,
voyage/at the operator level (superseding adr-4). - Satellites of this intent, all pre-existing: itd-11 (Pass B pitfall mitigation — its low-confidence-quarantine mechanism becomes the graveyard's cite-or-be-dropped validator), itd-35 (lifeboat integrity audit), itd-16 (hash-chain/Merkle audit), itd-8 (
--with-code), itd-9 (schema migrators), itd-7 (RepoPrompt workspace portability), itd-23 (Spec Kit interop). Each assumed an owning intent that did not exist. - itd-21 (
no-lifeboat-scaffolding) was read first to check for overlap: it owns the greenfield path (scaffold a new project with no lifeboat to embark from). It does not overlap — this intent only ever reads repositories that already exist. The boundary is recorded in What's Out of Scope. - Naur (1985), Programming as Theory Building — the recovery-humility frame the lifeboat already cites: the theory lives in the people, and an artefact is a proxy for it. This intent takes that seriously enough to measure the proxy's coverage rather than assert it.
repolinterand Conftest are the closest external analogues already adopted in this repo (by itd-85's audit engine): a rule set producing a per-rule verdict over a repository. Coverage differs in that a failing rule there is a defect, whereas a blank here is information — the question a human must answer.
Open Questions
- Which brief sections survive the cross-repo aggregate?
product/personasis predicted blank below abcd-native and only partial there; if that holds across the corpus, the section is not derivable from a repository at all and should not be in a lifeboat's brief. This is the question the experiment exists to answer, and it is deliberately open. - How many repositories does the aggregate need before the delta is trustworthy rather than anecdotal?
- Does
partialearn its place as a status, or does it become a bucket where every hard call goes to die?
Audit Notes
Fidelity review — receipt rcp-4d07032fc6ab (verifier abcd:intent-fidelity-reviewer claude-fable-5).
Provenance: abcd:intent-fidelity-reviewer@claude-fable-5 · rubric_hash sha256:bda482993615f6ee00d06f9649bff9c9bc8f22c989683386437eea4db28369b2 · prompt_hash sha256:95792472ae74ca0469f69a51c618946e0d33cb1380032460099ed4b469d67e86 Input attestations: diff:docs/itd-88-coverage-experiment @ 7b24b98befbd20440b335a96d0154bd33cbcec6e: internal/core/lifeboat/ (probe/coverage/plan/pack/graveyard), internal/surface/cli/cli.go disembark wiring, commands/abcd/disembark.md, .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md@-; rubric:.abcd/.work.local/reviews/rcp-4d07032fc6ab.request.md@sha256:bda482993615f6ee00d06f9649bff9c9bc8f22c989683386437eea4db28369b2;
Acceptance rollup: MET 6 · MET_WITH_CONCERNS 2 · NOT_MET 0 · INCONCLUSIVE 0
Per-criterion verdicts:
- ac-1 — MET: Live probe of a git-only fixture (git init, one revert, nothing else) exits 0 and renders all 23 sections with every blank carrying its searched list and a human question; completeness and question-on-every-blank are test-enforced. evidence: cmd: go run ./cmd/abcd disembark probe <git-only fixture> (exit 0) — "grounded 1 · partial 4 · blank 18 (of 23 sections) … searched: glossary, naming registry, reserved-vocabulary tables / ? Nothing probed grounds constraints/naming; a human must supply it." evidence: internal/core/lifeboat/probe_test.go:353 — "func TestProbeNeverBlankSectionCarriesAQuestion" evidence: internal/core/lifeboat/probe_test.go:322 — "func TestProbeReportsEverySection"
- ac-2 — MET: TestProbeLeavesEveryFileByteIdentical sha256-hashes every file before and after a probe and fails on any rewrite/create/remove; it and TestProbeNeverMutatesTheSource ran green (go test -run …, PASS), and all reads go through a contained read-only os.Root. evidence: internal/core/lifeboat/probe_test.go:254 — "func TestProbeLeavesEveryFileByteIdentical … t.Errorf("probe rewrote %s (sha256 %s -> %s)"" evidence: cmd: go test -run 'TestProbeLeavesEveryFileByteIdentical|TestProbeNeverMutatesTheSource' ./internal/core/lifeboat/ — "--- PASS: TestProbeLeavesEveryFileByteIdentical / --- PASS: TestProbeNeverMutatesTheSource" evidence: internal/core/lifeboat/probe.go:102 — "Probe must be side-effect-free and must never write to the source repository"
- ac-3 — MET: The anti-fiction rule is test-enforced (every non-blank row must cite evidence) and a live JSON sweep over abcd-cli, cobra, and requests found zero grounded/partial rows without a citation. evidence: internal/core/lifeboat/grounding_test.go:105-108 — "if s.Status != StatusBlank && len(s.Evidence) == 0 { t.Errorf("section %s is %s but cites no evidence"" evidence: cmd: disembark probe --json over abcd-cli/cobra/requests, checked for evidence-less non-blank rows — "non-blank rows missing evidence: NONE (all three repos)"
- ac-4 — MET: Live
disembark coverage self.json cobra.json requests.jsonrenders one 23-section × 3-repo status table, the per-repo probe summaries put the delta in numbers (grounded 21 vs 4 vs 3), and the research note states it as 17–18 grounded sections. evidence: cmd: go run ./cmd/abcd disembark coverage <3 reports> (exit 0) — "brief section abcd-cli cobra requests verdict … 0 of 23 sections are blank in every probed repo." evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:39-42 — "Keeping an abcd-native record is worth roughly 17–18 grounded sections" evidence: internal/core/lifeboat/coverage.go:203 — "func Aggregate(covs []Coverage) AggregateReport" - ac-5 — MET: TestProbeIsDeterministic requires byte-identical JSON across two probes and ran green, and a live double probe of this repository produced byte-identical output under cmp. evidence: internal/core/lifeboat/probe_test.go:385 — "func TestProbeIsDeterministic … if string(ja) != string(jb)" evidence: cmd: disembark probe . --json twice, cmp — "DETERMINISTIC: byte-identical"
- ac-6 — MET_WITH_CONCERNS: A live git-only fixture grounds graveyard at (git, high) with only the git tier present, and TestProbeGraveyardFromGitAlone enforces it — but grounded status requires a revert: deletions alone yield partial (this repository itself scored partial), and the parenthetical's unmerged-branches and removed-dependencies signals live in the packer's archaeology layer, not the probe's grounding decision.
evidence: cmd: disembark probe <git-only fixture> — "tiers present: git … + graveyard grounded (git, high) / evidence: 1 files deleted (e.g. f.txt), 1 reverted commits"
evidence: internal/core/lifeboat/grounding_test.go:115 — "func TestProbeGraveyardFromGitAlone"
evidence: internal/core/lifeboat/sources_git.go:81-89 — "deletions without any revert are only partial evidence, not a grounded graveyard"
evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:118-120 — "only
partial (git, medium)on this repository (40 deletions, no reverts detected)" - ac-7 — MET: IngestLessons drops any lesson whose evidence refs resolve to no layer-1/2 finding id ("no valid evidence refs") and TestIngestLessonsCiteOrDropped asserts the uncited lesson is dropped while the cited one is written; the test ran green. evidence: internal/core/lifeboat/graveyard_lessons.go:116 — "drop("no valid evidence refs")" evidence: internal/core/lifeboat/graveyard_lessons_test.go:96 — "func TestIngestLessonsCiteOrDropped … Evidence: []string{"no-such-id"} … res.Dropped != 1" evidence: cmd: go test -run TestIngestLessonsCiteOrDropped ./internal/core/lifeboat/ — "--- PASS: TestIngestLessonsCiteOrDropped"
- ac-8 — MET_WITH_CONCERNS: One code path holds — Pack calls the same Plan the dry-run renders (pack.go:84) — and parity is test-enforced as a hash chain (dry-run manifest hash = ManifestSHA256(planned files) = provenance hash = independent re-hash of the written tree), all green; the caveats are that the shipped verbs are
plan/pack <repo> <dest>rather than the promiseddry-run/to <dest>, and the parity assertion spans TestPlanManifestReportsHashAndTotals plus TestPackProvenanceHashVerifies rather than one direct plan-vs-written-files comparison. evidence: internal/core/lifeboat/pack.go:84 — "lb, err := Plan(repoAbs)" evidence: internal/core/lifeboat/pack_test.go:96 — "func TestPackProvenanceHashVerifies … does not verify against the written tree" evidence: internal/core/lifeboat/plan_test.go:741-743 — "if m.ManifestSHA256 != ManifestSHA256(lb.Files) { t.Error("manifest hash disagrees with the file set")" evidence: internal/surface/cli/cli.go:387-388 — "Use: "plan [repo]" … without writing anything (dry run)"
Gap audit:
- honoured:
- Probe before pack, read-only and out-of-tree — reads a repo without touching it evidence: internal/core/lifeboat/probe_test.go:254 — "TestProbeLeavesEveryFileByteIdentical" evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:24-25 — "Both were byte-identical after probing"
- A blank is a first-class result: what was searched and the question a human must answer evidence: internal/core/lifeboat/coverage.go:112-121 — "searched: … / ? %s" evidence: cmd: disembark probe <git-only fixture> — "every one of 18 blanks carries searched + question"
- The cross-repo table answers what keeping a record is worth, in a number evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:39-42 — "grounds 21 of 23 … the two git-plus-conventions repositories ground 4 and 3"
- Stable, aggregatable coverage schema with schema_version, enforced at the aggregate
evidence: internal/core/lifeboat/coverage.go:16 — "SchemaVersion int
json:\"schema_version\"" evidence: internal/surface/cli/cli.go:369-375 — "missing schema_version … upgrade abcd" - Graveyard as a first-class section with a code-enforced cite-or-be-dropped validator evidence: internal/core/lifeboat/graveyard_lessons.go:116 — "drop("no valid evidence refs")"
- Packer built after the aggregate settled the section list evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:77-78 — "the packer is built to all 23 brief sections"
- diverged:
- Packer surface promised as
disembark <repo> to <dest>withdry-run; shipped asdisembark plan [repo]anddisembark pack <repo> <dest>evidence: .abcd/development/intents/shipped/itd-88-lifeboat-coverage-experiment.md:41 — "The packer (disembark <repo> to <dest>)" evidence: internal/surface/cli/cli.go:413 — "Use: "pack <repo> <dest>"" - Graveyard grounding is narrower than the four-signal promise: only reverts ground; deletions alone are partial; unmerged branches and removed dependencies feed the pack-path archaeology, not the probe's grounding evidence: internal/core/lifeboat/sources_git.go:81-89 — "deletions without any revert are only partial evidence" evidence: internal/core/lifeboat/graveyard_archaeology_test.go:146 — "TestArchUnmergedBranchesOrderedByDivergence"
- Press release headlines
/abcd:disembark probeand/abcd:disembark coverage; the markdown command surface documents only plan and pack — probe/coverage ship as CLI verbs only evidence: commands/abcd/disembark.md:4 — "argument-hint: "<source-repo> <dest> | plan <source-repo>"" evidence: internal/surface/cli/cli.go:306 — "Use: "probe [repo]"" - The recorded delta compares record-rich against git+conventions repos, not a strictly git-only repo; the corpus is two foreign repositories evidence: .abcd/development/research/notes/2026-07-26-itd-88-coverage-experiment.md:134-137 — "suggestive but not yet a trustworthy population — the finding here is a first reading"
- Packer surface promised as
- missing:
- Pass B ships as a declared exemption in
_provenance.json, never a silent gap — no exemption field or marker exists anywhere in the lifeboat package or the Provenance struct evidence: internal/core/lifeboat/plan.go:65-80 — "type Provenance struct { SchemaVersion … Omissions } — no exemption field; grep 'exemption' across internal/core/lifeboat/ returns nothing"
- Pass B ships as a declared exemption in
Frontmatter
| id | itd-88 |
|---|---|
| type | intent |
| lifecycle | shipped |
| kind | standalone |
| severity | major |
.abcd/development/intents/shipped/itd-88-lifeboat-coverage-experiment.md
open on GitHub ↗ · commit history ↗
Referenced by11
- adr-35The lifeboat is a coverage experiment — read-only, out-of-tree, and proven before it is packed (supersedes adr-4)related
- adr-36Coverage blanks are a fillable lifecycle — authored is not extracted, and the interview is its own steprelated
- iss-2610262032172837itd-88 calls the packer `disembark <repo> to <dest>`; the platform page calls it `disembark pack <source-repo> <dest>`related
- iss-2610262032178049The brief's press release says pack runs three passes, including targeted chat retrieval over transcripts; itd-88 says Pass B ships only as a declared exemptionrelated
- iss-2610262033191807itd-88 names the packer `disembark <repo> to <dest>`; 02-disembark makes bare disembark a read-only listing and packing the `pack` sub-verbrelated
- iss-2610262042208017itd-88 writes the packer as `disembark <repo> to <dest>`; the disembark entry writes it as `abcd disembark pack <source-repo> <dest>`.related
- iss-2610262043446144itd-142 takes brownfield coverage from embark probe; itd-88 ships the coverage report as disembark proberelated
- iss-2610262044466021itd-8 writes the lifeboat packer as `/abcd:disembark pack <repo> <path>`; shipped itd-88 writes it as `disembark <repo> to <dest>`related
- iss-2610262045089996itd-7 has disembark run dev-sync, which writes .abcd/rp/workspace.json into the repo; itd-88 says disembark never writes into the source repositoryrelated
- iss-2610262045214826The lifeboat packer is `disembark pack <repo> <path>` in itd-24 and `disembark <repo> to <dest>` in itd-88related
- spc-3lifeboat-coverage-experimentimplemented by
mentions24
- dcn-26071400000000012026-07-14 — The lifeboat is built as a COVERAGE EXPERIMENT, not a feature
- dcn-26072400000000052026-07-24 — Next-run queue reshaped by the grill: the small consequences
- dcn-26080300000000012026-08-03 — iss-42 (v0.5.0 item D): CONTEXT.md's sharp-edges list gains a detector rather than only a correction, because the correction alone would have been the third one. The stale trust caveat (still calling iss-35's brief-vs-surface reconciliation "the open cross-check" months after `surface_coverage` shipped and iss-122 pinned the Direction-A crosscheck) is an instance of a class: the orientation doc grounds a live claim in a record, the record reaches a terminal state, and nothing in the workflow asks anyone to go back. `context_citation_currency` is that missing requirement made mechanical — it resolves every `iss-N`/`itd-N`/`spc-N`/`adr-N` handle in the "Live constraints / sharp edges" section against its store and blocks a citation to a terminal bucket (or, for the flat ADR store, a declared supersession or retired status). Deliberately narrow on two axes: ONE section of ONE document, because a terminal-state citation is legitimate in an evidence trail, a supersession chain, and a dated plan — history is supposed to name closed records; and terminal-state only, because a dangling handle is `record_schema`'s question and a second weaker implementation of an answered check is worse than none. Rejected: a git-diff-shaped handoff rule ("a change to a cited record must touch CONTEXT.md in the same commit"), which the ledger entry's wording suggests but which gates the wrong thing — it fires on commits that need no orientation change and stays silent on the case that actually bit us, a record moved in one branch and the caveat left standing in another. The state-based check has no such blind spot: whenever the citation is stale, the gate is red, regardless of which commit made it so. Alongside: `research/` stops contradicting its own README (five dated notes move into `notes/`, where ~25 peers already sit, with every citation followed — the itd-88 fidelity evidence trail, two DECISIONS.md evidence paths, `.abcd/rules.json`, and a plan link), the development record map's routing row names `research/`'s real children (`notes/` + `prompting/`, not the phantom `spikes/`), and two banned_tokens entries make both stalenesses non-silent on reintroduction. The dated plan and the ratified ADR that also mention `spikes/` are left untouched: they are chronological snapshots and a ratified decision, not living indexes, and rewriting them to match today would falsify the record — `development/README.md` alone is corrected because it alone claims to be current.
- dcn-26082000000000082026-08-20 — Bug-hunt round 3 (hunt B), branch bughunt-b/round-3. Baseline
- iss-94The intent corpus still specifies the pre-adr-35 lifeboat model: itd-2, itd-8, itd-9, itd-10, itd-13, itd-15, itd-19, itd-22 and itd-24 variously use the retired 'disembark to home' signature, the in-tree .abcd/lifeboat/ home, or the in-tree .abcd/development/voyage/ path (itd-9's acceptance writes voyage provenance in-tree — the exact path that would fail abcd's own privacy-hygiene audit rule). The brief, glossary and roadmap were reconciled to adr-35; the intents were deliberately NOT rewritten, because an intent is a proposal with its own lifecycle and silently rewriting nine of them inside an unrelated change is worse than tracking the drift. Each reconciles when it is next planned.
- iss-136itd-88's fidelity gap audit found a missing press-release claim: Pass B is promised to ship as a declared exemption in _provenance.json, never a silent gap, but no exemption field or marker exists anywhere in the lifeboat package or the Provenance struct — a promise with no implementing code, recorded in itd-88's Audit Notes (receipt rcp-4d07032fc6ab)
- iss-137probe and coverage ship as CLI verbs only: the plugin markdown surface (commands/abcd/disembark.md) documents plan and pack alone, while itd-88's press release headlines /abcd:disembark probe and coverage — either the surface doc grows the two verbs or the intent's diverged claim is the accepted record (dispositioned in itd-88's Audit Notes)
- iss-388roadmap phases README states itd-88 is in planned/ and unscheduled, but the intent has shipped — a false bucket claim in present-tense current-state prose
- iss-2610262033033258itd-90 relies on embark to write the product thinker's answers into the target; embark writes only its record families and never writes anything else from the lifeboat.
- itd-1Every Intent Has Acceptance Criteria; Every Audit Verifies Them
- itd-7Lifeboats Carry RepoPrompt Workspace Definitions Forward
- itd-8Lifeboats Carry Source Code, Not Just Lessons
- itd-9Old Lifeboats Still Unpack
- itd-11Disembark Survives Noisy Transcripts
- itd-16`/abcd:audit` Is the Umbrella; Conversation/Edit Chain Is Its Default Application
- itd-21Start a New Project With abcd Conventions
- itd-23Lifeboats Speak To External Tools
- itd-35Lifeboats Carry Their Own Integrity Proof
- itd-85A Read-Only Repo-Conformance Audit
- itd-89Capture the Session You Just Had, Because You Cannot Capture It Later
- itd-90The Product Thinker Is Handed Exactly The Questions Only They Can Answer — And Nothing Else
- itd-94An intent that is not planned cannot be implemented: abcd gains a machine-checkable implement-readiness gate that refuses with a remedy and offers the planning interview
- itd-158itd-88's fidelity gap audit found a missing press-release claim: Pass B is promised to ship as a declared exemption in _provenance.json, never a silent gap, but no exemption field or marker exists anywhere in the lifeboat package or the Provenance struct — a promise with no implementing code, recorded in itd-88's Audit Notes (receipt rcp-4d07032fc6ab)
- spc-51provenance-lacks-pass-b-exemption-marker