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 #13447
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 915e9404)
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 #13474 does not touch the file at this reading) and in seat 4's PR #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
objectstack-fleet commentedon Oct 25, 2026
Claim amendment ·
domain:ui#4· 2026-10-25T02:32Z · amends the claim6392281867(append-only; the claim's other lines stand)Premise fell (report
6392390016).@objectstack/spec/dataexports noSystemFieldName(checked at runtime and ind.ts, at objectui's pin, the card's pin and objectstackmain). Taking both imports off/systemmeasured +382 B gz on the eager closure: zero saving. The repoint and the ceiling move are dropped, and no PR is owed for them.Narrowed to a reading (no PR, no commit): an attribution of the console production build. It names which eager modules keep
/system(and/kernel,/api) invendor-objectstack, with gz bytes per subpath share where the build can give them. The reading goes in a newos-dev-reporton this card. The seat then carries the number to objectstack'sdomain:speclane (the shared-chunk ESM build,stripReadDecorations/ValidateDataIssueSchemare-exports) and closes or re-queues this card to match.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
os-dev-report
{ "issue": 13447, "status": "reading", "branch": "claude/project-thread-wqfjll", "pr": null, "session": "session_01DRkSLfTy6PpiFqHxtNBjSa", "premise_still_valid": false, "summary": "Attribution reading under the amended claim (option C). On objectui main 6f629a7 the console's eager closure is 3,106,386 bytes gz across 85 of 2291 chunks; vendor-objectstack is 1,642,324 gz and holds 45 modules, nine of them @objectstack/spec subpath bundles. /system is the largest share (about 339 KB gz) and stays eager through exactly four objectui modules: flowResponse.ts and FlowRunner.tsx (chunk useConsoleActionRuntime: translateFlow, FLOW_SCREEN_FIELD_COPY_KEYS, resolveFlowScreenFieldOptions) plus the two SystemFieldName imports. That is why the earlier experiment that removed only the SystemFieldName pair read +382: the flow-runtime pair still holds it. /kernel (about 246 KB gz) is held by ten eager objectui modules, eight of them for stripReadDecorations alone, the others for ManifestSchema, deriveNamespaceFromPackageId, validateObjectNamespacePrefix and MetadataProtectionFields. /api (about 92 KB gz) cannot leave from the objectui side at all: @objectstack/client (WELL_KNOWN_CAPABILITY_KEYS, MetadataEventSchema, DataEventSchema, BulkDataEventSchema) and @objectstack/formula (StandardErrorCode) import it inside vendor-objectstack itself, besides four objectui modules. The card's whole-bundle figures overstate what lands but not by an order: rolldown keeps 53 percent of /system's 3,020,046 source bytes, 52 percent of /kernel's 2,231,176 and 20 percent of /api's 2,130,364 (rendered bytes after tree-shaking). Per-importer byte splits inside one subpath are NOT MEASURED: tree-shaken bytes are shared by every importer of the bundle, so a split needs one ablation build per importer.", "readings": { "build": "objectui main 6f629a7, spec pin per .objectstack-sha at that commit; console production build", "eager_closure": "3,106,386 B gz, 85 of 2291 chunks", "vendor_objectstack_gz": 1642324, "share_method": "rendered bytes per module from the build (after tree-shaking); gz share = rendered share x the chunk's 1,642,324 gz bytes (estimate); gz-alone = that module's rendered code gzipped by itself (an upper bound: the nine add up to more than the chunk)", "spec_shares_in_vendor_objectstack": [ "/system rendered 1,597,279 (20.7%) ~339,225 gz, gz-alone 424,409", "root rendered 1,404,285 (18.2%) ~298,237 gz, gz-alone 380,016", "/kernel rendered 1,160,462 (15.0%) ~246,455 gz, gz-alone 321,580", "/ui rendered 847,848 (11.0%) ~180,063 gz, gz-alone 231,003", "/data rendered 744,773 (9.6%) ~158,172 gz, gz-alone 207,294", "/shared rendered 669,435 (8.7%) ~142,172 gz, gz-alone 184,712", "/api rendered 433,184 (5.6%) ~91,998 gz, gz-alone 123,344", "/automation rendered 238,531 (3.1%) ~50,658 gz, gz-alone 64,698", "/security rendered 63,641 (0.8%) ~13,516 gz, gz-alone 19,670", "spec total: 7,159,438 of 7,733,075 rendered bytes in the chunk (92.6%); the rest is @objectstack/formula, @objectstack/client, zod, cel-js, @objectstack/core logger" ], "system_eager_importers": [ "packages/app-shell/src/utils/flowResponse.ts (chunk useConsoleActionRuntime): translateFlow", "packages/app-shell/src/views/FlowRunner.tsx (chunk useConsoleActionRuntime): FLOW_SCREEN_FIELD_COPY_KEYS, resolveFlowScreenFieldOptions, translateFlow", "packages/permissions/src/MePermissionsProvider.tsx (chunk ui-components): SystemFieldName", "packages/plugin-list/src/ListView.tsx (chunk plugins-views): SystemFieldName", "lazy only: metadata-form-i18n.ts, previews/doc-draft.ts (register-builtin-designers), @objectstack/lint, clientValidation.ts dynamic; packages/types nested-component-walk.ts is not in the output" ], "kernel_eager_importers": [ "stripReadDecorations only: preview/capabilityLint.ts (index), preview/securityPostureLint.ts (ObjectView), metadata-admin/PermissionMatrixEditor.tsx (src), views/runtime-metadata-persistence.ts (runtime-metadata-persistence), data-objectstack draft-envelope.ts and index.ts (data-adapter)", "preview/DraftChangesPanel.tsx (ObjectView): MetadataProtectionFields, stripReadDecorations", "metadata-admin/package-schema.ts (packagedActions): ManifestSchema", "metadata-admin/PackageFormDialog.tsx (packagedActions): ManifestSchema, deriveNamespaceFromPackageId", "studio-design/packages-io.ts (packages-io): ManifestSchema, deriveNamespaceFromPackageId, validateObjectNamespacePrefix", "lazy only: metadata-admin/createBody.ts, studio-design/ObjectListViewInspector.tsx, @objectstack/lint; services/MetadataService.ts is not in the output" ], "api_eager_importers": [ "@objectstack/client dist (vendor-objectstack): WELL_KNOWN_CAPABILITY_KEYS, MetadataEventSchema, DataEventSchema, BulkDataEventSchema", "@objectstack/formula dist (vendor-objectstack): StandardErrorCode", "packages/data-objectstack/src/index.ts (data-adapter): ValidateDataIssueSchema", "packages/data-objectstack/src/metadata-client.ts (data-adapter): FlowRegistrationSchema, GetMetaItemLayeredResponseSchema", "metadata-admin/DraftConflictDialog.tsx (packagedActions): GetMetaItemResponseSchema, MetadataConflictErrorSchema", "packages/core/src/utils/column-sortability.ts (framework): re-exports FIELD_UNSORTABLE_VIRTUAL_TYPE, FIELD_SORTABLE_UNPROVISIONED_ANCHOR" ], "also_noted": "the platform's own packages pull other subpaths into the same chunk: @objectstack/formula imports the spec root (3 sites), /data (7), /api (1), /security (2); @objectstack/client imports /data and /api. Root and /data stay eager through them whatever objectui does." }, "tests": "Instrument: the console's own apps/console/vite.config.ts run through Vite's build() with one read-only module-dump plugin appended (generateBundle: per-module renderedLength, code gzipped alone, getModuleInfo importers / dynamicImporters), under scripts/pm/os-verify-lock.sh, after `CI=true pnpm exec turbo run build --filter=@object-ui/console^... --concurrency=2` (VERDICT command-exit 0). It wrote eager-closure.json 3,106,386 B gz / 85 of 2291 / vendor-objectstack 1,642,324. Calibration: the console's ordinary `CI=true pnpm exec vite build` in apps/console on the same tree (VERDICT command-exit 0) wrote the same three figures to the byte. Worktree clean at 6f629a7 throughout (git status empty). Bindings per importer read from the source import statements and the pinned client/formula dist.", "gates": "n/a: reading only, no diff, no PR", "dogfood_battery": "n/a: no PR", "mcp_calls": "0 this round (2 read-only issue_read calls in the previous round)", "api_writes": "1: this os-dev-report comment via the fleet-write relay (POST issues/13447/comments)", "open_questions": [ { "question": "What should the objectstack domain:spec card promise?", "options": [ "A: the shared-chunk multi-entry ESM build (the card's L item): it is the only lever that touches the duplication across all nine bundles, including root and /data that @objectstack/formula and @objectstack/client hold eager", "B: targeted re-exports so objectui can drop /system and /kernel: translateFlow, FLOW_SCREEN_FIELD_COPY_KEYS, resolveFlowScreenFieldOptions, SystemFieldName, stripReadDecorations, ManifestSchema, deriveNamespaceFromPackageId, validateObjectNamespacePrefix, MetadataProtectionFields from an already-eager subpath; ceiling of the gain about 585 KB gz (339 + 246) minus whatever those symbols drag in at their new home, NOT MEASURED", "C: B for /kernel only (one symbol, stripReadDecorations, covers 8 of its 10 eager importers), leaving /system to A" ], "recommendation": "A as the card, with the /system and /kernel importer lists above as its acceptance reading; B and C buy less than they look because each re-exported symbol may pull its schema graph into the new subpath's bundle, and /api cannot leave without client and formula changing too. Seat to route; no ruling made here." } ], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Blocked ·
domain:ui#4· 2026-10-25T03:16ZThe objectui half as filed is void.
@objectstack/spec/dataexports noSystemFieldName, and taking both imports off/systemmeasured zero (6392390016). The attribution reading (6392630038) shows what actually decidesvendor-objectstack: the spec's self-contained subpath bundles, which@objectstack/formula/@objectstack/clientalso hold eager. objectstack#8133 is the carrier (spec shared-chunk build, claimed and in flight on objectstack'sdomain:speclane); the reading is posted there.Blocked-by: objectstack-ai/objectstack#8133
When it unblocks: once objectui's
.objectstack-shacarries #8133, rebuild the console, readeager-closure.json, and lowerMAX_EAGER_CLOSURE_GZIP_BYTES/BASELINEby the measured drop (objectui#11762's rule). The claim is released in this stroke:pm:dispatched→pm:blocked, assignee cleared.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Unlock scan: still blocked · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T16:59Z⛔ Not a claim.
@objectstack/specships 18 self-contained entry bundles with no shared chunks, so a consumer mixing entry points gets differentConnectorSchema/defineConnectorobjects (measured) objectstack#8133 is closed, and its fix is3a2d38c6e2(spec shared chunks, build(spec): one module graph with shared chunks, so each schema ships once and is one object across entries objectstack#25748). It is not in objectui's.objectstack-sha5e7cf63e71(compare: behind 1).vendor-objectstackand re-baselines the eager-closure ceilings. Whatever eager-closure work is still owed here reads that measurement after it lands.Blocked-by: #13544
Generated by Claude Code