Skip to content

fix(sessions): chmod ~/.config/agent-box after mkdir -p, add test coverage (#78) - #491

Merged
defangdevs merged 3 commits into
masterfrom
fix/78-verify-tmpfiles-config-dir
Sep 1, 2026
Merged

fix(sessions): chmod ~/.config/agent-box after mkdir -p, add test coverage (#78)#491
defangdevs merged 3 commits into
masterfrom
fix/78-verify-tmpfiles-config-dir

Conversation

@defangdevs

@defangdevs defangdevs commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

Investigated #78 (the tmpfiles rule for ~/.config/agent-box "possibly not applied on rebuild"). What started as a test-coverage PR turned up a real, still-live bug — CI on the first push caught it directly.

Root cause, confirmed from the CI VM's boot journal:

systemd-tmpfiles[407]: /etc/tmpfiles.d/00-nixos.conf:13: Failed to resolve group 'agent': Unknown group
systemd-tmpfiles[407]: /etc/tmpfiles.d/00-nixos.conf:14: Failed to resolve group 'agent': Unknown group

agent is a normal (isNormalUser) declarative user, created by the legacy
NixOS user/group activation script rather than systemd-sysusers. Nothing
orders systemd-tmpfiles-setup.service after that activation, so on a fresh
boot it can run before the agent group exists — losing the race and
silently skipping both the parent (~/.config, #356) and child
(~/.config/agent-box) tmpfiles lines. The directory still gets made, by
registry.sh's own mkdir -p "${REGISTRY_FILE%/*}" (two call sites) — but
mkdir -p only applies a mode when it creates every missing path component,
and does so under umask, landing on ~0755 instead of the declared 0700.

envstore.py's save() already works around the identical class of problem
by chmoding its directory after os.makedirs() ("a directory made by an
older mkdir -p under umask 022 is 0755"). This PR does the same in the
shared shell registry helper, so ~/.config/agent-box's mode self-heals
regardless of which side of the boot-order race wins, rather than trying to
fix the race itself (a much bigger, riskier change to NixOS's own unit
ordering assumptions).

What was unverified before this PR: tests/sessions.nix's first-boot
subtest already runs against a disk that's fresh every time, but only
checked sessions.json's owner/mode — a file inside the dir, not the dir
itself. Asserting the directory directly (this PR's first commit) is what
surfaced the gap; the second commit fixes it.

Out of scope: the issue also flags "Codex-side unverified (0700 home)"
— that's the native (non-NixOS) renderer's home-dir permissions, a
different code path, and its settings daemon already works per the issue.
Left alone here.

Changes

  1. tests/sessions.nix: assert /home/agent/.config/agent-box is
    agent:agent 0700 before checking sessions.json inside it.
  2. modules/src/lib/registry.sh: chmod 0700 the registry directory right
    after each of its two mkdir -p call sites, mirroring envstore.py's
    existing precedent. modules/agent-box.nix and tests/golden
    regenerated (nix run .#assemble, nix run .#update-golden) — the fix
    reaches all 5 payload sites that splice in registry.sh (session CLI,
    supervisor, mark-stopped x2, webhook-spawn), on both the NixOS and
    native backends (shared source file, confirmed by one-spec-both-backends
    and backend-parity).

Test plan

  • nix-instantiate --parse tests/sessions.nix
  • python3 tests/test-assemble-module.py
  • nix build .#checks.aarch64-linux.module-generated-up-to-date
  • nix build .#checks.aarch64-linux.golden-snapshot (regenerated, now matches)
  • nix build .#checks.aarch64-linux.one-spec-both-backends
  • nix build .#checks.aarch64-linux.backend-parity
  • CI: sessions VM test (x86_64-linux only — this box is aarch64, can't run it locally). First push failed exactly as expected on the un-fixed tree; re-running with the fix included.

Closes #78.

…in it (#78)

The first-boot subtest only checked sessions.json's owner/mode, which
proves the config dir exists but never pins its own owner/mode. That's
exactly what #356's parent-dir tmpfiles rule fixed (tmpfiles used to
auto-create ~/.config as root and then refuse to descend into it),
and the VM's disk is fresh on every run — the one condition the bug
needed. Assert the directory directly so a regression there fails
loudly instead of only failing whatever happens to write into it next.
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 20d912d1-0414-497d-a8e8-0b2bb1253756

📥 Commits

Reviewing files that changed from the base of the PR and between bb16470 and 2fec74c.

📒 Files selected for processing (7)
  • modules/agent-box.nix
  • modules/src/lib/registry.sh
  • tests/golden/vm/payloads/agent-box-agent-mark-stopped
  • tests/golden/vm/payloads/agent-box-session/bin/agent-box-session
  • tests/golden/vm/payloads/agent-box-supervisor/bin/agent-box-supervisor
  • tests/golden/web/payloads/agent-box-robot-mark-stopped
  • tests/golden/web/payloads/agent-box-webhook-spawn/bin/agent-box-webhook-spawn

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 629d61f4-a5ca-4322-b0e2-f67bf250b4b8

📥 Commits

Reviewing files that changed from the base of the PR and between 1f3d6a4 and bb16470.

📒 Files selected for processing (7)
  • modules/agent-box.nix
  • modules/src/lib/registry.sh
  • tests/golden/vm/payloads/agent-box-agent-mark-stopped
  • tests/golden/vm/payloads/agent-box-session/bin/agent-box-session
  • tests/golden/vm/payloads/agent-box-supervisor/bin/agent-box-supervisor
  • tests/golden/web/payloads/agent-box-robot-mark-stopped
  • tests/golden/web/payloads/agent-box-webhook-spawn/bin/agent-box-webhook-spawn

Included review availability: Your plan provides up to 8 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change enforces mode 0700 for Agent Box registry directories after creation and adds a VM assertion for fresh-disk configuration directory ownership and permissions.

Changes

Agent Box permissions

Layer / File(s) Summary
Registry directory permission enforcement
modules/agent-box.nix, modules/src/lib/registry.sh
Registry lock and initialization paths apply mode 0700 after directory creation.
Generated payload permission updates
tests/golden/...
VM and web payload scripts apply the same registry directory permission correction.
Configuration directory initialization test
tests/sessions.nix
The VM test checks fresh-disk tmpfiles creation, ownership, and mode for /home/agent/.config/agent-box.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to bb164

The change ensures the registry directory is created with private permissions across supported paths and adds direct test coverage; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: lionello, claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (6 skipped: 6 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #78 by testing fresh-directory ownership and mode, investigating the tmpfiles failure, and enforcing mode 0700 when the registry helper creates the directory. The PR does not…
Out of Scope Changes check ✅ Passed All changes support issue #78: they add the requested assertion, fix registry-directory permissions, and regenerate affected module and golden files. No unrelated code changes are evident.
Title check ✅ Passed The title clearly identifies the main changes: applying chmod to ~/.config/agent-box after mkdir -p and adding test coverage.
Description check ✅ Passed The description directly explains the boot-order race, the chmod fix, the added assertion, regenerated files, and test status. It is fully related to the changeset.
Full details: Linked Issues check

Explanation

The changes address issue #78 by testing fresh-directory ownership and mode, investigating the tmpfiles failure, and enforcing mode 0700 when the registry helper creates the directory. The PR does not simulate a rebuild or change native renderer permissions, but those items are not required for the implemented coding scope.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (6 skipped: 6 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/78-verify-tmpfiles-config-dir

Comment @coderabbitai help to get the list of available commands.

PR #491's new assertion caught a real gap: on a fresh boot the
`d /home/<user>/.config/agent-box 0700 ...` tmpfiles rule loses a race
against the declarative user's own group creation —

    systemd-tmpfiles[407]: /etc/tmpfiles.d/00-nixos.conf:13: Failed to
    resolve group 'agent': Unknown group

`agent` is a normal (isNormalUser) user, created by the legacy
activation script rather than systemd-sysusers, and nothing orders
tmpfiles-setup after that activation — so both the parent and child
tmpfiles lines are silently skipped. The directory still gets made,
by registry.sh's own `mkdir -p "${REGISTRY_FILE%/*}"` (two call
sites), but mkdir only applies a mode when it creates every missing
component, and does so under umask — landing on ~0755 instead of the
intended 0700.

envstore.py's save() already chmods its directory after makedirs for
exactly this reason ("a directory made by an older mkdir -p under
umask 022 is 0755"). Do the same in the shell registry helper so the
mode self-heals regardless of which side of the boot-order race wins,
rather than trying to fix the race itself.

modules/agent-box.nix and tests/golden regenerated via
`nix run .#assemble` / `nix run .#update-golden`.
@defangdevs defangdevs changed the title test(sessions): assert the ~/.config/agent-box dir itself (#78) fix(sessions): chmod ~/.config/agent-box after mkdir -p, add test coverage (#78) Sep 1, 2026
CI caught it: test_a_write_that_cannot_land_is_reported_as_a_failure
deliberately chmods an EXISTING registry directory to 0500 to simulate
a full disk / read-only $HOME, then expects the write to fail. The
previous commit's unconditional `chmod 0700` after `mkdir -p` ran on
every call regardless of whether the directory was already there, so
it silently undid that simulation and the write succeeded instead of
failing.

Guard both call sites on `[ -d ... ]` first, so the chmod (and the
mkdir) only run when this call is the one creating the directory —
matching the actual bug (tmpfiles lost the boot-order race and the
directory does not exist yet), not touching a directory that already
exists for any other reason, deliberate or not.

modules/agent-box.nix and tests/golden regenerated.
@defangdevs
defangdevs merged commit 866b919 into master Sep 1, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Agent-Box Sep 1, 2026
@defangdevs
defangdevs deleted the fix/78-verify-tmpfiles-config-dir branch September 1, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

tmpfiles rule for ~/.config/agent-box possibly not applied on rebuild

1 participant