Openrig user skill

Use when a specific `rig` command, subcommand, or flag is already known and you need its exact syntax, JSON shape, defaults, or error meaning.

by mvschwarz·Apache-2.0 license·★ 4,707 Stars on the repo·GitHub ↗

Use now

Files of Openrig user

mvschwarz/main1 file shown
SKILL.md
Show the full text1413 lines
openrig-user/SKILL.md1413 lines · 67.4 KB
Outline
RawView on GitHub

OpenRig User

This is an as-built guide to the shipped rig CLI. Use current code and rig ... --help as ground truth if anything here ever conflicts with older planning docs.

Use the OpenRig builder guidance when changing OpenRig behavior, doctrine, or release posture.

Coordination trust boundary

Coordinate as openly as the trust boundary you actually control allows. Within a set of machines you own that already trust each other — they can reach each other's daemon URLs and the daemon itself requires no authentication — direct rig send, rig capture, and rig queue should just work. Don't invent bearer placeholders, allowlists, trust handshakes, or guest-reach restrictions the environment doesn't require.

Do not add or defend a restriction without naming the protected asset, the actual adversary, the blocked attack path, and the concrete consequence. Missing capability is not protection — repair the route, registration, runtime posture, or product defect directly. Arbitrary boundaries create constraint-induced circumvention: under goal pressure, agents build shadow transports, alternate credentials, and weaker proof instead of the direct authorized path. Keep only explicitly stated external or irreversible boundaries — public push / PR / publish, and destruction of canonical data.

Coordination primitives — when to use which

Three coordination surfaces, used together for forward-momentum work. Internalize this on first read — it shapes every turn you take in a rig.

rig send <seat> "<text>" — intra-pod direct messaging / nudges

Use when you need to ask a quick question or give a teammate context that does not carry handoff semantics. NOT for durable work. NOT for state that must survive across turns. The message lands in the target's pane; there is no durable queue record. The CLI prints Sent to ... (and Verified: yes/no with --verify); read the receipt and move on.

Example:

rig send dev-reviewer@example-project "The import report is ready; the durable handoff names its evidence." --verify
rig queue create --destination <Y> --tags <...> --body-file <path> — durable work item

Use for any substantive work that must not fall through chat — slice handoffs, guard verdicts, QA results, full-tip reviews, multi-item batches. Survives agent restarts. Tracked in the daemon SQLite schema. Surfaces in Project / queue views

  • in the destination seat's inbox. Tag with mission / slice / gate / checkpoint so future-you (and any peer) can find it.

Body discipline: substantive bodies go through --body-file <path> (or - for stdin) — the purpose-built, corruption-safe surface (it kills the backtick-shell-corruption class for multi-line bodies). Do NOT inline a backtick-heavy or multi-line body via --body: rig queue create body parsing breaks on unescaped backticks and rejects flag-like tokens.

Example:

rig queue create \
  --destination dev-reviewer@example-project \
  --tags "mission:data-import,slice:import-report" \
  --body-file /tmp/import-report-handoff.md
rig queue handoff <qitem-id> --to <next> ... — hot-potato handoff

Use when you have completed your turn on a qitem and the work moves to the next owner. This is forward momentum. The ball passes to the destination seat; chain-of-record (the prior qitem id) is preserved so the verdict trail is intact; tags carry the selected work context forward. Gate tags describe checks actually selected for that work; they do not require a fixed sequence of roles.

Example:

rig queue handoff <qitem-id> \
  --to dev-reviewer@example-project \
  --tags "mission:data-import,slice:import-report" \
  --body-file /tmp/import-report-handoff.md
§1b doctrine — turn ends by passing the ball

A turn ends by passing the ball, never by going idle holding the slice waiting on a confirmation the selected process does not include. Follow the current mission-slice-sop: proportional owner checks are the default; independent review runs when selected, at the authored work boundary. Role names do not add per-commit guard, QA, or orchestration gates. Do the authorized work, run its selected checks, and return the outcome through durable custody.

Valid pauses are only:

  • A genuine blocker — file a blocked-state qitem against the blocking peer or surface explicitly to orch.
  • A scope-or-architecture question that requires owner input and changes the plan — surface to orch with the specific decision needed.

Implementing already-authorized work is neither of these. Proceed without phantom-gating on an imagined "next prompt" or "operator confirmation" that the process does not require.

Anti-patterns
  • Using rig send for durable work → use rig queue create instead. Sends do not survive restarts and do not show up in queue/project views.
  • Idle-holding a slice for an imagined "next prompt" or "operator confirmation" that the process does not require → pass the ball via rig queue handoff and proceed to the next slice or stand by for the inbound verdict. See the §1b doctrine above.
  • Inlining a multi-line / backtick-heavy body into rig queue create --body → use --body-file /tmp/<descriptive-name>.txt (or - for stdin), the corruption-safe surface. The body parser does not tolerate raw backticks or flag-like tokens inline.

Runtime-Gated Coordination Primitives

OpenRig v0.3.1 is published publicly as @openrig/[email protected] and GitHub Release v0.3.1. It includes the bundled PL-004 Coordination Primitive System: Phase A rig stream / rig queue, Phase B rig project / rig view, Phase C rig watchdog, and Phase D rig workflow / workflow-keepalive.

These are shipped product surfaces in v0.3.x, but they require a compatible v0.3.x daemon and matching SQLite schema at runtime — the installed package version is not automatically the version of the daemon serving you. If a coordination command behaves unexpectedly, confirm the running daemon with rig whoami --json and daemon status before assuming a product bug.

Default posture:

  • Treat daemon rig queue, rig stream, rig project, rig view, rig watchdog, and rig workflow as the product coordination surfaces when the active daemon is v0.2.0 or newer.
  • Use daemon-backed rig queue for durable routing. update / show / list complement create / handoff for inspection and state changes; records in an unrelated store are not evidence that this daemon owns the work.
  • If a daemon-backed coordination command fails, debug the command/runtime/schema edge directly; do not assume the right workaround is to drop back to a config-layer primitive.
  • Do not perform daemon stop/start, production DB copy/mutation, release, publish, or other consequence-boundary actions unless the operator/workstream has granted that specific gate.

First-user workspace setup

When booting into a rig on a host where the workspace is unset, gap-ridden, or points at a stale layout, address that before substantive project work. The shipped surface is small + bounded — reach for the canonical commands rather than improvising.

Detect workspace state at boot

Agent-actionable when the daemon is reachable.

rig workspace validate --json
rig workspace validate <path> --kind <user|project|knowledge|lab|delivery> --json

rig workspace validate walks the workspace root and emits a structured frontmatter-gap report against the v0 contract. Exit code is non-zero when gaps exist (operators chain into hygiene fix loops). Default root is the current directory; pass a positional path to validate elsewhere. --kind scopes the contract to a specific workspace kind; omit for a kind-agnostic structural check.

If rig workspace validate reports a non-zero gapCount OR the workspace root is unset / unwritable, the workspace needs instantiation — see the next section.

Instantiate the canonical workspace scaffold

Agent-actionable. The operation is additive and preserves existing files.

rig config init-workspace
rig config init-workspace --root <path>
rig config init-workspace --dry-run --json

rig config init-workspace scaffolds the canonical workspace layout at the configured workspace.root (default ~/.openrig/workspace):

  • missions/ — release missions + slices
  • exhaust/ — project-local coordination exhaust
  • SPEC.md — project intent
  • project.yaml — project catalog selections and mission root
  • workspace.yaml — project registration
  • .gitignore — local OpenRig state and exhaust exclusions

--root <path> targets a non-default root for this call; --dry-run reports what would be created without writing. --force is deprecated compatibility and still preserves existing files.

Redirect the workspace root

Operator-gated when persistent. Agent-actionable when one-shot via env-var.

For a single command:

OPENRIG_WORKSPACE_ROOT=<path> rig <command> ...

For a persistent host-level redirect, the operator changes the config file or runs the setter:

rig config set workspace.root <path>

ConfigStore precedence: OPENRIG_WORKSPACE_ROOT env > config-file workspace.root > built-in default ~/.openrig/workspace. The same precedence governs OPENRIG_WORKSPACE_SPECS_ROOT → workspace.specs_root (default <workspace_root>/specs).

Prefer the env-var form for one-shot redirects (transparent to operators); reserve rig config set for changes the operator owns.

Build a workspace from scratch

Agent-actionable. Same surface as the canonical scaffold above; the workspace.root cascade handles non-existent host paths.

rig config init-workspace --root /path/to/new/workspace

The command additively creates any missing canonical entries and preserves every existing one; only a complete six-entry scaffold is a no-op. Run rig workspace validate /path/to/new/workspace --json after to confirm the contract holds.

Create a workflow inside an existing workspace

Authoring is operator-or-agent; validation + instantiation are agent-actionable.

Workflow spec files live at:

<workspace_root>/specs/workflows/<name>.yaml

<workspace_root> resolves via the ConfigStore precedence named above. There is no rig workflow create verb in v0.3.x — the spec YAML is authored directly. Template by hand from the documented schema, or copy a built-in starter from <openrig install>/dist/builtins/workflow-specs/ and adapt. Once written:

rig workflow validate <workspace_root>/specs/workflows/<name>.yaml --json

rig workflow instantiate <workspace_root>/specs/workflows/<name>.yaml \
  --root-objective "<one-line objective for the run>" \
  --created-by <your-session>@<your-rig> \
  --json

Both --root-objective <text> and --created-by <session> are REQUIRED on instantiate — omitting either yields a Commander required-option error before the daemon is contacted. --entry-owner <session> is an optional override for the entry-step owner; default routing is per the workflow spec.

validate returns a structured ok/error report; instantiate creates a workflow instance + entry-step qitem. Inspect existing surface state with:

rig workflow specs --json              # list registered specs (built-in + operator-authored)
rig workflow list --json               # list active workflow instances
rig workflow show <instanceId> --json  # inspect one instance
rig workflow project <instanceId>      # ADVANCE an instance — projects the next-step packet
rig workflow continue <instanceId>     # read-only inspector of an instance (does NOT advance it)

(Surface note — the current rig workflow command group registers 13 subcommands: validate, instantiate, project, list, specs, show, trace, continue, run, watch, route, resume, status. There is still no create verb — the spec YAML is authored on disk. project is the advancing verb (it projects the next-step packet); continue is a read-only inspector, NOT an advance — do not conflate them. The 13-verb set and the project-vs-continue semantics are verified against current product main d37a08ad (packages/cli/src/commands/workflow.ts, 13 registered .command(...) entries; the earlier "6-verb surface / continue-advances" claim here was stale). Verify individual subcommand flags with rig workflow --help.)

Permission policy — pick one at setup (onboarding)

OpenRig sets only a minimal usability floor on your harness permissions and otherwise stays out of the way — then it ships recommended policies you opt into. It never bakes a permission policy for you. On install / onboarding this is a required choice, presented as a top-level pick:

  • POLICY MODE — pick a built-in policy and have it applied:

    • Locked — deny-by-default whitelist; untrusted rigs/work.
    • Standard ⭐ (recommended) — routine development including push is allowed; PR creation, publication, merge/release, force-push and destructive actions ask.
    • Open — allow-by-default; everything except explicitly-destructive, which ask.

    The built-in definitions ship as read-only policy spec files (Locked / Standard / Open); applying your pick is the job of the applying-a-permission-policy skill — it translates the chosen spec into your live harness config (Claude settings.json / Codex config.toml), interactively, showing the diff before it writes.

  • YOLO MODE — done with permissions, just want it to work: OpenRig boots every seat with the harness full-bypass launch flag. No config policy is applied (the bypass overrides it). This is a deterministic OpenRig setting, not a skill.

  • No choice = the floor — the minimal usability baseline (Claude acceptEdits / Codex workspace-only / Pi --no-approve), one consistent minimum, nothing more.

The floor and YOLO are launch flags OpenRig sets deterministically; the Locked / Standard / Open policies are config-file policies the skill applies (agent-driven, because harness config formats drift). A rig carries its chosen policy on its spec and boots with it — see Lifecycle → Bring a rig up. To (re)apply or change a policy, open applying-a-permission-policy.

v0.3.x Starter, Workspace, And Plugin Surfaces

OpenRig v0.3.0 adds rig agent-image, rig context-pack, rig workspace, and rig config init-workspace. (0.5.0: the rig context-pack alias is retired — the store + compose library is the single rig context noun; see "Context packs and paced delivery (0.5.0)".) It also shifts fresh-user starter guidance toward product-team for human-directed work and conveyor for workflow-oriented work. Treat demo as legacy/test content unless a task specifically asks for the old demo spec.

OpenRig v0.3.1 adds public package/source surfaces for Plugin Primitive v0, Claude Auto-Compaction Policy, migration 040_workflow_specs_diagnostic, Library Explorer finishing, Settings Destination Explorer, Dashboard/For You vellum refresh, storytelling adapter, and action outcome + inline error UX.

rig plugin is read-only at v0:

rig plugin list
rig plugin show <id>
rig plugin used-by <id>
rig plugin validate <path>

There is no rig plugin install verb in v0.3.1. Plugin installation remains explicit operator copy/symlink to $OPENRIG_HOME/plugins/<plugin-id>/.

The v0.3.1 package introduced opt-in Claude auto-compaction policy through policies.claude_compaction.* ConfigStore keys. A package version alone says nothing about a running daemon's configuration; inspect the selected instance before relying on a policy or its default.

Compatibility checks:

  • rig down accepts a rig name or id. An ambiguous name matching more than one active rig is refused with matching ids; use the intended id.
  • For queue/view JSON or limit differences, compare the installed command's help, the running daemon version and the actual response. A wrapper mismatch is not by itself a daemon-health failure, and historical workarounds are not current behavior guarantees.
  • After a startup timeout, inspect status and logs before retrying; a timeout does not establish whether the underlying operation completed.

Recovery and Resilience (v0.3.4+)

v0.3.4's theme is Recovery + Resilience. The surfaces below compose into a single boot-to-running-rig path that survives crashes, hand-resumed sessions, profile-load drift, and partial workspace state without silently fudging status.

rig start — recovery entrypoint

rig start is the top-level recovery sequencer. It does not invent recovery; it composes existing primitives (daemon start + kernel verify + per-rig restore) into one call.

rig start                    # interactive: daemon + kernel + pick-and-restore
rig start --last             # headless: restore all rigs that were last running
rig start --all              # headless: restore all rigs with restore-usable snapshots
rig start --rigs <name> [<name>...]   # headless: restore only the named rigs
rig start --json             # JSON output for agents

Framing: rig start is the RECOVERY entry point, not the getting-started hero. The fresh-user boot hero remains rig up <starter> (typically rig up product-team). Reach for rig start after a host reboot, daemon restart, or any "bring my rigs back" moment.

rig reconcile-session — no-launch adopt of a hand-resumed session

When an operator has externally resumed an agent session (e.g. attached a shell, restarted a runtime by hand) and you want OpenRig to reconcile its lifecycle state without re-launching or sending input, use:

rig reconcile-session <session>
rig reconcile-session <session> --rig <rigId> --node <logicalId>
rig reconcile-session <session> --no-launch
rig reconcile-session <session> --json

This is a no-launch, no-input adopt. --rig/--node disambiguate when the canonical session name does not uniquely resolve. --no-launch is accepted for explicitness (it is the only mode this command has).

Five-term restore status vocabulary

The shipped restore vocabulary is intentionally honest. It surfaces in rig up / rig restore / rig ps. Use the term that fits — do not collapse to a generic "ok/failed":

  • resumed — seat resumed from its original session/snapshot and is live.
  • fresh-primed — seat opted into --fresh and was freshly started.
  • awaiting-decision — zero-session honest state. There is no resumable session AND no --fresh opt-in was given; the seat is waiting for an operator decision. Previously fudged as failed; that was wrong — nothing is broken, the system is asking for input.
  • attention_required — seat is in a state needing operator attention; not a transport failure. Clear via rig seat clear-attention once the attention has been resolved.
  • failed — the send transport or launch genuinely failed.

