Runtime reference
This describes the current alpha runtime, including the active-harness workflow available through the rivet work commands.
Project policy and diagnostics
Run rivet --help for command syntax. rivet init --project=<path> previews project policy; --write creates reviewed .rivet configuration. rivet preflight --project=<path> reports orchestration readiness; --mode=host checks host repository, tool, and script readiness without requiring a private goal or unused provider credentials. rivet doctor --project=<path> reports general project readiness.
Node.js 22 or 24 runs Rivet itself. The application can use any language with project-configured verification commands. Existing Node project configuration uses schema version 1, where each logical command is one three-token package-manager invocation, or schema version 2 for structured package-script steps:
schemaVersion: 2
commands:
build:
steps:
- {cwd: backend, argv: [yarn, run, build]}
- {cwd: frontend, argv: [yarn, run, build]}
test:
steps:
- {cwd: backend, argv: [yarn, run, test]}Supported schema-v2 logical checks are build, test, lint, and typecheck; typecheck may invoke a package script named typecheck or type-check. Every required step must pass. Doctor and preflight verify the exact bounded directory, package.json, script, package manager, and executable resolved by the same runtime resolver, without executing project scripts. Runtime verification revalidates each exact package manifest before executing steps sequentially relative to the isolated integration worktree through the existing shell-free package-manager policy. New setup proposals never add dev as a quality gate; an existing valid schema-v1 configuration may retain its previously configured dev command or gate.
Checks for any project language
Schema version 3 supports exact executable arguments without a Node package manifest. The following is the command portion of a Django project configuration:
schemaVersion: 3
commands:
check:
steps:
- {cwd: '.', argv: [python3, manage.py, check]}
test:
steps:
- {cwd: '.', argv: [python3, manage.py, test]}Supported logical checks are test, check, build, lint, and typecheck. The quality configuration must require at least one test or check gate; build is optional. Each step names an executable on PATH or a bounded ./ path relative to its cwd, exact arguments, and a safe relative cwd inside the isolated checkout. Arguments are passed directly, without a shell, expansion, or chaining. Shell executables and privilege wrappers are rejected. Review these commands as executable project policy. Doctor and preflight inspect the configured executables and directories without running the checks.
Setup proposes conventional commands for root Django manage.py, Python metadata identifying pytest, Go modules, and Cargo projects. Review those proposals for the actual application. When no checks are detected, interactive rivet setup --write asks for one verification command. For noninteractive setup or custom commands, provide argv arrays or step groups:
rivet setup --checks-json='{"test":["python3","-m","pytest"]}'
rivet setup --write --checks-json='{"check":{"steps":[{"cwd":"backend","argv":["python3","manage.py","check"]}]},"test":["python3","-m","pytest"]}'rivet init --project=<path> also accepts --checks-json, with --write to publish the reviewed proposal. The JSON value is limited to 16 KiB. Existing valid setup configuration is preserved; edit its project and quality files together to change checks. Setup saves policy without installing application dependencies. Use the reviewed dependency plan below or the project’s documented environment procedure for each isolated checkout.
Project dependency installation
Schema 3 can declare dependencies with inputs, provides, and ordered steps. Inputs are tracked repository-relative files whose contents bind the approval; provides names project-relative executables the plan creates. Steps contain exact cwd and argv, just like checks. Example project configuration fragment:
dependencies:
inputs: [requirements.txt]
provides: [./.rivet-deps/venv/bin/python]
steps:
- {cwd: '.', argv: [python3, -m, venv, .rivet-deps/venv]}
- cwd: '.'
argv: [./.rivet-deps/venv/bin/python, -m, pip, --isolated, install, --require-virtualenv, --no-user, -r, requirements.txt]Use ./.rivet-deps/venv/bin/python as the Python executable in the quality checks for this plan. Setup proposes this layout for conventionally detected Python projects with root requirements.txt. Other layouts and tools require explicit review; Rivet does not infer every package manager or framework dependency procedure.
For a custom Node project using Yarn, an explicit plan can be supplied during setup:
rivet setup --checks-json='{"test":["yarn","run","test"]}' \
--dependencies-json='{"inputs":["package.json","yarn.lock"],"provides":[],"steps":[{"cwd":".","argv":["yarn","install","--frozen-lockfile"]}]}'Review the preview, then repeat with --write. This example is for Yarn Classic with an existing Yarn lockfile; do not create a second lockfile just to use it. Existing valid project policy is preserved by setup. Dependencies can also be configured with rivet init --project=<path> --dependencies-json='<json>' alongside the project checks.
rivet task deps prepares the active clean host Worker or accepted integration checkout after showing the exact plan for approval. Spawned tasks request equivalent approvals for their checkouts. Installation rechecks checkout identity and tracked inputs; a declined or failed installation does not become successful verification. The source checkout is not the installation target. A managed .rivet-deps directory gets its own ignore file only after approval; Rivet does not rewrite the source .gitignore.
Doctor and preflight can report preparation-required for missing executables declared in a valid dependency plan. This means preparation may proceed, not that checks ran. All required checks must still execute successfully against the accepted integration commit before final approval. Exact argv and checkout binding are not an operating-system filesystem sandbox: dependency tools can run installation code, so review their behavior and follow the repository’s environment policy.
Rivet supports two execution styles. Host mode lets the active coding harness plan and perform each sealed action without launching another model process. This is the portable path for Claude Code, Codex, Gemini CLI, OpenCode, editor agents, and future harnesses. Spawned mode can still launch the selected Claude or Codex client. For spawned mode, configure RIVET_CLAUDE_EXECUTABLE or RIVET_CODEX_EXECUTABLE to the canonical installed executable. During terminal harness discovery (rivet run and task resume), exact #!/usr/bin/env node entrypoints use the canonical native Node executable running Rivet when no interpreter override is set. Other script entrypoints and direct low-level client construction require explicit interpreter configuration. Discovery rejects project-local interpreters and still checks required CLI capabilities. Project checks use the exact executables configured by project policy. Legacy Node schemas use npm, pnpm, yarn, or bun package scripts; schema 3 also supports other toolchains. Setup does not install those tools or project dependencies.
For interactive terminal use, rivet run "task" finds the configured Git root from the current directory, discovers a compatible installed Claude or Codex adapter, shows the complete bounded plan and required checks, and asks for approval before execution. When both adapters are eligible, Rivet offers a choice in the same terminal flow. --harness=claude|codex selects one directly. --project=<path> is only needed outside the project or to choose a root explicitly. rivet task status selects the sole active run in that project and shows the next action and verification evidence. rivet task start reviews and activates a saved terminal proposal. rivet task resume also offers review for a proposed terminal task, or continues an approved or blocked spawned run; it does not duplicate one marked running. Before a spawned Worker starts, Rivet shows the configured dependency installation commands and asks for separate approval; accepted integration preparation has its own approval. rivet task deps applies the same approval to a clean active host Worker or accepted integration checkout. Multiple active runs offer a numbered task selection in an interactive terminal; noninteractive use requires --run=<id>. Use --details with run or task for full graph/state identifiers. Successful terminal execution immediately offers final review; task resume reopens it for verified work. These human commands keep the exact run ID, version, and proposal digest internal in the usual case. A ticket ID by itself is not accepted as an inline request.
The terminal flow needs a real interactive terminal for review; piped input cannot approve a plan. Direct adapters check required CLI options without a release allowlist; see harness compatibility. It uses the selected installed CLI and its existing authentication. It does not grant credentials or install a harness. Spawned verification records the accepted integration commit and a durable check report for both pass and failure. A failed check returns nonzero; an environment-only repair can be retried at the same unchanged commit. Final approval requires a matching report, runtime, and clean checkout. A spawned run marked running after an interruption needs process and state inspection before recovery because Rivet cannot prove the prior worker has stopped.
Feature lifecycle
Use rivet --help for everyday commands and rivet --help --advanced for the complete command reference. Existing feature and work lifecycle commands accept either the positional run ID shown below or --run=<id> / --run <id>. Use one form only. Project, version and proposal-digest requirements remain unchanged; proposal-creation commands do not accept a run selector.
The feature commands accept a Markdown request or configured Jira/Linear intake. feature propose produces a reviewable plan; feature start requires the exact reviewed proposal and current version. feature status reports progress. feature resume applies to spawned runs; host runs use the work commands. The CLI does not silently replace stale approvals or widen scope.
Direct ticket intake accepts --acceptance-criteria '<user criteria>' alongside --ticket on work propose, feature propose and feature run. Separate multiple criteria with newlines. Rivet retains their user origin separately from tracker criteria and includes them in the request digest. When both sources are empty, ask the user for criteria and retry; do not invent them. This option is invalid for Markdown, inline or MCP requests. See tracker criteria.
Host mode uses this lifecycle:
rivet work propose --project=<path> --request-text=<text> --decomposition-json='<json>'
rivet feature start <run-id> --project=<path> --expected-version=<n> --proposal-digest=<digest>
rivet work prepare <run-id> --project=<path> --expected-version=<n>
rivet work next <run-id> --project=<path> --expected-runtime-version=<n>
rivet work submit <run-id> --project=<path> --expected-runtime-version=<n> --action-json='<json>' --result-json='<json>'
rivet work verify <run-id> --project=<path> --expected-version=<n> --expected-runtime-version=<n>
rivet work status <run-id> --project=<path>Direct JSON inputs avoid temporary files and keep the Git baseline clean. Each inline JSON value is limited to 64 KiB of UTF-8. Pass it as one argument, preferably using a shell-free argument array; JSON serialization alone is not shell escaping. Existing --decomposition, --action, and --result file inputs remain available for project-contained files up to 128 KiB. Choose exactly one form per object; mixed file/inline submissions are supported. File path and runtime contract checks are unchanged. Credentials do not belong in payloads; command arguments can appear in history or process listings. Review and commit setup configuration and required scripts before proposing from a clean default branch. work next creates one isolated Worker checkout and returns a canonical launch/result contract. work submit rejects stale actions, changed contracts, evidence mismatches, and edits outside the sealed paths before integration. work verify inspects the real integration commit and runs configured gates, then stops at final human approval. It stores a bounded private report for both passing and failed checks; failed checks return nonzero and do not advance the run to final approval.
By default, the selected CLI performs both planning and implementation. A configured worker harness can override the implementation client; see worker routing. Planning is read-only; implementation is limited to its approved worktree. The current bridge runs one Worker at a time and uses fast-forward integration. Checkouts remain under the sibling .rivet-worktrees directory until deliberately cleaned up.
work status reads existing private state without preparing worktrees. Its workerCheckouts report identifies reserved and active Worker paths, expected/observed branches, edits and lease expiry, including interrupted preparation. See task and checkout status for recovery guidance. It reports the integration path and branch, changed paths, worker claims, executed check results, blocked nodes when present, and a next action. Call work next with the current runtime version after an interruption to recover the same pending action. A failed check can be retried against the same unchanged commit after an environment or dependency repair; source corrections and blocked submissions need a new reviewed proposal. Dependencies must be prepared in the isolated checkout where they are needed: the active Worker path for editing, or the accepted integration path for verification. rivet task deps selects either eligible checkout from the private run and reservation state, validates its Git identity and dependency inputs, and asks for explicit approval. They are not copied from the original checkout or installed by Rivet's quality commands. Host preflight requires a clean checkout of the configured default branch and a fresh or ahead corresponding remote-tracking ref. It checks the same configured branch used for proposal admission.
Successful final approval status requires a coherent private verification report, accepted integration identity, runtime state, and clean checkout at the tested commit. Missing evidence is reported as undeliverable. After an interrupted host command, rivet task recover explicitly attempts safe recovery of abandoned host-operation, run, runtime and state locks. It selects the sole eligible host task or terminal task at final review; use --run=<id> when there are several or to select a completed task with an interrupted local approval. For a harness, use rivet work recover <run-id> --project=<absolute-path> --json. Recovery validates saved state and the current project configuration, requires an unchanged lock owner on this machine whose process is provably dead and whose lock is at least five minutes old, and preserves task snapshots and worktrees. It never resumes Workers. A blocked result can list locks already recovered before reaching another owner; inspect that result before retrying. There is no force option. See interruption recovery.
Successful execution stops at awaiting-final-approval. rivet task approve offers explicit local application or pull-request preparation. Local application requires unchanged committed policy and clean checkouts, fast-forwards the original default branch to the verified commit, records local acceptance and marks the run completed. It does not execute remote delivery gates. The feature workflow does not automatically push, merge, deploy or publish. Worker claims and a model's success message are different from executed checks; delivery still requires the relevant human decision.
State and status
Run state belongs under Rivet's directory in the repository's Git common directory. rivet status <instance-id> serves the selected orchestration instance on loopback. Treat its session URL as private. An explicit --fixture=<tracked-relative-path> is for synthetic status inspection; it does not execute work or prove live-provider compatibility.
Harness compatibility
Rivet checks CLI capabilities instead of requiring a specific release. Before a spawned task, bounded version and help probes verify the installed executable and required options. Claude uses --help; Codex uses exec --help. Selection records the observed version and checks it again before launch. Advanced explicitly configured clients detect their installed version unless their caller supplies an optional expectedVersion consistency check.
Claude requires print mode, text input, JSON output, no session persistence, model/effort selection, permission modes, tool restrictions, JSON schema, and a cost limit. Codex requires exec, ephemeral execution, ignored user configuration, color control, and sandbox selection. Each launch also checks its selected optional flags. Rivet never drops required safety flags. Executable identity checks, cancellation, output limits, and strict result validation still apply.
Help checks establish advertised options; they cannot prove unchanged semantics, authentication, model availability, or future output formats. Incompatible results fail validation. Tested releases are evidence, not an allowlist: prior fixtures cover Claude 2.1.207 and Codex 0.148.0-alpha.9; small authenticated macOS terminal trials completed with Claude 2.1.280 and Codex 0.155.0-alpha.16. Regression tests also exercise unfamiliar version labels.
Spawned process adapters currently support macOS and Linux. Native Windows execution is not supported; an app running on Windows does not remove that runtime limit. WSL needs its own compatible environment and qualification.
Native usage and task budgets
Claude Worker results use the CLI's native modelUsage counters and total_cost_usd, rather than usage figures written by the model. Token totals include input, output, cache creation and cache reads across all reported models, including delegated agents. Missing or invalid native accounting stops the result. The native cost is a client-side estimate, not a billing receipt; see Claude's usage documentation.
A measured overrun or native cost-cap stop records the observed usage and ends the task as budget-exhausted. It cannot accept success evidence or start another reconciliation. An operation already in progress may finish, but its result cannot advance an exhausted task to completion. Limits are checked against the approved allocation; counts are never clamped to make a task pass.
Large contexts can consume a token allowance even when cache use keeps the estimated cost low. Review the project's orchestration budgets and approve a new plan when a different allowance is needed. Existing approved runs keep their limits. Codex's current direct-result adapter still uses model-reported usage; those figures are estimates, not native usage measurements or billing guarantees.
CLI and desktop host sessions
Host mode uses the current session's model and tools without checking its app or CLI version.
| Surface | Host workflow requirements |
|---|---|
| Claude Code CLI | Rivet skill, terminal/file tools, project access, operation permissions |
| Claude desktop Code tab, local session | Same requirements; open the repository in a coding session |
| Codex CLI | Rivet skill, terminal/file tools, project access, operation permissions |
| Codex app, local task | Same requirements; attach the repository and make the skill available |
| Ordinary chat or restricted remote session | An execution environment exposing those capabilities; chat alone is insufficient |
The Claude desktop reference describes local Code sessions, skills, and permission modes. The Codex app features describe its coding environment. Product capabilities do not establish completed Rivet desktop qualification.
The host needs permission to invoke Rivet, edit the exact reserved checkout, write private Git state, create isolated worktrees, run checks, and present human approvals. rivet preflight --mode=host --project=<path> checks project readiness; it cannot prove the surrounding app grants every later operation.
Host permissions: private Git state and sibling worktrees require permission. Use normal operation approvals for those exact operations, or the terminal rivet run flow if permissions cannot be granted. Automated host lifecycle coverage is not live desktop qualification; full real-harness and fresh-user trials remain open.
Host proposal input format
--request-text requires Markdown with a # Title and a nonempty ## Acceptance Criteria bullet list. The active harness converts the user's request into this format. It must preserve the requested scope rather than inventing criteria.
--decomposition-json contains exactly schemaVersion: 1, kind: "agilno.feature-decomposition", and workItems. Each of 1–16 work items has objective, ownedPaths, and acceptanceCriterionIndexes. Indexes start at one and must cover every request criterion. Owned paths list files to change, not files merely read. Roles, commands, budgets, and approval gates come from project policy and are not decomposition fields. The installed Rivet skill includes a complete example.
Task decisions and review evidence
Use the task's decision record for design choices, assumptions and trade-offs that affect acceptance. Record the options considered, the reason for the selected option and supporting evidence. Material changes to scope or architecture need human approval; recording a decision does not expand the approved task.
rivet task decisions
rivet task decide --input=./review/decision.json
rivet task approve-decision --decision=<decision-id>For example, record a bounded implementation choice without creating a file:
rivet task decide --input-json='{"id":"health-response","tier":1,"title":"Health response format","options":[{"id":"json","description":"Return a JSON object using the existing API convention"},{"id":"text","description":"Return plain text"}],"choice":"json","rationale":"The approved endpoint task follows the existing JSON API convention."}'Choose the tier honestly; it does not grant additional task authority:
| Tier | Recorded behavior |
|---|---|
| 0 | Reuses a matching choice from the approved plan. Requires approvedPlanDecisionId referencing that existing decision. |
| 1 | Records an implementation choice within existing authority, without a new human approval. |
| 2 | Remains pending until explicit human approval. |
| 3 | Escalates the decision for human resolution; it also remains pending until explicit human approval. |
Use either --input=<project-local-json-file> (up to 128 KiB) or --input-json=<serialized-json> (up to 64 KiB), never both. Inline JSON avoids creating an untracked file on the clean source checkout. File examples above assume an already ignored private input directory; creating an ordinary untracked review/ directory can make the source checkout dirty and block workflow checks. Keep private context and credentials out of inputs. approve-decision requires an interactive human confirmation; an agent must not pipe an answer or approve its own exception. Use --run=<id> when the task cannot be selected unambiguously.
Review the plan before execution and the accepted changes before delivery:
rivet task review --phase=plan
rivet task review --phase=final
rivet task review --input=./review/report.jsonWithout --input, the command exports the review context for the selected phase. With --input or --input-json, it records a structured reviewer judgment against the matching task, request, plan and commit/diff identity. Re-export context after those inputs change. A review for different source or a different plan does not approve the current task. Rivet does not automatically send source to another model or launch an independent reviewer. Use your approved reviewer or harness, inspect the report, then submit it. The same mutually exclusive file/inline input limits apply; prefer inline input when a file would dirty the approved source checkout.
Configure review requirements in .rivet/quality.yaml and commit the policy before proposing a task:
review:
required: true
maxRounds: 3
strictCoverage: true
reviewers:
- id: security-reviewer
paths: ["src/auth/**"]
required: trueThe exported context includes reportTemplates and reviewer path assignments in review.reviewerPaths. Start with the template for the assigned reviewer and preserve its exact task, request, plan, commit and diff identities. Templates deliberately begin with status: FAIL, blocking: true, empty coverage and a finding stating that review has not happened.
Complete the review before submitting: replace the reviewer actor placeholder with the actual independent reviewer identity; record reviewed files, executed commands and the review time; and map each acceptance criterion by its one-based criterionIndex to assigned planNodeIds, reviewed paths and test/manual evidence with a reference and summary. Record missing requirements, unrequested work and other problems as findings. Use PASS only after the required coverage is complete and no blocking finding remains. Editing the template to say PASS without performing the review does not produce valid evidence.
Review is opt-in: required defaults to false. The default review-round limit is three per task phase, across accepted revisions. Changing the commit does not reset that limit; only reports for the current commit satisfy the review gate. Assigned reviewers can complete the same round for that commit, including the final permitted round. Path rules select the required reviewer coverage; use reviewer identities that are independent of the implementation actors. A structured report supports an accountable review but does not itself prove that a separate person or model performed the work. Missing required coverage, unresolved findings or exhausted rounds require correction or human resolution, not a manufactured passing report.
Optional changed-content checks
Add contentScan to .rivet/quality.yaml and commit the policy before proposing a task to scan changed committed content during verification. The scanner uses the accepted Git content, not a worker's description of its edits.
contentScan:
secrets: true
unicode: warn
maxFiles: 1000
maxBytes: 2097152
allowlist: []The built-in secret checks look for private-key markers and high-confidence GitHub, npm and AWS credential patterns. Findings include the file, line and rule, without matched values or source snippets. Detection is limited to those patterns; passing this scan does not prove the absence of secrets.
Unicode checks flag bidirectional control characters and mixed Latin/Cyrillic/Greek identifiers in recognized code files. warn is the default; required makes those findings blocking and off disables Unicode checks. The identifier scan is a lexical heuristic, not a language parser. Ordinary multilingual prose, strings, mathematical text and emoji are not banned, and legitimate joiners are not blanket-rejected.
Exceptions must specify one exact relative file path, one known rule and a nonempty explanation. Wildcard suppression and arbitrary regular expressions are not supported. For example, a reviewed fixture containing a private-key marker can use:
allowlist:
- ruleId: private-key
path: test/fixtures/key-marker.txt
reason: Contains a marker only for a scanner regression testThe example is nested under contentScan. Do not use an exception to accept a real credential. Resource-limit failures and unreadable scan inputs require investigation rather than being treated as a pass.
Projects can also opt into the known type-suppression rule for explicit file paths through shortcutRules, with a reason and optional required: true. This reports @ts-ignore and @ts-nocheck; it does not establish whether every shortcut or placeholder is acceptable. Use existing configured command gates for broader tools such as Gitleaks, language-specific linters and project-specific checks. Rivet does not install or launch extra scanners implicitly.