Skip to content

fix(cursor,hub): defer ACP reopen merge until ACP session/load ready#949

Open
heavygee wants to merge 3 commits into
tiann:mainfrom
heavygee:spike/issue-917-idle-exit-test
Open

fix(cursor,hub): defer ACP reopen merge until ACP session/load ready#949
heavygee wants to merge 3 commits into
tiann:mainfrom
heavygee:spike/issue-917-idle-exit-test

Conversation

@heavygee

Copy link
Copy Markdown
Collaborator

Fixes #917

Summary

  • CLI emits a { type: 'ready' } event immediately after successful Cursor ACP bootstrap so the hub can detect load success before merging sessions.
  • Hub defers mergeSessions on Cursor ACP resume/reopen until the spawned session is active and has emitted ready (30s timeout).
  • Hub keeps archived metadata intact during reopen until resume succeeds; failed handshakes restore the archived row instead of silently merging it away.
  • Dedup skips merging archived Cursor ACP duplicates until the active target has emitted ready.

Problem

Investigation on the reported repro showed the archived session was merged away in ~2s while session/load was still failing — not after a ~90s idle timeout. Premature merge destroyed the recovery path.

Testing

Notes

Does not fix sessions whose ACP store genuinely cannot load (missing/corrupt store.db); those now fail with an error and preserved archive row instead of silent merge-away.

Made with Cursor

@github-actions github-actions Bot 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.

Findings

  • [Major] Legacy Cursor rows without cursorSessionProtocol now wait for an ACP-only ready handshake — resumeSession treats missing protocol as ACP via (metadata.cursorSessionProtocol ?? 'acp') === 'acp', but the CLI still routes the same metadata shape (flavor: cursor, cursorSessionId present, protocol missing) to the legacy stream-json launcher. Legacy stream-json does not emit the new ACP bootstrap ready event on the spawned new session, so reopen/resume waits 30s and returns resume_failed even though the legacy runner started. Evidence: hub/src/sync/syncEngine.ts:1162, cli/src/cursor/utils/cursorProtocol.ts:15.

Summary

  • Review mode: initial
  • One Major issue found: hub-side ACP detection diverges from CLI Cursor protocol routing for pre-#799 legacy rows.

Testing

  • Not run (automation). Suggested: add a hub reopen/resume test for a Cursor archived row with cursorSessionId and no cursorSessionProtocol, asserting it does not call waitForSessionResumeReady and can complete through legacy routing.

HAPI Bot

Comment thread hub/src/sync/syncEngine.ts Outdated
heavygee added a commit to heavygee/hapi that referenced this pull request Jun 18, 2026
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol
in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without
cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI.

Fixes HAPI Bot Major on tiann#949.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heavygee

Copy link
Copy Markdown
Collaborator Author

Addressed the [Major] in 62348c5:

  • Moved `isLegacyCursorSession` / `resolveCursorRemoteProtocol` to `shared/src/cursorProtocol.ts` (same rules as CLI).
  • Hub resume + dedup now call `resolveCursorRemoteProtocol(metadata) === 'acp'` instead of defaulting missing protocol to ACP.
  • Added tests: legacy archived reopen skips `waitForSessionResumeReady`; legacy dedup merges without ready event.

CI re-running on push.

@github-actions github-actions Bot 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.

Findings

  • No issues found.

Summary

  • Review mode: follow-up after new commits
  • Prior bot finding about legacy Cursor rows without cursorSessionProtocol was addressed by sharing resolveCursorRemoteProtocol between CLI and hub and covering the legacy reopen/dedup cases. Residual risk: this review did not execute the test suite.

Testing

  • Not run (automation).

HAPI Bot

heavygee added a commit to heavygee/hapi that referenced this pull request Jun 18, 2026
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol
in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without
cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI.

Fixes HAPI Bot Major on tiann#949.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heavygee heavygee force-pushed the spike/issue-917-idle-exit-test branch from 62348c5 to 2fc65ec Compare June 18, 2026 16:31

@github-actions github-actions Bot 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.

Findings

  • No issues found.

Summary

  • Review mode: follow-up after new commits
  • No issues found in the current diff. Re-checked Cursor ACP ready gating, archived-row preservation on failed reopen, legacy protocol routing, and the added regression tests. Residual risk: this review did not execute the test suite.

Testing

  • Not run (automation).

HAPI Bot

heavygee and others added 2 commits June 20, 2026 22:34
Hub waited only for runner webhook (active) before mergeSessions, so a
failed ACP session/load could delete the archived recovery row anyway.

Emit ready after bootstrap, wait for that handshake on Cursor ACP resume,
defer archive-metadata clear until success, and skip dedup merge of
archived cursor ACP rows until the target is ready.

Fixes tiann#917

Co-authored-by: Cursor <cursoragent@cursor.com>
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol
in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without
cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI.

Fixes HAPI Bot Major on tiann#949.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heavygee heavygee force-pushed the spike/issue-917-idle-exit-test branch from 2fc65ec to 09c9d84 Compare June 20, 2026 21:35

@github-actions github-actions Bot 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.

Findings

  • [Major] Preserve legacy Cursor protocol before spawning — reopenSession now calls resumeSession before clearSessionArchiveMetadata, so pre-#799 Cursor rows with cursorSessionId but no cursorSessionProtocol are spawned without ever stamping stream-json. The hub-side resolveCursorRemoteProtocol(metadata) correctly skips the ACP ready wait, but the new CLI process only receives --resume plus existingSessionId; bootstrapExistingSession preserves no protocol when the old row has none, so cursorRemoteLauncher defaults to ACP and tries session/load on a legacy stream-json id. This breaks the legacy fallback path covered by the new test because the test pre-creates the spawned session with no protocol instead of exercising CLI metadata bootstrap. Evidence: hub/src/sync/syncEngine.ts:1291, related CLI routing at cli/src/cursor/runCursor.ts:45, cli/src/cursor/loop.ts:59, cli/src/cursor/cursorRemoteLauncher.ts:11.

Questions

  • None.

Summary

  • Review mode: follow-up after new commits
  • One Major regression found: archived legacy Cursor sessions can be reopened through the ACP launcher instead of stream-json when migration is disabled/skipped.

Testing

  • Not run (automation).

HAPI Bot

Comment thread hub/src/sync/syncEngine.ts
Defer clearSessionArchiveMetadata until resume succeeds (tiann#917), but pre-tiann#799
rows need stream-json on the existing row before spawn so CLI bootstrap routes
to legacy launcher instead of defaulting to ACP session/load.

Fixes HAPI Bot Major on tiann#949.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions Bot 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.

Findings

  • No findings.

Questions

  • None.

Summary

  • Review mode: follow-up after new commits
  • The prior Major finding around legacy Cursor protocol stamping before spawn is addressed in this head. I did not find any new Blocker/Major/Minor issues in the changed lines. Residual risk is mainly the Cursor ACP reopen/dedup timing path, but the PR adds focused hub and CLI tests for the ready handshake, rollback, legacy skip, and dedup behavior.

Testing

  • Not run (automation).

HAPI Bot

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.

POST /reopen on archived cursor ACP session: spawned cursor-agent dies ~90s after successful ACP load, merges away the original (no recovery)

1 participant