You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Add per-chunk budgets on top of the aggregate eager-closure ceiling — vendor-objectstack (38%) first — ruled follow-up of #5468 #5490
Work card created by the triage seat executing the maintainer's #5468 ruling. Provenance: maintainer, live PM chat 2026-08-21, verbatim 「其他接受」 accepting the triage recommendation for #5468 — A now + C next, B rejected: the absolute aggregate ceiling stays as shipped (PR #5466); this card delivers C, per-chunk budgets, so a single chunk cannot grow unnoticed inside aggregate headroom.
Extend scripts/__tests__/check-eager-closure-budget.test.ts (or a sibling in the same gauge) with per-chunk gzipped ceilings for the largest eager chunks — at minimum vendor-objectstack (1,493 KB / 38% of closure), framework (484 KB), ui-components (380 KB) — set truthful-current-state + small headroom, same discipline as the aggregate ceiling (no unilateral lowering).
Chunk names/sizes come from the shipped gauge's own measurement (eager-closure report), not hardcoded expectations that rot — pin the mapping loudly if a chunk disappears/renames.
Constraints from the ruling
⛔ No main-comparison ratchet (option B) — rejected for its merge-queue double-ejection failure mode and per-PR build cost.
Claimed by the domain:devx @ objectui execution seat (#5748), PM session session_019b5UBNMtTzKbVtZZGvFuxe. Branch: claude/issue-5490-per-chunk-budgets.
This card is already a ruling. ⛔ Nothing here is open.
It was written by the triage seat executing the maintainer's #5468 ruling (2026-08-21, verbatim 「其他接受」): A now + C next, B rejected. The aggregate ceiling stays as shipped in PR #5466; this card delivers C — per-chunk budgets, so a single chunk cannot grow unnoticed inside aggregate headroom.
⛔ Option B (a main-comparison ratchet) is rejected and must not be reintroduced, for two recorded reasons: its merge-queue double-ejection failure mode, and per-PR build cost. If the implementation starts to feel like it wants a comparison against main, that is a signal to stop and report — not to build it.
⚠️ The sequencing caveat is binding — check it before measuring
The ruling carries a recorded caveat: if #5325 / #5359 (the cleave work) has landed, set the per-chunk lines after it, not before.
Check that first. Baselines measured against a pre-cleave closure would be wrong the moment the cleave lands, and a budget set too high is a gate that cannot fail. Report which state you found and which you measured against.
What to build
Per-chunk gzipped ceilings in scripts/__tests__/check-eager-closure-budget.test.ts (or a sibling in the same gauge), for at minimum:
chunk
card's figure
vendor-objectstack
1,493 KB / 38% of closure
framework
484 KB
ui-components
380 KB
Set at truthful current state + small headroom, the same discipline as the aggregate ceiling. ⛔ No unilateral lowering — this is a ratchet, not an optimisation target, and lowering it below measured reality turns a budget into a bug report.
⚠️Re-measure all three. Those figures are from 2026-08-21 and this repo has moved a great deal; every inherited number tonight has been stale.
⭐ The requirement that decides whether this gate is worth anything
Chunk names/sizes come from the shipped gauge's own measurement (the eager-closure report), not hardcoded expectations that rot — pin the mapping loudly if a chunk disappears or renames.
That last clause is the whole design. A per-chunk budget keyed on a chunk name that no longer exists is vacuously green — the budget passes because it is measuring nothing. So:
If a budgeted chunk name is absent from the report, the gate must FAIL, not skip. Predict and prove it: rename or remove a budgeted chunk name and confirm the gate reds naming it.
If the report yields zero chunks, the gate must FAIL. A collapsed measurement must never read as under-budget.
Put the measured sizes in the verdict line, not just pass/fail, so a reader sees headroom rather than a tick.
Positive control: raise one chunk past its ceiling (or lower a ceiling below measured) and confirm the gate reds naming that chunk and both numbers. Predict each direction before running; prove mutations on disk by anchored counts, never an editor's exit code; restore via git checkout HEAD -- plus the explicit path with an empty git diff HEAD.
Scope
The budget test and whatever the gauge needs to expose per-chunk numbers. ⛔ Do not change chunking, ⛔ do not change the aggregate ceiling, ⛔ do not attempt the cleave work (#5325 / #5359).
Root vitest only (objectui#3378). Exit codes captured by redirect before any pipe. ⚠️ Derive the gate list from package.json and .github/workflows/ rather than from this order.
⚠️ This gate needs a real build to measure. Say plainly what happens if it runs against an unbuilt tree — ⛔ it must not silently pass. That exact false-green has bitten three of this seat's devs tonight on a different gate (check:doc-snippets prints "NOT run" and exits 0).
{
"issue": 5490,
"status": "done",
"branch": "claude/issue-5490-per-chunk-budgets",
"pr": "https://github.com/objectstack-ai/objectui/pull/6210",
"premise_still_valid": true,
"summary": "Per-chunk gzipped ceilings added on top of the aggregate eager-closure ceiling in scripts/check-eager-closure-budget.mjs, for vendor-objectstack (967,000 B), framework (502,000 B) and ui-components (399,000 B) — each set at the freshly measured size plus ~2%, each headroom far narrower than the 89 KiB regression the gate exists to catch. SEQUENCING CAVEAT: the cleave work has NOT landed — #5325 was closed by PR #6007 (a checked ledger pinning the 43 ineffective dynamic imports; no import moved) and #5359 by PR #5925 (a docs correction), and advancedChunks is untouched by both — so the lines are measured against the current pre-cleave closure at main tip 2c8474c04. The card's figures were stale in one direction that matters: vendor-objectstack measures 926.2 KB, not 1,493 KB (framework 480.9 vs 484; ui-components 381.9 vs 380). The ceilings key on the chunk names the report itself carries: emitEagerClosureReport now publishes rolldown's own chunk.name as files[].name (report v2, SUPPORTED_REPORT_VERSION bumped in lockstep and pinned by a test that parses the emitter), and a budgeted name ABSENT from the report is exit 2 naming it and listing every name present — never a skip. Zero named chunks, an empty ceiling map, and an unnamed member are errors for the same reason. Aggregate ceiling, its baseline, and chunking are untouched.",
"tests": "All at the final commit 32f162a77, exit codes captured by redirect before any pipe, heavy commands through the shared verify lock. (1) BUILD: `npx vite build` in apps/console — exit 0, 'eager closure: 52/508 chunks, 3298620 bytes gzipped'; three consecutive builds produced byte-identical totals, so the per-chunk numbers are measurements, not noise. (2) SHIPPED GATE against that real report: `node scripts/check-eager-closure-budget.mjs` exit 0, verdict lines carry the sizes — 'vendor-objectstack 926.2 KB / 944.3 KB ceiling (headroom 18.1 KB)', 'framework 480.9 KB / 490.2 KB (headroom 9.4 KB)', 'ui-components 381.9 KB / 389.6 KB (headroom 7.7 KB)'. (3) ROOT VITEST over the derived test set — eight tests in scripts/__tests__ read apps/console/vite.config.ts as their subject, so the whole directory was run: `npx vitest run scripts/__tests__ --maxWorkers=2` exit 0, 'Test Files 73 passed (73) / Tests 2019 passed (2019)'. (4) TYPE-CHECK: `npx tsc --noEmit -p tsconfig.scripts.json` exit 0, with both changed script files confirmed present in the program via --listFiles (a green run over a program that does not contain the file is the vacuity this guards against); `npx tsc -b apps/console/tsconfig.node.json --force` exit 0 — that, not tsconfig.scripts.json, is the program that owns vite.config.ts. (5) LINT: `pnpm lint:root` exit 0 over the FULL root scan (28 pre-existing warnings, 0 errors) plus targeted eslint on the three changed files, exit 0 with no problems — apps/console/vite.config.ts is outside lint:root's scope, so it was linted explicitly against the same flat config; eslint.config.js declares no project/projectService, so no type-aware rule can move a verdict on an untouched file. (6) OTHER DERIVED GATES: check:control-bytes, check:phantom-deps, check:esm-specifiers all exit 0. CONTROLS, each direction predicted before running: [A] POSITIVE — the #5266 incident replayed, +89 KiB onto vendor-objectstack in an internally consistent report (mutation confirmed on disk by reading the file back: 948461 -> 1039597, eagerGzipBytes 3389756): predicted exit 1 with the aggregate green, observed exactly that — 'Console eager closure is 3310.3 KB ... headroom 679.9 KB' green, per-chunk red 'vendor-objectstack 1015.2 KB / 944.3 KB ceiling (OVER by 70.9 KB)'. That single run is the whole argument for this card. [B] POSITIVE — ceiling lowered below measured (framework 502_000 -> 450_000; anchored counts on disk 1->0 and 0->1, never an editor exit code): predicted red naming framework, observed exit 1 '480.9 KB / 439.5 KB ceiling (OVER by 41.4 KB)'. Second direction: predicted at least the ceiling-vs-baseline unit test to red, observed SEVEN failures — wider than predicted, same direction, all one cause (fixtures are built from PER_CHUNK_BASELINE, which now exceeded the lowered ceiling). Restored with `git checkout HEAD -- scripts/check-eager-closure-budget.mjs`; anchored counts back to 1/0 and `git diff HEAD` empty (0 bytes). [C] NEGATIVE — a budgeted chunk renamed in a copy of the real report (anchored counts 1->0 and 0->1): predicted exit 2 naming it rather than a pass, observed exit 2 with the aggregate still green and 'Budgeted chunk `vendor-objectstack` is ABSENT ... That is a FAILURE, not a pass' followed by the 52 present names, vendor-objectstack-core at the top. [D] UNBUILT TREE, the question the dispatch asked: exit 2, both halves refusing — 'This is a broken gauge, not a passing budget' and 'Per-chunk ceilings measure nothing without a build — this is a broken gauge, not 3 budgets that all passed'. No path exits 0 having measured nothing; performance-budget.yml maps exit 2 to budget_status=error and fails the step, and it is the only CI caller, running after it builds the packages and the console.",
"open_questions": [],
"out_of_scope_findings": [
"NOT filed — already recorded as #5924 (searched first): the aggregate ceiling's live headroom is now ~769 KB, 8.4x the 89 KiB the gate is sized to catch, because the closure shrank ~707 KB below the frozen BASELINE (measured 3,298,620 on 2c8474c04 vs BASELINE 4,005,911 on 4c1623c0c). #5924 records the same drift measured at 3,308,221 on 0fce2ef81 and owns the disposition. Untouched here by ruling (#5468: the aggregate line stays as shipped), but recorded in the checker's header beside PER_CHUNK_BASELINE so the two readings are never mistaken for one measurement. The per-chunk headroom assertion inherits the same constant-vs-constant shape at a ~2% band instead of ~24%; the systemic fix (derive the headroom check from the report just read) belongs to #5924.",
"Not filed, noted only: `pnpm --filter @object-ui/console build` fails on a fresh worktree until `pnpm turbo run build --filter='./packages/*'` has run — 358 TS2307/TS2882 errors from missing package dist. Expected toolchain behaviour (CI builds packages first) and not a defect; recorded because it reads exactly like a broken main for the first minute."
]
}
Activity
yinlianghui-tw commentedon Aug 25, 2026
PM claim + dispatch order — R27
Claimed by the
domain:devx@ objectui execution seat (#5748), PM sessionsession_019b5UBNMtTzKbVtZZGvFuxe. Branch:claude/issue-5490-per-chunk-budgets.This card is already a ruling. ⛔ Nothing here is open.
It was written by the triage seat executing the maintainer's #5468 ruling (2026-08-21, verbatim 「其他接受」): A now + C next, B rejected. The aggregate ceiling stays as shipped in PR #5466; this card delivers C — per-chunk budgets, so a single chunk cannot grow unnoticed inside aggregate headroom.
⛔ Option B (a main-comparison ratchet) is rejected and must not be reintroduced, for two recorded reasons: its merge-queue double-ejection failure mode, and per-PR build cost. If the implementation starts to feel like it wants a comparison against
main, that is a signal to stop and report — not to build it.The ruling carries a recorded caveat: if #5325 / #5359 (the cleave work) has landed, set the per-chunk lines after it, not before.
Check that first. Baselines measured against a pre-cleave closure would be wrong the moment the cleave lands, and a budget set too high is a gate that cannot fail. Report which state you found and which you measured against.
What to build
Per-chunk gzipped ceilings in
scripts/__tests__/check-eager-closure-budget.test.ts(or a sibling in the same gauge), for at minimum:vendor-objectstackframeworkui-componentsSet at truthful current state + small headroom, the same discipline as the aggregate ceiling. ⛔ No unilateral lowering — this is a ratchet, not an optimisation target, and lowering it below measured reality turns a budget into a bug report.
⭐ The requirement that decides whether this gate is worth anything
That last clause is the whole design. A per-chunk budget keyed on a chunk name that no longer exists is vacuously green — the budget passes because it is measuring nothing. So:
Positive control: raise one chunk past its ceiling (or lower a ceiling below measured) and confirm the gate reds naming that chunk and both numbers. Predict each direction before running; prove mutations on disk by anchored counts, never an editor's exit code; restore via
git checkout HEAD --plus the explicit path with an emptygit diff HEAD.Scope
The budget test and whatever the gauge needs to expose per-chunk numbers. ⛔ Do not change chunking, ⛔ do not change the aggregate ceiling, ⛔ do not attempt the cleave work (#5325 / #5359).
Root vitest only (objectui#3378). Exit codes captured by redirect before any pipe.⚠️ Derive the gate list from
package.jsonand.github/workflows/rather than from this order.check:doc-snippetsprints "NOT run" and exits 0).Generated by Claude Code
test(scripts): add per-chunk gzipped ceilings to the eager-closure bu…
style(scripts): silence an unused-binding warning in the budget test
yinlianghui-tw commentedon Aug 25, 2026
os-dev-report
{ "issue": 5490, "status": "done", "branch": "claude/issue-5490-per-chunk-budgets", "pr": "https://github.com/objectstack-ai/objectui/pull/6210", "premise_still_valid": true, "summary": "Per-chunk gzipped ceilings added on top of the aggregate eager-closure ceiling in scripts/check-eager-closure-budget.mjs, for vendor-objectstack (967,000 B), framework (502,000 B) and ui-components (399,000 B) — each set at the freshly measured size plus ~2%, each headroom far narrower than the 89 KiB regression the gate exists to catch. SEQUENCING CAVEAT: the cleave work has NOT landed — #5325 was closed by PR #6007 (a checked ledger pinning the 43 ineffective dynamic imports; no import moved) and #5359 by PR #5925 (a docs correction), and advancedChunks is untouched by both — so the lines are measured against the current pre-cleave closure at main tip 2c8474c04. The card's figures were stale in one direction that matters: vendor-objectstack measures 926.2 KB, not 1,493 KB (framework 480.9 vs 484; ui-components 381.9 vs 380). The ceilings key on the chunk names the report itself carries: emitEagerClosureReport now publishes rolldown's own chunk.name as files[].name (report v2, SUPPORTED_REPORT_VERSION bumped in lockstep and pinned by a test that parses the emitter), and a budgeted name ABSENT from the report is exit 2 naming it and listing every name present — never a skip. Zero named chunks, an empty ceiling map, and an unnamed member are errors for the same reason. Aggregate ceiling, its baseline, and chunking are untouched.", "tests": "All at the final commit 32f162a77, exit codes captured by redirect before any pipe, heavy commands through the shared verify lock. (1) BUILD: `npx vite build` in apps/console — exit 0, 'eager closure: 52/508 chunks, 3298620 bytes gzipped'; three consecutive builds produced byte-identical totals, so the per-chunk numbers are measurements, not noise. (2) SHIPPED GATE against that real report: `node scripts/check-eager-closure-budget.mjs` exit 0, verdict lines carry the sizes — 'vendor-objectstack 926.2 KB / 944.3 KB ceiling (headroom 18.1 KB)', 'framework 480.9 KB / 490.2 KB (headroom 9.4 KB)', 'ui-components 381.9 KB / 389.6 KB (headroom 7.7 KB)'. (3) ROOT VITEST over the derived test set — eight tests in scripts/__tests__ read apps/console/vite.config.ts as their subject, so the whole directory was run: `npx vitest run scripts/__tests__ --maxWorkers=2` exit 0, 'Test Files 73 passed (73) / Tests 2019 passed (2019)'. (4) TYPE-CHECK: `npx tsc --noEmit -p tsconfig.scripts.json` exit 0, with both changed script files confirmed present in the program via --listFiles (a green run over a program that does not contain the file is the vacuity this guards against); `npx tsc -b apps/console/tsconfig.node.json --force` exit 0 — that, not tsconfig.scripts.json, is the program that owns vite.config.ts. (5) LINT: `pnpm lint:root` exit 0 over the FULL root scan (28 pre-existing warnings, 0 errors) plus targeted eslint on the three changed files, exit 0 with no problems — apps/console/vite.config.ts is outside lint:root's scope, so it was linted explicitly against the same flat config; eslint.config.js declares no project/projectService, so no type-aware rule can move a verdict on an untouched file. (6) OTHER DERIVED GATES: check:control-bytes, check:phantom-deps, check:esm-specifiers all exit 0. CONTROLS, each direction predicted before running: [A] POSITIVE — the #5266 incident replayed, +89 KiB onto vendor-objectstack in an internally consistent report (mutation confirmed on disk by reading the file back: 948461 -> 1039597, eagerGzipBytes 3389756): predicted exit 1 with the aggregate green, observed exactly that — 'Console eager closure is 3310.3 KB ... headroom 679.9 KB' green, per-chunk red 'vendor-objectstack 1015.2 KB / 944.3 KB ceiling (OVER by 70.9 KB)'. That single run is the whole argument for this card. [B] POSITIVE — ceiling lowered below measured (framework 502_000 -> 450_000; anchored counts on disk 1->0 and 0->1, never an editor exit code): predicted red naming framework, observed exit 1 '480.9 KB / 439.5 KB ceiling (OVER by 41.4 KB)'. Second direction: predicted at least the ceiling-vs-baseline unit test to red, observed SEVEN failures — wider than predicted, same direction, all one cause (fixtures are built from PER_CHUNK_BASELINE, which now exceeded the lowered ceiling). Restored with `git checkout HEAD -- scripts/check-eager-closure-budget.mjs`; anchored counts back to 1/0 and `git diff HEAD` empty (0 bytes). [C] NEGATIVE — a budgeted chunk renamed in a copy of the real report (anchored counts 1->0 and 0->1): predicted exit 2 naming it rather than a pass, observed exit 2 with the aggregate still green and 'Budgeted chunk `vendor-objectstack` is ABSENT ... That is a FAILURE, not a pass' followed by the 52 present names, vendor-objectstack-core at the top. [D] UNBUILT TREE, the question the dispatch asked: exit 2, both halves refusing — 'This is a broken gauge, not a passing budget' and 'Per-chunk ceilings measure nothing without a build — this is a broken gauge, not 3 budgets that all passed'. No path exits 0 having measured nothing; performance-budget.yml maps exit 2 to budget_status=error and fails the step, and it is the only CI caller, running after it builds the packages and the console.", "open_questions": [], "out_of_scope_findings": [ "NOT filed — already recorded as #5924 (searched first): the aggregate ceiling's live headroom is now ~769 KB, 8.4x the 89 KiB the gate is sized to catch, because the closure shrank ~707 KB below the frozen BASELINE (measured 3,298,620 on 2c8474c04 vs BASELINE 4,005,911 on 4c1623c0c). #5924 records the same drift measured at 3,308,221 on 0fce2ef81 and owns the disposition. Untouched here by ruling (#5468: the aggregate line stays as shipped), but recorded in the checker's header beside PER_CHUNK_BASELINE so the two readings are never mistaken for one measurement. The per-chunk headroom assertion inherits the same constant-vs-constant shape at a ~2% band instead of ~24%; the systemic fix (derive the headroom check from the report just read) belongs to #5924.", "Not filed, noted only: `pnpm --filter @object-ui/console build` fails on a fresh worktree until `pnpm turbo run build --filter='./packages/*'` has run — 358 TS2307/TS2882 errors from missing package dist. Expected toolchain behaviour (CI builds packages first) and not a defect; recorded because it reads exactly like a broken main for the first minute." ] }Generated by Claude Code
test(scripts): add per-chunk gzipped ceilings to the eager-closure bu…