Skip to content

OpenRig 0.6.11

Choose a tag to compare

@mvschwarz mvschwarz released this 17 Oct 23:25
· 319 commits to main since this release
379f0a0

OpenRig 0.6.11

0.6.11 is a fix release about recovery and wasted agent time, and most of it came from the community: 28 of its 46 changes are from thirteen outside contributors, and four more finish work that outside contributors started. A send that waits for a seat to go idle no longer holds up every other send to that seat. A parked seat isn't woken again for rows that haven't changed. Restore stops for a decision instead of starting a seat fresh when an earlier conversation may still be resumable. A Codex seat at its usage limit stays marked as limited while its screen redraws. And on Linux, a Codex seat can be restarted in place on the same conversation.

npm install -g @openrig/cli

It's built from 379f0a0d on the release branch: cb79b8c9, the 42 changes after 0.6.10, plus four reviewed fixes carried onto the release branch: #1212, #1218, #1085 and #1361, which corrects the in-place restart. Work merged to main after cb79b8c9 isn't in this release, apart from those four. If something breaks for you, please open an issue.

The bundled changelog and what's-new text were written before the final restart correction, #1361; these release notes include that fix and the later real-Codex restart check.

Before you upgrade

Restart the daemon after upgrading the CLI. The running daemon keeps its old build until it restarts: run rig daemon stop, then rig daemon start. One database migration runs on the first start: 103 adds one column to sessions, intentionally_stopped, which is 0 for every existing row, so OpenRig can tell a seat you stopped on purpose from one that exited (#1192). There are no migrations 100 or 102. The bundled openrig-core plugin stays at 0.1.9; two of its files changed (#1174, #1066).

Two new switches, both off by default:

  • output.compact (or OPENRIG_OUTPUT_COMPACT): the seven queue write commands (rig queue create, claim, unclaim, update, block, handoff and handoff-and-complete) print a short receipt instead of the whole row, and --full prints the whole row. While it's off, their output is unchanged; --full is accepted, and rig config lists the key (#1137).
  • provider.usage_windows (or OPENRIG_PROVIDER_USAGE_WINDOWS in the daemon's environment): rig provider status --refresh reads a Codex login's usage windows once. While it's off, --refresh says how to turn it on and exits 1 (#1194).
    Changed: rig queue whoami --work-candidates now returns up to 50 held and 50 next rows, with heldTruncated and nextTruncated; heldAndNextTruncated now means either list was cut. With OPENRIG_REFOCUS_WORK_PACKET on (off by default, as in 0.6.10), the refocus hook's work packet lists held and next work separately, up to 50 each (#1066).

Behaviour that changed:

  • Restore no longer starts a seat fresh when an earlier occupant left a resume token. If a seat wasn't running when the snapshot was taken, but an earlier session recorded a resume token, rig up --existing and rig launch stop that seat at awaiting-decision and start nothing, because the token doesn't prove that conversation can still resume. rig launch of such a seat now exits 1 where it used to start it fresh. The message names the command that starts it fresh on purpose (#1141). For a seat stopped when the snapshot was taken, restore does not resume an earlier recorded conversation; the offered --fresh command starts a new conversation, not that recorded one. See Known issues for how this shows in the rig status API.
  • rig queue create --verify reports outcome: "claimed" for a claimed row whose wake wasn't confirmed, instead of indeterminate. This was a known issue in 0.6.10 (#1168).
  • rig send --wait-for-idle N waits before it takes the seat's delivery lease, so other sends and queue wakes to that seat aren't held behind a long wait. N is now a deadline from the start of the wait, including any time spent waiting for the lease (#1103, reported in #1084). A timeout names the wait you asked for (#1183).
  • rig seat launch --fresh --stop checks before it stops anything. A seat with a still-live older session is refused before the current agent is stopped; 0.6.10 stopped it first. --plan previews a fresh launch without changing anything and exits 0 even when it would be blocked. --reason is required only to execute; leaving it out reports missing_reason (#1156, towards #889).
  • A seat you stop on purpose no longer makes its rig read degraded. rig seat stop records the stop, rig ps and the TUI leave that seat out of the rig's state, and running counts still exclude it. rig ps --nodes --json carries intentionallyStopped. A rig whose seats were all stopped this way reads stopped (#1192, reported in #401).
  • In a restore of a rig whose seats are in pods, a seat is rolled back as unresumable only when its runtime reports the conversation missing. When Claude, Codex or Pi reports that, the restore rolls the seat back to awaiting-decision and starts nothing, instead of reporting a failed launch and leaving the new pane behind. A rig where every seat ends this way reads partially_restored instead of failed; the exit code is 1 either way (#1191). A Claude that exits to its shell for another reason keeps 0.6.10's result: the restore reports the seat failed and keeps its pane, so you can read what happened. It isn't called unresumable, and nothing starts fresh (#1218). Restores of rigs without pods keep their earlier handling.

Highlights

Sends and wakes.

  • A parked seat whose occupant is known isn't woken again for the same rows after a wake was delivered, until it updates one of them or one changes state. A failed, refused or unrecorded wake still repeats at the next park, and a new occupant gets its first wake. "Delivered" means the wake was typed into the seat's terminal, not that the agent read it (#1142).
  • rig send --verify confirms enveloped multi-line messages that the agent's screen indents, and queue wakes use the same check (#1145).
  • When no activity hook is reporting, a Claude footer in auto, bypass or plan mode on the last line reads idle (#1179, reported in #808).
  • A failed Pi or OMP turn shows the provider's own reason when it gives one (#1181).
  • rig queue create --verify to a registered person who is also a seat with a pane reports the Slack receipt beside the terminal wake, in a gateway object (posted, transport-failed, never-posted or still-pending). Posted isn't read. The wait is bounded by the existing 30-second default, and it can use all of it even when Slack isn't set up or the row won't be posted; the Slack side then reads still-pending. GET /api/queue/:qitemId returns ownerNotificationLevel (#1085).

Restore and launch.

  • A forked Claude seat (rig fork, or session_source: fork) launches with its own session ID, so strict restore and clear-attention can verify it as its own conversation. Forking a Claude seat needs Claude Code 2.0.73 or later, which OpenRig doesn't check. Forks launched before this keep reading mismatch until they're relaunched (#1144).
  • Seats no longer inherit the launching Claude Code or Herdr session's identity variables, such as CLAUDECODE. If removing them fails, the launch goes ahead with a warning (#1151, finishing #771).
  • rig up warns on stderr when it chose / as the launch folder itself (#1150, from #226).
  • A member's cwd in a rig spec can be ~, start with ~/, or use $VAR or ${VAR}, expanded from the daemon's environment, when the path as written doesn't exist (#1153).
  • A late readiness result no longer overwrites a newer launch attempt (#1188).

Status.

  • A Codex seat at its usage limit stays unknown with reason usage_limit while its screen redraws, instead of reading running, and rig ps --nodes shows usage_limit under REASON. It clears when a readable screen shows no banner, or when Codex shows it's working again (#1185, towards #763 and #824). See Known issues.
  • rig ps takes a rig's running count and status from the same set of sessions as rig ps --nodes (#1186).
  • rig whoami --full --json shows a Codex seat's runtimeContext.threadId when its stored conversation ID was verified resumable (#911, towards #122).
  • The TUI says when a queue sample hit its cap or failed to load: counts read N+, a seat missing from the sample shows ?, and Pulse no longer lists a NEEDS YOU item a second time. The caps count the whole host, so a quiet rig can read ? while another rig is busy (#1175).
  • The TUI Topology table's Q, WORK and NOW columns fill again on drilled views and on a seat's page. They had been empty there since 0.5.14 (#1173, reported in #1172).
  • A handed-off closure with no visible successor gets the same custody advisory and stuck-sweep finding as a done closure (#1189, towards #318).

Restart a Codex seat in place, on Linux. rig seat restart <seat> --keep-conversation --reason "<why>" restarts one Codex seat in its own pane on the same conversation, so it starts again on whatever account its Codex home now holds. It doesn't switch accounts itself. Before it stops anything, it checks that the seat is a Codex seat OpenRig launched, in a single pane, with a conversation it can prove, and that relaunching wouldn't change the running settings; any doubt refuses with nothing stopped. --plan runs every check and stops nothing. --verify --expect-account <account> reports moved only when a tool turn has completed in the same conversation since the restart and Codex's status names that account. It supports Linux only: on macOS, a request that gets as far as reading the running process refuses before stopping the seat, because that reading depends on /proc (#1196, #1195, #1212). A restart could report native_unknown when Codex's resume screen was ready before its new process was visible; it now looks again, a bounded number of times, before deciding (#1361). What was proven: hermetic tests and review on Linux, and one restart of a real Codex seat on Linux with this exact package (see How it was tested). A unit fixture covers the process matcher's macOS shape; it isn't a macOS restart.

Slack. A reply sent with "Also send to channel" in the default channel is recovered after a connection gap (#1187, towards #739).

Ports. rig config set daemon.port refuses a port outside 0–65535, and a port like that from the environment or config.json falls back to the file or default with a warning (#1140). rig daemon start --port refuses one too, with a clear message and exit 1 (#1201).

Dependency and install-script changes

  • npm dependencies: none added, removed or changed, and the Node requirement is unchanged (node >=22). OpenRig's own version fields advance to 0.6.11 (#1253).
  • Install scripts: unchanged. The package's only lifecycle script is still postinstall: node scripts/check-abi.mjs.
  • Database: migration 103, as above.

Everything else since 0.6.10

Queue, scope and proof.

  • Parallel rig scope slice create calls get different slice numbers. A number is never reused, and each create leaves a hidden slices/.nn-NN claim file (#1007). See Known issues.
  • rig proof show and rig proof judge take --project <id> or a <project>: scope prefix, resolved through the workspace catalog. Scope readiness for a project selected in the TUI uses that project's own root (#1149, finishing #136).

Requests the daemon now refuses cleanly.

  • The chat send and topic routes return 400 before storing anything for payloads that used to fail with 500 (#1122).
  • /api/wake-resolve answers a fractional or non-numeric generation with its usual "does not exist" reply (#1129).
  • Watchdog registration refuses a scan_interval_seconds that can't be turned into a number, such as non-numeric text, a boolean or an empty array (#1131).
  • Discovery of unmanaged panes matches agent process names exactly, plus claude.exe and names cut to 15 or 16 characters (#1133).

Skills and docs.

  • The rigs and openrig-skills skill descriptions split by who is asking: a person in their own session, or an agent inside a rig (#1174, reported in #1171).
  • A reference page on keeping a watch for a person with today's queue commands (#1064). See Known issues.
  • The what-changed note, capability map and changelog for 0.6.11 (#1253).

Tests and repository checks.

  • Daemon and CLI tests that failed on some Linux machines (ext4 inode reuse, dash as /bin/sh, a 002 checkout umask) pass there now (#1148, finishing #83).
  • The pane-isolation tests clean up after themselves (#1169), and the TUI default socket-path test no longer fails on macOS (#1182).
  • The portability report runs when it's started through a symlinked path (#1109).

How it was tested

  • The final package: openrig-cli-0.6.11-379f0a0d.tgz, 4,208 files, SHA-256 289dc0073cb9e50ced92653e5faae063c27d005eb97fa190f036594d214267f6, built once from 379f0a0d in a clean environment. It differs from the package built just before it from af1b61bf in five files: two build stamps, and the restart command's compiled module and its two maps (#1361). That earlier package was compared file by file with the published 0.6.10 package: 314 files changed, 38 were added and 1 was removed, all traced to the changes. Installed from the exact final package, it reports 0.6.11 (379f0a0d), its daemon starts healthy, and a fresh database gets every packaged migration, including 103. The fuller installed checks ran on the af1b61bf package. Those that passed include migrations 098, 099, 101 and 103 and provider-free checks of the missing-token and partial-restore refusals and the port refusals; #1085's wait is under Not tested. They aren't repeated, because the five changed files are reached only by an in-place restart.
  • The first-user check ran on Linux only, on the af1b61bf package (an in-place restart isn't part of it). A fresh user, with no display, asked an open Claude Code session to set up OpenRig. It had help, as 0.6.10's check did: the package came from a local registry through a one-line npm setting, Claude Code was installed and signed in beforehand, and the person's terminal was already a tmux session. The operator was on screen 2 minutes 8 seconds after the ask, and reviewed work, with one blocking review finding fixed and rechecked, was done 12 minutes 51 seconds after the ask (2 minutes 46 seconds and 18 minutes 20 seconds with 0.6.10). These are this run's times, not a controlled comparison. Of 0.6.10's findings, two were seen again: a queue wake was typed into the builder's pane while the person had it attached, and a team test command still asked for approval (3 team approvals, 4 with 0.6.10). The approval promise wasn't tested: the person's "don't ask again" landed in the shared project settings, so the reviewer never asked, and nothing woke the operator. Two new findings are under Known issues. Codex as the person's agent wasn't covered.
  • A real Slack decision was checked separately, on macOS, on the af1b61bf package, with a test Slack app. The Slack input was real, sent by an agent driving a Slack web client signed in as a person, and 5 of 5 cases passed. A typed answer on an open decision was recorded; a click after it closed wasn't, and the bot said so; a click was recorded and confirmed; a later thread reply reached the asking seat as a linked message; and an "Also send to channel" reply sent while the connection was down was recovered once on restart and marked as a late delivery, with Slack's redelivery ignored as a duplicate (#1187).
  • The in-place Codex restart, with this exact package: one real Codex seat (Codex 0.153.4) on Linux ran a turn, then was restarted once with --keep-conversation. The restart reported restarted_account_unverified; the seat resumed the same conversation, recalled its first turn without reading a file, and ran a tool turn with the same settings. Not established: that the account stayed the same, the plan tier, which program bytes were loaded, which signal ended the old process, and peak memory and disk use. It wasn't run on macOS or with a Codex build that shares one app server. Before that: hermetic tests and review on Linux; a unit fixture covers the process matcher's macOS shape, and it isn't a macOS restart.
  • Each change ran the repository's automated tests, merged into the main of its day, before it merged. The tests ran again on the release commit itself and passed, the package tests on macOS and the other checks on Linux.
  • Teams at work: three Linux installs, one of them long-lived, were upgraded to the af1b61bf package and kept their running seats. On two of them, a team then returned useful work over about a day between its recorded start and end; those times don't show continuous activity, and one team's runtime wasn't verified. On the final package, a two-seat Codex team (a lead and a freshly started peer) did one task, a joined code review, with work passed both ways through the queue. That's one task, not a long run.
  • Not tested: useful work on a long-lived install; a team at work over a working day on the final package; #1085's 30-second --verify wait on the exact package (its test fixture failed, and no product failure was found); the in-place restart on macOS, with a Codex build that shares one app server, or with the account checked; Codex as the person's agent; and a first install on macOS or native Windows with this package.

Known issues

  • The rig status API can call a running rig blocked because of one seat that isn't running. It happens when the latest snapshot recorded no occupant for that seat, an earlier session of the seat left a resume token, and its newest session's restore policy is resume_if_possible. A restore from that snapshot would stop at the seat for a decision, and GET /api/rigs/:id/status folds that forecast into the rig's status, so it mixes current status with restore readiness: no seat is halted. rig status and the TUI's rig list don't show it for a running rig. The web UI's restore control shows "Resolve & restore" for such a rig, and it still works (#1141).
  • A Codex seat can keep reading as at its usage limit when an old usage-limit banner is followed by a submitted prompt and the agent's reply, with no Codex working line and no input line below. It's recorded again every five minutes, where 0.6.10 let it age out. The case was constructed from the source and hasn't been seen in the real sessions reviewed (#1185).
  • rig seat restart --keep-conversation supports Linux only, and it has restarted one real Codex seat, with Codex 0.153.4. It doesn't verify which account the seat resumes on, and Codex builds that share one app server weren't tried.
  • The keeping-a-watch page says a timer fires once, but a held-back wake uses up that fire. When the typing guard holds a one-shot --wake-after wake back (it shows as retained), that held-back attempt is recorded as the timer's one fire and later wakes aren't, so the timer isn't retired: it can wake the owner again at each interval while the task stays set aside. A task sharing the timer through --wake-watchdog, after the original task was handed off or stopped, loses its one wake if that wake is held back. Read the task's transitions after each wake (#1064).
  • After rig scope slice create says it couldn't verify membership, the slice was kept. Check mission.yaml before creating it again: creating it again makes a second slice with the same name (#1007).
  • The latest first-install check used 0.6.11 on Linux only (the af1b61bf package; a fresh user, no display, Claude Code only), with the help listed under How it was tested. macOS was last checked with 0.6.8, and native Windows hasn't been checked.
  • A second session in the same folder can misread a running team. In the first-user check, the person's agent in a second session checked only the kernel, told the person setup wasn't finished and asked for a goal, while the starter team was running there with its work done.
  • The operator can point a person without a display at the shared dashboard, without saying how to open it.
  • The skill installer may not select Claude Code. When npx skills add detects another agent, such as Codex, it asks which agents to install to, with Claude Code not selected. Pressing Enter on the defaults installs only to .agents/skills, which Claude Code doesn't read. Select Claude Code there.
  • rig doctor still checks both harnesses, including one you don't use. rig setup --providers doesn't change it.
  • rig tui --shared still attaches on the default tmux server, so it can't find the dashboard when the daemon runs on a non-default tmux socket. Use rig tui there instead.
  • A team's own first steps can still ask for approval in places, such as its roster file outside the project folder and its test runs.
  • A seat waiting at a permission prompt shows no product notice of its own, and the operator and leads, who are told to tell you, may not. Check your seats: rig ps --nodes shows needs_input.
  • A launched team still writes into its working folder: its skills, CLAUDE.md, .mcp.json, .openrig/ and an accept-edits .claude/settings.local.json. The operator now says so before you agree.
  • A resumed Claude seat still can't be confirmed after /clear, an in-process /resume, a hand-started process or a launcher shim, or with a plugin older than 0.1.9.
  • Help without a prompt has been checked in a live Claude session for only one selected lifecycle-help command (#927), as in 0.6.10.
  • Codex team seats don't yet ask before lifecycle commands such as rig up and rig down. Claude Code team seats do.
  • The send gate trusts the latest recorded hook, as in 0.6.10.
  • A Codex seat whose permission request was approved automatically can still read "needs input" (#896).
  • After a restart, rig status shows Kernel: skipped whatever the kernel seats' state. Read them with rig ps --nodes --rig kernel --full, and bring the kernel back with rig up kernel --existing.
  • Slack channel map: replies are matched to a thread by its timestamp alone, missed-message recovery covers the default channel only, and private channels and direct messages aren't supported targets, as in 0.6.10.
  • Refocus after compaction hasn't been proven on a long-running install.
  • Older issues, as in 0.6.10:
    • the starter's Codex reviewer needs a Codex newer than 0.145;
    • a restore can report a problem with a seat that works (#273);
    • a claude alias defined only in a nushell rc doesn't resolve;
    • after a reboot, start the daemon with rig daemon start and bring your rig back with rig up <name> --existing;
    • the web UI's file preview runs scripts, so preview only files you trust;
    • browser access isn't complete browser isolation;
    • Codex network inside the sandbox hasn't been checked with real logins, managed policy bundles or on Linux.

Thanks

To the people whose pull requests are in this release:

To the people whose earlier pull requests were finished here: @adampog (#771), @korallis (#136, with dajiaohuang), @Marius-prog (#226) and @mvdpoel (#83).

And to the people whose reports shaped fixes here: