Skip to content

[BUG] Cross-window stale subtask completion can orphan a newer child #1469

Description

@zoomote

Problem

With multiple VS Code windows sharing Zoo Code global storage, one extension host can finish an older delegated child after another host has already interrupted that child and re-delegated the parent to a newer child. The stale completion marks the parent active and clears its delegation pointers, leaving the newer child active but unable to return through attempt_completion.

Deterministic reproduction

A barrier-controlled harness using two production TaskHistoryStore instances against the same storage reproduced this 25/25 times:

  1. Parent P is delegated to child C.
  2. Host A passes reopenParentFromDelegation(P, C) ownership validation.
  3. Host B interrupts C, resumes P, and delegates P to child D.
  4. Host A applies C completion from its stale in-memory snapshot.
  5. D remains active with parentTaskId = P, while P becomes active with no awaitingChildId and completedByChildId = C.

Formal model

SPIN finds the same counterexample and violates this invariant:

If child D is active and delegated from parent P, P must be delegated and awaiting D.

The corrected model revalidates parent ownership inside the final transition and exhausts with zero assertion violations.

Root cause

reopenParentFromDelegation validates parent.awaitingChildId === childTaskId before message I/O, but its final atomicUpdatePair parent updater does not revalidate that relationship. atomicUpdatePair serializes only within one extension host; cross-process atomicity is explicitly not guaranteed.

Expected behavior

A stale child completion must abort without changing either record if the current parent snapshot no longer awaits that child. A newer delegated child and its parent linkage must remain intact.

TDD acceptance criteria

  • Add a deterministic two-store regression test using production persistence and real merge/lock behavior.
  • Prove the test fails on current main by producing the orphaned-child state.
  • Revalidate parent.status and parent.awaitingChildId inside the final pair update.
  • Reject stale completion before either child or parent is persisted.
  • Preserve normal child completion and interrupted-child resume behavior.
  • Run the complete Zoo Code test suite.

Related

Parent issue: #921
Broader task-history concurrency: #920
Original metadata-driven delegation: #9090
In-process atomic handoff: #725

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions