Context
Surfaced 2026-05-05 by @tobiu (relayed via @neo-gpt's empirical research): the Claude recovery target in resumeHarness.mjs:287-291 carries an open TODO about whether claude <prompt> invocation lands in Claude Desktop Tab 3 ("Code" tab) OR a terminal-attached CLI session.
Per @tobiu's calibration: "Claude CLI is a flaw for our harness target. We are using Claude Desktop in 2026, with the third tab being Claude Code. That is the target, not terminal-attached Claude CLI." The ambiguity is no longer acceptable.
The Problem
resumeHarness.mjs:287-291 (verbatim):
* @todo Empirically verify whether `claude <prompt>` lands as Claude Desktop Tab 3
* ("Code" tab) or a terminal-attached CLI session. Either satisfies the
* fresh-process / fresh-MCP / fresh-session substrate goal, but the operator
* surface differs. Document the observed shape post-verification.
Two failure modes from the unresolved TODO:
Substrate uncertainty: the recovery dispatcher doesn't know empirically which Claude target it lands in. If implementation drifts toward terminal-CLI without operator-territory verification, night-shift recovery would land in an environment that doesn't match the operator's working environment (Claude Desktop with Code tab is the deployed shape; terminal-CLI is a developer-only path).
Validation milestone blocker: #10671 epic-finish requires sunsetted-harness E2E recovery (kill harness → restart → fresh prompt → fresh MC session id → no extra-instance spam). Without verifying the recovery target, the "fresh prompt" step's success-shape is undefined.
The Architectural Reality
ai/scripts/resumeHarness.mjs:287-291 — the open TODO + comment block
resolveClaudeCliPath() (referenced at line 295) — current implementation resolves claude CLI binary path; uncertain whether invocation lands in Desktop Tab 3 OR terminal session
bridge-daemon.mjs — already knows Claude Desktop shape (Cmd+3 for the Code tab); proven working in current session via osascript
CLAUDE_CLI_PATH env var — operator override for test-mock injection per #10681 RUN_LIVE_OSASCRIPT discipline parallel
- @tobiu's deployed environment: Claude Desktop in 2026 with Code tab as Tab 3
The Fix
Two distinct work items:
Step 1: Empirical validation (operator-territory)
Operator-side verification of the current claude <prompt> invocation behavior. Concrete validation procedure:
<h1 class="neo-h1" data-record-id="7">In a controlled environment (not a real recovery scenario):</h1>
node ai/scripts/resumeHarness.mjs @neo-opus-ada "test recovery prompt" "" 0
<h1 class="neo-h1" data-record-id="8">Observe where the prompt lands:</h1>
<h1 class="neo-h1" data-record-id="9">(a) Claude Desktop opens / focuses Tab 3 with the prompt visible</h1>
<h1 class="neo-h1" data-record-id="10">(b) Terminal session opens with claude CLI + prompt</h1>
If outcome (a): current code is correct shape; just resolve the TODO with documented evidence.
If outcome (b): current code is wrong shape; needs replacement (Step 2).
Step 2: Replace if needed (agent-side authoring)
If empirical validation shows the wrong target, replace the claude CLI invocation with Claude Desktop Tab 3 targeting:
- Use
osascript parallel to bridge-daemon's existing pattern (which already knows Tab 3 = Cmd+3)
- Open Claude Desktop application + focus Tab 3 + paste the recovery prompt
- Preserve the fresh-process / fresh-MCP / fresh-session substrate goal (per existing
resumeHarness.mjs design — fresh OS process boundary forces fresh currentSessionId by construction)
The replacement substrate may be lighter than expected if bridge-daemon.mjs already has osascript-via-Cmd+3 helper logic that can be reused.
Acceptance Criteria
Out of Scope
- Linux/Windows Claude Desktop variants — sibling concern (per
resumeHarness.mjs:285 @todo Abstract for cross-platform execution (Windows/Linux) — sibling concern to #10684)
- Claude Desktop auto-update path resolution — already handled by
resolveClaudeCliPath() per existing code
- Antigravity / Codex Desktop sibling validation — separate sub-tickets of #10671 (already covered under #10677 / #10678 / #10679 closed subs of #10671)
Avoided Traps
- Implementing without empirical validation first: AC1 must establish ground truth before AC3 fires. Per
feedback_verify_before_assert.md umbrella — same family of pattern that produced #10782's wrong-shape blocker.
- Treating "either satisfies the substrate goal" as acceptable per the original TODO comment: @tobiu's calibration explicitly rejects ambiguity — Claude Desktop Tab 3 is the locked target, not "either CLI or Desktop is fine."
- Bundling with #10787 daemon-only entrypoint: different scope. #10787 is about WHICH script the launchd plist targets; this ticket is about WHERE the recovery prompt lands. Both are #10671 epic-finish prerequisites, but distinct.
Related
- Parent epic: #10671 (substrate-restart recovery)
- Sibling sub: #10787 (daemon-only entrypoint for swarm-heartbeat)
- Sibling sub: #10786 (test-isolation bug in harnessLifecycle.spec.mjs)
- Existing target-uncertainty surfaces:
resumeHarness.mjs:287-291 (the TODO this ticket resolves)
- Cross-platform sibling: #10684 (Windows/Linux variants — out-of-scope here)
- Empirical anchor: @tobiu's calibration relayed via @neo-gpt 2026-05-05 ~20:33Z (A2A MESSAGE:12f69838-8e89-4693-99a2-d35e796a308a)
Origin Session ID: 23b9cbcd-4938-4a46-b21a-0d48dd12e7e7
Retrieval Hint: query_raw_memories(query="Claude Desktop Tab 3 recovery target resumeHarness claude-cli ambiguity 287-291 TODO 10671 night-shift")
Context
Surfaced 2026-05-05 by @tobiu (relayed via @neo-gpt's empirical research): the Claude recovery target in
resumeHarness.mjs:287-291carries an open TODO about whetherclaude <prompt>invocation lands in Claude Desktop Tab 3 ("Code" tab) OR a terminal-attached CLI session.Per @tobiu's calibration: "Claude CLI is a flaw for our harness target. We are using Claude Desktop in 2026, with the third tab being Claude Code. That is the target, not terminal-attached Claude CLI." The ambiguity is no longer acceptable.
The Problem
resumeHarness.mjs:287-291(verbatim):* @todo Empirically verify whether `claude <prompt>` lands as Claude Desktop Tab 3 * ("Code" tab) or a terminal-attached CLI session. Either satisfies the * fresh-process / fresh-MCP / fresh-session substrate goal, but the operator * surface differs. Document the observed shape post-verification.Two failure modes from the unresolved TODO:
Substrate uncertainty: the recovery dispatcher doesn't know empirically which Claude target it lands in. If implementation drifts toward terminal-CLI without operator-territory verification, night-shift recovery would land in an environment that doesn't match the operator's working environment (Claude Desktop with Code tab is the deployed shape; terminal-CLI is a developer-only path).
Validation milestone blocker: #10671 epic-finish requires sunsetted-harness E2E recovery (kill harness → restart → fresh prompt → fresh MC session id → no extra-instance spam). Without verifying the recovery target, the "fresh prompt" step's success-shape is undefined.
The Architectural Reality
ai/scripts/resumeHarness.mjs:287-291— the open TODO + comment blockresolveClaudeCliPath()(referenced at line 295) — current implementation resolvesclaudeCLI binary path; uncertain whether invocation lands in Desktop Tab 3 OR terminal sessionbridge-daemon.mjs— already knows Claude Desktop shape (Cmd+3 for the Code tab); proven working in current session viaosascriptCLAUDE_CLI_PATHenv var — operator override for test-mock injection per #10681RUN_LIVE_OSASCRIPTdiscipline parallelThe Fix
Two distinct work items:
Step 1: Empirical validation (operator-territory)
Operator-side verification of the current
claude <prompt>invocation behavior. Concrete validation procedure:<h1 class="neo-h1" data-record-id="7">In a controlled environment (not a real recovery scenario):</h1> node ai/scripts/resumeHarness.mjs @neo-opus-ada "test recovery prompt" "" 0 <h1 class="neo-h1" data-record-id="8">Observe where the prompt lands:</h1> <h1 class="neo-h1" data-record-id="9">(a) Claude Desktop opens / focuses Tab 3 with the prompt visible</h1> <h1 class="neo-h1" data-record-id="10">(b) Terminal session opens with claude CLI + prompt</h1>If outcome (a): current code is correct shape; just resolve the TODO with documented evidence. If outcome (b): current code is wrong shape; needs replacement (Step 2).
Step 2: Replace if needed (agent-side authoring)
If empirical validation shows the wrong target, replace the
claudeCLI invocation with Claude Desktop Tab 3 targeting:osascriptparallel to bridge-daemon's existing pattern (which already knows Tab 3 = Cmd+3)resumeHarness.mjsdesign — fresh OS process boundary forces freshcurrentSessionIdby construction)The replacement substrate may be lighter than expected if
bridge-daemon.mjsalready hasosascript-via-Cmd+3 helper logic that can be reused.Acceptance Criteria
claude <prompt>behavior on a real Claude Desktop install (operator-territory; document the observed shape — Tab 3 OR terminal CLI)resumeHarness.spec.mjstest coverage to verify the locked-in target shape (mockosascriptinvocation pattern, similar to bridge-daemon's test coverage)resumeHarness.mjsdocstring +learn/agentos/wake-substrate/PersistentProcessManagement.mdto the locked-in target shapeOut of Scope
resumeHarness.mjs:285@todo Abstract for cross-platform execution (Windows/Linux) — sibling concern to #10684)resolveClaudeCliPath()per existing codeAvoided Traps
feedback_verify_before_assert.mdumbrella — same family of pattern that produced #10782's wrong-shape blocker.Related
resumeHarness.mjs:287-291(the TODO this ticket resolves)Origin Session ID: 23b9cbcd-4938-4a46-b21a-0d48dd12e7e7
Retrieval Hint:
query_raw_memories(query="Claude Desktop Tab 3 recovery target resumeHarness claude-cli ambiguity 287-291 TODO 10671 night-shift")