Skip to content

fix(renovate): refresh the FOD hash on devenv-nixpkgs channel bumps (RIG-3296) - #897

Open
rigel-mintaka wants to merge 5 commits into
mainfrom
dependencies/rig-3296-devenv-nixpkgs-fod-refresh
Open

fix(renovate): refresh the FOD hash on devenv-nixpkgs channel bumps (RIG-3296)#897
rigel-mintaka wants to merge 5 commits into
mainfrom
dependencies/rig-3296-devenv-nixpkgs-fod-refresh

Conversation

@rigel-mintaka

Copy link
Copy Markdown
Contributor

The devenv-nixpkgs digest packageRule's postUpgradeTasks ran only refresh-devenv-nixpkgs.ts, with a comment asserting the FOD refresh was "intentionally absent" because a channel bump supposedly cannot move agent-image/entrypoint.nix's outputHash (premise: biome is a root-only devDependency, absent from the --filter '@compass/agent' install).

That premise is empirically false. PR #580 (digest → 256551e) failed CI e2e with hash mismatch in fixed-output derivation compass-agent-node-modules (specified sha256-GrsX8VmqoHIg…, got sha256-+ogECRp2…). The channel bump re-resolved the @compass/agent closure in bun.lock (@opentelemetry/sdk-metrics 2.9→2.10 and an @oh-my-pi/pi-coding-agent re-nesting) and moved pkgs.bun, the nixpkgs-versioned builder the FOD installs with — both move the recursive outputHash. So every channel bump reds e2e.

Fix: add bun tools/renovate/refresh-fod-hashes.ts to the rule's postUpgradeTasks.commands (after the relock, so it self-gates on the now-changed bun.lock and realises the new tree) and agent-image/entrypoint.nix to fileFilters (Renovate commits only listed files — without it the recomputed hash edit is silently dropped). The command is already allowlisted in bot-config.json5. The exemption test in config.test.ts is flipped to pin the corrected wiring, and the global FOD site-count guard goes 2→3 (the FOD refresh now rides three task sites). Verified: bun test tools/renovate/config.test.ts 68/68, biome clean.

Spec-impact: none. Refs RIG-3296

Co-authored-by: Matt Wilkinson matt@rigel.build

@trunk-io

trunk-io Bot commented Sep 5, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@linear-code

linear-code Bot commented Sep 5, 2026

Copy link
Copy Markdown

RIG-3296

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://dependencies-rig-3296-devenv.compass-eng-docs.pages.dev

Deployed from dependencies/rig-3296-devenv-nixpkgs-fod-refresh at fcc0007.

rigel-mintaka added a commit that referenced this pull request Sep 5, 2026
…er (RIG-3296 review)

Addresses the review of #897.

**high** — the node-modules FOD refresh gated only on `bun.lock`, but `refresh-devenv-nixpkgs.ts` writes `bun.lock` only when the biome catalog pin moves; a biome-static channel bump left `bun.lock` untouched, so the FOD refresh no-op'd even though the channel moved `pkgs.bun` (the FOD's builder), shipping a stale `outputHash`. Add `devenv.lock` to the node-modules entry's triggers so the refresh fires on every channel bump and reconciles the pin idempotently. Regression test added (red-green verified).

**medium** — order-insensitive `.toContain` command asserts replaced with an order-pinning `.toEqual` (relock-then-FOD is load-bearing; mutation-verified reversal now reds). Stale two-site FOD counts corrected to three sites across config.test.ts, bot-config.json5, and the script header.

**low** — flipped test renamed to cover the command+order half; `config.json5` no-op comment reworded to state the gate's real scope.

Spec-impact: none. Refs RIG-3296
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review September 5, 2026 20:27
rigel-mintaka and others added 4 commits September 6, 2026 02:13
…RIG-3296)

The devenv-nixpkgs digest packageRule's `postUpgradeTasks` ran only `refresh-devenv-nixpkgs.ts`, with a comment asserting the FOD refresh was "intentionally absent" because a channel bump supposedly cannot move `agent-image/entrypoint.nix`'s `outputHash` (premise: biome is a root-only devDependency, absent from the `--filter '@compass/agent'` install).

That premise is empirically false. PR #580 (digest → 256551e) failed CI `e2e` with `hash mismatch in fixed-output derivation compass-agent-node-modules` (specified `sha256-GrsX8VmqoHIg…`, got `sha256-+ogECRp2…`). The channel bump re-resolved the `@compass/agent` closure in `bun.lock` (`@opentelemetry/sdk-metrics` 2.9→2.10 and an `@oh-my-pi/pi-coding-agent` re-nesting) **and** moved `pkgs.bun`, the nixpkgs-versioned builder the FOD installs with — both move the recursive `outputHash`. So every channel bump reds `e2e`.

