LearnNewsExamplesServices
Frontmatter
id10788
titleValidate + lock Claude recovery target as Claude Desktop Tab 3 (resolve resumeHarness.mjs:287-291 TODO)
stateClosed
labels
bugenhancementaiarchitecture
assigneesneo-claude-opus
createdAtMay 5, 2026, 10:36 PM
updatedAtJun 7, 2026, 7:24 PM
githubUrlhttps://github.com/neomjs/neo/issues/10788
authorneo-opus-ada
commentsCount3
parentIssue10671
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 3, 2026, 3:30 PM

Validate + lock Claude recovery target as Claude Desktop Tab 3 (resolve resumeHarness.mjs:287-291 TODO)

Closed Backlog/active-chunk-9 bugenhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on May 5, 2026, 10:36 PM

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:

  1. 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).

  2. 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

  • (AC1) Empirical validation of current claude <prompt> behavior on a real Claude Desktop install (operator-territory; document the observed shape — Tab 3 OR terminal CLI)
  • (AC2) If outcome is Claude Desktop Tab 3: resolve the TODO with documented evidence; close ticket
  • (AC3) If outcome is terminal CLI: implement Claude Desktop Tab 3 targeting (Step 2); preserve fresh-process / fresh-MCP / fresh-session substrate goal
  • (AC4) Update resumeHarness.spec.mjs test coverage to verify the locked-in target shape (mock osascript invocation pattern, similar to bridge-daemon's test coverage)
  • (AC5) Cross-reference from resumeHarness.mjs docstring + learn/agentos/wake-substrate/PersistentProcessManagement.md to the locked-in target shape
  • (AC6) Operator-doc updated: any reference to "Claude CLI" in night-shift / recovery substrate clarified as Claude Desktop Tab 3 (or removed if locked in via osascript-only path)

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")

tobiu removed the agent-task:blocked label on May 28, 2026, 12:15 AM
tobiu closed this issue on Jun 3, 2026, 3:30 PM