Repository navigation
Windows engine unbuildable from main: build workflows absent from default branch, npm packages unpublished #1225
Description
Activity
- addedbugSomething isn't workingSomething isn't workingplatformOS / toolchain portabilityOS / toolchain portabilitybuildBuild, packaging and developer setupBuild, packaging and developer setupwindowsMicrosoft Windows supportMicrosoft Windows support
on Sep 24, 2026 - CI - PRs exist and will be merged into main later.
- The NPM package will be published with the release.
- Not an issue with this repo - likely a setup issue.
Publish-day check: a successful install is not a successful rollout
Before or right after publishing, verify that every language directory's
ENGINE_IDequals--print-engine-idfor that language onmain:# on main, per language bash graph/pipeline/run-souffle.sh --print-engine-id --language typescript # vs what the published package carries cat node_modules/@axiomcode/engine-<os>-<cpu>/typescript/ENGINE_ID
They must match exactly. This is worth an explicit step because an engine built from the wrong tree installs perfectly cleanly and is only refused later, at solve time — so a green
npm installsays nothing about whether the rollout worked.Demonstrated end to end rather than predicted. I assembled a real package around the Windows TypeScript binary from run
34786932833(2026-09-13,engine-prebuilt, pre-restructure) using the committed tooling:packaging/assemble-engine-package.sh win32-x64 0.1.0 <engines> <out> assembled …: LICENSE.md README.md package.json typescriptThe script works as-is on Windows/Git Bash and emits a correct manifest (
os:["win32"],cpu:["x64"]). Installing it succeeds with no warning. Then:▶ engine id = de5c048b48f4b43c6493cdea183fa1d19b840ff329ddf61c8b00a84dd6928793 (rules + souffle 2.5) ! @axiomcode/engine-win32-x64 holds typescript at e66da7e43ad1…, these rules are de5c048b48f4… — not using it (publish a new engine version for these rules) ❌ no engine for typescript@de5c048b48f4… on this machine. ❌ 1 of 1 languages failed: typescriptengine id (typescript) packaged Sept-13 binary e66da7e43ad116c7e4d13314ca54a04a7c8d0d4c7f098181c3705961c679dac4mainat6553d243de5c048b48f4b43c6493cdea183fa1d19b840ff329ddf61c8b00a84dd6928793The guard at
graph/pipeline/run-souffle.sh:409-412behaved exactly as designed. The point is only that the failure surfaces one step later than the install, so publishing engines built fromengine-prebuiltrather thanmainwould look like a clean rollout and still leave every consumer unable to solve.
Positive finding: unpublished optional deps do not block a consumer install
Worth recording, because it means the package half is already rollout-ready. With
@axiomcode/engine-*still absent from the registry, a clean consumer install of the packed@axiomcode/code-graphtarball is green:npm install axiomcode-code-graph-0.1.0.tgz # exit 0, engine-* skipped silently node_modules/.bin/axiomcode --help # resolves and runsPointed at a real source tree it parses, stamps the IR with the source's git commit, and stops only at the solve. The package ships
bin/axiomcode,dist/,parser/dist/,graph/and the plugin (3,148 files, 19.4 MB unpacked) — the gaps from #886 are not present in this tree.Pre-publish-only footgun: npm crashes adding an engine tarball to a tree with unresolved optional deps
Only reachable while the packages are unpublished, noted so it is not mistaken for a package defect if someone hits it before the registry catches up. Installing an engine tarball into a project that already has
code-graph— whoseoptionalDependenciescould not resolve — crashes npm itself, inside its own dedupe:npm error Invalid Version: npm error at new SemVer (semver/classes/semver.js:40:13) npm error at Object.eq (semver/functions/eq.js:4:29) npm error at Node.canDedupe (@npmcli/arborist/lib/node.js:1140:32) npm error at PlaceDep.pruneDedupable (@npmcli/arborist/lib/place-dep.js:426:14)npm 11.6.2, node v24.11.1, Windows. The unresolved optional-dep node carries an empty version, and
semver.eqthrows on it.Two orderings that work:
- engine package alone into a clean project — exit 0
- engine package first, then
code-graphon top — exit 0, both resolve, binary andENGINE_IDin place
The broken order is
code-graphfirst (with its optional deps unresolved), engine second. Once the engine packages are on the registry,npm installresolves them as ordinary optional deps and this path should not be reached at all — so this is expected to disappear on publish rather than need a fix.
What
On a fresh Windows install there is no way to obtain an engine for
main, so every verb that builds a graph fails. The prebuilt-engine mechanism proposed in #454 was implemented (PR #478) but never landed onmainand never published, so all three routesrun-souffle.shoffers are dead at the same time.Verified at
6553d243(also held at2163292b).Route 1 — CI: the build workflows are absent from the default branch
mainhas no.githubdirectory at all:build-engines.ymlandpublish-npm.ymlexist only onengine-prebuilt:workflow_dispatchonly targets workflows present on the default branch, so neither can be dispatched at all.gh workflow run build-engines.ymlreturns:gh workflow listdoes showengine-binariesas "active", which is misleading — that entry is registered from runs onengine-prebuilt, not from a workflow onmain.Route 2 — npm: the engine packages were never published
package.jsonlists them asoptionalDependencies, sonpm installsilently skips them and the failure surfaces later, at solve time:Nothing under the
@axiomcodescope is published, so the "runnpm installhere" half of the error message ingraph/pipeline/run-souffle.sh:448cannot succeed for any platform.Route 3 — the existing CI artifacts are for superseded rules
engine-binarieslast succeeded on 2026-09-13 (runs34786932833,34784266642,34783648919,34782429231), all onengine-prebuilt. The binaries have not expired andengine-typescript-windows-x86_64downloads fine, but they predate thesrc/→graph/restructure and do not match current rules:6b0979c2e66da7e43ad1…mainat6553d243de5c048b48f4…Computed with
--print-engine-id --language typescriptat each commit (the script lived atsrc/pipeline/run-souffle.shthen,graph/pipeline/run-souffle.shnow).run-souffle.sh:409-412comparesENGINE_IDand correctly refuses a mismatch, so these artifacts are unusable by design — and those runs predate the id-verified packaging scheme, shipping only.exe+.sha256with noENGINE_IDfile.Reproduce
On any machine with no Soufflé and no engine cache:
Both suggested remedies are unavailable: the packages do not exist, and Soufflé is the dependency the prebuilt scheme was meant to remove.
Impact
axiomcode index, and the plugin'saxiomcode_indexplus anything that triggers a build (path,impact,changed,test_impact,graphon a repo with no graph yet).graph.sqlitebuilt elsewhere works normally, as does the plugin's query surface. The parser half also works: it produces full IR, and the run dies at the solve step.Worth noting Soufflé on Windows is not the blocker (#16 covers that separately):
build-engines.ymlgenerates the C++ with Soufflé on Linux and compiles it on Windows with MSVC, which is howengine-*-windows-x86_64was produced at all. The blocker is only thatmain's rules have never been compiled anywhere reachable.Which side this is
Not the IR and not the resolution rules — repo build/infrastructure. No parser behaviour and no engine rule is implicated; the rules are fine, they have simply never been built for consumption.
Suggested fix
One-time, in this order:
.github/workflows/build-engines.ymlandpublish-npm.ymlonmain(mergeengine-prebuilt, or cherry-pick the two workflow files). Until they are on the default branch nothing can be dispatched.build-engines.ymlonmainto produce engines for current rules, and confirm each carries anENGINE_IDmatching--print-engine-idfor its language.@axiomcode/engine-<os>-<cpu>under the scopegraph/pipeline/engine.confpins, so theoptionalDependenciesalready inpackage.jsonresolve.Step 1 is the real gap — 2 through 4 are what #454/#478 already built and are blocked only on it.
Related
engine-prebuilt.