Files
agentic-mobile-control/openspec/specs/task-scheduler/spec.md
T
2026-07-06 23:52:53 +08:00

5.0 KiB

task-scheduler Specification

Purpose

TBD - created by archiving change cloud-runtime. Update Purpose after archive.

Requirements

Requirement: Task submission enqueues a scheduled task

The system SHALL allow a caller to submit a task (a goal string, or a reference to a WorkflowDefinition, plus optional device constraints: driver_type, required capability tags) and SHALL enqueue it as a ScheduledTask with status queued, returning a stable task id the caller can poll.

Scenario: Successful submission

  • WHEN a caller submits a task with a goal and no constraints
  • THEN the scheduler creates a ScheduledTask with status queued, assigns it a unique id, and returns that id to the caller without blocking for a device to become available

Scenario: Queue depth limit reached

  • WHEN a caller submits a task while the queue already holds config.max_queue_depth queued tasks
  • THEN the scheduler rejects the submission with a clear error rather than accepting an unbounded backlog

Requirement: Assignment matches a queued task to an idle, constraint-matching device

The system SHALL assign a queued ScheduledTask to an idle PooledDevice (as reported by the device-pool capability) whose driver_type and capability tags satisfy the task's constraints, using a named, registrable AssignmentStrategy.

Scenario: Matching idle device available

  • WHEN assign() runs and at least one idle PooledDevice matches the head-of-queue task's constraints
  • THEN the scheduler selects one such device via the configured AssignmentStrategy, transitions the task to status assigned, and records the chosen device_id/host_id

Scenario: No matching device available

  • WHEN assign() runs and no idle PooledDevice matches the head-of-queue task's constraints
  • THEN the task remains queued (not failed), and assign() returns without error, ready to be retried on a later call

Scenario: Unknown assignment strategy configured

  • WHEN TaskScheduler is configured with an AssignmentStrategy name that is not registered
  • THEN the scheduler raises a clear configuration error at startup/first-assign rather than silently falling back to a default strategy

Requirement: Assignment strategies are pluggable by name

The system SHALL provide an AssignmentStrategy registry mapping a strategy name to an implementation, with a default fifo_match strategy (oldest-queued matching task first, first matching idle device), and SHALL allow a new strategy to be added by registering a name without modifying TaskScheduler's control flow.

Scenario: Default FIFO strategy orders by submission time

  • WHEN two tasks with satisfiable, overlapping constraints are queued in order A then B, and one matching idle device exists
  • THEN the default fifo_match strategy assigns the device to task A, leaving task B queued

Scenario: Adding a new strategy requires no scheduler edit

  • WHEN a new AssignmentStrategy implementation is registered under a new name
  • THEN TaskScheduler can be configured to use it by name alone, with no change to scheduler.py's assignment control flow

Requirement: Local dispatch executes an assignment via existing runners

The system SHALL provide a TaskDispatcher that, for an assignment whose device is owned by the local process's own host, executes the assigned task by composing the existing agent-runtime task-execution entry point (for a goal-based submission) or the workflow-orchestration workflow-execution entry point (for a workflow-based submission), without reimplementing planning/execution/retry logic.

Scenario: Dispatching a goal-based assignment

  • WHEN TaskDispatcher.dispatch() is called with an assignment for a goal-based ScheduledTask whose device is local
  • THEN the dispatcher constructs and runs a Task through the existing task-execution entry point, and updates the ScheduledTask's status to done or failed based on the resulting task's outcome

Scenario: Dispatching a workflow-based assignment

  • WHEN TaskDispatcher.dispatch() is called with an assignment referencing a WorkflowDefinition whose device is local
  • THEN the dispatcher runs the definition through the existing workflow-execution entry point and updates the ScheduledTask's status based on the resulting workflow run's outcome

Requirement: Remote assignments are rejected explicitly, not silently ignored

The system SHALL raise a distinct, typed error when TaskDispatcher.dispatch() is called for an assignment whose device is owned by a host other than the dispatching process's own host, rather than attempting execution or silently no-op'ing.

Scenario: Assignment targets a remote host's device

  • WHEN TaskDispatcher.dispatch() is called with an assignment whose host_id does not match the local process's own host id
  • THEN the dispatcher raises a RemoteDispatchNotSupportedError and leaves the ScheduledTask's status unchanged from assigned