agentguard-local
v0.1.1
Published
macOS-first RAM-aware admission controller for local AI coding CLI processes
Maintainers
Readme
AgentGuard
AgentGuard is a macOS-first local admission controller for AI coding CLI processes. It starts guarded jobs only when local policy and memory pressure allow it, queues new guarded work when the machine is under stress, pauses guarded process groups on critical pressure, and explains those decisions through a small CLI.
AgentGuard is not an agent orchestrator, worktree manager, sandbox, cloud IDE, RAM cleaner, or process killer for arbitrary apps. It only manages jobs launched through agentguard run or an installed AgentGuard shim.
What ships in this MVP
agentguardd: launchd-friendly user daemon with a user-only Unix domain socket.agentguard: CLI forstatus,run,policy,pause,resume,cancel,doctor, andinstall-shim.- SQLite state for jobs, process samples, events, policy, and tool path mappings.
- Pure scheduler and policy modules with deterministic tests.
- Process-group spawning with
SIGSTOPandSIGCONTfor guarded jobs only. - Codex adapter that injects
-c agents.max_threads=Nunless the user already supplied an explicitagents.max_threadsconfig. - Deterministic fake pressure support for tests through
AGENTGUARD_FAKE_PRESSURE_FILE.
Install
The npm package currently ships prebuilt binaries for macOS on Apple Silicon:
npm install -g agentguard-localThe npm package is named agentguard-local to avoid collisions with existing packages. It installs the agentguard and agentguardd commands.
Then start the daemon:
agentguardd \
--socket "$HOME/.agentguard/agentguard.sock" \
--db "$HOME/.agentguard/state.db" \
--foregroundBuild From Source
cargo build --workspace --all-featuresIf Cargo is not on PATH, install Rust first. On macOS with Homebrew:
brew install rustRun The Daemon
Foreground mode is easiest while testing from a source checkout:
target/debug/agentguardd \
--socket "$HOME/.agentguard/agentguard.sock" \
--db "$HOME/.agentguard/state.db" \
--foregroundThe daemon listens only on a local Unix domain socket and stores state in SQLite. It does not open a TCP listener.
Use The CLI
Check status:
target/debug/agentguard status
target/debug/agentguard status --jsonRun a guarded command:
target/debug/agentguard run -- /bin/echo hello
target/debug/agentguard run --priority low -- /bin/sleep 30Manage policy:
target/debug/agentguard policy get
target/debug/agentguard policy set max_active_jobs 1
target/debug/agentguard policy set pause_enabled truePause, resume, or cancel a guarded job:
target/debug/agentguard pause <job-id>
target/debug/agentguard resume <job-id>
target/debug/agentguard cancel <job-id>Run diagnostics:
target/debug/agentguard doctorInstall A Temporary Shim
Install a shim for a real tool path into a directory you control:
target/debug/agentguard install-shim codex \
--real-path /path/to/real/codex \
--shim-dir "$HOME/.agentguard/bin"Then put the shim directory before the real tool in PATH:
export PATH="$HOME/.agentguard/bin:$PATH"The shim dispatches through agentguard run, preserves cwd/env/stdin/stdout/stderr/args/exit code, and avoids PATH recursion by storing the real binary path.
Uninstall
Stop any foreground agentguardd process, remove the shim directory from PATH, and delete the local data directory if you no longer want state:
rm -rf "$HOME/.agentguard"If you later add a launchd plist, unload and remove it before deleting state.
Safety Model
- AgentGuard never pauses, resumes, cancels, or kills unguarded user processes.
- Automatic pause/resume uses process-group signals only for jobs that AgentGuard admitted and registered.
- Cancel sends
SIGTERMonly to the guarded process group for the selected job. - Job commands and events are stored locally in SQLite. Prompts are not separately captured.
- The v1 control plane is a user-only Unix socket with
0600permissions.
Limitations
- v1 does not queue individual Codex subagents after Codex is already running. It caps fan-out at launch.
- The current system pressure sampler uses stable macOS command output as a documented fallback while preserving the sampler boundary for native API work.
- There is no menu bar UI, cloud offload, container runtime, microVM dependency, or team dashboard.
- Pause does not immediately free all memory; it stops execution so pressure can recover.
