Background agents
Background agents let you kick off a task and walk away. The agent runs detached, captures output to a log file, and you can check on it later.
Start
isonforge --bg "audit every fetch() call for missing await + timeout"
Output:
✓ Background agent started: a3f8c1d2
pid: 18472
logs: isonforge logs a3f8c1d2
follow: isonforge attach a3f8c1d2
stop: isonforge stop a3f8c1d2
The parent process exits immediately. The agent continues running in the background using your current working directory. It calls IsonForge in --print --yolo mode internally, so all tools are auto-approved.
Manage
isonforge agents # list all
isonforge logs <id> # tail recent stdout (default 50 lines)
isonforge logs <id> -n 200 # tail more
isonforge attach <id> # follow live (Ctrl+C to detach)
isonforge stop <id> # SIGTERM then SIGKILL after 3s
isonforge respawn <id> # restart a stopped agent with original prompt
isonforge rm <id> # remove a stopped agent from the list
List output
ID State Started Prompt
───────────────────────────────────────────────────
a3f8c1d2 running 2h ago audit every fetch() call for missing await...
91b4ef0a stopped 5h ago refactor session.py to use redis with proper...
c2d7a3b8 running 45s ago summarize all README.md files in submodules
State derives from the recorded PID:
running- pid alive.stopped- pid not found (process completed or was killed).
State auto-syncs when you list.
State files
Each agent has a directory at ~/.isonforge/agents/<id>/:
| File | Contents |
|---|---|
meta.json |
id, pid, prompt, cwd, started_at, state |
stdout.log |
cumulative stdout from the agent |
stderr.log |
cumulative stderr |
The agent process holds an exclusive write to the log files. You can cat / tail them safely as a reader.
Why background?
- Long-running audits. "Review every file" can take 20 minutes. Don't tie up a terminal.
- Parallel features. Launch one agent per feature, work on something else while they progress.
- Trigger-and-forget. Fire off a routine task and check tomorrow.
Pair with worktrees
The most useful pattern: one background agent per worktree.
isonforge -w feature-auth --bg "implement the new auth flow with tests"
isonforge -w feature-billing --bg "wire up the stripe webhook handler"
isonforge agents
Each agent runs in its own branch directory with its own isolated state. Combined effect: like having multiple junior engineers each working on a separate ticket.
Carve out effort / permission
The agent inherits the spawn-time effort and permission mode:
isonforge --bg --effort max --permission-mode auto "audit every endpoint"
These persist in meta.json and apply on respawn.
Respawn
If an agent crashed or hit a budget cap and stopped, restart it with the same prompt:
isonforge respawn a3f8c1d2
The respawned agent is a fresh --print run with the original prompt. Conversation state from the previous run is NOT preserved - this isn't a true resume. If you need conversation continuity, use sessions (/sessions + --continue) instead.
Remove
When done with an agent:
isonforge stop <id> # if still running
isonforge rm <id> # delete the directory + logs
rm refuses to delete running agents - stop first.
Caveats
- Stdin is closed. Agents can't ask for permission - they run with
--yolo. Don't background a task that requires human-in-the-loop decisions. - No live UI. No streaming reasoning panel, no permission prompts, no slash commands.
- Cost not tracked. Self-hosted, so usually not an issue. If you set
ISONFORGE_RATE_*env in the parent, the agent picks them up but no budget cap is enforced unless you also pass--max-budget-usd. - Crashes silent. If the agent dies, you see "stopped" state but no auto-alert. Check
stderr.log. - Detached from terminal. Closing your terminal doesn't kill the agent. Use
isonforge stoporkill <pid>.
When NOT to background
- Quick tasks. Anything under 30 seconds - just run it in the foreground.
- Tasks that need decisions. Anything where the model might ask "should I do X or Y?".
- First time running this task. Try it foreground once to see the behavior, then background it for repeat runs.