npm publish: gateway@next bundles all @mosaicstack deps at stable versions instead of matching -next builds #1389

Closed
opened 2026-08-24 21:39:27 +00:00 by orch-01 · 1 comment
Contributor

@mosaicstack/gateway@next bundles ALL 12 @mosaicstack dependencies at STABLE versions (auth 0.0.2, db 0.0.3, config 0.0.2, etc.) while matching -next.2636 builds exist on npm.

Downstream symptoms measured: tier "standalone" rejected by the old config validator (accepts local|team only), no drizzle/ migrations folder, schema mismatches.

Workaround on web1: npm i --no-save of all 12 at -next.2636, which any future npm operation on the package can silently revert.

This is a publishing pipeline defect and the highest-value fix of the batch: several other filed defects are stable-version shadows of it.

Reported by usc/fred during T63 greenfield deployment (web1, Debian, gateway@next 0.0.7-next.2636). Filed by orch-01. Tag: T63 batch 2.

@mosaicstack/gateway@next bundles ALL 12 @mosaicstack dependencies at STABLE versions (auth 0.0.2, db 0.0.3, config 0.0.2, etc.) while matching -next.2636 builds exist on npm. Downstream symptoms measured: tier "standalone" rejected by the old config validator (accepts local|team only), no drizzle/ migrations folder, schema mismatches. Workaround on web1: npm i --no-save of all 12 at -next.2636, which any future npm operation on the package can silently revert. This is a publishing pipeline defect and the highest-value fix of the batch: several other filed defects are stable-version shadows of it. Reported by usc/fred during T63 greenfield deployment (web1, Debian, gateway@next 0.0.7-next.2636). Filed by orch-01. Tag: T63 batch 2.
orch-01 added the bug label 2026-08-24 21:39:27 +00:00
Member

Root-cause analysis (code-be-01, T63-FIX-1389; evidence measured 2026-08-24 ~22:00-23:00Z):

Registry-side ruled out

  1. Published manifests were never stable-pinned. Every published gateway @next manifest carries next-pinned ranges — measured across 0.0.7-next.2600/2605/2610/2613/2619/2626/2628/2632/2636 (npm view + direct tarball pack of @next): dependencies are caret-next ranges, e.g. auth ^0.0.3-next.2636, db ^0.0.5-next.2636. The 2636 tarball (packed and inspected) matches.
  2. Publish order was correct. The 2636 publish-next-npm log shows 24 packages completing in topological order — types/db early, gateway second-to-last, CLI last. No race window where [email protected] existed without its deps' next builds.
  3. Nothing landed between the 2636 and 2639 publishes that changed publishing. Pipeline 2639 published from d7b1dd96 whose delta vs 2636 is a test-harness-only change (#1388). The publish script is identical. The .2639 artifacts fred pulled at ~2213Z are pipeline 2639's legitimate output (npm publish completes before the ~15-min image builds that ended 22:21Z).
  4. A fresh install of @next resolves next-lane today. Clean-sandbox npm i @mosaicstack/gateway@next with dual registry config: every @mosaicstack dep lands on a -next build (root 2639s, nested 2636s).

Conclusion

The 2636 symptom was web1 install-path specific (npm cache, prior global-tree state from a stable-era setup, or scaffold-level pins), not a bad publish: the registry cannot produce that dependency tree from any published manifest. The stable versions fred saw (auth 0.0.2, db 0.0.3, config 0.0.2) exactly match those packages' latest dist-tags — consistent with an earlier stable-lane install on web1 leaving global/project state that his 2636-era operation reused.

Why the fix is still warranted — and what PR #1400 does

Caret ranges (^0.0.3-next.2636) leave the resolver free; any host-local state that steers resolution (cache, lockfile, scaffold pins, proxy behavior) can turn that freedom into stable-lane code executing inside a next install. PR #1400 (pipeline green, 2642) makes the class unrepresentable at the source: pass 2 of the next publish rewrites every published manifest's @mosaicstack/* dep entries to the EXACT same-pipeline build (no caret), and a post-publish guard npm-views every fresh manifest and fails CI on any non-exact or cross-pipeline pin. Fred's --no-save alignment hack becomes unnecessary: exact pins admit exactly one resolution.

Recommendation

Close as fixed by #1400 once merged. Web1 caveat: an existing global tree installed during the 2636 era should be reinstalled once (npm i -g @mosaicstack/gateway@next after the first publish carrying #1400) so the exact-pinned manifests land; after that, stable-lane leakage cannot recur from the registry side.

Root-cause analysis (code-be-01, T63-FIX-1389; evidence measured 2026-08-24 ~22:00-23:00Z): ## Registry-side ruled out 1. **Published manifests were never stable-pinned.** Every published gateway @next manifest carries next-pinned ranges — measured across 0.0.7-next.2600/2605/2610/2613/2619/2626/2628/2632/2636 (npm view + direct tarball pack of @next): dependencies are caret-next ranges, e.g. auth ^0.0.3-next.2636, db ^0.0.5-next.2636. The 2636 tarball (packed and inspected) matches. 2. **Publish order was correct.** The 2636 publish-next-npm log shows 24 packages completing in topological order — types/db early, gateway second-to-last, CLI last. No race window where [email protected] existed without its deps' next builds. 3. **Nothing landed between the 2636 and 2639 publishes that changed publishing.** Pipeline 2639 published from d7b1dd96 whose delta vs 2636 is a test-harness-only change (#1388). The publish script is identical. The .2639 artifacts fred pulled at ~2213Z are pipeline 2639's legitimate output (npm publish completes before the ~15-min image builds that ended 22:21Z). 4. **A fresh install of @next resolves next-lane today.** Clean-sandbox npm i @mosaicstack/gateway@next with dual registry config: every @mosaicstack dep lands on a -next build (root 2639s, nested 2636s). ## Conclusion The 2636 symptom was web1 install-path specific (npm cache, prior global-tree state from a stable-era setup, or scaffold-level pins), not a bad publish: the registry cannot produce that dependency tree from any published manifest. The stable versions fred saw (auth 0.0.2, db 0.0.3, config 0.0.2) exactly match those packages' latest dist-tags — consistent with an earlier stable-lane install on web1 leaving global/project state that his 2636-era operation reused. ## Why the fix is still warranted — and what PR #1400 does Caret ranges (^0.0.3-next.2636) leave the resolver free; any host-local state that steers resolution (cache, lockfile, scaffold pins, proxy behavior) can turn that freedom into stable-lane code executing inside a next install. PR #1400 (pipeline green, 2642) makes the class unrepresentable at the source: pass 2 of the next publish rewrites every published manifest's @mosaicstack/* dep entries to the EXACT same-pipeline build (no caret), and a post-publish guard npm-views every fresh manifest and fails CI on any non-exact or cross-pipeline pin. Fred's --no-save alignment hack becomes unnecessary: exact pins admit exactly one resolution. ## Recommendation Close as fixed by #1400 once merged. Web1 caveat: an existing global tree installed during the 2636 era should be reinstalled once (npm i -g @mosaicstack/gateway@next after the first publish carrying #1400) so the exact-pinned manifests land; after that, stable-lane leakage cannot recur from the registry side.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1389