Skip to main content

mdx_rust_core/
agent_contract.rs

1//! Agent-facing command contract for `mdx-rust`.
2//!
3//! This artifact is intentionally small and stable enough for coding agents to
4//! inspect before deciding which CLI command to call.
5
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
10pub struct MdxAgentContract {
11    pub schema_version: String,
12    pub product_version: String,
13    pub json_mode_contract: String,
14    pub mutation_contract: String,
15    pub commands: Vec<AgentCommandSpec>,
16    pub workflows: Vec<AgentWorkflow>,
17    pub artifact_globs: Vec<String>,
18    pub safety_rules: Vec<String>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
22pub struct AgentCommandSpec {
23    pub name: String,
24    pub purpose: String,
25    pub mutates_source: bool,
26    pub required_flags_for_mutation: Vec<String>,
27    pub primary_schema: String,
28    pub example: String,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
32pub struct AgentWorkflow {
33    pub id: String,
34    pub goal: String,
35    pub steps: Vec<String>,
36}
37
38pub fn agent_contract() -> MdxAgentContract {
39    MdxAgentContract {
40        schema_version: "0.8".to_string(),
41        product_version: env!("CARGO_PKG_VERSION").to_string(),
42        json_mode_contract:
43            "Pass --json for machine-pure stdout. Errors are emitted as structured JSON when --json is set."
44                .to_string(),
45        mutation_contract:
46            "Only improve --apply, apply-plan --apply, autopilot --apply, and evolve --apply may mutate source files; every mutation routes through isolated validation and rollback gates."
47                .to_string(),
48        commands: vec![
49            AgentCommandSpec {
50                name: "recipes".to_string(),
51                purpose:
52                    "List recipe tiers, required evidence, and executable mutation paths."
53                        .to_string(),
54                mutates_source: false,
55                required_flags_for_mutation: Vec::new(),
56                primary_schema: "recipe-catalog".to_string(),
57                example: "mdx-rust --json recipes".to_string(),
58            },
59            AgentCommandSpec {
60                name: "scorecard".to_string(),
61                purpose:
62                    "Build one agent briefing with map, plan, recipe catalog, readiness, and next commands."
63                        .to_string(),
64                mutates_source: false,
65                required_flags_for_mutation: Vec::new(),
66                primary_schema: "evolution-scorecard".to_string(),
67                example: "mdx-rust --json scorecard src/service".to_string(),
68            },
69            AgentCommandSpec {
70                name: "evidence".to_string(),
71                purpose:
72                    "Collect measured evidence profiles that control autonomous recipe depth."
73                        .to_string(),
74                mutates_source: false,
75                required_flags_for_mutation: Vec::new(),
76                primary_schema: "evidence-run".to_string(),
77                example: "mdx-rust --json evidence src/service --include-coverage".to_string(),
78            },
79            AgentCommandSpec {
80                name: "map".to_string(),
81                purpose:
82                    "Build a non-mutating repo intelligence map with evidence gates and risks.".to_string(),
83                mutates_source: false,
84                required_flags_for_mutation: Vec::new(),
85                primary_schema: "codebase-map".to_string(),
86                example: "mdx-rust --json map src/service".to_string(),
87            },
88            AgentCommandSpec {
89                name: "plan".to_string(),
90                purpose:
91                    "Build a non-mutating refactor plan with executable and plan-only candidates."
92                        .to_string(),
93                mutates_source: false,
94                required_flags_for_mutation: Vec::new(),
95                primary_schema: "refactor-plan".to_string(),
96                example: "mdx-rust --json plan src/service".to_string(),
97            },
98            AgentCommandSpec {
99                name: "evolve".to_string(),
100                purpose:
101                    "Run budget-bounded autonomous improvement over evidence-allowed candidates."
102                        .to_string(),
103                mutates_source: true,
104                required_flags_for_mutation: vec!["--apply".to_string()],
105                primary_schema: "autopilot-run".to_string(),
106                example:
107                    "mdx-rust --json evolve src/service --budget 10m --tier 2 --min-evidence covered"
108                        .to_string(),
109            },
110            AgentCommandSpec {
111                name: "apply-plan".to_string(),
112                purpose:
113                    "Execute explicitly executable candidates from a saved plan after hash and staleness checks."
114                        .to_string(),
115                mutates_source: true,
116                required_flags_for_mutation: vec!["--apply".to_string()],
117                primary_schema: "refactor-batch-apply-run".to_string(),
118                example: "mdx-rust --json apply-plan .mdx-rust/plans/plan.json --all".to_string(),
119            },
120            AgentCommandSpec {
121                name: "explain".to_string(),
122                purpose:
123                    "Summarize an mdx-rust artifact and recommend safe next actions."
124                        .to_string(),
125                mutates_source: false,
126                required_flags_for_mutation: Vec::new(),
127                primary_schema: "artifact-explanation".to_string(),
128                example: "mdx-rust --json explain .mdx-rust/plans/refactor-plan.json"
129                    .to_string(),
130            },
131            AgentCommandSpec {
132                name: "schema".to_string(),
133                purpose: "Emit JSON Schema for agent-facing artifacts.".to_string(),
134                mutates_source: false,
135                required_flags_for_mutation: Vec::new(),
136                primary_schema: "json-schema".to_string(),
137                example: "mdx-rust --json schema agent-contract".to_string(),
138            },
139        ],
140        workflows: vec![
141            AgentWorkflow {
142                id: "safe-intake".to_string(),
143                goal: "Understand a Rust target before proposing code changes.".to_string(),
144                steps: vec![
145                    "mdx-rust --json agent-contract".to_string(),
146                    "mdx-rust --json recipes".to_string(),
147                    "mdx-rust --json scorecard <target>".to_string(),
148                    "mdx-rust --json evidence <target>".to_string(),
149                    "mdx-rust --json map <target>".to_string(),
150                    "mdx-rust --json plan <target>".to_string(),
151                ],
152            },
153            AgentWorkflow {
154                id: "covered-autonomy".to_string(),
155                goal: "Apply Tier 2 mechanical improvements only when measured coverage allows it."
156                    .to_string(),
157                steps: vec![
158                    "mdx-rust --json evidence <target> --include-coverage".to_string(),
159                    "mdx-rust --json evolve <target> --budget 10m --tier 2 --min-evidence covered"
160                        .to_string(),
161                    "Review the autopilot artifact before rerunning with --apply.".to_string(),
162                ],
163            },
164        ],
165        artifact_globs: vec![
166            ".mdx-rust/evidence/*.json".to_string(),
167            ".mdx-rust/maps/*.json".to_string(),
168            ".mdx-rust/scorecards/*.json".to_string(),
169            ".mdx-rust/plans/*.json".to_string(),
170            ".mdx-rust/autopilot/*.json".to_string(),
171            ".mdx-rust/hardening/*.json".to_string(),
172        ],
173        safety_rules: vec![
174            "Treat plan and map commands as read-only.".to_string(),
175            "Never add --apply unless the user explicitly asked for mutation.".to_string(),
176            "Do not bypass min-evidence or tier restrictions.".to_string(),
177            "Re-run plan after any source file changes because stale plans are rejected.".to_string(),
178            "Use artifact_path fields as the source of truth for follow-up inspection.".to_string(),
179        ],
180    }
181}