- name
- openrig-user
- description
- Use 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.
# 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:
```bash
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:
```bash
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:
```bash
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/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`, 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.
```bash
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.
```bash
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:
```bash
OPENRIG_WORKSPACE_ROOT=<path> rig <command> ...
```
For a persistent host-level redirect, the operator changes the config file or
runs the setter:
```bash
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.
```bash
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:
```bash
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:
```bash
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. *(Current teams: `starter` and `factory` are built in;
`workshop` is a bundle. The former `product-team`, `conveyor` and `demo` starters
were removed. `first-project` is Starter's compatibility name.)*
For new specs, use the [topology naming reference](https://github.com/mvschwarz/openrig/blob/95412717f319c6557c970d870cc22fa976565837/docs/reference/topology-naming.md):
rig = purpose, pod = domain, member = role. Existing addresses and provider choices
stay intact until deliberately changed.
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:
```bash
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.
```bash
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 starter`). 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:
```bash
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.
Auf GitHub ansehen