docs(openspec): add task-cancellation proposal, design, specs, tasks

This commit is contained in:
2026-07-15 17:38:02 +08:00
parent a25542694d
commit 947434b65a
9 changed files with 655 additions and 0 deletions
@@ -0,0 +1,59 @@
## ADDED Requirements
### Requirement: Queued task cancellation is immediate
The system SHALL, when a cancellation is requested against a task in status `queued`, transition that task directly to status `cancelled` synchronously within the same request, without contacting any Host.
#### Scenario: Cancel a task that has not been assigned
- **WHEN** an authorized caller requests cancellation of a task whose status is `queued`
- **THEN** the task's status becomes `cancelled` in the same request and no assignment or lease is ever created for it
### Requirement: In-flight task cancellation is a durable, collaborative request
The system SHALL, when a cancellation is requested against a task in status `assigned` or `dispatched`, durably record a cancellation request against that task rather than immediately marking it `cancelled`, and SHALL surface that pending request to the owning Host Agent no later than its next lease renewal.
#### Scenario: Cancel a task currently executing on a Host
- **WHEN** an authorized caller requests cancellation of a task whose status is `dispatched`
- **THEN** the system records the cancellation request against the task's current attempt, the task's status remains `dispatched` until the Host reports a terminal result, and the request survives a control-plane restart
#### Scenario: Owning Host observes the pending cancellation at lease renewal
- **WHEN** the Host Agent executing the task renews its lease after a cancellation request was recorded
- **THEN** the renewal response signals the pending cancellation and the Host Agent stops further planned actions at the next available step boundary
#### Scenario: Cancellation is not instantaneous
- **WHEN** a cancellation is requested against a `dispatched` task
- **THEN** the system does not guarantee the task reaches status `cancelled` before the owning Host's next lease-renewal cycle completes
### Requirement: Host reports a cancelled outcome distinct from a failed outcome
The Host Agent SHALL report a terminal status of `cancelled`, distinct from `failed`, when its active execution stopped because of an observed cancellation request rather than a lease loss or an execution error, and the control plane SHALL record that task as status `cancelled`.
#### Scenario: Execution stops due to a cancellation request
- **WHEN** the Host Agent's active `TaskRunner` or `WorkflowRunner` execution stops because a lease renewal signaled a pending cancellation
- **THEN** the Host Agent reports terminal status `cancelled`, and the control plane transitions the task to status `cancelled` and releases its device reservation
#### Scenario: Execution stops due to lease loss unrelated to cancellation
- **WHEN** the Host Agent's active execution stops because its lease was rejected or lost for a reason other than a pending cancellation
- **THEN** the Host Agent reports terminal status `failed`, not `cancelled`
### Requirement: Cancellation requests are idempotent
The system SHALL treat a repeated cancellation request against a task that already has a pending or completed cancellation as a no-op that returns the task's current status, rather than as an error.
#### Scenario: Cancel a task twice
- **WHEN** an authorized caller requests cancellation of a task that already has a pending cancellation request recorded
- **THEN** the system returns the same successful response as the first request without creating a duplicate cancellation record
#### Scenario: Cancel an already-cancelled task
- **WHEN** an authorized caller requests cancellation of a task whose status is already `cancelled`
- **THEN** the system returns success reflecting the `cancelled` status without error
### Requirement: Cancellation is rejected for tasks already in a terminal, non-cancelled state
The system SHALL reject a cancellation request against a task whose status is already `done` or `failed` with a clear conflict error, without altering that task's recorded outcome.
#### Scenario: Cancel a completed task
- **WHEN** an authorized caller requests cancellation of a task whose status is `done`
- **THEN** the system rejects the request with a conflict error and the task's status and result remain unchanged
### Requirement: An expiring lease on a task with a pending cancellation resolves to cancelled, not requeued
The system SHALL, when an active lease expires on a task that has a pending cancellation request, mark that task `cancelled` rather than returning it to `queued` for a further attempt.
#### Scenario: Lease expires while a cancellation is pending
- **WHEN** the active lease on a `dispatched` task with a pending cancellation request expires before a terminal result is reported
- **THEN** the task transitions to status `cancelled` and its device reservation is released, instead of being requeued for another attempt