agent_orchestrator/task_repository/trait_def.rs
1//! Synchronous task-execution repository traits.
2//!
3//! The original monolithic `TaskRepository` is now composed from seven
4//! domain-aligned sub-traits. A blanket implementation keeps the
5//! `TaskRepository` supertrait backward-compatible — any type that
6//! implements all sub-traits automatically implements `TaskRepository`.
7//!
8//! ## Sub-traits
9//!
10//! | Trait | Domain |
11//! |-------|--------|
12//! | [`TaskQueryRepository`] | Task discovery, lookup, and metadata |
13//! | [`TaskItemQueryRepository`] | Item enumeration and health-check queries |
14//! | [`TaskStateRepository`] | Task lifecycle state mutations |
15//! | [`TaskItemMutRepository`] | Task item state mutations |
16//! | [`CommandRunRepository`] | Command run recording and process tracking |
17//! | [`EventRepository`] | Event insertion |
18//! | [`TaskGraphRepository`] | Task graph planning records |
19
20use crate::dto::{TaskGraphDebugBundle, TaskItemRow, TaskSummary};
21use anyhow::Result;
22
23use super::TaskDetailRows;
24use super::command_run::NewCommandRun;
25use super::types::{DbEventRecord, TaskLogRunRow, TaskRuntimeRow};
26
27// ── Read-side sub-traits ────────────────────────────────────────────
28
29/// Task discovery, lookup, and metadata queries.
30pub trait TaskQueryRepository {
31 /// Resolves a full task identifier from an exact ID or prefix.
32 fn resolve_task_id(&self, task_id_or_prefix: &str) -> Result<String>;
33 /// Loads the summary row for a task.
34 fn load_task_summary(&self, task_id: &str) -> Result<TaskSummary>;
35 /// Loads the full detail row bundle for a task.
36 fn load_task_detail_rows(&self, task_id: &str) -> Result<TaskDetailRows>;
37 /// Loads `(total, resolved, unresolved)` item counts for a task.
38 fn load_task_item_counts(&self, task_id: &str) -> Result<(i64, i64, i64)>;
39 /// Lists task identifiers ordered from newest to oldest.
40 fn list_task_ids_ordered_by_created_desc(&self) -> Result<Vec<String>>;
41 /// Returns the latest resumable task, optionally including pending tasks.
42 fn find_latest_resumable_task_id(&self, include_pending: bool) -> Result<Option<String>>;
43 /// Loads execution state needed to resume a task.
44 fn load_task_runtime_row(&self, task_id: &str) -> Result<TaskRuntimeRow>;
45 /// Loads the current task status string.
46 fn load_task_status(&self, task_id: &str) -> Result<Option<String>>;
47 /// Loads the human-readable name of a task.
48 fn load_task_name(&self, task_id: &str) -> Result<Option<String>>;
49}
50
51/// Task item enumeration and health-check queries.
52pub trait TaskItemQueryRepository {
53 /// Returns the first task-item identifier for a task, if any.
54 fn first_task_item_id(&self, task_id: &str) -> Result<Option<String>>;
55 /// Lists task items participating in the current cycle.
56 fn list_task_items_for_cycle(&self, task_id: &str) -> Result<Vec<TaskItemRow>>;
57 /// Counts unresolved items for the task.
58 fn count_unresolved_items(&self, task_id: &str) -> Result<i64>;
59 /// Counts stale pending items (FR-038).
60 fn count_stale_pending_items(&self, task_id: &str) -> Result<i64>;
61 /// Counts recent heartbeat events for specified item IDs since cutoff (FR-052).
62 fn count_recent_heartbeats_for_items(
63 &self,
64 task_id: &str,
65 item_ids: &[String],
66 cutoff_ts: &str,
67 ) -> Result<i64>;
68}
69
70// ── Write-side sub-traits ───────────────────────────────────────────
71
72/// Task lifecycle state mutations.
73pub trait TaskStateRepository {
74 /// Updates the task status and optionally stamps completion metadata.
75 fn set_task_status(&self, task_id: &str, status: &str, set_completed: bool) -> Result<()>;
76 /// Prepares a task for a fresh start by resetting batch-execution state.
77 fn prepare_task_for_start_batch(&self, task_id: &str) -> Result<()>;
78 /// Persists cycle counters and `init_once` completion state for a task.
79 fn update_task_cycle_state(
80 &self,
81 task_id: &str,
82 current_cycle: u32,
83 init_done: bool,
84 ) -> Result<()>;
85 /// Persists the serialized pipeline-variable map for a task.
86 fn update_task_pipeline_vars(&self, task_id: &str, pipeline_vars_json: &str) -> Result<()>;
87 /// Deletes a task and returns log paths that should be cleaned up afterward.
88 fn delete_task_and_collect_log_paths(&self, task_id: &str) -> Result<Vec<String>>;
89}
90
91/// Task item state mutations.
92pub trait TaskItemMutRepository {
93 /// Marks a task item as currently running.
94 fn mark_task_item_running(&self, task_item_id: &str) -> Result<()>;
95 /// Sets a terminal status for a task item.
96 fn set_task_item_terminal_status(&self, task_item_id: &str, status: &str) -> Result<()>;
97 /// Updates a task item to an arbitrary status value.
98 fn update_task_item_status(&self, task_item_id: &str, status: &str) -> Result<()>;
99 /// Persists accumulated pipeline variables back to the task item's dynamic_vars column.
100 fn update_task_item_pipeline_vars(
101 &self,
102 task_item_id: &str,
103 pipeline_vars_json: &str,
104 ) -> Result<()>;
105 /// Persists the active ticket lists and preview content for a task item.
106 fn update_task_item_tickets(
107 &self,
108 task_item_id: &str,
109 ticket_files_json: &str,
110 ticket_content_json: &str,
111 ) -> Result<()>;
112}
113
114/// Command run recording and process tracking.
115pub trait CommandRunRepository {
116 /// Inserts a command-run record.
117 fn insert_command_run(&self, run: &NewCommandRun) -> Result<()>;
118 /// Updates an existing command-run record.
119 fn update_command_run(&self, run: &NewCommandRun) -> Result<()>;
120 /// Updates a command run and appends events in a single repository call.
121 fn update_command_run_with_events(
122 &self,
123 run: &NewCommandRun,
124 events: &[DbEventRecord],
125 ) -> Result<()>;
126 /// Persists a completed phase result together with its emitted events.
127 fn persist_phase_result_with_events(
128 &self,
129 run: &NewCommandRun,
130 events: &[DbEventRecord],
131 ) -> Result<()>;
132 /// Updates the operating-system PID associated with a running command.
133 fn update_command_run_pid(&self, run_id: &str, pid: i64) -> Result<()>;
134 /// Lists recent command runs for log streaming or inspection.
135 fn list_task_log_runs(&self, task_id: &str, limit: usize) -> Result<Vec<TaskLogRunRow>>;
136 /// Returns active child PIDs for a task.
137 fn find_active_child_pids(&self, task_id: &str) -> Result<Vec<i64>>;
138 /// Returns in-flight command runs for a task (FR-038).
139 fn find_inflight_command_runs_for_task(
140 &self,
141 task_id: &str,
142 ) -> Result<Vec<super::write_ops::InflightRunRecord>>;
143 /// Returns completed runs whose parent items are still `pending` (FR-038).
144 fn find_completed_runs_for_pending_items(
145 &self,
146 task_id: &str,
147 ) -> Result<Vec<super::write_ops::CompletedRunRecord>>;
148}
149
150/// Event insertion.
151pub trait EventRepository {
152 /// Inserts an event record.
153 fn insert_event(&self, event: &DbEventRecord) -> Result<()>;
154}
155
156/// Task graph planning records.
157pub trait TaskGraphRepository {
158 /// Inserts a new task-graph planning run record.
159 fn insert_task_graph_run(&self, run: &super::types::NewTaskGraphRun) -> Result<()>;
160 /// Updates the status of an existing task-graph run.
161 fn update_task_graph_run_status(&self, graph_run_id: &str, status: &str) -> Result<()>;
162 /// Persists one task-graph snapshot.
163 fn insert_task_graph_snapshot(
164 &self,
165 snapshot: &super::types::NewTaskGraphSnapshot,
166 ) -> Result<()>;
167 /// Loads debug bundles for graph-planning diagnostics.
168 fn load_task_graph_debug_bundles(&self, task_id: &str) -> Result<Vec<TaskGraphDebugBundle>>;
169}
170
171// ── Composite supertrait (backward-compatible) ──────────────────────
172
173/// Full task repository — backward-compatible supertrait composing all
174/// domain-specific sub-traits.
175///
176/// Existing code using `TaskRepository` as a bound continues to compile
177/// unchanged. New code may depend on narrower sub-traits for reduced
178/// coupling.
179pub trait TaskRepository:
180 TaskQueryRepository
181 + TaskItemQueryRepository
182 + TaskStateRepository
183 + TaskItemMutRepository
184 + CommandRunRepository
185 + EventRepository
186 + TaskGraphRepository
187{
188}
189
190/// Blanket implementation: any type implementing all sub-traits
191/// automatically satisfies `TaskRepository`.
192impl<T> TaskRepository for T where
193 T: TaskQueryRepository
194 + TaskItemQueryRepository
195 + TaskStateRepository
196 + TaskItemMutRepository
197 + CommandRunRepository
198 + EventRepository
199 + TaskGraphRepository
200{
201}