Measured in a dedicated worktree at origin/main + the pin bump from #10129, not recalled.
scripts/build-console.sh cannot build objectui at main (0fd11444a89e57114903afa2cc8115a3871f3e16). The console build dies in generateBundle:
[plugin assert-lazy-linter-stays-lazy]
RolldownError: [assert-lazy-linter-stays-lazy] counter-probe failed: no eagerly loaded chunk
contains an `@objectstack/spec` module. The spec is reached synchronously from the app entry,
so it must be in the eager closure — its absence means this walk is reading the graph wrongly,
not that the bundle improved. Fix the walk before trusting the linter assertion below.
(entry chunks: assets/index-mpVXni3j.js; eager chunks: 59/508)
This blocks #10129 (bump the pin to current objectui main) and it will turn Console Pin Gate red on any PR that moves .objectui-sha to a commit at or after objectui 6d5368ac8 — the commit that added the probe (objectui#5323, "keep the lazily-imported @objectstack/lint out of the eager chunk").
The two mechanisms, and why they are incompatible
Ours (#8134, hook added in objectui#4854).build-console.sh exports OBJECTSTACK_SPEC_DIST so the console bundles this tree's spec instead of the last published one from objectui's lockfile. objectui's apps/console/vite.config.ts honours it through resolveSpecDistInjection, which rewrites all 18@objectstack/spec* specifiers to absolute paths in the framework tree:
@objectstack/spec/ai => /path/to/objectstack/packages/spec/dist/ai/index.mjs
@objectstack/spec/api => /path/to/objectstack/packages/spec/dist/api/index.mjs
... (18 aliases, one per exports-map entry)
That helper already knows this rewrite moves the spec out of node_modules, and it compensates where it must: it returns a widenedvendorChunkTest, so the chunk grouping keeps recognising the injected spec —
/[\\/]node_modules[\\/](@objectstack)[\\/]|\/path\/to\/objectstack\/packages\/spec[\\/]/
Theirs (objectui#5323).assertLazyLinterStaysLazy() in the same vite.config.ts carries its own private module-id regex and is not widened:
constSPEC=/@objectstack[\\/+]spec/;
Under the injection, zero emitted module ids match it — the ids are now framework-tree absolute paths with no @objectstack segment at all. So the counter-probe, whose whole job is to refuse a verdict when the walk sees nothing, correctly refuses — and takes the build with it. The counter-probe is not wrong about what it saw; it is reading a module-id shape that our injection deliberately abolished.
Reproduction — the injection is the only variable
Same objectui build tree, same pin, same command:
OBJECTSTACK_SPEC_DIST | result |
|---|
set (what build-console.sh does) | Build failed in 11.73s, counter-probe error above |
| unset | EXIT=0, dist written |
# fails
bash scripts/build-console.sh
# succeeds — identical tree, injection removedcd .cache/objectui-0fd11444a89e
OBJECTSTACK_CLIENT_DIST=/path/to/objectstack/packages/client \
pnpm --filter @object-ui/console exec vite build
CI reproduces it as-is: Console Pin Gate runs bash scripts/build-console.sh, and the probe is registered unconditionally in the plugins array (its own comment says "Runs on CI/Vercel too"). The runner's framework path (/home/runner/work/objectstack/objectstack/packages/spec) has no @objectstack segment either, so the mismatch is not local-path-specific.
Where the fix belongs
objectui, apps/console/vite.config.ts — the file already computes the widened test three lines away:
constvendorObjectstackTest=specDistInjection ? specDistInjection.vendorChunkTest : VENDOR_OBJECTSTACK_TEST;
assertLazyLinterStaysLazy() should consume the injection-aware location the same way instead of hardcoding SPEC, i.e. take the spec test as a parameter. Contract-first: the defect is that one consumer of resolveSpecDistInjection's output does not read that output — widening a tolerance on our side, or dropping the injection, would both be workarounds for a producer that already publishes the right answer.
Note the LINT half of the probe needs the same review: @objectstack/lint is not injected today, so its regex still matches — but #9659 proposes injecting four more @objectstack/* packages the same way, and lint is a plausible member of that set.
A companion objectui PR is required; this repo cannot fix it alone. Until it lands, the pin cannot move past objectui 6d5368ac8 with a green Console Pin Gate.
Not the remedy
Back-link: blocks objectstack#10129. Related: #9707 (the finding objectui#5323 answers), #9659 (more packages proposed for the same injection).
Measured in a dedicated worktree at
origin/main+ the pin bump from #10129, not recalled.scripts/build-console.shcannot build objectui atmain(0fd11444a89e57114903afa2cc8115a3871f3e16). The console build dies ingenerateBundle:This blocks #10129 (bump the pin to current objectui
main) and it will turn Console Pin Gate red on any PR that moves.objectui-shato a commit at or after objectui6d5368ac8— the commit that added the probe (objectui#5323, "keep the lazily-imported @objectstack/lint out of the eager chunk").The two mechanisms, and why they are incompatible
Ours (#8134, hook added in objectui#4854).
build-console.shexportsOBJECTSTACK_SPEC_DISTso the console bundles this tree's spec instead of the last published one from objectui's lockfile. objectui'sapps/console/vite.config.tshonours it throughresolveSpecDistInjection, which rewrites all 18@objectstack/spec*specifiers to absolute paths in the framework tree:That helper already knows this rewrite moves the spec out of
node_modules, and it compensates where it must: it returns a widenedvendorChunkTest, so the chunk grouping keeps recognising the injected spec —Theirs (objectui#5323).
assertLazyLinterStaysLazy()in the samevite.config.tscarries its own private module-id regex and is not widened:Under the injection, zero emitted module ids match it — the ids are now framework-tree absolute paths with no
@objectstacksegment at all. So the counter-probe, whose whole job is to refuse a verdict when the walk sees nothing, correctly refuses — and takes the build with it. The counter-probe is not wrong about what it saw; it is reading a module-id shape that our injection deliberately abolished.Reproduction — the injection is the only variable
Same objectui build tree, same pin, same command:
OBJECTSTACK_SPEC_DISTbuild-console.shdoes)Build failed in 11.73s, counter-probe error aboveEXIT=0, dist writtenCI reproduces it as-is: Console Pin Gate runs
bash scripts/build-console.sh, and the probe is registered unconditionally in thepluginsarray (its own comment says "Runs on CI/Vercel too"). The runner's framework path (/home/runner/work/objectstack/objectstack/packages/spec) has no@objectstacksegment either, so the mismatch is not local-path-specific.Where the fix belongs
objectui,
apps/console/vite.config.ts— the file already computes the widened test three lines away:assertLazyLinterStaysLazy()should consume the injection-aware location the same way instead of hardcodingSPEC, i.e. take the spec test as a parameter. Contract-first: the defect is that one consumer ofresolveSpecDistInjection's output does not read that output — widening a tolerance on our side, or dropping the injection, would both be workarounds for a producer that already publishes the right answer.Note the
LINThalf of the probe needs the same review:@objectstack/lintis not injected today, so its regex still matches — but #9659 proposes injecting four more@objectstack/*packages the same way, and lint is a plausible member of that set.A companion objectui PR is required; this repo cannot fix it alone. Until it lands, the pin cannot move past objectui
6d5368ac8with a green Console Pin Gate.Not the remedy
OBJECTSTACK_SPEC_DISTinbuild-console.sh. That injection exists to collapse a three-step publish ordering (#7804'sGlobalFilterSchema.objectis unreachable in the Studio designer, and no console pin bump can fix it — the console vendors the PUBLISHED@objectstack/spec, which the key postdates #8134) and its absence is a silent skew, not a build error.6d5368ac8as a fix. That is a workaround that re-opens the freshness gap Bump the objectui pin to current main — 149 commits of frontend are outside the release record #10129 exists to close; it is at most a stopgap and needs a maintainer decision.Back-link: blocks objectstack#10129. Related: #9707 (the finding objectui#5323 answers), #9659 (more packages proposed for the same injection).