Skip to content

feat: withdraw a waiting submission with POST /submissions/{id}/cancel - #3

Merged
cyrilcaoyang merged 1 commit into
mainfrom
feat/cancel-submission
Sep 7, 2026
Merged

feat: withdraw a waiting submission with POST /submissions/{id}/cancel#3
cyrilcaoyang merged 1 commit into
mainfrom
feat/cancel-submission

Conversation

@cyrilcaoyang

Copy link
Copy Markdown
Collaborator

The first live acceptance test on the P1S left an approved job in the queue with no way to remove it. This closes that gap.

Cancel is a queue operation, not an abort

Legal only from queued and approved (CANCELLABLE_STATES). It reaches no printer and is refused for anything past the queue — stopping a running print is a control-plane action that needs a claim, and this surface has none. That is structural rather than conventional: a test pins that cancelled is unreachable from dispatching / running / finished / failed / rejected, so it stays true once dispatch lands.

Other choices worth reviewing

  • The artifact is deleted, the record is not. A withdrawn job has no further use for its file, and it is the submitter's data. The job survives with the actor and any reason in its history, and artifact_removed: true marks that the file is gone. No undo — a withdrawn job is resubmitted, not revived.
  • Cancelling an approved job retracts dispatch_ready, or the record would still read as cleared to run.
  • A rejected job cannot be cancelled (409). Rejection is already terminal; overwriting it would muddy why the job ended.

Beyond the contract

The design's §5 state machine declares no cancelled state. Recorded in docs/TODO.md as an addition to fold back into SUBMISSION_PIPELINE_DESIGN.md when that doc is next revised, rather than editing the contract unilaterally here.

uv run ruff check . and uv run pytest -q (126 tests, 12 new) pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UQvsfEeDitEyNzbCwrcEdD

The first live acceptance test on the P1S left an approved job in the queue
with no way to remove it, which is what this closes.

Cancel is a queue operation, not an abort. It is legal only from `queued` and
`approved` (`CANCELLABLE_STATES`), reaches no printer, and is refused for
anything past the queue: stopping a running print is a control-plane action
that needs a claim, and this surface has none. A test pins that `cancelled` is
unreachable from `dispatching` / `running` / `finished` / `failed` / `rejected`.

Cancelling deletes the stored artifact -- a withdrawn job has no further use
for it, and it is the submitter's data -- and marks `artifact_removed`. The job
record stays, with the actor and any reason in its history, so the withdrawal
remains auditable. An approved job that is cancelled has `dispatch_ready`
retracted, or the record would still read as cleared to run. There is no undo;
a withdrawn job is resubmitted, not revived.

Note this goes beyond the design's §5 state machine, which declares no
`cancelled` state. Recorded in docs/TODO.md as an addition to fold back into
SUBMISSION_PIPELINE_DESIGN.md when that doc is next revised.

`uv run ruff check .` and `uv run pytest -q` (126 tests) pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQvsfEeDitEyNzbCwrcEdD
@cyrilcaoyang
cyrilcaoyang merged commit 7a96f93 into main Sep 7, 2026
1 check passed
@cyrilcaoyang
cyrilcaoyang deleted the feat/cancel-submission branch September 7, 2026 03:42
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.

2 participants