Development record
abcd lab mechanises the lab conventions three hand-run experiments proved
Press Release
abcd labmints, preflights, records, sweeps and harvests a lab, and the procedure the labs converged on becomes a discipline record."Three labs, and by the third the procedure returned SHIP with zero findings, because every amendment had been written down and the scaffolding had been rebuilt by hand each time," said a technical facilitator reading the capstone. "Now the verb builds the scaffolding, the procedure is a record, and no rule can be forgotten under pressure."
Why This Matters
Between 31 August and 1 September eight labs ran under ~/.abcd/lab/, three of them the core series; the capstone's series review shows review churn falling from four rounds with three application failures to one round to SHIP as the procedure accumulated amendments, and a draft intent for the verb family was written as evidence and never filed. The recording model (evidence at operator level, knowledge through ceremony, pointers in the local tier) held across the runs. Ruled 2026-09-21: file it from the capstone's text; the four product findings the series left unfiled are captured on the same branch.
Mechanism
We expect a mechanised lab to reproduce the third lab's SHIP on its first run, because the variable that moved across the series was the procedure and the procedure is what the verb encodes; shown wrong if a lab run under the verb needs more review rounds than lab 3 did.
Scope Conditions
- Holds on a machine whose lab store is
~/.abcd/lab/keyed as the other machine-scoped stores are; the repository never holds lab evidence. - Holds while a real-session smoke stage is available: offline suites passed while the plugin was unloadable by the host.
What's In Scope
- The verb family
abcd lab mint | preflight | record | sweep | harvest: the home minted with its registry entry and snapshot pin; the preflight artefact (harness isolation, dual-binary vintage); probe-record scaffolding; the retraction sweep (grep the pattern, not the instance); harvest assembly against the lifeboat's section shape. - The procedure as a discipline record: the amendments across the three chains, present tense, host-agnostic.
- The recording model as the recorded convention: evidence at
~/.abcd/lab/, knowledge through ceremony, pointers in the local tier; the never-in-repo rules. - Halt-and-record on a gate refusal as a lab rule the verb enforces.
- No cost claim: the series could not measure token cost; the verb records what the runner reports and claims nothing more.
What's Out of Scope
- Auto-merge for lab filings.
- Labs as a grouping of the record.
- A next-labs runner; the menu stays a note.
Decisions
Ruled by the product thinker on 2026-09-21, in the interview that filed and planned this intent (adr-2609212115255771 records the vocabulary rulings it rests on):
- Filed from the capstone's draft with its ten evidence items (ruled 2026-09-21).
- Auto-merge for lab-derived work stays out; a lab's findings are captured and drained like any other.
Open Questions
None open.
Acceptance Criteria
- Given
abcd lab mint <question>, when it runs, then a lab home exists under the machine-scoped lab store with a registry entry, the snapshot pin and the lifecycle's sections scaffolded, and nothing is written into the repository. - Given
abcd lab preflight, when it runs, then the harness-isolation and dual-binary checks are written as an artefact, and a failed check halts the lab naming it. - Given a lab's corrections, when
abcd lab sweepruns, then every instance of a retracted pattern is listed and an unapplied correction fails the sweep. - Given a finished lab, when
abcd lab harvestruns, then the harvest is assembled in the lifeboat's section shape with the probe records cited, and its product findings are listed as capture candidates. - Given a gate refusal during a lab, when it occurs, then the lab halts and records it as a finding rather than adapting around it.
- Given the discipline record, when it is read, then it carries the procedure's amendments in present tense, host-agnostic.
Typed Links
- built on by
itd-2610161733316518(one feature built across a model matrix): Runs the matrix as a lab, adding a model pin beside the commit and binary pins a lab already records.
Audit Notes
Fidelity review — receipt rcp-2e848c471a09 (verifier intent-auditor claude-fable-5-1).
Provenance: intent-auditor@claude-fable-5-1 · rubric_hash sha256:effa65b3e9e88ff29433b443ec2be159522a8b0b71cf1434526514aa61edb13e · prompt_hash sha256:db1fb13e6920b3bc6ba25cd8ce987662648bdc1d6cf5ce1ea5f9c67bc4bbbd82 Input attestations: diff:internal/core/lab, internal/surface/cli/lab.go, commands/lab.md and intents/disciplines/itd-2609251624540864 at chore/audit-run-a-1 5b4a43b6 (git ls-tree -r; spc-2609212141418943 closed, itd-2609212137128014 shipped)@sha256:fba4544c04fa39af51fde0aabe9789398732117e51dee5531efbca65bc59499d;
Acceptance rollup: MET 5 · MET_WITH_CONCERNS 1 · NOT_MET 0 · INCONCLUSIVE 0
Per-criterion verdicts:
- ac-1 — MET: Mint lays the lab home under ~/.abcd/lab/< root-sha>/ with one registry line, a detached snapshot at the pin, INTENTION.md carrying snapshot_pin and the lifecycle sections; the test asserts the registry line, the snapshot HEAD equals the pin, no remote, and git status --porcelain --ignored of the repository is empty afterwards evidence: internal/core/lab/lab.go:9 — "// ~/.abcd/lab/< root-sha>/index.jsonl one registry line per lab" evidence: internal/core/lab/mint.go:35 — "func Mint(repoRoot, question, pin string) (Minted, error) {" evidence: internal/core/lab/mint.go:107 — "if _, err := gitutil.Run(snap, "checkout", "--quiet", "--detach", e.Pin); err != nil {" evidence: internal/core/lab/lab_test.go:106 — "func TestMintLaysDownALabAndWritesNothingInTheRepo(t *testing.T) {" evidence: internal/core/lab/lab_test.go:147 — "if got := r.Git("status", "--porcelain", "--ignored"); got != "" {"
- ac-2 — MET: Preflight runs the harness-isolation checks (home, snapshot, remotes, hooks) and the dual-binary checks (work, pinned, test), writes state/preflight.md and .json, and on any failure halts with ErrHalted naming the failed check ids and recording a gate finding; the test asserts the halt names binary.work, the artefact records both groups, and Record refuses while halted evidence: internal/core/lab/preflight.go:31 — "GroupIsolation = "harness-isolation"" evidence: internal/core/lab/preflight.go:68 — "func Preflight(repoRoot, id string) (Preflighted, error) {" evidence: internal/core/lab/preflight.go:128 — "return res, fmt.Errorf("%w: the preflight refused %s; recorded as %s in %s", ErrHalted, strings.Join(failed, ", "), fid, l.display(findingsName))" evidence: internal/core/lab/lab_test.go:234 — "func TestPreflightHaltsNamingTheFailedCheckAndRecordsIt(t *testing.T) {"
- ac-3 — MET: Sweep searches every retracted literal across the lab's own documents, lists every instance by file and line, and an unapplied or unreadable correction fails the sweep with a halt; the test plants two retractions and asserts the instances in findings.md and review-1-triage.md are listed while probe stdout and the snapshot are not, and the sweep halts evidence: internal/core/lab/sweep.go:109 — "// Sweep verifies every correction the lab recorded is applied: each retracted" evidence: internal/core/lab/sweep.go:118 — "func Sweep(repoRoot, id string) (Swept, error) {" evidence: internal/core/lab/lab_test.go:505 — "func TestSweepListsEveryInstanceAndFailsOnAnUnappliedCorrection(t *testing.T) {"
- ac-4 — MET: Harvest assembles the lifeboat's sections from the intention, the findings and the probe records, refuses and writes nothing on a finding no record backs, and lists each product finding as a capture candidate carrying the abcd capture command; the tests cover the assembled shape with probe citations and the refusal evidence: internal/core/lab/harvest.go:65 — "func Harvest(repoRoot, id string) (Harvested, error) {" evidence: internal/core/lab/harvest.go:127 — "Command: "abcd capture " + shellQuote(f.Title) + " --found-during " + shellQuote(found)," evidence: internal/core/lab/harvest.go:135 — "return res, fmt.Errorf("%w: %d finding citation(s) cannot be verified from the lab's records; nothing was written", ErrHalted, len(res.Gaps))" evidence: internal/core/lab/lab_test.go:661 — "func TestHarvestAssemblesTheLifeboatShapeCitingProbes(t *testing.T) {" evidence: internal/core/lab/lab_test.go:733 — "func TestHarvestRefusesAFindingItsRecordsCannotBackAndWritesNothing(t *testing.T) {"
- ac-5 — MET_WITH_CONCERNS: haltAndRecord writes a gate finding and marks the lab halted so no probe is recorded until the gate passes, and a repeated refusal reuses its finding; the concern is reach: the verb enforces this for its own two gates (preflight, sweep) and the harvest's citation gaps only, while a refusal by the world's own gates during the mutate stage or a STOP condition is the discipline record's rule with nothing mechanical behind it, since the verb runs nothing inside the snapshot evidence: internal/core/lab/findings.go:145 — "// haltAndRecord is the lab rule a gate refusal enforces: the refusal is written" evidence: internal/core/lab/findings.go:137 — "for _, g := range []string{"preflight", "sweep"} {" evidence: internal/core/lab/lab_test.go:272 — "// Halted, the lab records no probe: the refusal is not adapted around." evidence: .abcd/development/intents/disciplines/itd-2609251624540864-a-lab-runs-one-procedure-from-intention.md:172 — "- Given a gate refusal or a STOP condition during a lab, when it occurs," evidence: commands/lab.md:60 — "The verb runs nothing:"
- ac-6 — MET: the discipline record itd-2609251624540864 states the six-stage procedure in present tense as the rule every lab inherits, with the amendments the hand-run labs earned folded in and a BDD gate section; no agent-harness name appears in it evidence: .abcd/development/intents/disciplines/itd-2609251624540864-a-lab-runs-one-procedure-from-intention.md:5 — "kind: discipline" evidence: .abcd/development/intents/disciplines/itd-2609251624540864-a-lab-runs-one-procedure-from-intention.md:20 — "A lab is a throwaway world pinned at one commit, run to answer one question. It" evidence: .abcd/development/intents/disciplines/itd-2609251624540864-a-lab-runs-one-procedure-from-intention.md:164 — "## The gate"
Gap audit:
- honoured:
- the five-verb family is wired on the CLI and the plugin page evidence: internal/surface/cli/lab.go:60 — "Use: "mint < question>"," evidence: internal/surface/cli/lab.go:200 — "Use: "harvest < lab-id>"," evidence: commands/lab.md:28 — ""${CLAUDE_PLUGIN_ROOT}/abcd" lab mint --json "< question>""
- no lab verb writes into the repository; evidence stays at operator level evidence: internal/core/lab/lab_test.go:147 — "if got := r.Git("status", "--porcelain", "--ignored"); got != "" {" evidence: commands/lab.md:11 — "**no lab verb writes into"
- the procedure is a discipline record evidence: .abcd/development/intents/disciplines/itd-2609251624540864-a-lab-runs-one-procedure-from-intention.md:16 — "# A lab runs one procedure from intention to discard"
- diverged:
- halt-and-record on a gate refusal as a lab rule the verb enforces evidence: internal/core/lab/findings.go:137 — "for _, g := range []string{"preflight", "sweep"} {" evidence: commands/lab.md:60 — "The verb runs nothing:"
- missing: (none)
Scope-condition dispositions:
- cond-2609212141418357 — survived: the store is ~/.abcd/lab/< root-sha>/ keyed on the root commit like the other machine-scoped stores, and the mint test proves the repository top level and status are untouched evidence: internal/core/lab/lab.go:6 — "// The store is machine-scoped and keyed on the repository's root commit, the way" evidence: internal/core/lab/lab.go:49 — "const storeRelPath = ".abcd/lab"" evidence: internal/core/lab/lab_test.go:152 — "t.Errorf("repository top level changed: %d entries before, %d after", len(before), len(after))"
- cond-2609212141414079 — untested: nothing in the lab package runs or checks a real-session smoke stage; the only mention is a fixture finding title in the harvest test
Grounds
- pursued: three hand-run labs proved the procedure and paid for its scaffolding three times; we expect the verb to reproduce lab 3's SHIP on the first mechanised run; shown wrong if it needs more review rounds than lab 3 did
Frontmatter
| id | itd-2609212137128014 |
|---|---|
| type | intent |
| lifecycle | shipped |
| kind | standalone |
| severity | minor |
.abcd/development/intents/shipped/itd-2609212137128014-abcd-lab-mechanises-the-lab-conventions.md
open on GitHub ↗ · commit history ↗
References4
- adr-2609212115255771Phases and milestones are retired: sequencing is dependencies rendered as status, the checkpoint is the derived releaserelated
- itd-22abcd Reaches Any Harness Through an Adaptorbuilds on
- itd-59Every Autonomous Run Pass Leaves the Same Durable, Queryable Transcript an Interactive Session Doesrelated
- itd-75abcd Proves Your CLI Actually Runs — From Fixtures You Drop Inrelated
Referenced by7
- iss-2610262032094044Invariant 21 names abcd's home `~/.abcd.noindex`; itd-2609212137128014 records lab evidence at `~/.abcd/lab/`.related
- iss-2610262045316034itd-2609212137128014 records lab evidence at ~/.abcd/lab/; itd-2610030720038073 renames the home the lab lives inrelated
- itd-2609221009495079abcd's typed judgements can run through a decision adapter, measured in a lab before it decides anythingbuilt on by
- itd-2609251624540864A lab runs one procedure from intention to discardbuilt on by
- itd-2610040822131032A lab runs end to end from a question the product thinker asksbuilt on by
- itd-2610161733316518One task done across a model matrix, re-runnablybuilt on by
- spc-2609212141418943abcd-lab-mechanises-the-lab-conventions-three-hand-runimplemented by
mentions3
- dcn-26092100000000012026-09-21 — Phases and milestones are retired, and the word roadmap with them (product thinker, at an interactive interview after an independent research pass; adr-2609212115255771 supersedes adr-9). Sequencing is dependencies plus the lifecycle shelves, rendered as a Now / Next / Later status block on the `abcd` board and the site (itd-2609212103568351), never stored; the checkpoint is the derived release plus each intent's acceptance criteria, with an optional `target_release` the cut reports and moves forward (itd-2609212103572513); the unit below a spec is the step, a section not a family (itd-2609212103565953); an issue carries no spec by design; the batch is the run's internal order; one page maps the families (itd-2609211913453478). itd-24 becomes release retrospectives; itd-34 drops its phase rule. Same interview: `build` is the verb a person types and `implement` the loop (itd-2609201916151817 decision 8), the loop takes an issue key (decision 10), only the loop writes a verdict (decision 9); the person's command list is grouped with an agents block behind `--agent` (itd-146), every verb opens with a does/writes/refuses sentence (itd-2609212113220149), modes become flags and five checks one lint (itd-2609212130136102, breaking); the status-line badge is guarded and reset (itd-2609212130146198); a new capture or draft is matched and linked at filing, never refused (itd-2609212137116617); abcd's text names the product thinker or the technical facilitator and never the maintainer (itd-2609212137129937, captured for the run, no sweep today); the lab conventions become `abcd lab` (itd-2609212137128014); a managed repository's site goes live by one verb behind a provider seam (itd-2609061543533170).
- dcn-26092600000000042026-09-26 — The lab store is keyed `~/.abcd/lab/<root-sha>/<lab-id>/`, with one `index.jsonl` registry per root-sha lane beside the lab homes (lane implementer, autonomous run A, on review-lab's third finding against spc-2609212141418943 for itd-2609212137128014). This supersedes two recorded texts: the spec's literal `~/.abcd/lab/<lab-id>/` (scope item 1), and the 2026-08-31 lab-convention entry's hand-run keying `~/.abcd/lab/<timestamp>-<source-sha7>/` with a single top-level `~/.abcd/lab/index.jsonl`, whose stated divergence from root-sha keying is withdrawn. Why: the intent's scope condition keys the store "as the other machine-scoped stores are", and the worktree and transcript stores key on the repository's root commit, because a checkout moves, is renamed and is cloned twice on one machine while its root commit does none of that; a lab's identity is still its intention, carried by its id `lab-<yymmddHHMMSS>-<pin7>` (the UTC mint time and the pin), so several labs share one baseline inside one lane. The hand-run labs that predate the verb stay where they are, beside the root-sha lanes, and the verb neither reads nor writes them or the top-level registry, so no real lab is moved or migrated by the change. A later text naming `~/.abcd/lab/<lab-id>/` (the open spc-2609221011151661's `pairs.jsonl` among them) means the lab home inside its root-sha lane.
- iss-2609261457366568itd-2609212137128014 ac-5 promises halt-and-record on a gate refusal during a lab as a rule the verb enforces; the verb enforces it only for its own preflight and sweep gates and the harvest's citation gaps, while a refusal by the world's own gates during the mutate stage or a STOP condition is the discipline's rule with nothing mechanical behind it