feat(runs): stopped and failed runs can be resumed; Abandon becomes Stop; redo confirmation redesign (#51) #53

Merged
cmoriarty merged 1 commit from stop-and-resume-runs into main 2026-09-26 16:46:04 -04:00
Owner

Refs #51 (closed after the OpenSpec change is archived). OpenSpec change: openspec/changes/stop-and-resume-runs.

Why

Stopping (abandoning) a run cancelled every step after the one it interrupted, and nothing ever put them back. A redo already re-opened the run and restarted its opencode server, so the redone step ran, and then the run dead-ended on the wall of cancelled steps.

What changed

  • Stop run replaces Abandon run; the run shows as stopped. Same behaviour. POST /api/runs/{id}/stop added; /abandon kept. The stored status and event keep their names, so recorded runs replay unchanged.
  • Resume run in the stage header and on the ledger row, and POST /api/runs/{id}/resume: re-opens a stopped or failed run and returns to pending what the stop ended (and, for a failed run, failed and unreachable steps). Each runs as a new attempt from its entry checkpoint; succeeded steps stay. Refuses succeeded, live, archived and reclaimed runs with a reason.
  • Redo on a stopped run carries the whole run on; its button reads "Resume and redo".
  • Redo confirmation redesign: what happens / what it undoes / what it cannot undo, one type style, empty sections omitted, the mechanism behind ⓘ, no "abandoned" wording.
  • A resumed step uses the current context per agent (already read per attempt); the run keeps its backend and model.

Verification

  • Backend: 1736 passed (new route tests in test_abandon.py, scheduler re-open tests in test_liveness.py).
  • UI: tsc -b, 381 vitest tests, vite build clean.
  • Playwright against the fake osfd: 66/68; the 2 failures are follow-the-tail, which needs a live osfd and fails identically on main.
  • In a real browser: stop a run → header shows Resume, not Stop; redo reads "Resume and redo"; Resume → run back to running.

🤖 Generated with Claude Code

Refs #51 (closed after the OpenSpec change is archived). OpenSpec change: `openspec/changes/stop-and-resume-runs`. ## Why Stopping (abandoning) a run cancelled every step after the one it interrupted, and nothing ever put them back. A redo already re-opened the run and restarted its opencode server, so the redone step ran, and then the run dead-ended on the wall of cancelled steps. ## What changed - **Stop run** replaces Abandon run; the run shows as **stopped**. Same behaviour. `POST /api/runs/{id}/stop` added; `/abandon` kept. The stored status and event keep their names, so recorded runs replay unchanged. - **Resume run** in the stage header and on the ledger row, and `POST /api/runs/{id}/resume`: re-opens a stopped or failed run and returns to pending what the stop ended (and, for a failed run, failed and unreachable steps). Each runs as a new attempt from its entry checkpoint; succeeded steps stay. Refuses succeeded, live, archived and reclaimed runs with a reason. - **Redo on a stopped run** carries the whole run on; its button reads "Resume and redo". - **Redo confirmation redesign:** what happens / what it undoes / what it cannot undo, one type style, empty sections omitted, the mechanism behind ⓘ, no "abandoned" wording. - A resumed step uses the current context per agent (already read per attempt); the run keeps its backend and model. ## Verification - Backend: 1736 passed (new route tests in `test_abandon.py`, scheduler re-open tests in `test_liveness.py`). - UI: `tsc -b`, 381 vitest tests, `vite build` clean. - Playwright against the fake osfd: 66/68; the 2 failures are `follow-the-tail`, which needs a live osfd and fails identically on main. - In a real browser: stop a run → header shows Resume, not Stop; redo reads "Resume and redo"; Resume → run back to running. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Stopping a run cancelled every step after the one it interrupted and nothing put them back, so
a redo re-opened the run and then dead-ended one step later. Resume (a header button, a ledger
action and POST /api/runs/{id}/resume) re-opens a stopped or failed run and returns to pending
what the stop or the failure ended; each runs again as a new attempt from its entry checkpoint,
and what succeeded stays. A redo on a stopped run does the same, so the run carries on past the
redone step. "Abandon run" is "Stop run" (POST /stop; /abandon kept), stored as before.

The redo confirmation answers what happens, what it undoes and what it cannot undo, in one type
style, leaving out empty sections and putting the mechanism behind ⓘ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cmoriarty deleted branch stop-and-resume-runs 2026-09-26 16:46:04 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cmoriarty/braid!53
No description provided.