Skip to content

fix(server): recover OpenCode turns from live busy status - #11640

Open
hugojosefson wants to merge 1 commit into
pingdotgg:mainfrom
hugojosefson:fix/opencode-busy-recovery
Open

hugojosefson wants to merge 1 commit into
pingdotgg:mainfrom
hugojosefson:fix/opencode-busy-recovery

Conversation

@hugojosefson

@hugojosefson hugojosefson commented Sep 13, 2026 •

Copy link
Copy Markdown

Note

🤖 Prepared by GPT-6 Astra on behalf of hugojosefson

OpenCode can report busy after T3 Code records a turn as completed or failed. The adapter ignores that status when activeTurnId is missing. Output can continue while T3 shows Idle and has no active-turn protection from session cleanup.

On a parent-session busy or retry event, this change checks live OpenCode status before it creates one active turn. It rechecks session ownership, generation, and cancellation after the request. User Stop prevents recovery. No status polling is added.

This corrects recovery after a terminal state. #10805 prevents completion before work ends. This PR applies directly to main. It works without the changes from #10805.

Validation:

  • Two synthetic regression tests failed on base 77bca8b2 and passed with this correction.
  • All 202 focused adapter, provider, and ingestion tests passed.
  • Targeted lint, server typecheck, and git diff --check passed.
  • Tests cover live busy after completion or failure, stale busy events with live idle or unknown status, duplicate events, completion, and Stop during recovery.

The PR build at 881f9db897733181227fede49aa45d97124dc972 passed an isolated development check on September 13, 2026. The compiled server used a new database and a synthetic OpenCode HTTP/SSE server. Commands and state updates used the actual T3 WebSocket API.

Live checks:

  • A completed turn returned to running with a new active turn after verified busy status.
  • A turn with an error returned to running after verified busy status.
  • A stale busy event with live idle status did not start an active turn.
  • Recovered work completed and cleared its active turn.
  • Stop sent one OpenCode abort request and set interrupted with no active turn.
  • A subsequent busy event did not cancel Stop.

The unchanged client helpers received actual WebSocket session states. They returned Working and the correct Stop command during recovered work. That Stop command produced the abort result above. After Stop, the helpers returned no Stop command.

The check used event receipts, with timeouts only as failure limits. It did not use private data or model inference. No new browser or desktop rendering check was performed.

Server artifact SHA256:

029253c00c3cf744dc21c9d67495a9a4fc128c7a3824b2b78bbc0624e35e7ce7

A stable v0.0.40 build with this correction and #10805 completed an unattended turn of about 69 minutes with two compactions. T3 showed Working with a Stop button, work continued after compaction, and the turn finished. This is live desktop evidence for the combined build. The isolated development check above used only this PR on main.

If the live status request fails, recovery waits for another busy event. Intentional Stop remains authoritative until a new T3 turn clears that state.

Model: GPT-6. Harness: Codex.

Summary by CodeRabbit

  • Bug Fixes
    • Improved recovery when a session reports a busy or retrying state without an active turn.
    • Eligible sessions now resume processing automatically and display the correct running state.
    • Prevented interrupted, failed, idle, or otherwise ineligible sessions from being incorrectly resumed.
    • Stop actions remain effective while session recovery is still being evaluated.

Read the live OpenCode status before recovery after an idle or error event.
Start one active turn when the server reports busy work.
Keep user Stop active during recovery.

Tests include stale status, duplicate busy events, completion, and Stop during recovery.
@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Sep 13, 2026
@github-actions github-actions Bot added the size:M 30-99 changed lines (additions + deletions). label Sep 13, 2026
@hugojosefson
hugojosefson marked this pull request as ready for review September 13, 2026 21:58
@cursor

cursor Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 7cd9694d-8fb9-4dbb-aa0a-b3aab7e90a9b

📥 Commits

Reviewing files that changed from the base of the PR and between 77bca8b and 881f9db.

📒 Files selected for processing (2)
  • apps/server/src/provider/Layers/OpenCodeAdapter.test.ts
  • apps/server/src/provider/Layers/OpenCodeAdapter.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The OpenCode adapter now recovers eligible busy or retry sessions when no turn is active. Tests cover recovery conditions, replacement turn state, preserved session states, cleanup, and interruption during pending status recovery.

Changes

OpenCode busy-turn recovery

Layer / File(s) Summary
Busy-status recovery flow
apps/server/src/provider/Layers/OpenCodeAdapter.ts
Busy or retry status events without an active turn now trigger live-status validation. Eligible sessions receive a new turn, running state, reset token usage, and a turn.started event.
Recovery validation
apps/server/src/provider/Layers/OpenCodeAdapter.test.ts
Parameterized tests cover prior turn states and live statuses. Concurrency tests verify that interruption prevents recovery and performs one abort request.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: t3dotgg

Sequence Diagram(s)

sequenceDiagram
  participant OpenCode
  participant OpenCodeAdapter
  participant ProviderSession
  OpenCode->>OpenCodeAdapter: Send busy or retry session.status
  OpenCodeAdapter->>OpenCode: Poll session.status
  OpenCodeAdapter->>ProviderSession: Create active turn and set running
  OpenCodeAdapter->>ProviderSession: Emit turn.started
Loading

Merge Risk: ⚪ Minimal · up to 881f9

The recovery path safely abandons a live-status check when it cannot obtain a result, with no concrete merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: recovering OpenCode turns from a live busy status.
Description check ✅ Passed The description explains what changed, why it changed, the recovery behavior, Stop handling, tests, and validation results. It does not use the template headings or include the checklist, but the requ…
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@hugojosefson

Copy link
Copy Markdown
Author

Note

🤖 GPT-6 Astra responding on behalf of hugojosefson

I examined the docstring coverage warning. recoverBusyOpenCodeTurn is an internal helper. I kept the local comments, in accordance with repository guidance. They give the reason for the live status check.

The isolated development check passed on commit 881f9db8. The PR body records the artifact hash, behavior checks, and test limits.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant