OpenRig User
SkillDev toolsUse when a specific `rig` command, subcommand, or flag is already known and you need its exact syntax, JSON shape, defaults, or error meaning. NOT for natural capability discovery, open-ended how-do-I questions, or choosing which OpenRig move applies.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the OpenRig User skill
What this skill tells your AI
The instructions your AI receives, as published by mvschwarz/openrig in packages/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md and read by ahel’s review.
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 sendfor durable work → userig queue createinstead. 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 handoffand 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/cli@0.3.1 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, andrig workflowas the product coordination surfaces when the active daemon is v0.2.0 or newer. - Use daemon-backed
rig queuefor durable routing.update / show / listcomplementcreate / handofffor 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 + slicesexhaust/— project-local coordination exhaustSPEC.md— project intentproject.yaml— project catalog selections and mission rootworkspace.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-policyskill — it translates the chosen spec into your live harness config (Claudesettings.json/ Codexconfig.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 downaccepts 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--freshand was freshly started.awaiting-decision— zero-session honest state. There is no resumable session AND no--freshopt-in was given; the seat is waiting for an operator decision. Previously fudged asfailed; 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 viarig seat clear-attentiononce 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> is the operator-attestation override path; without it the
command runs the evidence gate. Either way the action is audited.
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— defaulttruesnapshots.periodic.interval_seconds— default300snapshots.periodic.retention_keep— default10
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 pslists ALL active rigs (one row each — the cheap "know the world" view). The--nodes(per-seat) view defaults to your CURRENT rig only (fromOPENRIG_SESSION_NAME's@<rig>suffix);--rig <name>picks another rig,-Awidens--nodesto the whole host (expensive — prefer--fields/--limit). - Per-node TL;DR projection (compact) is the default;
--fullreturns the raw byte-equivalent passthrough. Daemon-siderecoveryGuidancerelocated to a guidance-by-reference map (no longer duplicated per-node) — even--fullbenefits. - All-states stays default (different from
rig queue listwhich defaults to active-only) — forps, non-running states ARE often the actionable signal. - Resume-token security:
--fullJSON emitsresumeTokenPresent(boolean) — the actualresumeTokenvalue also remains in--fullfor downstream consumers that legitimately need it, but the compact default never carries it (an orch glance never accidentally leaks token material).
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 67
- Forks
- 12
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
openrig-user- Source
- github.com/mvschwarz/openrig