Find and stop stale AI-agent work without killing the wrong thing.
Agent runs can leave behind shells, browsers, containers, test loops, repo scans, local model processes, and sometimes other agents. Zen helps identify which work is still active and which Zen-owned work is safe to stop.
Zen is a small Linux CLI for that problem. It audits CPU, RAM, swap, processes, Docker, and leases created by Zen, then shows what is safe to stop and what it will leave alone.
audit -> classify -> protect -> lease -> clean
The default command is intentionally non-destructive:
zen cleanThat command is read-only: it reports pressure, workload buckets, cleanup candidates, and safety gates without killing processes or stopping containers.
Zen is not a RAM booster, generic process killer, or desktop cleaner. It tracks agent-spawned work and only cleans up work it can prove it owns:
- group observed Linux processes into heuristic workload buckets such as agents, browsers, Docker/Kubernetes-related commands, terminals, build tools, services, kernel/system work, and other processes
- protect known browser, terminal, desktop/session, local model, and agent CLI process patterns by default, with policy hooks for local additions
- run new work with TTL leases
- stop only expired Zen-owned process groups after re-checking the recorded root process identity and process group
- label Docker runs with Zen ownership and expiry metadata
- keep local JSONL events and short pressure history
- emit default-redacted JSON reports for automation, debugging, or local handoff
- attempt to enforce optional CPU/RAM/process-count budgets through
systemd-run --user --scopeor writable delegated cgroup v2, and mark budgets advisory when enforcement is unavailable
Zen is deliberately conservative: it may report unknown work, but execution paths are limited to expired work that Zen owns and can re-identify.
Zen is early-stage local tooling for Linux developer workstations. Its execution paths are intentionally narrow and test-covered before being expanded.
From source:
git clone https://github.com/dodge1218/zen.git
cd zen
python3 -m pip install -e .Or run directly from the checkout:
PYTHONPATH=. python3 -m zen.cli cleanzen status
zen doctor
zen clean
zen clean --jsonExample output shape:
CPU/RAM audit:
pressure: yellow
load: 4.21 3.80 3.10
ram available: 8.4 GiB / 16.0 GiB
swap used: 3.1 GiB / 10.0 GiB (31.0%)
by workload:
agents cpu=120.0% rss=1.2 GiB swap=512.0 MiB procs=8
browsers cpu= 15.0% rss=2.8 GiB swap=300.0 MiB procs=24
docker/kube cpu= 10.0% rss=600.0 MiB swap= 20.0 MiB procs=12
recommendations:
[review] Agent CPU is the top pressure source; inspect active runs before stopping anything.
[protect] Browsers are large but protected; Zen cleanup does not close browser tabs or browser processes by default.
zen status # pressure summary
zen doctor # resource summary and proposed actions
zen explain # why each cleanup action is gated
zen explain --json # JSON explanation of cleanup gates
zen clean # CPU/RAM audit + dry-run cleanup
zen clean --json # machine-readable audit, never executes
zen clean --execute # execute only Zen-owned expired leases
zen clean --execute --allow-docker # additionally allow Zen-owned Docker stops
zen ps --top 25 # hot processes
zen swap # processes using swap
zen swap-refresh # explain swapoff/swapon safety gates
zen swap-refresh --execute # refresh swap after a RAM-headroom gate passes
zen docker # container classification
zen docker-run --ttl 30m IMAGE # run labeled Docker container
zen run --ttl 30m -- command # run command under a Zen-owned TTL lease
zen adopt PID --ttl 30m # observe-only lease for existing process
zen reap # continuously enforce expired owned leases
zen reap --once # one TTL enforcement pass
zen leases # active Zen leases
zen events # recent lifecycle/cleanup events
zen history --record # record one pressure snapshot
zen history --json # show pressure history
zen report # redacted host report
zen config --init # create editable policy configZen only kills through a narrow path:
zen cleanis dry-run.zen clean --jsonis read-only and cannot be combined with--execute.zen clean --executecan stop only expired leases with verified process identity.zen adopt PIDis observe-only unless--allow-killis explicit.- Docker cleanup requires Zen ownership labels, expiry labels, and
--allow-docker. - Heuristic matches only get reported. They are never enough to kill a process.
- Browsers, terminals, desktop/session processes, and active LLM sessions are protected by default.
Classification and protection are policy-driven heuristics. Unknown tools,
renamed binaries, unusual terminal/browser builds, or custom agent launchers may
need entries in ~/.config/zen/policy.json.
The test suite uses real subprocesses for process-safety checks and unit-level coverage for Docker gates, JSON read-only behavior, event logging, history logging, and swap-refresh headroom checks.
Run it:
PYTHONPATH=. python3 -m unittest discover -s tests -vRun future work with a TTL:
zen run --class test --ttl 30m -- pytest
zen run --class agent-scan --ttl 45m -- codex exec "scan this repository"When a Zen-owned lease expires, zen clean --execute or zen reap can stop its
process group. Before sending a signal, Zen re-checks the process UID, process
group, session, and Linux start-time tick recorded in the lease. Stale or
hand-edited lease state is reported but not killed.
Run Docker work with Zen labels:
zen docker-run --ttl 30m --name test-db postgres:16
zen docker-run --ttl 30m --mem 1g --cpu 1 --pids 128 redis:7Only expired containers launched with Zen ownership and expiry labels are
eligible for zen clean --execute --allow-docker.
Zen does not manage Kubernetes resources directly. Kubernetes-related pressure is currently process/container visibility, not cluster object lifecycle management.
Leases can also carry resource budgets:
zen run --class eval --ttl 2h --mem 8g --cpu 4 --pids 128 -- commandWhen systemd-run --user --scope is available, Zen runs budgeted commands in a
transient systemd scope with MemoryMax, CPUQuota, and TasksMax. If systemd
is unavailable, Zen tries a delegated cgroup v2 backend. If neither backend is
available, the command still runs and the lease records that Zen could not
enforce the budgets.
zen swap-refresh --execute is still a system-wide swap operation. Review the
plan before execution, especially on production, remote, or shared hosts.
Redacted reports hide commands, cwd, hostnames, and container details by default, but they may still include operational metadata such as PIDs, tags, platform data, and action reasons.
Zen is Linux-only today. It relies on /proc, POSIX process groups, optional
systemd-run --user, optional cgroup v2, and the Docker CLI when Docker
features are used. macOS, Windows, WSL, containers, and locked-down CI hosts may
have partial or unsupported behavior.
Zen does not create more RAM, replace Linux memory management, or make large models smaller. It does not prove that a workload is abandoned. It records ownership and expiry metadata for agent work so expired Zen-owned processes, containers, and runners can be reviewed or stopped safely.