Skip to content

Commit ada3cbb

Browse files
chore(ui): re-pin the console eager-closure ceiling after the spec shared chunks (#26127)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9VQKUCrmuRDnacLPUeKUV3p)_ Part of #25925 Clause-②: no Metadata-protocol: none ## What Re-pins the console eager-closure budget in `ui/scripts/check-eager-closure-budget.mjs` onto a reading of `main`, and moves the two rendered-reading literals its unit test pins. Nothing reaches a bundler input, nothing under `ui/packages/**` changes, so the sdui manifest record does not move. | constant | before | after | |---|---:|---:| | `MAX_EAGER_CLOSURE_GZIP_BYTES` | 3,579,945 | 2,489,948 (down 1,089,997) | | `BASELINE` | 3,072,056 · 85 of 2291 · `b6f11d3` | 1,982,059 · 85 of 2387 · `cc378e93` | | `PER_CHUNK_GZIP_CEILINGS['vendor-objectstack']` | 1,867,000 | 842,730 (down 1,024,270) | | `PER_CHUNK_BASELINE['vendor-objectstack']` | 1,531,986 | 507,716 | Each line comes down by exactly what its payload lost, so each keeps the headroom it had: aggregate 507,889 bytes (0.71x the 695 KiB regression), `vendor-objectstack` 335,014 (0.47x). The other three per-chunk rows stayed in range and are untouched. ## Why On `main` at `cc378e93` the gate exits 2: its headroom-sensitivity half calls the aggregate ceiling (1560.4 KB of headroom, 2.25x) and the `vendor-objectstack` row (1327.4 KB, 1.91x) blind. The closure shrank by about a third since the objectui-era baseline, almost all of it `vendor-objectstack`, after `@objectstack/spec` moved to one shared-chunk ESM graph (`3a2d38c6e2`) and objectui moved into this repository as `ui/`. How the drop splits between those two is not measured. ## Readings (one container, one instrument) `pnpm --filter '@object-ui/console^...' build`, then `CI=true pnpm exec vite build` in `ui/apps/console`, both under `scripts/pm/os-verify-lock.sh` (VERDICT command-exit 0), reading `ui/apps/console/dist/eager-closure.json`. | build | eager gz bytes | chunks | `vendor-objectstack` gz | |---|---:|---:|---:| | `main` `cc378e93` (control) | 1,982,059 | 85 of 2387 | 507,716 | | `cc378e93` again, after the edit (re-read) | 1,982,059 | 85 of 2387 | 507,716 | | experiment: both `SystemFieldName` imports replaced by a local literal, uncommitted | 1,981,898 | 85 of 2387 | 507,693 | The experiment moved the aggregate by -161 bytes (largest moves: `vendor-objectstack` -23, `ui-components` -19, `index` -16): zero saving. On-disk proof before its build: marker count 1 and old-import count 0 in both files; restored with `git checkout HEAD --` under a trap, both blob hashes equal to HEAD's and `git diff HEAD` empty afterwards. The console aliases workspace packages to `src`, so the build read the mutated sources. ## Gate output on this branch `node scripts/check-eager-closure-budget.mjs` after the re-pin: closure ✅ 1935.6 KB / 2431.6 KB, per-chunk ✅ ×4, sensitivity ✅ ×5 (aggregate 0.71x, `vendor-objectstack` 0.47x). It still exits 1 on the membership half, which this PR does not touch (see Acceptance notes). ## Acceptance notes - The card's first step, repointing the two `SystemFieldName` imports at `@objectstack/spec/data`, is not possible: `packages/spec/src/data/index.ts` re-exports no `SystemFieldName` (it is declared in `packages/spec/src/system/constants/system-names.ts` and reaches consumers through `system/index.ts` only), so the repoint would fail type-check. It would also save nothing: `FlowRunner.tsx` and `flowResponse.ts` in app-shell still import `/system` by value, and the local-literal experiment above measured -161 bytes. Both import lines are left as they are. - The membership half reds on `main` before and after this change: "`packages/core` is declared in `framework` but 1 in `vendor-objectstack` (89 of its 90 modules landed in `framework`)". Which module moved is not measured here. Its fix lives in the grouping rules in `ui/apps/console/vite.config.ts`, outside this card's file surface, and the gate itself says not to move a ceiling to absorb it. - No workflow under `.github/workflows/` runs `check:eager-closure` today, so the gate is local-only until the ui CI lands; this re-pin makes it meaningful again when it does. - The spec half of #25925 (re-exporting `stripReadDecorations` / `ValidateDataIssueSchema` from a subpath the console already loads) is `domain:spec` work and is not addressed here. ## Tests - `./node_modules/.bin/vitest run --maxWorkers=2` in `ui/` over `scripts/__tests__/check-eager-closure-budget.test.ts` plus the five other test files that name the checker (`check-eager-locale-catalogues`, `check-side-effects-array`, `vite-declared-lazy-views`, `vite-types-zod-lazy`, `vite-ineffective-dynamic-imports`): Test Files 6 passed (6), Tests 300 passed (300). Before the literal move, the same run failed exactly the two cases that pin the rendered reading. - No changeset: `ui/scripts/**` belongs to the private `object-ui-monorepo` root and publishes nothing. --- _Generated by [Claude Code](https://claude.ai/code/session_01PykFDU1CQLdgAD1T6LPhLS)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent bd28708 commit ada3cbb

2 files changed

Lines changed: 81 additions & 14 deletions

File tree

‎ui/scripts/__tests__/check-eager-closure-budget.test.ts‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -833,9 +833,10 @@ describe('ceiling sensitivity, judged live (objectui#5924)', () => {
833833
// 3160.1 when the built-in designers left it, ruling 6070754914,
834834
// objectui#12030 down to 3049.3 on objectstack#22044, the payback of the
835835
// objectui#11717 raise, objectui#13410 down to 3000.1 when the chat UI left
836-
// the first load) — a rendering derived in the test would agree with the
837-
// renderer by construction and pin nothing.
838-
expect(result.message).toContain('3000.1');
836+
// the first load, objectstack#25925 down to 1935.6 after the spec's shared
837+
// chunks and the move into objectstack) — a rendering derived in the test
838+
// would agree with the renderer by construction and pin nothing.
839+
expect(result.message).toContain('1935.6');
839840
});
840841

841842
it('is exactly one regression wide, from either side of the line', () => {
@@ -1672,7 +1673,7 @@ describe('main', () => {
16721673
// about the FIXTURE while the gate under test behaved correctly. The number
16731674
// this case is actually about is "the report's chunk count, echoed".
16741675
expect(outputs.closure_chunks).toBe(String(fixture.files.length));
1675-
expect(outputs.closure_gzip_kb).toBe('3000.1');
1676+
expect(outputs.closure_gzip_kb).toBe('1935.6');
16761677
});
16771678

16781679
it('exits 1 — a verdict about the BUNDLE — when over budget', () => {

‎ui/scripts/check-eager-closure-budget.mjs‎

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,8 +1367,44 @@ import { isEntrypoint } from './invoked-as.mjs';
13671367
* 347,000 ceiling; the other three budgeted chunks did not move, so
13681368
* {@link PER_CHUNK_GZIP_CEILINGS} and {@link PER_CHUNK_BASELINE} stand. Not
13691369
* {@link REGRESSION_THIS_GATE_MUST_CATCH_BYTES}. No exemption was added.
1370+
*
1371+
* ## ⭐ RE-PINNED AFTER THE SPEC SHARED CHUNKS AND THE MOVE INTO objectstack (objectstack#25925)
1372+
*
1373+
* From 3,579,945 to 2,489,948: down by 1,089,997 bytes, exactly what the
1374+
* closure lost between {@link BASELINE}'s previous reading (`b6f11d3`,
1375+
* 3,072,056 across 85 of 2291 chunks) and `main` at `cc378e93` (1,982,059
1376+
* across 85 of 2387). Lowered by that amount, as the objectui#13410 entry
1377+
* above was: ⛔ not re-derived as the new reading plus half a regression and
1378+
* ⛔ not rounded. Left where it was, the ceiling sat 1560.4 KB over the
1379+
* reading, 2.25x {@link REGRESSION_THIS_GATE_MUST_CATCH_BYTES}, and
1380+
* {@link evaluateHeadroomSensitivity} called it blind (exit 2) on `main`:
1381+
* that is the re-pin the gate asked for.
1382+
*
1383+
* The `cc378e93` reading: `pnpm --filter '@object-ui/console^...' build`,
1384+
* then `CI=true pnpm exec vite build` in `ui/apps/console` (exit 0, both
1385+
* under `scripts/pm/os-verify-lock.sh`), reading
1386+
* `ui/apps/console/dist/eager-closure.json`. Almost all of the drop is
1387+
* `vendor-objectstack`, 1,531,986 at {@link PER_CHUNK_BASELINE} to 507,716.
1388+
*
1389+
* ⚠️ The two readings are two trees, ⛔ not a control and a change: between
1390+
* them `@objectstack/spec` moved to one shared-chunk ESM graph (`3a2d38c6e2`),
1391+
* so the bundler can merge the copies each self-contained subpath entry used
1392+
* to carry (the duplication objectstack#25925 names), and objectui moved into
1393+
* this repository as `ui/`, so `@objectstack/*` resolves from the workspace
1394+
* instead of a pinned build. How the drop splits between those is NOT
1395+
* MEASURED.
1396+
*
1397+
* Headroom 507,889 bytes = 0.71x {@link REGRESSION_THIS_GATE_MUST_CATCH_BYTES}
1398+
* over {@link BASELINE}: exactly the headroom the objectui#13410 entry left,
1399+
* because the ceiling came down by the aggregate's own delta.
1400+
*
1401+
* What moved with it: `vendor-objectstack`'s row in
1402+
* {@link PER_CHUNK_GZIP_CEILINGS} and {@link PER_CHUNK_BASELINE}, which the
1403+
* same run called blind (1.91x). Not the other three per-chunk rows, which
1404+
* stayed in range; not {@link REGRESSION_THIS_GATE_MUST_CATCH_BYTES}. No
1405+
* exemption was added.
13701406
*/
1371-
export const MAX_EAGER_CLOSURE_GZIP_BYTES = 3_579_945;
1407+
export const MAX_EAGER_CLOSURE_GZIP_BYTES = 2_489_948;
13721408

13731409
/**
13741410
* The measurement the ceiling above was derived from. Exported so the two
@@ -1381,6 +1417,18 @@ export const BASELINE = Object.freeze({
13811417
/**
13821418
* `emitEagerClosureReport`'s `eagerGzipBytes` on this commit.
13831419
*
1420+
* `cc378e93` is `main` in this repository, re-pinned with the ceiling it was
1421+
* lowered with (the objectstack#25925 entry on
1422+
* {@link MAX_EAGER_CLOSURE_GZIP_BYTES} carries the instrument and the reading
1423+
* it superseded, ⛔ not restated here). Measured on `main` itself, not on a
1424+
* branch commit: the pull request that re-pins it edits this file and its
1425+
* unit test only, which reach no bundler input, so it cannot move the figure
1426+
* it pins.
1427+
*
1428+
* ⚠️ The paragraph below describes the reading this one superseded, the
1429+
* previous baseline `b6f11d3` (3,072,056 across 85 of 2291 chunks), kept as
1430+
* its provenance.
1431+
*
13841432
* `b6f11d3` is objectui#13410's branch commit: `main` at `7981384` plus the
13851433
* change that takes the chat UI out of the first load, re-pinned with the
13861434
* ceiling it was lowered with (the objectui#13410 entry on
@@ -1547,10 +1595,10 @@ export const BASELINE = Object.freeze({
15471595
* and not from `main` once it is squash-merged — the dead end objectui#9355
15481596
* added `squashMerge` below to route around.
15491597
*/
1550-
gzipBytes: 3_072_056,
1598+
gzipBytes: 1_982_059,
15511599
chunks: 85,
1552-
totalChunks: 2291,
1553-
commit: 'b6f11d3',
1600+
totalChunks: 2387,
1601+
commit: 'cc378e93',
15541602

15551603
/**
15561604
* The squash merge that carried the reading above onto `main`, recorded when
@@ -1560,7 +1608,9 @@ export const BASELINE = Object.freeze({
15601608
*
15611609
* `null` since objectui#10996, and `null` again after objectui#11101,
15621610
* objectui#11438, objectui#11717, objectui#11798, objectui#11854,
1563-
* objectui#11939, objectui#12030 and objectui#13410, deliberately. This field can only ever be BACK-FILLED: a squash sha does
1611+
* objectui#11939, objectui#12030 and objectui#13410, deliberately; and `null`
1612+
* after objectstack#25925 because its reading was taken on `main` itself,
1613+
* which a `main` checkout resolves without a handle. This field can only ever be BACK-FILLED: a squash sha does
15641614
* not exist until the pull request merges, so the change that re-pins the
15651615
* field above ⛔ cannot write its own here. ⛔ Do not guess one: a wrong sha in
15661616
* this position is worse than an absent one, because it RESOLVES, and a
@@ -2147,7 +2197,17 @@ export const PER_CHUNK_GZIP_CEILINGS = Object.freeze({
21472197
//
21482198
// ⚠️ RAISED ×1.20 by objectui#12653 (2026-10-16), the maintainer's 20%
21492199
// ruling, from 1,555,705 (the entry on MAX_EAGER_CLOSURE_GZIP_BYTES).
2150-
'vendor-objectstack': 1_867_000,
2200+
//
2201+
// ⭐ LOWERED by objectstack#25925, from 1,867,000 by exactly the 1,024,270
2202+
// bytes this chunk lost between the baseline below and `main` at `cc378e93`
2203+
// (1,531,986 to 507,716; the objectstack#25925 entry on
2204+
// MAX_EAGER_CLOSURE_GZIP_BYTES names the instrument and the two changes that
2205+
// fall between them). Left where it was, the line sat 1327.4 KB over the
2206+
// reading, 1.91x REGRESSION_THIS_GATE_MUST_CATCH_BYTES, and the sensitivity
2207+
// half called it blind. Headroom 335,014 bytes = 0.47x
2208+
// REGRESSION_THIS_GATE_MUST_CATCH_BYTES over the baseline below, what this
2209+
// key had before, kept to the byte.
2210+
'vendor-objectstack': 842_730,
21512211
// ⭐ LOWERED, and RE-KEYED, by objectui#7479 — this line used to read
21522212
// `'i18n-locales': 465_000` and budget TEN catalogues. Nine of them are
21532213
// `import()`ed on demand now, so the chunk that name pointed at no longer
@@ -2318,12 +2378,14 @@ export const PER_CHUNK_GZIP_CEILINGS = Object.freeze({
23182378
* the same build, when the objectstack#22044 payback lowered both lines; the
23192379
* other three keys moved by at most 846 bytes across its two builds and stayed
23202380
* where they were. objectui#13410 re-pinned the aggregate onto
2321-
* BASELINE's `b6f11d3` and left every key where it was: across its two builds
2381+
* `b6f11d3` and left every key where it was: across its two builds
23222382
* `vendor-objectstack`, `framework` and `i18n-locale-en` moved by 0 bytes and
23232383
* `ui-components` by +12,267 (the markdown modules its entry on
23242384
* {@link MAX_EAGER_CLOSURE_GZIP_BYTES} attributes), every ceiling stayed in
2325-
* range, and no ceiling moved. `vendor-objectstack` is therefore still the
2326-
* `5488ae7` reading moved by objectui#12626's measured delta. The aggregate is the later reading for every other key:
2385+
* range, and no ceiling moved. objectstack#25925 re-pinned the aggregate onto
2386+
* BASELINE's `cc378e93` and `vendor-objectstack` with it, from the same build,
2387+
* when both lines had drifted blind; the other three keys stayed in range and
2388+
* where they were. The aggregate is the later reading for every other key:
23272389
* `bbf6b02d9` (2026-09-13, objectui#9251) for `ui-components`, and `3f775eeb8`
23282390
* for `framework`. ⚠️ `i18n-locale-en`'s commit was `755d34a5f` when it
23292391
* was taken and the aggregate has moved on since, which is exactly why the two
@@ -2399,7 +2461,11 @@ export const PER_CHUNK_BASELINE = Object.freeze({
23992461
// PER_CHUNK_GZIP_CEILINGS). ⚠️ So this is no longer one build's reading: it
24002462
// is the `5488ae7` reading plus the next.2 bump's measured delta, which
24012463
// keeps the ceiling-minus-baseline gap this key carried.
2402-
'vendor-objectstack': 1_531_986,
2464+
//
2465+
// Re-pinned by objectstack#25925 onto `cc378e93`, the same console build as
2466+
// BASELINE above, from 1,531,986 to that build's 507,716, with its ceiling.
2467+
// It is one build's reading again.
2468+
'vendor-objectstack': 507_716,
24032469
// `755d34a5f` (objectui#7479) — the SAME console build as
24042470
// BASELINE above, so the two are directly comparable, and the same instrument
24052471
// and container as the control build it is subtracted from. It supersedes

0 commit comments

Comments
 (0)