check:pack-artifact and check:pack-boot have been self-contradictory since
05/08, blocking the v3.8.50 publish in ci.yml (build:cli job) and
npm-publish.yml:
- check:pack-artifact FAILS any tarball path containing a node_modules
segment (PACK_ARTIFACT_NEVER_ALLOWED_SEGMENTS; files[] also excludes
"!**/node_modules/**").
- check:pack-boot REQUIRED sql.js under the vendored
dist/node_modules/sql.js location — a path the tarball can never carry,
so both gates could never be green at once.
The packaging model is now dependency-based: sql.js and node-machine-id
are declared `dependencies` (a clean install places them under
<packageRoot>/node_modules/), and better-sqlite3 is an optionalDependency
installed natively per platform (^13.0.2 — which also covers the
darwin-arm64 prebuild gap from #11242 by construction). The runtime
already resolves the WASM at <cwd>/node_modules/sql.js/dist/sql-wasm.wasm
(src/lib/db/adapters/sqljsAdapter.ts).
Changes:
- scripts/check/check-pack-boot.mjs: REQUIRED_SQLJS_RUNTIME_FILES now
points at node_modules/sql.js/{package.json,dist/sql-wasm.js,
dist/sql-wasm.wasm} — the dependency-installed location the clean-prefix
install actually produces. REQUIRED_MACHINE_TOKEN_RUNTIME_FILES was
already correct and is unchanged.
- bin/cli/runtime/sqliteRuntime.mjs: BETTER_SQLITE3_VERSION bumped
^12.10.1 -> ^13.0.2 to match optionalDependencies (the lazy runtime
install was pulling the wrong major), and exported for the guard.
- tests/unit/pack-boot-runtime-paths.test.ts (new, TDD: RED -> GREEN):
pins that (a) no pack-boot required path references a never-publishable
vendored dist/<segment> location (driven by
PACK_ARTIFACT_NEVER_ALLOWED_SEGMENTS), (b) sql.js/node-machine-id stay
declared dependencies, (c) the lazy-install spec stays on the declared
optionalDependency major.
- tests/unit/check-pack-boot.test.ts: the sql.js contract test pinned the
old vendored path; updated to node_modules/sql.js/dist/sql-wasm.wasm.
This is alignment to the real new contract (vendoring ended), not
masking — the same test still asserts the find-missing behavior.
Electron is unaffected: the vendored dist/node_modules bundle still
exists for Electron packaging (postinstall.mjs and assembleStandalone.mjs
untouched).
Refs #11242
Refs #10296
Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Obrigado por restaurar e endurecer a autenticação por machine-token no CLI empacotado.
Validação (worktree combinado a partir de origin/release/v3.8.50, merge limpo, 0 conflitos — 34 arquivos, +1078/-247):
- `npm run typecheck:core` — limpo
- `node scripts/check/check-complexity.mjs` — OK (2558 violações vs baseline 2774)
- `node scripts/check/check-cognitive-complexity.mjs` — OK (1152 violações vs baseline 1223)
- `node scripts/check/check-file-size.mjs` — OK
- `node scripts/check/check-changelog-integrity.mjs` — OK
- Testes focados (8 arquivos: cli-doctor-command, cli-machine-token, lib/machineToken, lib/managementCliToken, agentSkills-generator, api/settings-audit, check-pack-boot, next-config) — 95/95 passando
Os dois achados de segurança do maintainer-feedback original (checagem de loopback tipo SSRF, escopo de cookie/CSRF) já estavam corrigidos e cobertos por teste no commit `2b785f0068a862fbd867221294325ad921787782` desta branch.
Three releases shipped a tarball that crashed on every boot (tls-options/3.8.41,
head-response-guard #7040/#7065) because no gate ever EXECUTED the artifact.
check:pack-boot packs the tree, installs the tarball into a clean prefix
(postinstall runs for real), boots the installed CLI on a reserved port with an
isolated DATA_DIR and polls /api/monitoring/health until it returns 200 with
the packed version — failing loudly with the server's last output otherwise.
Wired into the CI package-artifact job (reuses the dist/ the job already
assembles) and into check:release-green --with-build (parallel slow wave).
Live evidence: packed v3.8.49, installed and booted in 16.6s, health 200.