Skip to content

feat(containers): per-container user/group/homeDir + config-only isBuilding (RIG-2404) - #4

Merged
mattwilkinsonn merged 2 commits into
mainfrom
compass-repo/rig-2404-containers-identity
Aug 22, 2026
Merged

feat(containers): per-container user/group/homeDir + config-only isBuilding (RIG-2404)#4
mattwilkinsonn merged 2 commits into
mainfrom
compass-repo/rig-2404-containers-identity

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Aug 21, 2026

Copy link
Copy Markdown

Ports the Compass agent-image patch set onto src/modules/containers.nix so this shared canonical fork carries the container-identity machinery the Compass agent base image needs. This is the L0a slice of the compass forks-reversal (RIG-2336): the patch that lived as a vendored subtree in compass/forks/devenv/ moves here, into the fork repo it belongs to.

What changes (all in src/modules/containers.nix)

  • Per-container user / group / homeDir options. Upstream hardcodes user user with $HOME=/env module-wide; these move the passwd/group/shadow rows, the file-ownership perms, and the image config's User/HOME/USER together per container. Upstream's values are kept as the defaults (user, /env), so a consumer that sets none of them resolves to a byte-identical image — the identity is preserved by construction (the parameterized script bodies keep upstream's exact bytes, including line breaking, since a comment inside runCommand's text is part of the build command and shifts the derivation hash on its own).
  • Config-only buildingContainer / buildingHomeDir lookup, replacing the impure envContainerName = builtins.getEnv "DEVENV_CONTAINER" and the two config blocks it drove. The env path is dead: the nix backend already forces both container.isBuilding and containers.<name>.isBuilding (lib.mkForce true), and nothing in the tree writes DEVENV_CONTAINER. Reading identity out of an impure getEnv while the options already carry it is two sources of truth; the config-only lookup keeps one.
  • config.env serialized directly into the image config Env (plus HOME/USER from the resolved identity), matching the merged base. No DEVENV_-prefix filter in the module: a reusable module applies the minimal fix, not a blanket namespace strip. The one real leak (DEVENV_PROFILE, an absolute /nix/store path that acts as a closure root) is neutralized consumer-side, gated on isBuilding, exactly as orion already ships it — so this module stays byte-faithful to the currently-shipping image and a future consumer can drop its own override once every consumer relies on the module default.

Base & verification

Rebased onto this fork's current main (1a7cae09, the merged writable-$HOME change RIG-2368), not cherry-picked from the vendored bytes — the identity was re-established against the merged base.

Byte-identity nix-eval check (the gate the design requires): a default-identity container (copyToRoot = [ ], no user/group/homeDir override) resolves to the same image-spec store path on both this patched tree and the unpatched base — myvgpmpylndahwlza46mr4bqkfjhw4nd-image-devenv-shell-probe.json. The refactor is proven-pure for the default path; upstream devenv CI does not exercise the $HOME property, so this check — not the fork repo's own CI — is what proves the port.

CI status (triaged)

  • generate-docssuccess. This is the defect L0a targets: the workflow's EndBug/add-and-commit auto-commit step is push-gated and 403s under github-actions[bot], so the regenerated docs/gen options were committed locally in this PR. Green confirms the regen matches.
  • assign-reviewerssuccess.
  • pipeline (aarch64-linux | x86_64-linux | aarch64-darwin) / buildqueued indefinitely, expected. These legs require self-hosted runners (pr-test.yml matrix: ["self-hosted", "linux", "ARM64"] etc.) from the upstream devenv fleet that this fork does not have — runnerName never assigns. "PR Test" has never completed on this repo (all historical runs cancelled/queued). This is an environment gap, not a code defect. They are not merge-blocking: main has no branch protection (404) and no rulesets (gh api .../rules/branches/main → empty).

Spec-impact: none. Refs RIG-2404

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

…ilding (RIG-2404)

Ports the Compass agent-image patch set onto `src/modules/containers.nix` so this shared canonical fork carries the container-identity machinery the Compass agent base image needs. This is the L0a slice of the compass forks-reversal (RIG-2336): the patch that lived as a vendored subtree in `compass/forks/devenv/` moves here, into the fork repo it belongs to.

## What changes (all in `src/modules/containers.nix`)

- **Per-container `user` / `group` / `homeDir` options.** Upstream hardcodes user `user` with `$HOME=/env` module-wide; these move the passwd/group/shadow rows, the file-ownership `perms`, and the image config's `User`/`HOME`/`USER` together per container. **Upstream's values are kept as the defaults** (`user`, `/env`), so a consumer that sets none of them resolves to a byte-identical image — the identity is preserved by construction (the parameterized script bodies keep upstream's exact bytes, including line breaking, since a comment inside `runCommand`'s text is part of the build command and shifts the derivation hash on its own).
- **Config-only `buildingContainer` / `buildingHomeDir` lookup**, replacing the impure `envContainerName = builtins.getEnv "DEVENV_CONTAINER"` and the two config blocks it drove. The env path is dead: the nix backend already forces both `container.isBuilding` and `containers.<name>.isBuilding` (`lib.mkForce true`), and nothing in the tree writes `DEVENV_CONTAINER`. Reading identity out of an impure `getEnv` while the options already carry it is two sources of truth; the config-only lookup keeps one.
- **`config.env` serialized directly** into the image config `Env` (plus `HOME`/`USER` from the resolved identity), matching the merged base. No `DEVENV_`-prefix filter in the module: a reusable module applies the minimal fix, not a blanket namespace strip. The one real leak (`DEVENV_PROFILE`, an absolute `/nix/store` path that acts as a closure root) is neutralized consumer-side, gated on `isBuilding`, exactly as orion already ships it — so this module stays byte-faithful to the currently-shipping image and a future consumer can drop its own override once every consumer relies on the module default.

## Base & verification

Rebased onto this fork's current `main` (`1a7cae09`, the merged writable-`$HOME` change RIG-2368), not cherry-picked from the vendored bytes — the identity was re-established against the merged base.

**Byte-identity nix-eval check (the gate the design requires):** a default-identity container (`copyToRoot = [ ]`, no user/group/homeDir override) resolves to the *same* image-spec store path on both this patched tree and the unpatched base — `myvgpmpylndahwlza46mr4bqkfjhw4nd-image-devenv-shell-probe.json`. The refactor is proven-pure for the default path; upstream devenv CI does not exercise the `$HOME` property, so this check — not the fork repo's own CI — is what proves the port.

Spec-impact: none. Refs RIG-2404

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Aug 21, 2026

Copy link
Copy Markdown

RIG-2404

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

🔍 Suggested Reviewers

Based on git blame analysis of the changed lines, the following contributors have significant experience with the modified code:

  • @domenkozar - 64.2% of changed lines (34 lines)
  • @mcdonc - 26.4% of changed lines (14 lines)

Please consider reviewing this PR as you have authored significant portions of the code being modified. Your expertise would be valuable! 🙏

This comment was automatically generated by git-blame-auto-reviewer

Last updated: 2026-08-21T21:33:44.067Z

…tions

The container-identity patch (per-container user/group/homeDir +
config-only isBuilding) adds module options that the docs generator
reflects into docs/src/reference/options.md. Regenerate via
`devenv shell devenv-generate-doc-options` so the options reference
carries the new containers.<name>.{user,group,homeDir,isBuilding}
entries and the generate-docs CI check passes.

Generated, not hand-edited (header: DO NOT MODIFY).
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review August 21, 2026 22:07
@mattwilkinsonn
mattwilkinsonn merged commit 15a81f3 into main Aug 22, 2026
4 of 7 checks passed
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.

2 participants