Uh oh!
There was an error while loading. Please reload this page.
fix(ci): name which eager-closure half objected in the budget PR comment - #6242
Conversation
`check-eager-closure-budget.mjs` publishes a verdict for each of its three halves — `closure_status` (aggregate ceiling), `closure_chunk_status` (per-chunk ceilings) and `closure_headroom_status` (ceiling sensitivity) — but `performance-budget.yml` passed only the first into the comment step. The other two were written to `$GITHUB_OUTPUT` and never read. The step's exit code folds all three into one `budget_status`, so the comment could say a budget objected but not which half did. In the shape the gate family exists for — one chunk over its own ceiling while the total sits inside the aggregate one — both metrics the comment prints are green and the verdict is still FAIL, with nothing in the body explaining it. - Wire both missing verdicts into the comment step and render them. - Render nothing when every half passed: the healthy comment is byte-for-byte what it was. An observability change that rewrites the green output is a regression. - Exit 2 lands in the not-measured branch, so render the halves there too, and stop asserting "nothing was measured" when the closure was measured and only a ceiling drifted. - Pin the obligation: the suite fails if the checker publishes a `closure_*` verdict the workflow does not pass through. The exit-code mapping is untouched — every `budget_status=` and `CLOSURE_CODE` line is byte-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
yinlianghui-tw
commented
Aug 25, 2026
PM review — ACCEPT. ⭐ The card understated the defect and you found the real one; both extras verified here.Reviewed by the ⭐ Finding (a): the card said "two of three not forwarded." The truth is none of the three was rendered.I filed #6230 off a CI log showing Zero. The one status that was wired had never been read. So the comment could not name which half objected not because two keys were missing, but because the renderer consulted none of them — it printed metrics and took the overall ⛔ That is my premise being wrong in the direction that matters: I diagnosed from a log line rather than from the code that consumes it, and the log line was consistent with a smaller bug. ⭐ Finding (b): a false sentence the fix would otherwise have printed under a table contradicting itConfirmed on
Discriminating on the same emptiness the verdict branch already keys on — The evidence that makes the case, and it is one comparison
⭐ That is the defect at its sharpest, and it is exactly the #5266 shape the whole gate family exists for: the aggregate is green, a chunk is over, and the reader is shown a red verdict above numbers that all look fine. Holding the numbers constant so the only variable is which half failed is the comparison that proves the comment was uninformative — not an assertion that it was. Leg 1 ⭐ And you rendered against both renderers by reading the pre-change one from the The exit-code mapping, pinned mechanically
That is the right way to prove "I did not change the thing I was told not to change" — a content-only comparison that is immune to the line shifts your own diff causes. Eyeballing it would have been the usual answer and would have proved nothing. The new contract guard reverse-verified against the old workflow blob, reddening on exactly the two keys the card names, is the non-vacuity leg. And confirming all 7 new tests collected by name under Scope and hygiene
#6243 filed
⛔ Not armed yet
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#6230
Takes disposition 1 from the card: wire the unread verdicts into the comment and render them.
The defect, confirmed from source
scripts/check-eager-closure-budget.mjspublishes six keys, three of them verdicts:.github/workflows/performance-budget.ymlpassed four into the comment step.closure_chunk_status(#5490) andclosure_headroom_status(#5924) were written and never read.The step's exit code folds all three halves into one
budget_status, so the comment could say a budget objected but not which half did. Two things I found beyond the card's description:closure_statusreached the renderer and was dropped on the floor.renderBudgetCommentreadinput.closureStatusinto itsclosureobject;verdictBodynever referenced it. So no half verdict was rendered — not even the aggregate one that was wired. This change makes it live.budget_status=error, which is not inMEASURED_STATUSES, so it lands innotMeasuredBody. See "the leg-4 consequence" below.The shape this is for
The per-chunk case is #5266's: a regression that lands outside the entry chunk and inside the aggregate ceiling's headroom. Both numbers the comment prints are green and the verdict is still FAIL.
Rendering the old renderer against all-pass and chunk-fail env with identical numbers, the whole diff is:
A ❌ FAIL whose two visible metric rows are both inside budget, and nothing anywhere saying why. The new renderer on the same env adds:
The exit-code mapping is untouched
Checked mechanically, not by eye. Every
budget_status=,CLOSURE_CODE,ENTRY_OVERandMAX_ENTRY_GZIP_KB=line in the workflow is byte-identical to0409b766d:Exit 2 still maps to
error, any other non-zero tofail, anderrorstill outranksfailacross all three halves. Only line numbers moved, by the comment block added above the checker invocation. This PR changes what the step reports, not what it does.The leg-4 consequence, called out rather than buried
A drifted ceiling is exit 2 →
budget_status=error→ the not-measured branch. Rendering the halves there exposed a sentence that is false on that path: the body said "Nothing was measured — the numbers a real violation would carry are simply absent" directly above a table showing two ceilings that had just measured fine.That contradiction is latent on
main(the halves weren't shown); showing them makes it visible, so leaving it would mean shipping a self-contradicting comment. The branch now discriminates on the same emptiness the verdict branch already keys on — the checker publishesclosure_gzip_kbempty when it has no report, never as a stale number, and that is pinned by its own tests:error→ "gauge not trustworthy": the closure was measured, a ceiling stopped meaning what it names, nothing grew.This is the only wording change to an existing path, and it is confined to the case the card's leg 4 is about.
Verification
Renderer is a plain node script, so each leg was rendered from the env that scenario produces, against both this renderer and the pre-change one read from the
0409b766dgit blob (no working-tree mutation). Each was predicted before running; all four matched.passcmpclean) — the green comment does not changefailAggregate closure ceiling ❌ over its ceiling, other two✅ passpass, chunkfailPer-chunk ceilings ❌, aggregate row✅— the #5266 shapeerrorkind: not-measured,Ceiling sensitivity (headroom) ⚠️ broken gauge, no❌anywhere, no "Nothing was measured"The all-pass leg is the one that mattered most, so it is asserted as byte equality rather than by reading.
Reverse-verification of the new contract guard. Its logic, applied to the pre-change workflow from the git blob:
It reds on exactly the two keys this card reports, and greens here. That is the card's ⛔ "no third round of this" made mechanical: a fourth half fails the suite until it reaches the comment.
Suites — the four under
scripts/__tests__that read these two files, at final commitaf60a25b8:All 7 new tests confirmed collected by name in a
--reporter=verboserun, not inferred from the total.Gates, each read from its own printed verdict line:
pnpm type-check:scripts→ exit 0 (script name echoed; not a zero-match--filter)pnpm lint:root→✖ 28 problems (0 errors, 28 warnings), exit 0. Run unnarrowed over the whole root scope; zero occurrences of my files in the output, all 28 warnings pre-existing and elsewhere.check-control-bytes→✅ OK (scanned 5149 tracked text file(s); skipped 85 binary)check:entry-guard→✓ 46 scripts/ file(s) — no entry guard outside the baseline(shrink-only ratchet unmoved)check-vi-mock-specifiers→✅ OKcheck:esm-specifiers→ no un-ledgered extensionless relative specifierchangeset:check→ all three lines ✅Heavy commands ran through the shared verify lock.
Changeset
Empty-frontmatter, following the repo's precedent for CI-only changes (objectui has no
skip-changesetlabel). Nothing here ships to a package.Generated by Claude Code
Generated by Claude Code