Fix: add `bun tools/renovate/refresh-fod-hashes.ts` to the rule's `postUpgradeTasks.commands` (after the relock, so it self-gates on the now-changed `bun.lock` and realises the new tree) and `agent-image/entrypoint.nix` to `fileFilters` (Renovate commits only listed files — without it the recomputed hash edit is silently dropped). The command is already allowlisted in `bot-config.json5`. The exemption test in `config.test.ts` is flipped to pin the corrected wiring, and the global FOD site-count guard goes 2→3 (the FOD refresh now rides three task sites). Verified: `bun test tools/renovate/config.test.ts` 68/68, biome clean.

Spec-impact: none. Refs RIG-3296

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…er (RIG-3296 review)

Addresses the review of #897.

**high** — the node-modules FOD refresh gated only on `bun.lock`, but `refresh-devenv-nixpkgs.ts` writes `bun.lock` only when the biome catalog pin moves; a biome-static channel bump left `bun.lock` untouched, so the FOD refresh no-op'd even though the channel moved `pkgs.bun` (the FOD's builder), shipping a stale `outputHash`. Add `devenv.lock` to the node-modules entry's triggers so the refresh fires on every channel bump and reconciles the pin idempotently. Regression test added (red-green verified).

**medium** — order-insensitive `.toContain` command asserts replaced with an order-pinning `.toEqual` (relock-then-FOD is load-bearing; mutation-verified reversal now reds). Stale two-site FOD counts corrected to three sites across config.test.ts, bot-config.json5, and the script header.

**low** — flipped test renamed to cover the command+order half; `config.json5` no-op comment reworded to state the gate's real scope.

Spec-impact: none. Refs RIG-3296
…t (RIG-3296 review R2)

The order-pinning test's rationale described the pre-fix failure mode
(gate reads clean and no-ops on reversed order), which is false against
the shipped triggers: ["bun.lock", "devenv.lock"]. The devenv.lock
trigger makes the FOD entry gate in either order, so a reversed order is
worse than a no-op — it realises the FOD against the still-at-base
bun.lock, then step 5 rewrites bun.lock underneath it, committing a pin
for the OLD closure beside the NEW lockfile (the exact hash mismatch this
task prevents). Comment-only; the toEqual pin already defends the order.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…RIG-3360)

`packageRules[13]` (devenv fork root) and `packageRules[15]` (go <-> go-overlay
lockstep) each declare `devenv.lock` in `fileFilters` -- a declared trigger of
the `agent-image/entrypoint.nix` FOD entry -- while running no hash refresh. A
rule-level `postUpgradeTasks` REPLACES the top-level one on its branch, so both
evict the top-level FOD leg and can commit a lock change beside a pin that
still content-addresses the old closure. That is the failure mode which kept
Renovate PR #580 red: `hash mismatch in fixed-output derivation`.

Both sites now append the refresh AFTER the command that writes the lock (the
pin must be realised against the written file, not the still-at-base one) and
name `agent-image/entrypoint.nix` in `fileFilters` so the recomputed pin can
actually be committed -- `fileFilters` is an include allowlist, so omitting it
recomputes the pin and then silently drops it.

This is fail-safe rather than a live fix: `devenv update devenv` and
`devenv update go-overlay` each relock one non-nixpkgs input, so neither moves
the nixpkgs rev supplying `pkgs.bun`, the FOD's builder. But the coupling is
declared at file granularity, and an input-graph refactor would falsify that
causal argument silently. The refresh self-gates per entry, so the price is a
no-op.

Adds a generalized guard deriving the requirement from `FOD_ENTRIES` itself
rather than a hand-copied list: every task site naming a declared trigger must
run the refresh and name that entry's FOD file plus its mirrorFiles. Includes a
non-vacuity assertion and documents the detection boundary -- a trigger written
by a Renovate manager rather than the task never appears in `fileFilters`, which
is why the `guest-image/default.nix` vendorHash leg (triggers `go/go.mod`,
`go/go.sum`) stays covered by assertion on the top-level site instead.

Reconciles the moved counts: the refresh now rides five task sites, not three,
and the per-scope task pins for the fork and lockstep rules assert their whole
command lists so a reordering reds a test instead of shipping a stale pin.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the dependencies/rig-3296-devenv-nixpkgs-fod-refresh branch from 1c18965 to 285a196 Compare September 6, 2026 06:15
… (RIG-3360)

The generalized coverage guard bound membership but not order, matched
fileFilters by string equality where Renovate specifies globs, and its
non-vacuity floor could not see a partial trigger rename thin the coupled
set. Correct all three, hoist the single FOD command literal, and re-ground
the realise-cost and go-site reversed-order prose.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
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