Skip to content

fix(delegation): atomically serialize reopenParentFromDelegation#725

Draft
edelauna wants to merge 1 commit into
mainfrom
issue/365
Draft

fix(delegation): atomically serialize reopenParentFromDelegation#725
edelauna wants to merge 1 commit into
mainfrom
issue/365

Conversation

@edelauna

@edelauna edelauna commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #365

Description

Replaces the sentinel-based multi-step write in reopenParentFromDelegation (parent active → close child → child completed → clear sentinel) with a single atomicUpdatePair call that writes child=completed and parent=active in one lock acquisition — no intermediate state is ever persisted.

Key changes:

  • TaskHistoryStore.atomicUpdatePair — new public method that updates two HistoryItems within a single withLock acquisition. Both updaters run before any I/O; both files are written before the lock releases. Extracted upsertCore private helper to share the write+cache logic without triggering onWrite/index-write per record.
  • reopenParentFromDelegation steps 3–5removeClineFromStack (step 4) moved before the atomic write so any stale "active" status written by abortTask is immediately overwritten. Steps 3, 5, and 5B collapsed into one atomicUpdatePair(childTaskId, parentTaskId, ...) call. Falls back to updateTaskHistory for the parent if atomicUpdatePair fails.
  • TestsatomicUpdatePair unit tests added to TaskHistoryStore.spec.ts (happy path, concurrent upsert ordering, missing-ID throws, partial-failure/known-limitation, onWrite called once). history-resume-delegation.spec.ts updated to stub taskHistoryStore.atomicUpdatePair instead of updateTaskHistory; handoff-correctness and partial-failure tests added. nested-delegation-resume.spec.ts updated with taskHistoryStore stub.

Why child first: a crash after the child write but before the parent write leaves child=completed, parent=delegated — which reconcileDelegationState already handles (resumable). A crash after the parent write but before the child write would leave parent=active with child=active and no way to report back.

Test Procedure

cd src
npx vitest run __tests__/history-resume-delegation.spec.ts \
  __tests__/nested-delegation-resume.spec.ts \
  core/task-persistence/__tests__/TaskHistoryStore.spec.ts

All 6447 tests pass (npx vitest run).

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: No documentation updates required (internal persistence layer change).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Additional Notes

assertValidTransition referenced in the issue pseudocode is not implemented — the guard at the top of reopenParentFromDelegation (checking status === "delegated" || status === "active" and awaitingChildId === childTaskId) already enforces valid state before the updaters run, and no transition table exists in the codebase to validate against.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a5efb0fe-3848-4f15-a0f3-31ea9c2ff42e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/365

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.

@edelauna edelauna changed the title fix(delegation): atomically serialize reopenParentFromDelegation fix(delegation): atomically serialize reopenParentFromDelegation steps 3–5 (#365) Jun 26, 2026
@edelauna edelauna changed the title fix(delegation): atomically serialize reopenParentFromDelegation steps 3–5 (#365) fix(delegation): atomically serialize reopenParentFromDelegation Jun 26, 2026
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.15385% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/core/webview/ClineProvider.ts 85.71% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

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.

[Story 2.2] Serialize reopenParentFromDelegation steps 4–5

1 participant