Skip to content

🤖 bug: a crash during a delegated workspace creation orphans the workspace #4983

Closed

Description

@ThomasK33

Problem

WorkspaceTurnManager.createWorkspaceTurn (mode "new") creates the target workspace (workspaceService.create) and only later persists the workspace-turn handle record (taskHandleStore.upsertWorkspaceTurn). Since #4841, every return or throw in between removes the created workspace through the _creationFinalizer (removeWhileTaskTreeLocked, which keeps a branch the creation only reused). A crash (SIGKILL, power loss) during the awaits in that window still leaves the checkout and its config row without any handle record. The owner cannot reach the workspace with mode "existing" (invalid_scope), so it stays orphaned until the user removes it by hand.

The awaits in the window are the target agent validation, resolveNodeAgentAiSettings, the lifecycle lock, desktop admission, the live-owner lock, and the record write itself.

The startup sweep clearOrphanedDelegatedConsentDefaults() already visits rows tagged mux.taskHandleId, but it only clears their pending consent.

Fix direction

At startup, find rows tagged mux.taskHandleId that have no matching handle record and whose live-owner lock is not held by a live process. Remove them with a forced removal that keeps the branch (the creation's own createdBranch is not persisted, so keeping it is the lossless choice). Do this in the same pass as the consent sweep.

This split out of #4819, whose non-crash exits #4841 fixed.

Refs #4819


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $25.30

Activity

  1. linear-code commented on Sep 28, 2026

    @linear-code
  2. ThomasK33 commented on Sep 29, 2026

    @ThomasK33
    MemberAuthor

    Picked up by the issue coordinator: workspace delegated-creation-orphan-sweep, branch delegated-creation-orphan-sweep


    Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

  3. ThomasK33 commented on Sep 29, 2026

    @ThomasK33
    MemberAuthor

    Parked: requirements for a future fix

    PR #5130 tried an automatic startup sweep that removes a crash-orphaned delegated target. It was closed unmerged and parked. Three review rounds each found a different missing safety gate, and the orphan is a visible, clean workspace the user can remove by hand. The branch delegated-creation-orphan-sweep (head 8febd715d0) is the reference implementation.

    A future attempt must satisfy all of these:

    • (a) An unforgeable binding between handle, target row and owner. workspace.create accepts any tags, and a stale live-owner lock proves only that a handle id existed. For example, the lock or record written at creation carries the target workspaceId and ownerId, and the sweep verifies both before it acts.
    • (b) An admission and mutation fence taken before the emptiness checks, so no turn, exec, terminal or other activity can start between the check and the deletion. This includes the sweeping backend's own activity. 🤖 fix: remove delegated targets orphaned by a crash before their handle record #5130 did this with a removal option that runs the checks under the removal's gate, admission hold and pendingRemoval marker, with a strict gate policy.
    • (c) Durable external-app markers honored. A native terminal or external editor takes no lease and may outlive the crash (hasUntrackableExternalAppOpen()).
    • (d) Proof that the target never ran work: no chat history, a clean checkout, and no commit that only its branch holds. The branch is kept.
    • (e) Non-worktree runtimes: 🤖 bug: the crash-orphan sweep leaves delegated targets on non-worktree runtimes #5129.

    Facts established in #5130:

    • Handle records are deleted only together with the owner's session dir.
    • readWorkspaceTurnFile returns null for corrupt records and for records written by a newer build, so a null there does not prove the record is absent.

    Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

  4. added
    needs-alignmentPR or Issue needs contributor alignment on design before implementation
    on Sep 29, 2026
  5. ThomasK33 commented on Sep 29, 2026

    @ThomasK33
    MemberAuthor

    Picked up by the issue coordinator: workspace plan-crash-orphan-sweep-4983, branches delegated-creation-binding (backend) and delegated-creation-banner (UI), as a 2-PR native stack.

    Approach (approved): surface orphaned delegated targets to the user instead of deleting them. A creator-written row field binds the target row to its handle and owner; a startup pass flags rows whose setup never finished; a banner offers the normal confirmed removal or Keep.


    Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $10.22

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

    backlogbugneeds-alignmentPR or Issue needs contributor alignment on design before implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions