Skip to content

feat(renovate): verify the agent-image FOD through its own builder (RIG-3365) - #1047

Open
rigel-mintaka wants to merge 1 commit into
dependencies/rig-3365-agent-image-nixpkgsfrom
dependencies/rig-3365-agent-image-fod-vehicle
Open

feat(renovate): verify the agent-image FOD through its own builder (RIG-3365)#1047
rigel-mintaka wants to merge 1 commit into
dependencies/rig-3365-agent-image-nixpkgsfrom
dependencies/rig-3365-agent-image-fod-vehicle

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 2 PRs:

  1. main
  2. feat(renovate): track the agent-image nixpkgs channel pin (RIG-3365) #1046
  3. "feat(renovate): verify the agent-image FOD through its own builder (RIG-3365)" (this PR)

agent-image/entrypoint.nix carries one outputHash over the installed
node_modules tree, and two consumers import it with different nixpkgs revs:
guest-image/default.nix with root's pkgs, agent-image/devenv.nix with the
agent-image scope's. The FOD builder takes nativeBuildInputs = [ pkgs.bun ], so
one hash is correct for both only while both channels' bun produce a
byte-identical install tree.

The refresh realised a single vehicle, guest-image/default.nix, which resolves
root's pkgs. Nothing built agent-image/devenv.nix. So a channel-rev drift left
the pin right for guest-image and silently wrong for the agent image, surfacing
only in the OCI build.

Give that consumer its own realise vehicle and check the shared pin through it:

  • BUILD_FILE/BUILD_TARGET move from module globals onto FodEntry, so one pin can
    be realised through two vehicles.
  • A third table row verifies rather than writes: it recomputes through the
    agent-image scope and compares, throwing with both SRIs, both vehicles and
    both channel revs on divergence. The authoritative row keeps writing.
  • refreshFodEntries partitions writes before verifies, so the baseline is always
    the refreshed pin; refreshEntry refuses a verify entry outright.
  • Load-time table invariants: one writer per pin, a verify entry must share its
    target's pin and triggers and realise a DIFFERENT vehicle, and drvFragment
    disjointness is scoped per vehicle (the two rows share a fragment because they
    are the same derivation under two channels).

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

@linear-code

linear-code Bot commented Sep 9, 2026

Copy link
Copy Markdown

RIG-3365

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://dependencies-rig-3365-agent.compass-eng-docs.pages.dev

Deployed from dependencies/rig-3365-agent-image-fod-vehicle at 2e023a0.

…IG-3365)

agent-image/entrypoint.nix carries one outputHash over the installed
node_modules tree, and two consumers import it with different nixpkgs revs:
guest-image/default.nix with root's pkgs, agent-image/devenv.nix with the
agent-image scope's. The FOD builder takes nativeBuildInputs = [ pkgs.bun ], so
one hash is correct for both only while both channels' bun produce a
byte-identical install tree.

The refresh realised a single vehicle, guest-image/default.nix, which resolves
root's pkgs. Nothing built agent-image/devenv.nix. So a channel-rev drift left
the pin right for guest-image and silently wrong for the agent image, surfacing
only in the OCI build.

Give that consumer its own realise vehicle and check the shared pin through it:

- BUILD_FILE/BUILD_TARGET move from module globals onto FodEntry, so one pin can
  be realised through two vehicles.
- A third table row verifies rather than writes: it recomputes through the
  agent-image scope and compares, throwing with both SRIs, both vehicles and
  both channel revs on divergence. The authoritative row keeps writing.
- refreshFodEntries partitions writes before verifies, so the baseline is always
  the refreshed pin; refreshEntry refuses a verify entry outright.
- Load-time table invariants: one writer per pin, a verify entry must share its
  target's pin and triggers and realise a DIFFERENT vehicle, and drvFragment
  disjointness is scoped per vehicle (the two rows share a fragment because they
  are the same derivation under two channels).

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the dependencies/rig-3365-agent-image-fod-vehicle branch from 6917e89 to 2e023a0 Compare September 10, 2026 01:30
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review September 10, 2026 01:30
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