Skip to content

Implementation Plan: Separate reset_dispatch State Reset from Artifact Destruction#4115

Merged
Trecek merged 6 commits into
developfrom
reset-dispatch-is-too-destructive-should-preserve-state-for/4114
Jun 26, 2026
Merged

Implementation Plan: Separate reset_dispatch State Reset from Artifact Destruction#4115
Trecek merged 6 commits into
developfrom
reset-dispatch-is-too-destructive-should-preserve-state-for/4114

Conversation

@Trecek

@Trecek Trecek commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Refactor reset_dispatch to decouple internal state reset from external artifact destruction by adding a destroy_artifacts parameter (default False). Promote issue_url to an identity field so it survives retry resets. Extend find_dispatch_for_issue to search PENDING dispatches with a staleness guard to prevent double-dispatch races. These changes make force=true orthogonal to artifact preservation — force bypasses the resume gate, destroy_artifacts controls whether worktrees/branches/PRs are removed. Campaign-level artifact sweep is deferred to a follow-up task.

Implementation Plan

Plan file: /home/talon/projects/autoskillit-runs/impl-20260626-092004-754802/.autoskillit/temp/make-plan/reset_dispatch_preserve_state_plan_2026-06-26_093000.md

Closes #4114

🤖 Generated with Claude Code via AutoSkillit

Token Usage Summary

Step Model count uncached output cache_read peak_ctx turns cache_write time
plan* opus[1m] 1 5.6k 20.4k 1.2M 110.3k 45 82.6k 22m 11s
review_approach* sonnet 1 6.6k 6.2k 222.7k 54.9k 16 40.4k 8m 55s
verify* opus[1m] 1 66 15.7k 2.2M 100.2k 55 81.5k 10m 33s
implement* MiniMax-M3 1 107.7k 22.4k 5.3M 0 144 0 8m 32s
fix* sonnet 1 438 25.9k 4.6M 112.1k 122 93.7k 11m 16s
Total 120.5k 90.6k 13.6M 112.1k 298.2k 1h 1m

* Step used a non-Anthropic provider; caching behavior may differ.

Token Efficiency

Step LoC Changed cache_read/LoC cache_write/LoC output/LoC
plan 0
review_approach 0
verify 0
implement 389 13601.9 0.0 57.5
fix 35 131817.6 2676.3 740.9
Total 424 32035.4 703.4 213.6

Model Usage Breakdown

Model steps uncached output cache_read cache_write time
opus[1m] 2 5.7k 36.1k 3.5M 164.1k 32m 45s
sonnet 2 7.1k 32.1k 4.8M 134.1k 20m 11s
MiniMax-M3 1 107.7k 22.4k 5.3M 0 8m 32s

Trecek and others added 6 commits June 26, 2026 09:59
The issue URL identifies what's being worked on (the issue), not the specific
dispatch attempt. Promoting it to an identity field ensures it survives retry
state resets, enabling label cleanup and dispatch lookup after a reset.

This makes T1 and T2 pass.
Decouple internal state reset from external artifact destruction. By default,
reset_dispatch now swaps labels and resets state while preserving the worktree,
branches, and PRs. Pass destroy_artifacts=True to invoke the existing
destruction path (worktree removal, branch deletion, PR closure).

The runner is now only required when destroy_artifacts=True, since the
state-only path doesn't need subprocess access.

The response envelope now includes destroy_artifacts: bool.

Makes T5, T6, T7, T8 pass.
…ENDING guard to claim helper

find_dispatch_for_issue:
- Add Pass 3 that searches for stale PENDING dispatches matching the issue URL.
  A PENDING dispatch matches when it has attempt_history (was previously
  dispatched), no active dispatched_session_id (no fresh claim), no
  labels_cleaned flag, and either ended_at=0.0 (process crashed without
  recording end time) or ended_at is older than 60s (the quiet period).
  RUNNING and TERMINAL_UNCLEANED passes continue to take priority.

_try_claim_with_liveness:
- Add a PENDING-status branch that returns claimed=False with a 'pending retry'
  reason. This prevents a returned PENDING dispatch from falling through to the
  dead-dispatch cleanup path and unblocking a claim that should be blocked.

Makes T9-T15 and T16 pass.
…tch PENDING search, claim PENDING block

- T1-T2 (test_retry_failed_dispatch.py): issue_url is an identity field
  preserved through retry resets.
- T5-T8 (test_tools_fleet_reset.py): reset_dispatch state-only default,
  destroy_artifacts=True preserves full destruction, state-only still cleans
  labels using dispatch.issue_url, force=True is orthogonal to destroy_artifacts.
- T9-T15 (test_find_dispatch_for_issue.py): PENDING stale match, too-fresh skip,
  empty history skip, active session skip, RUNNING/TERMINAL beats PENDING,
  ended_at=0.0 treated as stale.
- T16 (test_claim_liveness.py): PENDING dispatch blocks claim with
  'pending retry' reason; cleanup_orphaned_labels is not called.
…kipped

Change time.time() - 10 to time.time() - 5, giving 55 seconds of CI
slack before xdist scheduling delays could push the age past the
60-second quiet period threshold and flip the test verdict.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Trecek Trecek added this pull request to the merge queue Jun 26, 2026
Merged via the queue into develop with commit 0d13966 Jun 26, 2026
3 checks passed
@Trecek Trecek deleted the reset-dispatch-is-too-destructive-should-preserve-state-for/4114 branch June 26, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant