Skip to content

Recover an open issue left in-progress by a Run that was killed outright #710

Open

Description

@JacobStephens2

This was generated by AI during triage.

Split from #695.

Problem

A Run or Spec run killed outright (kill -9, an OOM kill, a power cut, a reboot) never ends its Claim. README.md says: "A process killed outright, with kill -9 or by a power cut, releases nothing: the issue stays in-progress for you to relabel." src/claim.rs ends a Claim only from inside the Run that made it. The Sweep only takes in-progress off closed issues. So an open issue whose Run died stays in-progress until the Day shift notices it. Its Worktree, local Issue branch and agent session are left behind too.

Recovery is possible today, but only by hand: a Continuation (ADR 0002) picks up from the Issue branch when someone reruns thirdshift on the issue.

What done looks like

A later Pass notices an open in-progress issue whose Run is no longer alive, and handles it without a human. It either continues the Run, resuming the agent session by id where the Harness allows, or ends the Claim the way a Failed run would.

Design questions

Background

The Temporal research in #694 (docs/research/temporal-for-thirdshift.md, §7) names crash recovery as the main thing Temporal would add. It recommends not adopting Temporal now.

Activity

  1. added
    in-progressA Claim: thirdshift has taken this issue
    and removed
    needs-triageMaintainer needs to evaluate this issue
    on Nov 10, 2026
  2. JacobStephens2 commented on Nov 10, 2026

    @JacobStephens2
    OwnerAuthor

    This was generated by AI during triage.

    Investigation summary

    The recovery gap remains on selected Base commit 9eea88c. Keep #710 open for a recovery-policy decision and proposed split.

    Evidence:

    • src/claim.rs:119 ends a Claim through the running process. SIGKILL prevents that completion path. The current manual explicitly documents the resulting stranded Claim (docs/guide.md:102).
    • src/pickup.rs:352 sweeps closed issues; it does not inspect open Claims for dead owners.
    • Existing local Command records already contain hostname, PID and process-start identity (src/logs/command_record.rs:87). src/logs/process_identity.rs combines boot identity with process-start ticks, handling PID reuse and reboot. The log reader already classifies unfinished records whose process is gone as died (src/logs/reading.rs:414). These provide reusable evidence, but do not associate exclusive recovery authority with the current Claim.
    • A killed Pass-started Run can also leave an origin reservation. Reservations already record Host, Process and Started (src/reservation.rs:64); normal release happens in Drop with an exact lease. Open Notice a reservation whose owning process has died #1959 addresses orphan reservations, but releasing a reservation does not end a Claim or preserve retained work. ADR 0017 explicitly distinguishes these operations.
    • Automatic Continuation needs more than relabelling: worktree acquisition refuses conflicting local branches (src/worktree.rs:155), and existing Resume handling operates inside a live Run (src/session.rs:337). Cross-Run session recovery needs separate design.
    • Parent death does not establish that all writers stopped. HeldRun::kill explicitly leaves descendants alive (tests/support/mod.rs:322); the killed-Run regression releases its surviving fake Harness later. Recovery must establish writer quiescence before allowing replacement work.

    Validation: cargo test --test pickup_run a_killed_pickup_run_or_ticket_run_frees_its_slot_for_the_next_pass -- --exact --nocapture passed (1 test). It confirms the Command slot is freed and the next Pass takes another Ready issue, rather than recovering the killed issue. scripts/affected-tests main reported no changed files; Git status and diff remained clean.

    Related issues are complementary: #1901 explicitly excludes #710; #1959 covers reservations; #833 covers identifying the Claim's host. #613 and #617 are closed and address graceful interruption and subsequent hand-back, respectively.

    Recommended next step: shape a staged Spec after the Day shift settles the questions below. Preserve ADR 0009's one-Pass model and ADR 0017's prohibition on timer-based reservation expiry. No GitHub writes or source/history changes were made.

    Questionnaire

    For the Day shift deciding #710: repository investigation confirms that killed Runs leave recovery work beyond the origin reservation covered by #1959. The following decisions are needed to make implementation actionable.

    1. Should Recover an open issue left in-progress by a Run that was killed outright #710 become a staged Spec with this split: (a) establish recovery ownership and reuse Notice a reservation whose owning process has died #1959 for orphan-reservation handling; (b) add idempotent Pass recovery that preserves retained work and ends the dead Run's Claim; (c) add automatic Continuation and cross-Run Harness session Resume as a later feature? This keeps reservation work from being filed twice and separates recovery from session restoration.
    2. For the first version, should recovery apply normal Failed-run handling, or start a bounded automatic Continuation? I recommend Failed-run handling first, aligned with Spec: in-progress marks only a live Run #1901/ADR 0029, with automatic Continuation deferred. This decides the resulting labels and retry behavior.
    3. Should the initial scope cover Ticket runs and Spec runs during Pickup and Triage Passes, or also Custom processes and existing-issue Triage runs? Their failure endings differ, so this determines the required cases.
    4. Should recovery initially act only when this host can verify the exact dead owner and establish that surviving writers have stopped, leaving foreign-host, legacy and uncertain ownership for the Day shift? For retained dirty files or unpushed commits, should it attempt the existing Failed-run preservation path or retain everything and report the blocker? I recommend preserving uncertain work without resetting or deleting it. These choices determine safe recovery authority and handling of leftovers.
  3. added and removed
    in-progressA Claim: thirdshift has taken this issue
    on Nov 10, 2026
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions