specs/025-resume-selected-executable/spec.md
Specification: Resume Retains Selected Executable Path
Feature Branch: t3/resume-selected-executable
Created: 2026-10-08
Status: Implemented
Input: When an agent session is launched with an explicit path-qualified binary (such as /opt/tools/codex), subsequent resume commands generated by session reporters and executed by pane.resume must retain the selected executable path rather than falling back to bare binary lookup in $PATH.
Problem
When a terminal pane is spawned with an explicit path-qualified executable (e.g. /opt/.../codex), the agent is detected by its executable basename. However, when session identity is reported via report-session or hook-event, the writers fetch the adapter's official resume argv via adapter.resume_capability(&session_id). Built-in adapters emit bare command names (e.g. ["codex", "resume", "<session_id>"]).
Consequently:
pane.agent.resume_argvstores a bare command ("codex"), losing the path qualifier from the original launch.- When the user or automation calls
pane.resume,h_pane_resumespawns this bare argv. If/opt/.../codexis not on$PATH, or if an incompatible binary exists earlier on$PATH,pane.resumeeither fails to spawn or invokes the wrong binary. - Furthermore, Codex local runtime probe (
supports_no_daemon) insignaltty-server::codexruns--no-daemon --versionagainstargv[0]. Ifargv[0]is bare"codex", probing fails or probes the wrong binary, disabling per-pane local runtime isolation.
Requirements
Functional Requirements
FR-001 (Executable Retention): When a pane's original launch
argv[0]is absolute (including relative launch paths anchored at spawn) and its filename/basename matches the bare official resume command (resume_argv[0]), the resume command'sargv[0]must be replaced with the original path-qualifiedargv[0].FR-002 (Preserve Adapter Arguments): The remaining arguments from the adapter's official resume command (e.g.
["resume", "<session_id>"]or["--resume", "<session_id>"]) must be retained intact. Original launch options, model names, profile arguments, or suffix flags must NOT be copied into the resume argv.FR-003 (Preserve Configuration Environment): The pane's retained
agent.config_env(e.g.CODEX_HOME,CLAUDE_CONFIG_DIR) must continue to be passed to the resumed process unchanged.FR-004 (Preserve Promoted Shells): If a pane was started with a shell (e.g.
/bin/bashor/usr/bin/zsh) and later promoted to an agent kind, the original basename ("bash") does not match the bare official command ("codex"). In this case, the helper must NOT replace the command; bare"codex"is preserved.FR-005 (Preserve Differing Basename Wrappers): If a pane was launched via a wrapper executable whose basename differs from the official agent command (e.g.
/usr/local/bin/codex-wrapper), the helper must NOT replace the command; bare"codex"is preserved.FR-006 (Preserve Explicit Manifest Templates): If an agent manifest specifies an explicit path-qualified resume template (e.g.
resume = ["/custom/bin/codex", "resume", "{session_id}"]), the helper must NOT override this explicit official path, even if its basename matches the launch binary.FR-007 (Dual Application Seams): The resolution helper must be applied:
- At both session identity writers:
h_hook_eventandh_pane_report_session. - At resume execution:
h_pane_resume, dynamically repairing existing panes or persisted snapshots that contain bare resume commands.
- At both session identity writers:
FR-008 (No Schema Changes): The IPC schema, parameter types, and wire models remain unchanged.
FR-009 (Stable Relative Launch): Anchor path-qualified relative executables to the initial spawn or split directory before process launch and store that absolute path in existing pane argv. Live cwd refresh must not redirect resume.
FR-010 (Legacy Relative Compatibility): A restored relative original launch path must not replace a bare adapter resume command, because the initial launch directory is not reliably persisted.
Matrix and Edge Cases
- Built-in Adapters Matrix:
codex-> official bare command"codex"claude-> official bare command"claude"opencode-> official bare command"opencode"cursor-> official bare command"cursor-agent"pi-> official bare command"pi"
- Path Qualification:
- Absolute paths (e.g.
/opt/agents/codex) are retained. - New relative paths containing
/are anchored to the launch directory before spawn/split and retained as absolute paths. Legacy relative snapshot paths keep the adapter command. - Bare commands (no
/, e.g.codex) remain bare.
- Absolute paths (e.g.
- Empty or Degenerate Inputs:
- Empty
original_argvor emptyoriginal_argv[0]leaves resume argv unchanged. - Empty
resume_argvreturns an empty vector without panic.
- Empty
Success Criteria
- SC-001: Pure unit tests in
signaltty-agentverify the matrix of all 5 built-in adapters, relative paths, empty inputs, bare commands, promoted shells, explicit manifest paths, wrapper differences, and suffix flags. - SC-002: Real IPC regression sibling test
report_session_builds_resume_retains_selected_executable_without_manifestlaunches an absolute Codex fixture without any manifest resume template, reports session, callspane.resume, and verifies bothfixture-resume:<id>andfixture-local-runtime. - SC-003: Hook-event writer and stale snapshot repair tests verify dynamic resolution at both entry points.
- SC-004: Zero new clippy warnings and formatting clean.