- ExecutionMode enum adds Undecided variant (default for new tasks)
- Webhook creates tasks as Undecided instead of hardcoded SshCli
- Dispatch loop: Phase 1 matches ssh_cli hosts, Phase 2 marks remaining as HttpPull
- Dequeue now returns http_pull AND undecided tasks (atomic claim)
- New endpoint: POST /api/v1/tasks/{id}/assign for coordinator explicit assignment
- Backward compatible: existing SshCli/HttpPull tasks unaffected
- 37 tests passing (6 new)
82 lines
4 KiB
Markdown
82 lines
4 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: ExecutionMode enum includes Undecided variant
|
|
`ExecutionMode` enum SHALL include an `Undecided` variant as the default for newly created tasks.
|
|
|
|
#### Scenario: Task created via Forgejo webhook
|
|
- **WHEN** a Forgejo Issue webhook creates a task
|
|
- **THEN** `execution_mode` SHALL be `Undecided`
|
|
- **AND** the task SHALL be eligible for both ssh_cli dispatch and http_pull dequeue
|
|
|
|
#### Scenario: Task created via API
|
|
- **WHEN** a task is created via direct API call without specifying execution_mode
|
|
- **THEN** `execution_mode` SHALL default to `Undecided`
|
|
|
|
### Requirement: Two-phase dispatch loop
|
|
The dispatch loop SHALL use a two-phase approach to handle `Undecided` tasks.
|
|
|
|
#### Scenario: Undecided task with matching ssh_cli host
|
|
- **GIVEN** an `Undecided` task with labels `["agent:code"]`
|
|
- **AND** a registered ssh_cli host with agent capabilities matching `["agent:code"]`
|
|
- **WHEN** the dispatch loop runs
|
|
- **THEN** the task SHALL be assigned `execution_mode = SshCli`
|
|
- **AND** the task SHALL be dispatched via SSH for execution
|
|
|
|
#### Scenario: Undecided task with no matching ssh_cli host
|
|
- **GIVEN** an `Undecided` task with labels `["agent:review", "agent:document"]`
|
|
- **AND** no registered ssh_cli host with matching capabilities
|
|
- **WHEN** the dispatch loop runs
|
|
- **THEN** the task SHALL be assigned `execution_mode = HttpPull`
|
|
- **AND** the task SHALL become available for http_pull dequeue
|
|
|
|
#### Scenario: Undecided task with matching ssh_cli host but agent offline
|
|
- **GIVEN** an `Undecided` task with matching ssh_cli host
|
|
- **AND** the ssh_cli host is unreachable or agent is offline
|
|
- **WHEN** the dispatch loop runs
|
|
- **THEN** the task SHALL remain `Undecided` (retry next cycle)
|
|
- **AND** the task SHALL also be available for http_pull dequeue (fallback)
|
|
|
|
### Requirement: Coordinator explicit assignment
|
|
The API SHALL provide an endpoint for coordinators to explicitly assign tasks to specific agents.
|
|
|
|
#### Scenario: Coordinator assigns task to specific agent
|
|
- **GIVEN** a task in `Created` or `Undecided` status
|
|
- **WHEN** coordinator calls `POST /api/v1/tasks/{id}/assign` with `{"agent_id": "hermes-worker-01"}`
|
|
- **THEN** the task SHALL be assigned to the specified agent
|
|
- **AND** execution_mode SHALL be auto-detected from the agent's registration type (http_pull for registered agents, ssh_cli for configured hosts)
|
|
- **AND** the task status SHALL transition to `Assigned`
|
|
|
|
#### Scenario: Coordinator assigns to non-existent agent
|
|
- **WHEN** coordinator calls assign with an unknown agent_id
|
|
- **THEN** the API SHALL return 404 Not Found
|
|
|
|
#### Scenario: Coordinator assigns already-running task
|
|
- **WHEN** coordinator calls assign on a task in `Running` or `Completed` status
|
|
- **THEN** the API SHALL return 400 Bad Request
|
|
|
|
### Requirement: Dequeue accepts Undecided tasks
|
|
The dequeue endpoint SHALL return tasks with `execution_mode` of either `HttpPull` or `Undecided`.
|
|
|
|
#### Scenario: Agent dequeues Undecided task
|
|
- **GIVEN** an `Undecided` task matching the agent's capabilities
|
|
- **WHEN** an http_pull agent calls dequeue
|
|
- **THEN** the task SHALL be returned
|
|
- **AND** `execution_mode` SHALL be atomically updated to `HttpPull`
|
|
- **AND** the task SHALL be assigned to the dequeuing agent
|
|
|
|
#### Scenario: No race condition between dispatch and dequeue
|
|
- **GIVEN** an `Undecided` task
|
|
- **WHEN** both ssh_cli dispatch and http_pull dequeue attempt to claim it simultaneously
|
|
- **THEN** exactly one SHALL succeed (atomic claim via DB transaction)
|
|
- **AND** the other SHALL get no task / skip the task
|
|
|
|
### Requirement: Backward compatibility
|
|
Existing tasks with `execution_mode = SshCli` or `HttpPull` SHALL continue to work without changes.
|
|
|
|
#### Scenario: Pre-existing SshCli task
|
|
- **WHEN** a task already has `execution_mode = SshCli`
|
|
- **THEN** the dispatch loop SHALL process it as before (no change)
|
|
|
|
#### Scenario: Pre-existing HttpPull task
|
|
- **WHEN** a task already has `execution_mode = HttpPull`
|
|
- **THEN** the dequeue endpoint SHALL return it as before (no change)
|