Repository navigation
console first load: @objectstack/spec arrives as self-contained subpath bundles that duplicate each other; three tiny imports pull /system, /kernel and /api whole into the eager closure #25925
Description
维护者速读
生产构建实测:首屏急加载闭包 3,248 KB gzip(78/2,262 个 chunk),其中 vendor-objectstack 一个 chunk 1,578.7 KB gzip = 48.6 %。原因是 spec 的 dist 每个子路径入口都是自包含 bundle,同一个 schema 在多个 bundle 里各带一份,打包器无法去重;而 objectui 为了一个常量 SystemFieldName 从 @objectstack/spec/system(833 KB gz)整包导入,为 68 行的 stripReadDecorations 整包导入 /kernel(633 KB gz),为 ValidateDataIssueSchema 整包导入 /api(602 KB gz)。短期改三处导入即可,长期要 spec 改构建。
Measured (console production build on 2026-10-24, HEAD 7981384, spec pin 915e940)
apps/console/dist/eager-closure.json: 78 eager chunks of 2,262, 3,326,131 bytes gzipped;pnpm check:eager-closurepasses at 3248.2 KB against the 3744.1 KB ceiling. Largest eager chunks (gz KB): vendor-objectstack 1578.7, ui-components 289, plugin-chatbot 170 (objectui#13410), plugin-grid 123, useMetadata 112, vendor-markdown 100.- The pinned spec dist (
node_modules/.cache/objectstack/spec/dist) ships 24 JS files, 9.76 MB gzipped in total; each subpath entry is self-contained:system/index.mjs833 KB gz,index.mjs826,kernel/index.mjs633,api/index.mjs602,shared/index.mjs446,data/index.mjs438,ui/index.mjs412,automation/index.mjs147. - Duplication is real, not inferred:
grep -l "FieldSchema = " dist/index.mjs dist/*/index.mjs | wc -lgives 15 bundles each carrying their ownFieldSchema;ObjectSchema8,PageComponentSchema6,retiredKey17. Different module ids, so rolldown keeps every copy. - objectui runtime value imports by subpath (non-test source):
/ui402,/data227,/automation40,/kernel35,/system27,/api22,/shared13,/security5,/contracts5,/identity4. - The eager pulls:
packages/permissions/src/MePermissionsProvider.tsxandpackages/plugin-list/src/ListView.tsxbothimport { SystemFieldName } from '@objectstack/spec/system'whiledata/index.mjs(already eager) exports the same constant;packages/app-shell/src/services/MetadataService.tsandpackages/data-objectstack/src/index.tsimportstripReadDecorationsfrom@objectstack/spec/kernel(the only exporter; the function is 68 lines inspec/src/kernel/metadata-read-decorations.ts);packages/data-objectstack/src/index.tsimportsValidateDataIssueSchemafrom@objectstack/spec/api(only exporter).
Recommendation
- (S, objectui) Point the two
SystemFieldNameimports at@objectstack/spec/data; rebuild and readeager-closure.json— that single reading settles how much of the 833 KB/systembundle leaves the closure (未实测 until then). - (S, cross-repo) Ask spec to re-export
stripReadDecorationsandValidateDataIssueSchemafrom a subpath the console already loads (/dataor/shared), or decide on the objectui side to keep only the type and a local thin implementation. - (L, cross-repo) spec builds one shared-chunk multi-entry ESM graph instead of self-contained bundles — the generalisation of the objectstack#22044 payback that objectui#11762 tracks (that one change recovered 226 KB on
vendor-objectstack). - Then lower
MAX_EAGER_CLOSURE_GZIP_BYTESand re-pinBASELINEinscripts/check-eager-closure-budget.mjsby the measured amount, per objectui#11762's rule.
Refs: objectui#11798, objectui#11942, objectui#11939, objectui#11762, objectui#13410. None of them names the subpath duplication or these three pulls.
Filed by the read-only whole-repo review session https://claude.ai/code/session_01BDtwYUWhLGyWLzYQjZ95Cf on 2026-10-24; the maintainer approved filing (「同意,创建任务」). Full evidence files sit in that session's scratchpad (objectui-review-report.md, findings-*.md). ⛔ Not a claim; for triage to grade and route.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 24, 2026
Triage: first grade —
enhancement·priority:p2·domain:ui·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-24T15:04Z⛔ Not a claim, ⛔ not a dispatch.
findingcomes off.domain:speccomes off: one lane per card.SystemFieldNameimports at@objectstack/spec/data, rebuild, and readeager-closure.json. Then lowerMAX_EAGER_CLOSURE_GZIP_BYTESby the measured amount (objectui#11762's rule).stripReadDecorationsandValidateDataIssueSchemafrom a loaded subpath; spec's shared-chunk ESM build, L) is objectstack'sdomain:specwork. It is filed there once the objectui reading gives the number.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 1 · 2026-10-25T02:07Z
Session:
session_01DRkSLfTy6PpiFqHxtNBjSa(the card session that works this card; claim written by thedomain:uiseat 4 sessionsession_01XWGTsmqrtrt1Zqh1ioWqsT)Account:
os-elon-muskBranch:
claude/project-thread-wqfjll(platform-assigned at spawn; the card session can push only this branch)Worktree:
objectui-issue-13447Domain:
domain:uiSeat:
domain:ui#4File surface: the
SystemFieldNameimport line inpackages/permissions/src/MePermissionsProvider.tsxand inpackages/plugin-list/src/ListView.tsx(that line only);MAX_EAGER_CLOSURE_GZIP_BYTES/BASELINEinscripts/check-eager-closure-budget.mjsand the tests that pin them (scripts/__tests__/check-eager-closure-budget.test.ts,scripts/__tests__/ci-cd-pipeline-doc.test.ts) and the doc line they read;.changeset/13447-*.mdif a published package changes (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6385771626
Premise: holds — on objectui
mainc85408fMePermissionsProvider.tsx:23andListView.tsx:48importSystemFieldNamefrom@objectstack/spec/system; the ceiling isMAX_EAGER_CLOSURE_GZIP_BYTES = 3_579_945atcheck-eager-closure-budget.mjs:1371Serial constraints cleared:
ListView.tsxis in seat 1's objectui#13442 surface (its PR objectstack-ai/objectui#13474 does not touch the file at this reading) and in seat 4's PR objectstack-ai/objectui#13486 (in the merge queue; it edits the@object-ui/coreand@objectstack/spec/uiimport lines, not line 48) — this card edits one other import line; mergemainbefore opening and again before landingWrites: all PR, comment and label writes go only through objectstack's relay (
scripts/pm/fleet-write); never write with GitHub MCP.6385771626: this card is the objectui half only — repoint the two imports, rebuild, readapps/console/dist/eager-closure.json, then lower the ceiling by the measured amount (objectui#11762's rule).vendor-objectstackchunk) from a real production build on the same machine. If the repoint saves nothing measurable, do not lower the ceiling; report the reading and stop.stripReadDecorations/ValidateDataIssueSchemafrom a loaded subpath; spec's shared-chunk ESM build). The seat passes the measured number to objectstack'sdomain:speclane after landing; the dev files nothing there.objectstack-fleet commentedon Oct 25, 2026
os-dev-report
{ "issue": 13447, "status": "done", "branch": "claude/project-thread-wqfjll", "pr": null, "session": "session_01DRkSLfTy6PpiFqHxtNBjSa", "premise_still_valid": false, "summary": "Premise falsified twice; no code change and no PR, per the claim's 'if it saves nothing, don't touch the ceiling; report the readings and stop'. (1) `@objectstack/spec/data` does not export `SystemFieldName`: the constant is declared in packages/spec/src/system/constants/system-names.ts and data/index.ts re-exports nothing by that name at e649c2d9 (objectui's pin), 915e9404 (the card's pin) or objectstack origin/main 25f88e8. The `SystemFieldName = {` the card found in dist/data/index.mjs is a bundled private copy used by data's own injected-system-column code, not an export. Runtime, from packages/permissions: `'SystemFieldName' in await import('@objectstack/spec/data')` = false, `/system` = true, root `@objectstack/spec` = false; dist/data/index.d.ts has zero mentions. So the claimed one-line repoint would fail type-check and resolve to undefined. (2) Even taken off /system, the two imports pull nothing that is not already eager: an uncommitted experiment build that replaced both imports with a local `{ OWNER_ID: 'owner_id' }` literal moved the eager closure by +382 bytes gzipped, not down. The /system code stays in vendor-objectstack because other eager modules import /system values (FlowRunner, flowResponse, metadata-form-i18n, packages/types nested-component-walk are the candidates; not attributed below the chunk), and rolldown tree-shakes the self-contained subpath bundle, so the 833 KB whole-bundle figure is not what lands (the system-only marker strings 'Vector clock' and 'Backup retention' are absent from the eager chunks of the main build; 'Log destination' is present).", "tests": "Two console production builds, same container, same instrument, each `CI=true NODE_OPTIONS=--max-old-space-size=6144 pnpm exec turbo run build --filter=@object-ui/console... --concurrency=2` under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0 both; 35/35 tasks), reading apps/console/dist/eager-closure.json. Control = main c85408f: 3,086,819 bytes gz across 85 of 2291 chunks, vendor-objectstack 1,622,904. Experiment = c85408f plus the two imports swapped for a local literal (uncommitted; on-disk proof: marker grep 1 and old import grep 0 in both files before the build; restored by trap with `git checkout HEAD --`, `git diff HEAD` empty after): 3,087,201 across 85 of 2291, vendor-objectstack 1,623,222. Delta: aggregate +382, vendor-objectstack +318, ui-components -52, every other chunk name within +-10. No test suites run: nothing committed.", "gates": "n/a: no diff, no commit, no PR. `pnpm check:eager-closure` not re-run; the ceiling and BASELINE are untouched as the claim directs for a zero saving.", "dogfood_battery": "n/a: no PR", "mcp_calls": "2: mcp__github__issue_read get and get_comments on objectui#13447 (read-only; no write tool)", "api_writes": "1: this os-dev-report comment via the fleet-write relay (POST issues/13447/comments)", "open_questions": [ { "question": "Does the /system part of the card survive at all, and if so where?", "options": [ "A: close the SystemFieldName item as measured zero; move the first-load effort to the objectstack domain:spec half (shared-chunk multi-entry ESM build), which is what actually decides vendor-objectstack's size", "B: ask spec to re-export SystemFieldName from /data anyway (tidiness only; measured saving 0)", "C: before either, have someone attribute which eager modules keep /system in vendor-objectstack (a module-level dump of the console build), so the /system share is a number rather than a candidate list" ], "recommendation": "C then A: the experiment shows these two imports are not the lever, and the card's 833 KB is a whole-bundle figure that tree-shaking does not deliver; the attribution reading is cheap and tells the spec card what to promise. Seat to route; no ruling made here." } ], "out_of_scope_findings": [] }Generated by Claude Code
7 remaining items
objectstack-fleet commentedon Oct 26, 2026
Unlock scan: blocker moot, waiting on the transfer · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T02:53Z⛔ Not a claim.
not_planned, because there is no pin left: objectui is now objectstack'sui/workspace, and the spec shared chunks (3a2d38c6e2) are in the same tree. The measurement this card waits for is now taken in objectstack.claude/*branches; the maintainer archives (parent #25752 steps 7–8) #25854's transfer, and its state is set when it lands in objectstack.Blocked-by: #25854
Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Transferred 2026-10-26T04:15Z from objectstack-ai/objectui#13447, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the
ui/workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.Paths. Read every repository path in the body with a
ui/prefix:packages/permissions/src/MePermissionsProvider.tsxis nowui/packages/permissions/src/MePermissionsProvider.tsx;packages/plugin-list/src/ListView.tsxis nowui/packages/plugin-list/src/ListView.tsx;packages/app-shell/src/services/MetadataService.tsis nowui/packages/app-shell/src/services/MetadataService.ts;packages/data-objectstack/src/index.tsis nowui/packages/data-objectstack/src/index.ts;scripts/check-eager-closure-budget.mjsis nowui/scripts/check-eager-closure-budget.mjs.Not found under
ui/or at the root onmaine167956e3f:apps/console/dist/eager-closure.json; re-check that premise before work starts.No stale
pm:dispatchedor assignee to strip.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Unlock scan: unlocked →
pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T07:57Z⛔ Not a claim, ⛔ not a dispatch.
claude/*branches; the maintainer archives (parent #25752 steps 7–8) #25854 (the transfer) is done: this card is here, in the same tree as the spec's shared-chunk build (3a2d38c6e2). The dev re-measures first: the card's numbers (vendor-objectstack1,578.7 KB gz) are from objectui before the shared chunks and before the merge. If the eager closure is already within budget, the card closes on that reading. Grade unchanged (p2 ·domain:ui).Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 1
Session:
session_017iXjUm1rujwDk7f3KT1Pkk(seat); implementing card threadsession_01PykFDU1CQLdgAD1T6LPhLSAccount:
os-steveBranch:
claude/project-thread-oaf230(platform-assigned card-thread branch; a card thread can push only its assigned branch, and the name carries no issue number, so this claim is the identity record)Worktree: the card thread's own container
Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/permissions/src/MePermissionsProvider.tsxandui/packages/plugin-list/src/ListView.tsx(one import line each:SystemFieldNamefrom@objectstack/spec/datainstead of/system), the file that holdsMAX_EAGER_CLOSURE_GZIP_BYTES(lowered by the measured amount, objectui#11762 rule),scripts/sdui-manifest.record.json(derived hash), changeset. The PR states theeager-closure.jsonreading before and after. The spec half (re-exportingstripReadDecorations/ValidateDataIssueSchemafrom a loaded subpath) isdomain:specwork, filed once this reading gives the number; not in this card.plugin-listis seat 2's package (one import line; seat 2 told) (stop on breach; explain in the report). ⛔ui/.github/**and the root.github/workflows/ci.ymlare out of bounds (maintainer's word, ui-merge epic in flight). Changeset in the root.changeset/.Container & model:
S,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no (import paths and a budget constant; no exported type change)
Metadata-protocol: none
Responsibility:
n/a: renderer defect in ui/, the producing code is the cited ui file; no platform path covers it; reached through the public ConsoleThread-read: 6411044444
Premise: holds (read-only check by the seat at
origin/main: bothSystemFieldNameimports still read@objectstack/spec/system2026-10-26T12:23Z)Serial constraints cleared: manifest-hash single token: this PR re-records the sdui hash, so it enters the merge queue only when the seat hands it the token (order on the seat post); no open PR edits these two import lines (open-PR file scan 2026-10-26T12:23Z)
Dispatch order handed to the card thread by the project coordinator (three partitions: ruling / mechanism hypotheses / suggested route); the dev does not claim, and starts only once this claim names its branch.
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25925, "status": "done", "branch": "claude/project-thread-oaf230", "pr": "https://github.com/objectstack-ai/objectstack/pull/26127", "session": "session_01PykFDU1CQLdgAD1T6LPhLS", "premise_still_valid": false, "summary": "Measured first, per the seat's acceptance. The repoint half is void: packages/spec/src/data/index.ts exports no SystemFieldName on main cc378e93 (declared in system/constants/system-names.ts, reached through system/index.ts only), and an uncommitted experiment replacing both imports with a local literal moved the eager closure by -161 B gz, because FlowRunner.tsx and flowResponse.ts still import /system by value. The ceiling half holds: on main the gate exits 2, its sensitivity half calling the aggregate ceiling (2.25x) and the vendor-objectstack row (1.91x) blind after the spec shared-chunk build and the move into ui/. PR #26127 lowers both by exactly what their payload lost (3,579,945 to 2,489,948; 1,867,000 to 842,730), keeping each line's previous headroom, re-pins BASELINE and PER_CHUNK_BASELINE vendor-objectstack onto cc378e93, and moves the two rendered-reading literals in the unit test. Touches only ui/scripts/check-eager-closure-budget.mjs and its test: no ui/packages change, no sdui record change, no merge-queue token needed. PR body says Part of #25925, not Fixes: the seat decides whether the card closes or goes back to triage.", "tests": "Readings, one container: `pnpm --filter '@object-ui/console^...' build` (os-verify-lock VERDICT command-exit 0, 720s), then `CI=true pnpm exec vite build` in ui/apps/console (VERDICT command-exit 0), reading ui/apps/console/dist/eager-closure.json. Control main cc378e93: 1,982,059 B gz, 85 of 2387 chunks, vendor-objectstack 507,716. Experiment (both SystemFieldName imports -> local literal; marker grep 1 and old import grep 0 in both files before the build; trap restore with git checkout HEAD --, blob hashes equal HEAD and git diff HEAD empty after): 1,981,898, 85 of 2387, vendor-objectstack 507,693, delta -161. Re-read after the edit (same tree content for the bundler): 1,982,059 to the byte. Gate after the re-pin: closure pass 1935.6 / 2431.6 KB, per-chunk pass x4, sensitivity pass x5 (0.71x, 0.47x), exit 1 on the membership half only (pre-existing on main). Unit tests at 6a75282d: `./node_modules/.bin/vitest run --maxWorkers=2` in ui/ over check-eager-closure-budget, 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 2 rendered-reading cases. No ablation: the diff changes budget constants and pins, no tested behaviour.", "gates": "Local derived set at 6a75282d (`node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, 18 families), each exit captured before any pipe: check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-undeclared-dep-imports (+ --self-test), check:cross-package-test-inputs, check:driver-memory-census, check:engine-double-contract, check:gitlink-declared, check:nul-bytes, check:published-files, check:query-options-erasure, check:refd-timer-probe, check:tier-file-adoption, check:type-check-coverage, check:type-check-debt, check:watch-hint-literal, check:where-matcher: all exit 0. `--ran` with exit codes: 18 derived, 18 run, 0 NOT-MEASURED (a derived zero). CI families: in_progress at report time, read from the PR's check-runs by the seat.", "dogfood_battery": "n/a: no `!` in the PR title and no (narrowing) arm", "mcp_calls": "5: mcp__github__issue_read get, get_comments x2 on #25925, get_labels on 26127 (failed, not an issue), mcp__github__pull_request_read get on #26127; all read-only, no write tool", "api_writes": "2: pr_create #26127 via the fleet-write relay (with-fleet.sh --via dispatch, labels skip-changeset, assignees os-steve; read-back identical, 5094 bytes) and this os-dev-report comment via post-stamped (POST issues/25925/comments); plus git push of the branch (not a REST write)", "open_questions": [ { "question": "What happens to the card once #26127 lands?", "options": [ "A: close #25925 on #26127: the repoint item is void with evidence and the ceiling item is done; the spec half is filed separately as triage already said", "B: send it back to triage for the spec half (stripReadDecorations / ValidateDataIssueSchema re-exports) under this number" ], "recommendation": "A, because triage already split the spec half off this card and both ui items are now settled by measurement. Seat to route." } ], "out_of_scope_findings": [ "class: a · reach: `node scripts/check-eager-closure-budget.mjs` in ui/ after a console build of main cc378e93 prints a red membership verdict (`packages/core` declared in `framework`, 1 of 90 modules in `vendor-objectstack`) and exits non-zero before and after this PR · evidence: gate output in the PR body; which module moved NOT MEASURED; fix site is the grouping rules in ui/apps/console/vite.config.ts · dedupe words: eager-closure membership packages/core framework vendor-objectstack", "carrier: none · noted, not filed: no workflow under .github/workflows runs check:eager-closure today (grep of .github/workflows and ui/.github finds no caller), so the console budget gate is local-only until the ui CI port lands; recorded in the PR's Acceptance notes" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim amendment (seat
domain:ui#1, 2026-10-26T13:11Z): amends the claim6415922107after the measurement it asked for (report 6416818207). Append-only; the lines not named here stand.Readings (same container, same instrument):
mainatcc378e931,982,059 B gzip; with the twoSystemFieldNameimports swapped 1,981,898 B. A difference of 161 B is zero saving.File surface, replaced: the two import-line edits (
MePermissionsProvider.tsx,ListView.tsx),scripts/sdui-manifest.record.jsonand the changeset are dropped. The surface is nowui/scripts/check-eager-closure-budget.mjsand its unit testui/scripts/__tests__/check-eager-closure-budget.test.ts.What changes: the aggregate ceiling and
vendor-objectstack's per-chunk row come down by exactly the bytes the closure lost since the previous baseline, keeping their old headroom.BASELINEis re-pinned tocc378e93. Onmainthe gate's sensitivity half exits 2: it calls the aggregate (2.25x) andvendor-objectstack(1.91x) blind.Serial constraints: no
ui/packages/**source changes, so the sdui manifest hash does not move and no token is needed. Lands as an ordinary queue PR (#26127). The spec half named in the claim is moot, since@objectstack/specalready ships one shared-chunk graph.Card disposition:
Part of #25925in the PR. The seat closes the card when #26127 lands, because the premise's duplication has gone and the gate it left blind is re-pinned.objectstack-fleet commentedon Oct 26, 2026
Seat close-out ·
domain:uiseat 1 · 2026-10-26T13:46Z: PR #26127 merged at 2026-10-26T13:46Z (merge commitada3cbb02a33), carryingPart of #25925. The seat closes the card as the claim amendment 6416858265 said it would.main.@objectstack/specnow ships one shared-chunk ESM graph. The measured saving from the import swap the card proposed was 161 B, which is zero.vendor-objectstack's row came down by the bytes lost, keeping the headroom they had.BASELINEis nowcc378e93.main, is console: eager-closure membership check is red on main, with one packages/core module grouped into vendor-objectstack instead of framework #26131. The gate still runs in no workflow, which is noted on console: eager-closure membership check is red on main, with one packages/core module grouped into vendor-objectstack instead of framework #26131 for the ui CI port.No remaining item is owed, so the card closes as completed and
pm:dispatchedcomes off. If triage reads a remaining item differently, reopen it with that item named.