Skip to content

design(recovery): reconcile abandoned claims without stealing work #1245

Closed

Description

@joryirving

Problem

Persisted assignment labels/claims can exclude otherwise eligible work after the original worker disappears or its identity changes. A claim is not proof of active execution, but absence of a Courier CoderRun is not proof of abandonment either.

Observed 2026-10-13: windowstead#398, pinchflat#109, and Courier#243 retained legacy agent/courier assignments. The configured frontier consumer was courier-frontier; default queue filtering excluded the other identity's claims. An operator explicitly released those three claims through Dispatch, after checking the corresponding cluster attempts; frontier immediately picked up windowstead#398. This demonstrates stale ownership can strand work, not that every legacy assignment should be released automatically.

Required design

  • Inventory current claim, lease, acknowledgement and AgentWork semantics. Define authoritative ownership/liveness evidence separately from GitHub assignment and status labels.
  • Support arbitrary worker clients, not just Courier. Define a minimal optional client capability for durable ownership/renewal/terminal disposition; specify safe handling for clients without that capability.
  • Distinguish abandoned execution, legitimate long-running work, review-owned work, external dependency waits, deliberate human assignments, and maintainer holds.
  • Specify bounded reconciliation, expiration/grace periods, restart recovery and explicit operator controls. Evidence that a worker is unreachable or telemetry is missing must not immediately mean abandonment.
  • Release only verified obsolete ownership atomically, with fencing against a renewed/replaced owner. Preserve attempt history, audits, genuine blocker reasons and linked-PR ownership; select the next eligible state rather than always forcing ready.
  • Treat legacy identity migration explicitly. Do not alias all agent/courier* identities, steal another consumer's assignment, or assume one app owns a whole family of labels.
  • Keep GitHub/cache/lease state consistent and expose unresolved or conflicting ownership as unknown. Bound reconciler retries and repeated release/reclaim churn.

Acceptance / design deliverable

An ownership state model, evidence hierarchy, compatibility/migration policy, reconciliation transition table, operator escape hatch, and race/failure cases. Include active renewal concurrent with release, disconnected workers, missing events, closed issues, open linked PRs, explicit holds and generic legacy assignments. Inspect existing mechanisms first; identify improvements rather than inventing a parallel lease system.

Related: misospace/courier#287 is local run retention; deleting local history must not become Dispatch's recovery algorithm. misospace/courier#320 concerns model exhaustion; quota reset alone must not release unrelated claims.

Non-goals

Design only. No claim release, blanket label cleanup, requeue, implementation, worker credential migration or deployment changes. Genuine human decisions remain held until explicitly resolved.

Activity

  1. joryirving commented on Oct 13, 2026

    @joryirving
    ContributorAuthor

    Implementation handoff (2026-10-13)

    Both remain status/blocked until design PR #1246 is accepted. Related #1202 is the existing lifecycle evidence stream, not something these issues should duplicate. Do not alias agent/courier* identities or turn missing telemetry into permission to steal work. Docs merge completes design, not implementation.

  2. added and removed
    status/in-reviewPull request or human review is in progress.
    on Oct 14, 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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions