Repository navigation
fix(packages): install opencode node_modules with its exact pinned Bun - #287
Merged
Merged
Conversation
Mux owned the only implementation of the exact-Bun contract: pin the manifest's packageManager Bun, hash its release archives, keep them through the pins-only stage, and refuse duplicate runtime entries. Move that into ExactBunNodeModulesHashUpdater so another Bun-locked source can reuse it. Candidate handoff restored only direct MappingMetadata subclasses, which would have dropped MuxSourceMetadata once it specialized the shared base. Walk the whole subclass tree. Co-authored-by: George Kontridze <[email protected]>
…result Flake-input hash probes overrode only the package's own sources entry, so a companion read its parent's pre-update workspace file. opencode-desktop's node_modules is opencode's derivation: once opencode pins an exact Bun, a packageManager bump would make desktop evaluate the stale pin and fail. Pass the companion parent's in-run entry into the probe overrides, as the source-backed updaters already do, and declare opencode-desktop a companion of opencode. Co-authored-by: George Kontridze <[email protected]>
Update run 40086686747 failed opencode and opencode-desktop on x86_64-linux: their node_modules FODs ran nixpkgs bun 1.4.2 against fork rev d5ea4ab, whose bun.lock the fork now regenerates with its packageManager Bun ([email protected], bumped upstream in anomalyco/opencode#58087). With the fork's root `vite: catalog:` devDependency, 1.4.2 re-resolves the vite 7/8 split and rejects --frozen-lockfile ("lockfile had changes"); 1.4.4 accepts the same tree for both filter sets on every target. nixpkgs ships 1.4.2 on every channel. Build opencode's node_modules and CLI with lib/exact-bun.nix at the input's packageManager version, maintained by the updater like mux and superset. Desktop inherits it through opencode's node_modules and buildBun. Drop the packageManager rewrite: exact-bun.nix now asserts that equality instead. sources.json is regenerated by the updaters for the still-locked a6fde022 ([email protected]): the same release archives nixpkgs fetches, so the carried node_modules hashes still build (verified on x86_64-linux). Co-authored-by: George Kontridze <[email protected]>
Co-authored-by: George Kontridze <[email protected]>
The subclass-tree walk visited classes last-defined-first, so a reloaded updater module's stale metadata class shadowed the live one and restored metadata failed isinstance checks. Visit in definition order, as the direct-subclass comprehension did. Co-authored-by: George Kontridze <[email protected]>
cachix-flush-proof.yml (#286) carried a 114-column comment line that fails lint-yaml-yamllint, and nix fmt marks opencode-desktop's unused node_modules override argument. Both already fail on main.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Update run 40089810663 failed prepare-pins at bootstrap with exit 1 and no diagnostic. 92e3ee5 added a `nix eval` of `(builtins.getFlake "git+file://<checkout>").inputs.nixpkgs.outPath`. Actions checks out with fetch-depth 1, and Determinate Nix (3.22.5 on the runners) rejects an explicit git+file URL to a clean shallow clone: "'<checkout>' is a shallow Git repository, so 'revCount' is not available". The `.` flake reference used by the preceding `nix build` and `nix develop` adds `shallow=1` implicitly, so only the eval failed. Bootstrap now takes its flake URL from the shared `local_flake_url`, which opts into `shallow=1`. That also covers the updaters that build the same URL and only avoided the failure because the tree was dirty or the devshell's Nix 2.34.9 tolerates it. The job launcher's entrypoint now reports a failed child's command and the tail of its captured stderr before exiting with its status, so a captured failure can no longer exit silently.
update_bun_lock.py is a standalone template that cannot import lib.update.paths, so it carried its own copy of the git+file URL without the shallow=1 opt-in. Its test now asserts that the installable equals local_flake_url, and the neutils resolution-event test derives its expected URL from the same helper.
6 tasks done
Resolve the two conflicts with 92e3ee5's engineering-discipline remediation: - packages/mux/updater.py: keep this branch's move onto ExactBunNodeModulesHashUpdater and adopt main's shared require_exact_semantic_version in place of mux's private regex. - .github/workflows/cachix-flush-proof.yml: take main's rewritten header comment; this branch only rewrapped the old one for yamllint.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Update run 40086686747 (main @
a5f02837) failedprepare-x86 / native. In Phase 2/4, theopencodeandopencode-desktopnode_modules FODs at fork revd5ea4abranbun install v1.4.2 --frozen-lockfile. Both stopped witherror: lockfile had changes, but lockfile is frozen.electron-runtimesthen failed only as their prerequisite.Root cause
The fork's lockfile was generated by one Bun release and checked by Nix with another.
packageManager: [email protected]on 2026-10-22 (anomalyco/opencode#58087). nixcfg's currently locked fork reva6fde022still declared[email protected].bun.lockitself. Since5deeb3a0andafa1bb25(2026-10-24), the fork's nightly no longer replays its lockfile. It runsbun install --lockfile-onlywith the Bun pinned inpackageManager(1.4.4), and verifies the result with--frozen-lockfileunder 1.4.4 only.d5ea4abis that regenerated lockfile.nix/node_modules.nixand usespkgs.bunfrom nixcfg's nixpkgs. That is 1.4.2, and it is still 1.4.2 on every channel, includingmaster."vite": "catalog:"devDependency (fork commit05743a66) puts vite 7.3.6 at the root, while astro, vitest, and app pull vite 8.2.2. Bun 1.4.2 resolves that split differently from the 1.4.4-written lockfile, so it refuses the frozen install. Upstream's own lockfile has no root vite, and 1.4.2 still accepts it.Evidence:
d5ea4absource as the FOD sees it (fileset, flags, filters)--cpu/--ostargets × both filter sets (CLI and desktop)dev(f20760b8)vitedevDependency, relocked by 1.4.4packages/uidevDependencies, relocked by 1.4.4opencode.node_modulesderivation with--override-input opencode …/d5ea4ab(baseline)Fix
The input's
packageManagerdecides which Bun installs the dependencies. That matches how the lockfile is generated and verified.overlays/opencodebuilds the fork's node_modules and CLI withlib/exact-bun.nixat the input'spackageManagerversion, the same mechanism mux and superset use.opencode-desktopinherits it through opencode's node_modules andbuildBun.sync_package_manager_bun_version.pyis removed.exact-bun.nixnow asserts that the pinned Bun equalspackageManager, and only the root manifest declares one.OpencodeUpdaterderivespins.bunVersionfrom the locked commit'spackage.jsonand hashes the Bun release archives. The exact-Bun updater mechanics that only mux had (the pin, runtime hashing,_is_latest, the pins-only finalize, and duplicate guards) now live in a sharedExactBunNodeModulesHashUpdaterbase, and mux uses it too.opencode-desktopnow declarescompanion_of = "opencode".FlakeInputHashUpdaterprobes now include the companion parent's result from the current run, as the source-backed updaters already do. Without this, a futurepackageManagerbump would make desktop evaluate opencode's stale workspace pin, andexact-bun.nixwould reject it.ResolvedVersion.restorelisted only directMappingMetadatasubclasses, soMuxSourceMetadatawould have failed the pins-to-native candidate handoff. It now walks the whole subclass tree, in definition order.sources.json. The updaters regenerated both files for the still-lockeda6fde022([email protected]). That pin uses the same release archives nixpkgs fetches, so the carried-forward node_modules hashes still build. Update moves the input tod5ea4ab(Bun 1.4.4) after merge.docs/update/README.mdandruntime.mdare updated. One.github/update-kickline is added, so merging starts exactly one Update run.Nothing is weakened.
--frozen-lockfile, platform coverage, and every validation stay as they were, and no package is skipped.Fork follow-up (gkze/opencode)
nixcfg no longer depends on this, but it is still a gap in the fork. The fork's
relockandreplaysteps verifybun.lockonly with thepackageManagerBun. The fork'snix-hashesworkflow runs only on pushes todev, never ongkze/patches. So the fork's ownnix build .#opencode(which uses nixpkgs Bun 1.4.2) is broken atd5ea4ab, and nothing on the fork catches it. Two options: havenix/node_modules.nixuse a Bun that matchespackageManager, or run the Nix node_modules build as part of nightly validation.Separately, the fork's "Publish fork nightly" run 40086226766 is failing with
Every new commit needs provenance. That is unrelated to this hash failure.Validation
nixcfg ci update prepare --pins-only -- opencode opencode-desktopresolvedd5ea4abwithbunVersion 1.4.4. The nativeprepare --previousthen succeeded for both, withsuccess: trueand no errors. Computed hashes:nodeModulesHashx86_64-linux:sha256-Q4r9RztFAcEw+cxlxFRtXmUk5bwonBgZgz9JrACocS4=nodeModulesHashx86_64-linux:sha256-eJTns72ExUwqzZg6+joA34C/fDNt0d2i8G1e9kttEBs=a6fde022, the x86_64-linux opencode and desktop node_modules FODs build with the exact Bun 1.4.2 and match the committed hashes. Both packages evaluate on x86_64-linux, aarch64-linux, and aarch64-darwin.PR update preparemaps this diff tomux opencode opencode-desktop t3code-workspaceand runs the native prepare stages on macos-15, ubuntu-arm, and ubuntu x86. That computes and proves the aarch64-linux and aarch64-darwin hashes.prek run -apasses. It needed a reflow of a pre-existing 114-column comment line from fix(update): bound the Cachix flush and recover a wedged daemon #286.certify-pythonset passes (697 tests).test-nix-opencode-desktop,test-nix-package-helpers, andtest-nix-repo-checkspass.origin/main. Those 58 failures are environment-specific to this VM: macOS tooling, Node, and one timing-flaky test.nix fmt's shellcheck step fails on the same unrelated zsh and shell files on main.Merge with main after 36e573f
mainmoved to36e573f5(92e3ee5, engineering-discipline remediation), which conflicted with this branch.mainwas merged in, not rebased, so the history above is unchanged.packages/mux/updater.py. Keeps this branch's move ontoExactBunNodeModulesHashUpdater, and adopts main's sharedrequire_exact_semantic_versionin place of mux's private regex..github/workflows/cachix-flush-proof.yml. Takes main's rewritten header comment. This branch had only rewrapped the old comment for yamllint.PR update preparerunsbootstrapon afetch-depth: 1checkout, and on main that fails like Update run 40089810663. The fix(ci): make bootstrap's flake eval work on shallow checkouts #288 commits are merged here unchanged, so fix(packages): install opencode node_modules with its exact pinned Bun #287 and fix(ci): make bootstrap's flake eval work on shallow checkouts #288 merge cleanly in either order. The existing.github/update-kickline is still the only kick.Re-validated on the merged tree:
25f53830to02c087f3. On x86_64-linux, theopencode.node_modules,opencode-desktop.node_modules, andmux.offlineCacheFODs build from scratch, match the committed hashes, and reproduce undernix build --rebuild.prek run -apasses, and so doruff format --checkand the touched andcertify-pythontests (816 passed).origin/main. Its 50 failures are macOS host tools missing from this Linux VM.