This replaces the prior collapsed model (the v0.3.3 four-term vocabulary, in which rebuilt was a term, is retired).

rig seat clear-attention — audited reconcile of stuck attention

When a seat is stuck in attention_required, do NOT hand-edit SQLite to fake-clear the state. Use the evidence-gated, operator-attested, audited reconcile:

rig seat clear-attention <session>
rig seat clear-attention <session> --reason "operator attested: the operator re-authed, confirmed live"
rig seat clear-attention <session> --json

--reason <text> can acknowledge startup-status and subset-restore attention. It does not bypass full-restore continuity checks or an active pane-identity mismatch/missing-pane check; those run first. Successful identity re-verification can also clear coexisting startup or subset-restore attention. If neither earlier path clears attention, omitting --reason requires activity or send evidence. Startup and restore clears write their corresponding audit events; an identity-only clear updates the current binding and identity verdict without a clear event. Acknowledgment or responsiveness alone does not prove that the original conversation resumed.

A 422 response names the uncleared class and its failed check. If the recorded native token needs correction and you know the actual token, use rig seat set-resume-token <session> --token-stdin --reason <explanation>, then rerun rig seat clear-attention <session> to check the live evidence. The token update records operator provenance; it does not itself prove continuity. Stopping/relaunching a working seat is a separate disruptive operation, not a required cleanup or proof of resumed lineage.

Periodic snapshots — crash-insurance floor

The daemon ships a periodic-snapshot scheduler. It runs independently of teardown events and provides the crash-insurance floor that prior event-only/teardown-only snapshots could not provide on hard crashes.

Config keys (SettingsStore):

  • snapshots.periodic.enabled — default true
  • snapshots.periodic.interval_seconds — default 300
  • snapshots.periodic.retention_keep — default 10

Newest-wins semantics: when both auto-periodic and auto-pre-down snapshots exist for a rig, the freshest of the two is selected for restore. A newer auto-periodic beats a stale auto-pre-down (the crash fix); a genuinely-fresher auto-pre-down still wins on graceful cycles. Manual snapshots are handled separately. See packages/daemon/src/domain/snapshot-repository.ts for the ordering rule.

The last-snapshot floor surfaces in rig ps / status output so an operator can see at a glance how recent the crash-insurance floor is.

Codex profile-v2 preflight

Profile-bearing launch/restore surfaces run a profile-load preflight. When profile-load issues are detected, the failure is honest and actionable (named error + remediation pointer) instead of a silent partial launch that would later look like an attention_required seat with no explanation.

cmux launch readiness

cmux-backed launches no longer produce silent partial workspace state. When parts of the workspace are missing, the launch surfaces partial state honestly and the UI exposes a one-click open-missing affordance.

