Skip to content

Keep Claude's answer out of the fold when a task from an earlier turn wakes it - #1037

Open
zcy22606 wants to merge 1 commit into
hardbeat920:mainfrom
zcy22606:fix/woken-task-row
Open

zcy22606 wants to merge 1 commit into
hardbeat920:mainfrom
zcy22606:fix/woken-task-row

Conversation

@zcy22606

@zcy22606 zcy22606 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What changed

When Claude Code wakes itself for a background task that MonoCode is no longer tracking (the turn that started it is over), the task now gets a finished background row under the answer Claude yielded with, the same row it would have had if the turn had waited for it. The work Claude does after it wakes no longer folds that answer away.

Why

Claude Code wakes itself when a background task finishes, even after the MonoCode turn has ended. The adapter only follows tasks for the turn it has open:

  • sendClaudeTurn clears backgroundTasks / backgroundRows on every new message, and showBackgroundRows returns early when !live.activeTurn. So a task started before the latest message, or one Claude backgrounds in a turn it woke itself for (for example a watcher it re-arms on every wake), never gets a row.
  • When that task finishes, noteTaskNotification returns at if (!live.activeTurn) return;, so the answer still gets no row.
  • Claude's woken turn then streams its tool calls and text directly after the answer. yieldedAt() looks for a background row right after prose, finds none, and foldableWork() reads the answer as commentary on the work that follows and folds it.

The fix is in noteTaskNotification. Once Claude has yielded (turnResultSeen), a notification for a task that has no row adds one through the same tool.started as showBackgroundRows (now a small shared showBackgroundRow helper) and settles it right away. yieldedAt() then stops the fold at the answer. This doesn't change:

How it shows up (hit in daily use in a downstream fork with the same adapter code, with a heartbeat watcher Claude re-arms on every wake):

  1. A turn ends at Claude's answer while a background task Claude knows about is not tracked by the adapter (it was started before the latest message, or re-armed in a self-woken turn).
  2. The task finishes; Claude Code wakes and runs a command or two, then writes a short follow-up.
  3. The settled turn shows only the follow-up; the original answer is inside the "work" fold.

Related: #888 handles a different case in a different place. There the user writes in while the turn is still open and waiting, and the second answer has no row under it, so #888 marks yielded answers in core/apply.ts / transcriptActivity.ts from background.updated. Here the MonoCode turn has already ended, so background.updated never fires for the task, and #888's mark doesn't apply. This PR only touches the Claude adapter (claude.ts). The two don't overlap, and either can land first.

UI

No chrome change. The transcript now keeps the yielded answer above a finished background row instead of folding it. No screenshot because reproducing it needs a live background task that outlives the turn. The unit test below covers the transcript result.

Validation

  • New test keeps the answer above what a task from an earlier turn wakes Claude to do (claudeLive.test.ts): ends a turn at "The answer.", then sends a task_notification for an untracked task, followed by a woken turn (Bash + reply). It checks the block order and that the fold doesn't take the answer. It fails on main: there's no background row (['The answer.', '[tool]', 'Pushed back half an hour.']), and with that assertion removed, foldedBlocks contains 'The answer.'. It passes with this change.
  • New test adds no row for a task that finishes before Claude yields or after a stop: guards the mid-turn and post-stop paths. It passes on main as well; removing the new turnResultSeen check makes it fail.
  • npm run check:web: vitest 483 files / 5365 tests passed (2 files / 13 tests skipped), tsc --noEmit clean. No Rust touched, so I didn't run check:rust.
  • prettier --check is clean on the changed hunks. The test file has some pre-existing unformatted lines that I left alone.

Checklist

  • I ran npm run check (check:web; no Rust files changed)
  • This PR is small and focused
  • I did not mix unrelated changes

Summary by CodeRabbit

  • Bug Fixes
    • Improved background task notifications so completed answers stay in the correct order, and notifications received before Claude yields or after a turn stops don’t add background rows.
    • Ensured notifications during active turns settle existing rows correctly.

… wakes it

Claude Code wakes itself when a background task finishes, even after the
MonoCode turn has ended, but the adapter only tracks tasks for the turn it
has open. A task left from an earlier turn therefore had no row under the
answer Claude yielded with, and the work it woke Claude to do folded that
answer away. Once Claude has yielded, a notification for a task with no row
now adds a finished background row under the answer, so yieldedAt keeps it
out of the fold.
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f908555c-f34a-43a5-ba90-f3885b9a0cdc
📥 Commits

Reviewing files that changed from the base of the PR and between e49a5ae and d0a1a26.

📒 Files selected for processing: 2
  • src/integrations/harness/providers/claude/claude.ts
  • src/integrations/harness/providers/claude/claudeLive.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 5 remain after this review.

📝 Walkthrough

Claude task notifications now create, settle, or ignore background rows based on turn state and timing. New tests check transcript ordering and cases where notifications should not add rows.

Changes: Claude background task handling

Layer / File(s) Summary
Background-row creation and settlement
src/integrations/harness/providers/claude/claude.ts
A shared helper creates background rows. Existing rows can be settled while a turn is active.
Notification timing and transcript ordering
src/integrations/harness/providers/claude/claude.ts, src/integrations/harness/providers/claude/claudeLive.test.ts
Notifications before the turn result are ignored. After the result, agent notifications during an active turn become task notes; other notifications create and settle background rows. Tests check transcript order and ignored notifications.

Priority: ⬇️ Low

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

Change: Bug fix

Suggested reviewers: itizarsa

Merge Risk: ⚪ Minimal · up to d0a1a

Stopped turns do not add background rows from later notifications. No merge-blocking issue is established.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: preventing Claude's answer from being folded when a task from an earlier turn wakes it.
Description check Passed The description includes all required sections: What changed, Why, UI, and Checklist. It provides specific behavior, scope, validation results, and confirms the required checklist items.
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 a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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.

1 participant