Skip to content

fix(seat): restart in place accepts a Codex that OpenRig launched through its staged script - #1212

Merged
mvschwarz merged 2 commits into
mainfrom
t4/s05-codex-launch-pane
Oct 13, 2026
Merged

mvschwarz merged 2 commits into
mainfrom
t4/s05-codex-launch-pane

Conversation

@mvschwarz

@mvschwarz mvschwarz commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

What's wrong (on main since #1196, and in 0.6.10)

rig seat restart --keep-conversation refuses an ordinary OpenRig-launched Codex seat with pane_shape_unknown.

The Codex adapter types every launch through tmux.sendShellCommand without sourceInPane or execInScript, so the pane shell runs /bin/sh <tmpdir>/openrig-tmux-send-<pid>-<uuid>.txt. That covers fresh launch, fork, resume, restore resume, and this restart's own relaunch (sendResumeCommand). The pane is therefore shell → sh → Codex launcher → Codex.

seat-restart-in-place.ts accepts only Codex as the pane root, or Codex directly under the pane's shell. So it refuses every managed Codex seat, including any seat it has already restarted once. The refusal is safe (nothing is stopped), but the command can't run on the seats it is for.

The correction

  • The shape check accepts exactly one extra link between the pane's shell and the Codex launcher chain. That link must be an sh whose only argument is an absolute path carrying the name the tmux adapter gives its staged scripts.
    • The name check is isStagedSendScriptPath, which sits next to the name generator in adapters/tmux.ts.
    • The script removes itself as it starts, so this is a name check, not a file check.
  • Everything else is still refused: any other process in that position, sh -c …, a relative path, a different script name, or more than one link.
  • Shape reported: shell_backed. Stop, relaunch and reporting are unchanged: the shell-backed path already waits for the pane's shell to come back, and the staged script exits when Codex does.
  • What doesn't change: launch, the adapter, and the direct-native path.

The change is self-contained (4 files, +90/−10) and applies cleanly on cb79b8c and on current main.