(See also ## Token-Efficient Defaults (v0.4.0+) below for the compact-by-default read-command surface that lands in 0.4.0.)

Token-Efficient Defaults (v0.4.0+)

v0.4.0 flips the five most frequently invoked read-commands from firehose-by-default to compact-by-default, and rig queue list adopts the docker / kubectl read-command grammar. All defaults preserve breadth and capability — the firehose is one explicit flag away.

rig ps — scope-aware: bare rig ps = ALL rigs; --nodes = your rig only
rig ps                      # ALL active rigs on the host, one compact row each — RUN FIRST to know the world
rig ps --rig <name>         # one named rig's summary
rig ps --nodes --rig <name> # per-node (seat) detail for a NAMED rig — the normal drill-in
rig ps --nodes              # per-node detail — CURRENT rig ONLY (deliberately narrow; NOT the whole host)
rig ps --json               # compact JSON (default = a bare array of ALL non-archived rigs)
rig ps --nodes -A           # cross-rig node inventory (was v0.3.4 default)
rig ps --nodes --full       # complete record (the v0.3.4 per-node default shape; resumeToken VALUE retained here for downstream consumers)
rig ps --nodes --session <sess>  # narrow to one canonical session
rig ps --active             # opt-in active-state filter (does NOT change the all-states default — ps surfaces topology/readiness, where stopped/recoverable/attention IS the actionable signal)

v0.4.0 breadth + projection changes:

  • Rig-level rig ps lists ALL active rigs (one row each — the cheap "know the world" view). The --nodes (per-seat) view defaults to your CURRENT rig only (from OPENRIG_SESSION_NAME's @<rig> suffix); --rig <name> picks another rig, -A widens --nodes to the whole host (expensive — prefer --fields/--limit).
  • Per-node TL;DR projection (compact) is the default; --full returns the raw byte-equivalent passthrough. Daemon-side recoveryGuidance relocated to a guidance-by-reference map (no longer duplicated per-node) — even --full benefits.
  • All-states stays default (different from rig queue list which defaults to active-only) — for ps, non-running states ARE often the actionable signal.
  • Resume-token security: --full JSON emits resumeTokenPresent (boolean) — the actual resumeToken value also remains in --full for downstream consumers that legitimately need it, but the compact default never carries it (an orch glance never accidentally leaks token material).

⚠ SCOPE-AWARENESS — the one that bites: rig ps --nodes (and --nodes --json) show ONLY your current rig's seats, by design — the narrow default protects your context window. Narrow output is not the whole world. Never conclude "my rig is the only rig on the host" from a --nodes read — run bare rig ps FIRST (cheap; it lists every rig), then rig ps --nodes --rig <name> for the one you need. (-A widens to the whole-host node view; choose it when that breadth is needed.)

rig whoami — compact-by-default + --full (--verbose alias)
rig whoami                  # compact: identity + peers names + edges + transcript path
rig whoami --json           # compact JSON
rig whoami --full           # complete payload (v0.3.4 default shape)
rig whoami --verbose        # alias of --full

The first command every agent runs on boot AND every compaction-restore. The compact default keeps identity-recovery essentials (identity, peers names + sessionNames, edges directional kind + to.sessionName, transcriptPath). --full adds contextUsage, commands, peersNote, runtimeContext. The compact-default is an ALLOWLIST projection — future payload fields default to --full and cannot silently re-bloat the every-boot path.

rig queue list — active-frontier + docker/kubectl grammar
rig queue list                       # active, compact, CURRENT-rig (docker-ps default)
rig queue list -a                    # + closed/done history within current breadth (docker -a)
rig queue list -A                    # cross-rig breadth (kubectl -A)
rig queue list --full                # add body + chain-of-record + transition history
rig queue list -o json               # compact JSON (token-safe, machine-parseable)
rig queue list --full -o json        # full JSON
rig queue list --mine                # just the caller's items
rig queue list --destination <s>     # destined to <s>
rig queue list --source <s>          # sourced by <s>
rig queue show <qitemId>             # bounded single-item body preview
rig queue show <qitemId> --full      # complete body and chain fields

Four orthogonal axes (scope × history × field-breadth × encoding), all composable. STOP using bare rig queue list as the cross-rig firehose. Default is now active + compact + current-rig. Cross-rig history with full bodies is opt-in via -A -a --full; request only the breadth and fields needed for the question.

rig restore-check — summary + not-ready-only default + --full
rig restore-check               # summary counts + not-ready seats (with reasons) only
rig restore-check --full        # complete per-seat readiness across the fleet (v0.3.4 default)
rig restore-check --rig <name>  # narrow
rig restore-check --as <session>  # narrow to one seat

The summary retains not-ready seats and their reasons; --full adds ready-seat detail when needed. Scope the query before expanding its payload.

rig context — context-window usage viewer (0.4.x; REMOVED in 0.5.0)
rig context                # compact summary        (0.4.x only)
rig context --full         # complete current payload
rig context --rig <name>   # narrow to one rig
rig context --threshold 80 # filter to seats at/above 80%

Lower leverage than the others; keeps the read-command surface compact-by-default after the 0.4.0 upgrade. ⚠ 0.5.0: this usage viewer is removed entirely and the rig context name is reassigned to the context library (store + compose) — see "Context packs and paced delivery (0.5.0)" below. On a 0.5.0 host, bare rig context is the library, not this viewer.

Keep routine reads bounded

Choose scope, active/history breadth and fields before expanding a result. A status question usually needs identifiers, owner, state and reason; open the full body or artifact when it is relevant. Preserve full evidence on disk instead of repeatedly loading unchanged output. Compact defaults reduce reading cost; they do not remove the full-detail path or prove that nothing exists outside the scope.

rig scope mission|slice progress — deterministic progress updates
rig scope mission progress <mission> --add "<line>"   # append a progress line; --set replaces; --section <heading> (default Rail); --status active|done|blocked
rig scope slice progress <slice-path> --add "<line>"  # same flags: --add / --set, --section <heading>, --status active|done|blocked

Replaces hand-editing PROGRESS.md with markdown. Writes the canonical structure the OpenRig PROGRESS UI page reads. rig scope mission create + rig scope slice create now scaffold PROGRESS.md automatically.

rig scope mission|slice stage / verified / repair — deterministic maturity vocabulary
rig scope slice stage <slice> <new-stage>             # wip / provisional / established / canonical / superseded / retired
rig scope slice stage <slice> superseded --successor <id>  # superseded REQUIRES --successor (rejected otherwise)
rig scope mission stage <mission> <new-stage>         # same enum + rules at mission tier

rig scope slice verified <slice> --against "<source>" # stamp `verified: <today> against <source>`; --against MANDATORY
rig scope mission verified <mission> --against "<source>"

rig scope slice repair <slice>                        # idempotent repair: backfill PROGRESS.md, conform id/stage/verified, repair ghosts
rig scope mission repair <mission>                    # mission-tier idempotent repair

rig scope slice show <slice>                          # derives read-time effective-reliability from (stage × verified)
                                                      # — stale-`verified` `canonical` reported as effectively `provisional`

Composes with the progress command + scaffolding to update scope IDs and maturity vocabulary through rig scope. Agents update stage / verified / id through commands rather than hand-editing markdown and drifting. The --against MANDATORY rule on verified is the anti-stale keystone: bare timestamps are rejected because a bare timestamp is exactly what lets stale trackers lie while looking fresh. STOP hand-editing the stage / verified / id fields in scope frontmatter; use the new verbs. Existing missions / slices with id:null ghosts or missing PROGRESS.md are repaired idempotently via repair.

rig skill audit — skill cascade provenance
rig skill audit                  # human report of findings
rig skill audit --json           # structured findings
rig skill audit --severity warn  # stale + mirror-drift only
rig skill audit --rig <name>     # narrow to embedded skill copies for one rig

Read-only audit of the skill cascade. Detects missing / stale / self-referential / invalid-date / mirror-drift across the canonical skills workspace → product mirror → hub cwd → installed plugin chain. Findings route back to the lifecycle for shaped propagation runs. False-green prevention: when audit evidence is unavailable, the CLI emits unable-to-audit with exit code 2 rather than reporting clean.

rig seat clear-attention — extended to derived projection staleness

clear-attention also reaches restore-derived attention even when startupStatus=ready and sessionStatus=running. Full-restore attention requires the restore reconciler's exact native-token and usable-pane checks; --reason cannot replace them. Subset-restore attention can reach the attestation path when no active pane-identity class takes precedence. That path records operator_recovered with runtimeCwdVerified:false; it is an acknowledgment, not proof of resumed lineage. Without an explicit stored continuity outcome, inventory leaves continuity null (unverified in rig seat status) unless the same restore attempt has a matching receipt and reconciliation with strict native-token and usable-pane proof. Explicit stored outcomes remain historical facts; acknowledgment or responsiveness alone cannot infer resumed.

Native Codex session id capture

Codex seats can now record the real native session id from the Codex SessionStart hook instead of relying on scrape-shaped identity. Corroborate the id across the current hook payload, provider history and managed record before relying on it. A release introducing native capture does not prove that every existing seat uses it; retain any unavailable or conflicting identity evidence explicitly.

Codex resume preserves approval posture

Resuming a Codex seat preserves the launching seat's approval/sandbox posture and profile flags. Product-emitted resume commands carry the posture flags instead of silently falling back to implicit-deny or an unrelated profile.

Do not "fix" a resumed Codex seat by relaunching it with broader approvals unless the operator explicitly grants a bounded window. Verify the seat's active posture first, and preserve it when composing recovery commands.

rig seat set-resume-token --token-stdin
printf '%s' "$RESUME_TOKEN" | rig seat set-resume-token <session> --token-stdin

Use this command to set or restore a seat resume token. It replaces direct SQLite edits, rejects unauthorized writes and bad/null token false-ready paths, records redacted audit/provenance, and keeps token material out of command arguments, stdout, logs, and normal status rows. Use stdin, not an inline flag, when passing token material.

Core Loop

Most work in OpenRig reduces to this loop:

  • recover identity: rig whoami (compact default; add --full only when you need the heavy payload)
  • inspect inventory: rig ps --nodes (compact default; add --full only when you need the firehose)
  • read context: rig transcript ..., rig ask ..., rig chatroom history ...
  • act: rig send, rig capture, rig broadcast, lifecycle commands

Agent-Managed Apps

An agent-managed app is a deployable OpenRig unit made of:

  • the software or service
  • one specialist agent dedicated to that software

Treat the specialist as the domain delegate for that app. The current canonical example is:

  • rig: secrets-manager
  • pod: vault
  • member: specialist
  • logical ID: vault.specialist
  • session: vault-specialist@secrets-manager

Typical operator loop:

rig up secrets-manager --cwd /path/to/project
rig ps --nodes --json
rig send vault-specialist@secrets-manager "Check Vault health and report back." --verify
rig env status secrets-manager
rig env logs secrets-manager

Cross-rig communication is valid when the target session resolves uniquely. Example:

rig send vault-specialist@secrets-manager "Read secret/data/dogfood and report the value." --verify

Use the specialist instead of teaching every peer the same app-specific toolchain. For Vault, ask vault.specialist to do secrets-domain work rather than improvising curl or Vault CLI usage in unrelated agents.

Identity and Recovery

Start here after launch, compaction, or confusion:

rig whoami --json

What it gives you today:

  • identity: rig, logical ID, pod/member, session name, runtime
  • peers and directional edges
  • transcript info
  • contextUsage when available

Flags:

rig whoami --session <name>
rig whoami --node-id <id>

If the daemon is unreachable but identity can still be inferred, --json may return a partial result instead of crashing.

WhoamiResult (v0.3.3+) carries a required peersNote field with three pointers the agent can use to navigate the rest of the rig from a cold start. The human-formatted CLI output preserves the literal Peers: line prefix verbatim (parser/test compatibility) and surfaces the clarifier in-band beneath it; the JSON form exposes peersNote directly for programmatic consumers.

Inventory and Monitoring

rig ps                      # ALL active rigs on the host, one compact row each (run FIRST to know the world)
rig ps --nodes              # compact node inventory (current rig)
rig ps -A                   # all-rigs breadth (was the pre-0.4.0 default)
rig ps --nodes --full       # complete per-node record (the firehose — opt-in)
rig ps --nodes --json       # compact JSON node inventory (add --full for the full record)

v0.4.0 flipped these to compact-by-default — see the rig ps compact-defaults section above; STOP using bare rig ps --nodes --json as a fleet-wide firehose (scope and detail are separate choices). The compact rig ps --nodes node inventory (add --full only when you need the complete record, -A for cross-rig breadth) carries, per node:

  • session name
  • runtime
  • session/startup status
  • restore outcome (compact: resumeTokenPresent boolean; the token VALUE is in --full)
  • attach/resume commands
  • latest error

Other health surfaces:

rig status
rig daemon status
rig config
rig preflight
rig doctor
rig env status <rig>
rig env logs <rig>
rig env down <rig>
Bounded agent self-scout

Use the typed health projection before reading raw coordination history. The default query is the current seat; widen deliberately when the evidence points beyond it:

rig health --json
rig health --rig <rig-id> --json
rig health --instance --json
rig health explain <finding-id> --json

Follow the returned stable finding ID and suggestedInspection. Use explain when the summary matters: it returns the same canonical record with its bounded window, freshness, literal detector rule, evidence references, and next inspection. Human output projects those same fields; it does not calculate a second score.

An empty result means only that no records matched the bounded query. It is not a healthy assertion. Stale, unavailable, contradictory, and indeterminate evidence stays explicit. Never read raw SQLite for a self-scout, and never turn a finding into an acknowledgement, notification, queue row, or remediation automatically: rig health is strictly read-only.

Transcript and Communication

Transcript access
rig transcript <session> --tail 100
rig transcript <session> --grep "pattern"
rig transcript <session> --json
Send to one session
rig send <session> "message"
rig send <session> "message" --verify
rig send <session> "message" --wait-for-idle <seconds>
rig send <session> "message" --raw
rig send <session> "message" --dangerously-interact --reason "<why>"
rig send <session> "message" --host <id>
rig send <session> "message" --json

The send-guard (v0.4.0) — the default is SAFE. A default rig send is guarded: it will NOT submit into an interactive prompt / permission block on the target pane. Flags:

  • --verify — delivery evidence.
  • --force — a back-compat no-op on the send DECISION: it never bypasses the interactive-prompt/permission guard and never changes whether a message is delivered (a mid-task/busy pane already sends-with-advisory by default). (It does NOT "bypass activity-risk checks" — that earlier teaching is retired.) It is not fully inert, though — it is still parsed solely to be rejected in combination with --wait-for-idle: rig send … --force --wait-for-idle <n> prints --wait-for-idle cannot be combined with --force, exits 1, and sends nothing. So do not read "no-op" as "--force --wait-for-idle is harmless"; that pairing errors. (Verified against current product main d37a08ad: the guard-bypass no-op is declared at send.ts and confirmed by runtime capture — a plain --force send delivers through the ordinary path; the --wait-for-idle rejection is enforced at send.ts, routes/transport.ts, and session-transport.ts, and confirmed by runtime capture — exit 1, nothing sent.)
  • --wait-for-idle <seconds> — wait until the target is explicitly idle before sending. Cannot be combined with --force (that pairing is rejected: exit 1, nothing sent).
  • --raw — send exact text/keystrokes without the From/To messaging envelope (still guarded against interactive prompts).
  • --dangerously-interact --reason "<why>" — the ONLY override of the prompt/permission guard: deliberately drive an interactive prompt/permission block (implies --raw, requires --reason, audit-logged).
  • --host <id> — send on a remote host declared in ~/.openrig/hosts.yaml (ssh hosts shell out; http hosts go CLI-direct to the remote daemon).
  • --from <session> — deprecated and ignored; it does not select the sender. Sender identity comes from the current seat and transport provenance; cross-host envelopes use the durable local origin, not the supplied flag or a relay identity.
  • --context <ref> (0.5.0) — attach a composed context pack/piece by ref (see "Context packs and paced delivery"). Small piece → send --context; a real pack → rig walk. The noun rig context composes the ref; the verb delivers it.

Durable work goes to the QUEUE, not send. rig send is an ephemeral message to a pane — it can be missed, and its delivery status is pane-render, not receipt. If you are assigning work, or the message is important enough that losing it would be a real bummer, use rig queue (below): it's durable, owned, tracked, and survives compaction and restart. Reach for send for a quick conversational nudge; reach for the queue for anything that must not get lost. Do not default to send for work — that's the most common mistake.

As of v0.3.3, content beginning with -- or - is safe: rig send <session> "content starting with -- or - is now safe" delivers literally. The daemon's send_text path carries an explicit -- end-of-options sentinel so tmux no longer parses dash-prefixed content as its own flags. The CLI surface itself is unchanged. For multi-line or large bodies handed off as durable work, use rig queue create --body-file <path> (- for stdin) — that's the queue-side surface, not rig send.

--verify delivery outcomes (v0.3.3+):

  • delivered — text + Enter both succeeded and capture re-confirmed the body landed.
  • rendered-unconfirmed — text + Enter both succeeded but capture could not re-confirm the body (TUI redraw race or scroll). The message landed; the post-send re-check could not prove it. Treat as landed-but-unconfirmable, NOT failure.
  • failed — the send transport itself failed.

The legacy Verified: yes/no line is preserved verbatim (parser/test compatibility). A new Delivery: <outcome> line carries the named outcome above.

Observed operator nuance for --verify:

  • Sent to ... + Verified: yes (Delivery: delivered) = strong positive delivery evidence.
  • Sent to ... + Verified: no + Delivery: rendered-unconfirmed = the message landed; capture could not re-prove it. Don't blind-retry — check reply / rig capture / transcript before sending again.
  • Sent to ... + Verified: no + Delivery: failed = send-transport failure.
  • no Sent to ... line or a hard error = send failure.

When you get Verified: no, do not immediately retry blindly. First check one of:

  • a direct reply from the target
  • rig capture <session>
  • transcript evidence
  • queue/outbox state if the message asked for a durable handoff
Capture terminal output
rig capture <session>
rig capture <session> --lines 50
rig capture --rig <name>
rig capture --pod <name> --rig <name>
rig capture --rig <name> --json
Broadcast
rig broadcast --rig <name> "message"
rig broadcast --pod <name> "message"
rig broadcast "message"
rig broadcast --rig <name> "message" --json

Use rig broadcast sparingly — prefer rig send fan-out. Without --rig or --pod, broadcast targets every running session across ALL rigs (plus attached external_cli nodes) — the fastest way to cause a broadcast storm. Reserve rig broadcast for small rigs or a genuine all-hands emergency. For the normal "message several seats at once" case, use rig send, which scopes the fan-out and keeps the messaging envelope, the delivery/interactive-prompt guards, and per-recipient results:

rig send --to dev-impl@my-rig,dev-qa@my-rig "message to specific seats"   # named seats (comma-list or repeat --to)
rig send --pod dev "message to one pod"                                    # scoped fan-out
rig send --rig my-rig "message to one rig"                                 # scoped fan-out
Chatroom
rig chatroom send <rig> <message> [--sender <name>]
rig chatroom history <rig> [--topic <name>] [--after <id>] [--since <ts>] [--sender <name>] [--limit <n>] [--json]
rig chatroom wait <rig> [--after <id>] [--topic <name>] [--sender <name>] [--timeout <seconds>] [--json]
rig chatroom clear <rig>
rig chatroom topic <rig> <topic-name> [--body <text>] [--sender <name>]
rig chatroom watch <rig> [--tmux]

Key commands:

  • send — post a message
  • history — retrieve with composable filters (sender, since, after, topic)
  • wait — block until new matching messages arrive (polls history, times out honestly)
  • clear — delete all messages for the rig (destructive, rig-scoped)

See something, say something

OpenRig has an observation stream — the fleet's zero-friction institutional memory, mined for real product improvements. When you notice anything worth externalizing, say something and keep working:

  • a bug, a rough edge, or something that needs fixing
  • a feature idea or an improvement
  • something that worked really well — a technique, tool, or pattern worth spreading
  • an observation, positive or negative feedback, or something genuinely cool, productive, or funny
rig stream emit --source <your-session> --body "what you noticed"

That's the whole reflex. Don't decide where it goes or who it's for — the intake router triages (destination/type/urgency/tags are optional hints — --hint-type review|handoff|idea, --hint-urgency routine|urgent|critical, --hint-tags — never required). One command, then carry on; the value is the habit, not the polish. Don't overdo it, either: stream real signal, not narration — a good observation beats ten noisy ones. It's a passing thought you externalize, not a chore.

  • topic — set a topic marker
  • watch — SSE or tmux-based live stream

Roundtable protocol:

  1. Inspect old room: rig chatroom history my-rig --limit 5
  2. Save if needed: rig chatroom history my-rig --json > /tmp/old-room.json
  3. Clear if needed: rig chatroom clear my-rig
  4. Set topic: rig chatroom topic my-rig "ROUND START"
  5. Post: rig chatroom send my-rig "position..." --sender <session>
  6. Monitor: rig chatroom wait my-rig --timeout 120
  7. Close: rig chatroom topic my-rig "ROUND CLOSED"
rig ask
rig ask <rig> "question"
rig ask <rig> "question" --json

Current shipped behavior:

  • queries the daemon for evidence
  • returns rig summary
  • returns transcript excerpts
  • may return chat excerpts
  • returns insufficiency state and optional guidance

This is an evidence/context command. It is not a hidden second-LLM call.

rig auth — agent auth-profile management (v0.4.1, product-native)

Product-native switching of agent auth profiles from the CLI. The runtime is a flag (--runtime <codex>), not a command noun — never rig codex-auth.

rig auth status --runtime codex          # presence / mode / parseability / login-state (never prints token contents)
rig auth list --runtime codex            # saved profiles
rig auth save <profile> --runtime codex  # snapshot the auth FILE (mode-guarded), never echoes contents
rig auth switch <profile> --runtime codex
rig auth validate <profile> --runtime codex
rig auth seats … --runtime codex         # seat -> profile registry (metadata only; NOT proof of a live account)

Hard secret boundary: no token value is ever printed, logged, queued, streamed, or committed; status/validate report presence/mode/login-state only; seat labels are metadata, not live-account proof. MVP is --runtime codex; other runtimes use the same surface with a different --runtime, never a parallel command.

Context packs and paced delivery (0.5.0)

Compose context once, hand it to a seat cleanly. A library primitive plus a set of delivery flags. The rule that keeps the grammar coherent — internalize this one: the noun stores and composes; the verbs deliver. rig context never sends anything; delivery is only ever rig send / rig broadcast / rig walk / rig queue.

Version note: this describes the library surface introduced in 0.5.0. Check the installed command and serving daemon before relying on it. In 0.4.x, bare rig context was a context-window usage viewer (above); in 0.5.0 that viewer is removed and the rig context name belongs to the library here.

rig context — the store + compose library (never delivers)

Manage and compose context (any text/markdown) into reusable packs. Every piece and pack has a stable, path-like ref — you address context the way you address files (skills/claude-compaction-restore, reference/rig-spec.md).

rig context list                     # what's in the library
rig context show <ref>               # read a piece or pack
rig context add <source-dir>         # install an existing pack directory into the store
rig context preview <ref>            # assemble + show a pack WITHOUT delivering it
rig context sync                     # re-walk discovery roots, refresh the library index
rig context rm <ref>
rig context compose --out packs/<ref> --from <fileA> <fileB> ...   # ordered pieces -> a durable pack
  • Sensible default store location; works unconfigured, can be pointed elsewhere later (another folder now; a machine or URL later).
  • compose (v1) is honest ordered concatenation of named files into a durable pack with a ref — "here's a file, read a file."
  • No delivery verb lives on the noun. To get a pack to a seat, hand its ref to a delivery verb below.
rig walk — paced delivery of a sequence
rig walk <seat> --through <ref | file ...> --pace 10s

Walk a seat through a pack: each piece is sent into the pane, spaced by --pace, so the agent processes between sends (the human paste → wait → paste rhythm). Its own top-level verb, push-direction — the walker leads and does not wait for replies; the spacing does the work. Reach for walk on onboarding, repriming, or a fleet update — anything absorbed in order rather than all at once.

The delivery grammar — send a ref, walk a pack, or attach it to a qitem
When Verb
One thing, now rig send <seat> --context <ref>
One thing, everyone rig broadcast --rig <rig> --context <ref>
A sequence, absorbed rig walk <seat> --through <ref> --pace 10s
Context riding a durable handoff rig queue create … --body-context <ref>
  • Rule of thumb: small piece → send --context; real pack → walk. An oversized send --context warns "this is walk-sized" instead of blasting the pane.
  • --body-context snapshot rule: a qitem built from a ref stores the resolved content in its body plus the ref for provenance — the handoff carries what was actually sent, and a later library edit never silently rewrites a past handoff's history.
  • The orchestrator habit — assign work with its context attached:
    rig context compose --out packs/qitem-brief --from <brief-file> <proof-file>
    rig queue create --destination dev-driver@build --body-context packs/qitem-brief --summary "…"
    
    Replace <brief-file> and <proof-file> with your existing local files. The curated context rides the durable handoff, survives compaction, and is auditable.

Skills tier vs context tier: skills are the HOT tier (ambient, finite, always-visible front-matter); context packs are the COLD tier (unbounded, fetched on instruction — "read rig context get onboarding-width"). Don't overrun the skill layer by using skills as context packs — that's what this primitive is for.

Lifecycle

Bring a rig up
rig up <source>
rig up <source> --plan
rig up <source> --yes
rig up <source> --cwd /path/to/project
rig up <source> --existing
rig up <source> --fresh <seat...>
rig up <source> --json

<source> can be:

  • a rig spec path
  • a .rigbundle path
  • a bare name

Bare names are special:

  • if they match a library spec, rig up launches from the spec library
  • if they do not match a library spec, rig up treats the name as an existing-rig restore/power-on target
  • if both exist, rig up fails loudly on ambiguity

Resume-original-by-default (v0.3.4+):

  • For an existing rig, rig up <name> resumes each seat from its original session/snapshot by default (operation A). Seats that successfully resume report resumed.
  • --fresh <seat...> is the per-seat opt-in for deliberate fresh-prime (operation B). Named seats are reported as fresh-primed.
  • --existing forces existing-rig restore semantics on a bare name, bypassing library-spec resolution. Useful when a rig name collides with a library spec name.
  • Example: rig up --existing my-rig --fresh dev-impl — resume everything in my-rig except dev-impl, which is freshly primed.
  • Seats with no resumable session land in awaiting-decision (zero-session honest state, NOT failed); see the five-term restore vocabulary in "Recovery and Resilience" below.

--plan (v0.3.4+):

  • rig up <source> --plan produces a read-only restore plan preview. It surfaces per-seat resume/fresh-prime intent and any awaiting-decision seats without mutating state. Honest async timeout: a stuck plan reports the timeout rather than hanging silently.

Current behavior notes:

  • --target <root> is only for .rigbundle / package installation. It does not change agent cwd.
  • rig up --cwd is shipped. rig up --cwd <path> sends a per-run cwd override for all members in that launch.
  • local: agent_ref values resolve relative to the rig spec directory, not your shell cwd.
  • if you copy a built-in spec elsewhere, keep its agents/ tree beside the YAML or rewrite those refs to path:/absolute/path
  • rig specs add <directory> installs a full spec tree when the directory contains rig.yaml or agent.yaml.
  • Permission policy: a rig carries a permission policy and boots with it (never changed on the fly). Default if none set = the minimum floor (Claude acceptEdits / Codex workspace-only / Pi --no-approve); otherwise a chosen built-in (Locked / Standard / Open) or deliberately none. When you spec or bring up a rig, decide its policy — apply it via applying-a-permission-policy (see also the onboarding menu, "Permission policy — pick one at setup").

Legacy/spec-specific surfaces still ship too:

rig bootstrap <spec> [--plan] [--yes] [--json]
rig requirements <spec> [--json]
Tear a rig down
rig down <rig>            # <rig> = rig name or id (active rig)
rig down <rig> --snapshot
rig down <rig> --delete
rig down <rig> --force
rig down <rig> --json

If --snapshot succeeds, human output includes the restore hint.

Archive a stopped rig (recoverable) — v0.3.3+
rig archive <rig> [--json]
rig unarchive <rig> [--json]

rig archive marks a stopped rig as archived (sets archivedAt) without discarding it. The rig is preserved for later restoration via rig unarchive, which clears archivedAt and returns the rig to the active set.

Archive vs delete:

  • rig down --delete — permanent removal; not recoverable.
  • rig archive — recoverable; the rig is hidden from the default active view but its record + snapshots are preserved.

Visibility in rig ps:

  • rig ps — active rigs only (default).
  • rig ps --include-archived — includes archived rigs, marked with *.

SSE events rig.archived / rig.unarchived drive Project / dashboard updates; consumers that depend on the rig list should subscribe rather than poll.

Environment services
rig env status <rig>
rig env logs <rig> [service]
rig env down <rig>

Use these for service-backed rigs and agent-managed apps. For secrets-manager, these are the fastest CLI surfaces for:

  • confirming whether Vault is healthy
  • reading Vault container logs
  • stopping the Vault env without tearing down the specialist session first
Release management without killing live claimed sessions
rig release <rigId>
rig release <rigId> --delete
rig release <rigId> --json

Use rig release for adopted/claimed-session rigs when you want OpenRig to stop managing the rig but leave the tmux sessions alive. This is the safe recovery/reset surface for the "sessions still exist, management is broken or stale" case. If the rig contains OpenRig-launched nodes, rig release refuses loudly instead of pretending the mixed rig is safe to detach.

Snapshots and restore
rig snapshot <rigId>
rig snapshot list <rigId>
rig restore <snapshotId> --rig <rigId>

rig restore requires --rig <rigId>.

Claude Code autonomy note:

  • unattended rig whoami on boot may require the local permission allow list to include Bash(rig:*)
Import/export and bundles
rig export <rigId> -o rig.yaml
rig import <path> [--instantiate] [--materialize-only] [--preflight] [--target-rig <rigId>] [--rig-root <root>]
rig bundle create <spec> -o out.rigbundle
rig bundle inspect <bundle>
rig bundle install <bundle> [--plan] [--yes] [--target <root>] [--json]
Legacy package surface

This still ships, but is explicitly marked legacy:

rig package validate <path>
rig package plan <path> [--target <dir>] [--runtime <runtime>] [--role <name>]
rig package install <path> [--target <dir>] [--runtime <runtime>] [--role <name>] [--allow-merge]
rig package list
rig package rollback <installId>

Discovery and Topology Mutation

Discover unmanaged tmux sessions
rig discover
rig discover --json
rig discover --draft
Bind a discovered session
rig bind <discoveredId> --rig <rigId> --node <logicalId>
rig bind <discoveredId> --rig <rigId> --pod <namespace> --member <name>

There is no shipped top-level rig claim command. The current adoption surface is discover, bind, adopt, and unclaim.

Self-attach the current shell or agent
rig attach --self --rig <rigId> --node <logicalId>
rig attach --self --rig <rigId> --node <logicalId> --print-env
rig attach --self --rig <rigId> --pod <namespace> --member <name> --runtime <runtime>

Use rig attach --self when the current agent should attach itself directly instead of going through discover + bind.

Current proven behavior:

  • inside tmux: attaches as a normal tmux-backed node, preserving inbound rig send / rig capture
  • outside tmux: attaches as external_cli
  • --print-env prints the OPENRIG_NODE_ID and OPENRIG_SESSION_NAME exports for the current shell

Recommended flow:

rig attach --self --rig <rigId> --node <logicalId> --print-env > /tmp/openrig-self-attach.env
. /tmp/openrig-self-attach.env
rig whoami --json

Notes:

  • for tmux-backed self-attach, rig whoami --json is the right verification
  • for raw/external self-attach, rig ps --nodes --json is currently the more reliable verification surface
  • if the current shell is outside tmux, pass --display-name <name> when you want a stable human session label recorded
Adopt a topology and bind live sessions
rig adopt <path> --bind <logicalId=tmuxSessionOrDiscoveryId>
rig adopt <path> --bind <logicalId=...> --bind <logicalId=...> --json
rig adopt <path> --bindings-file <bindings.yaml>
rig adopt <path> --bind <logicalId=...> --target-rig <rigId> --rig-root <root>

Use rig adopt when the sessions already exist and you want OpenRig to start managing them.

A bindings file is the durable map from authored logical IDs to live sessions. Shape:

bindings:
  dev1.impl2: dev1.impl2@rigged-buildout
  dev1.qa: dev1.qa@rigged-buildout

Spec + bindings is the proven recovery pair for adopted rigs. Spec gives OpenRig the intended topology. Bindings tells OpenRig which discovered live session belongs in each logical node.

Proven adopted-rig recovery workflow

This workflow is proven for the case where the external tmux sessions are still alive:

rig release <rigId> --delete
rig discover --json
rig adopt <spec.yaml> --bindings-file <bindings.yaml>

What this does:

  • removes OpenRig management without killing the sessions
  • re-discovers those same sessions as unmanaged
  • re-attaches them to the topology defined by the spec + bindings

Important limits:

  • this is for sessions still alive
  • spec alone is not enough for adopted rigs; you also need bindings
  • this does not yet mean OpenRig can recreate dead external sessions from nothing
Add unmanaged pods into an existing rig

This is the proven workflow when a rig is already managed, but a new pod was created outside OpenRig and you want to add it later:

rig adopt <pod-fragment.yaml> --bindings-file <pod.bindings.yaml> --target-rig <rigId>

Use this when:

  • the target rig already exists
  • the new sessions are live and visible in rig discover --json
  • you want additive topology growth, not a full rebuild

What to prepare:

  • a pod fragment spec with only the new pod
  • a bindings file mapping the new logical IDs to the live session names

Verification loop:

rig discover --json
rig adopt <fragment.yaml> --bindings-file <bindings.yaml> --target-rig <rigId>
rig ps --nodes --rig <rigId>   # the target rig's nodes (--nodes alone = your current rig)
rig export <rigId> -o rig.yaml

Success looks like:

  • the new sessions stop appearing in rig discover
  • the new logical IDs appear in rig ps --nodes --rig <rigId>
  • rig export includes the new pod
Mixed-origin rigs are allowed

One rig can contain both:

  • adopted nodes bound from already-running sessions
  • OpenRig-launched nodes created later with rig expand / rig launch

Current safety rule:

  • rig release is for claimed/adopted-only rigs
  • if a rig contains launched nodes, rig release fails with contains_launched_nodes
Manager-assisted recovery

The proven operator pattern is:

  • keep one OpenRig manager session outside the rig it manages
  • address the target by rig name, not cached rig ID
  • find the target rig with bare rig ps (lists all rigs), then resolve its owner from rig ps --nodes --rig <target> (a bare --nodes read is your current rig only, not the target's)
  • send the manager the spec path, bindings path, and verification steps with rig send

This lets ordinary agents ask the manager for OpenRig help instead of every agent needing to be an OpenRig expert.

Add/remove running topology parts
rig grow <rig-id> <member...> [--pod <pod> | --new-pod <pod>] [--runtime <runtime>] [--cwd <path>] [--json]
rig expand <rig-id> <pod-fragment-path> [--rig-root <path>] [--json]
rig launch <rigId> <nodeRef> [--json]
rig launch <rigId> --seats <a,b,c> [--hold-reason <text>] [--json]
rig remove <rigId> <nodeRef> [--json]
rig shrink <rigId> <podRef> [--json]
rig unclaim <sessionRef> [--json]

rig grow is the simplest way to add seats: no YAML, the default agent spec, and one runtime and working directory for the named seats (--new-pod creates a pod for them). Check rig grow --help on your installed version. Use a fragment with rig expand (a pod) or rig add (one member) when a seat needs an explicit model, a permission policy, a different agent spec or role profile, per-seat runtime or cwd, or startup files.

Node-granular managed partial restore (v0.3.4+):

  • rig launch <rigId> <nodeRef> relaunches a single seat by logical id or node id through orchestration.
  • rig launch <rigId> --seats <a,b,c> relaunches a comma-separated subset of seats.
  • --hold-reason <text> records a reason for holding non-target seats during the partial launch.
  • This is a SUPPORTED managed path. The prior pod_aware_launch_unsupported dead-end is retired; pod-aware narrow launch now goes through this surface rather than ad-hoc rebuilds.
Add a member to an existing pod — v0.3.3+
rig add <rig-id> <pod-namespace> <member-fragment-path> [--json]

rig add is the top-level verb for the add_member converge op. It adds a single member to an existing pod from a YAML/JSON member fragment file. The daemon resolves the named pod, validates the member, runs preflight, and launches the member in place.

HTTP outcomes:

  • 201 — member added; per-node launch state included in the response.
  • 400 — validation_failed or preflight_failed (the fragment or its launch posture is rejected before any state change).
  • 409 — member_conflict (a member with that identity already exists in the pod).

Use rig add when you want additive growth inside a pod without re-running the full rig expand pod-fragment path or rebuilding the rig.

Specs and Validation

Validate specs
rig spec validate <path> [--json]
rig spec preflight <path> [--rig-root <root>] [--json]
rig agent validate <path> [--json]
Spec library
rig specs ls [--kind <kind>] [--json]
rig specs show <name-or-id> [--json]
rig specs preview <name-or-id> [--json]
rig specs add <yaml-or-directory> [--json]
rig specs sync [--json]
rig specs remove <name-or-id> [--json]
rig specs rename <name-or-id> <new-name> [--json]

MCP

rig mcp serve [--port <port>]

Current shipped MCP tools:

  • rig_up
  • rig_down
  • rig_ps
  • rig_status
  • rig_snapshot_create
  • rig_snapshot_list
  • rig_restore
  • rig_discover
  • rig_bind
  • rig_bundle_inspect
  • rig_agent_validate
  • rig_rig_validate
  • rig_rig_nodes
  • rig_send
  • rig_capture
  • rig_chatroom_send
  • rig_chatroom_watch

Troubleshooting and Weird States

When the CLI behaves strangely, use the smallest truthful check first:

rig whoami --json
rig daemon status
rig ps --nodes --json

Specific operator rules:

  • Sent to ... + Verified: no is ambiguous delivery, not automatic failure. Check reply, rig capture, transcript evidence, or queue/outbox state before retrying.
  • partial rig whoami --json can happen when identity is still inferable but the daemon-backed path is degraded.
  • the unified-exec-process warning is a host/tooling-layer signal, not automatic proof that the OpenRig topology is unhealthy.

If you hit the unified-exec warning, inspect for stale one-shot helpers before touching live seats:

ps -axo pid,ppid,command | rg 'tmux send-keys|rig queue create|tmux attach|codex|claude'

Safe cleanup target:

  • orphaned one-shot wrappers like tmux send-keys ...

Do not mass-kill:

  • tmux attach ...
  • codex ...
  • claude ...

JSON and Error Posture

Design assumptions that hold in the shipped CLI:

  • many operator commands support --json
  • error messages are intended to say what happened, why it matters, and what to do next
  • daemon-backed commands fail loudly when the daemon is stopped or unhealthy
  • restore failure is not something you should silently reinterpret as success

After-Compaction Recovery Checklist

  1. rig whoami --json
  2. rig transcript <your-session> --tail 100
  3. rig ps — lists ALL rigs on the host (know the world FIRST); then rig ps --nodes --rig <your-rig> for your seats. ⚠ rig ps --nodes --json alone is your CURRENT rig only — do NOT mistake it for the whole host (a freshly-compacted agent has no other context to catch the lie).
  4. rig chatroom history <rig> --limit 50

Commands That Do Not Exist

Do not assume these exist unless the shipped help starts listing them:

  • rig claim
  • rig blame
  • rig replay
1---
2name: openrig-user
3description: >-
4 Use when a specific `rig` command, subcommand, or flag is already known and you need its exact
5 syntax, JSON shape, defaults, or error meaning. NOT for natural capability discovery, open-ended
6 how-do-I questions, or choosing which OpenRig move applies.
7---
8 
9# OpenRig User
10 
11This is an as-built guide to the shipped `rig` CLI.
12Use current code and `rig ... --help` as ground truth if anything here ever conflicts with older planning docs.
13 
14Use the OpenRig builder guidance when changing OpenRig behavior, doctrine, or release posture.
15 
16 
17## Coordination trust boundary
18 
19Coordinate as openly as the trust boundary you actually control allows. Within a set of machines you
20own that already trust each other — they can reach each other's daemon URLs and the daemon itself
21requires no authentication — direct `rig send`, `rig capture`, and `rig queue` should just work.
22Don't invent bearer placeholders, allowlists, trust handshakes, or guest-reach restrictions the
23environment doesn't require.
24 
25Do not add or defend a restriction without naming the protected asset, the actual adversary, the
26blocked attack path, and the concrete consequence. Missing capability is not protection — repair the
27route, registration, runtime posture, or product defect directly. Arbitrary boundaries create
28constraint-induced circumvention: under goal pressure, agents build shadow transports, alternate
29credentials, and weaker proof instead of the direct authorized path. Keep only explicitly stated
30external or irreversible boundaries — public push / PR / publish, and destruction of canonical data.
31 
32## Coordination primitives — when to use which
33 
34Three coordination surfaces, used together for forward-momentum work. Internalize this
35on first read — it shapes every turn you take in a rig.
36 
37### `rig send <seat> "<text>"` — intra-pod direct messaging / nudges
38 
39Use when you need to ask a quick question or give a teammate context that does not
40carry handoff semantics. **NOT for durable work.** NOT for state that must survive
41across turns. The message lands in the target's pane; there is no durable queue
42record. The CLI prints `Sent to ...` (and `Verified: yes/no` with `--verify`); read
43the receipt and move on.
44 
45Example:
46 
47```bash
48rig send dev-reviewer@example-project "The import report is ready; the durable handoff names its evidence." --verify
49```
50 
51### `rig queue create --destination <Y> --tags <...> --body-file <path>` — durable work item
52 
53Use for any substantive work that must not fall through chat — slice handoffs,
54guard verdicts, QA results, full-tip reviews, multi-item batches. Survives agent
55restarts. Tracked in the daemon SQLite schema. Surfaces in Project / queue views
56+ in the destination seat's inbox. Tag with mission / slice / gate / checkpoint
57so future-you (and any peer) can find it.
58 
59Body discipline: substantive bodies go through **`--body-file <path>`** (or `-` for stdin) — the
60purpose-built, corruption-safe surface (it kills the backtick-shell-corruption class for multi-line
61bodies). Do NOT inline a backtick-heavy or multi-line body via `--body`: `rig queue create` body
62parsing breaks on unescaped backticks and rejects flag-like tokens.
63 
64Example:
65 
66```bash
67rig queue create \
68 --destination dev-reviewer@example-project \
69 --tags "mission:data-import,slice:import-report" \
70 --body-file /tmp/import-report-handoff.md
71```
72 
73### `rig queue handoff <qitem-id> --to <next> ...` — hot-potato handoff
74 
75Use when you have completed your turn on a qitem and the work moves to the next
76owner. **This is forward momentum.** The ball passes to the destination seat;
77chain-of-record (the prior qitem id) is preserved so the verdict trail is intact;
78tags carry the selected work context forward. Gate tags describe checks actually
79selected for that work; they do not require a fixed sequence of roles.
80 
81Example:
82 
83```bash
84rig queue handoff <qitem-id> \
85 --to dev-reviewer@example-project \
86 --tags "mission:data-import,slice:import-report" \
87 --body-file /tmp/import-report-handoff.md
88```
89 
90### §1b doctrine — turn ends by passing the ball
91 
92**A turn ends by passing the ball, never by going idle holding the slice waiting
93on a confirmation the selected process does not include.** Follow the current
94`mission-slice-sop`: proportional owner checks are the default; independent review
95runs when selected, at the authored work boundary. Role names do not add per-commit
96guard, QA, or orchestration gates. Do the authorized work, run its selected checks,
97and return the outcome through durable custody.
98 
99Valid pauses are only:
100 
101- A genuine blocker — file a blocked-state qitem against the blocking peer or
102 surface explicitly to orch.
103- A scope-or-architecture question that requires owner input and changes the
104 plan — surface to orch with the specific decision needed.
105 
106Implementing already-authorized work is neither of these. Proceed without
107phantom-gating on an imagined "next prompt" or "operator confirmation" that the
108process does not require.
109 
110### Anti-patterns
111 
112- Using `rig send` for durable work → use `rig queue create` instead. Sends do
113 not survive restarts and do not show up in queue/project views.
114- Idle-holding a slice for an imagined "next prompt" or "operator confirmation"
115 that the process does not require → pass the ball via `rig queue handoff` and
116 proceed to the next slice or stand by for the inbound verdict. See the §1b
117 doctrine above.
118- Inlining a multi-line / backtick-heavy body into `rig queue create --body`
119 → use `--body-file /tmp/<descriptive-name>.txt` (or `-` for stdin), the
120 corruption-safe surface. The body parser does not tolerate raw backticks or
121 flag-like tokens inline.
122 
123## Runtime-Gated Coordination Primitives
124 
125OpenRig v0.3.1 is published publicly as `@openrig/[email protected]` and GitHub Release
126`v0.3.1`. It includes the bundled PL-004 Coordination Primitive System: Phase A
127`rig stream` / `rig queue`, Phase B `rig project` / `rig view`, Phase C
128`rig watchdog`, and Phase D `rig workflow` / `workflow-keepalive`.
129 
130These are shipped product surfaces in v0.3.x, but they require a compatible
131v0.3.x daemon and matching SQLite schema at runtime — the installed package
132version is not automatically the version of the daemon serving you. If a
133coordination command behaves unexpectedly, confirm the running daemon with
134`rig whoami --json` and daemon status before assuming a product bug.
135 
136Default posture:
137 
138- Treat daemon `rig queue`, `rig stream`, `rig project`, `rig view`, `rig watchdog`, and
139 `rig workflow` as the product coordination surfaces when the active daemon is v0.2.0 or newer.
140- Use daemon-backed `rig queue` for durable routing. `update / show / list`
141 complement `create / handoff` for inspection and state changes; records in an
142 unrelated store are not evidence that this daemon owns the work.
143- If a daemon-backed coordination command fails, debug the command/runtime/schema edge directly;
144 do not assume the right workaround is to drop back to a config-layer primitive.
145- Do not perform daemon stop/start, production DB copy/mutation, release, publish, or other
146 consequence-boundary actions unless the operator/workstream has granted that specific gate.
147 
148## First-user workspace setup
149 
150When booting into a rig on a host where the workspace is unset, gap-ridden, or
151points at a stale layout, address that before substantive project work. The
152shipped surface is small + bounded — reach for the canonical commands rather
153than improvising.
154 
155### Detect workspace state at boot
156 
157Agent-actionable when the daemon is reachable.
158 
159```bash
160rig workspace validate --json
161rig workspace validate <path> --kind <user|project|knowledge|lab|delivery> --json
162```
163 
164`rig workspace validate` walks the workspace root and emits a structured
165frontmatter-gap report against the v0 contract. Exit code is non-zero when
166gaps exist (operators chain into hygiene fix loops). Default root is the
167current directory; pass a positional path to validate elsewhere. `--kind`
168scopes the contract to a specific workspace kind; omit for a kind-agnostic
169structural check.
170 
171If `rig workspace validate` reports a non-zero `gapCount` OR the workspace
172root is unset / unwritable, the workspace needs instantiation — see the next
173section.
174 
175### Instantiate the canonical workspace scaffold
176 
177Agent-actionable. The operation is additive and preserves existing files.
178 
179```bash
180rig config init-workspace
181rig config init-workspace --root <path>
182rig config init-workspace --dry-run --json
183```
184 
185`rig config init-workspace` scaffolds the canonical workspace layout at the
186configured `workspace.root` (default `~/.openrig/workspace`):
187 
188- `missions/` — release missions + slices
189- `exhaust/` — project-local coordination exhaust
190- `SPEC.md` — project intent
191- `project.yaml` — project catalog selections and mission root
192- `workspace.yaml` — project registration
193- `.gitignore` — local OpenRig state and exhaust exclusions
194 
195`--root <path>` targets a non-default root for this call; `--dry-run` reports
196what would be created without writing. `--force` is deprecated compatibility
197and still preserves existing files.
198 
199### Redirect the workspace root
200 
201Operator-gated when persistent. Agent-actionable when one-shot via env-var.
202 
203For a single command:
204 
205```bash
206OPENRIG_WORKSPACE_ROOT=<path> rig <command> ...
207```
208 
209For a persistent host-level redirect, the operator changes the config file or
210runs the setter:
211 
212```bash
213rig config set workspace.root <path>
214```
215 
216ConfigStore precedence: `OPENRIG_WORKSPACE_ROOT` env > config-file
217`workspace.root` > built-in default `~/.openrig/workspace`. The same
218precedence governs `OPENRIG_WORKSPACE_SPECS_ROOT` → `workspace.specs_root`
219(default `<workspace_root>/specs`).
220 
221Prefer the env-var form for one-shot redirects (transparent to operators);
222reserve `rig config set` for changes the operator owns.
223 
224### Build a workspace from scratch
225 
226Agent-actionable. Same surface as the canonical scaffold above; the
227`workspace.root` cascade handles non-existent host paths.
228 
229```bash
230rig config init-workspace --root /path/to/new/workspace
231```
232 
233The command additively creates any missing canonical entries and preserves
234every existing one; only a complete six-entry scaffold is a no-op. Run
235`rig workspace validate /path/to/new/workspace --json` after to confirm the
236contract holds.
237 
238### Create a workflow inside an existing workspace
239 
240Authoring is operator-or-agent; validation + instantiation are
241agent-actionable.
242 
243Workflow spec files live at:
244 
245```
246<workspace_root>/specs/workflows/<name>.yaml
247```
248 
249`<workspace_root>` resolves via the ConfigStore precedence named above.
250There is no `rig workflow create` verb in v0.3.x — the spec YAML is authored
251directly. Template by hand from the documented schema, or copy a built-in
252starter from `<openrig install>/dist/builtins/workflow-specs/` and adapt.
253Once written:
254 
255```bash
256rig workflow validate <workspace_root>/specs/workflows/<name>.yaml --json
257 
258rig workflow instantiate <workspace_root>/specs/workflows/<name>.yaml \
259 --root-objective "<one-line objective for the run>" \
260 --created-by <your-session>@<your-rig> \
261 --json
262```
263 
264Both `--root-objective <text>` and `--created-by <session>` are REQUIRED
265on `instantiate` — omitting either yields a Commander required-option
266error before the daemon is contacted. `--entry-owner <session>` is an
267optional override for the entry-step owner; default routing is per the
268workflow spec.
269 
270`validate` returns a structured ok/error report; `instantiate` creates a
271workflow instance + entry-step qitem. Inspect existing surface state with:
272 
273```bash
274rig workflow specs --json # list registered specs (built-in + operator-authored)
275rig workflow list --json # list active workflow instances
276rig workflow show <instanceId> --json # inspect one instance
277rig workflow project <instanceId> # ADVANCE an instance — projects the next-step packet
278rig workflow continue <instanceId> # read-only inspector of an instance (does NOT advance it)
279```
280 
281*(Surface note — the current `rig workflow` command group registers **13** subcommands: `validate`, `instantiate`, `project`, `list`, `specs`, `show`, `trace`, `continue`, `run`, `watch`, `route`, `resume`, `status`. There is still no `create` verb — the spec YAML is authored on disk. `project` is the advancing verb (it projects the next-step packet); `continue` is a read-only inspector, NOT an advance — do not conflate them. The 13-verb set and the project-vs-continue semantics are verified against current product main `d37a08ad` (`packages/cli/src/commands/workflow.ts`, 13 registered `.command(...)` entries; the earlier "6-verb surface / continue-advances" claim here was stale). Verify individual subcommand flags with `rig workflow --help`.)*
282 
283## Permission policy — pick one at setup (onboarding)
284 
285OpenRig sets only a **minimal usability floor** on your harness permissions and otherwise stays out of the way — then it ships **recommended policies you opt into**. It never bakes a permission policy for you. On install / onboarding this is a required choice, presented as a top-level pick:
286 
287- **POLICY MODE** — pick a built-in policy and have it applied:
288 - **Locked** — deny-by-default whitelist; untrusted rigs/work.
289 - **Standard** ⭐ (recommended) — routine development including push is allowed; PR creation, publication, merge/release, force-push and destructive actions ask.
290 - **Open** — allow-by-default; everything except explicitly-destructive, which ask.
291 
292 The built-in definitions ship as read-only policy spec files (Locked / Standard / Open); applying your pick is the job of the **`applying-a-permission-policy`** skill — it translates the chosen spec into your live harness config (Claude `settings.json` / Codex `config.toml`), interactively, showing the diff before it writes.
293- **YOLO MODE** — done with permissions, just want it to work: OpenRig boots every seat with the harness full-bypass launch flag. No config policy is applied (the bypass overrides it). This is a deterministic OpenRig setting, not a skill.
294- **No choice = the floor** — the minimal usability baseline (Claude `acceptEdits` / Codex workspace-only / Pi `--no-approve`), one consistent minimum, nothing more.
295 
296The floor and YOLO are **launch flags** OpenRig sets deterministically; the Locked / Standard / Open policies are **config-file** policies the skill applies (agent-driven, because harness config formats drift). A rig **carries** its chosen policy on its spec and boots with it — see Lifecycle → Bring a rig up. To (re)apply or change a policy, open **`applying-a-permission-policy`**.
297 
298## v0.3.x Starter, Workspace, And Plugin Surfaces
299 
300OpenRig v0.3.0 adds `rig agent-image`, `rig context-pack`, `rig workspace`, and
301`rig config init-workspace`. *(0.5.0: the `rig context-pack` alias is retired — the store + compose library is the single `rig context` noun; see "Context packs and paced delivery (0.5.0)".)* It also shifts fresh-user starter guidance toward
302`product-team` for human-directed work and `conveyor` for workflow-oriented
303work. Treat `demo` as legacy/test content unless a task specifically asks for
304the old demo spec.
305 
306OpenRig v0.3.1 adds public package/source surfaces for Plugin Primitive v0,
307Claude Auto-Compaction Policy, migration `040_workflow_specs_diagnostic`,
308Library Explorer finishing, Settings Destination Explorer, Dashboard/For You
309vellum refresh, storytelling adapter, and action outcome + inline error UX.
310 
311`rig plugin` is read-only at v0:
312 
313```bash
314rig plugin list
315rig plugin show <id>
316rig plugin used-by <id>
317rig plugin validate <path>
318```
319 
320There is no `rig plugin install` verb in v0.3.1. Plugin installation remains
321explicit operator copy/symlink to `$OPENRIG_HOME/plugins/<plugin-id>/`.
322 
323The v0.3.1 package introduced opt-in Claude auto-compaction policy through
324`policies.claude_compaction.*` ConfigStore keys. A package version alone says
325nothing about a running daemon's configuration; inspect the selected instance
326before relying on a policy or its default.
327 
328Compatibility checks:
329- `rig down` accepts a rig name or id. An ambiguous name matching more than one
330 active rig is refused with matching ids; use the intended id.
331- For queue/view JSON or limit differences, compare the installed command's help,
332 the running daemon version and the actual response. A wrapper mismatch is not
333 by itself a daemon-health failure, and historical workarounds are not current
334 behavior guarantees.
335- After a startup timeout, inspect status and logs before retrying; a timeout
336 does not establish whether the underlying operation completed.
337 
338## Recovery and Resilience (v0.3.4+)
339 
340v0.3.4's theme is Recovery + Resilience. The surfaces below compose into a
341single boot-to-running-rig path that survives crashes, hand-resumed sessions,
342profile-load drift, and partial workspace state without silently fudging
343status.
344 
345### `rig start` — recovery entrypoint
346 
347`rig start` is the top-level recovery sequencer. It does not invent recovery;
348it composes existing primitives (daemon start + kernel verify + per-rig
349restore) into one call.
350 
351```bash
352rig start # interactive: daemon + kernel + pick-and-restore
353rig start --last # headless: restore all rigs that were last running
354rig start --all # headless: restore all rigs with restore-usable snapshots
355rig start --rigs <name> [<name>...] # headless: restore only the named rigs
356rig start --json # JSON output for agents
357```
358 
359Framing: `rig start` is the RECOVERY entry point, not the getting-started
360hero. The fresh-user boot hero remains `rig up <starter>` (typically
361`rig up product-team`). Reach for `rig start` after a host reboot, daemon
362restart, or any "bring my rigs back" moment.
363 
364### `rig reconcile-session` — no-launch adopt of a hand-resumed session
365 
366When an operator has externally resumed an agent session (e.g. attached a
367shell, restarted a runtime by hand) and you want OpenRig to reconcile its
368lifecycle state without re-launching or sending input, use:
369 
370```bash
371rig reconcile-session <session>
372rig reconcile-session <session> --rig <rigId> --node <logicalId>
373rig reconcile-session <session> --no-launch
374rig reconcile-session <session> --json
375```
376 
377This is a no-launch, no-input adopt. `--rig`/`--node` disambiguate when the
378canonical session name does not uniquely resolve. `--no-launch` is accepted
379for explicitness (it is the only mode this command has).
380 
381### Five-term restore status vocabulary
382 
383The shipped restore vocabulary is intentionally honest. It surfaces in
384`rig up` / `rig restore` / `rig ps`. Use the term that fits — do not collapse
385to a generic "ok/failed":
386 
387- `resumed` — seat resumed from its original session/snapshot and is live.
388- `fresh-primed` — seat opted into `--fresh` and was freshly started.
389- `awaiting-decision` — zero-session honest state. There is no resumable
390 session AND no `--fresh` opt-in was given; the seat is waiting for an
391 operator decision. Previously fudged as `failed`; that was wrong — nothing
392 is broken, the system is asking for input.
393- `attention_required` — seat is in a state needing operator attention; not
394 a transport failure. Clear via `rig seat clear-attention` once the
395 attention has been resolved.
396- `failed` — the send transport or launch genuinely failed.
397 
398This replaces the prior collapsed model (the v0.3.3 four-term vocabulary, in
399which `rebuilt` was a term, is retired).
400 
401### `rig seat clear-attention` — audited reconcile of stuck attention
402 
403When a seat is stuck in `attention_required`, do NOT hand-edit SQLite to
404fake-clear the state. Use the evidence-gated, operator-attested, audited
405reconcile:
406 
407```bash
408rig seat clear-attention <session>
409rig seat clear-attention <session> --reason "operator attested: the operator re-authed, confirmed live"
410rig seat clear-attention <session> --json
411```
412 
413`--reason <text>` can acknowledge startup-status and subset-restore attention.
414It does not bypass full-restore continuity checks or an active pane-identity
415mismatch/missing-pane check; those run first. Successful identity re-verification
416can also clear coexisting startup or subset-restore attention. If neither earlier
417path clears attention, omitting `--reason` requires activity or send evidence.
418Startup and restore clears write their corresponding audit events; an identity-only
419clear updates the current binding and identity verdict without a clear event.
420Acknowledgment or responsiveness alone does not prove that the original
421conversation resumed.
422 
423A 422 response names the uncleared class and its failed check. If the recorded
424native token needs correction and you know the actual token, use
425`rig seat set-resume-token <session> --token-stdin --reason <explanation>`, then
426rerun `rig seat clear-attention <session>` to check the live evidence. The token
427update records operator provenance; it does not itself prove continuity.
428Stopping/relaunching a working seat is a separate disruptive operation, not a
429required cleanup or proof of resumed lineage.
430 
431### Periodic snapshots — crash-insurance floor
432 
433The daemon ships a periodic-snapshot scheduler. It runs independently of
434teardown events and provides the crash-insurance floor that prior
435event-only/teardown-only snapshots could not provide on hard crashes.
436 
437Config keys (SettingsStore):
438- `snapshots.periodic.enabled` — default `true`
439- `snapshots.periodic.interval_seconds` — default `300`
440- `snapshots.periodic.retention_keep` — default `10`
441 
442Newest-wins semantics: when both `auto-periodic` and `auto-pre-down`
443snapshots exist for a rig, the freshest of the two is selected for restore.
444A newer `auto-periodic` beats a stale `auto-pre-down` (the crash fix); a
445genuinely-fresher `auto-pre-down` still wins on graceful cycles. Manual
446snapshots are handled separately. See
447`packages/daemon/src/domain/snapshot-repository.ts` for the ordering rule.
448 
449The last-snapshot floor surfaces in `rig ps` / status output so an operator
450can see at a glance how recent the crash-insurance floor is.
451 
452### Codex profile-v2 preflight
453 
454Profile-bearing launch/restore surfaces run a profile-load preflight. When
455profile-load issues are detected, the failure is honest and actionable
456(named error + remediation pointer) instead of a silent partial launch that
457would later look like an attention_required seat with no explanation.
458 
459### cmux launch readiness
460 
461cmux-backed launches no longer produce silent partial workspace state. When
462parts of the workspace are missing, the launch surfaces partial state
463honestly and the UI exposes a one-click open-missing affordance.
464 
465(See also `## Token-Efficient Defaults (v0.4.0+)` below for the compact-by-default read-command surface that lands in 0.4.0.)
466 
467## Token-Efficient Defaults (v0.4.0+)
468 
469v0.4.0 flips the five most frequently invoked read-commands from firehose-by-default to compact-by-default, and `rig queue list` adopts the docker / kubectl read-command grammar. **All defaults preserve breadth and capability — the firehose is one explicit flag away.**
470 
471### `rig ps` — scope-aware: bare `rig ps` = ALL rigs; `--nodes` = your rig only
472 
473```bash
474rig ps # ALL active rigs on the host, one compact row each — RUN FIRST to know the world
475rig ps --rig <name> # one named rig's summary
476rig ps --nodes --rig <name> # per-node (seat) detail for a NAMED rig — the normal drill-in
477rig ps --nodes # per-node detail — CURRENT rig ONLY (deliberately narrow; NOT the whole host)
478rig ps --json # compact JSON (default = a bare array of ALL non-archived rigs)
479rig ps --nodes -A # cross-rig node inventory (was v0.3.4 default)
480rig ps --nodes --full # complete record (the v0.3.4 per-node default shape; resumeToken VALUE retained here for downstream consumers)
481rig ps --nodes --session <sess> # narrow to one canonical session
482rig ps --active # opt-in active-state filter (does NOT change the all-states default — ps surfaces topology/readiness, where stopped/recoverable/attention IS the actionable signal)
483```
484 
485**v0.4.0 breadth + projection changes**:
486- **Rig-level `rig ps` lists ALL active rigs** (one row each — the cheap "know the world" view). The **`--nodes` (per-seat) view defaults to your CURRENT rig only** (from `OPENRIG_SESSION_NAME`'s `@<rig>` suffix); `--rig <name>` picks another rig, `-A` widens `--nodes` to the whole host (expensive — prefer `--fields`/`--limit`).
487- **Per-node TL;DR projection (compact) is the default**; `--full` returns the raw byte-equivalent passthrough. Daemon-side `recoveryGuidance` relocated to a guidance-by-reference map (no longer duplicated per-node) — even `--full` benefits.
488- **All-states stays default** (different from `rig queue list` which defaults to active-only) — for `ps`, non-running states ARE often the actionable signal.
489- **Resume-token security**: `--full` JSON emits `resumeTokenPresent` (boolean) — the actual `resumeToken` value also remains in `--full` for downstream consumers that legitimately need it, but the compact default never carries it (an orch glance never accidentally leaks token material).
490 
491**⚠ SCOPE-AWARENESS — the one that bites:** `rig ps --nodes` (and `--nodes --json`) show ONLY your current rig's seats, by design — the narrow default protects your context window. **Narrow output is not the whole world.** Never conclude "my rig is the only rig on the host" from a `--nodes` read — run bare `rig ps` FIRST (cheap; it lists every rig), then `rig ps --nodes --rig <name>` for the one you need. (`-A` widens to the whole-host node view; choose it when that breadth is needed.)
492 
493### `rig whoami` — compact-by-default + `--full` (`--verbose` alias)
494 
495```bash
496rig whoami # compact: identity + peers names + edges + transcript path
497rig whoami --json # compact JSON
498rig whoami --full # complete payload (v0.3.4 default shape)
499rig whoami --verbose # alias of --full
500```
501 
502The first command every agent runs on boot AND every compaction-restore. The compact default keeps identity-recovery essentials (`identity`, `peers` names + sessionNames, `edges` directional `kind` + `to.sessionName`, `transcriptPath`). `--full` adds `contextUsage`, `commands`, `peersNote`, `runtimeContext`. The compact-default is an ALLOWLIST projection — future payload fields default to `--full` and cannot silently re-bloat the every-boot path.
503 
504### `rig queue list` — active-frontier + docker/kubectl grammar
505 
506```bash
507rig queue list # active, compact, CURRENT-rig (docker-ps default)
508rig queue list -a # + closed/done history within current breadth (docker -a)
509rig queue list -A # cross-rig breadth (kubectl -A)
510rig queue list --full # add body + chain-of-record + transition history
511rig queue list -o json # compact JSON (token-safe, machine-parseable)
512rig queue list --full -o json # full JSON
513rig queue list --mine # just the caller's items
514rig queue list --destination <s> # destined to <s>
515rig queue list --source <s> # sourced by <s>
516rig queue show <qitemId> # bounded single-item body preview
517rig queue show <qitemId> --full # complete body and chain fields
518```
519 
520Four orthogonal axes (scope × history × field-breadth × encoding), all composable. **STOP using bare `rig queue list` as the cross-rig firehose.** Default is now active + compact + current-rig. Cross-rig history with full bodies is opt-in via `-A -a --full`; request only the breadth and fields needed for the question.
521 
522### `rig restore-check` — summary + not-ready-only default + `--full`
523 
524```bash
525rig restore-check # summary counts + not-ready seats (with reasons) only
526rig restore-check --full # complete per-seat readiness across the fleet (v0.3.4 default)
527rig restore-check --rig <name> # narrow
528rig restore-check --as <session> # narrow to one seat
529```
530 
531The summary retains not-ready seats and their reasons; `--full` adds ready-seat detail when needed. Scope the query before expanding its payload.
532 
533### `rig context` — context-window usage viewer (0.4.x; REMOVED in 0.5.0)
534 
535```bash
536rig context # compact summary (0.4.x only)
537rig context --full # complete current payload
538rig context --rig <name> # narrow to one rig
539rig context --threshold 80 # filter to seats at/above 80%
540```
541 
542Lower leverage than the others; keeps the read-command surface compact-by-default after the 0.4.0 upgrade. **⚠ 0.5.0: this usage viewer is removed entirely and the `rig context` name is reassigned to the context library (store + compose) — see "Context packs and paced delivery (0.5.0)" below. On a 0.5.0 host, bare `rig context` is the library, not this viewer.**
543 
544### Keep routine reads bounded
545 
546Choose scope, active/history breadth and fields before expanding a result. A
547status question usually needs identifiers, owner, state and reason; open the full
548body or artifact when it is relevant. Preserve full evidence on disk instead of
549repeatedly loading unchanged output. Compact defaults reduce reading cost; they
550do not remove the full-detail path or prove that nothing exists outside the scope.
551 
552### `rig scope mission|slice progress` — deterministic progress updates
553 
554```bash
555rig scope mission progress <mission> --add "<line>" # append a progress line; --set replaces; --section <heading> (default Rail); --status active|done|blocked
556rig scope slice progress <slice-path> --add "<line>" # same flags: --add / --set, --section <heading>, --status active|done|blocked
557```
558 
559Replaces hand-editing `PROGRESS.md` with markdown. Writes the canonical structure the OpenRig PROGRESS UI page reads. `rig scope mission create` + `rig scope slice create` now scaffold `PROGRESS.md` automatically.
560 
561### `rig scope mission|slice stage / verified / repair` — deterministic maturity vocabulary
562 
563```bash
564rig scope slice stage <slice> <new-stage> # wip / provisional / established / canonical / superseded / retired
565rig scope slice stage <slice> superseded --successor <id> # superseded REQUIRES --successor (rejected otherwise)
566rig scope mission stage <mission> <new-stage> # same enum + rules at mission tier
567 
568rig scope slice verified <slice> --against "<source>" # stamp `verified: <today> against <source>`; --against MANDATORY
569rig scope mission verified <mission> --against "<source>"
570 
571rig scope slice repair <slice> # idempotent repair: backfill PROGRESS.md, conform id/stage/verified, repair ghosts
572rig scope mission repair <mission> # mission-tier idempotent repair
573 
574rig scope slice show <slice> # derives read-time effective-reliability from (stage × verified)
575 # — stale-`verified` `canonical` reported as effectively `provisional`
576```
577 
578Composes with the `progress` command + scaffolding to update scope IDs and maturity vocabulary through `rig scope`. Agents update `stage` / `verified` / `id` through commands rather than hand-editing markdown and drifting. The `--against` MANDATORY rule on `verified` is the anti-stale keystone: bare timestamps are rejected because a bare timestamp is exactly what lets stale trackers lie while looking fresh. **STOP hand-editing the `stage` / `verified` / `id` fields in scope frontmatter; use the new verbs.** Existing missions / slices with `id:null` ghosts or missing `PROGRESS.md` are repaired idempotently via `repair`.
579 
580### `rig skill audit` — skill cascade provenance
581 
582```bash
583rig skill audit # human report of findings
584rig skill audit --json # structured findings
585rig skill audit --severity warn # stale + mirror-drift only
586rig skill audit --rig <name> # narrow to embedded skill copies for one rig
587```
588 
589Read-only audit of the skill cascade. Detects `missing` / `stale` / `self-referential` / `invalid-date` / `mirror-drift` across the canonical skills workspace → product mirror → hub cwd → installed plugin chain. Findings route back to the lifecycle for shaped propagation runs. **False-green prevention**: when audit evidence is unavailable, the CLI emits `unable-to-audit` with exit code `2` rather than reporting `clean`.
590 
591### `rig seat clear-attention` — extended to derived projection staleness
592 
593`clear-attention` also reaches restore-derived attention even when
594`startupStatus=ready` and `sessionStatus=running`. Full-restore attention requires
595the restore reconciler's exact native-token and usable-pane checks; `--reason`
596cannot replace them. Subset-restore attention can reach the attestation path
597when no active pane-identity class takes precedence. That path records
598`operator_recovered` with `runtimeCwdVerified:false`; it is an acknowledgment,
599not proof of resumed lineage. Without an explicit stored continuity outcome,
600inventory leaves continuity null (`unverified` in `rig seat status`) unless the
601same restore attempt has a matching receipt and reconciliation with strict
602native-token and usable-pane proof. Explicit stored outcomes remain historical
603facts; acknowledgment or responsiveness alone cannot infer `resumed`.
604 
605### Native Codex session id capture
606 
607Codex seats can now record the real native session id from the Codex
608`SessionStart` hook instead of relying on scrape-shaped identity. Corroborate the id across the current hook payload, provider history and
609managed record before relying on it. A release introducing native capture does
610not prove that every existing seat uses it; retain any unavailable or conflicting
611identity evidence explicitly.
612 
613### Codex resume preserves approval posture
614 
615Resuming a Codex seat preserves the launching seat's approval/sandbox posture
616and profile flags. Product-emitted resume commands carry the posture flags
617instead of silently falling back to implicit-deny or an unrelated profile.
618 
619Do not "fix" a resumed Codex seat by relaunching it with broader approvals
620unless the operator explicitly grants a bounded window. Verify the seat's
621active posture first, and preserve it when composing recovery commands.
622 
623### `rig seat set-resume-token --token-stdin`
624 
625```bash
626printf '%s' "$RESUME_TOKEN" | rig seat set-resume-token <session> --token-stdin
627```
628 
629Use this command to set or restore a seat resume token. It replaces direct
630SQLite edits, rejects unauthorized writes and bad/null token false-ready paths,
631records redacted audit/provenance, and keeps token material out of command
632arguments, stdout, logs, and normal status rows. Use stdin, not an inline flag,
633when passing token material.
634 
635## Core Loop
636 
637Most work in OpenRig reduces to this loop:
638- recover identity: `rig whoami` (compact default; add `--full` only when you need the heavy payload)
639- inspect inventory: `rig ps --nodes` (compact default; add `--full` only when you need the firehose)
640- read context: `rig transcript ...`, `rig ask ...`, `rig chatroom history ...`
641- act: `rig send`, `rig capture`, `rig broadcast`, lifecycle commands
642 
643## Agent-Managed Apps
644 
645An agent-managed app is a deployable OpenRig unit made of:
646- the software or service
647- one specialist agent dedicated to that software
648 
649Treat the specialist as the domain delegate for that app.
650The current canonical example is:
651- rig: `secrets-manager`
652- pod: `vault`
653- member: `specialist`
654- logical ID: `vault.specialist`
655- session: `vault-specialist@secrets-manager`
656 
657Typical operator loop:
658 
659```bash
660rig up secrets-manager --cwd /path/to/project
661rig ps --nodes --json
662rig send vault-specialist@secrets-manager "Check Vault health and report back." --verify
663rig env status secrets-manager
664rig env logs secrets-manager
665```
666 
667Cross-rig communication is valid when the target session resolves uniquely.
668Example:
669 
670```bash
671rig send vault-specialist@secrets-manager "Read secret/data/dogfood and report the value." --verify
672```
673 
674Use the specialist instead of teaching every peer the same app-specific toolchain.
675For Vault, ask `vault.specialist` to do secrets-domain work rather than improvising curl or Vault CLI usage in unrelated agents.
676 
677## Identity and Recovery
678 
679Start here after launch, compaction, or confusion:
680 
681```bash
682rig whoami --json
683```
684 
685What it gives you today:
686- identity: rig, logical ID, pod/member, session name, runtime
687- peers and directional edges
688- transcript info
689- `contextUsage` when available
690 
691Flags:
692```bash
693rig whoami --session <name>
694rig whoami --node-id <id>
695```
696 
697If the daemon is unreachable but identity can still be inferred, `--json` may return a partial result instead of crashing.
698 
699`WhoamiResult` (v0.3.3+) carries a required `peersNote` field with three pointers
700the agent can use to navigate the rest of the rig from a cold start. The
701human-formatted CLI output preserves the literal `Peers:` line prefix verbatim
702(parser/test compatibility) and surfaces the clarifier in-band beneath it; the
703JSON form exposes `peersNote` directly for programmatic consumers.
704 
705## Inventory and Monitoring
706 
707```bash
708rig ps # ALL active rigs on the host, one compact row each (run FIRST to know the world)
709rig ps --nodes # compact node inventory (current rig)
710rig ps -A # all-rigs breadth (was the pre-0.4.0 default)
711rig ps --nodes --full # complete per-node record (the firehose — opt-in)
712rig ps --nodes --json # compact JSON node inventory (add --full for the full record)
713```
714 
715**v0.4.0 flipped these to compact-by-default — see the `rig ps` compact-defaults section above; STOP using bare `rig ps --nodes --json` as a fleet-wide firehose (scope and detail are separate choices).** The compact `rig ps --nodes` node inventory (add `--full` only when you need the complete record, `-A` for cross-rig breadth) carries, per node:
716- session name
717- runtime
718- session/startup status
719- restore outcome (compact: `resumeTokenPresent` boolean; the token VALUE is in `--full`)
720- attach/resume commands
721- latest error
722 
723Other health surfaces:
724 
725```bash
726rig status
727rig daemon status
728rig config
729rig preflight
730rig doctor
731rig env status <rig>
732rig env logs <rig>
733rig env down <rig>
734```
735 
736### Bounded agent self-scout
737 
738Use the typed health projection before reading raw coordination history. The
739default query is the current seat; widen deliberately when the evidence points
740beyond it:
741 
742```bash
743rig health --json
744rig health --rig <rig-id> --json
745rig health --instance --json
746rig health explain <finding-id> --json
747```
748 
749Follow the returned stable finding ID and `suggestedInspection`. Use `explain`
750when the summary matters: it returns the same canonical record with its bounded
751window, freshness, literal detector rule, evidence references, and next
752inspection. Human output projects those same fields; it does not calculate a
753second score.
754 
755An empty result means only that no records matched the bounded query. It is
756**not a healthy assertion**. Stale, unavailable, contradictory, and
757indeterminate evidence stays explicit. Never read raw SQLite for a self-scout,
758and never turn a finding into an acknowledgement, notification, queue row, or
759remediation automatically: `rig health` is strictly read-only.
760 
761## Transcript and Communication
762 
763### Transcript access
764 
765```bash
766rig transcript <session> --tail 100
767rig transcript <session> --grep "pattern"
768rig transcript <session> --json
769```
770 
771### Send to one session
772 
773```bash
774rig send <session> "message"
775rig send <session> "message" --verify
776rig send <session> "message" --wait-for-idle <seconds>
777rig send <session> "message" --raw
778rig send <session> "message" --dangerously-interact --reason "<why>"
779rig send <session> "message" --host <id>
780rig send <session> "message" --json
781```
782 
783**The send-guard (v0.4.0) — the default is SAFE.** A default `rig send` is guarded: it will NOT submit into an interactive prompt / permission block on the target pane. Flags:
784- `--verify` — delivery evidence.
785- `--force` — **a back-compat no-op on the send DECISION**: it never bypasses the interactive-prompt/permission guard and never changes whether a message is delivered (a mid-task/busy pane already sends-with-advisory by default). *(It does NOT "bypass activity-risk checks" — that earlier teaching is retired.)* It is **not fully inert**, though — it is still parsed solely to be **rejected in combination with `--wait-for-idle`**: `rig send … --force --wait-for-idle <n>` prints `--wait-for-idle cannot be combined with --force`, exits 1, and sends nothing. So do not read "no-op" as "`--force --wait-for-idle` is harmless"; that pairing errors. *(Verified against current product main `d37a08ad`: the guard-bypass no-op is declared at `send.ts` and confirmed by runtime capture — a plain `--force` send delivers through the ordinary path; the `--wait-for-idle` rejection is enforced at `send.ts`, `routes/transport.ts`, and `session-transport.ts`, and confirmed by runtime capture — exit 1, nothing sent.)*
786- `--wait-for-idle <seconds>` — wait until the target is explicitly idle before sending. **Cannot be combined with `--force`** (that pairing is rejected: exit 1, nothing sent).
787- `--raw` — send exact text/keystrokes without the From/To messaging envelope (still guarded against interactive prompts).
788- `--dangerously-interact --reason "<why>"` — the ONLY override of the prompt/permission guard: deliberately drive an interactive prompt/permission block (implies `--raw`, requires `--reason`, audit-logged).
789- `--host <id>` — send on a remote host declared in `~/.openrig/hosts.yaml` (ssh hosts shell out; http hosts go CLI-direct to the remote daemon).
790- `--from <session>` — deprecated and ignored; it does not select the sender. Sender identity comes from the current seat and transport provenance; cross-host envelopes use the durable local origin, not the supplied flag or a relay identity.
791- `--context <ref>` **(0.5.0)** — attach a composed context pack/piece by ref (see "Context packs and paced delivery"). Small piece → `send --context`; a real pack → `rig walk`. The noun `rig context` composes the ref; the verb delivers it.
792 
793> **Durable work goes to the QUEUE, not `send`.** `rig send` is an *ephemeral* message to a pane — it can be missed, and its delivery status is pane-render, not receipt. If you are **assigning work, or the message is important enough that losing it would be a real bummer**, use `rig queue` (below): it's durable, owned, tracked, and survives compaction and restart. Reach for `send` for a quick conversational nudge; reach for the **queue** for anything that must not get lost. Do not default to `send` for work — that's the most common mistake.
794 
795As of v0.3.3, content beginning with `--` or `-` is safe:
796`rig send <session> "content starting with -- or - is now safe"` delivers
797literally. The daemon's `send_text` path carries an explicit `--`
798end-of-options sentinel so tmux no longer parses dash-prefixed content
799as its own flags. The CLI surface itself is unchanged. For multi-line
800or large bodies handed off as durable work, use
801`rig queue create --body-file <path>` (`-` for stdin) — that's the
802queue-side surface, not `rig send`.
803 
804`--verify` delivery outcomes (v0.3.3+):
805- `delivered` — text + Enter both succeeded and capture re-confirmed the body landed.
806- `rendered-unconfirmed` — text + Enter both succeeded but capture could not re-confirm the body (TUI redraw race or scroll). The message landed; the post-send re-check could not prove it. Treat as landed-but-unconfirmable, NOT failure.
807- `failed` — the send transport itself failed.
808 
809The legacy `Verified: yes/no` line is preserved verbatim (parser/test
810compatibility). A new `Delivery: <outcome>` line carries the named outcome
811above.
812 
813Observed operator nuance for `--verify`:
814- `Sent to ...` + `Verified: yes` (`Delivery: delivered`) = strong positive delivery evidence.
815- `Sent to ...` + `Verified: no` + `Delivery: rendered-unconfirmed` = the message landed; capture could not re-prove it. Don't blind-retry — check reply / `rig capture` / transcript before sending again.
816- `Sent to ...` + `Verified: no` + `Delivery: failed` = send-transport failure.
817- no `Sent to ...` line or a hard error = send failure.
818 
819When you get `Verified: no`, do not immediately retry blindly. First check one of:
820- a direct reply from the target
821- `rig capture <session>`
822- transcript evidence
823- queue/outbox state if the message asked for a durable handoff
824 
825### Capture terminal output
826 
827```bash
828rig capture <session>
829rig capture <session> --lines 50
830rig capture --rig <name>
831rig capture --pod <name> --rig <name>
832rig capture --rig <name> --json
833```
834 
835### Broadcast
836 
837```bash
838rig broadcast --rig <name> "message"
839rig broadcast --pod <name> "message"
840rig broadcast "message"
841rig broadcast --rig <name> "message" --json
842```
843 
844**Use `rig broadcast` sparingly — prefer `rig send` fan-out.** Without `--rig` or `--pod`, broadcast targets
845**every running session across ALL rigs** (plus attached external_cli nodes) — the fastest way to cause a
846broadcast storm. Reserve `rig broadcast` for small rigs or a genuine all-hands emergency. For the normal
847"message several seats at once" case, use `rig send`, which scopes the fan-out and keeps the messaging
848envelope, the delivery/interactive-prompt guards, and per-recipient results:
849 
850```bash
851rig send --to dev-impl@my-rig,dev-qa@my-rig "message to specific seats" # named seats (comma-list or repeat --to)
852rig send --pod dev "message to one pod" # scoped fan-out
853rig send --rig my-rig "message to one rig" # scoped fan-out
854```
855 
856### Chatroom
857 
858```bash
859rig chatroom send <rig> <message> [--sender <name>]
860rig chatroom history <rig> [--topic <name>] [--after <id>] [--since <ts>] [--sender <name>] [--limit <n>] [--json]
861rig chatroom wait <rig> [--after <id>] [--topic <name>] [--sender <name>] [--timeout <seconds>] [--json]
862rig chatroom clear <rig>
863rig chatroom topic <rig> <topic-name> [--body <text>] [--sender <name>]
864rig chatroom watch <rig> [--tmux]
865```
866 
867**Key commands:**
868- `send` — post a message
869- `history` — retrieve with composable filters (sender, since, after, topic)
870- `wait` — block until new matching messages arrive (polls history, times out honestly)
871- `clear` — delete all messages for the rig (destructive, rig-scoped)
872 
873## See something, say something
874 
875OpenRig has an **observation stream** — the fleet's zero-friction institutional memory, mined for
876real product improvements. When you notice **anything worth externalizing**, say something and keep
877working:
878 
879- a **bug**, a rough edge, or something that needs fixing
880- a **feature idea** or an improvement
881- something that **worked really well** — a technique, tool, or pattern worth spreading
882- an **observation**, positive or negative feedback, or something genuinely cool, productive, or funny
883 
884```bash
885rig stream emit --source <your-session> --body "what you noticed"
886```
887 
888That's the whole reflex. **Don't** decide where it goes or who it's for — the intake router triages
889(destination/type/urgency/tags are optional hints — `--hint-type review|handoff|idea`,
890`--hint-urgency routine|urgent|critical`, `--hint-tags` — never required). One command, then carry
891on; the value is the habit, not the polish. **Don't overdo it, either:** stream real signal, not
892narration — a good observation beats ten noisy ones. It's a passing thought you externalize, not a chore.
893- `topic` — set a topic marker
894- `watch` — SSE or tmux-based live stream
895 
896**Roundtable protocol:**
8971. Inspect old room: `rig chatroom history my-rig --limit 5`
8982. Save if needed: `rig chatroom history my-rig --json > /tmp/old-room.json`
8993. Clear if needed: `rig chatroom clear my-rig`
9004. Set topic: `rig chatroom topic my-rig "ROUND START"`
9015. Post: `rig chatroom send my-rig "position..." --sender <session>`
9026. Monitor: `rig chatroom wait my-rig --timeout 120`
9037. Close: `rig chatroom topic my-rig "ROUND CLOSED"`
904 
905### `rig ask`
906 
907```bash
908rig ask <rig> "question"
909rig ask <rig> "question" --json
910```
911 
912Current shipped behavior:
913- queries the daemon for evidence
914- returns rig summary
915- returns transcript excerpts
916- may return chat excerpts
917- returns insufficiency state and optional guidance
918 
919This is an evidence/context command. It is not a hidden second-LLM call.
920 
921### `rig auth` — agent auth-profile management (v0.4.1, product-native)
922 
923Product-native switching of agent auth profiles from the CLI. The runtime is a **flag** (`--runtime <codex>`), not a command noun — never `rig codex-auth`.
924 
925```bash
926rig auth status --runtime codex # presence / mode / parseability / login-state (never prints token contents)
927rig auth list --runtime codex # saved profiles
928rig auth save <profile> --runtime codex # snapshot the auth FILE (mode-guarded), never echoes contents
929rig auth switch <profile> --runtime codex
930rig auth validate <profile> --runtime codex
931rig auth seats … --runtime codex # seat -> profile registry (metadata only; NOT proof of a live account)
932```
933 
934**Hard secret boundary:** no token value is ever printed, logged, queued, streamed, or committed; status/validate report presence/mode/login-state only; seat labels are metadata, not live-account proof. MVP is `--runtime codex`; other runtimes use the same surface with a different `--runtime`, never a parallel command.
935 
936## Context packs and paced delivery (0.5.0)
937 
938**Compose context once, hand it to a seat cleanly.** A library primitive plus a set of delivery flags. The rule that keeps the grammar coherent — internalize this one: **the noun stores and composes; the verbs deliver.** `rig context` never sends anything; delivery is only ever `rig send` / `rig broadcast` / `rig walk` / `rig queue`.
939 
940> Version note: this describes the library surface introduced in 0.5.0. Check the installed command and serving daemon before relying on it. In 0.4.x, bare `rig context` was a context-window usage viewer (above); in 0.5.0 that viewer is removed and the `rig context` name belongs to the library here.
941 
942### `rig context` — the store + compose library (never delivers)
943 
944Manage and compose context (any text/markdown) into reusable **packs**. Every piece and pack has a stable, **path-like ref** — you address context the way you address files (`skills/claude-compaction-restore`, `reference/rig-spec.md`).
945 
946```bash
947rig context list # what's in the library
948rig context show <ref> # read a piece or pack
949rig context add <source-dir> # install an existing pack directory into the store
950rig context preview <ref> # assemble + show a pack WITHOUT delivering it
951rig context sync # re-walk discovery roots, refresh the library index
952rig context rm <ref>
953rig context compose --out packs/<ref> --from <fileA> <fileB> ... # ordered pieces -> a durable pack
954```
955 
956- Sensible default store location; works unconfigured, can be pointed elsewhere later (another folder now; a machine or URL later).
957- `compose` (v1) is honest ordered concatenation of named files into a durable pack with a ref — "here's a file, read a file."
958- **No delivery verb lives on the noun.** To get a pack to a seat, hand its ref to a delivery verb below.
959 
960### `rig walk` — paced delivery of a sequence
961 
962```bash
963rig walk <seat> --through <ref | file ...> --pace 10s
964```
965 
966Walk a seat *through* a pack: each piece is sent into the pane, spaced by `--pace`, so the agent processes between sends (the human paste → wait → paste rhythm). Its own top-level verb, push-direction — the walker leads and does not wait for replies; the spacing does the work. Reach for `walk` on onboarding, repriming, or a fleet update — anything absorbed in order rather than all at once.
967 
968### The delivery grammar — send a ref, walk a pack, or attach it to a qitem
969 
970| When | Verb |
971|---|---|
972| One thing, now | `rig send <seat> --context <ref>` |
973| One thing, everyone | `rig broadcast --rig <rig> --context <ref>` |
974| A sequence, absorbed | `rig walk <seat> --through <ref> --pace 10s` |
975| Context riding a durable handoff | `rig queue create … --body-context <ref>` |
976 
977- **Rule of thumb:** small piece → `send --context`; real pack → `walk`. An oversized `send --context` warns "this is walk-sized" instead of blasting the pane.
978- **`--body-context` snapshot rule:** a qitem built from a ref stores the **resolved content** in its body **plus the ref for provenance** — the handoff carries what was actually sent, and a later library edit never silently rewrites a past handoff's history.
979- **The orchestrator habit — assign work *with* its context attached:**
980 ```bash
981 rig context compose --out packs/qitem-brief --from <brief-file> <proof-file>
982 rig queue create --destination dev-driver@build --body-context packs/qitem-brief --summary "…"
983 ```
984 Replace `<brief-file>` and `<proof-file>` with your existing local files. The curated context rides the durable handoff, survives compaction, and is auditable.
985 
986**Skills tier vs context tier:** skills are the HOT tier (ambient, finite, always-visible front-matter); context packs are the COLD tier (unbounded, fetched on instruction — "read `rig context get onboarding-width`"). Don't overrun the skill layer by using skills as context packs — that's what this primitive is for.
987 
988## Lifecycle
989 
990### Bring a rig up
991 
992```bash
993rig up <source>
994rig up <source> --plan
995rig up <source> --yes
996rig up <source> --cwd /path/to/project
997rig up <source> --existing
998rig up <source> --fresh <seat...>
999rig up <source> --json
1000```
1001 
1002`<source>` can be:
1003- a rig spec path
1004- a `.rigbundle` path
1005- a bare name
1006 
1007Bare names are special:
1008- if they match a library spec, `rig up` launches from the spec library
1009- if they do not match a library spec, `rig up` treats the name as an existing-rig restore/power-on target
1010- if both exist, `rig up` fails loudly on ambiguity
1011 
1012Resume-original-by-default (v0.3.4+):
1013- For an existing rig, `rig up <name>` resumes each seat from its original session/snapshot by default (operation A). Seats that successfully resume report `resumed`.
1014- `--fresh <seat...>` is the per-seat opt-in for deliberate fresh-prime (operation B). Named seats are reported as `fresh-primed`.
1015- `--existing` forces existing-rig restore semantics on a bare name, bypassing library-spec resolution. Useful when a rig name collides with a library spec name.
1016- Example: `rig up --existing my-rig --fresh dev-impl` — resume everything in `my-rig` except `dev-impl`, which is freshly primed.
1017- Seats with no resumable session land in `awaiting-decision` (zero-session honest state, NOT `failed`); see the five-term restore vocabulary in "Recovery and Resilience" below.
1018 
1019`--plan` (v0.3.4+):
1020- `rig up <source> --plan` produces a read-only restore plan preview. It surfaces per-seat resume/fresh-prime intent and any awaiting-decision seats without mutating state. Honest async timeout: a stuck plan reports the timeout rather than hanging silently.
1021 
1022Current behavior notes:
1023- `--target <root>` is only for `.rigbundle` / package installation. It does not change agent cwd.
1024- `rig up --cwd` is shipped. `rig up --cwd <path>` sends a per-run cwd override for all members in that launch.
1025- `local:` `agent_ref` values resolve relative to the rig spec directory, not your shell cwd.
1026- if you copy a built-in spec elsewhere, keep its `agents/` tree beside the YAML or rewrite those refs to `path:/absolute/path`
1027- `rig specs add <directory>` installs a full spec tree when the directory contains `rig.yaml` or `agent.yaml`.
1028- **Permission policy:** a rig carries a permission policy and boots with it (never changed on the fly). Default if none set = the minimum floor (Claude `acceptEdits` / Codex workspace-only / Pi `--no-approve`); otherwise a chosen built-in (Locked / Standard / Open) or deliberately none. When you spec or bring up a rig, decide its policy — apply it via `applying-a-permission-policy` (see also the onboarding menu, "Permission policy — pick one at setup").
1029 
1030Legacy/spec-specific surfaces still ship too:
1031 
1032```bash
1033rig bootstrap <spec> [--plan] [--yes] [--json]
1034rig requirements <spec> [--json]
1035```
1036 
1037### Tear a rig down
1038 
1039```bash
1040rig down <rig> # <rig> = rig name or id (active rig)
1041rig down <rig> --snapshot
1042rig down <rig> --delete
1043rig down <rig> --force
1044rig down <rig> --json
1045```
1046 
1047If `--snapshot` succeeds, human output includes the restore hint.
1048 
1049### Archive a stopped rig (recoverable) — v0.3.3+
1050 
1051```bash
1052rig archive <rig> [--json]
1053rig unarchive <rig> [--json]
1054```
1055 
1056`rig archive` marks a stopped rig as archived (sets `archivedAt`) without
1057discarding it. The rig is preserved for later restoration via `rig unarchive`,
1058which clears `archivedAt` and returns the rig to the active set.
1059 
1060Archive vs delete:
1061- `rig down --delete` — permanent removal; not recoverable.
1062- `rig archive` — recoverable; the rig is hidden from the default active view but its record + snapshots are preserved.
1063 
1064Visibility in `rig ps`:
1065- `rig ps` — active rigs only (default).
1066- `rig ps --include-archived` — includes archived rigs, marked with `*`.
1067 
1068SSE events `rig.archived` / `rig.unarchived` drive Project / dashboard updates;
1069consumers that depend on the rig list should subscribe rather than poll.
1070 
1071### Environment services
1072 
1073```bash
1074rig env status <rig>
1075rig env logs <rig> [service]
1076rig env down <rig>
1077```
1078 
1079Use these for service-backed rigs and agent-managed apps.
1080For `secrets-manager`, these are the fastest CLI surfaces for:
1081- confirming whether Vault is healthy
1082- reading Vault container logs
1083- stopping the Vault env without tearing down the specialist session first
1084 
1085### Release management without killing live claimed sessions
1086 
1087```bash
1088rig release <rigId>
1089rig release <rigId> --delete
1090rig release <rigId> --json
1091```
1092 
1093Use `rig release` for adopted/claimed-session rigs when you want OpenRig to stop managing the rig but leave the tmux sessions alive.
1094This is the safe recovery/reset surface for the "sessions still exist, management is broken or stale" case.
1095If the rig contains OpenRig-launched nodes, `rig release` refuses loudly instead of pretending the mixed rig is safe to detach.
1096 
1097### Snapshots and restore
1098 
1099```bash
1100rig snapshot <rigId>
1101rig snapshot list <rigId>
1102rig restore <snapshotId> --rig <rigId>
1103```
1104 
1105`rig restore` requires `--rig <rigId>`.
1106 
1107Claude Code autonomy note:
1108- unattended `rig whoami` on boot may require the local permission allow list to include `Bash(rig:*)`
1109 
1110### Import/export and bundles
1111 
1112```bash
1113rig export <rigId> -o rig.yaml
1114rig import <path> [--instantiate] [--materialize-only] [--preflight] [--target-rig <rigId>] [--rig-root <root>]
1115rig bundle create <spec> -o out.rigbundle
1116rig bundle inspect <bundle>
1117rig bundle install <bundle> [--plan] [--yes] [--target <root>] [--json]
1118```
1119 
1120### Legacy package surface
1121 
1122This still ships, but is explicitly marked legacy:
1123 
1124```bash
1125rig package validate <path>
1126rig package plan <path> [--target <dir>] [--runtime <runtime>] [--role <name>]
1127rig package install <path> [--target <dir>] [--runtime <runtime>] [--role <name>] [--allow-merge]
1128rig package list
1129rig package rollback <installId>
1130```
1131 
1132## Discovery and Topology Mutation
1133 
1134### Discover unmanaged tmux sessions
1135 
1136```bash
1137rig discover
1138rig discover --json
1139rig discover --draft
1140```
1141 
1142### Bind a discovered session
1143 
1144```bash
1145rig bind <discoveredId> --rig <rigId> --node <logicalId>
1146rig bind <discoveredId> --rig <rigId> --pod <namespace> --member <name>
1147```
1148 
1149There is no shipped top-level `rig claim` command.
1150The current adoption surface is `discover`, `bind`, `adopt`, and `unclaim`.
1151 
1152### Self-attach the current shell or agent
1153 
1154```bash
1155rig attach --self --rig <rigId> --node <logicalId>
1156rig attach --self --rig <rigId> --node <logicalId> --print-env
1157rig attach --self --rig <rigId> --pod <namespace> --member <name> --runtime <runtime>
1158```
1159 
1160Use `rig attach --self` when the current agent should attach itself directly instead of going through `discover` + `bind`.
1161 
1162Current proven behavior:
1163- inside `tmux`: attaches as a normal tmux-backed node, preserving inbound `rig send` / `rig capture`
1164- outside `tmux`: attaches as `external_cli`
1165- `--print-env` prints the `OPENRIG_NODE_ID` and `OPENRIG_SESSION_NAME` exports for the current shell
1166 
1167Recommended flow:
1168 
1169```bash
1170rig attach --self --rig <rigId> --node <logicalId> --print-env > /tmp/openrig-self-attach.env
1171. /tmp/openrig-self-attach.env
1172rig whoami --json
1173```
1174 
1175Notes:
1176- for tmux-backed self-attach, `rig whoami --json` is the right verification
1177- for raw/external self-attach, `rig ps --nodes --json` is currently the more reliable verification surface
1178- if the current shell is outside tmux, pass `--display-name <name>` when you want a stable human session label recorded
1179 
1180### Adopt a topology and bind live sessions
1181 
1182```bash
1183rig adopt <path> --bind <logicalId=tmuxSessionOrDiscoveryId>
1184rig adopt <path> --bind <logicalId=...> --bind <logicalId=...> --json
1185rig adopt <path> --bindings-file <bindings.yaml>
1186rig adopt <path> --bind <logicalId=...> --target-rig <rigId> --rig-root <root>
1187```
1188 
1189Use `rig adopt` when the sessions already exist and you want OpenRig to start managing them.
1190 
1191A bindings file is the durable map from authored logical IDs to live sessions. Shape:
1192 
1193```yaml
1194bindings:
1195 dev1.impl2: dev1.impl2@rigged-buildout
1196 dev1.qa: dev1.qa@rigged-buildout
1197```
1198 
1199Spec + bindings is the proven recovery pair for adopted rigs.
1200Spec gives OpenRig the intended topology. Bindings tells OpenRig which discovered live session belongs in each logical node.
1201 
1202### Proven adopted-rig recovery workflow
1203 
1204This workflow is proven for the case where the external tmux sessions are still alive:
1205 
1206```bash
1207rig release <rigId> --delete
1208rig discover --json
1209rig adopt <spec.yaml> --bindings-file <bindings.yaml>
1210```
1211 
1212What this does:
1213- removes OpenRig management without killing the sessions
1214- re-discovers those same sessions as unmanaged
1215- re-attaches them to the topology defined by the spec + bindings
1216 
1217Important limits:
1218- this is for `sessions still alive`
1219- spec alone is not enough for adopted rigs; you also need bindings
1220- this does not yet mean OpenRig can recreate dead external sessions from nothing
1221 
1222### Add unmanaged pods into an existing rig
1223 
1224This is the proven workflow when a rig is already managed, but a new pod was created outside OpenRig and you want to add it later:
1225 
1226```bash
1227rig adopt <pod-fragment.yaml> --bindings-file <pod.bindings.yaml> --target-rig <rigId>
1228```
1229 
1230Use this when:
1231- the target rig already exists
1232- the new sessions are live and visible in `rig discover --json`
1233- you want additive topology growth, not a full rebuild
1234 
1235What to prepare:
1236- a pod fragment spec with only the new pod
1237- a bindings file mapping the new logical IDs to the live session names
1238 
1239Verification loop:
1240 
1241```bash
1242rig discover --json
1243rig adopt <fragment.yaml> --bindings-file <bindings.yaml> --target-rig <rigId>
1244rig ps --nodes --rig <rigId> # the target rig's nodes (--nodes alone = your current rig)
1245rig export <rigId> -o rig.yaml
1246```
1247 
1248Success looks like:
1249- the new sessions stop appearing in `rig discover`
1250- the new logical IDs appear in `rig ps --nodes --rig <rigId>`
1251- `rig export` includes the new pod
1252 
1253### Mixed-origin rigs are allowed
1254 
1255One rig can contain both:
1256- adopted nodes bound from already-running sessions
1257- OpenRig-launched nodes created later with `rig expand` / `rig launch`
1258 
1259Current safety rule:
1260- `rig release` is for claimed/adopted-only rigs
1261- if a rig contains launched nodes, `rig release` fails with `contains_launched_nodes`
1262 
1263### Manager-assisted recovery
1264 
1265The proven operator pattern is:
1266- keep one OpenRig manager session outside the rig it manages
1267- address the target by rig name, not cached rig ID
1268- find the target rig with bare `rig ps` (lists all rigs), then resolve its owner from `rig ps --nodes --rig <target>` (a bare `--nodes` read is your current rig only, not the target's)
1269- send the manager the spec path, bindings path, and verification steps with `rig send`
1270 
1271This lets ordinary agents ask the manager for OpenRig help instead of every agent needing to be an OpenRig expert.
1272 
1273### Add/remove running topology parts
1274 
1275```bash
1276rig grow <rig-id> <member...> [--pod <pod> | --new-pod <pod>] [--runtime <runtime>] [--cwd <path>] [--json]
1277rig expand <rig-id> <pod-fragment-path> [--rig-root <path>] [--json]
1278rig launch <rigId> <nodeRef> [--json]
1279rig launch <rigId> --seats <a,b,c> [--hold-reason <text>] [--json]
1280rig remove <rigId> <nodeRef> [--json]
1281rig shrink <rigId> <podRef> [--json]
1282rig unclaim <sessionRef> [--json]
1283```
1284 
1285`rig grow` is the simplest way to add seats: no YAML, the default agent spec, and one
1286runtime and working directory for the named seats (`--new-pod` creates a pod for them).
1287Check `rig grow --help` on your installed version. Use a fragment with `rig expand` (a pod)
1288or `rig add` (one member) when a seat needs an explicit model, a permission policy, a
1289different agent spec or role profile, per-seat runtime or cwd, or startup files.
1290 
1291Node-granular managed partial restore (v0.3.4+):
1292- `rig launch <rigId> <nodeRef>` relaunches a single seat by logical id or node id through orchestration.
1293- `rig launch <rigId> --seats <a,b,c>` relaunches a comma-separated subset of seats.
1294- `--hold-reason <text>` records a reason for holding non-target seats during the partial launch.
1295- This is a SUPPORTED managed path. The prior `pod_aware_launch_unsupported` dead-end is retired; pod-aware narrow launch now goes through this surface rather than ad-hoc rebuilds.
1296 
1297### Add a member to an existing pod — v0.3.3+
1298 
1299```bash
1300rig add <rig-id> <pod-namespace> <member-fragment-path> [--json]
1301```
1302 
1303`rig add` is the top-level verb for the `add_member` converge op. It adds a
1304single member to an existing pod from a YAML/JSON member fragment file. The
1305daemon resolves the named pod, validates the member, runs preflight, and
1306launches the member in place.
1307 
1308HTTP outcomes:
1309- `201` — member added; per-node launch state included in the response.
1310- `400` — `validation_failed` or `preflight_failed` (the fragment or its launch posture is rejected before any state change).
1311- `409` — `member_conflict` (a member with that identity already exists in the pod).
1312 
1313Use `rig add` when you want additive growth inside a pod without re-running
1314the full `rig expand` pod-fragment path or rebuilding the rig.
1315 
1316## Specs and Validation
1317 
1318### Validate specs
1319 
1320```bash
1321rig spec validate <path> [--json]
1322rig spec preflight <path> [--rig-root <root>] [--json]
1323rig agent validate <path> [--json]
1324```
1325 
1326### Spec library
1327 
1328```bash
1329rig specs ls [--kind <kind>] [--json]
1330rig specs show <name-or-id> [--json]
1331rig specs preview <name-or-id> [--json]
1332rig specs add <yaml-or-directory> [--json]
1333rig specs sync [--json]
1334rig specs remove <name-or-id> [--json]
1335rig specs rename <name-or-id> <new-name> [--json]
1336```
1337 
1338## MCP
1339 
1340```bash
1341rig mcp serve [--port <port>]
1342```
1343 
1344Current shipped MCP tools:
1345- `rig_up`
1346- `rig_down`
1347- `rig_ps`
1348- `rig_status`
1349- `rig_snapshot_create`
1350- `rig_snapshot_list`
1351- `rig_restore`
1352- `rig_discover`
1353- `rig_bind`
1354- `rig_bundle_inspect`
1355- `rig_agent_validate`
1356- `rig_rig_validate`
1357- `rig_rig_nodes`
1358- `rig_send`
1359- `rig_capture`
1360- `rig_chatroom_send`
1361- `rig_chatroom_watch`
1362 
1363## Troubleshooting and Weird States
1364 
1365When the CLI behaves strangely, use the smallest truthful check first:
1366 
1367```bash
1368rig whoami --json
1369rig daemon status
1370rig ps --nodes --json
1371```
1372 
1373Specific operator rules:
1374- `Sent to ...` + `Verified: no` is ambiguous delivery, not automatic failure. Check reply, `rig capture`, transcript evidence, or queue/outbox state before retrying.
1375- partial `rig whoami --json` can happen when identity is still inferable but the daemon-backed path is degraded.
1376- the unified-exec-process warning is a host/tooling-layer signal, not automatic proof that the OpenRig topology is unhealthy.
1377 
1378If you hit the unified-exec warning, inspect for stale one-shot helpers before touching live seats:
1379 
1380```bash
1381ps -axo pid,ppid,command | rg 'tmux send-keys|rig queue create|tmux attach|codex|claude'
1382```
1383 
1384Safe cleanup target:
1385- orphaned one-shot wrappers like `tmux send-keys ...`
1386 
1387Do not mass-kill:
1388- `tmux attach ...`
1389- `codex ...`
1390- `claude ...`
1391 
1392## JSON and Error Posture
1393 
1394Design assumptions that hold in the shipped CLI:
1395- many operator commands support `--json`
1396- error messages are intended to say what happened, why it matters, and what to do next
1397- daemon-backed commands fail loudly when the daemon is stopped or unhealthy
1398- restore failure is not something you should silently reinterpret as success
1399 
1400## After-Compaction Recovery Checklist
1401 
14021. `rig whoami --json`
14032. `rig transcript <your-session> --tail 100`
14043. `rig ps` — lists ALL rigs on the host (know the world FIRST); then `rig ps --nodes --rig <your-rig>` for your seats. ⚠ `rig ps --nodes --json` alone is your CURRENT rig only — do NOT mistake it for the whole host (a freshly-compacted agent has no other context to catch the lie).
14054. `rig chatroom history <rig> --limit 50`
1406 
1407## Commands That Do Not Exist
1408 
1409Do not assume these exist unless the shipped help starts listing them:
1410- `rig claim`
1411- `rig blame`
1412- `rig replay`
1413 

Discussion