You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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–5 — removeClineFromStack (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.
Tests — atomicUpdatePair 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).
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related GitHub Issue
Closes: #365
Description
Replaces the sentinel-based multi-step write in
reopenParentFromDelegation(parentactive→ close child → childcompleted→ clear sentinel) with a singleatomicUpdatePaircall that writeschild=completedandparent=activein one lock acquisition — no intermediate state is ever persisted.Key changes:
TaskHistoryStore.atomicUpdatePair— new public method that updates twoHistoryItems within a singlewithLockacquisition. Both updaters run before any I/O; both files are written before the lock releases. ExtractedupsertCoreprivate helper to share the write+cache logic without triggeringonWrite/index-write per record.reopenParentFromDelegationsteps 3–5 —removeClineFromStack(step 4) moved before the atomic write so any stale"active"status written byabortTaskis immediately overwritten. Steps 3, 5, and 5B collapsed into oneatomicUpdatePair(childTaskId, parentTaskId, ...)call. Falls back toupdateTaskHistoryfor the parent ifatomicUpdatePairfails.atomicUpdatePairunit tests added toTaskHistoryStore.spec.ts(happy path, concurrent upsert ordering, missing-ID throws, partial-failure/known-limitation,onWritecalled once).history-resume-delegation.spec.tsupdated to stubtaskHistoryStore.atomicUpdatePairinstead ofupdateTaskHistory; handoff-correctness and partial-failure tests added.nested-delegation-resume.spec.tsupdated withtaskHistoryStorestub.Why child first: a crash after the child write but before the parent write leaves
child=completed,parent=delegated— whichreconcileDelegationStatealready handles (resumable). A crash after the parent write but before the child write would leaveparent=activewithchild=activeand 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.tsAll 6447 tests pass (
npx vitest run).Pre-Submission Checklist
Additional Notes
assertValidTransitionreferenced in the issue pseudocode is not implemented — the guard at the top ofreopenParentFromDelegation(checkingstatus === "delegated" || status === "active"andawaitingChildId === childTaskId) already enforces valid state before the updaters run, and no transition table exists in the codebase to validate against.