Skip to content

docs(decisions): 0253 — the eval record is an eval-namespaced PR comment (#4769) - #5271

Merged
usirin merged 1 commit into
mainfrom
usirin/adr-0253-eval-record-4769-9652AB4D
Aug 10, 2026
Merged

docs(decisions): 0253 — the eval record is an eval-namespaced PR comment (#4769)#5271
usirin merged 1 commit into
mainfrom
usirin/adr-0253-eval-record-4769-9652AB4D

Conversation

@usirin

@usirin usirin commented Aug 10, 2026

Copy link
Copy Markdown
Member

The fabrika grading chain requires a review run to leave behind an eval result bound to the commit it graded, and then never says where that result lives, what its marker is called, or what "a grader returned no verdict" means. Three downstream children — the gate that reads it, the scorecard that aggregates it, and the axis that writes it — would each have invented an answer. ADR 0253 pins all three: the record is a PR comment under its own eval namespace, and a run that returns no verdict is a counted NoVerdict over four named reasons that never passes and never leaves the denominator.

Fixes #4769

What changed

  • .decisions/0253-eval-record-is-an-eval-namespaced-pr-comment.md — the record.
  • packages/fabrika-cli/src/eval/README.md — the #4769 open-call bullet now points at the ADR, and a short section states the pins for a builder, mirroring how ADR 0252's section reads.

Deviations

@github-actions

github-actions Bot commented Aug 10, 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. (5eb9a44)
  • web — Stage pr-5271 torn down.

@usirin

usirin commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

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

This verdict does not authorize a merge. The PR is in the control-plane set by CONTENT, not by path (ADR 0164): pipeline-cli cp-classify classify returned content-undetermined [content-source-present] — no CODEOWNERS path matched — and pipeline-cli guard-content-probe classify then returned guard-touching (§CP, ADR 0164) [guard-vocabulary-match] on the ADR body at head. A @kamp-us/control-plane approval at head is what authorizes the merge; ship-it then enqueues (ADR 0135/0048).

Reviewed-head: @ 5eb9a44

Doc class: .decisions/0253-eval-record-is-an-eval-namespaced-pr-comment.md (new, +275). The packages/** README is the code class and is verdicted separately in the review-code namespace on this same head.

Acceptance criteria (#4769)

#4769 carries no ### Acceptance criteria heading — it is a report-shaped type:decision issue. Flagging that as a process gap at intake, not a PR defect: the PR cannot fix the issue's shape, and rubber-stamping is not an option either. The gate is therefore run against the issue's three enumerated absences (its actual contract) plus the founder ruling landed on it 2026-08-02, each verified one at a time.

  • [PASS] Absence 1 — the marker namespace is unnamed. Pinned to the literal eval (Decision §1), stated as a root and not a review-<x> member, with a named home (packages/fabrika-cli/src/wire/eval-record.ts plus one registry row, ADR 0241 terms). Restated in the Binding constraints list, so a consumer has a string to match.
  • [PASS] Absence 2 — the storage location is unstated. Pinned to a PR comment on the PR under review, never a committed file, one per (head, cell), latest-in-force wins (Decision §3), with four reasons and an explicit downstream ruling that committed scorecards, the trend co-gate, and the model-churn re-run contract #4680 is parse-and-commit.
  • [PASS] Absence 3 — "returns no verdict" has no referent. Pinned as the typed tag NoVerdict over a closed four-reason vocabulary — no-output, unparseable, timed-out, invocation-failed — in a table that says what each covers (Decision §4). The counting rule the issue called load-bearing is stated in full: stays in runs, never in passed, counted in its own noVerdict, never retried inside the five.
  • [PASS] Founder ruling honored — the 2026-08-02 ruling (results = SHA-bound PR comments; scorecard harvested to a committed file) is implemented, not re-litigated: Decision §3 settles the comment, and the Consequences name claude-plugins/fabrika/reports/eval/<date>.json (ADR 0252 §3) as the harvested downstream.
  • [PASS] Chief-of-staff constraint honored (comment 2026-08-10) — "the namespace must be readable by the wire/verdict-marker layer; a namespace nothing can read is a deadlock". §1 addresses it directly and inverts it with a reason: eval is deliberately unreadable by verdict-marker.ts so no ship gate verdict scan can read a measurement as a merge verdict, and readability is supplied by a sibling module the ADR names. Verified against source at head: NAMESPACE_PREFIXES = ["review", "check-epic-plan", "governance"] means eval does not "reach", so the reader answers Absent exactly as §1 claims.
  • [PASS] Cited priors check out at head — packages/fabrika-cli/src/wire/verdict-marker.ts carries the namespace class verbatim as quoted (/^(review|check-epic-plan|governance)(-[a-z0-9]+)*$/), and ScorecardCell in packages/fabrika-cli/src/eval/report.ts carries stage / surface / model / gradedRuns / passedRuns / passRate exactly as the field-spelling rule in §5 depends on. Both claims are grounded, not asserted.
  • [PASS] ADR 0252 reused, not edited — 0252 §1 defines dispersion = min(passed, runs − passed) and carries runs / passed; 0253's case block adds noVerdict / perRun alongside them and moves nothing. Confirmed against 0252 at head.

Doc hygiene

  • [PASS] House format — frontmatter carries id / title / status / date / tags; ## Context / ## Decision / ## Consequences all present, plus a ## Records section matching the recent-ADR house shape.
  • [PASS] Index row — no .decisions/index.md is committed (correct per ADR 0126, discovery is ambient); frontmatter status: accepted is the source the ambient map renders.
  • [PASS] Links resolve — all 12 relative targets exist at head (9 sibling ADRs, .glossary/TERMS.md, and the two packages/fabrika-cli/** source files), verified by git ls-tree against the head ref. Standard markdown relative paths, no wikilinks.
  • [PASS] No leaked local/home paths — the added lines carry no machine-local path class, and pipeline-cli leak-guard scan-pr 5271 reports clean over the landed comments. Note for the record: the author's session report did carry such paths; the committed files and the PR body do not, which is what this row gates.
  • [PASS] Supersession — nothing is superseded. The ADR states plainly that it contradicts none of its priors and that no ADR's status line moves; 0252 / 0243 / 0241 are reused or applied, not amended. No forward pointer is owed.
  • [PASS] Status sanity — accepted is coherent: storage was founder-ruled and the residue was explicitly delegated to engineering, so nothing here is still proposed.
  • [PASS] Single Diátaxis mode — single-mode: explanation. The ADR argues a decision throughout; the JSON block is illustrative of the decision, not a how-to.
  • [PASS] Clear, concise prose — active voice, concrete, no AI-tell density. House idioms (§VERDICT, fail-closed, ADR frontmatter) treated as established vocabulary.
  • [PASS] Example is derivable (ADR 0247) — the §5 case block is internally consistent and re-derivable: perRun holds 3 pass / 1 fail / 1 no-verdict:timed-out, giving runs 5, passed 3, noVerdict 1, and dispersion = min(3, 5−3) = 2, which is what the block states. The cell aggregate 19/20 = 0.95 matches the marker line's example.

ADR contradiction sweep (Step 4a)

  • [PASS] Sweep — 5 questions enumerated (namespace string; wire-format home; storage location; outcome-token vocabulary; no-verdict taxonomy + counting rule). adr-sweep scanned 250 ADRs, 204 live-accepted-and-uncited in scope, and shortlisted 8. All 8 opened and judged adjacent, none re-deciding a question 0253 settles:
    • 0236 (eval-harness spawning shell) is the closest call and is clean. Its §3 NoModelTurns classifies a run that never reached a model in the pipeline-cli eval-harness; NoVerdict classifies a grader that returned no verdict in fabrika-cli. Different module, different condition, and the two agree on the governing principle ("a typed failure, never a free pass"). ADR 0238 — which 0253 cites — already fixes that module relationship, so no amendment is owed.
    • 0244 (recorded stage key is provenance) rules on corpus rows, not on the eval record; 0253's cell.stage is a live key recorded at emit time, which is exactly what 0244 calls provenance.
    • 0242 (fabrika skill nouns) and 0243 (stage/surface discriminator) rule on vocabulary routing, and 0253 follows 0243's stated precedent — route the coined term through the glossary path rather than inline so the PR stays additive.
    • 0246, 0248, 0249, 0229, 0037 are lexical neighbours only.
      Semantic pass done by reading, per the sweep's own caveat that a clean shortlist is not evidence of no contradiction.

Non-blocking observations (no action required to merge)

ADR numbering


review-doc · §CP advisory (content axis, ADR 0164) · head 5eb9a448ee6bf4345f16e473e15652f063a9192b · verified read-only off a per-run ref, no checkout

Verdict-written: 2026-08-10T04:28:44Z

@usirin

usirin commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

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

This verdict does not authorize a merge. The PR is control-plane by CONTENT, not by path (ADR 0164): pipeline-cli cp-classify classify returned content-undetermined [content-source-present] (no CODEOWNERS path matched) and pipeline-cli guard-content-probe classify then returned guard-touching (§CP, ADR 0164) [guard-vocabulary-match] on .decisions/0253-*.md at head. §CP attaches to the PR, so this namespace is advisory too. A @kamp-us/control-plane approval at head authorizes the merge; ship-it then enqueues (ADR 0135/0048).

Reviewed-head: @ 5eb9a44

Why this namespace exists on an ADR PR. pipeline-cli class-probe classify --namespaces names two required gates for this diff — review-code and review-doc — because packages/fabrika-cli/src/eval/README.md sits under a code root, which §CLASS classes has-code, not has-docs. Leaving it to the doc gate alone would strand review-code empty and stall the PR at ship-it. The ADR itself is verdicted in the review-doc namespace on this same head.

Code class under review: packages/fabrika-cli/src/eval/README.md (+27 / −4). No .ts, no test, no package.json, no config — a documentation-only change inside a code root.

Acceptance criteria (#4769)

#4769 carries no ### Acceptance criteria heading (report-shaped type:decision); the intake gap is flagged in the review-doc verdict and is not a PR defect. The code-class contribution to the issue's contract is the one thing this file was changed for:

  • [PASS] The README no longer points a builder at an unsettled question. The "deliberately not decided here" bullet naming #4678's eval-result record has no defined shape, namespace, or storage location #4769 is struck through and redirected to ADR 0253, and a new ## The eval record (#4769) section states the pins for a builder. This is exactly the shape ADR 0252's PR used for the same README.
  • [PASS] The README and the ADR do not disagree. Walked the new section claim by claim against the ADR at head: PR comment / one per (head, cell) / latest in-force wins; namespace eval as its own root in a sibling wire-format module with verdict-marker.ts not widened; RECORDED | UNRECORDABLE not a polarity with the 90% bar out of the record; NoVerdict over the same four reasons with the same counting rule; the two-level field spellings. No drift and no claim the README makes alone.
  • [PASS] The README does not become a second source. It explicitly says "build against [the ADR], not against the issue bodies", which keeps the ADR authoritative — the property the file's own "never become a second source that drifts from it" line asks for.

Code hygiene

  • [PASS] Build / typecheck / lint / tests — not applicable and not skipped: the diff changes no executable file, so no compilation unit, type, export, or test is touched. Nothing in the change can move a build result.
  • [PASS] Link resolves — the added ../../../../.decisions/0253-eval-record-is-an-eval-namespaced-pr-comment.md resolves from packages/fabrika-cli/src/eval/ to the repo root and the target exists at head (it is the ADR this PR adds). Verified with git ls-tree against the head ref, not inferred.
  • [PASS] No leaked local/home paths — the added lines carry no machine-local path class, and pipeline-cli leak-guard scan-pr 5271 reports clean over the landed comments. The author's session report did carry absolute paths; the committed files and the PR body do not.
  • [PASS] Glossary freshness (Step 3c) — no new code surface is introduced by this diff, so no .glossary/TERMS.md row is owed by the diff. The coined term eval record is routed to the glossary path as a follow-up on ADR 0243's stated precedent; that keeps the PR additive. Recorded as a non-blocking observation in the review-doc verdict rather than a gate failure here.
  • [PASS] Package README convention — packages/fabrika-cli keeps its README; this change edits it in place and removes nothing structural.
  • [PASS] Prose fits its surface — the new section is reference-mode (a pin list a builder reads), matching the rest of the file. No why-essay imported from the ADR; it points instead.

Non-blocking observations (no action required to merge)

  • The struck-through bullet keeps the old text visible with ~~ ~~ rather than deleting it. That is a deliberate legibility choice and consistent with how this README already records superseded pins, so it is not flagged as a defect — noting it only so a later reader does not "clean it up" without knowing.

review-code · §CP advisory (content axis, ADR 0164) · head 5eb9a448ee6bf4345f16e473e15652f063a9192b · verified read-only off a per-run ref, no checkout

Verdict-written: 2026-08-10T04:29:24Z

@usirin usirin added the status:cp-banked Control-plane PR banked on the board, awaiting a control-plane approval label Aug 10, 2026
@usirin
usirin requested a review from notusirin August 10, 2026 04:30
usirin added a commit that referenced this pull request Aug 10, 2026
Three in-flight lanes each derived 0253 off the same origin/main max (0252).
Ordered by PR creation time, #5271 (04:18:29Z) keeps 0253, #5273 (04:18:57Z)
takes 0254, and this PR (04:25:21Z) takes 0255.

Renames the file, updates the frontmatter `id` and the H1 self-reference, and
repoints the two fabrika contract links. No decision content changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
usirin added a commit that referenced this pull request Aug 10, 2026
Three in-flight lanes each derived 0253 off the same origin/main max (0252).
Ordered by PR creation time, #5271 (04:18:29Z) keeps 0253, #5273 (04:18:57Z)
takes 0254, and this PR (04:25:21Z) takes 0255.

Renames the file, updates the frontmatter `id` and the H1 self-reference, and
repoints the two fabrika contract links. No decision content changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@usirin usirin added this to the fabrika campaign milestone Aug 10, 2026
usirin added a commit that referenced this pull request Aug 10, 2026
…me, never by backfill (#5041)

Repair round 1, addressing review-doc's FAIL on PR #5273.

F1 — the ADR recorded the opposite of what was ruled. The founder ruled directly
at 2026-08-10 ~07:43Z on #5041: LAZY cutover, no bulk backfill. That confirms the
founder-delegated ruling of 2026-08-10T00:15:28Z on the same issue, which the first
draft contradicted and cited nowhere. The decision is re-recorded as lazy: absence of
a `ready-for:` label stays an exclusion, the label is applied at triage time going
forward, and the already-triaged rows are not backfilled. The ruling history is now in
`## Context` as its own table, and backfill-first is written up as a rejected option
with the false-signal reason. Rewritten rather than amended: this is an unmerged draft,
and the landed record must read as one coherent decision.

F2 — renumbered 0253 -> 0254. PR #5271 opened 28 seconds earlier and owns 0253.
Re-enumerated at repair time: main carries 0250-0252, 0255, 0270 (no 0253/0254); open
PRs claim 0253 (#5271 and this one), 0256 (#5281), 0257 (#5282), 0258 (#5285), 0237
(#4703), 0235 (#4614). 0254 is free. The slug changed with the decision.
@usirin
usirin added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit 2165d36 Aug 10, 2026
46 checks passed
@usirin
usirin deleted the usirin/adr-0253-eval-record-4769-9652AB4D branch August 10, 2026 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:cp-banked Control-plane PR banked on the board, awaiting a control-plane approval

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#4678's eval-result record has no defined shape, namespace, or storage location

2 participants