use std::{fmt::Debug, fs, path::PathBuf};
use serde::{de::DeserializeOwned, Serialize};
use serde_json::Value;
use subc_control::{
CatalogEntry, ClientControlRequest, ClientControlResponse, ConsumerIdentity, PollKind,
SupervisorEntry, SupervisorHealthEntry, SupervisorHealthStatus, SupervisorRescanResult,
};
use subc_protocol::{
manifest::{
Concurrency, ExecutionMode, IdentityScope, InternalTransport, ManagementOperation,
ManagementOperationKind, ObservabilityKind, ObservabilitySurface, PipelineAppliesTo,
PipelineStageKind, ProviderRole, Tool,
},
session::HealthStatus,
BindIdentity, RouteTarget, PROTOCOL_VERSION,
};
#[test]
fn control_wire_shapes_match_golden_json_and_round_trip() {
for (name, request) in client_control_requests() {
assert_golden(name, &request);
}
for (name, response) in client_control_responses() {
assert_golden(name, &response);
}
assert_golden("catalog_entry", &catalog_entry());
assert_golden("supervisor_entry", &supervisor_entry());
assert_golden("poll_kind_status", &PollKind::Status);
assert_golden("poll_kind_liveness", &PollKind::Liveness);
}
fn assert_golden<T>(name: &str, value: &T)
where
T: Serialize + DeserializeOwned + PartialEq + Debug,
{
let actual = serde_json::to_value(value).unwrap();
let path = golden_path(name);
if std::env::var_os("UPDATE_GOLDEN").is_some() {
fs::write(
&path,
format!("{}\n", serde_json::to_string_pretty(&actual).unwrap()),
)
.unwrap();
}
let expected: Value = serde_json::from_str(&fs::read_to_string(&path).unwrap()).unwrap();
assert_eq!(
actual, expected,
"golden JSON drift for {name}; rerun with UPDATE_GOLDEN=1 only after updating the TS mirror"
);
let decoded: T = serde_json::from_value(expected).unwrap();
assert_eq!(
&decoded, value,
"golden JSON no longer decodes to canonical Rust {name}"
);
}
fn golden_path(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("golden")
.join(format!("{name}.json"))
}
fn client_control_requests() -> Vec<(&'static str, ClientControlRequest)> {
vec![
(
"client_control_request_server_describe",
ClientControlRequest::ServerDescribe {},
),
(
"client_control_request_catalog_list",
ClientControlRequest::CatalogList {
module_id: Some("aft-tools".to_string()),
},
),
(
"client_control_request_route_open",
ClientControlRequest::RouteOpen {
target: RouteTarget::InternalService {
module_id: "llm-runner".to_string(),
service_id: "llm".to_string(),
},
identity: bind_identity(),
consumer_identity: Some(ConsumerIdentity {
module_id: "subc-mcp".to_string(),
launch_nonce: "0123456789abcdef".to_string(),
}),
consumer_capabilities: Some(vec!["elicitation".to_string(), "roots".to_string()]),
admission_facts: Some(
serde_json::json!({"schema": 1, "verified_class": "service"}),
),
},
),
(
"client_control_request_route_open_without_consumer_capabilities",
ClientControlRequest::RouteOpen {
target: RouteTarget::InternalService {
module_id: "llm-runner".to_string(),
service_id: "llm".to_string(),
},
identity: bind_identity(),
consumer_identity: Some(ConsumerIdentity {
module_id: "subc-mcp".to_string(),
launch_nonce: "0123456789abcdef".to_string(),
}),
consumer_capabilities: None,
admission_facts: None,
},
),
(
"client_control_request_route_poll",
ClientControlRequest::RoutePoll {
route_channel: 42,
route_epoch: 7,
kind: PollKind::Status,
},
),
(
"client_control_request_supervisor_list",
ClientControlRequest::SupervisorList {},
),
(
"client_control_request_supervisor_restart",
ClientControlRequest::SupervisorRestart {
module_id: "aft-tools".to_string(),
},
),
(
"client_control_request_supervisor_reload",
ClientControlRequest::SupervisorReload {
module_id: "aft-tools".to_string(),
},
),
(
"client_control_request_supervisor_rescan",
ClientControlRequest::SupervisorRescan { preview: false },
),
(
"client_control_request_supervisor_rescan_preview",
ClientControlRequest::SupervisorRescan { preview: true },
),
(
"client_control_request_supervisor_set_enabled",
ClientControlRequest::SupervisorSetEnabled {
module_id: "aft-tools".to_string(),
enabled: false,
},
),
(
"client_control_request_supervisor_health_probe",
ClientControlRequest::SupervisorHealthProbe {
module_id: "aft-tools".to_string(),
},
),
(
"client_control_request_supervisor_health",
ClientControlRequest::SupervisorHealth {},
),
]
}
fn client_control_responses() -> Vec<(&'static str, ClientControlResponse)> {
vec![
(
"client_control_response_server_describe",
ClientControlResponse::ServerDescribe {
protocol_ver: PROTOCOL_VERSION,
subc_ops: thin_core_ops(),
capabilities: vec!["manifest_registration_v1".to_string()],
connected_clients: 2,
counters: None,
build_git_sha: None,
build_lock_digest: None,
},
),
(
"client_control_response_server_describe_with_counters",
ClientControlResponse::ServerDescribe {
protocol_ver: PROTOCOL_VERSION,
subc_ops: thin_core_ops(),
capabilities: vec!["manifest_registration_v1".to_string()],
connected_clients: 2,
counters: Some(serde_json::json!({
"module_frames_dropped_no_route": 3,
"client_frames_dropped_stale_route": 2,
"client_egress_close_delivery_failed": 1,
"goodbye_relay_client_failed": 4,
"goodbye_relay_module_dropped": 5,
"route_released_epoch_fenced": 6,
"route_release_stale_skipped": 7,
})),
build_git_sha: Some("0123456789abcdef0123456789abcdef01234567".to_string()),
build_lock_digest: Some(
"9d2c0d69cd82f2151bbb2b32ab9ac9d861063ffde2f8582afe767ec7e1f2145c".to_string(),
),
},
),
(
"client_control_response_catalog_list",
ClientControlResponse::CatalogList {
generation: 7,
modules: vec![catalog_entry()],
subc_ops: thin_core_ops(),
},
),
(
"client_control_response_route_open",
ClientControlResponse::RouteOpen {
route_channel: 42,
route_epoch: 7,
},
),
(
"client_control_response_route_poll",
ClientControlResponse::RoutePoll {
route_channel: 42,
route_epoch: 7,
status: Some("indexing".to_string()),
live: None,
},
),
(
"client_control_response_supervisor_list",
ClientControlResponse::SupervisorList {
generation: 7,
modules: vec![supervisor_entry()],
},
),
(
"client_control_response_supervisor_ack",
ClientControlResponse::SupervisorAck {
module_id: "aft-tools".to_string(),
applied: true,
},
),
(
"client_control_response_supervisor_rescan",
ClientControlResponse::SupervisorRescan {
result: SupervisorRescanResult {
added: vec!["new-tools".to_string()],
removed: vec!["old-tools".to_string()],
changed_pending_reload: vec!["aft-tools".to_string()],
enabled_changes: vec!["paused-tools".to_string()],
unchanged: 3,
preview: false,
restart_required: vec!["storage".to_string()],
},
},
),
(
"client_control_response_supervisor_health_probe",
ClientControlResponse::SupervisorHealthProbe {
module_id: "aft-tools".to_string(),
status: HealthStatus::Degraded,
detail: Some("warming model".to_string()),
metrics: Some(serde_json::json!({"queue_depth": 3})),
},
),
(
"client_control_response_supervisor_health",
ClientControlResponse::SupervisorHealth {
generation: 7,
modules: vec![supervisor_health_entry()],
},
),
]
}
fn thin_core_ops() -> Vec<String> {
vec![
"server.describe".to_string(),
"catalog.list".to_string(),
"route.open".to_string(),
"route.poll".to_string(),
"supervisor.list".to_string(),
"supervisor.restart".to_string(),
"supervisor.reload".to_string(),
"supervisor.rescan".to_string(),
"supervisor.set_enabled".to_string(),
"supervisor.health_probe".to_string(),
"supervisor.health".to_string(),
]
}
fn bind_identity() -> BindIdentity {
BindIdentity {
project_root: PathBuf::from("/tmp/subc/project"),
harness: "opencode".to_string(),
session: "session-0001".to_string(),
}
}
fn catalog_entry() -> CatalogEntry {
CatalogEntry {
module_id: "aft-tools".to_string(),
module_version: Some("0.9.3".to_string()),
roles: provider_roles(),
control_ops: vec!["route.bind".to_string(), "route.status".to_string()],
}
}
fn supervisor_entry() -> SupervisorEntry {
SupervisorEntry {
module_id: "aft-tools".to_string(),
state: "running".to_string(),
enabled: true,
live: true,
health: SupervisorHealthStatus::Degraded,
last_probe_ms: Some(1_700_000_000_000),
last_exit_code: None,
last_exit_signal: None,
restart_count: Some(2),
max_restarts: Some(3),
}
}
fn supervisor_health_entry() -> SupervisorHealthEntry {
SupervisorHealthEntry {
module_id: "aft-tools".to_string(),
status: SupervisorHealthStatus::Degraded,
detail: Some("warming model".to_string()),
metrics: Some(serde_json::json!({"queue_depth": 3})),
consecutive_failures: 0,
late_answer_count: 2,
last_late_answer_latency_ms: Some(8_000),
last_action: Some("report".to_string()),
last_action_ms: Some(1_700_000_000_100),
last_probe_ms: Some(1_700_000_000_050),
}
}
fn provider_roles() -> Vec<ProviderRole> {
vec![
ProviderRole::ToolProvider {
tools: vec![Tool {
name: "memory.read".to_string(),
description: None,
execution_mode: ExecutionMode::Pure,
schema: serde_json::json!({"type": "object", "required": ["id"]}),
}],
identity_scope: vec![IdentityScope::Project, IdentityScope::Session],
concurrency: Concurrency::ModuleManaged,
emits_push: true,
sub_supervises: true,
},
ProviderRole::PipelineStage {
stage: PipelineStageKind::Transform,
applies_to: PipelineAppliesTo {
provider: "anthropic".to_string(),
model: "claude".to_string(),
},
interface: "proxy-transform-v1".to_string(),
declares_frozen_floor: true,
needs_signals: vec!["route.status".to_string()],
conformance_class: "lossless".to_string(),
},
ProviderRole::ManagementSurface {
operations: vec![ManagementOperation {
name: "memory.list".to_string(),
kind: ManagementOperationKind::Query,
}],
config_schema: serde_json::json!({"type": "object"}),
observability: vec![ObservabilitySurface {
name: "memory.stats".to_string(),
kind: ObservabilityKind::Snapshot,
}],
identity_scope: vec![IdentityScope::Project],
},
ProviderRole::InternalService {
service_id: "llm".to_string(),
transport: InternalTransport::Bulk,
agent_facing: true,
operations: vec!["llm.complete".to_string()],
},
]
}