Loading...
Loading...
Multi-agent coordination, inter-terminal messaging bus, distributed file/mutex locking with monotonic fencing tokens, orchestrating multi-stage DAG task pipelines, cluster health watchdog sweeping, and worker queues over Redis. Use when coordinating work between multiple AI assistants or terminal sessions, acquiring distributed mutex locks before editing shared files or running migrations/deployments, generating monotonic fencing tokens to prevent zombie writes, dispatching tasks or RPC queries to peer agents, producing/consuming from competing-consumer work queues, orchestrating multi-stage pipelines with automatic dependency resolution, reliably claiming tasks with leases and ack/DLQ handling, scattering tasks to a pool for quorum aggregation, sharing scratchpad memory, managing floor control in roundtable brainstorming, setting and checking run cancellation tokens, running blind consensus ballots without anchoring bias, electing resilient mesh leaders with automated lease failover, auditing cluster health and sweeping dead agent/listener garbage, or discovering active teammates and their status. Triggers: 'rhizo', 'coordinate with the other terminal/agent', 'talk to agent', 'send task to', 'ask the other assistant', 'inter-agent chat', 'lock file', 'lock resource', 'mutex lock', 'prevent concurrent edits', 'fencing token', 'monotonic counter', 'zombie writes', 'work queue', 'enqueue task', 'claim task', 'ack task', 'reliable queue', 'dead letter queue', 'dlq', 'blackboard', 'scratchpad', 'shared memory', 'floor control', 'speaker ring', 'moderated roundtable', 'pass floor', 'yield floor', 'cancel task', 'cancel run', 'cancellation token', 'abort run', 'ballot', 'vote', 'consensus', 'blind voting', 'leader election', 'acquire leader', 'failover', 'mesh leader', 'scatter', 'gather', 'quorum', 'workflow', 'dag', 'pipeline', 'task dependencies', 'resolve step', 'workflow next', 'sweep', 'clean dead agents', 'stale locks', 'garbage collection', 'cluster watchdog', 'who is online', 'agent status', 'rhizo', 'Redis bus'.
npx skill4agent add axiomantic/rhizo rhizo(Formerly Rhizo / Rhizo)
EVALSHArhizocommand -v rhizonpm install -g @axiomantic/rhizonpm install -g @axiomantic/rhizo @axiomantic/vine @axiomantic/gardenrhizo$PATHrhizo$RHIZO_REDIS_PREFIXrhizo:$RHIZO_PROJECTproject,tag*@all${RHIZO_REDIS_PREFIX}inbox:<my_name>~/.config/rhizo/secretrhizo listenRHIZO_ENCRYPT=1rhizo openrhizo closerhizo listenrhizo listen <agent>IsDaemon=truerhizo listen <agent>rhizo listenrhizo check-inboxrhizo listenwhile trueforlistener:<agent>--listenstderr--soon--immediate--soon--immediate--reply-to <previous_id> --immediateclient.session.abortpi.abort()export RHIZO_AGENT_NAME=<name>export RHIZO_SESSION_ID=<runtime>:<sessionId><runtime>:<sessionId>opencode:<sessionID>claude:<sessionID>~/.config/rhizo/sessions.json${RHIZO_REDIS_PREFIX}sessionsrhizo listenRHIZO_AGENT_NAMERHIZO_SESSION_IDrhizo listen <name>rhizo whorhizo listenpkill rhizorhizops -p <pid> -o commandrhizo lockrhizo unlockrhizo lock <lock_name> [ttl_sec]rhizo unlock <lock_name>RHIZO_REDIS_URLRHIZO_VALKEY_URLVALKEY_URLREDIS_URLAGENTS.md.rhizo.toml.envredis://127.0.0.1:6379valkey://127.0.0.1:6379| Action | Command |
|---|---|
| Register & Announce | |
| Arm Background Listener | |
| Send Direct Task (O2O) | `rhizo send --to <recipient> --subject "<subj>" --body "<body>" [--immediate |
| Send Reply | `rhizo reply --to <sender> --subject "Re: <subj>" --body "<body>" [--reply-to <msg_id>] [--immediate |
| Broadcast (O2M) | `rhizo broadcast --tags "<tags>" --subject "<subj>" --body "<body>" [--immediate |
| Synchronous RPC | `rhizo request --to <recipient> --subject "<subj>" --body "<body>" [--immediate |
| Scatter-Gather Quorum | `rhizo scatter --targets <@tag|agent1,agent2|*> --subject "<subj>" --body "<body>" [--immediate |
| Produce to Work Queue | |
| Consume from Work Queue | |
| Reliable Task Claim | |
| Claim Lease Renewal | |
| Acknowledge Task | |
| Shared Blackboard / Scratchpad | |
| Floor Control (Speaker Ring) | |
| Run Cancellation Token | `rhizo cancel <run_id> [--reason <reason>] |
| Blind Voting & Ballot | |
| Leader Election (Lease) | |
| DAG Workflow Engine | |
| Cluster Health Watchdog | |
| Set Status & Activity | |
| Distributed Mutex Lock | |
| Distributed Mutex Unlock | |
| Ephemeral Pub/Sub Send | |
| Ephemeral Pub/Sub Recv | |
| Discover Peers | |
| Dynamic Tags | |
| Global Session Map | |
| Check Inbox Count | |
| Drain Backlog | |
| Desktop Notification Listener | |
| Unregister / Close | |
| Config & Provenance | |
| Cluster Secret | |
# Recommended: Register and arm background ear in a single step
rhizo open my-agent-1 "backend,qa" --listen
# Or register with a session ID:
rhizo open my-agent-1 "backend,qa" --session-id "opencode:ses_123"
# Or register without immediately listening:
rhizo open my-agent-1 "backend,qa"Tip for Multi-Agent Host Isolation: When running multiple agents across terminal tabs or IDE sessions on the same computer, isolate via process environment () or session ID mapping (export RHIZO_AGENT_NAME="my-agent-1"). Multiple agents in the same working directory will never collide.export RHIZO_SESSION_ID="opencode:<sessionId>"
[!IMPORTANT] The Core Invariant: Never Leave an Agent in a "Deaf" State Rhizo is an asynchronous distributed message bus over Redis. An agent can ONLY receive messages if it has an active listener running or has a continuation hook installed. If an agent completes a task and concludes its turn without an active listener, it becomes "deaf"—subsequent messages from peer agents will sit in Redis unread until human intervention occurs. Every command sequence below is designed to ensure continuous, uninterrupted inbox coverage.
flowchart TD
Start([Session Bootstrap]) --> Recipe1["Recipe 1: Default Startup<br/><code>rhizo open <my-name> '<tags>' --listen</code>"]
Recipe1 --> InTurn["Execute Task / Tool Calls<br/>(Normal Turn Processing)"]
InTurn --> Check{"Do you need to reply or wait for next task?"}
Check -->|Reply with Result & Await Next Task| Recipe2["Recipe 2: Atomic Reply & Re-Arm<br/><code>rhizo reply --to <sender> --reply-to '<id>' ... --listen</code>"]
Check -->|No Reply Needed, Just Wait| Recipe2b["Recipe 2b: Indefinite Wait (Zero Timeout)<br/><code>rhizo listen <my-name></code>"]
Check -->|Work Completely Finished| RecipeClose["Recipe 5: Clean Disconnect<br/><code>rhizo close <my-name></code>"]
Check -->|Using Autonomous Continuation Hooks| Recipe4["Recipe 4: Stop Hook Continuation<br/>Turn ends naturally; hook detects incoming message & continues"]
Check -->|Subagent Completed One-Shot Listen| Recipe3["Recipe 3: Relaunch Subagent Ear<br/>Spawn fresh subagent with <code>rhizo listen <my-name></code>"]
Recipe2 --> InTurn
Recipe2b --> InTurn
Recipe3 --> InTurn
Recipe4 --> InTurn
RecipeClose --> Done([Session Closed Cleanly])rhizo open <my-name> "<tags>" --listen--listen--listen-l--listenrhizo open <my-name> "<tags>"pi.devrhizo open <my-name> "<tags>"--listenopencode-ear.jspi-ear.tsrun_command(CommandLine="rhizo open <my-name> \"<tags>\"", WaitMsBeforeAsync=5000)run_command(CommandLine="rhizo listen <my-name>", WaitMsBeforeAsync=500, IsDaemon=true)rhizo openrhizo openopenrhizo openrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>" --listen--reply-to "<id>"rhizo request--listen-l0rhizo listen <my-name>timeout = 0BLPOPrhizo listen <my-name>rhizo reply --reply-to "<id>" ...rhizo listen <my-name>claude_stop_hook.pycodex_stop_hook.pyagy_stop_hook.pywhile true&rhizo check-inbox{"decision": "block", ...}rhizo close <my-name>rhizo closerhizo whorhizo listenstderr[rhizo LIFECYCLE NOTICE] Listener for 'worker-1' delivered message 'msg_...' and EXITED.
- Detected harness: <harness> (consult SKILL.md Step 2 for your harness playbook)
- Expected follow-up action:
1. When finished, reply and re-arm atomically in one command:
rhizo reply --to <sender> --reply-to "<id>" --subject "Re: <subj>" --body "<results>" --listen
2. If no reply is needed, wait for next task (zero-timeout infinite wait):
rhizo listen worker-1
3. If this ran inside a subagent: dispatch a fresh one-shot listener subagent before concluding your turn.
4. If disconnecting or finishing session work completely:
rhizo close worker-1
(To silence this notice: pass --quiet / -q, or set RHIZO_QUIET=1)rhizo listen | jq .opencode:pi:codex:agy:claude:cursor:OPENCODE_SESSION_IDPI_SESSION_IDCODEX_SESSION_IDANTIGRAVITY_APP_DIRCLAUDE_CODECURSOR_APPrhizo listenrun_command--listen--listen--quiet-qRHIZO_QUIET=1flowchart TD
Start([Evaluate Available Tools]) --> CheckPlugin{"Has In-Process Extension Plugin?<br/>(e.g., OpenCode opencode-ear.js / Pi)"}
CheckPlugin -->|Yes| Branch1["Branch 1: In-Process Extension (Tier 1)<br/>• 0 LLM token overhead<br/>• DO NOT execute rhizo listen with any tool<br/>• Plugin streams ear & injects turns automatically"]
CheckPlugin -->|No| CheckDaemon{"Has Shell Command tool<br/>with native daemon parameter?<br/>(e.g., run_command(IsDaemon=true))"}
CheckDaemon -->|Yes| Branch2["Branch 2: Native Daemon Shell Task (Tier 2)<br/>• 0 subagent token overhead<br/>• Run rhizo listen in main chat with IsDaemon=true<br/>• Harness reactively resumes turn on stdout"]
CheckDaemon -->|No| CheckSubagent{"Has Subagent / Task tool<br/>with background parameter?<br/>(e.g., Task(background=true))"}
CheckSubagent -->|Yes| Branch3["Branch 3: Background Subagent Ear (Tier 3)<br/>• Dispatch subagent with background parameter<br/>• <b>INSIDE subagent: command is BLOCKING (No double-daemons!)</b><br/>• One-and-done: exits on message to notify parent"]
CheckSubagent -->|No| Branch4["Branch 4: Synchronous Shell Only (Tier 4)<br/>• <b>DO NOT run rhizo listen</b> (freezes active turn!)<br/>• Inform user of harness limitation<br/>• Check inbox explicitly via rhizo check-inbox"]run_command(IsDaemon=true)opencode-ear.jswhile true; do rhizo listen; donerhizo listenopencode-ear.jspi-ear.tsopencode-ear.jspi-ear.tsrhizo listenrun_command(..., IsDaemon=true, WaitMsBeforeAsync=500)Task(..., background=true)spawn_agent&rhizo listen <agent>rhizo listenrhizorhizo check-inboxopencodeOPENCODE_SESSION_IDbashexecrhizo listenbashexecTaskrhizo listen &nohup rhizo listen &opencode-ear.jspromptAsyncrhizo listenopencode-ear.js~/.config/opencode/opencode.json{
"plugin": [
"~/.gemini/config/skills/rhizo/opencode-ear.js"
]
}bashrhizo open <my-name> "<tags>"opencode:<sessionId><my-name>~/.config/rhizo/sessions.jsonRHIZO_SESSION_ID--soonbashrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel task" --body "Retract build #104 immediately" --immediaterhizo send --to <recipient> --subject "URGENT CONTEXT: Re: <prev_subj>" --body "STOP: Table users is locked in prod; use CONCURRENTLY" --reply-to "<prev_msg_id>" --immediateopencode-ear.jsclient.session.abortbashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"--immediate--listenopencode-ear.jsclient.session.promptAsyncclient.session.abort--immediate[rhizo:<name>] {"id":"msg_...","from":"...","to":"...","type":"...","subject":"...","body":"..."}rhizo replybashbashspawn_agentrhizo listen &bash> /dev/null 2>&1 &> file.log &&nohupdisownBRPOPrhizo listen <my-name> 30120while true; do rhizo listen; donebashrhizo open <my-name> "<tags>"--soonbashrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel run" --body "Upstream retracted. Stop compiling immediately." --immediaterhizo send --to <recipient> --subject "URGENT CONTEXT: Re: <prev_subj>" --body "STOP: Credentials expired, switch to staging auth" --reply-to "<prev_msg_id>" --immediatebashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"--immediatebash&rhizo listen <my-name>rhizo listen0bashrhizo reply --to <peer> --subject "Re: Task" --body "Done" --listenspawn_agent"Run 'rhizo listen <my-name>' once in bash. Do NOT use loops or while-true. When rhizo listen prints the message JSON and exits 0, output that exact JSON and terminate immediately."
rhizo listenbashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"rhizo listen <my-name>rhizo close <my-name>Stop~/.codex/hooks.json{
"hooks": {
"Stop": [{ "hooks": [{ "type": "command", "command": "python3 <skill-dir>/hooks/codex_stop_hook.py" }] }],
"SessionStart": [{ "hooks": [{ "type": "command", "command": "python3 <skill-dir>/hooks/session_lifecycle_hook.py start" }] }],
"SessionEnd": [{ "hooks": [{ "type": "command", "command": "python3 <skill-dir>/hooks/session_lifecycle_hook.py end" }] }]
}
}{"decision": "block", "reason": "..."}rhizo listen --notifyBashrhizo listen <my-name> --notifyclaudeBash(command="...")Task(prompt="...", background=true)rhizo listen &Bash&nohupdisown> /dev/null 2>&1 &> /tmp/listen.log &/dev/nullrhizo listen <my-name> 30BLPOPBashrhizo open <my-name> "<tags>"--soonBashrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel build" --body "Retract build #104 immediately" --immediaterhizo send --to <recipient> --subject "URGENT CONTEXT: Re: <prev_subj>" --body "STOP: Credentials expired, switch to staging auth" --reply-to "<prev_msg_id>" --immediateBashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"--immediateTask(background=true)Taskbackground=true"Run 'rhizo listen <my-name>' in bash with NO timeout. Do NOT run with '&' and do NOT redirect stdout/stderr. When rhizo listen prints the message JSON and exits 0, return that exact JSON."
Stop.claude/settings.json~/.claude/settings.json{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 <skill-dir>/hooks/claude_stop_hook.py"
}
]
}
],
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 <skill-dir>/hooks/session_lifecycle_hook.py start"
}
]
}
],
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 <skill-dir>/hooks/session_lifecycle_hook.py end"
}
]
}
]
}
}{"decision": "block", ...}additionalContext--listen--listenBashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>" --listenrhizo listen --notifyBashrhizo listen <my-name> --notifyrun_commandmanage_taskinvoke_subagentrun_commandmanage_taskinvoke_subagentsend_message&> /dev/null 2>&1 &run_command&rhizo listen <my-agent> 300manage_task(Action="status")run_commandrun_command(CommandLine="rhizo open <my-agent> \"<tags>\"", WaitMsBeforeAsync=5000)run_commandrun_command(CommandLine="rhizo listen <my-agent>", WaitMsBeforeAsync=500, IsDaemon=true)manage_task(Action="status")rhizo listenrhizo listen--listenrun_command(CommandLine="rhizo listen <my-agent>", WaitMsBeforeAsync=500, IsDaemon=true)--soonrun_commandrun_command(CommandLine="rhizo send --to <recipient> --subject \"<subj>\" --body \"<body>\" --soon", WaitMsBeforeAsync=5000)--immediaterun_command(CommandLine="rhizo send --to <recipient> --subject \"ABORT: Cancel build\" --body \"Retract build #104 immediately\" --immediate", WaitMsBeforeAsync=5000)run_command(CommandLine="rhizo send --to <recipient> --subject \"URGENT CONTEXT: Re: <prev_subj>\" --body \"STOP: Credentials expired, switch to staging auth\" --reply-to \"<prev_msg_id>\" --immediate", WaitMsBeforeAsync=5000)run_commandrun_command(CommandLine="rhizo reply --to <sender> --subject \"Re: <subj>\" --body \"<result>\" --reply-to \"<id>\"", WaitMsBeforeAsync=5000)--immediaterun_commandrun_command(CommandLine="rhizo reply --to <sender> --subject \"Re: <subj>\" --body \"<result>\" --reply-to \"<id>\" --listen", WaitMsBeforeAsync=500)Stop~/.gemini/config/hooks.json.agents/hooks.json{
"rhizo": {
"Stop": [
{
"type": "command",
"command": "python3 <skill-dir>/hooks/agy_stop_hook.py"
}
]
}
}pipi.dev@earendil-works/pi-coding-agentbashshrhizopi-ear.ts~/.pi/agent/extensions/*.tsjitipi-ear.tspi:<sessionId>RHIZO_AGENT_NAMErhizo listen <agent> 0pi-ear.ts--immediatepi-ear.tsbashrhizorhizo open <my-name> "<tags>"pi:<sessionId><my-name>~/.config/rhizo/sessions.jsonRHIZO_SESSION_ID--soonbashrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel build" --body "Retract build #104 immediately" --immediaterhizo send --to <recipient> --subject "URGENT CONTEXT: Re: <prev_subj>" --body "STOP: Credentials expired, switch to staging auth" --reply-to "<prev_msg_id>" --immediatebashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"check-inboxpi-ear.ts[rhizo BUS message for @<my-name> from @<sender> [host: <origin>] (subject: "<subj>")]:
<payload>rhizo replycursorterminalrun_terminal_cmd.cursor/rules/rhizo.mdc.cursorrulesrhizo listen &terminalrhizo check-inboxterminalrhizo open <my-name> "<tags>"--soonterminalrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel build" --body "Retract build #104 immediately" --immediaterhizo send --to <recipient> --subject "URGENT CONTEXT: Re: <prev_subj>" --body "STOP: Table users is locked; abort migration" --reply-to "<prev_msg_id>" --immediateterminalrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"rhizo listen <my-name>rhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>" --listenrhizo listen <my-name> --notifycopilotgh copilotbash.github/copilot-instructions.mdbashrhizo open <my-name> "<tags>"--soonbashrhizo send --to <recipient> --subject "<subj>" --body "<body>" --soon--immediaterhizo send --to <recipient> --subject "ABORT: Cancel run" --body "Stop compiling immediately" --immediatebashrhizo reply --to <sender> --subject "Re: <subj>" --body "<result>" --reply-to "<id>"bashrhizo listen <my-name>rhizo reply --to <sender> ... --reply-to "<id>" --listenrhizo listen --notifyrhizo listen <my-name> --notifynotify-send0rhizo requestrhizo request --to <peer> --subject "<query>" --body "<input>" [--timeout 30] [--raw]reply:<req_id>BRPOP--rawrhizo enqueuerhizo workrhizo enqueue <queue_name> --subject "<title>" --body "<payload>"rhizo work <queue_name>rhizo lockrhizo unlock# Acquire lease before editing a shared file (returns 0 on success, 1 on conflict):
rhizo lock file:schema.prisma 60
# Acquire lock with monotonic fencing token to prevent zombie writes:
rhizo lock deploy:staging 120 --fencing
# Or output bare token for piping:
token=$(rhizo lock deploy:staging 120 --fencing --raw)
# Perform safe edits or migration...
# Release lease immediately after completing the work (guarantees only owner can unlock):
rhizo unlock file:schema.prismarhizo statusrhizo status busy "Running full regression suite"
# When ready for new work:
rhizo status idle "Awaiting next task"rhizo who "*"rhizo pubrhizo sub# Subscriber:
rhizo sub alerts 10
# Publisher:
rhizo pub alerts "Build completed"rhizo scatterrhizo scatter --targets @reviewers --subject "Review PR #42" --body "Diff ready" --quorum 2 --timeout 15rhizo claimrhizo acktask=$(rhizo claim batch_pipeline --lease 60)
# Process task...
rhizo ack batch_pipeline <task_id>rhizo blackboardrhizo blackboard set design_room arch_spec '{"runtime": "nim"}'
rhizo blackboard append design_room notes "Checked DB migrations"
snapshot=$(rhizo blackboard snapshot design_room)rhizo floor# Request speaker lease (blocks if occupied):
rhizo floor request design_room 30
# Yield when finished:
rhizo floor yield design_room
# Or pass directly:
rhizo floor pass design_room specialist_agentrhizo cancel# Cancel an entire workflow run:
rhizo cancel run_42 --reason "Operator requested abort"
# In worker loops before expensive LLM calls or tool actions:
if rhizo cancel check run_42 --exit-code; then
echo "Run was cancelled! Aborting cleanly..."
exit 0
firhizo ballot# 1. Open ballot with options:
rhizo ballot open db_choice --options "postgres,sqlite,redis" --voters "arch,db_spec,sec_spec"
# 2. Voters cast blind votes (hidden until tally):
rhizo ballot cast db_choice --vote "sqlite"
# 3. Tally votes and reveal winner:
rhizo ballot tally db_choice --closerhizo leader# Attempt to acquire leader role (with 30s lease):
rhizo leader acquire orchestrator 30
# Leader periodically renews lease in background:
rhizo leader renew orchestrator 30
# Leader gracefully resigns when work is complete:
rhizo leader resign orchestratorrhizo workflow# 1. Define DAG pipeline:
rhizo workflow define release_flow --steps "lint,test,build,deploy" --deps "test:lint;build:lint;deploy:test,build"
# 2. Query ready unblocked steps:
ready=$(rhizo workflow next release_flow --raw)
# 3. Complete a step and automatically unlock downstream stages:
rhizo workflow resolve release_flow lint --output "passed"rhizo sweep# Dry run (audits without modifying Redis):
rhizo sweep --dry-run
# Run full health sweep:
rhizo sweep
# Output human-readable summary:
rhizo sweep --rawrhizo close# 1. Acquire 60s lease on target file (returns 0 on success, 1 on conflict):
rhizo lock file:src/router.ts 60
# 2. Inspect, modify, test, or format the file safely...
# 3. Release lease immediately upon completion:
rhizo unlock file:src/router.ts# Producer (Orchestrator): Push tasks onto shared queue
rhizo enqueue test_suite --subject "Run Unit Tests" --body "tests/auth_test.go"
rhizo enqueue test_suite --subject "Run Integration Tests" --body "tests/api_test.go"
# Workers (Run concurrently across terminal tabs or subagents):
# Blocks silently until a task is available; guarantees exactly-once delivery:
task=$(rhizo work test_suite)# Caller: Dispatches task and blocks up to 30s; --raw outputs clean response body for piping
res=$(rhizo request --to db-expert --subject "Query Plan" --body "SELECT * FROM users" --timeout 30 --raw)
# Specialist (Responder): Answers directly with rhizo reply
rhizo reply --to orchestrator --subject "Re: Query Plan" --body "Add composite index on (created_at, user_id)" --reply-to <req_id> --listen# 1. Discover who is online across the project or cluster:
rhizo who -a --json
# 2. Broadcast what you are actively working on:
rhizo status busy "Refactoring auth middleware"
# 3. Signal completion when ready for new tasks:
rhizo status idle "Awaiting next task"# Subscriber: Wait up to 60s for event stream
rhizo sub build_events 60
# Publisher: Broadcast event to all currently attached subscribers
rhizo pub build_events '{"commit": "348d001", "status": "passed"}'rhizo listenopencode-ear.jspromptAsync&rhizo listen <name>rhizo listen <name>rhizo reply ... --listen.claude/settings.jsonStoprun_command(CommandLine="rhizo listen <agent>", WaitMsBeforeAsync=500)Stop# Fan out to all agents with tag 'reviewers', waiting for at least 2 approvals:
replies=$(rhizo scatter --targets @reviewers --subject "Review PR #42" --body "Please review diff in staging" --quorum 2 --timeout 15)
# Or fan out to explicit agents and pipe bare response bodies:
rhizo scatter --targets "analyzer1,analyzer2" --subject "Benchmark" --body "run" --raw# 1. Non-destructively claim task with a 60s lease (supports --run-id for cancellation awareness):
task=$(rhizo claim batch_pipeline --lease 60 --run-id run_101)
# 2. Extract task ID and payload:
task_id=$(echo "$task" | jq -r '.id')
payload=$(echo "$task" | jq -r '.body')
# 3. For long-running execution (>60s), periodically renew lease to prevent task theft:
rhizo claim renew batch_pipeline "$task_id" --lease 60
# 4. Confirm completion and clear lease:
rhizo ack batch_pipeline "$task_id"
# Note: If the worker crashes mid-task, the lease expires after 60s and is automatically returned to the queue (or moved to dlq:batch_pipeline after 3 failed attempts).# 1. Set shared architecture specification in room 'brainstorm':
rhizo blackboard set brainstorm arch_spec '{"runtime": "nim", "crypto": "openssl_evp"}'
# 2. Inspect current Optimistic Concurrency Control (OCC) revision:
rev=$(rhizo blackboard rev brainstorm arch_spec)
# => "1"
# 3. Append ideas or action items to a shared list:
rhizo blackboard append brainstorm ideas "Idea 1: Add monotonic fencing tokens to mutex locks"
rhizo blackboard append brainstorm ideas "Idea 2: DAG-based workflow pipeline engine"
# 4. Dump entire room scratchpad as clean structured JSON:
snapshot=$(rhizo blackboard snapshot brainstorm)# 1. Request the floor (with a 30s speaker lease). Blocks if someone else is speaking until granted or timeout:
rhizo floor request design_review 30
# 2. Speak / write findings to the blackboard or broadcast to the room:
rhizo blackboard append design_review notes "Speaker proposal: Split monolithic config into modular schemas"
# 3. Yield the floor to the next waiting speaker, or explicitly pass to a designated agent:
rhizo floor yield design_review
# Or: rhizo floor pass design_review architect_bob# Lead / Orchestrator: Publish cancellation token for active run
rhizo cancel run_101 --reason "Requirements updated: pivoting to Redis streams"
# Workers: Pass --run-id directly to work/claim loops (exits 0 immediately if cancelled):
rhizo work batch_pipeline 30 --run-id run_101
# Or manual pre-check before expensive inferences:
if rhizo cancel check run_101 --exit-code; then
echo "Run cancelled: $(rhizo cancel check run_101 --raw). Halting execution."
exit 0
fi
# Reset token when starting a clean re-run:
rhizo cancel clear run_101# 1. Lead opens ballot:
rhizo ballot open arch_debate --options "monolith,microservices,modular_monolith" --voters "claude,gpt,gemini"
# 2. Each assistant independently casts their ballot (votes remain sealed):
rhizo ballot cast arch_debate --vote "modular_monolith" --voter "claude"
rhizo ballot cast arch_debate --vote "modular_monolith" --voter "gpt"
rhizo ballot cast arch_debate --vote "monolith" --voter "gemini"
# 3. Lead tallies the votes and locks the ballot:
tally=$(rhizo ballot tally arch_debate --close)
winner=$(echo "$tally" | jq -r '.winner')
echo "Consensus winner: $winner"# 1. Primary candidate acquires leadership lease (30s TTL):
rhizo leader acquire cluster_lead 30
# 2. While primary is healthy, periodically renew lease:
rhizo leader renew cluster_lead 30
# 3. Standby candidates monitor leadership:
leader_status=$(rhizo leader status cluster_lead)
# If primary crashes or drops lease, standby's acquire call automatically succeeds:
rhizo leader acquire cluster_lead 30
# 4. Graceful handoff: primary resigns, instantly waking standbys:
rhizo leader resign cluster_lead# 1. Define pipeline graph: lint -> test, build; test & build -> deploy:
rhizo workflow define release_pipeline \
--steps "lint,test,build,deploy" \
--deps "test:lint;build:lint;deploy:test,build"
# 2. Query ready steps (returns bare step names with --raw):
ready_steps=$(rhizo workflow next release_pipeline --raw)
# => "lint"
# 3. Worker executes 'lint', then resolves it:
rhizo workflow resolve release_pipeline lint --output "lint clean"
# Automatically unlocks dependent stages 'test' and 'build'
# 4. Check ready steps again:
ready_steps=$(rhizo workflow next release_pipeline --raw)
# => "test"
# "build"
# 5. Workers run 'test' and 'build' concurrently and resolve them:
rhizo workflow resolve release_pipeline test --output "all tests green"
rhizo workflow resolve release_pipeline build --output "artifacts packaged"
# 'deploy' is now unlocked because both dependencies ('test' and 'build') are resolved!
# 6. Worker runs deploy and resolves it:
rhizo workflow resolve release_pipeline deploy --output "deployed to prod"
# Workflow status transitions to 'completed'# 1. Periodically run health sweep or invoke during mesh initialization:
sweep_res=$(rhizo sweep)
# 2. Inspect swept resources:
echo "$sweep_res" | jq .
# => {
# "pruned_agents": ["dead_worker_123"],
# "pruned_listeners": ["stale_listener_456"],
# "dry_run": false
# }
# 3. Fast CLI status check (prints single line summary):
rhizo sweep --raw
# => "Pruned 0 dead agents, 0 stale listeners."# 1. Acquire lock with monotonic fencing token counter:
lock_out=$(rhizo lock db_migration 60 --fencing)
# => "LOCKED db_migration by lead_agent (fencing: 42)"
# Or obtain bare token directly for shell piping:
fence_token=$(rhizo lock db_migration 60 --fencing --raw)
# => "42"
# 2. Pass fencing token to database or storage update:
# e.g., UPDATE records SET data = '...', last_fence = 42 WHERE last_fence < 42;
# 3. Release lock when complete:
rhizo unlock db_migration--immediate# 1. Cancelling an In-Flight Task / Build:
rhizo send --to builder-1 \
--subject "ABORT: Cancel build #104" \
--body "Upstream PR was retracted. Halt compilation immediately." \
--immediate
# 2. Injecting Vital Context to a Message / Operation Already In Flight:
# Use --reply-to with the target's in-flight task ID to attach vital corrections:
rhizo send --to db-worker \
--subject "URGENT CONTEXT: Re: Schema Migration" \
--body "STOP: Table 'users' has active locks in prod. Do not run ALTER TABLE without CONCURRENTLY" \
--reply-to "msg_1758694000_abcd" \
--immediate
# 3. Emergency Security Halt across a Team or Tag Group:
rhizo broadcast --tags "deploy" \
--subject "SECURITY ALERT: Revoke Key" \
--body "Compromised credential detected in commit 4a9f. Halt deployment pipeline now." \
--immediate
# 4. Synchronous Urgent Inquiry (Preempt peer for immediate answer):
res=$(rhizo request --to auth-service \
--subject "Verify Revocation" \
--body "tok_xyz" \
--immediate \
--timeout 10 \
--raw)rhizonimble build -y -d:releaseredis-cli -u "$RHIZO_REDIS_URL" EVAL "$(cat "scripts/<script>.lua")" ...