Skip to content

feat(fabrika-cli): publish the ruled KEEP corpus as an enumeration (#4823) - #4837

Merged
usirin merged 2 commits into
mainfrom
usirin/publish-ruled-keep-corpus-4823-3CD86FC3
Aug 3, 2026
Merged

feat(fabrika-cli): publish the ruled KEEP corpus as an enumeration (#4823)#4837
usirin merged 2 commits into
mainfrom
usirin/publish-ruled-keep-corpus-4823-3CD86FC3

Conversation

@usirin

@usirin usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member

The list of incidents that make up fabrika's eval feedstock was ruled in #4642 but never written down, so anyone who needed it re-ran a two-artifact join by hand — and the size that got published, 74, matched no derivation anyone could reproduce. This PR commits the list next to the corpus it feeds, along with the derivation that produced it, and adds fabrika eval keeps to read it.

The corrected figure is 66 members plus one pending row. #4180 is that pending row: the #4642 ruling retracted its sweep verdict and never replaced it, so it is carried explicitly rather than silently included or dropped.

Part of #4823.

What changed

  • packages/fabrika-cli/src/eval/incident-corpus/ruled-keeps.json — the enumeration. Each row carries the issue number and title, its #NNNN | VERDICT | reason row from the Investigation: sweep the 222 open pipeline issues — which encode real incidents worth preserving as eval cases #4634 sweep table, which sweep section it came from, whether it is one of the 7 borderline items, and a dated snapshot of its board state. A derivation block records the recipe, the three source comments, and the arithmetic.
  • packages/fabrika-cli/src/eval/ruled-keeps.ts — the decoder + integrity rules + the coverage join.
  • packages/fabrika-cli/src/eval/command.tsfabrika eval keeps <path> [--provenance <path>] [--json].
  • packages/fabrika-cli/src/eval/incident-corpus/README.md — points a case author at the enumeration instead of the hand-run join, and publishes 66 instead of 74.
  • Two test files: ruled-keeps.unit.test.ts (the pure core) and ruled-keeps.data.unit.test.ts (the committed data + the README).

Two design calls worth flagging

Coverage is derived, never stored. The ticket asks each row to carry "whether a case in provenance.json already pins it". That is computed at read time by withCoverage, joining the two files — there is no committed pinned field. A stored copy would be a second source of truth that drifts silently from the ledger, which is exactly the defect class (#4482) the enumeration exists to remove. The emitted enumeration carries the column; the file does not store it.

Board state is a dated snapshot, not a claim of currency. Milestone and state move under a committed file. The field is named snapshot, carries its own at date, and the README does not ask anyone to trust it as live.

Both are disclosed as class-1 departures under ## Deviations below.

How the 66 was derived

Both derivations were run mechanically over the two artifacts and land on the same 66 issues:

Step Figure
#4634 sweep rows 222 (80 KEEP-AS-EVAL, 138 KILL-CANDIDATE, 4 UNSURE)
Derivation A — 80 KEEP rows minus the 14 that appear in the 153-issue kill list 66
Derivation B — 80 KEEP rows minus the 14 crew-layer re-buckets 66
A and B name the same issue set yes

74 double-counts: the 7 borderline (#4338 #3330 #4285 #4163 #4145 #3945 #3709) all carry KEEP-AS-EVAL rows and none is among the 14 re-buckets, so they were inside the KEEP set already and were added a second time. The 67 they were added to was itself computed from the sweep's stated 81 rather than the 80 rows that exist.

Observed output

$ fabrika eval keeps src/eval/incident-corpus/ruled-keeps.json
fabrika eval feedstock — the ruled KEEP corpus of #4642 — 66 member(s) plus 1 pending, derived 2026-08-03.
  7 borderline · 7 pinned by a committed case · 59 uncovered.

  #2118 [no case] KEEP-AS-EVAL — non-hermetic deployed-worker smoke drift evicted 4 unrelated approved §CP PRs
  ...
  #3594 [pinned by case 12] KEEP-AS-EVAL — 2/2 coders addressed initial Write/Edit to primary-checkout absolute paths
  ...
  #4180 [PENDING · no case] KILL-CANDIDATE — error-attribution polish sliver; the incident evidence is folded into #3943/#4162
      pending: #4642 ruling, EXCLUDED / HELD: “**#4180** — **table correction**: chunk E returned 31 verdicts by count (18 KEEP / 13 KILL) but its #4180 row was dropped in transit, and the merged table above wrongly reconstructed it as KILL; arithmetic implies it was the 18th KEEP. Held for one direct read at execution time; the merged table's #4180 row is hereby retracted.” …
  ...
EXIT=0

--json emits the same rows with a summary block (members: 66, pending: 1, borderline: 7, covered: 7, uncovered: 59) and each row's pinnedBy case ids. A missing path exits 1 with a named reason.

Acceptance criteria

AC5 — deferred by this lane, then discharged off-lane

This lane could not post the #4642 comment itself. The mis-attribution guard refused the write, and a guard refusal is not overridable by reasoning:

$ step3_5-claim-is-mine.sh 4642
{"issue":4642,"mine":false,"reason":"no-winner","winner":null,"superseded":[]}
claim: #4642: no authorized claim resolves — NOT mine, back off (default-deny, never a false win).
GUARD-EXIT=1

This lane's dispatch pre-authorized #4823 only; #4642 was never named, so the refusal was correct and the dispatch was at fault. The arithmetic the comment owed was committed here in ruled-keeps.json's derivation.arithmetic regardless.

The comment has since been posted: 5162555158 on #4642 at 2026-08-03T05:13:36Z, appended not edited, with the same arithmetic. The follow-up that tracked the deferral, #4836, was consequently closed not_planned — it was filed 78 minutes after the work it described had already landed. Nothing about AC5 is outstanding, and #4836 is not an open follow-up.

Part of #4823 rather than Fixes still stands, for a different reason: triage separately filed #4838 for three stale "74-issue KEEP corpus" strings in provenance.json that this diff does not touch and #4823's ACs never named. #4823 must stay open past this merge until #4838 lands.

Deviations

Verification

  • pnpm vitest run in packages/fabrika-cli — 39 files, 532 tests, all passing.
  • pnpm typecheck — 30/30 tasks successful.
  • pnpm lint:worktree — clean.
  • pipeline-cli cp-classify classifynot-control-plane [path-clear-no-content-source] … Proven ordinary.

The README assertions were written before the README was changed and observed failing against it (3 failures: the two-ways instruction, the 74 KEEP string, the missing ruled-keeps.json pointer). The member-verdict integrity rule was temporarily removed from ruledKeepsViolations to confirm its test reds rather than passing vacuously.

Not touched

packages/fabrika-cli/package.json is unchanged — @kampus/fabrika-cli@0.1.0 is published and PR #4833 already proposes 0.1.1. No collision with the release train.

This PR does not touch PR #4832 (/triage skill) or anything under its surface; the two diffs are disjoint.

@github-actions

github-actions Bot commented Aug 3, 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. (6be4e4f)
  • web — Stage pr-4837 torn down.

@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Scope note from the intake desk — not a review verdict, and not a change request.

Triage of #4836 ran a propagation sweep on the corrected KEEP-corpus size and found one surface the
correction has not reached, in the directory this PR already touches.

packages/fabrika-cli/src/eval/incident-corpus/provenance.json carries three verification strings
(cases id 15, 16, 17 — pinning #4285 / #4163 / #4338) that still read
"...named in that ruling's fold into the 74-issue KEEP corpus." The 74 is the double-counted
figure; it is the same stale number this PR corrects in
packages/fabrika-cli/src/eval/incident-corpus/README.md.

It fell through rather than being declined: this PR's file list does not include provenance.json,
and #4823's acceptance criteria name only the README and the #4642 ruling comment.

Filed and triaged as #4838 (type:chore, p2, fabrika campaign) so it cannot be lost. It is a
three-string edit, not a re-derivation.

Suggestion, entirely the author's call: if this PR is still open when you read this, folding the
three strings in here is cheaper than a second PR into the same directory. If it has moved on, #4838
stands on its own and needs nothing from this lane.

@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

review-code: PASS @ aa30e00 — merge-ready

Re-gate of PR #4837 against #4823 after repair round 1. The head is deliberately unchanged — the repair was a PR-body-only edit (PATCH .../pulls/4837, body updated_at 2026-08-03T07:00:32Z), no push, no fabricated empty commit. So this verdict lands at the same SHA the prior review-code: FAIL was bound to, and pipeline-cli verdict post upserted it in place on that comment (5163227992) rather than appending — the (PR, gate, head, run) upsert key resolved to the same record (ADR 0058 rule 2 / ADR 0213). This PASS therefore supersedes and replaces that FAIL, which no longer stands at this head. For the record it is replacing: round 1 carried exactly one blocking row — deviation-disclosure (§DEV), the body's missing ## Deviations section — plus one non-blocking accuracy note about a stale AC5 narrative citing #4836. Both are cleared below.

Everything substantive in round 1 already passed there — the 66 re-derived to an exact set match, the schema-key handling, the non-vacuous guards, the CLI run — and none of it was re-derived here; this pass confirms the two body obligations, re-confirms that nothing in the diff moved, and re-confirms CI + run-evidence at the same head.

The blocking row — now cleared

  • [PASS] deviation-disclosure (§DEV) — the body now carries a ## Deviations section, anchored <a id="deviations"></a>, positioned between the acceptance-criteria section and ## Verification, with three class-1 scope-narrowing entries, each in full Said / Did / Why / Disposition shape:
    1. The Part of #4823 partial-split. §DEV names this case specifically — "don't let the token stand in for the reasoning" — and the reasoning is present, not just the token: Said names Fixes #N as the default; Did states the body says Part of #4823 so the merge does not close the issue; Why gives the substantive ground (triage filed provenance.json still publishes the discredited 74 as the KEEP-corpus size — the one place the 74→66 correction did not reach #4838 for three stale "74-issue KEEP corpus" strings in provenance.json, a surface this diff does not touch and Publish the ruled fabrika eval corpus as an enumeration — membership is derivable but never written down, and the published size (74) is wrong #4823's ACs never named, so auto-closing would close an issue with real work left); Disposition names the filed follow-up and that no ADR is owed. This is the disclosure §DEV asks for, not a token restatement.
    2. Coverage derived from provenance.json at read time rather than committed as a flag. Said quotes AC1's "whether a case in provenance.json already pins it"; Did states no coverage field is committed and withCoverage joins the ledger, emitting pinnedBy; Why cites the The 'check runs, exits clean, observed the wrong surface' defect class has no citable home — artifacts cite a closed, narrower instance #4482 second-source-of-truth class; Disposition records no action needed. Consistent with the prior gate's independent judgement that this is the stronger design, not a shortcut.
    3. Board state as a dated snapshot. Said quotes the Scope's "current milestone and state"; Did states each row carries a snapshot object with its own at date; Why gives the real ground — a committed file physically cannot hold a "current" value, and AC1 never lists milestone/state, so the field sits above the AC floor; Disposition records it as an acceptable deviation, not an apology. Correctly framed.
  • [PASS] "Two design calls worth flagging" no longer the sole home for that reasoning — it now closes with "Both are disclosed as class-1 departures under ## Deviations below", and the anchor it links resolves to the <a id="deviations"></a> target in the same body. The narrative section is now a pointer into the canonical section rather than a substitute for it.

The accuracy note — now corrected, and independently verified

Each claim in the rewritten AC5 narrative was checked against the API, not read off the body:

Claim in the body Verified
AC5 discharged by comment 5162555158 on #4642, 2026-08-03T05:13:36Z GET /issues/comments/5162555158issue_url ends /issues/4642, created_at 2026-08-03T05:13:36Z, author usirin
appended, not edited the comment opens ## Amendment (2026-08-02, triage of #4823) … and its first prose line is **Appended, not edited.**
#4836 is closed not_planned, no longer cited as an open follow-up state: closed, state_reason: not_planned, created_at 06:31:03Z, closed_at 06:38:42Z — filed 77m27s after the 05:13:36Z work it described
#4838 is the reason #4823 stays open past this merge state: open, state_reason: null, title names provenance.json still publishes the discredited 74 — genuinely open, and its surface is untouched by this diff
the guard refusal on this lane was correct the body keeps that record intact: the dispatch pre-authorized #4823 only, #4642 was never named, "the refusal was correct and the dispatch was at fault". Kept as honesty, not re-litigated.

AC5's checkbox now reads [x] … **discharged** and attributes the discharge to that comment. No stale "deferred / filed as #4836" narrative survives anywhere in the body, and #4836 appears only as an explicitly-closed record.

Nothing in the diff moved

  • Changed-file set identical to the prior round — 6 files, unchanged: src/eval/command.ts, src/eval/incident-corpus/README.md, src/eval/incident-corpus/ruled-keeps.json, src/eval/ruled-keeps.data.unit.test.ts, src/eval/ruled-keeps.ts, src/eval/ruled-keeps.unit.test.ts (all under packages/fabrika-cli/). changed_files: 6, commits: 1, +1615/-11.
  • packages/fabrika-cli/package.json is still absent from the diff — the published-immutable-version constraint and Release PR chore: release main #4833 (chore: release main, still OPEN) are untouched.
  • PR feat(fabrika): the /triage skill and its derived CLI contract (#4706) #4832 (feat(fabrika): the /triage skill …) is still OPEN and its surface is disjoint from these 6 paths — not touched.
  • Timeline carries one committed event (2026-08-03T06:28:21Z) and no head_ref_force_pushed — the head is provably the same tree the prior gate read.

Part of #4823 unchanged and still correct

The linking line is Part of #4823. — it has not become Fixes. The two other occurrences of the word are prose describing the token choice (the default token is Fixes #NandPart of #4823rather thanFixes``); neither is a closing keyword bound to an issue number, so no auto-close linkage exists. Correct: #4838 leaves real work on #4823 past this merge.

Standing gate rows (re-confirmed at this head)

  • unresolved-threads: not applicableunresolved-threads-read.sh ran and returned no threads (§ZS: the read fired). The unaccounted unresolved review thread CI check is green at this head. Row omitted.
  • comment-discipline — no code line changed since the prior round's scan, which found the added comments load-bearing under the deslop-comments rubric. Not re-derived.
  • glossary-freshness: not applicable — no new feature folder / public package / public export; detector expressible on base. Row omitted.
  • flag-gating: not applicablePublish the ruled fabrika eval corpus as an enumeration — membership is derivable but never written down, and the published size (74) is wrong #4823 carries no **Containment:** marker. Row omitted.
  • session-caching gate: not applicable — no new session-caching path. Row omitted.

Evidence at head

Run-evidence bundle: PRESENT for head aa30e00c — producer run 30790515962, artifact 8846944201, manifest.commit == head, schemaVersion 1; checks 2/2 pass; tests 2420/2420 passed, 0 failed, 0 skipped. Independently re-read via pipeline-cli run-evidence read --pr 4837 (state present, reason validated), not carried over from the prior verdict.

Head CI at aa30e00c: green — 46 check-runs, 0 failing, 0 running, 0 wedged (ci-required success; lint / format / typecheck, unit + client tests, packages unit tests, CodeQL all success; the e2e/integration/deploy contexts skipped by change-detection).

Classification, re-run independently rather than inherited:

  • pipeline-cli class-probe classify --namespaces6 changed file(s) → has-codereview-code, one required namespace. No apps/web/src/ path, so review-design is not required and is not emitted.
  • pipeline-cli cp-classify classifynot-control-plane [path-clear-no-content-source] (exit 3) — "no path matched the live CONTROL_PLANE_RE and no .decisions/** file is present … Proven ordinary." Non-blocking, so this verdict is a binding PASS @ <sha>, not a §CP advisory.

One nit, not blocking

The body (and the prior verdict) says the #4642 comment "open[s] **Appended, not edited.**". Strictly it opens with the ## Amendment (2026-08-02, triage of #4823) heading, and **Appended, not edited.** is the first prose line under it. The substance — appended, not edited, same arithmetic — is exactly right; the wording is a hair loose. Not worth a round-trip.


Verdict: PASS — merge-ready at aa30e00cbaa939f5b58b31c96144fb93929b1f1d. Every acceptance criterion of #4823 is satisfied, the single blocking §DEV row from round 1 is cleared with an honest three-entry ## Deviations section, and the AC5 narrative now matches the verifiable record.

review-code does not merge. ship-it is the single authorized merge step (ADR 0048). Note for the shipper: this PR carries Part of #4823, not Fixes — merging it will not close #4823, which is correct and deliberate; #4823 stays open until #4838 lands.

Read the PR head (§HEAD): the head was pinned via REST and reached read-only through a per-run ref — no working tree was switched, reset, or checked out, and nothing under review was edited.

Verdict-written: 2026-08-03T07:07:52Z

@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Repair round 1 — body-only, head unchanged at aa30e00cbaa939f5b58b31c96144fb93929b1f1d.

Addressing the FAIL at #4837 (comment):

No file in the diff was touched and nothing was re-verified, per the verdict. The head SHA has deliberately not moved — no empty commit was pushed to force one, since the verdict at this head passed every substantive row.

Re-requesting review at the same head.

@usirin
usirin added this pull request to the merge queue Aug 3, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 3, 2026
@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

ship-it: merge-queue ejection detected — PR #4837 was enqueued but the queue dropped it without merging (still open, no longer queued, not merged). Likely a textual conflict on the batch ref or a combined-batch CI failure (ADR 0132; GitHub "Managing a merge queue"). Routing back to repair/re-queue — this is NOT a shipped state.

@usirin
usirin added this pull request to the merge queue Aug 3, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 3, 2026
@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

ship-it: merge-queue ejection detected — PR #4837 was enqueued but the queue dropped it without merging (still open, no longer queued, not merged). Routing back to repair/re-queue — this is NOT a shipped state.

This was the second ejection, and unlike the first it has an identified cause: a combined-batch CI failure (a semantic conflict, exactly what the queue exists to catch — ADR 0132), not a batch textual conflict and not a queue timeout.

Timeline (issue timeline events, no paired merged on either):

  • added_to_merge_queue 07:12:15Zremoved_from_merge_queue 07:18:14Z (attempt 1)
  • added_to_merge_queue 07:23:20Zremoved_from_merge_queue 07:29:50Z (attempt 2)

Cause, on the batch ref gh-readonly-queue/main/pr-4837-89195133…: the CI workflow concluded failure — job packages unit tests:

FAIL packages/fabrika-cli/src/excess-operand.unit.test.ts
  > every registered leaf verb declares the excess-operand catch-all
  > `fabrika eval keeps` binds its trailing operands
AssertionError: expected 'path' to be 'excess'

Why the PR head is green and the batch is not. packages/fabrika-cli/src/excess-operand.unit.test.ts landed on main at 07:05:05Z in 89195133 — "fix(fabrika-cli): refuse an operand a leaf verb never declared (#4828) (#4839)". This PR's own head CI ran at 06:32:04Z, before that guard existed. The new leaf verb this PR adds, fabrika eval keeps <path>, does not declare the excess-operand catch-all the newly-landed guard now requires of every registered leaf verb — so the PR is green alone and red combined with current main. No file in this PR's diff conflicts textually; mergeable_state still reads clean.

The fix is on the branch, not in the queue: give fabrika eval keeps the excess-operand catch-all binding (excess, not path) that #4839's guard requires, then re-review at the new head and re-ship. ship-it did not re-enqueue (a bare re-enqueue would loop on the same failing batch), and left no armed merge intent (guard 6, ADR 0198: INTENT_UNCLEARED=0).

On the first ejection. Its batch ref showed integration tests still in_progress and three guard checks cancelled at removal time with nothing failed, which read as a queue-side drop. In light of attempt 2 the more likely reading is that attempt 1 was the same batch-CI failure caught mid-flight and the surviving check states were the post-cancel residue. The queue's own entry state is GraphQL-only and this org bans GraphQL, so the queue's authoritative removal reason is not readable from here — that reading is inference from the batch-ref check runs, not a quoted queue reason.

usirin and others added 2 commits August 3, 2026 00:35
…4823)

The fabrika eval feedstock was ruled into existence in #4642 but never written
down, so every consumer re-ran a two-artifact join by hand — and the size that
was published (74) matched no derivation. Commit the list.

`incident-corpus/ruled-keeps.json` carries the 66 members plus #4180 as an
explicitly pending row, each with its #4634 sweep verdict, its borderline flag,
and a dated snapshot of its board state. The `derivation` block records the
recipe, the source artifacts, and the arithmetic that shows why 74 double-counts
the 7 borderline items.

`fabrika eval keeps <path>` reads it and joins the coverage column live from
`provenance.json`, so "does a case already pin this incident" cannot drift from
the ledger. The corpus README now points at the enumeration instead of
instructing an author to run the join.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#4823)

`eval keeps` was authored before #4839 landed the leaf-verb catch-all guard, so
it bound its trailing operand as `path` where the guard requires `excess`. Green
alone, red combined with `main` — the merge queue ejected the PR twice on
`excess-operand.unit.test.ts`, with no textual conflict to show for it.

Declared through `leafCommand`, the same way every other leaf verb now does, so
an undeclared extra token is refused on stderr with exit 1 and empty stdout.
@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

review-code: PASS @ 6be4e4f — merge-ready

Re-gate of PR #4837 against #4823 at the new head 6be4e4fb, after the merge-queue double ejection. The prior review-code: PASS @ aa30e00c is staleness-invalidated by the rebase (ADR 0058) and is superseded by this verdict.

The head moved for a real cause, not a review defect. PR #4839 landed the excess-operand coverage guard on main at 07:05:05Z (89195133) — it asserts every registered leaf verb declares the catch-all. This PR's head CI ran at 06:32:04Z, before that guard existed, and keeps bound its trailing operand as path where the guard requires excess. Green alone, red combined: a semantic conflict with no textual conflict, exactly what the merge queue exists to catch (ADR 0132).

Class + §CP. class-probe classify --namespaces resolved to review-code — 1 required namespace, exit 0, 6 changed file(s) → has-code. classify-control-plane returned CONTROL_PLANE_TOUCHED='', GUARD_TOUCHING='', 6 files scanned, 0 .decisions/** content-probed: not-control-plane, auto-merge lane.

Reviewed-head: @ 6be4e4f

Acceptance criteria of #4823 — one at a time

Repair-round gates

  • [PASS] The guard was conformed to, not weakened. excess-operand.unit.test.ts is byte-identical to main — blob ad9fa4ab65f9ebd5602695b021473893f934d1cb on both the PR head and origin/main. No skip, no special case, no allowlist entry for keeps, no relaxed assertion. Stronger still: the head-vs-origin/main tree diff over packages/fabrika-cli/src/ is exactly the 6 PR files, so the guard's whole dependency cone (excess-operand.ts, registry.ts, the leafCommand helper) is untouched. And keeps declares through the same leafCommand path as every other leaf — no bespoke shim; the only bare group constructor left in the file is the one for the verb group itself, which is not a leaf.
  • [PASS] Red-then-green, reproduced. At the head the guard is 17/17 green including the exact ejecting row — verbose output shows a passing `fabrika eval keeps` binds its trailing operands. Reverting only that one line in a throwaway copy reds precisely that row: AssertionError: expected 'path' to be 'excess' — the byte-for-byte assertion that ejected the PR — with Tests 1 failed | 16 passed (17). Restoring returns 17/17. The test is non-vacuous and the fix is causal, not incidental. The counterfactual ran only inside the review gate's own throwaway worktree, was restored byte-exact and torn down; no file under review was edited.
  • [PASS] Behaviour preserved. Ran both myself at the head. The keeps verb still emits 66 member(s) plus 1 pending, derived 2026-08-03 and 7 borderline · 7 pinned by a committed case · 59 uncovered. JSON mode emits exactly {"members":66,"pending":1,"borderline":7,"covered":7,"uncovered":59} with 67 rows. The catch-all did not break the verb's own path operand or its flags.
  • [PASS] The new refusal works, and refuses cleanly. A trailing bogus operand gives exit 1, stdout 0 bytes (measured with wc -c, not eyeballed), and the message on stderr: fabrika: unexpected operand "bogus" for "fabrika eval keeps" — the verb declares no argument to bind it to. No plausible payload rides the non-zero exit — the defect class this repo keeps hitting is closed here.
  • [PASS] Nothing else moved, and the prior content survived the rebase provably. Still the same 6 files; packages/fabrika-cli/package.json is ABSENT from the diff and still reads version 0.1.0 — no collision with the standing 0.1.1 Release PR chore: release main #4833. Comparing the pre-rebase head aa30e00c to this head over packages/fabrika-cli/src/, the files ruled-keeps.json, ruled-keeps.ts, ruled-keeps.unit.test.ts, ruled-keeps.data.unit.test.ts and incident-corpus/README.md are byte-identical (absent from the tree diff), so the 66 member rows, both derivations, the pending Worktree owner stamps are never written on the live harness path — 0 of 256 trees stamped #4180 row, the M37 17/14 counts and the corrected AC5 narrative all carried intact. The only deltas are the eval command file (the one authored line) plus the adr/report command files and the three excess-operand.* files — all rebase-carried from fix(fabrika-cli): refuse an operand a leaf verb never declared (#4828) #4839, confirmed by origin/main already declaring check/report/cases/run through leafCommand.
  • [PASS] Decoder path + non-vacuous guards. ruled-keeps.ts decodes through Schema.decodeUnknownResult(RuledKeepsFile); its single JSON.parse sits inside a Result.try yielding a typed RuledKeepsDecodeError — a total decoder, not a raw parse. Full package suite green at the head: 41 files / 561 tests.
  • [PASS] Part of #4823 preserved, not Fixes. No closing keyword anywhere in the body (a closing-keyword-plus-issue-number scan returns zero matches); Part of #4823 present. Publish the ruled fabrika eval corpus as an enumeration — membership is derivable but never written down, and the published size (74) is wrong #4823 correctly stays open past this merge for provenance.json still publishes the discredited 74 as the KEEP-corpus size — the one place the 74→66 correction did not reach #4838.
  • [PASS] ## Deviations is append-only. Four entries in order: the three earlier **Scope narrowing** rows (the Part of partial-split, coverage-derived-not-stored, board state as a dated snapshot) — matching the round-1 repair record in substance — then one appended **(repair round 1) Post-review change** entry naming the semantic conflict with fix(fabrika-cli): refuse an operand a leaf verb never declared (#4828) #4839 as its cause and stating the guard was not weakened. Nothing above it was rewritten (§DEV satisfied).

Standing sub-gates

CI + evidence

CI at 6be4e4fb is fully green — the checks that read blocked at hand-off have since completed: ci-required, lint / format / typecheck, packages unit tests, unit + client tests, CodeQL and the full guard set all success; only integration, e2e, deploy and lint workflow YAML are skipped, correct for a packages-only diff. No failure or cancellation at this head.

Run-evidence bundle: PRESENT for head 6be4e4fb — producer run 30794435837, artifact 8848387916, manifest.commit == head, schemaVersion 1; checks 2/2 pass; tests 2420/2420 passed, 0 failed, 0 skipped.

Read the PR head (§HEAD): every file under review was sourced from 6be4e4fb1830b19358b67ddea26f247141804ab4 through a per-run ref and an isolated throwaway worktree, never the launched checkout's working copy. The worktree was torn down after the run.

Branch mechanics (verified, not a gate): the branch was pinned by its own lane, the author worked inside that lane using the sanctioned ignore-other-worktrees switch, touched no other worktree, and never committed detached (#4826). No finding.

All criteria pass. This PR is merge-ready. review-code does not mergeship-it is the authorized merge step; merging will not close #4823 (Part of, by design — #4838 must land first).

Verdict-written: 2026-08-03T07:59:20Z

@usirin

usirin commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Accuracy note on the verdict above (no change to the PASS): the glossary-freshness awk diagnostic I flagged is already tracked as #4700 — "review-code's glossary-freshness detector never compiles". My verdict said "filed separately"; it is already filed, not newly filed by me. Unchanged either way: it is pre-existing tooling noise, not a finding on PR #4837, and the check still returned its honest not-applicable skip with a positive scope count (50 candidate surfaces on base).

@usirin
usirin added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit c84046e Aug 3, 2026
46 checks passed
@usirin
usirin deleted the usirin/publish-ruled-keep-corpus-4823-3CD86FC3 branch August 3, 2026 08:09
@github-actions github-actions Bot mentioned this pull request Aug 3, 2026
usirin added a commit that referenced this pull request Aug 9, 2026
…eration (#4823)

The enumeration landed in PR #4837, but the ticket's scope line — correct the
published cardinality at each place it appears — was discharged surface by
surface, and one was missed: the fabrika authoring-brief contract still told
every brief author to pull incident rows from "the 74-issue KEEP corpus" and
pointed at #4642/#4634 rather than at the committed file. It predates the
correction, so it is the same defect as #4838 one directory over.

The doc now points at ruled-keeps.json and publishes 66 members plus 1 pending,
keeping #4642/#4634 as the enumeration's provenance rather than as the recipe a
reader is asked to re-run.

To stop the next copy going stale, the figure is derived rather than written:
`publishedFigure` computes it from the rows, and `publishedFigureViolations`
checks each artifact that publishes it. The data test declares both surfaces —
the corpus README and the authoring-brief contract — and reads each by path, so
an unreadable surface throws rather than counting as clean; "could not read it"
and "it carries no stale figure" are different facts.

Proven by mutation, not by reading: deleting one member row reds both surfaces
(65 members plus 1 pending is published nowhere), reintroducing the string
"74-issue KEEP corpus" reds the contract doc, and pointing a declared surface at
a missing file reds with ENOENT.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant