Skip to content

[BLOCKED — DO NOT MERGE] build(deps): better-sqlite3 13.0.3 pin + prebuild prune - #337

Open
KnockOutEZ wants to merge 2 commits into
studio-handofffrom
slice-bs3-v13-pin
Open

[BLOCKED — DO NOT MERGE] build(deps): better-sqlite3 13.0.3 pin + prebuild prune#337
KnockOutEZ wants to merge 2 commits into
studio-handofffrom
slice-bs3-v13-pin

Conversation

@KnockOutEZ

@KnockOutEZ KnockOutEZ commented Aug 17, 2026

Copy link
Copy Markdown
Owner

⛔ Do not merge. The v13 pin breaks Windows installs.

CI on my own head SHA measured a clean platform split: every macOS and Linux row green, every Windows row red.

clean-machine smoke (macos-latest, node 22)   success
clean-machine smoke (macos-latest, node 24)   success
clean-machine smoke (ubuntu-latest, node 22)  success
clean-machine smoke (ubuntu-latest, node 24)  success
clean-machine smoke (ubuntu-22.04-arm, n22)   success
clean-machine smoke (windows-latest, node 22) FAILURE
lint + build + unit (windows-latest)          FAILURE
studio unit (windows-latest)                  FAILURE

Base ee346f77 is 16/16 green including all Windows jobs, so these are mine.

Cause

npm ci on Windows runs node-gyp rebuild for better-sqlite3 and dies at find VS could not find a version of Visual Studio 2017 or newer.

v12 shipped an install script (prebuild-install) that ran in pure Node and exited 0 the moment it found the bundled binary — node-gyp was never invoked. v13 removed it, and npm then supplies its own implicit node-gyp rebuild for any package carrying a binding.gyp, ignoring the gypfile: false better-sqlite3 publishes to suppress exactly that. Upstream: npm/cli#9837, WiseLibs/better-sqlite3#1503, #1505.

binding.gyp's own prebuild_exists guard cannot save it — gyp must configure before it can evaluate any variable, and configure is the step needing the toolchain.

Why this is not a CI-image problem to paper over

A Windows user without Python + VC++ Build Tools could not npm i wigolo at all. The clean-machine gate exists to catch that class, and it did.

What is still good here, if v13 ever becomes viable

  • scripts/prune/sqlite-prebuilds.mjs + 22 tests (2 mutations verified to kill 3 tests each). v13 ships all 8 targets in one tarball; unpruned it reds the blocking G-DIET gate (372 → 387, limit 383), pruned it passes (374).
  • The G-DIET derivation change: at the new anchor the prune lapsing (391) becomes a smaller regression than the browser driver returning to dependencies (394), so it takes over as the binding regression — first time in five diet slices that identity has changed.
  • packaging/binary/pkg.config.json fix: it named build/Release/better_sqlite3.node, a path v13 does not ship, so the single-file binary channel would have broken silently.

Revisit when npm/cli#9837 lands or better-sqlite3 restores a JS-only install script.

The desktop shell and the core must load the SAME native module once the DB
broker retires, and only v13 can be loaded by both: its prebuilds are Node-API
(no ABI suffix, napi 10), so one binary spans Node ABI 127 and the shell's 148.
The 12.9.0 pin is V8-ABI-bound via node-gyp and fails under the shell with
NODE_MODULE_VERSION 127 vs 148 — measured, not inferred.

v13 ships all eight targets in one tarball, so the bump alone costs 16 MiB of
prebuilds/ and REDS the blocking install-size gate. Measured on the gate's own
protocol, darwin-arm64: 371 MiB at the old pin, 387 unpruned (FAIL, limit 383),
372 with the prune. Re-measured as a back-to-back pair on the current base:
372 -> 374, so the bump costs +2 MiB net and the anchor moves 375 -> 377.

The limit deliberately does not move, and the derivation changes hands: at the
new anchor this prune lapsing (worth 14 MiB, landing at 391) is a SMALLER
regression than the browser driver returning to dependencies (17 MiB, 394), so
it now sets the window at 377..391. Accommodating the unpruned 387 would have
needed a limit above 388 and blinded the gate to a regression this very change
introduces the possibility of.

Also fixes the single-file binary channel, which the bump would otherwise break
silently: pkg.config.json named build/Release/better_sqlite3.node, a path v13
does not ship. v13's prebuild name is computed at runtime, so pkg cannot find it
by static analysis and it must be declared per target — and it moves out of the
composer's platform-agnostic set, since that path is no longer the same on every
platform.

The prune keeps both libc builds on linux: the loader's musl probe is a genuine
runtime check, but this runs at install time in a different process, and a
multi-stage container can populate under glibc and run under musl. Removal is
allowlisted rather than pattern-matched because `linuxmusl` is not a value
process.platform ever takes, so interpolation would delete the file a musl host
is the only one that can load. The planner refuses outright unless it has
positively identified a loadable prebuild: unlike the other prunes here, a wrong
removal does not degrade a capability, it throws on require and the cache
database never opens.

Corrects studio-mcp-server.ts's stated reason for existing, which this pin
falsifies. It claimed the subsystem graph CANNOT load in the desktop shell
because that shell rejects 12.9.0. That was true of the old pin; 13.0.3 loads
there. The module stays separate on boot cost, not on an ABI wall.
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5ab61094-d22e-4d83-aecd-b82b4fb67150

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

CI measured what a green macOS run could not: every macOS and Linux row passes
and every Windows row fails, at `npm ci`, with node-gyp unable to find Visual
Studio.

v12 shipped an install script (prebuild-install) that ran in pure Node and
exited 0 as soon as it found the bundled binary, so node-gyp was never invoked.
v13 removed it, and npm supplies its own implicit `node-gyp rebuild` for any
package carrying a binding.gyp — ignoring the `gypfile: false` better-sqlite3
publishes to suppress exactly that (npm/cli#9837, WiseLibs/better-sqlite3#1503
and #1505). binding.gyp's own prebuild_exists guard cannot help, because gyp
must configure before it can evaluate a variable and configure is the step that
needs the toolchain.

This is a user-facing install regression, not a CI-image detail: a Windows user
without Python and VC++ Build Tools could not `npm i wigolo` at all. The
clean-machine job exists to catch precisely that, and it did.

Retracts the claim in the previous commit's ci.yml comment that v13 "never falls
back to a source compile on any row". It was written from a macOS result and the
Windows matrix falsifies it.
@KnockOutEZ KnockOutEZ changed the title build(deps): pin better-sqlite3 13.0.3 and prune its non-host prebuilds [BLOCKED — DO NOT MERGE] build(deps): better-sqlite3 13.0.3 pin + prebuild prune Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant