docs(decisions): 0248 — the authoring session mints a contract's implementation ticket at handoff (#4749) - #5235
Conversation
…ementation ticket at handoff (#4749) The spec-to-build seam had no owner: a landed fabrika contract.md specifies verbs nobody has built, and an open issue is the only route into the build pool, so both early instances (#4725, #4748) got a ticket only because an agent happened to look. Records the founder ruling: the authoring session files the implementation ticket as part of its handoff, the handoff names its number, and review-skill lists it as a gate criterion scoped to fabrika contract PRs (out of scope = PASS with evidence, unreadable file list = fail, ADR 0092). Nothing mints a ticket by machine. Fixes #4749
No preview deploy
|
|
review-skill: advisory — blocking-set PR (§CP — approval-gated) Reviewed-head: @ f8d56d6 Verified PR #5235 against #4749's acceptance criteria + the skill-rigor checklist. Graded against the newest ruling on #4749 (2026-08-10T00:12:17Z — authoring session mints at handoff, Skill-class files under review (3): Acceptance criteria
Skill rigor
The self-gating question: does the
|
| Invariant | State after the diff |
|---|---|
| "a rigor FAIL fails the gate… conjunctive across both lists" | Untouched — not in the diff. Check 5 inherits it, so a check-5 FAIL fails the gate. |
| Rigor checks 1–4 bodies | Byte-identical. Zero - lines fall inside checks 1–4; the only deletion in that region is the list-header sentence. |
| Zero-scope disposition | Fail-closed, correct. Unreadable file list = UNKNOWN = fails (ADR 0092), with the anti-pattern named explicitly. Out-of-scope PASS is evidence-bearing, not silent. |
Marker contract (@ <sha>, namespace, upsert key, never-merges, advisory arm) |
Untouched — the description's marker sentence and §VERDICT are unchanged. |
| ADR 0073's four behavioral failures | Preserved as four, correctly. Line 518 still reads "the four behavioral failures ADR 0073 enumerated" — that is the 0073 failure taxonomy, a different list from the now-five checks. The coder did not over-apply the count edit here, which is the right call. |
All 7 deletions in this file are count phrasing ("the four rigor checks" → "the rigor checks") or the two sentences the new clause extends. Nothing normative was softened: author-skill's "Write to satisfy all four up front" → "Write to satisfy them up front" now binds five, not four.
The one place a count survives that I checked closely — line 21, "You exist to check those four" — is accurate: it refers to the four ADR 0073 concerns enumerated in the sentence immediately above it, not to the rigor-check count.
Residual nit (non-blocking, no repair asked). In the brief-contract's field 6, the new clause says "review-skill lists this as a criterion" three paragraphs after the same field says "nothing waits on fabrika's own /review-skill". Two different things share a name there. ADR 0248's "whichever skill is the live skill-class gate" bullet resolves it, so a reader who follows the link is not misled.
Two claims I verified rather than accepted
Scope claim — check 5 is genuinely scoped, not a fifth universal check. Confirmed in the text: "Scope this check off the PR's changed-file list", with an explicit Out of scope branch. Confirmed too that leaving packages/fabrika-cli/src/eval/corpus.ts untouched was correct, not an omission: its SKILL_RIGOR_CHECKS closed vocabulary is keyed to a different rubric (claude-plugins/fabrika/skills/review/rubrics/skill.md) whose fourth member is fabrika-conventions, not gate-invariant-preservation, and whose docblock already excludes a fifth candidate on purpose per ADR 0243 §1a. Editing it would have been the defect.
ADR number 0248 is unclaimed. origin/main tops out at 0246. I enumerated the .decisions/ files of every open PR: #5230 → 0247, #4703 → 0237, #4614 → 0235; #5233, #5231, #4833, #3941 add none. No collision.
Advisory only — three files sit under /claude-plugins/kampus-pipeline/skills/, owned by @kamp-us/control-plane in live CODEOWNERS. This authorizes nothing on its first line; a control-plane approval at head is what merges it.
|
review-doc: advisory — blocking-set PR (§CP — approval-gated) Reviewed-head: @ f8d56d6 Verified PR #5235's prose surface against #4749's acceptance criteria + doc hygiene. Doc text sourced read-only from Doc-class file under review (1): Acceptance criteria
Doc hygiene
ADR number 0248 is unclaimed — Closing keywords — the body's closing set is exactly Advisory only — this PR is §CP (three files under |
|
review-code: advisory — blocking-set PR (§CP — approval-gated) Reviewed-head: @ f8d56d6 Verified PR #5235 against #4749's acceptance criteria. Files sourced read-only from Why this namespace is required — the no-class fail-closed rule (#2765). I ran
File under review (1): Acceptance criteria
Correctness / hygiene
The 16 deleted lines — confirmed line-level rewrites, nothing load-bearing dropped. I enumerated every
No rule, no fence, no invariant and no cross-reference was removed. Diff shape matches independently: 5 files, +197/−16, 1 added / 4 modified, no file deletions. Closing keywords — closing set is exactly Advisory only — this PR is §CP (three files under |
Fixes #4749
Records the founder ruling on the spec-to-build seam (issue comment 2026-08-10T00:12:17Z, which supersedes the earlier 2026-08-02 comment's CI-guard shape) and writes it into the two in-repo surfaces that carry it.
The decision
The authoring session mints a fabrika contract's implementation ticket, as part of its handoff, and
review-skillchecks it exists.review-skillrigor criterion, scoped to a PR that adds or changes aclaude-plugins/fabrika/skills/*/contract.md: the ticket must exist, be open, be named in the PR body or handoff, and route to these verbs.Fixes #<brief>does not satisfy it — that closes the brief, which is a done-signal, not the hand-off.contract.mdis out of scope and records PASS with that evidence; an unreadable file list is UNKNOWN and fails, never "no contract touched."Rejected on the record: minting implementation children on the epic up front (amends #4650's ruled briefs-only plan, and drops unassigned children into the coder pool), and leaving it to ambient noticing (the gap itself).
Why the teeth are a gate criterion, not a new CI job
A grep-shaped CI guard answers "does the body contain an issue number" — satisfiable by the brief's own
Fixes #<brief>line. The question that matters is "does an open ticket route to these verbs", which is a semantic read.review-skillalready opens the PR, its linked issues and the contract text, and already did exactly this informally on thefront-doorPR (#5216). One listed criterion beats a second job that re-derives a weaker answer and drifts.Acceptance criteria
.decisions/0248-authoring-session-mints-the-implementation-ticket.md(actor, moment, and what enforces it)adr(Implement packages/fabrika-cli — the sixadrverbs from the wave-0 pilot's derived contract #4725) andreport(Implement the three /report fabrika verbs — the merged contract has no implementation ticket #4748) are both closed; the rule is retroactively satisfied and applies at authoring time onlyFiles
.decisions/0248-authoring-session-mints-the-implementation-ticket.mdclaude-plugins/fabrika/docs/authoring-brief-contract.mdclaude-plugins/kampus-pipeline/skills/review-skill/SKILL.mdclaude-plugins/kampus-pipeline/skills/author-skill/SKILL.mdclaude-plugins/kampus-pipeline/skills/write-code/SKILL.mdThree of the five are under
claude-plugins/kampus-pipeline/skills/, so this PR is §CP and needs a@kamp-us/control-planeapproval at head beforeship-itcan enqueue it. No CODEOWNERS row was added or widened, and nothing underclaude-plugins/fabrika/skills/was touched.Checks run locally
validate-skills.sh— OK, 30 skills validpipeline-cli decisions-index validate— no duplicate or mismatched id (0247 is claimed by open PR docs(fabrika): specify adr sweep's ranking and add the derivable-example rule (#4735) #5230; 0248 re-checked free againstorigin/mainand every open PR immediately before commit)pipeline-cli gh-phoenix lint-skillson the three edited skills — clean