Files
nixpkgs/PLAN.md
2026-04-14 18:36:13 +02:00

99 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PLAN
## Context
- Target implementation is confirmed as `m3ta.pi-agent` (no container mode).
- You want a **fresh-from-scratch rewrite** of `modules/nixos/pi-agent.nix` and to ignore prior behavior as design baseline.
- Required behavior:
- dedicated isolated Unix user/group for Pi (`pi-agent` defaults)
- host UX stays `pi`
- bypass prevention (wrapper should be the canonical executable path)
- per-host-user project root policy (different roots per user)
- no writable/access scope beyond isolated Pi home/state + explicitly allowed project roots
- isolated environment must include user Pi config from HM (`modules/home-manager/coding/agents/pi.nix`) and support Nix-managed settings/env merging.
- Repo findings:
- `modules/nixos/default.nix` + `flake.nix` already import/export `pi-agent` module.
- `modules/home-manager/coding/agents/pi.nix` already renders Pi config files under a configurable relative path (`coding.agents.pi.path`, default `.pi/agent`).
## Approach
- Fully replace `modules/nixos/pi-agent.nix` with a new design centered on:
1. **Dedicated runtime identity** (`user/group/createUser/stateDir`).
2. **Policy-driven wrapper flow** (`pi` -> privileged runner -> isolated execution).
3. **Per-user project allowlists** (cwd must be under roots assigned to invoking host user).
4. **Config + env convergence**:
- sync user HM Pi config directory (e.g. `~/.pi/agent`) into isolated state,
- merge Nix-managed Pi settings into isolated `settings.json`,
- merge Nix-managed env vars + env files into isolated runtime env source,
- make merged results visible to the isolated runtime every invocation (without container recreation semantics).
5. **Hard isolation defaults** with `systemd-run` sandboxing and explicit bind/read-write paths only for state + allowed projects.
- Keep wrapper command as `pi`, and avoid exposing direct package binary on PATH when wrapper mode is enabled.
## Files to modify
- `modules/nixos/pi-agent.nix` (full rewrite)
- `modules/nixos/default.nix` (only if import list changes)
- `flake.nix` (only if output export attrs change)
- `docs/guides/pi-agent-isolation.md` (update option model + merge behavior)
- `docs/guides/using-modules.md` (update examples/options)
## Reuse
- Module/user/service patterns:
- `modules/nixos/mem0.nix`
- `templates/nixos-module/default.nix`
- Pi config rendering contract to consume/sync:
- `modules/home-manager/coding/agents/pi.nix` (`coding.agents.pi.path`, `settings.json`, `mcp.json`, agent docs)
## Steps
- [ ] Define the new `m3ta.pi-agent` option schema for fresh module behavior, including:
- base runtime options (`package`, `binaryName`, `user`, `group`, `createUser`, `stateDir`),
- wrapper controls (`enable`, `commandName`, runner name, hide-direct-binary behavior),
- per-user policy map (allowed users and each users allowed project roots),
- host-config sync knobs (source path relative/absolute),
- Nix-managed settings/env options for merge.
- [ ] Implement new wrapper script:
- identify invoking user,
- validate user exists in policy map,
- expand/resolve that users roots,
- deny out-of-policy cwd,
- escalate only to the dedicated runner.
- [ ] Implement new privileged runner script:
- enforce root-only execution,
- resync host Pi config into isolated config dir,
- merge managed settings into isolated settings file,
- merge managed env + env files into isolated env file/export source,
- prepare deterministic project mount aliases under isolated home,
- launch Pi through hardened transient `systemd-run` unit as isolated user.
- [ ] Apply hardening policy in execution profile:
- `ProtectSystem=strict`, `ProtectHome=yes`, `NoNewPrivileges=yes`,
- explicit `ReadWritePaths` limited to state + mounted allowed projects,
- bounded runtime PATH and writable tool/cache locations under `stateDir`.
- [ ] Add assertions for misconfiguration (e.g., empty per-user roots, wrapper enabled without authorized users).
- [ ] Add tightly scoped sudoers rule for runner command only.
- [ ] Ensure bypass prevention in packaging/PATH behavior when wrapper mode is enabled.
- [ ] Update docs with new option examples (per-user roots + settings/env merge + HM sync expectations).
## Verification
- Static/eval:
- `nix flake check`
- host config eval/build with new module options.
- Policy checks:
- authorized user in authorized root: succeeds
- authorized user outside authorized root: denied
- unauthorized user: denied
- Isolation checks:
- runtime identity is isolated service user (`pi-agent`)
- no unintended write access outside `stateDir` + allowed project binds
- direct binary bypass unavailable when wrapper mode is enabled
- Merge checks:
- HM-rendered Pi files are present in isolated config dir
- Nix-managed settings are merged into effective isolated `settings.json`
- env values from declarative attrs + env files are present in isolated runtime environment.
## Open questions
- None.
## Resolved decisions
- Merge precedence is confirmed as:
1) synced host Pi config/env,
2) Nix-managed settings/env override synced values,
3) wrapper/runtime shell env does not implicitly override managed values.
- Per-user host config source defaults to `.pi/agent` for all users, with optional per-user override support in the policy map.