100 lines
2.4 KiB
Markdown
100 lines
2.4 KiB
Markdown
|
|
# Pi Agent Isolation (two-repo setup)
|
||
|
|
|
||
|
|
This guide documents the split setup where:
|
||
|
|
|
||
|
|
- `m3ta-nixpkgs` provides reusable module logic.
|
||
|
|
- `nixos-config` consumes it on specific hosts.
|
||
|
|
|
||
|
|
## 1) In `m3ta-nixpkgs`
|
||
|
|
|
||
|
|
Use:
|
||
|
|
|
||
|
|
- Home Manager module: `coding.agents.pi`
|
||
|
|
- renders Pi config in user space (default path: `.pi/agent` => `~/.pi/agent`)
|
||
|
|
- NixOS module: `m3ta.pi-agent`
|
||
|
|
- dedicated user/group (default `pi-agent`)
|
||
|
|
- state directory (default `/var/lib/pi-agent`)
|
||
|
|
- hardened execution via transient `systemd-run`
|
||
|
|
- host-side wrapper command (default `pi`)
|
||
|
|
- per-user allowlists via `hostUsers.<name>.projectRoots`
|
||
|
|
- host config sync into isolated runtime (default source `.pi/agent`)
|
||
|
|
- managed settings/env merge into isolated runtime
|
||
|
|
|
||
|
|
## 2) In consumer repo (`nixos-config`)
|
||
|
|
|
||
|
|
### Home Manager side
|
||
|
|
|
||
|
|
Keep Pi config rendering enabled for your normal user:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
coding.agents.pi = {
|
||
|
|
enable = true;
|
||
|
|
agentsInput = inputs.agents;
|
||
|
|
path = ".pi/agent";
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### NixOS host side (example: `m3-kratos`)
|
||
|
|
|
||
|
|
Enable isolated wrapper execution:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
m3ta.pi-agent = {
|
||
|
|
enable = true;
|
||
|
|
stateDir = "/var/lib/pi-agent";
|
||
|
|
|
||
|
|
hostUsers = {
|
||
|
|
m3tam3re = {
|
||
|
|
projectRoots = ["~/p" "~/work/private"];
|
||
|
|
# optional; defaults to wrapper.hostConfigPath
|
||
|
|
configPath = ".pi/agent";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
settings = {
|
||
|
|
defaultProvider = "anthropic";
|
||
|
|
defaultModel = "anthropic/claude-sonnet-4";
|
||
|
|
quietStartup = true;
|
||
|
|
};
|
||
|
|
|
||
|
|
environment = {
|
||
|
|
PI_TELEMETRY = "0";
|
||
|
|
};
|
||
|
|
|
||
|
|
environmentFiles = [
|
||
|
|
"/run/secrets/pi-agent.env"
|
||
|
|
];
|
||
|
|
|
||
|
|
wrapper = {
|
||
|
|
enable = true;
|
||
|
|
commandName = "pi";
|
||
|
|
hideDirectBinary = true;
|
||
|
|
hostConfigPath = ".pi/agent";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 3) Authorization model
|
||
|
|
|
||
|
|
The wrapper uses a tightly scoped sudo rule:
|
||
|
|
|
||
|
|
- authorized users may run only the privileged runner command
|
||
|
|
- with `NOPASSWD`
|
||
|
|
- no broad `NOPASSWD: ALL`
|
||
|
|
|
||
|
|
## 4) Merge behavior
|
||
|
|
|
||
|
|
At invocation time, isolated runtime files are built from:
|
||
|
|
|
||
|
|
1. Host user Pi config (synced from source path, e.g. `~/.pi/agent`)
|
||
|
|
2. Nix-managed settings/env (override host values)
|
||
|
|
3. Environment files (appended after managed env attrs)
|
||
|
|
|
||
|
|
This keeps user-authored Pi config available while allowing reproducible Nix overrides.
|
||
|
|
|
||
|
|
## 5) Migration notes
|
||
|
|
|
||
|
|
- If wrapper mode is canonical, remove direct `pi-coding-agent` from user package lists to reduce command-path ambiguity.
|
||
|
|
- Rebuild host config and test from an allowlisted project path.
|
||
|
|
- Validate `pi` process identity runs as `pi-agent`.
|