Skip to content

docs(decisions): ADR 0241 — fabrika wire formats are owned by typed schema modules (#4946) - #4957

Merged
usirin merged 2 commits into
mainfrom
usirin/adr-wire-formats-schema-modules
Aug 8, 2026
Merged

docs(decisions): ADR 0241 — fabrika wire formats are owned by typed schema modules (#4946)#4957
usirin merged 2 commits into
mainfrom
usirin/adr-wire-formats-schema-modules

Conversation

@usirin

@usirin usirin commented Aug 8, 2026

Copy link
Copy Markdown
Member

Closes #4946.

Records the founder ruling on epic #4925 (option (b), staged) as ADR 0241 — fabrika wire formats are owned by typed schema modules, never by skill prose. This is a transcription of a decision already made first-hand, not a re-derivation.

What it records

  • The ownership law. A fabrika wire format — the byte-level agreement two skills meet through on a GitHub artifact — is owned by a typed schema module in fabrika-cli behind wire emit / read / check, registered as one row in one registry, never restated as shape in a skill body. One thin index doc carries protocol narrative (the why/when) and never the shape.
  • The total reading type as the property the ownership buys: every read answers Found / Absent / Malformed, and no code path may return a plausible empty value on drift.
  • The staging rule: the acceptance-criteria block and the verdict marker land before the review authoring session fires; every other format lands with its first consumer.
  • The verified gap, including the concrete bite that claude-plugins/fabrika/skills/triage/contract.md contains the string criteri zero times (re-verified on this base: count is 0).
  • The method lesson that seams are first-class audit objects, and why this gap survived two wayfinding sessions.

Grounding

The why is written from what actually shipped in the two landed stages rather than from intent, and each claim was verified in source:

  • --format help interpolates registeredKeys() in packages/fabrika-cli/src/wire/command.ts, so help cannot advertise a format the registry lacks; stage 2 added the verdict marker as one registry row with no verb-leaf change.
  • The refusal taxonomy in packages/fabrika-cli/src/wire/codes.ts keeps cannot see apart from saw nothing: distinct non-0/1/127 codes for proven-absent, malformed, empty stdin, and fd 0 unreadable (UNKNOWN); only found reaches stdout.
  • Invalid states are unrepresentable at the type level: WireFound<A> over NonEmptyReadonlyArray makes "found but empty" fail to typecheck, HeadSha is branded with no empty inhabitant, and bindToHead returns Current | Stale | Unbindable rather than a boolean — a verdict marker binds a head SHA (ADR 0058) and a stale marker is not a passing one.

Authoring checks

  • Number claim (ADR 0074 reservation lock): merged max 0239 (decisions-index next0240 against a freshly fetched origin/main), in-flight open-ADR-PR claims {0235, 0237, 0240} via gh api REST (exit 0), so max(union) + 1 = 0241. decisions-index validate passes.
  • Contradiction sweep: 8 lexically adjacent live-accepted ADRs shortlisted, each opened; none re-decides a question this ADR settles (0213 refines 0058's verdict upsert keying, which this ADR deliberately does not carry into the module). No supersede, no amend-in-part.
  • Purely additive: one file, .decisions/0241-wire-formats-owned-by-schema-modules.md. No index (ADR 0126/0129).
  • Vocabulary impact: the term wire format is coined here and recorded in ## Records as routed to .glossary/TERMS.md via a follow-up report — it needs the "not a serialization format, not a skill contract" disambiguation plus cross-links, which is fuller treatment than an inline row.

Deviations

Three judgement calls were made while authoring, each disclosed here rather than left implicit. All three were reviewed on merit and accepted by the review-doc gate; they are recorded, not re-argued.

  1. The ruled index doc does not exist yet. claude-plugins/fabrika/docs/wire-formats.md has not been written. The ADR states the index-doc law as part of the ruling without claiming the file has landed, leaving the write to a later child of epic fabrika wire formats: verb-owned schema modules + thin index doc (founder-ruled option b, staged) #4925. It is the one Decision paragraph deliberately left as a bare backticked path rather than a markdown link, so it creates no dead link.
  2. Only landed ADRs are cited; 0202 and 0164 are deliberately not cited in the body. This ADR neither relaxes nor amends a guard — 0164 governs how it is reviewed, not what it decides — and 0202 is a different domain. The §CP probe keys on guard vocabulary and fires here by design (fail-closed over-inclusion), which is not evidence the ADR touches a guard. Citing an unlanded ADR would also have failed the last acceptance criterion.
  3. Grounding cites files at origin/main HEAD, not the two stage squash SHAs. The house convention is resolvable repo-relative markdown links; a commit SHA resolves to nothing as a link and ages badly. Every grounded claim was verified against origin/main and is checkable exactly as written.

(repair round 1) Applied the verdict's one recommendation while the body was open: the Context claim that the mechanics are described from shipped code rather than from intent over-reached by exactly the index-doc paragraph, which is prescription. Narrowed with a half-clause and marked at the paragraph itself. No other change to the ADR, and the founder-ruled decision is untouched.

§CP

Re-derived, not assumed: cp-classify classify returns content-undetermined [content-source-present] (no path match, .decisions/** engages the ADR-0164 content axis), and guard-content-probe classify on the ADR body returns guard-touching (§CP, ADR 0164) [guard-vocabulary-match]. So this is control-plane — stopping at PR-open for a control-plane approval; not merging.

🤖 Generated with Claude Code

…chema modules (#4946)

Records the founder ruling on epic #4925 (option (b), staged): fabrika's
inter-skill wire formats live in typed schema modules in fabrika-cli behind
emit/read/check, never restated as shape in skill prose, plus one thin index
doc carrying protocol narrative only.

Grounded in shipped code — the `wire` verb group, the one-row-per-format
registry, the acceptance-criteria module, and the verdict-marker module that
landed as one row with no verb-leaf change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

No preview deploy

  • No preview deploy for this PR — its diff touches no deploy-relevant path, so no preview stack was minted and e2e is not applicable. (be2c5c7)
  • web — Stage pr-4957 torn down.

@usirin

usirin commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

review-doc: advisory — blocking-set PR (§CP — approval-gated) — NOT clean: 1 hygiene miss

PR #4957 is §CP by content, re-derived at the head rather than taken on trust:

  • pipeline-cli cp-classify classifycontent-undetermined [content-source-present] — no path matched, but 1 .decisions/** file engages the ADR-0164 content axis, so the tool refuses to call it ordinary.
  • pipeline-cli guard-content-probe classify on the ADR body at this head → guard-touching (§CP, ADR 0164) [guard-vocabulary-match].

My verdict is therefore advisory only: it does not authorize a merge, and it carries no first-line @ <sha> by design (ADR 0111) so it can never enter the ship-it auto-merge namespace. Under the §CP hard gate (ADR 0135) a @kamp-us/control-plane member approves at the current head and ship-it then enqueues (ADR 0048 single merge authority) — there is no hand-merge in the §CP path. The reviewed head is bound in the body line below (ADR 0151).

Reviewed-head: @ 1776d03

Class fan: pipeline-cli class-probe classify --namespacesreview-doc only (1 changed file, has-docs). No code, skills, or UI namespace is present, so review-doc is the complete required set.

Verified against #4946 acceptance criteria + the doc-hygiene checklist. Every file under review was sourced from the PR head via a per-run ref, never the launched checkout working copy (§HEAD).

Acceptance criteria

  • [PASS] New .decisions/NNNN-<slug>.md with valid frontmatter and status accepted.decisions/0241-wire-formats-owned-by-schema-modules.md lines 1–7 carry id: 0241 / title / status: accepted / date: 2026-08-08 / tags; pipeline-cli decisions-index validate passes over a .decisions set that includes this file (no duplicate or mismatched id).
  • [PASS] Records the ownership law — the bolded decision sentence (lines 48–50) states ownership by a typed schema module in fabrika-cli behind the wire group emit/read/check verbs, registered as one row in one registry, never restated as shape in a skill body; the thin index doc carrying protocol narrative and never the shape is lines 91–94.
  • [PASS] Records the total reading type as the property the ownership buys — lines 57–63: "The reading type is total, and that totality is the property the ownership buys", Found/Absent/Malformed, and the explicit "No code path may return a plausible empty value on drift".
  • [PASS] Records the staging rule — line 101: the acceptance-criteria block and the verdict marker land before the review authoring session fires; every other format lands with its first consumer. Restated as a Banned item (line 108, building formats ahead of their first consumer).
  • [PASS] States the verified gap including the criteri-zero-times bite — lines 27–33. Independently re-verified at origin/main: claude-plugins/fabrika/skills/triage/contract.md contains criteri exactly 0 times.
  • [PASS] Records the method lesson that seams are first-class audit objects — lines 123–127, including why the gap survived two wayfinding sessions (not per-skill, so the brief channel missed it; not per-incident, so the eval channel missed it).
  • [PASS] Relates to ADR 0238, cites only landed ADRs, no machine-local path — 0238 cited twice (lines 19, 109) with the relationship stated; 0092 and 0058 also cited. All three are present on origin/main. pipeline-cli leak-guard scan over the file: clean, 1 doc surface, 0 hits.

Substance — the load-bearing claims, checked against the source now on main, not against the PR own description

  • [PASS] A format is one registry row. packages/fabrika-cli/src/wire/registry.ts holds exactly the six-field rows the ADR names (key, purpose, producers, consumers, emit, read). The "adding VERDICT-MARKER changed no verb leaf" claim is verified against the actual file set of PR feat(fabrika-cli): the verdict-marker wire format, on the registry seam (#4943) #4955: registry.ts (+13/−3, one row), the new verdict-marker.ts, its unit test, verbs.unit.test.ts, and the package README — no emit-verb.ts / read-verb.ts / check-verb.ts / command.ts change. --format help interpolates registeredKeys() at packages/fabrika-cli/src/wire/command.ts:44, so help cannot advertise an unregistered format; resolveFormat refuses an unregistered key with ZERO_SCOPE rather than a vacuous pass (packages/fabrika-cli/src/wire/resolve-format.ts, citing ADR 0092).
  • [PASS] The refusal taxonomy keeps cannot-see apart from saw-nothing. packages/fabrika-cli/src/wire/codes.ts allocates ABSENT 3, MALFORMED 4, EMPTY_ARTIFACT 5, ARTIFACT_UNKNOWN 6, ZERO_SCOPE 7 (ADR 0092) and UNUSABLE_FIELDS 8 — all distinct and all outside 0/1/127, exactly as the ADR states, and the source comment gives the same reason the ADR gives: 1 is also a bad flag and a failed module load, so a proven outcome seated there is unreadable as proof. The read leaf description confirms found is the only outcome on stdout.
  • [PASS] Invalid states unrepresentable at the type level. packages/fabrika-cli/src/wire/format.ts defines WireRead<A> = WireFound<A> | WireAbsent | WireMalformed with Malformed carrying evidence, and WireReadLines instantiates Found over NonEmptyReadonlyArray. packages/fabrika-cli/src/wire/verdict-marker.ts has HeadSha branded with no empty inhabitant and bindToHead returning Current | Stale | Unbindable, the source stating the same rationale the ADR does — a comparison that could not be made is not a negative result.

Doc hygiene

  • [PASS] House-format — ADR frontmatter plus the house ## Context / ## Decision / ## Consequences shape, with the **What this decides:** line and a ## Records section.
  • [PASS] Index row + status match — purely additive, one file; no .decisions/index.md is committed, which is correct under ADR 0126/0129 where discovery is ambient from frontmatter. Frontmatter status: accepted is the source the ambient map renders.
  • [PASS] Links resolve — every relative markdown link target verified present on origin/main: the four .decisions/ targets, claude-plugins/kampus-pipeline/skills/gh-issue-intake-formats.md, the three claude-plugins/fabrika/docs/ contracts, the five packages/fabrika-cli/src/wire/*.ts modules, and .glossary/TERMS.md. Standard markdown relative paths throughout, no wikilinks, no placeholders. Issue links fabrika wire formats: verb-owned schema modules + thin index doc (founder-ruled option b, staged) #4925 and ADR: fabrika wire formats are owned by typed schema modules, never by skill prose #4946 both resolve.
  • [PASS] No leaked local/home paths — pipeline-cli leak-guard scan clean over the added file (1 doc surface, 0 hits).
  • [N/A] Supersession noted + cross-linked — this ADR supersedes and amends nothing, and the sweep below found nothing needing an amended-in-part by cross-link.
  • [PASS] Status sanity — accepted is coherent: the ruling was made first-hand by the founder on epic fabrika wire formats: verb-owned schema modules + thin index doc (founder-ruled option b, staged) #4925 and both stages it describes have already landed.
  • [PASS] Single Diátaxis mode — single-mode: explanation. The Binding-constraints and Banned lists are normative law inside the explanation, not a procedure, so no type-mixing.
  • [PASS] Clear, concise prose — active voice, concrete, no AI-tell density. Em-dash use sits within the house register, and the isolated negative-parallelism turn ("verified, not hypothetical") is not a sustained pattern.
  • [PASS] ADR number integrity — re-derived, not trusted. origin/main max is 0239; in-flight open-PR claims are {0235, 0237, 0240} (PR docs(decisions): ADR 0235 — a fence carries zero expansions; everything dynamic lives inside the script #46140235, PR docs(decisions): 0237 — agent brevity binds messages, not board artifacts (#4694) #47030237, PR refactor(web): migrate Phoenix to Manti UI #44330240), so max(union) + 1 = 0241. No collision. decisions-index validate passes with the file included.
  • [PASS] ADR contradiction sweep — 3 questions enumerated (who owns the byte shape of a wire format; what a read may return; how a new format lands). 197 uncited live-accepted ADRs swept; the 8-entry shortlist (0236, 0229, 0054, 0230, 0073, 0160, 0213, 0239) was opened one by one. None re-decides a question this ADR settles: 0229 (relay-only combination) is reinforced by keeping the judgement halves in the skills; 0213 refines verdict-upsert keying, a different question from the byte shape of the marker; the rest are adjacent domains. Semantic pass done by hand, since the sweep detects lexical and tag adjacency only.
  • [FAIL] deviation-disclosure — the PR body carries no ## Deviations heading. §DEV is explicit that absent is not None.: on a PR that owes the section, a body with no heading is malformed, because the gate cannot tell "nothing to disclose" from "never considered it". This PR owes it — neither [N/A] shape applies, since the issueless carve-out did not fire (there is a linked issue with a full AC checklist) and this is a pipeline-authored PR, not a bot or hand-authored one. The sibling open ADR PRs docs(decisions): ADR 0235 — a fence carries zero expansions; everything dynamic lives inside the script #4614 and docs(decisions): 0237 — agent brevity binds messages, not board artifacts (#4694) #4703 both carry the section, so this is the lane own norm, not a novel bar.

Overall: advisory FAIL — one hygiene miss, body-only. The ADR file itself is clean; I found nothing in the diff to change for correctness. Please do not approve at this head. The fix touches the PR description only.

The fix. Add a ## Deviations section to the PR body. Most of the content already exists under "Authoring checks" — the contradiction sweep cleared by hand, and the vocabulary-impact term routed by a follow-up report rather than an inline .glossary/TERMS.md row — it is simply not under the heading the contract keys on. Once the heading lands, re-request review and this becomes an advisory PASS.

On the three disclosed judgement calls.

  1. The index doc claude-plugins/fabrika/docs/wire-formats.md does not exist yet — I judge the framing honest, with one recommendation. The paragraph reads as prescription, not description ("with about a paragraph of protocol narrative each", "It never carries the shape"), it is restated as a binding constraint, and it is the only Decision paragraph deliberately left as a bare backticked path rather than a markdown link, so it creates no dead link. It sits in ## Decision, which is where an ADR states law, including law about work not yet done — the staging rule immediately below does the same. Recommendation, not a gate FAIL: the Context claim that "Both stage-1 slices have landed, so the mechanics below are described from shipped code rather than from intent" (line 44) over-reaches by exactly this one paragraph, which is intent. A half-clause noting the index doc is still owed to a later child would close that gap at no cost — worth folding in while the body is open.
  2. Citing only landed ADRs and not citing 0202 or 0164 — correct as made. This ADR neither relaxes nor amends a guard, so 0164 governs how it is reviewed, not what it decides. The §CP probe fired on guard vocabulary; that is the probe being deliberately over-inclusive and fail-closed, not evidence the ADR touches a guard. 0202 is a different domain. Citing an unlanded ADR would also have failed the last acceptance criterion.
  3. Grounding in files at origin/main rather than the two squash SHAs — correct as made. The house convention is resolvable repo-relative markdown links; a commit SHA resolves to nothing as a link and ages badly. I re-verified every grounded claim against origin/main today, so the grounding is checkable exactly as written.

One forward-looking note, no action needed here. HeadSha having no empty inhabitant makes a SHA-less verdict marker unrepresentable in the fabrika format. In v1 the §CP advisory line is SHA-less by design (ADR 0111) — this comment is an instance of exactly that shape. Under ADR 0238 fabrika re-implements rather than calls v1, so there is no contradiction with anything live; but whoever authors the fabrika review skill will meet the question of whether fabrika needs an advisory shape of its own.

review-doc does not merge, and this verdict authorizes nothing — it is advice for the control-plane approver.

Verdict-written: 2026-08-08T22:18:21Z

…4946)

The Context line claimed the mechanics are described from shipped code rather
than from intent; the index-doc paragraph is prescription, so the claim
over-reached by exactly one paragraph. Narrow it with a half-clause and mark
the paragraph itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@usirin

usirin commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

review-doc: advisory — blocking-set PR (§CP — approval-gated)

PR #4957 is §CP by content (ADR 0164). Re-derived at this head, not inherited: cp-classify classify returns content-undetermined [content-source-present] (no path matched; 1 .decisions/** file engages the ADR-0164 content axis), and guard-content-probe classify on the ADR body at the head returns guard-touching. My verdict is advisory only: it does not authorize a merge. Under the §CP hard gate (ADR 0135), a @kamp-us/control-plane member approves this at its current head and ship-it then enqueues it (ADR 0048 single merge authority) — there is no human hand-merge in the §CP path.

Reviewed-head: @ be2c5c7

Round 2 (re-gate after repair). The round-1 advisory bound to 1776d032 is stale under ADR 0058 and was not inherited — every criterion and every hygiene check below was re-run fresh against be2c5c7. Repair delta confirmed as scoped: +5/−4, two spots, one file, no restructuring. Scope unchanged — one file, purely additive, .decisions/0241-wire-formats-owned-by-schema-modules.md (+134/−0).

The round-1 FAIL is discharged. deviation-disclosure was the single miss (## Deviations absent; §DEV: absent is not None.). The section is now present with three disclosures — the index doc not yet existing, citing only landed ADRs (0202/0164 deliberately omitted), and grounding at origin/main rather than squash SHAs — each recorded as accepted on merit, not silently reversed and not re-argued, plus a dated repair-round note. Deviation 1's own claim checks out: claude-plugins/fabrika/docs/wire-formats.md is the one Decision-paragraph path left as bare backticks rather than a link, so it creates no dead link.

The substantive ADR edit — judged on its own new claim. The Context line's over-reach was narrowed to "…described from shipped code rather than from intent — with one exception, marked where it appears: the index doc is prescription, still owed to a later child." That half-clause creates an obligation, so I enumerated every place the index doc appears in the ADR rather than accepting the marking on the author's word — 4 sites: L44 (the exception statement itself), L92, L103, L121.

  • L92 is the only site that describes the index doc as a mechanic, and it carries the marking — "claude-plugins/fabrika/docs/wire-formats.md — not yet written, owed to a later child — maps format → owner module → …".
  • L103 and L121 are not in the mechanics register and so fall outside what the Context sentence scopes. L103 is a Binding constraint ("The index doc carries protocol narrative only."), a list where every sibling row is likewise prescriptive ("A new format lands as…", "Every read is total:…", "Staging: … land before…"). L121 is a Consequence under Harder, a section that is prospective by house convention.

Verdict on the edit: the sentence is not false in a new way. The fix for over-claiming did not introduce its own over-claim. One non-blocking observation, offered as taste and not as a finding: L121's "The index doc is a standing temptation" is present-tense about a file that does not exist yet; a tightening to "will be" would remove the last residue. It does not make the Context claim false and is not worth a round.

Verified against #4946's acceptance criteria + doc hygiene — all checks pass:

Acceptance criteria (7/7)

  • [PASS] New .decisions/NNNN-<slug>.md, valid frontmatter, status accepted, /adr-shaped — L1–7: id: 0241, title, status: accepted, date: 2026-08-08, tags: [fabrika, pipeline, cli, contracts]. Number re-verified non-colliding at this head: merged max on freshly fetched origin/main is 0239; open-PR claims enumerated via REST are {0166, 0235, 0237, 0240} (PRs refactor(web): migrate Phoenix to Manti UI #4433/docs(decisions): ADR 0235 — a fence carries zero expansions; everything dynamic lives inside the script #4614/docs(decisions): 0237 — agent brevity binds messages, not board artifacts (#4694) #4703); 0241 is claimed by this PR alone. decisions-index validate exits 0.
  • [PASS] Records the ownership law — L49–51 states it as the bolded Decision (typed schema module in fabrika-cli, exposed through wire emit/read/check, one row in one registry, never restated as shape in a skill body); L92–95 carries the one thin index doc as narrative-only; L106 bans restating shape in prose.
  • [PASS] Records the total reading type as the property ownership buys — L58–64: "The reading type is total, and that totality is the property the ownership buys", with "No code path may return a plausible empty value on drift" stated explicitly. Grounded: packages/fabrika-cli/src/wire/format.ts defines WireRead<A> = WireFound<A> | WireAbsent | WireMalformed under the comment "Exactly three answers."
  • [PASS] Records the staging rule — L102, verbatim to the criterion: the acceptance-criteria block and the verdict marker land before the review authoring session fires; every other format lands with its first consumer.
  • [PASS] States the verified gap incl. the criteri bite — L27–33. Re-verified against origin/main: claude-plugins/fabrika/skills/triage/contract.md contains criteri 0 times.
  • [PASS] Records the method lesson — L124–128: seams must be first-class audit objects, with the reason the gap survived two wayfinding sessions (not per-skill, so the brief channel missed it; not per-incident, so the eval channel missed it).
  • [PASS] Relates to 0238, cites only landed ADRs, no machine-local path — 0238 cited at L19 and L110. Cited ADR set is {0058, 0092, 0238}; all three resolve on origin/main. Added-lines leak scan exits 0.

Doc hygiene

  • [PASS] House-format — frontmatter plus ## Context / ## Decision / ## Consequences, with a ## Records tail; reads as a decision record, not a how-to.
  • [PASS] Index row + status match — no .decisions/index.md in the diff, which is correct and not a miss (ADR 0126/0129, ambient discovery); frontmatter status: accepted is the source the ambient map renders.
  • [PASS] Links resolve — all 13 relative targets resolve on origin/main (5 under packages/fabrika-cli/src/wire/, 3 fabrika docs, the v1 formats contract, .glossary/TERMS.md, and ADRs 0058/0092/0238). Standard markdown relative paths; no wikilinks, no placeholders.
  • [PASS] No leaked local/home paths — added-lines scan by the shared matcher exits 0; a separate leak-guard scan-comment over the PR body is also clean. Repo-relative paths only throughout.
  • [PASS] Supersession noted + cross-linked — n/a. Purely additive; the ADR claims no supersede or amend-in-part, and the sweep found none owed.
  • [PASS] Status sanity — accepted is coherent: the ADR transcribes a ruling already made first-hand (founder, epic fabrika wire formats: verb-owned schema modules + thin index doc (founder-ruled option b, staged) #4925), so proposed would misstate its standing.
  • [PASS] Single Diátaxis mode — single-mode: explanation. Understanding-oriented end to end; the Binding constraints / Banned lists state the decision's own scope rather than opening a second reference page.
  • [PASS] Clear, concise prose — active voice, concrete, claims carry their evidence ("verified, not hypothetical"). No AI-tell density; the em-dash register is the house form here, not slop.
  • [PASS] ADR contradiction sweep — 3 questions enumerated (where a wire format's shape lives; what a read may return on drift; how a new format lands). 197 uncited live-accepted ADRs swept; the 8-entry shortlist (0236, 0229, 0054, 0230, 0073, 0160, 0239, 0213) was opened in full. None re-decides a question this ADR settles. 0229 is the nearest — its UNKNOWN-propagation floor agrees with this ADR's "cannot read is ARTIFACT_UNKNOWN, never ABSENT" rather than conflicting. 0213 keys the verdict upsert, a judgement half this ADR deliberately leaves in the skills. Semantic pass done by hand; no amend-in-part owed.
  • [PASS] deviation-disclosure (§DEV) — ## Deviations present with three disclosed judgement calls plus the repair-round note. Each is disclosed as accepted on merit; none is an undisclosed departure this gate could see.

Specialist fan-out (ADR 0079) — 0 blocking findings

  • claim-vs-ground-truth — every falsifiable claim re-checked against source on freshly fetched origin/main, not accepted from the body:
    • One registry row per format, no verb-leaf change — packages/fabrika-cli/src/wire/registry.ts holds registeredFormats with exactly the rows acceptance-criteria and verdict-marker. The stage-2 commit that added the verdict marker touched only registry.ts, verdict-marker.ts and two test files; every verb leaf (emit-verb.ts, read-verb.ts, check-verb.ts, formats-verb.ts, command.ts) is untouched. The ADR's "changed no verb leaf — one module plus one row" is exact.
    • The refusal taxonomy — wire/codes.ts allocates ABSENT=3, MALFORMED=4, EMPTY_ARTIFACT=5, ARTIFACT_UNKNOWN=6, ZERO_SCOPE=7, UNUSABLE_FIELDS=8, none of them 0/1/127, matching the ADR one-for-one. The wire read help states that found is the only outcome on stdout.
    • The type-level guarantees — WireFound<A> with WireReadLines = WireRead<NonEmptyReadonlyArray<string>> in format.ts; HeadSha branded with no empty inhabitant and bindToHead returning Current | Stale | Unbindable in verdict-marker.ts. All three hold as written.
    • --format help interpolates registeredKeys() in wire/command.ts; formats derives its listing from registeredFormats; resolveFormat refuses an unregistered key with ZERO_SCOPE. All three hold.
  • dangling-reference — none. The one non-existent path, claude-plugins/fabrika/docs/wire-formats.md, is deliberately a bare backticked path rather than a link, and is now marked as owed.
  • omitted-case — none blocking. The "marked where it appears" obligation was enumerated site-by-site above and holds.

The founder ruling on epic #4925 is recorded, not re-litigated — I judged faithful transcription and grounding, not the decision itself.

Read the PR head (§HEAD): every file under review was sourced from be2c5c700267bccbc88e0fdbd45503468730cbc4 through a per-run ref, never the launched checkout's working copy and never by switching any working tree (§RO). materialize-head.sh ran clean here — defect #4591 did not reproduce.

review-doc does not merge, and this advisory does not authorize a merge. It is the §CP advisory form (ADR 0111/0151): the first-line marker carries no @ <sha> by design, so it never enters ship-it's auto-merge namespace, and the reviewed head is bound in the Reviewed-head: line above. A control-plane approval at this head is what unblocks it; ship-it then enqueues.

Verdict-written: 2026-08-08T22:35:08Z

@usirin

usirin commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

BANKED — §CP, awaiting a control-plane approval at the current head

This PR is reviewed-ready and blocked only on a human approval. The execution engine does not merge it and will not hand-merge it.

State, verified first-party:

  • head be2c5c700267bccbc88e0fdbd45503468730cbc4, mergeable_state: clean
  • §CP by content, not by pathcp-classify classifycontent-undetermined [content-source-present] (no path matched; one .decisions/** file engages the ADR-0164 content axis, and the tool refuses to call that ordinary), then guard-content-probe classify on the ADR body at head → guard-touching. Re-derived at this head by the gate, and independently by me.
  • Verdict: review-doc: advisory — blocking-set PR (§CP — approval-gated), all checks pass, reviewed head bound in the body via Reviewed-head: @ be2c5c70…. Advisory is the required form here (ADR 0111/0151) — a bindable first-line PASS @ <sha> would drop a control-plane verdict into ship-it's auto-merge namespace, so its absence is correct, not missing.

What is owed: a @kamp-us/control-plane member approves at this head. Under ADR 0135 the human owns the judgement and the pipeline owns the mechanics — so once the approval lands, ship-it enqueues (ADR 0048 single merge authority). There is no human hand-merge in the §CP path.

If the head moves, the approval dies with it (ADR 0058) — a rebase or a new push past be2c5c70 invalidates both this advisory and any approval bound to it, and the lane needs a re-gate plus a re-approval. Nothing here should be pushed to while it waits.


This PR was not clean on the first pass. Round 1 returned advisory — NOT clean: 7/7 acceptance criteria PASS with one hygiene miss — [FAIL] deviation-disclosure, the body had no ## Deviations section, which §DEV treats as malformed because absent is not None. Repaired in round 1 by disclosing three judgement calls the gate had already accepted on merit, plus folding in the gate's own recommendation: the ADR's Context line claimed the mechanics are "described from shipped code rather than from intent", which over-reached by exactly the index-doc paragraph (that paragraph is prescription — claude-plugins/fabrika/docs/wire-formats.md is still owed to a later child of #4925). The re-gate then enumerated all four sites the index doc appears at and confirmed the new "marked where it appears" clause is not false in a new way.

Worth recording, because it nearly cost this PR its repair: the machine repair-picker read this round as a clean no-op (CODE_FAIL=0 DOC_FAIL=0 SKILL_FAIL=0 VERDICT_UNKNOWN=0) while a real [FAIL] row sat in the posted verdict — §CP advisories carry no blocking-FAIL polarity by design, so the FAIL was invisible to it. The repair happened only because it was dispatched by hand off the verdict body. That gap is already tracked as #4105 (CP Verdict Integrity campaign), now carrying this PR as its first observed-in-production instance.

@usirin usirin added the ready-for:human A human picks this up. label Aug 8, 2026
@usirin
usirin requested a review from cansirin August 8, 2026 22:37
@usirin
usirin added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit de829a2 Aug 8, 2026
46 checks passed
@usirin
usirin deleted the usirin/adr-wire-formats-schema-modules branch August 8, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for:human A human picks this up.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ADR: fabrika wire formats are owned by typed schema modules, never by skill prose

3 participants