Operate Shoal
Build the operator environment that keeps multiple agents legible: stable topology, fast supervision, durable journals, and explicit human checkpoints.
Flow-State Workflows¶
Shoal is not just a command launcher. At its best, it becomes a terminal interface for distributed attention: one place to stage intent, route work, supervise approvals, and keep yourself in flow.
Design target¶
The highest-leverage Shoal setup optimizes for four things:
Session creation should feel defaulted, not like a ritual that burns attention before work begins.
Keep the operator surface stable so supervision, review, and intervention stay near the work.
Shorten the distance between waiting prompts, escalation signals, and human decisions.
Use journals and naming conventions so interruption recovery costs less than re-explaining the task.
The mistake to avoid
Optimizing each tool in isolation. The unit of measure is the end-to-end loop from "work appears" to "work is reviewed or escalated" — not how fast a single session starts.
Build the reference environment¶
The intended daily-driver stack is:
fish
Use shell ergonomics that keep navigation, completions, and helper functions fast enough to disappear.
tmux
Anchor the fleet in a durable topology instead of reopening fragile terminal layouts all day.
Reuse stable pane shapes and tool defaults so the system reads the same way every time.
Capture intent, blockers, and handoff state where the next operator can actually use it.
Relieve waiting-state pressure without hiding the approvals and escalation points that still need a human.
The design mistake to avoid is optimizing each tool in isolation. Optimize the end-to-end loop from "work appears" to "work is reviewed or escalated."
Set the control plane defaults¶
Start with a clean ~/.config/shoal/config.toml that reflects how you actually work:
[general]
default_tool = "codex"
worktree_dir = ".worktrees"
use_nerd_fonts = true
[tmux]
session_prefix = "_"
popup_width = "92%"
popup_height = "88%"
popup_key = "S"
[robo]
default_tool = "pi"
default_profile = "default"
session_prefix = "__"
[remote.devbox]
host = "devbox.example.com"
user = "rr"
api_port = 8080
Tip
Use defaults aggressively. Every choice you defer to session-creation time is a micro-interruption that compounds across the day.
The goal is to remove choice at the point where work should begin. Use defaults aggressively.
Also decide where your active attention will live:
shoal popupfor rapid supervision,- a pinned tmux window for
shoal status, - one naming convention for sessions and branches,
- one default review topology that you can reach for without thinking.
Design stable worker templates¶
The difference between "parallel terminals" and a real multi-agent system is repeatable structure. Templates give the robo, the popup, and you a consistent mental model.
[template]
name = "codex-review"
description = "Codex worker with a terminal wingman and shared MCP"
extends = "base-dev"
tool = "codex"
mcp = ["memory"]
[template.worktree]
name = "feat/{template_name}"
create_branch = true
[[windows]]
name = "tests"
[[windows.panes]]
split = "root"
title = "runner"
command = "pytest -q"
Guidelines:
- Give windows semantic names, not generic ones.
- Keep the first pane as the agent pane unless there is a strong reason not to.
- Use the same template names for recurring work patterns.
Use session topology, not session sprawl¶
Three patterns work especially well.
Pattern summary
- Author + reviewer + supervisor — one writes, one critiques, robo keeps approvals short.
- Planner + implementer + closer — use when sequencing is the bottleneck, not raw throughput.
- Overnight batch — throughput while away, but with explicit escalation and a reviewer lane.
Author, reviewer, supervisor¶
shoal new -t codex -w feat/auth-api -b --template codex-dev
shoal new -t claude -w review/auth-api -b --template claude-dev
shoal robo setup default --tool pi
shoal robo watch default --daemon
Use this when you want one agent writing, one critiquing, and one reducing approval latency.
Read it left to right: the human keeps intent, the author pushes code forward, the reviewer applies pressure, and robo keeps approval delays from stalling the lane.
flowchart LR
Operator["Operator"] --> Author["Author session<br/>feat/auth-api"]
Operator --> Reviewer["Reviewer session<br/>review/auth-api"]
Operator --> Robo["Robo supervisor"]
Author -->|code + journal updates| Reviewer
Reviewer -->|findings + risk notes| Author
Robo -->|approvals / escalation| Author
Robo -->|approvals / escalation| Reviewer
Planner, implementer, closer¶
shoal new -t omp -w plan/release-cut -b
shoal new -t omp -w feat/release-automation -b --template omp-dev
shoal new -t claude -w docs/release-notes -b
Use this when the bottleneck is orchestration, not raw coding.
Overnight batch¶
shoal new -t codex -w feat/cache-pass -b --template codex-dev
shoal new -t claude -w feat/test-pass -b --template claude-dev
shoal robo watch overnight-batch --daemon
Use this when you want work to continue while you are away, but you still need an explicit escalation path.
Turn journals into shared working memory¶
Journals are not just logs. They are the narrative layer that keeps sessions legible.
Use them for:
- intent at session start,
- decision records before risky changes,
- handoffs between author and reviewer sessions,
- escalation context for robo and remote control.
shoal journal feat/auth-api --append "Goal: split auth service and keep endpoint surface stable."
shoal journal review/auth-api --append "Review focus: regressions in error handling and config loading."
Journal structure that works
Four lines cover most cases:
Free-form notes below that are fine. Opaque notes are not.Configure robo as a pressure valve¶
Robo is most effective when it is narrowing the gap between waiting state and forward motion.
[robo]
name = "default"
tool = "pi"
auto_approve = false
[monitoring]
poll_interval = 10
waiting_timeout = 240
[escalation]
notify = true
auto_respond = false
escalation_session = "__meta"
escalation_timeout = 300
Good robo behavior:
- auto-approve only genuinely safe prompts,
- escalate ambiguity quickly,
- log decisions,
- avoid becoming a silent source of hidden automation.
The robo should shorten waiting time, not make the system feel more mysterious.
Make waiting states cheap to resolve¶
The fastest way to destroy flow is to let approvals pile up.
Use this loop:
- Keep
shoal popupnearby. - Treat
waitingas a first-class queue, not an annoyance. - Use
shoal journal <name>orcapture_paneimmediately. - Approve or redirect fast.
The point is not endless autonomy. The point is low-latency intervention.
Build an explicit review lane¶
The highest-leverage teams usually separate implementation from review even when both are agent driven.
Example:
shoal new -t codex -w feat/payment-retry -b --template codex-dev
shoal new -t claude -w review/payment-retry -b --template claude-review
shoal journal feat/payment-retry --append "Primary goal: stabilize retry semantics without widening API surface."
shoal journal review/payment-retry --append "Review for regression risk in idempotency and migration paths."
This creates:
- a clear author lane,
- a clear critic lane,
- a durable handoff boundary,
- faster merge confidence.
Separate human intent from agent throughput¶
| Human owns | Agent owns |
|---|---|
| Task selection | Draft implementation |
| Merge decisions | Repetitive edits |
| Destructive operations | Tests and diagnostics |
| Branch closure | First-pass reviews |
| Escalation resolution | Search and summarization |
Shoal works best when those boundaries are explicit.
Keep names and branches readable¶
Use names that encode role and intent:
feat/auth-apireview/auth-apidocs/auth-guideplan/release-cut
Readable names make shoal ls, journals, task logs, and robo decisions easier to parse at speed.
Remote fleets need the same discipline¶
When you add remote hosts, do not change the workflow shape. Reuse the same naming, templates, and review patterns.
shoal remote connect devbox
shoal remote sessions devbox
shoal remote send devbox feat/auth-api "run the focused test subset"
Consistency matters more than novelty when you are operating across machines.
Read it left to right: keep one operator surface locally, tunnel control to the remote host, and let the remote Shoal instance manage the actual session runtime.
flowchart LR
Operator["Operator laptop"] --> Local["Local Shoal CLI / popup"]
Local --> Tunnel["SSH tunnel"]
Local --> Orch["shoal-orchestrator tools"]
Tunnel --> RemoteShoal["Remote Shoal control plane"]
RemoteShoal --> Sessions["Remote tmux sessions + worktrees"]
Orch --> RemoteShoal
Sessions -->|status / journals / output| RemoteShoal
Advanced configurations that actually help¶
These are worth adopting once the basics are stable.
1. Use templates for role clarity¶
Create separate templates for authoring, review, planning, and overnight batch work. The point is not more templates. The point is fewer ambiguous sessions.
2. Keep a standing meta session¶
Reserve one session for orchestration, release prep, or escalation handling. This prevents your active implementation lanes from becoming cluttered with control-plane work.
3. Standardize journals¶
Use the same structure in journal entries:
- goal,
- constraints,
- current blocker,
- next expected human decision.
That makes interruption recovery dramatically faster.
4. Tune supervision latency¶
If you work in short bursts, decrease robo polling and keep the popup bound close at hand. If you prefer deep uninterrupted blocks, raise the polling interval and rely on a reviewer lane to catch drift before you intervene.
5. Favor a few stable workflows¶
If a pattern happens more than twice, template it. If it happens once, do not immortalize it in configuration. Flow state comes from repeatability, not maximal optionality.
Developer enjoyment is an operational concern¶
Flow state is not fluff. It is a throughput multiplier.
Shoal should feel like:
- fewer tiny decisions,
- fewer invisible states,
- fewer terminals to babysit,
- faster recovery when an agent blocks,
- better continuity when you return to work later.
The feeling to aim for
Fewer tiny decisions. Fewer invisible states. Fewer terminals to babysit. Faster recovery when an agent blocks. Better continuity when you return. If a workflow makes the tool feel heavier or more ceremonial, simplify it.
If a workflow makes the tool feel heavier, slower, or more ceremonial, simplify it. Shoal is at its best when it disappears into the terminal and leaves only clear intent, quick feedback, and a sense of momentum.
For a reviewer-lane contract you can reuse across tasks, see Review Checklist.