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

102 lines
8.4 KiB
Markdown

# workflow-orchestration Specification
## Purpose
TBD - created by archiving change workflow-orchestration-runtime. Update Purpose after archive.
## Requirements
### Requirement: Workflow definition as an ordered, branchable list of typed steps
The system SHALL provide a `WorkflowDefinition` model representing an ordered, possibly-branching list of `WorkflowStep`s, where each step is exactly one of four kinds: a planned-goal step (a natural-language sub-goal delegated to the existing single-goal Planner/Executor loop), a skill-invocation step (a reference to a locally-synthesized flow-template skill plus argument values), a wait-for-condition step (a named condition, timeout, and poll interval), or a branch step (a named condition plus two target step ids). Each step SHALL have a unique `step_id` within its `WorkflowDefinition`.
#### Scenario: Workflow with heterogeneous step kinds is constructed
- **WHEN** a `WorkflowDefinition` is built with a planned-goal step, a skill-invocation step, a wait-for-condition step, and a branch step in sequence
- **THEN** the system accepts the definition and each step retains its declared kind and fields without requiring fields belonging to another step kind
#### Scenario: Duplicate step id is rejected
- **WHEN** a `WorkflowDefinition` is constructed with two steps sharing the same `step_id`
- **THEN** the system rejects the definition before any run is created from it
### Requirement: Persisted, checkpointed workflow run
The system SHALL persist a `WorkflowRun` record for each execution of a `WorkflowDefinition`, containing the run's status, the currently active step id, workflow-scoped variables, and a per-step result log, and SHALL update this record after every completed step before advancing to the next one.
#### Scenario: Run status transitions as steps execute
- **WHEN** a `WorkflowRun` is started for a `WorkflowDefinition`
- **THEN** the system creates a persisted run record with status `running` and, as each step completes, updates the persisted `current_step_id` and per-step result log before the next step begins
#### Scenario: Run reaches terminal status
- **WHEN** all steps in a `WorkflowDefinition` complete successfully, or a step fails without a defined recovery path
- **THEN** the system updates the persisted `WorkflowRun` status to `completed` or `failed` respectively, and records a failure reason when failed
### Requirement: Resume from last checkpoint without re-executing completed steps
The system SHALL support resuming an interrupted `WorkflowRun` from its last persisted checkpoint, continuing execution from the currently active step without re-executing any step already recorded as completed in that run's step result log.
#### Scenario: Resume after simulated process restart
- **WHEN** a `WorkflowRun` has completed its first two steps and the process driving it stops before the third step completes, and a new `WorkflowRunner` instance is later pointed at the same persisted run id
- **THEN** the system resumes execution starting at the third step and does not re-invoke the tool calls or sub-goal already recorded as completed for the first two steps
#### Scenario: Resume on an already-completed run is a no-op
- **WHEN** `resume` is called with the id of a `WorkflowRun` whose status is already `completed`
- **THEN** the system returns the run's existing final state without executing any further steps
### Requirement: Planned-goal step delegates to the existing single-goal loop
The system SHALL execute a planned-goal step by delegating its sub-goal to the existing Planner/Executor Observe-Think-Act-Observe loop for a single task, and SHALL derive that step's success or failure from the resulting task's final status.
#### Scenario: Planned-goal step succeeds
- **WHEN** a planned-goal step's delegated task reaches a completed status
- **THEN** the workflow step is recorded as succeeded and the run advances to the next step
#### Scenario: Planned-goal step fails
- **WHEN** a planned-goal step's delegated task reaches a failed status
- **THEN** the workflow step is recorded as failed with the task's failure reason and the run's status becomes `failed` unless a branch step defines an alternate path
### Requirement: Skill-invocation step resolves parameters and executes a flow-template skill
The system SHALL execute a skill-invocation step by validating its supplied argument values against the referenced flow-template skill's declared parameters, substituting the validated values into the skill's stored tool-call template, and executing the resolved tool calls in order.
#### Scenario: Skill invocation with valid parameters executes resolved tool calls
- **WHEN** a skill-invocation step supplies argument values that satisfy the referenced skill's declared required parameters
- **THEN** the system substitutes those values into the skill's stored steps and executes the resulting tool calls in the skill's recorded order
#### Scenario: Skill invocation with a missing required parameter fails without executing any tool call
- **WHEN** a skill-invocation step omits a value for a parameter the referenced skill declares as required
- **THEN** the system fails the step before issuing any tool call and records the missing-parameter reason
#### Scenario: Skill invocation referencing a non-flow-template skill is rejected
- **WHEN** a skill-invocation step references a skill whose kind is not a flow-template
- **THEN** the system fails the step as a step-definition error rather than attempting to execute it
### Requirement: Wait-for-condition step polls until satisfied or timed out
The system SHALL execute a wait-for-condition step by repeatedly evaluating its named condition at the step's configured poll interval until the condition is satisfied or the step's configured timeout elapses.
#### Scenario: Condition becomes true before timeout
- **WHEN** a wait-for-condition step's condition evaluates true within its configured timeout
- **THEN** the system stops polling, records the step as succeeded, and advances the run to the next step
#### Scenario: Condition never becomes true before timeout
- **WHEN** a wait-for-condition step's condition has not evaluated true by its configured timeout
- **THEN** the system records the step as failed with a timeout reason and the run's status becomes `failed` unless a branch step defines an alternate path
### Requirement: Branch step selects the next step from a condition
The system SHALL execute a branch step by evaluating its named condition and setting the run's next active step to the branch's configured true-target step id or false-target step id accordingly, instead of advancing to the next step in definition order.
#### Scenario: Branch condition true selects the true-target step
- **WHEN** a branch step's condition evaluates true
- **THEN** the system sets the run's current step to the branch's `on_true` target step id
#### Scenario: Branch condition false selects the false-target step
- **WHEN** a branch step's condition evaluates false
- **THEN** the system sets the run's current step to the branch's `on_false` target step id
### Requirement: Condition kinds are pluggable via a registry
The system SHALL evaluate wait-for-condition and branch step conditions through a registry mapping a condition kind name to an evaluator, SHALL provide at least `scene_contains_text`, `world_variable_equals`, `elapsed_seconds`, and `step_result_success` as built-in kinds, and SHALL allow a new condition kind to be added without modifying the workflow runner's step-dispatch logic.
#### Scenario: Built-in condition kind evaluates against current state
- **WHEN** a wait-for-condition or branch step specifies the `scene_contains_text` kind with a target text value
- **THEN** the system evaluates the condition against the most recently observed scene and returns true only when the target text is present
#### Scenario: Unregistered condition kind fails the step
- **WHEN** a step specifies a condition kind that is not present in the registry
- **THEN** the system fails that step with an unrecognized-condition-kind reason instead of executing an undefined check
#### Scenario: World-state-dependent condition degrades safely when world state is absent
- **WHEN** a `world_variable_equals` condition is evaluated for a run whose task context has no `WorldState` available
- **THEN** the system treats the condition as not satisfied rather than raising an error, allowing the step to continue polling until its timeout