docs(decisions): 0251 — fabrika pins shared wire formats, and owns their tests (#4892) - #5252
Conversation
No preview deploy
|
4621fc4 to
82f3707
Compare
|
review-doc: FAIL @ 82f3707 — changes-requested Reviewed-head: @ 82f3707 Verified PR #5252 against #4892's acceptance criteria + the doc-hygiene checklist. Read the PR head (§HEAD): every file under review was sourced from Classification — §CP by CONTENT (ADR 0164), not by path. The path axis is clean: a live CODEOWNERS read carries no Acceptance criteria (#4892)
The AC-3 failure, in detail
ADR 0251 Three problems, all checkable:
The net effect is the failure mode the criterion's "not left silently open" clause exists to prevent, and it leaves two live records disagreeing: a shipped skill contract says remedy (c) is moot, a shipped ADR says it is open pending #4712. Which one an agent obeys depends on which file it opens first. Remedy. Take remedy (c) as moot rather than deferred, and say why: #4712's Doc hygiene
ADR contradiction sweep (Step 4a)
Renumber + collision checks
Closing-keyword check (load-bearing)
Deviation disclosure (§DEV)
Routing note — this PR needs two more gates. Failing items above must be addressed before this PR can merge. The PR stays open and unmerged; #4892 stays open and assigned. Re-request review once they are satisfied. Note on authority: this PR is §CP by content (ADR 0164), so even a clean Verdict-written: 2026-08-10T02:42:55Z |
review-doc AC-3: the shipped plan-epic contract (#4712, b5465b6) already rules remedy (c) moot, and it handed the write-up to this ADR. Recording a deferral instead left the answer written nowhere and pointed at three closed issues. Verified at the owner module: detection is enrich.ts's whole-line-anchored MARKER_RE matched at its first occurrence, so no splicer anchor set reaches it.
82f3707 to
042fdee
Compare
|
review-doc: advisory — PASS (repair round 1 verified; prior FAIL discharged) Reviewed-head: @ 042fdee The prior FAIL, re-checked
Acceptance criteria
Deviations disclosure
ADR number 0251
Hygiene
Verdict: PASS (advisory). Merge authority is the |
|
review-skill: advisory — PASS Reviewed-head: @ 042fdee Round 0 posted only What changed in the behavioral artifactThe contract stops grounding a fabrika property in another package's line numbers, at four sites — this is AC-4's skill half and the ADR's first binding constraint applied to its own surface.
Residual citations — checked, all sanctioned
Skill hygiene
Nit, non-blocking: the L1190-1191 sentence wraps mid-clause ( Verdict: PASS (advisory). |
|
review-code: advisory — PASS Reviewed-head: @ 042fdee Why this namespace is required
Executable surface
Repo conventions
Verdict: PASS (advisory) — vacuous on executable surface, and the source claim the changed prose rests on is verified true at the owner module. |
fabrika's rule was "calls
pipeline-clinowhere". But the envelope fabrika writes on an epic and the splicer that plans that epic have to agree on the same bytes, and neither side can re-implement its way out of that. This records the founder-delegated ruling: fabrika owns those bytes as a wire format with a committed golden fixture, and the other side conforms by pinning that fixture in a test of its own. The rule, in one line, is re-implement calls, pin formats — and a test asserting a fabrika property lives in fabrika's package.The evidence that this was already costing something: fabrika's envelope grew a
<!-- fabrika:enriched … -->marker line under the #4866 ruling, and the copy of the envelope inside v1's test file — the one whose docblock says "byte for byte" — still has no marker. Nothing went red.Fixes #4892
What changed
.decisions/0251-shared-formats-are-pinned-not-reimplemented.md— the ruling. Extends ADR 0238 (which stands unchanged on calls) and ADR 0241 (whose ownership law this applies to a format whose second party sits outside fabrika). Names the sanctioned gate-deferral carve-out —pitch-guard,homing-guard,cp-classify— explicitly, so the ruled class is not caught by the new rule.claude-plugins/fabrika/README.md— the absent-list's "no dependency on v1" bullet now says what the calls rule does not cover.claude-plugins/fabrika/skills/triage/contract.md— four sites stopped grounding the envelope's survival inepic-splice.tsline numbers (one of which was already two lines stale) and now cite the ruling instead. The observed behaviour is unchanged; what changed is which side owes it.Against the issue's acceptance criteria
packages/fabrika-cli/; a test asserting v1's splicer preserves what it is handed stays with the splicer and reads fabrika's fixture.triage enrich(Implement the nine fabrika triage verbs specified by the /triage derived contract #4831) has landed, so ADR 0241's staging condition is already met and the slice is unblocked. It is filed as Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249 rather than half-built inside a decision PR.claude-plugins/fabrika/skills/plan-epic/contract.md, which rules the plan region is located by the enrichment marker and never by position, states remedy (c) is thereby moot, and hands the write-up to this ADR. Verified at the owner module rather than on the contract's word: detection isMARKER_REinpackages/fabrika-cli/src/triage/enrich.ts, a whole-line-anchored multiline pattern matched at its first occurrence, so no splicer anchor set can reach the answer.## Dependenciesheading inside the preserved brief makes a first-time plan truncate the epic body #4879 — untouched, and the ADR says why the two must not be merged.Deviations
fabrika wire indexreds on a narrative section naming no registered format — so a half-built format inside a decision PR would red CI and violate 0241's own shape rule. Disposition: follow-up Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249 filed and named in the ADR, the PR body and the progress comment.plan-epicwrites its plan. Disposition: deferred with Authoring brief: /plan-epic — fabrika skill (wave 2) #4712 named as decider, per the issue's own acceptance criterion; a Not decided here section in the ADR lists the two questions I left open and who settles them. (Superseded in repair round 1 — see below. Left standing as the log of what round 0 shipped.)origin/main, which had taken 0249 for0249-skill-trigger-coverage-lives-in-the-eval-set.md; then renumbered again to 0251, because open PR docs(decisions): 0250 — a fabrika hook whose verb cannot run fails open, loudly (#5079) #5250 — filed first and already at its gate — had taken 0250 while this lane was in flight. Why: two number collisions one step apart; the mid-flight recheck caught the first race but landed on a slot another open PR already held. Disposition: 0251 re-verified free immediately before the commit againstorigin/main(tops out at 0249) and against every open PR's.decisions/diff (only docs(decisions): 0250 — a fabrika hook whose verb cannot run fails open, loudly (#5079) #5250/0250, docs(decisions): 0237 — agent brevity binds messages, not board artifacts (#4694) #4703/0237, docs(decisions): ADR 0235 — a fence carries zero expansions; everything dynamic lives inside the script #4614/0235). Every in-repo reference was rewritten,decisions-index validatepasses, and the already-filed Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249 carries a further dated amendment comment pointing at 0251.claude-plugins/fabrika/docs/wire-formats.mdalone (class: declined an adjacent change). Said: a new format gets a narrative section there. Did: no edit. Why:fabrika wire indexreds on a section naming no registered format, and the registry row lands with Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249. That page's own staging-rule section already says an unwritten format is not a missing one. Disposition: rides Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249.triage/contract.mdspells the envelope out today. Why: there is no owner module to move it into until Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249 lands. Disposition: named in the ADR's Consequences and in Land the epic-envelope wire format: owner module, golden fixture, and the test split #5249's scope.reports/snapshot (grounding for the design session) #4890, riding map fabrika's skill set — live/die/merge/split over the 16 authoring briefs #4891." Did: took remedy (c) as moot and recorded why. Why:claude-plugins/fabrika/skills/plan-epic/contract.md— in this PR's own tree, landed onmaininb5465b6avia feat(fabrika): author the plan-epic skill and derive its ledger CLI contract #5178 — already rules remedy (c) moot and explicitly leaves the write-up to this ADR, so round 0 had two shipped records contradicting each other and the answer written nowhere. Authoring brief: /plan-epic — fabrika skill (wave 2) #4712 is closed (2026-08-09T21:50:05Z), and Land the 2026-08-07 fabrika skill-set audits as a datedreports/snapshot (grounding for the design session) #4890/fabrika's skill set — live/die/merge/split over the 16 authoring briefs #4891/Investigation: can fabrika's plan-epic preserve terminality and unify enrich's two detectors? #4896 are all closed too, so the "live" pointer named three closed issues. Disposition: the ADR's## Sequencingnow states the mootness, grounded at fabrika's own owner module (enrich.ts's whole-line-anchoredMARKER_RE, matched at first occurrence) rather than on the contract's word; the round-0 deviation entry above is marked superseded rather than rewritten.0250commit while the remote head was the0251commit — so this round reset the local ref to the pushed head82f3707abefore editing, then rebased onto latestorigin/mainper the repair contract. Why: rebasing the stale ref would have silently un-done the renumber. Disposition: the pushed head therefore differs from82f3707aby both the fix commit and a fresher base; the ADR file, its frontmatterid, its H1 and every in-repo reference still read 0251, andorigin/mainnow holds0250(from docs(decisions): 0250 — a fabrika hook whose verb cannot run fails open, loudly (#5079) #5250), so the slot is still uncontested.