brainos_orchestrate/step.rs
1//! Task step types — individual units of work in a task plan.
2
3use std::path::PathBuf;
4
5use audit::ActionTier;
6use serde::{Deserialize, Serialize};
7
8/// A single executable step in a task plan.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct TaskStep {
11 /// Unique step ID (UUID).
12 pub id: String,
13 /// Human-readable description.
14 pub description: String,
15 /// What kind of action this step performs.
16 pub action: StepAction,
17 /// Step IDs this depends on (must complete first).
18 pub depends_on: Vec<String>,
19 /// Required approval tier.
20 pub tier: ActionTier,
21 /// Estimated LLM token cost for budget pre-check.
22 pub estimated_tokens: u64,
23}
24
25/// The kind of action a step performs.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(tag = "type", rename_all = "snake_case")]
28pub enum StepAction {
29 /// Research — search memory and/or web.
30 Research { query: String },
31 /// Plan — produce a plan artifact (text output).
32 Plan { output: String },
33 /// Implement — delegate to an agent.
34 Implement { spec: String, agent: String },
35 /// Execute — run a command in the sandbox via direct argv (no shell).
36 /// Use for simple `binary arg arg` commands. The first token must be
37 /// on the per-binary allowlist. No pipes, redirects, $VAR, or
38 /// PATH-dependent lookups beyond the sanitised env.
39 Execute { command: String, workdir: PathBuf },
40 /// Test — run tests in the sandbox via direct argv.
41 Test { command: String, workdir: PathBuf },
42 /// Shell — run a command via `sh -c "<command>"` so the system
43 /// shell handles pipes, redirects, escaping, $VAR, and PATH
44 /// resolution. Use for any non-trivial command. The per-binary
45 /// allowlist is bypassed for the wrapped command (only `sh` is
46 /// gated); rlimits + Seatbelt + timeout + the explicit
47 /// forbidden-list still apply.
48 Shell { command: String, workdir: PathBuf },
49 /// Review — present an artifact for human review.
50 Review { artifact: String },
51 /// Notify — send a notification via a channel.
52 Notify { channel: String, message: String },
53}