Skip to main content

ag_protocol/
subtask.rs

1//! Orchestrator subtask model shared across protocol, coordinator, and UI
2//! code.
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7/// One proposed child session in an orchestrator decomposition plan.
8///
9/// Each subtask is executed unattended by its own child session in its own
10/// worktree, branched from the same base branch as its siblings. Children never
11/// coordinate with each other while running, so each prompt must be
12/// self-contained. `touched_areas` provides best-effort planning context rather
13/// than an exclusive ownership boundary.
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
15#[schemars(
16    title = "SubtaskItem",
17    description = "One proposed child session in an orchestrator decomposition plan. Each subtask \
18                   runs unattended in its own worktree branched from the same base branch, so it \
19                   must be completable without coordinating with its siblings."
20)]
21pub struct SubtaskItem {
22    /// Observable conditions the worker must satisfy before the controller
23    /// may verify this task as complete.
24    #[serde(default)]
25    #[schemars(
26        title = "acceptance_criteria",
27        description = "Concrete, testable acceptance criteria for this subtask. The approval UI \
28                       shows these criteria and the controller verifies the finished child \
29                       against the same list."
30    )]
31    pub acceptance_criteria: Vec<String>,
32    /// Complete standalone prompt handed to the child session.
33    #[schemars(
34        title = "prompt",
35        description = "Complete standalone prompt for the child session. The child sees only this \
36                       prompt and the repository, so restate every constraint it needs instead of \
37                       referring back to the plan or to sibling subtasks."
38    )]
39    pub prompt: String,
40    /// Stable identifier for this subtask within one orchestration.
41    #[schemars(
42        title = "task_key",
43        description = "Short stable `kebab-case` identifier for this subtask, unique within the \
44                       plan. Reuse the exact same key when re-proposing a subtask so a retry \
45                       replaces the previous attempt instead of creating a duplicate."
46    )]
47    pub task_key: String,
48    /// Short human-readable subtask title.
49    #[schemars(
50        title = "title",
51        description = "Short human-readable title describing what this subtask delivers."
52    )]
53    pub title: String,
54    /// Best-effort repository-relative paths or directories this subtask is
55    /// expected to change.
56    #[serde(default)]
57    #[schemars(
58        title = "touched_areas",
59        description = "Best-effort repository-relative file or directory paths this subtask is \
60                       expected to modify. Wildcard patterns are not supported. Paths may overlap \
61                       between subtasks and workers may modify additional files when needed to \
62                       satisfy the task. Defaults to an empty list when omitted."
63    )]
64    pub touched_areas: Vec<String>,
65}