Skip to main content

a3s_code_core/
sdk_capabilities.rs

1//! Cross-language SDK capability contract.
2//!
3//! The Rust core has a deliberately larger implementation surface than any
4//! one FFI binding (for example, Rust hosts can provide native trait objects).
5//! This module is the single source of truth for the *product* capability
6//! surface.  Every official SDK exposes this inventory verbatim so an
7//! embedding application can discover features instead of guessing from
8//! package versions or parsing tool definitions.
9//!
10//! Capabilities are tagged with a [`CapabilityTier`]:
11//! - **baseline** — required for a governed local coding-agent harness
12//! - **advanced** — optional product surfaces (workflows, evaluation, serve,
13//!   S3, state graphs, research-adjacent contracts, and similar)
14
15use serde::{Deserialize, Serialize};
16
17/// Schema identifier for [`SdkCapability`] values (pre-tier inventory).
18pub const SDK_CAPABILITIES_SCHEMA_V1: &str = "a3s-code/sdk-capabilities/v1";
19
20/// Current schema for the tiered capability inventory.
21pub const SDK_CAPABILITIES_SCHEMA_V2: &str = "a3s-code/sdk-capabilities/v2";
22
23/// Product maturity / packaging tier for one capability.
24#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
25#[serde(rename_all = "snake_case")]
26pub enum CapabilityTier {
27    /// Default coding-agent harness surface.
28    Baseline,
29    /// Opt-in or host-specialized surface; not required for local coding loops.
30    Advanced,
31}
32
33impl CapabilityTier {
34    pub const fn as_str(self) -> &'static str {
35        match self {
36            Self::Baseline => "baseline",
37            Self::Advanced => "advanced",
38        }
39    }
40}
41
42/// A product capability exposed by the Core and its official SDKs.
43///
44/// `host_owned` means that the embedding application supplies policy,
45/// credentials, or a lifecycle owner.  It does not mean that the capability
46/// is unavailable to an SDK; the SDK exposes the same typed operation and the
47/// host remains responsible for the external resource.
48#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49pub struct SdkCapability {
50    /// Stable snake-case identifier.
51    pub id: String,
52    /// Broad area used for UI grouping and telemetry.
53    pub category: String,
54    /// Human-readable contract summary.
55    pub description: String,
56    /// Canonical operation names. Language bindings map these to their naming
57    /// conventions (for example `web_search` becomes `webSearch` in Node).
58    pub operations: Vec<String>,
59    /// Whether the host owns policy, credentials, or an external lifecycle.
60    pub host_owned: bool,
61    /// Baseline coding harness versus advanced / optional surfaces.
62    pub tier: CapabilityTier,
63}
64
65struct CapabilitySpec {
66    id: &'static str,
67    category: &'static str,
68    description: &'static str,
69    operations: &'static [&'static str],
70    host_owned: bool,
71    tier: CapabilityTier,
72}
73
74const CAPABILITY_SPECS: &[CapabilitySpec] = &[
75    CapabilitySpec {
76        id: "agent_runtime",
77        category: "runtime",
78        description: "Create agents, bind workspaces, resume, replace, and close sessions.",
79        operations: &["agent.create", "agent.session", "agent.resume_session", "agent.close"],
80        host_owned: false,
81        tier: CapabilityTier::Baseline,
82    },
83    CapabilitySpec {
84        id: "conversation",
85        category: "runtime",
86        description: "Send, run, stream, attach content, inspect history, and cancel transcript-affecting turns.",
87        operations: &[
88            "session.send",
89            "session.run",
90            "session.stream",
91            "session.send_with_attachments",
92            "session.history",
93            "session.cancel",
94        ],
95        host_owned: false,
96        tier: CapabilityTier::Baseline,
97    },
98    CapabilitySpec {
99        id: "run_control",
100        category: "runtime",
101        description: "Steer or cooperatively interrupt an active run with idempotent receipts and optimistic turn guards.",
102        operations: &["session.steer", "session.interrupt", "session.run_control_snapshot"],
103        host_owned: true,
104        tier: CapabilityTier::Baseline,
105    },
106    CapabilitySpec {
107        id: "governed_tools",
108        category: "execution",
109        description: "Invoke built-in and MCP tools through validation, policy, confirmation, hooks, budgets, and tracing.",
110        operations: &["session.tool", "session.governed_tool", "session.tool_definitions"],
111        host_owned: true,
112        tier: CapabilityTier::Baseline,
113    },
114    CapabilitySpec {
115        id: "workspace_tools",
116        category: "workspace",
117        description: "Read, write, list, edit, patch, shell, glob, and grep through the governed workspace boundary.",
118        operations: &[
119            "session.read_file",
120            "session.write_file",
121            "session.ls",
122            "session.edit_file",
123            "session.patch_file",
124            "session.bash",
125            "session.glob",
126            "session.grep",
127            "session.git",
128        ],
129        host_owned: true,
130        tier: CapabilityTier::Baseline,
131    },
132    CapabilitySpec {
133        id: "workspace_retrieval",
134        category: "workspace",
135        description: "Run exact, lexical, symbol, semantic, and hybrid retrieval with bounded session-owned state.",
136        operations: &[
137            "session.workspace_retrieval_status",
138            "session.semantic_search",
139            "session.hybrid_search",
140        ],
141        host_owned: true,
142        tier: CapabilityTier::Baseline,
143    },
144    CapabilitySpec {
145        id: "model_adapters",
146        category: "model",
147        description: "Resolve configured Anthropic, OpenAI-compatible, and custom host model adapters.",
148        operations: &["agent.create", "session.send", "session.stream"],
149        host_owned: true,
150        tier: CapabilityTier::Baseline,
151    },
152    CapabilitySpec {
153        id: "structured_output",
154        category: "model",
155        description: "Request schema-constrained model output with validation and bounded repair.",
156        operations: &["session.send", "session.run", "session.task"],
157        host_owned: true,
158        tier: CapabilityTier::Baseline,
159    },
160    CapabilitySpec {
161        id: "mcp_and_skills",
162        category: "extension",
163        description: "Discover and mutate isolated MCP servers and filesystem or inline Skills.",
164        operations: &[
165            "session.add_mcp",
166            "session.remove_mcp",
167            "session.mcps",
168            "session.add_skill",
169            "session.skill_names",
170        ],
171        host_owned: true,
172        tier: CapabilityTier::Baseline,
173    },
174    CapabilitySpec {
175        id: "planning_delegation",
176        category: "orchestration",
177        description: "Run plans, worker agents, and unified `task` delegation with bounded fan-out and cancellation. Model-visible `parallel_task` is removed (`HARNESS-CONV4`); use `session.tasks` / multi-item `task`.",
178        operations: &["session.task", "session.tasks", "session.register_worker_agent"],
179        host_owned: true,
180        tier: CapabilityTier::Baseline,
181    },
182    CapabilitySpec {
183        id: "priority_scheduling",
184        category: "orchestration",
185        description: "Share bounded priority/FIFO admission and observe scheduler occupancy, fairness, and lifecycle counters.",
186        operations: &[
187            "session.task_scheduler_stats",
188            "session.task_scheduler_health",
189            "session.model_generation_pool_health",
190            "session.model_middleware_health",
191            "session.queue_stats",
192            "session.set_lane_handler",
193        ],
194        host_owned: false,
195        tier: CapabilityTier::Baseline,
196    },
197    CapabilitySpec {
198        id: "persistence",
199        category: "state",
200        description: "Atomically save and restore session state, runs, artifacts, traces, and verification evidence.",
201        operations: &["session.save", "agent.resume_session", "session.get_artifact"],
202        host_owned: true,
203        tier: CapabilityTier::Baseline,
204    },
205    CapabilitySpec {
206        id: "governance",
207        category: "security",
208        description: "Configure permissions, confirmations, hooks, budgets, verification, sanitization, and sandbox policy.",
209        operations: &[
210            "session.pending_confirmations",
211            "session.confirm_tool_use",
212            "session.register_hook",
213            "session.set_budget_guard",
214            "session.verify_commands",
215        ],
216        host_owned: true,
217        tier: CapabilityTier::Baseline,
218    },
219    CapabilitySpec {
220        id: "run_observability",
221        category: "observability",
222        description: "Inspect durable run snapshots, event pages, active tools, traces, and child-task state.",
223        operations: &[
224            "session.runs",
225            "session.run_snapshot",
226            "session.run_events",
227            "session.run_event_page",
228            "session.active_tools",
229            "session.subagent_tasks",
230        ],
231        host_owned: false,
232        tier: CapabilityTier::Baseline,
233    },
234    CapabilitySpec {
235        id: "context_memory",
236        category: "context",
237        description: "Use working, short-term, durable, and semantic memory with typed health and recall APIs.",
238        operations: &[
239            "session.memory",
240            "session.remember",
241            "session.recall",
242            "session.memory_stats",
243        ],
244        host_owned: true,
245        tier: CapabilityTier::Baseline,
246    },
247    CapabilitySpec {
248        id: "web_search",
249        category: "web",
250        description: "Search HTTP, native, RSS, and JavaScript-rendered engines through a3s-search v3.1.0.",
251        operations: &["session.web_search", "session.tool:web_search"],
252        host_owned: true,
253        tier: CapabilityTier::Baseline,
254    },
255    CapabilitySpec {
256        id: "code_intelligence",
257        category: "workspace",
258        description: "Query saved-file symbols, navigation, and diagnostics when a language service is available.",
259        operations: &[
260            "session.tool:code_symbols",
261            "session.tool:code_navigation",
262            "session.tool:code_diagnostics",
263        ],
264        host_owned: true,
265        tier: CapabilityTier::Advanced,
266    },
267    CapabilitySpec {
268        id: "cognitive_packages",
269        category: "context",
270        description: "Bind exact cited cognitive knowledge generations supplied by an authoritative host.",
271        operations: &[
272            "session.cognitive_package_binding",
273            "session.current_cognitive_package_binding",
274        ],
275        host_owned: true,
276        tier: CapabilityTier::Advanced,
277    },
278    CapabilitySpec {
279        id: "use_runtime_tasks",
280        category: "integration",
281        description: "Project host-owned A3S Use runtime tasks as governed model and direct-tool capabilities.",
282        operations: &["session.tool:use_runtime_task"],
283        host_owned: true,
284        tier: CapabilityTier::Advanced,
285    },
286    CapabilitySpec {
287        id: "programmable_workflows",
288        category: "orchestration",
289        description: "Execute bounded QuickJS programs and resumable parallel or Flow-backed workflows. Prefer unified `task` for model-driven coding fan-out; treat this surface as host-authored Advanced orchestration.",
290        operations: &[
291            "session.program",
292            "session.parallel",
293            "session.parallel_resumable",
294            "session.workflow_step",
295        ],
296        host_owned: true,
297        tier: CapabilityTier::Advanced,
298    },
299    CapabilitySpec {
300        id: "state_graph",
301        category: "state",
302        description: "Maintain hash-linked state graph events, patches, forks, and deterministic diffs.",
303        operations: &[
304            "state_graph.create",
305            "state_graph.restore",
306            "state_graph.propose_patch",
307            "state_graph.diff",
308        ],
309        host_owned: true,
310        tier: CapabilityTier::Advanced,
311    },
312    CapabilitySpec {
313        id: "agent_release_contract",
314        category: "deployment",
315        description: "Validate versioned asset manifests, provenance, and compatibility before activation.",
316        operations: &["release.admit", "release.bind_publication", "release.verify"],
317        host_owned: true,
318        tier: CapabilityTier::Advanced,
319    },
320    CapabilitySpec {
321        id: "agent_protocol",
322        category: "transport",
323        description: "Serve versioned session/run start, cancellation, recovery, and event-page protocols.",
324        operations: &[
325            "agent_protocol.start",
326            "agent_protocol.cancel",
327            "agent_protocol.recover",
328            "agent_protocol.events",
329        ],
330        host_owned: true,
331        tier: CapabilityTier::Advanced,
332    },
333    CapabilitySpec {
334        id: "evaluation_substrate",
335        category: "evaluation",
336        description: "Project bounded evidence, isolated auxiliary lifecycle, restart-safe dispatch claims, and immutable evaluation records through versioned boundaries.",
337        operations: &[
338            "evaluation.evidence",
339            "evaluation.auxiliary",
340            "evaluation.dispatch_ledger",
341            "evaluation.result",
342            "evaluation.result_store",
343            "evaluation.wire_v1",
344        ],
345        host_owned: true,
346        tier: CapabilityTier::Advanced,
347    },
348    CapabilitySpec {
349        id: "moli_runtime",
350        category: "web",
351        description: "Use a verified packaged or shared-cache Moli runtime with cross-process installation locking.",
352        operations: &["moli.default", "moli.ensure", "moli.packaged"],
353        host_owned: true,
354        tier: CapabilityTier::Advanced,
355    },
356    CapabilitySpec {
357        id: "s3_workspace",
358        category: "workspace",
359        description: "Use an S3-compatible workspace backend with bounded reads and search. Requires the SDK `s3` Cargo feature.",
360        operations: &[
361            "session.workspace_backend:s3",
362            "session.read_file",
363            "session.write_file",
364        ],
365        host_owned: true,
366        tier: CapabilityTier::Advanced,
367    },
368    CapabilitySpec {
369        id: "filesystem_agent_server",
370        category: "deployment",
371        description: "Serve agent directories with validated schedules, tools, readiness, and joined shutdown. Requires the SDK `serve` Cargo feature.",
372        operations: &["agent.serve_agent_dir", "serve.status", "serve.stop"],
373        host_owned: true,
374        tier: CapabilityTier::Advanced,
375    },
376    CapabilitySpec {
377        id: "opentelemetry",
378        category: "observability",
379        description: "Export redacted runtime traces and metrics through the optional OTLP integration. Requires the Core `telemetry` Cargo feature.",
380        operations: &["telemetry.init", "session.trace_events"],
381        host_owned: true,
382        tier: CapabilityTier::Advanced,
383    },
384];
385
386/// Return the complete, ordered product capability inventory.
387pub fn sdk_capabilities() -> Vec<SdkCapability> {
388    CAPABILITY_SPECS
389        .iter()
390        .map(|spec| SdkCapability {
391            id: spec.id.to_owned(),
392            category: spec.category.to_owned(),
393            description: spec.description.to_owned(),
394            operations: spec
395                .operations
396                .iter()
397                .map(|value| (*value).to_owned())
398                .collect(),
399            host_owned: spec.host_owned,
400            tier: spec.tier,
401        })
402        .collect()
403}
404
405/// Return baseline coding-harness capabilities only.
406pub fn sdk_baseline_capabilities() -> Vec<SdkCapability> {
407    sdk_capabilities()
408        .into_iter()
409        .filter(|capability| capability.tier == CapabilityTier::Baseline)
410        .collect()
411}
412
413/// Return the schema identifier used by the inventory endpoint.
414pub const fn sdk_capabilities_schema() -> &'static str {
415    SDK_CAPABILITIES_SCHEMA_V2
416}
417
418#[cfg(test)]
419mod tests {
420    use super::*;
421    use std::collections::HashSet;
422
423    #[test]
424    fn inventory_is_stable_and_complete() {
425        let capabilities = sdk_capabilities();
426        assert!(capabilities.len() >= 20);
427        let ids = capabilities
428            .iter()
429            .map(|item| item.id.as_str())
430            .collect::<Vec<_>>();
431        assert_eq!(ids.len(), ids.iter().collect::<HashSet<_>>().len());
432        for capability in &capabilities {
433            assert!(!capability.category.is_empty());
434            assert!(!capability.description.is_empty());
435            assert!(!capability.operations.is_empty());
436        }
437        let required_baseline = [
438            "agent_runtime",
439            "conversation",
440            "governed_tools",
441            "workspace_tools",
442            "workspace_retrieval",
443            "planning_delegation",
444            "persistence",
445            "governance",
446            "run_control",
447            "web_search",
448        ];
449        for id in required_baseline {
450            let capability = capabilities
451                .iter()
452                .find(|item| item.id == id)
453                .unwrap_or_else(|| panic!("missing capability {id}"));
454            assert_eq!(
455                capability.tier,
456                CapabilityTier::Baseline,
457                "{id} must be baseline"
458            );
459        }
460        let required_advanced = [
461            "evaluation_substrate",
462            "state_graph",
463            "programmable_workflows",
464            "s3_workspace",
465            "filesystem_agent_server",
466            "opentelemetry",
467            "moli_runtime",
468        ];
469        for id in required_advanced {
470            let capability = capabilities
471                .iter()
472                .find(|item| item.id == id)
473                .unwrap_or_else(|| panic!("missing capability {id}"));
474            assert_eq!(
475                capability.tier,
476                CapabilityTier::Advanced,
477                "{id} must be advanced"
478            );
479        }
480    }
481
482    #[test]
483    fn planning_delegation_omits_deprecated_parallel_task() {
484        let planning = sdk_capabilities()
485            .into_iter()
486            .find(|item| item.id == "planning_delegation")
487            .expect("planning_delegation");
488        assert!(planning
489            .operations
490            .iter()
491            .all(|operation| operation != "session.parallel_task"));
492        assert!(
493            planning.description.contains("removed")
494                || planning.description.contains("HARNESS-CONV4"),
495            "planning_delegation must document parallel_task removal"
496        );
497    }
498
499    #[test]
500    fn baseline_filter_excludes_advanced_surfaces() {
501        let baseline = sdk_baseline_capabilities();
502        assert!(baseline
503            .iter()
504            .all(|capability| capability.tier == CapabilityTier::Baseline));
505        assert!(!baseline.iter().any(|capability| {
506            matches!(
507                capability.id.as_str(),
508                "evaluation_substrate"
509                    | "state_graph"
510                    | "s3_workspace"
511                    | "filesystem_agent_server"
512                    | "programmable_workflows"
513            )
514        }));
515        assert!(baseline.len() >= 12);
516        assert!(baseline.len() < sdk_capabilities().len());
517    }
518
519    #[test]
520    fn inventory_serializes_with_schema() {
521        let value = serde_json::json!({
522            "schema": sdk_capabilities_schema(),
523            "capabilities": sdk_capabilities(),
524        });
525        assert_eq!(value["schema"], SDK_CAPABILITIES_SCHEMA_V2);
526        let first = &value["capabilities"][0];
527        assert!(first.get("tier").is_some());
528        assert!(value["capabilities"]
529            .as_array()
530            .is_some_and(|items| !items.is_empty()));
531    }
532
533    #[test]
534    fn tier_display_strings_are_stable() {
535        assert_eq!(CapabilityTier::Baseline.as_str(), "baseline");
536        assert_eq!(CapabilityTier::Advanced.as_str(), "advanced");
537    }
538}