This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
Commit 7c83e70
test(cutover-prep F): ui tests pay the first load of the specifiers check:test-source-alias names at module scope (objectstack#25763) (#13513)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoHZM3TyZPr2yRmDU4cH4TJH)_
Part of objectstack#25763 (cutover prep F of the objectui → objectstack
`ui/` merge). Part of objectstack#25677.
Clause-②: no
Metadata-protocol: none
## What changes
In the merged tree every `@objectstack/*` import in a ui test resolves
to a workspace package's `dist`, so a first load paid inside a test
body, a `vi.mock` factory or after `vi.resetModules()` bills a cold
transform to a clocked window (verify runs 8 and 11 reddened Test UI
3/16 on exactly this shape). objectstack's `check:test-source-alias`
names these sites.
Each of the 26 files below now also loads the same specifier with a
module-scope side-effect import, so the transform is paid during
collection, which vitest clocks against nothing. Every dynamic import
stays where it was: this only decides where the first load is paid. No
timeout is widened, nothing is skipped, and no production code changes.
The changeset is empty-frontmatter (test-only, releases nothing).
The 30 findings fall in three shapes, each with its own one-line comment
in the file:
- **in a test body or a helper a test awaits** (13 files):
`@objectstack/spec`, `spec/ui`, `spec/data`, `spec/api`, `spec/kernel`,
`spec/system`, `spec/security`, `spec/integration`,
`@objectstack/formula`, `@object-ui/components`;
- **inside a `vi.mock` factory** (10 files): `@object-ui/i18n/locales`,
`@object-ui/react`, `@object-ui/components`;
- **re-imported after each `vi.resetModules()`** (3 files,
`@object-ui/core`): the reset re-evaluates, but the transform is cached,
so warming it once moves the compile out of every clocked re-import.
`DraftChangesPanel.securityProblems.test.tsx` is 2c round 2 (a)'s
(objectstack#25727) and is not touched; the gate does not list it on
this tree either.
## Gate reading on the merged layout
Verify branch `claude/project-thread-dwhq6r-25697-verify` head
`9e37acd126`, this diff applied with `git apply --directory=ui` (applies
clean: all 33 named files are byte-identical between that tree's `ui/`
and objectui `main` `0063f22ce`). `node
scripts/check-test-source-alias.mjs`:
| | before | after |
|---|---|---|
| function-body lines printed under `ui/` | 57 | 12 |
| unique (file, specifier) findings | 37 | 7 |
| real findings (a runtime load) | 30 | **0** |
| every other line of the gate's output | — | byte-identical to before |
### Gate false positives, left untouched (see objectstack#25766)
These 7 never load anything at run time, so there is no cost to warm;
adding a side-effect import would add a load these files do not pay
today. The gate reads them because its type-query check knows only
`typeof`, and its import pattern runs over a projection that still holds
string content.
- `packages/plugin-calendar/src/__tests__/spec-symbol-4650.test.ts`,
type alias under a `@ts-expect-error` tripwire
- `packages/plugin-form/src/__tests__/spec-symbol-4650.test.ts`, same
- `packages/plugin-grid/src/__tests__/spec-symbol-4650.test.ts`, same
- `packages/plugin-kanban/src/__tests__/spec-symbol-4650.test.ts`, same
(the four headers explain why the inline type-level form is deliberate)
-
`packages/types/src/__tests__/dashboard-global-filters-spec-binding.test.ts`,
type alias
-
`packages/components/src/renderers/complex/__tests__/data-table.test.ts`,
type annotation
- `scripts/__tests__/check-spec-range-floors.test.ts`, text inside a
template-literal fixture
## Timing, before and after
The 26 touched files, run as one set (`vitest run` on those paths, json
reporter), once per cell on a 4-vCPU box under the shared verify lock.
Merged layout = the tree above after the CI build of the seven
`@objectstack` packages, run from `ui/` with `--root .`; standalone =
this branch after `pnpm run setup`. Both before and after: 26 files, 342
tests, all passed.
| | merged before | merged after | standalone before | standalone after
|
|---|---|---|---|---|
| vitest "tests" (summed across files, s) | 173.88 | 164.70 | 161.17 |
151.87 |
| vitest "import" (collection, s) | 175.03 | 190.95 | 133.82 | 138.96 |
| wall duration (s) | 135.99 | 138.08 | 117.33 | 114.44 |
The cost moved from the clocked "tests" phase into the unclocked import
phase, which is the point. Single runs on a shared box, so differences
of a few hundred ms on one file are noise. The clear per-file moves are
in the slowest-test column:
| file | findings before → after | slowest test, merged before → after
(ms) | file test time, merged before → after (ms) | file test time,
standalone before → after (ms) |
|---|---|---|---|---|
| `apps/console/src/__tests__/masterDetailFormTypeManifest.test.ts` | 1
→ 0 | 3 → 3 | 9 → 11 | 11 → 16 |
| `packages/app-shell/src/__tests__/spec-symbol-parity.test.ts` | 1 → 0
| 3 → 4 | 10 → 14 | 24 → 15 |
|
`packages/app-shell/src/console/__tests__/AppContent.deniedVsUnpublished.test.tsx`
| 1 → 0 | 113 → 96 | 720 → 767 | 608 → 653 |
|
`packages/app-shell/src/hooks/__tests__/useConsoleActionRuntime.flowRowGuard-13397.test.tsx`
| 1 → 0 | 31 → 32 | 105 → 102 | 111 → 140 |
|
`packages/app-shell/src/views/ObjectView.listLinksPlural-11733.test.tsx`
| 1 → 0 | 204 → 184 | 697 → 545 | 500 → 665 |
|
`packages/app-shell/src/views/RecordDetailView.paramRuntimeParity-6431.test.tsx`
| 1 → 0 | 97 → 100 | 566 → 600 | 532 → 644 |
|
`packages/app-shell/src/views/metadata-admin/MetadataTypeActions.paramDialogClose-6473.test.tsx`
| 1 → 0 | 357 → 364 | 715 → 760 | 656 → 670 |
|
`packages/app-shell/src/views/metadata-admin/ResourceEditPage.requiredInGatedSection-6900.test.tsx`
| 1 → 0 | 994 → 912 | 4749 → 4493 | 4229 → 3975 |
|
`packages/app-shell/src/views/metadata-admin/clientValidation.optOuts.test.ts`
| 5 → 0 | 848 → 11 | 1251 → 56 | 555 → 44 |
|
`packages/app-shell/src/views/metadata-admin/clientValidation.retiredFormulaKey.test.ts`
| 1 → 0 | 7161 → 1948 | 8077 → 2008 | 1170 → 1347 |
|
`packages/app-shell/src/views/metadata-admin/inspectors/ViewVariantInspector.requiredInGatedSection-6900.test.tsx`
| 1 → 0 | 536 → 638 | 2177 → 2461 | 2389 → 1824 |
|
`packages/app-shell/src/views/studio-design/DataPillar.addFieldPopover-12516.test.tsx`
| 1 → 0 | 2127 → 2086 | 6589 → 6457 | 6521 → 6650 |
|
`packages/app-shell/src/views/studio-design/DataPillar.formToolbar-12451.test.tsx`
| 1 → 0 | 530 → 578 | 1119 → 1067 | 1205 → 1093 |
|
`packages/app-shell/src/views/studio-design/DataPillar.gridProjection.test.tsx`
| 1 → 0 | 481 → 768 | 595 → 917 | 755 → 565 |
|
`packages/app-shell/src/views/studio-design/DataPillar.picklistServedOptions-10202.test.tsx`
| 1 → 0 | 2666 → 2850 | 2804 → 3022 | 2866 → 2835 |
|
`packages/app-shell/src/views/studio-design/StudioDesignSurface.autosaveInFlight-11204.test.tsx`
| 1 → 0 | 6006 → 6112 | 30663 → 30220 | 30119 → 30270 |
|
`packages/app-shell/src/views/studio-design/StudioDesignSurface.autosaveSwitch-11232.test.tsx`
| 1 → 0 | 6723 → 6860 | 70743 → 70922 | 70562 → 70445 |
|
`packages/app-shell/src/views/studio-design/StudioDesignSurface.draftVersionConflict-11773.test.tsx`
| 1 → 0 | 5311 → 5355 | 27022 → 27192 | 26673 → 26866 |
| `packages/auth/src/__tests__/auth-spec-parity.test.ts` | 1 → 0 | 359 →
94 | 478 → 96 | 188 → 108 |
|
`packages/plugin-calendar/src/__tests__/ObjectCalendar.dataObjectArmRefused-8348.test.tsx`
| 1 → 0 | 79 → 65 | 163 → 113 | 130 → 114 |
|
`packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.i18nLabel.test.tsx`
| 1 → 0 | 111 → 85 | 355 → 292 | 274 → 379 |
|
`packages/plugin-grid/src/__tests__/gridBareArrayDataRefused-8348.test.tsx`
| 1 → 0 | 137 → 107 | 441 → 380 | 398 → 410 |
|
`packages/react/src/__tests__/SchemaRenderer.concealmentGateFaultDiagnostic.test.tsx`
| 1 → 0 | 1045 → 369 | 3787 → 2973 | 1065 → 512 |
|
`packages/react/src/__tests__/SchemaRenderer.disabledGateFaultDiagnostic.test.tsx`
| 1 → 0 | 1066 → 423 | 5952 → 5784 | 8207 → 838 |
|
`packages/react/src/__tests__/SchemaRenderer.productionPredicateFaultWarning.test.tsx`
| 1 → 0 | 1103 → 426 | 3792 → 3112 | 1038 → 490 |
| `packages/types/src/__tests__/registry-meta-carry-9102.test.ts` | 1 →
0 | 54 → 58 | 191 → 220 | 273 → 206 |
| **total (26 files)** | 30 → 0 | | 173770 → 164584 | 161059 → 151774 |
`clientValidation.retiredFormulaKey` on the merged layout shows the
bill-24 shape at small scale. Its first test went from 903 to 41 ms, and
its `expression`-draft test from 7161 to 1948 ms. The remaining 1.9 s is
not a load the gate attributes to this file, so this card leaves it
alone (not investigated further).
## Verification record (exit codes)
objectui standalone, this branch after `pnpm run setup`:
| gate | exit |
|---|---|
| `pnpm exec vitest run` on the 26 touched files (342 tests) | 0 |
| `pnpm exec turbo run type-check` for the 8 touched packages
(app-shell, auth, console, plugin-calendar, plugin-dashboard,
plugin-grid, react, types; 43 tasks incl. each package's
`tsconfig.test.json` and `type-check:e2e`) | 0 |
| `pnpm exec eslint` on the changed files | 0 errors; 72 warnings, the
same 72 as the base versions of those files |
| `node scripts/check-changeset-presence.mjs` | 0 |
| `node scripts/check-changeset-overwrite.mjs` | 0 |
| `node scripts/check-changeset-no-major.mjs` | 0 |
| `pnpm check:changeset-claims` | 0 |
| `pnpm check:new-line-citations` | 0 |
| `pnpm check:control-bytes` | 0 |
| `pnpm check:test-path-roots` | 0 |
Merged layout (verify head `9e37acd126` plus this diff):
| step | exit |
|---|---|
| `git apply --check --directory=ui` | 0 |
| `pnpm install --frozen-lockfile` | 0 |
| CI build of the seven `@objectstack` packages (36 tasks) | 0 |
| `vitest run --root .` from `ui/` on the 26 touched files (342 tests) |
0 |
| `node scripts/check-test-source-alias.mjs` | 1, as on the base: the 7
false positives above plus the alias-half findings, which belong to the
cutover adaptation commit; no real function-body finding left |
- [x] Adds no product-specific widget, dialog, hook or string (see
AGENTS.md › Product-neutral renderer)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Session: `https://claude.ai/code/session_01N1dH2ywuFXe38A89awucwV`
Co-authored-by: Claude <noreply@anthropic.com>1 parent d12c615 commit 7c83e70
27 files changed
Lines changed: 89 additions & 0 deletions
File tree
- .changeset
- apps/console/src/__tests__
- packages
- app-shell/src
- __tests__
- console/__tests__
- hooks/__tests__
- views
- metadata-admin
- inspectors
- studio-design
- auth/src/__tests__
- plugin-calendar/src/__tests__
- plugin-dashboard/src/__tests__
- plugin-grid/src/__tests__
- react/src/__tests__
- types/src/__tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
27 | 30 | | |
28 | 31 | | |
29 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
82 | 85 | | |
83 | 86 | | |
84 | 87 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
38 | 41 | | |
39 | 42 | | |
40 | 43 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
83 | 86 | | |
84 | 87 | | |
85 | 88 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
70 | 73 | | |
71 | 74 | | |
72 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
41 | 44 | | |
42 | 45 | | |
43 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
39 | 46 | | |
40 | 47 | | |
41 | 48 | | |
| |||
0 commit comments