Skip to main content

supercode_harness/
support.rs

1//! Canonical implementation inventory for external coding harnesses.
2//!
3//! This registry describes wiring that exists in the compiled core. It does
4//! not claim that a harness has passed a real executable smoke test; the
5//! autonomy audit joins this inventory with behavioral probe receipts and
6//! tracker state before it calls anything verified.
7
8use std::collections::BTreeMap;
9
10use serde::{Deserialize, Serialize};
11
12use crate::{
13    AcpRuntimeBackend, ClaudeCodeRuntimeBackend, CodexRuntimeBackend, HarnessId,
14    OpenCodeRuntimeBackend, PiRuntimeBackend, RuntimeBackend, RuntimeCapabilities, RuntimeLaunch,
15};
16
17/// Schema emitted by [`harness_support_registry`].
18pub const SUPPORT_REGISTRY_SCHEMA: &str = "supercode.support-registry.v1";
19
20/// How a primitive is wired into the compiled core.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum ImplementationKind {
24    /// A harness-specific implementation is registered.
25    BuiltIn,
26    /// A protocol-generic implementation is usable with a known launch.
27    GenericProtocol,
28    /// No implementation is present.
29    Absent,
30}
31
32/// Persisted-session and translation implementation facts.
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub struct NativeSupport {
35    /// Whether the catalog can discover this harness's sessions.
36    pub discover: ImplementationKind,
37    /// Whether the core can load this harness's native persisted format.
38    pub load: ImplementationKind,
39    /// Whether the generic follower can open this harness's native storage.
40    pub follow: ImplementationKind,
41    /// Whether the canonical session can import this native format.
42    pub import: ImplementationKind,
43    /// Whether the canonical session can export this native format.
44    pub export: ImplementationKind,
45}
46
47/// Live runtime wiring known without launching the real executable.
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
49pub struct RuntimeSupport {
50    /// Harness-specific or protocol-generic adapter registration.
51    pub implementation: ImplementationKind,
52    /// Protocol spoken by the adapter.
53    pub protocol: String,
54    /// Command used when callers do not provide an override.
55    pub default_launch: Option<RuntimeLaunch>,
56    /// Static adapter capabilities. Optional protocol features are only true
57    /// for known agents that advertise them; the adapter validates them again
58    /// during the live handshake.
59    pub capabilities: RuntimeCapabilities,
60}
61
62/// One compiled harness implementation descriptor.
63#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
64pub struct HarnessSupportDescriptor {
65    /// Stable harness identifier.
66    pub id: HarnessId,
67    /// Human-readable name.
68    pub display_name: String,
69    /// Native persistence/translation implementation.
70    pub native: NativeSupport,
71    /// Live runtime implementation.
72    pub runtime: RuntimeSupport,
73}
74
75/// Machine-readable compiled support inventory.
76#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
77pub struct SupportRegistryReport {
78    /// Report schema.
79    pub schema: String,
80    /// Harness descriptors, in stable product order.
81    pub harnesses: Vec<HarnessSupportDescriptor>,
82}
83
84fn built_in_native() -> NativeSupport {
85    NativeSupport {
86        discover: ImplementationKind::BuiltIn,
87        load: ImplementationKind::BuiltIn,
88        follow: ImplementationKind::BuiltIn,
89        import: ImplementationKind::BuiltIn,
90        export: ImplementationKind::BuiltIn,
91    }
92}
93
94fn built_in_runtime(
95    backend: &dyn RuntimeBackend,
96    protocol: &str,
97    launch: RuntimeLaunch,
98) -> RuntimeSupport {
99    RuntimeSupport {
100        implementation: ImplementationKind::BuiltIn,
101        protocol: protocol.into(),
102        default_launch: Some(launch),
103        capabilities: backend.capabilities(),
104    }
105}
106
107/// Return the single compiled inventory used by product surfaces and audits.
108pub fn harness_support_registry() -> SupportRegistryReport {
109    let claude = ClaudeCodeRuntimeBackend::new();
110    let codex = CodexRuntimeBackend::new();
111    let opencode = OpenCodeRuntimeBackend::new();
112    let pi = PiRuntimeBackend::new();
113    let grok_launch = RuntimeLaunch {
114        program: "grok".into(),
115        arguments: vec![
116            "--sandbox".into(),
117            "workspace".into(),
118            "agent".into(),
119            "--no-leader".into(),
120            "stdio".into(),
121        ],
122        env: BTreeMap::from([("GROK_AGENT_DASHBOARD".into(), "0".into())]),
123    };
124    let grok = AcpRuntimeBackend::new(HarnessId::from(HarnessId::GROK), grok_launch.clone())
125        .with_resume_support(true);
126    let gemini_launch = RuntimeLaunch {
127        program: "gemini".into(),
128        arguments: vec!["--acp".into()],
129        env: BTreeMap::new(),
130    };
131    let gemini = AcpRuntimeBackend::new(HarnessId::from(HarnessId::GEMINI), gemini_launch.clone())
132        .with_resume_support(true);
133    let goose_launch = RuntimeLaunch {
134        program: "goose".into(),
135        arguments: vec!["acp".into()],
136        env: BTreeMap::new(),
137    };
138    let goose = AcpRuntimeBackend::new(HarnessId::from(HarnessId::GOOSE), goose_launch.clone())
139        .with_resume_support(true);
140    let supercode_launch = RuntimeLaunch {
141        program: "supercode".into(),
142        arguments: vec!["acp".into()],
143        env: BTreeMap::new(),
144    };
145    let supercode = AcpRuntimeBackend::new(
146        HarnessId::from(HarnessId::SUPERCODE),
147        supercode_launch.clone(),
148    )
149    .with_resume_support(true);
150
151    SupportRegistryReport {
152        schema: SUPPORT_REGISTRY_SCHEMA.into(),
153        harnesses: vec![
154            HarnessSupportDescriptor {
155                id: HarnessId::from(HarnessId::CLAUDE_CODE),
156                display_name: "Claude Code".into(),
157                native: built_in_native(),
158                runtime: built_in_runtime(
159                    &claude,
160                    "claude-stream-json",
161                    RuntimeLaunch {
162                        program: "claude".into(),
163                        arguments: Vec::new(),
164                        env: BTreeMap::new(),
165                    },
166                ),
167            },
168            HarnessSupportDescriptor {
169                id: HarnessId::from(HarnessId::CODEX),
170                display_name: "Codex".into(),
171                native: built_in_native(),
172                runtime: built_in_runtime(
173                    &codex,
174                    "codex-app-server-jsonl",
175                    RuntimeLaunch {
176                        program: "codex".into(),
177                        arguments: vec!["app-server".into()],
178                        env: BTreeMap::new(),
179                    },
180                ),
181            },
182            HarnessSupportDescriptor {
183                id: HarnessId::from(HarnessId::OPENCODE),
184                display_name: "OpenCode".into(),
185                native: built_in_native(),
186                runtime: built_in_runtime(
187                    &opencode,
188                    "opencode-http-sse",
189                    RuntimeLaunch {
190                        program: "opencode".into(),
191                        arguments: vec!["serve".into()],
192                        env: BTreeMap::new(),
193                    },
194                ),
195            },
196            HarnessSupportDescriptor {
197                id: HarnessId::from(HarnessId::PI),
198                display_name: "Pi".into(),
199                native: built_in_native(),
200                runtime: built_in_runtime(
201                    &pi,
202                    "pi-rpc-jsonl",
203                    RuntimeLaunch {
204                        program: "pi".into(),
205                        arguments: vec!["--mode".into(), "rpc".into()],
206                        env: BTreeMap::new(),
207                    },
208                ),
209            },
210            HarnessSupportDescriptor {
211                id: HarnessId::from(HarnessId::GROK),
212                display_name: "Grok".into(),
213                native: built_in_native(),
214                runtime: RuntimeSupport {
215                    implementation: ImplementationKind::GenericProtocol,
216                    protocol: "acp-v1-jsonrpc".into(),
217                    default_launch: Some(grok_launch),
218                    capabilities: grok.capabilities(),
219                },
220            },
221            HarnessSupportDescriptor {
222                id: HarnessId::from(HarnessId::GEMINI),
223                display_name: "Gemini CLI".into(),
224                native: built_in_native(),
225                runtime: RuntimeSupport {
226                    implementation: ImplementationKind::GenericProtocol,
227                    protocol: "acp-v1-jsonrpc".into(),
228                    default_launch: Some(gemini_launch),
229                    capabilities: gemini.capabilities(),
230                },
231            },
232            HarnessSupportDescriptor {
233                id: HarnessId::from(HarnessId::GOOSE),
234                display_name: "Goose".into(),
235                native: built_in_native(),
236                runtime: RuntimeSupport {
237                    implementation: ImplementationKind::GenericProtocol,
238                    protocol: "acp-v1-jsonrpc".into(),
239                    default_launch: Some(goose_launch),
240                    capabilities: goose.capabilities(),
241                },
242            },
243            HarnessSupportDescriptor {
244                id: HarnessId::from(HarnessId::SUPERCODE),
245                display_name: "Supercode".into(),
246                native: built_in_native(),
247                runtime: RuntimeSupport {
248                    implementation: ImplementationKind::GenericProtocol,
249                    protocol: "acp-v1-jsonrpc".into(),
250                    default_launch: Some(supercode_launch),
251                    capabilities: supercode.capabilities(),
252                },
253            },
254        ],
255    }
256}
257
258/// Look up one harness in the compiled registry.
259pub fn harness_support(id: &str) -> Option<HarnessSupportDescriptor> {
260    harness_support_registry()
261        .harnesses
262        .into_iter()
263        .find(|harness| harness.id.as_str() == id)
264}
265
266#[cfg(test)]
267mod tests {
268    use super::*;
269
270    #[test]
271    fn registry_is_unique_and_reports_all_native_support() {
272        let report = harness_support_registry();
273        assert_eq!(report.schema, SUPPORT_REGISTRY_SCHEMA);
274        assert_eq!(report.harnesses.len(), 8);
275        let ids = report
276            .harnesses
277            .iter()
278            .map(|harness| harness.id.as_str())
279            .collect::<std::collections::BTreeSet<_>>();
280        assert_eq!(ids.len(), report.harnesses.len());
281
282        let grok = report
283            .harnesses
284            .iter()
285            .find(|harness| harness.id.as_str() == HarnessId::GROK)
286            .unwrap();
287        assert_eq!(grok.native.discover, ImplementationKind::BuiltIn);
288        assert_eq!(grok.native.load, ImplementationKind::BuiltIn);
289        assert_eq!(grok.native.follow, ImplementationKind::BuiltIn);
290        assert_eq!(grok.native.import, ImplementationKind::BuiltIn);
291        for id in [HarnessId::GEMINI, HarnessId::SUPERCODE] {
292            let harness = report
293                .harnesses
294                .iter()
295                .find(|harness| harness.id.as_str() == id)
296                .unwrap();
297            assert_eq!(harness.native.discover, ImplementationKind::BuiltIn);
298            assert_eq!(harness.native.load, ImplementationKind::BuiltIn);
299            assert_eq!(harness.native.follow, ImplementationKind::BuiltIn);
300        }
301        assert_eq!(grok.native.export, ImplementationKind::BuiltIn);
302        assert_eq!(
303            grok.runtime.implementation,
304            ImplementationKind::GenericProtocol
305        );
306        assert_eq!(
307            grok.runtime.default_launch.as_ref().unwrap().arguments,
308            ["--sandbox", "workspace", "agent", "--no-leader", "stdio"]
309        );
310        assert!(!grok
311            .runtime
312            .default_launch
313            .as_ref()
314            .unwrap()
315            .arguments
316            .iter()
317            .any(|argument| argument == "--always-approve"));
318        assert!(grok.runtime.capabilities.resume_session);
319    }
320}