1use 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.9".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, evolve --apply, or a runtime evolve call with apply=true and confirm_mutation=true may mutate source files; every mutation routes through isolated validation and rollback gates."
47 .to_string(),
48 commands: vec![
49 AgentCommandSpec {
50 name: "runtime".to_string(),
51 purpose:
52 "Describe local agent runtime transports, tools, and mutation rules."
53 .to_string(),
54 mutates_source: false,
55 required_flags_for_mutation: Vec::new(),
56 primary_schema: "agent-runtime-manifest".to_string(),
57 example: "mdx-rust --json runtime".to_string(),
58 },
59 AgentCommandSpec {
60 name: "mcp".to_string(),
61 purpose:
62 "Run the local stdio agent tool protocol for scorecard, evidence, map, plan, explain, recipes, and gated evolve."
63 .to_string(),
64 mutates_source: true,
65 required_flags_for_mutation: vec![
66 "apply=true".to_string(),
67 "confirm_mutation=true".to_string(),
68 ],
69 primary_schema: "agent-runtime-manifest".to_string(),
70 example: "mdx-rust mcp --stdio".to_string(),
71 },
72 AgentCommandSpec {
73 name: "serve".to_string(),
74 purpose:
75 "Expose the same local agent tools over localhost HTTP for agents that prefer a socket API."
76 .to_string(),
77 mutates_source: true,
78 required_flags_for_mutation: vec![
79 "apply=true".to_string(),
80 "confirm_mutation=true".to_string(),
81 ],
82 primary_schema: "agent-runtime-manifest".to_string(),
83 example: "mdx-rust serve --bind 127.0.0.1:3799".to_string(),
84 },
85 AgentCommandSpec {
86 name: "agent-pack".to_string(),
87 purpose:
88 "Generate agent instruction files that teach Codex, Claude, or generic tools to use mdx-rust safely."
89 .to_string(),
90 mutates_source: false,
91 required_flags_for_mutation: Vec::new(),
92 primary_schema: "agent-pack".to_string(),
93 example: "mdx-rust --json agent-pack codex".to_string(),
94 },
95 AgentCommandSpec {
96 name: "recipes".to_string(),
97 purpose:
98 "List recipe tiers, required evidence, and executable mutation paths."
99 .to_string(),
100 mutates_source: false,
101 required_flags_for_mutation: Vec::new(),
102 primary_schema: "recipe-catalog".to_string(),
103 example: "mdx-rust --json recipes".to_string(),
104 },
105 AgentCommandSpec {
106 name: "scorecard".to_string(),
107 purpose:
108 "Build one agent briefing with map, plan, recipe catalog, readiness, and next commands."
109 .to_string(),
110 mutates_source: false,
111 required_flags_for_mutation: Vec::new(),
112 primary_schema: "evolution-scorecard".to_string(),
113 example: "mdx-rust --json scorecard src/service".to_string(),
114 },
115 AgentCommandSpec {
116 name: "evidence".to_string(),
117 purpose:
118 "Collect measured evidence profiles that control autonomous recipe depth."
119 .to_string(),
120 mutates_source: false,
121 required_flags_for_mutation: Vec::new(),
122 primary_schema: "evidence-run".to_string(),
123 example: "mdx-rust --json evidence src/service --include-coverage".to_string(),
124 },
125 AgentCommandSpec {
126 name: "map".to_string(),
127 purpose:
128 "Build a non-mutating repo intelligence map with evidence gates and risks.".to_string(),
129 mutates_source: false,
130 required_flags_for_mutation: Vec::new(),
131 primary_schema: "codebase-map".to_string(),
132 example: "mdx-rust --json map src/service".to_string(),
133 },
134 AgentCommandSpec {
135 name: "plan".to_string(),
136 purpose:
137 "Build a non-mutating refactor plan with executable and plan-only candidates."
138 .to_string(),
139 mutates_source: false,
140 required_flags_for_mutation: Vec::new(),
141 primary_schema: "refactor-plan".to_string(),
142 example: "mdx-rust --json plan src/service".to_string(),
143 },
144 AgentCommandSpec {
145 name: "evolve".to_string(),
146 purpose:
147 "Run budget-bounded autonomous improvement over evidence-allowed candidates."
148 .to_string(),
149 mutates_source: true,
150 required_flags_for_mutation: vec!["--apply".to_string()],
151 primary_schema: "autopilot-run".to_string(),
152 example:
153 "mdx-rust --json evolve src/service --budget 10m --tier 2 --min-evidence covered"
154 .to_string(),
155 },
156 AgentCommandSpec {
157 name: "apply-plan".to_string(),
158 purpose:
159 "Execute explicitly executable candidates from a saved plan after hash and staleness checks."
160 .to_string(),
161 mutates_source: true,
162 required_flags_for_mutation: vec!["--apply".to_string()],
163 primary_schema: "refactor-batch-apply-run".to_string(),
164 example: "mdx-rust --json apply-plan .mdx-rust/plans/plan.json --all".to_string(),
165 },
166 AgentCommandSpec {
167 name: "explain".to_string(),
168 purpose:
169 "Summarize an mdx-rust artifact and recommend safe next actions."
170 .to_string(),
171 mutates_source: false,
172 required_flags_for_mutation: Vec::new(),
173 primary_schema: "artifact-explanation".to_string(),
174 example: "mdx-rust --json explain .mdx-rust/plans/refactor-plan.json"
175 .to_string(),
176 },
177 AgentCommandSpec {
178 name: "schema".to_string(),
179 purpose: "Emit JSON Schema for agent-facing artifacts.".to_string(),
180 mutates_source: false,
181 required_flags_for_mutation: Vec::new(),
182 primary_schema: "json-schema".to_string(),
183 example: "mdx-rust --json schema agent-contract".to_string(),
184 },
185 ],
186 workflows: vec![
187 AgentWorkflow {
188 id: "safe-intake".to_string(),
189 goal: "Understand a Rust target before proposing code changes.".to_string(),
190 steps: vec![
191 "mdx-rust --json agent-contract".to_string(),
192 "mdx-rust --json runtime".to_string(),
193 "mdx-rust --json recipes".to_string(),
194 "mdx-rust --json scorecard <target>".to_string(),
195 "mdx-rust --json evidence <target>".to_string(),
196 "mdx-rust --json map <target>".to_string(),
197 "mdx-rust --json plan <target>".to_string(),
198 ],
199 },
200 AgentWorkflow {
201 id: "agent-runtime".to_string(),
202 goal: "Let an external coding agent call mdx-rust through a local runtime surface.".to_string(),
203 steps: vec![
204 "mdx-rust --json runtime".to_string(),
205 "mdx-rust mcp --stdio".to_string(),
206 "Call tools/list before tools/call.".to_string(),
207 "Only call mutation-capable tools with apply=true and confirm_mutation=true after human approval.".to_string(),
208 ],
209 },
210 AgentWorkflow {
211 id: "covered-autonomy".to_string(),
212 goal: "Apply Tier 2 mechanical improvements only when measured coverage allows it."
213 .to_string(),
214 steps: vec![
215 "mdx-rust --json evidence <target> --include-coverage".to_string(),
216 "mdx-rust --json evolve <target> --budget 10m --tier 2 --min-evidence covered"
217 .to_string(),
218 "Review the autopilot artifact before rerunning with --apply.".to_string(),
219 ],
220 },
221 ],
222 artifact_globs: vec![
223 ".mdx-rust/evidence/*.json".to_string(),
224 ".mdx-rust/maps/*.json".to_string(),
225 ".mdx-rust/scorecards/*.json".to_string(),
226 ".mdx-rust/plans/*.json".to_string(),
227 ".mdx-rust/autopilot/*.json".to_string(),
228 ".mdx-rust/hardening/*.json".to_string(),
229 ".mdx-rust/agent-pack/*".to_string(),
230 ],
231 safety_rules: vec![
232 "Treat plan and map commands as read-only.".to_string(),
233 "Never add --apply unless the user explicitly asked for mutation.".to_string(),
234 "Do not bypass min-evidence or tier restrictions.".to_string(),
235 "Re-run plan after any source file changes because stale plans are rejected.".to_string(),
236 "Use artifact_path fields as the source of truth for follow-up inspection.".to_string(),
237 ],
238 }
239}