Skip to content

fix(workflow): give stranded runs an exit - #14

Draft
decebal wants to merge 1 commit into
mainfrom
fix/run-exits
Draft

decebal wants to merge 1 commit into
mainfrom
fix/run-exits

Conversation

@decebal

@decebal decebal commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Every refusal caused by a pending operation now names the command that clears it. commit and verification point to checkpoint, verify or abandon. publication points to ship. The rest point to recover or abandon. Before this, handoff, plan, build and resume said "reconcile before execution" and recover said "requires its destination-specific resume command", so a run whose commit hook rejected the message looked permanently stuck.
  • New allstack abandon <run> --epoch N ends a run that will not ship. It checkpoints the active worktree, records a terminal abandoned event (new Stage::Abandoned), releases the Chronis task when this run holds the claim under any epoch, and removes the run's worktrees under the same unexpected-edit check as ship. It is refused once publication starts. Repeating it retries release and cleanup. Commits already made in the original checkout stay.
  • current treats an abandoned run as inactive. docs/reference/cli.md documents the new exit and the checkpoint route for a pending commit.

Test plan

  • cargo nextest run --locked: 90 passed, 2 skipped (the bootstrap tests that need a real Chronis)
  • cargo fmt --check, cargo clippy --all-targets --locked -- -D warnings
  • New stranded_commit_names_its_exits_and_can_be_abandoned: handoff and recover refusals name checkpoint, verify and abandon; a stale epoch is refused; abandon ends the run, build is refused afterwards, a repeat records no second event
  • New abandon_is_refused_once_publication_starts: refused mid-publication with a pointer to ship, refused after shipping, no task release in either case
  • New only_an_unpublished_run_can_be_abandoned_and_abandonment_is_terminal: event validation allows abandon from planning, building and verifying only, and nothing after it
  • Real cn in a scratch tracker: a claim held by allstack:<run>:codex:3 reads status:in-progress / claimed_by:<actor>, and cn release as that actor yields status:open, the fields Tasks::release parses
  • Quality on e7e4d8d: ubuntu-24.04, macos-15 and source-and-dependencies pass

Limits

  • Tasks::release has no automated test against a real Chronis; the adapter shape was checked by hand as above.
  • Not run against the stranded Longhand run 1596a6d9. Abandoning it would release t-b5248f.
  • abandon fails if the active worktree is missing, because it checkpoints first.

🤖 Generated with Claude Code

A run left pending a commit or verification refused handoff, plan,
build and resume with "reconcile before execution", and recover refused
with "requires its destination-specific resume command". None of them
named the command that clears the operation, so a run whose commit hook
rejected the message looked permanently stuck, though checkpoint and
verify both accept it. Every refusal on a pending operation now names
its clearing command.

A run nobody will ship also had no terminal state other than shipped,
so its Chronis task stayed claimed. allstack abandon <run> --epoch N
checkpoints the active worktree, records a terminal abandoned event,
releases the task when this run holds the claim under any epoch, and
removes the run's worktrees under the same unexpected-edit check as
ship. It is refused once publication starts. Repeating it retries the
release and cleanup.
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