Proof (hermetic; ovh08 is under Fleet's real-home hold)

  • Unit (seat-restart-in-place.test.ts): the staged script is accepted for plan and execute, and Codex is signalled. Five near-misses are refused with no keys or signals sent:
    • another script;
    • a short name;
    • sh -c;
    • a non-sh wrapper;
    • a relative path.
  • Native (seat-restart-in-place-native.test.ts): a new case uses a real private tmux server and the stub Codex.
    • It launches through the tmux adapter's real staging path, the same way OpenRig launches.
    • It then restarts twice in the same pane, so the second restart runs on the restart's own relaunch.
    • It fails on main with pane_shape_unknown and passes with the fix.
  • feat(seat): restart a Codex seat in place on its home's current account (rig seat restart --keep-conversation) #1196 fixture LOW folded in: the direct-native case now compares the stub with the reported replacement process, and separately ties that process to the respawned pane (its root or the root's direct child). It now holds where the image's sh doesn't exec a lone command (review-r2's dash).
  • Checks run: typecheck, lint, the unit file (49) and the native file (4) all pass on the box.
  • Not run here:
    • The full suite. It was stopped at 07:08Z for Fleet's no-writer window around SRE's ~/.codex correction; CI runs it.
    • A real-Codex check, which is under Fleet's hold.

Round 1 (df7ee77)

  • P1-1, macOS. macOS's /bin/sh is a shim that runs bash (or dash or zsh), so ps names the staged script's process bash, and the link never matched there.
    • The link now accepts the shells /bin/sh can run as (sh, bash, dash, zsh) as the process name.
    • Every argv check is kept: exactly two arguments, argv[0] /bin/sh or sh, and the staged absolute path.
    • A macOS-shaped unit fixture (process bash, /bin/sh /var/folders/…/T/openrig-tmux-send-…txt) is accepted. It was red before this change.
    • /bin/bash <script> and an extra argument stay refused.
    • The macOS case is proven by that fixture only. CI skips the native suite, and nothing native runs on macOS here, so a native macOS check falls to Fleet's release readiness.
  • LOW. The staged script's name now comes from one prefix and suffix, shared by the generator and the matcher. A unit test passes the real defaultTmuxFileOps().tmpName() through isStagedSendScriptPath.
  • Checks:
    • unit (restart and tmux adapter, 190) and native (4, private tmux with the stub; HOME and CODEX_HOME set to a scratch dir) pass;
    • typecheck passes;
    • still applies on cb79b8c and on current main.

Refs OPR.0.7.0.5, #1196.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • In-place restarts now work for Codex sessions launched through the supported shell-based startup flow, while keeping the existing pane shell intact.
    • Restart planning continues to reject unsupported process chains, preventing signals from being sent to Codex when an unexpected intermediary is present. Only the recognized staged startup script is accepted; other wrappers and command forms remain unsupported.

…ough its staged script

OPR.0.7.0.5. OpenRig types every Codex launch (fresh, fork, resume, and this restart's own
relaunch) as `/bin/sh <tmpdir>/openrig-tmux-send-<pid>-<uuid>.txt`, so a managed Codex runs one sh
below the pane's shell, and `rig seat restart --keep-conversation` refused it as pane_shape_unknown
(the same chain on 0.6.10). The shell-backed shape now also accepts exactly that one link: an sh
whose only argument is an absolute path with the name the tmux adapter gives its staged scripts
(isStagedSendScriptPath). Any other process between the shell and Codex is still refused.

The native harness gains a case that launches through the adapter's staging and restarts twice in
the same pane (red on main). It also folds in #1196's fixture LOW: the direct-native case compares
the stub with the reported replacement process and ties it to the respawned pane separately, so it
holds where the image's sh doesn't exec a lone command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6564595f-74a8-4e84-bca1-aa67a05c5acd
📥 Commits

Reviewing files that changed from the base of the PR and between e773e5b and df7ee77.

📒 Files selected for processing (3)
  • packages/daemon/src/adapters/tmux.ts
  • packages/daemon/src/domain/seat-restart-in-place.ts
  • packages/daemon/test/seat-restart-in-place.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 3 remain after this review.

📝 Walkthrough

Shell-backed Codex restart detection now accepts a direct child process that runs the exact OpenRig-staged send script. Other intermediary process shapes remain rejected. Tests cover staged restarts, rejected process shapes, and direct-native replacement PID relationships.

Changes: Staged-shell Codex restart

Layer / File(s) Summary
Recognize staged shell launches
packages/daemon/src/adapters/tmux.ts, packages/daemon/src/domain/seat-restart-in-place.ts
The path matcher accepts absolute paths with the staged-send filename format. Shell-backed pane detection accepts Codex below the pane shell when the intermediate process runs the validated staged script.
Test restart and rejected process shapes
packages/daemon/test/seat-restart-in-place.test.ts, packages/daemon/test/seat-restart-in-place-native.test.ts
Tests cover repeated staged restarts, supported Linux and macOS process-name forms, rejected process shapes, and direct-native replacement PID relationships.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Suggested reviewers: lbny22727-create

Merge Risk: ⚪ Minimal · up to df7ee

No concrete current-head failure is established. The change recognizes the staged Codex launch while continuing to refuse unrecognized pane shapes.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: allowing in-place restart for Codex processes launched through OpenRig's staged script.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lbny22727-create lbny22727-create left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…ns as bash

#1212 round 1. P1-1 (dev60-review, measured on macOS): /bin/sh there is a shim that runs bash (or
dash or zsh), so ps names the staged script's process bash and the new link never matched. The
link now accepts the shells /bin/sh can run as (sh, bash, dash, zsh) for the process name, and
keeps every argv check: exactly two arguments, argv[0] /bin/sh or sh, and the staged absolute path.
A macOS-shaped fixture (bash, /bin/sh /var/folders/.../T/openrig-tmux-send-...) is accepted (red
before this change); `/bin/bash <script>` and an extra argument stay refused.

LOW: the staged script's name now comes from one prefix and suffix used by both the generator and
the matcher, and a unit test passes the real defaultTmuxFileOps().tmpName() through the matcher.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@openrig-review openrig-review left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at df7ee77. rig seat restart --keep-conversation now accepts the pane shape OpenRig itself produces when it launches Codex: the pane's shell running /bin/sh with exactly one argument, the absolute path of OpenRig's staged launch script, with Codex below it. On macOS, /bin/sh reports as bash, dash or zsh. Main refused that shape with pane_shape_unknown for every OpenRig-launched Codex seat, including seats launched by 0.6.10 and the restart's own relaunch. The match is a disclosed name check, not proof of origin. Every other shape is still refused, and the bound-pane, resume-identity, settings and typing gates are unchanged. Required CI passed at this head.

— dev60-planner@v-openrig-build

@mvschwarz
mvschwarz merged commit b100b4e into main Oct 13, 2026
10 checks passed
@mvschwarz
mvschwarz deleted the t4/s05-codex-launch-pane branch October 13, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants