#![allow(clippy::expect_used, clippy::unwrap_used)]

use std::fs;
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use std::time::{SystemTime, UNIX_EPOCH};

use std::collections::BTreeMap;

use chio_core::{
    aggregate_generic_listing_reports, canonical_json_bytes, GenericListingActorKind,
    GenericListingQuery, GenericListingReport, GenericListingStatus, GenericRegistryPublisherRole,
    Keypair, PublicKey, Signature, SignedGenericGovernanceCase, SignedGenericGovernanceCharter,
    SignedGenericListing, SignedGenericTrustActivation, SignedOpenMarketFeeSchedule,
    SignedOpenMarketPenalty,
};
use chio_credentials::{
    build_portable_negative_event_artifact, build_portable_reputation_summary_artifact,
    evaluate_portable_reputation, PortableNegativeEventEvidenceKind,
    PortableNegativeEventEvidenceReference, PortableNegativeEventIssueRequest,
    PortableNegativeEventKind, PortableReputationEvaluationRequest, PortableReputationFindingCode,
    PortableReputationSummaryArtifactContext, PortableReputationSummaryIssueRequest,
    PortableReputationWeightingProfile, SignedPortableNegativeEvent,
    SignedPortableReputationSummary,
};
use chio_reputation::{
    BoundaryPressureMetrics, DelegationHygieneMetrics, HistoryDepthMetrics,
    IncidentCorrelationMetrics, LeastPrivilegeMetrics, LocalReputationScorecard, MetricValue,
    ReliabilityMetrics, ResourceStewardshipMetrics, SpecializationMetrics,
};
use reqwest::blocking::Client;

fn unique_path(prefix: &str, suffix: &str) -> PathBuf {
    let nonce = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("system time before unix epoch")
        .as_nanos();
    std::env::temp_dir().join(format!("{prefix}-{nonce}{suffix}"))
}

fn workspace_root() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .ancestors()
        .nth(2)
        .expect("workspace root")
        .to_path_buf()
}

fn reserve_listen_addr() -> std::net::SocketAddr {
    let listener = std::net::TcpListener::bind("127.0.0.1:0").expect("bind temp listener");
    let addr = listener.local_addr().expect("listener addr");
    drop(listener);
    addr
}

struct ServerGuard {
    child: Child,
}

impl Drop for ServerGuard {
    fn drop(&mut self) {
        let _ = self.child.kill();
        let _ = self.child.wait();
    }
}

fn spawn_trust_service(
    listen: std::net::SocketAddr,
    service_token: &str,
    certification_registry_file: Option<&PathBuf>,
    certification_discovery_file: Option<&PathBuf>,
    advertise_url: Option<&str>,
    certification_public_metadata_ttl_seconds: Option<u64>,
) -> ServerGuard {
    let mut command = Command::new(env!("CARGO_BIN_EXE_chio"));
    command.current_dir(workspace_root()).args([
        "trust",
        "serve",
        "--listen",
        &listen.to_string(),
        "--service-token",
        service_token,
    ]);
    if let Some(certification_registry_file) = certification_registry_file {
        command.args([
            "--certification-registry-file",
            certification_registry_file
                .to_str()
                .expect("certification registry path"),
        ]);
    }
    if let Some(certification_discovery_file) = certification_discovery_file {
        command.args([
            "--certification-discovery-file",
            certification_discovery_file
                .to_str()
                .expect("certification discovery path"),
        ]);
    }
    let advertise_url = advertise_url
        .map(str::to_string)
        .unwrap_or_else(|| format!("http://{listen}"));
    command.args(["--advertise-url", &advertise_url]);
    if let Some(ttl_seconds) = certification_public_metadata_ttl_seconds {
        command.args([
            "--certification-public-metadata-ttl-seconds",
            &ttl_seconds.to_string(),
        ]);
    }
    let child = command
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::piped())
        .spawn()
        .expect("spawn trust service");
    ServerGuard { child }
}

fn spawn_trust_service_with_public_registry(
    listen: std::net::SocketAddr,
    service_token: &str,
    certification_registry_file: Option<&PathBuf>,
    advertise_url: &str,
    receipt_db_path: &PathBuf,
    authority_db_path: &PathBuf,
) -> ServerGuard {
    let mut command = Command::new(env!("CARGO_BIN_EXE_chio"));
    command.current_dir(workspace_root()).args([
        "--receipt-db",
        receipt_db_path.to_str().expect("receipt db path"),
        "--authority-db",
        authority_db_path.to_str().expect("authority db path"),
        "trust",
        "serve",
        "--listen",
        &listen.to_string(),
        "--service-token",
        service_token,
        "--advertise-url",
        advertise_url,
    ]);
    if let Some(certification_registry_file) = certification_registry_file {
        command.args([
            "--certification-registry-file",
            certification_registry_file
                .to_str()
                .expect("certification registry path"),
        ]);
    }
    let child = command
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::piped())
        .spawn()
        .expect("spawn trust service with public registry");
    ServerGuard { child }
}

fn wait_for_trust_service(client: &Client, base_url: &str) {
    for _ in 0..100 {
        match client.get(format!("{base_url}/health")).send() {
            Ok(response) if response.status() == reqwest::StatusCode::OK => return,
            Ok(_) | Err(_) => std::thread::sleep(std::time::Duration::from_millis(100)),
        }
    }
    panic!("trust service did not become ready");
}

fn write_scenario(dir: &PathBuf, id: &str) {
    fs::create_dir_all(dir).expect("create scenarios dir");
    fs::write(
        dir.join(format!("{id}.json")),
        format!(
            r#"{{
  "id": "{id}",
  "title": "Scenario {id}",
  "area": "core",
  "category": "mcp-core",
  "specVersions": ["2025-11-25"],
  "transport": ["stdio"],
  "peerRoles": ["client_to_chio_server"],
  "deploymentModes": ["wrapped_stdio"],
  "requiredCapabilities": {{"server": [], "client": []}},
  "tags": ["wave1"],
  "expected": "pass"
}}"#
        ),
    )
    .expect("write scenario");
}

fn write_results(dir: &PathBuf, scenario_id: &str, status: &str) {
    fs::create_dir_all(dir).expect("create results dir");
    fs::write(
        dir.join("results.json"),
        format!(
            r#"[{{
  "scenarioId": "{scenario_id}",
  "peer": "js",
  "peerRole": "client_to_chio_server",
  "deploymentMode": "wrapped_stdio",
  "transport": "stdio",
  "specVersion": "2025-11-25",
  "category": "mcp-core",
  "status": "{status}",
  "durationMs": 12,
  "assertions": [{{"name": "ok", "status": "pass"}}]
}}]"#
        ),
    )
    .expect("write results");
}

fn write_discovery_network(path: &PathBuf, operators: &[(&str, &str, &str, bool)]) {
    let operators_json = operators
        .iter()
        .map(
            |(operator_id, registry_url, control_token, allow_publish)| {
                (
                    operator_id.to_string(),
                    serde_json::json!({
                        "operatorId": operator_id,
                        "operatorName": format!("Operator {operator_id}"),
                        "registryUrl": registry_url,
                        "controlToken": control_token,
                        "allowPublish": allow_publish,
                        "trustLabels": ["public"]
                    }),
                )
            },
        )
        .collect::<serde_json::Map<String, serde_json::Value>>();
    fs::write(
        path,
        serde_json::to_vec_pretty(&serde_json::json!({
            "version": "chio.certify.discovery-network.v1",
            "operators": operators_json
        }))
        .expect("serialize discovery network"),
    )
    .expect("write discovery network");
}

fn run_certify_check(
    scenarios_dir: &PathBuf,
    results_dir: &PathBuf,
    output_path: &PathBuf,
    seed_path: &PathBuf,
    tool_server_id: &str,
    tool_server_name: Option<&str>,
) {
    let mut command = Command::new(env!("CARGO_BIN_EXE_chio"));
    command.current_dir(workspace_root()).args([
        "certify",
        "check",
        "--scenarios-dir",
        scenarios_dir.to_str().expect("scenarios dir"),
        "--results-dir",
        results_dir.to_str().expect("results dir"),
        "--output",
        output_path.to_str().expect("output path"),
        "--tool-server-id",
        tool_server_id,
        "--signing-seed-file",
        seed_path.to_str().expect("seed path"),
    ]);
    if let Some(tool_server_name) = tool_server_name {
        command.args(["--tool-server-name", tool_server_name]);
    }
    let output = command.output().expect("run chio certify check");
    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
}

fn publish_remote_certification(
    base_url: &str,
    service_token: &str,
    artifact_path: &PathBuf,
) -> serde_json::Value {
    let output = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "publish",
            "--input",
            artifact_path.to_str().expect("artifact path"),
        ])
        .output()
        .expect("run remote certification publish");
    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    serde_json::from_slice(&output.stdout).expect("parse remote publish output")
}

fn revoke_remote_certification(
    base_url: &str,
    service_token: &str,
    artifact_id: &str,
    reason: &str,
) -> serde_json::Value {
    let output = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "revoke",
            "--artifact-id",
            artifact_id,
            "--reason",
            reason,
        ])
        .output()
        .expect("run remote certification revoke");
    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    serde_json::from_slice(&output.stdout).expect("parse remote revoke output")
}

fn issue_local_liability_provider(
    receipt_db_path: &PathBuf,
    authority_db_path: &PathBuf,
    provider_id: &str,
) -> serde_json::Value {
    let provider_file = unique_path("chio-generic-listing-provider", ".json");
    fs::write(
        &provider_file,
        serde_json::to_vec_pretty(&serde_json::json!({
            "schema": "chio.market.provider.v1",
            "displayName": "Generic Listing Carrier",
            "providerId": provider_id,
            "providerType": "admitted_carrier",
            "providerUrl": "https://carrier-generic.example.com",
            "lifecycleState": "active",
            "supportBoundary": {
                "curatedRegistryOnly": true,
                "automaticTrustAdmission": false,
                "permissionlessFederationSupported": false,
                "boundCoverageSupported": false
            },
            "policies": [{
                "jurisdiction": "us-ny",
                "coverageClasses": ["tool_execution"],
                "supportedCurrencies": ["USD"],
                "requiredEvidence": ["credit_provider_risk_package"],
                "claimsSupported": true,
                "quoteTtlSeconds": 1800
            }],
            "provenance": {
                "configuredBy": "operator@example.com",
                "configuredAt": 1,
                "sourceRef": "phase-117-test"
            }
        }))
        .expect("serialize provider input"),
    )
    .expect("write provider input");
    let output = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--receipt-db",
            receipt_db_path.to_str().expect("receipt db path"),
            "--authority-db",
            authority_db_path.to_str().expect("authority db path"),
            "trust",
            "liability-provider",
            "issue",
            "--input-file",
            provider_file.to_str().expect("provider input path"),
        ])
        .output()
        .expect("run liability provider issue");
    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    serde_json::from_slice(&output.stdout).expect("parse issued liability provider")
}

fn sample_portable_reputation_scorecard(
    subject_key: &str,
    composite_score: f64,
) -> LocalReputationScorecard {
    LocalReputationScorecard {
        subject_key: subject_key.to_string(),
        computed_at: 1_700_000_100,
        boundary_pressure: BoundaryPressureMetrics {
            deny_ratio: MetricValue::Known(0.1),
            policies_observed: 4,
            receipts_observed: 8,
        },
        resource_stewardship: ResourceStewardshipMetrics {
            average_utilization: MetricValue::Known(0.8),
            fit_score: MetricValue::Known(0.9),
            capped_grants_observed: 3,
        },
        least_privilege: LeastPrivilegeMetrics {
            score: MetricValue::Known(0.9),
            capabilities_observed: 6,
        },
        history_depth: HistoryDepthMetrics {
            score: MetricValue::Known(0.8),
            receipt_count: 8,
            active_days: 4,
            first_seen: Some(1_700_000_000),
            last_seen: Some(1_700_000_100),
            span_days: 4,
            activity_ratio: MetricValue::Known(0.75),
        },
        specialization: SpecializationMetrics {
            score: MetricValue::Known(0.7),
            distinct_tools: 2,
        },
        delegation_hygiene: DelegationHygieneMetrics {
            score: MetricValue::Known(0.8),
            delegations_observed: 2,
            scope_reduction_rate: MetricValue::Known(0.8),
            ttl_reduction_rate: MetricValue::Known(0.8),
            budget_reduction_rate: MetricValue::Known(0.8),
        },
        reliability: ReliabilityMetrics {
            score: MetricValue::Known(0.9),
            completion_rate: MetricValue::Known(0.95),
            cancellation_rate: MetricValue::Known(0.02),
            incompletion_rate: MetricValue::Known(0.03),
            receipts_observed: 8,
        },
        incident_correlation: IncidentCorrelationMetrics {
            score: MetricValue::Known(0.9),
            incidents_observed: Some(0),
        },
        composite_score: MetricValue::Known(composite_score),
        effective_weight_sum: 1.0,
    }
}

#[test]
fn certify_check_emits_signed_pass_artifact_and_report() {
    let scenarios_dir = unique_path("chio-certify-scenarios", "");
    let results_dir = unique_path("chio-certify-results", "");
    let output_path = unique_path("chio-certify-artifact", ".json");
    let report_path = unique_path("chio-certify-report", ".md");
    let seed_path = unique_path("chio-certify-seed", ".txt");

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");

    let output = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "certify",
            "check",
            "--scenarios-dir",
            scenarios_dir.to_str().expect("scenarios dir"),
            "--results-dir",
            results_dir.to_str().expect("results dir"),
            "--output",
            output_path.to_str().expect("output path"),
            "--tool-server-id",
            "demo-server",
            "--tool-server-name",
            "Demo Server",
            "--report-output",
            report_path.to_str().expect("report path"),
            "--signing-seed-file",
            seed_path.to_str().expect("seed path"),
        ])
        .output()
        .expect("run chio certify check");

    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    assert!(output_path.exists(), "artifact should exist");
    assert!(report_path.exists(), "report should exist");
    assert!(seed_path.exists(), "seed file should exist");

    let artifact: serde_json::Value =
        serde_json::from_slice(&fs::read(&output_path).expect("read artifact"))
            .expect("parse artifact");
    assert_eq!(artifact["body"]["schema"], "chio.certify.check.v1");
    assert_eq!(artifact["body"]["verdict"], "pass");
    assert_eq!(
        artifact["body"]["criteriaProfile"],
        "conformance-all-pass-v1"
    );
    assert_eq!(
        artifact["body"]["evidence"]["evidenceProfile"],
        "conformance-report-bundle-v1"
    );
    assert_eq!(
        artifact["body"]["evidence"]["generatedReportMediaType"],
        "text/markdown"
    );
    assert_eq!(
        artifact["body"]["evidence"]["provenanceMode"],
        "artifact-signer-key"
    );
    assert_eq!(artifact["body"]["summary"]["passCount"], 1);

    let public_key: PublicKey =
        serde_json::from_value(artifact["signerPublicKey"].clone()).expect("public key");
    let signature: Signature =
        serde_json::from_value(artifact["signature"].clone()).expect("signature");
    let body = artifact["body"].clone();
    let body_bytes = canonical_json_bytes(&body).expect("canonical body");
    assert!(public_key.verify(&body_bytes, &signature));

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(report_path);
    let _ = fs::remove_file(seed_path);
}

#[test]
fn certify_check_emits_signed_fail_artifact_with_findings() {
    let scenarios_dir = unique_path("chio-certify-scenarios-fail", "");
    let results_dir = unique_path("chio-certify-results-fail", "");
    let output_path = unique_path("chio-certify-artifact-fail", ".json");
    let seed_path = unique_path("chio-certify-seed-fail", ".txt");

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "unsupported");

    let output = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "certify",
            "check",
            "--scenarios-dir",
            scenarios_dir.to_str().expect("scenarios dir"),
            "--results-dir",
            results_dir.to_str().expect("results dir"),
            "--output",
            output_path.to_str().expect("output path"),
            "--tool-server-id",
            "demo-server",
            "--signing-seed-file",
            seed_path.to_str().expect("seed path"),
        ])
        .output()
        .expect("run chio certify check");

    assert!(
        output.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );

    let artifact: serde_json::Value =
        serde_json::from_slice(&fs::read(&output_path).expect("read artifact"))
            .expect("parse artifact");
    assert_eq!(artifact["body"]["verdict"], "fail");
    assert_eq!(artifact["body"]["summary"]["unsupportedCount"], 1);
    assert!(artifact["body"]["findings"]
        .as_array()
        .expect("findings array")
        .iter()
        .any(|finding| finding["kind"] == "non-pass-result"));

    let public_key: PublicKey =
        serde_json::from_value(artifact["signerPublicKey"].clone()).expect("public key");
    let signature: Signature =
        serde_json::from_value(artifact["signature"].clone()).expect("signature");
    let body = artifact["body"].clone();
    let body_bytes = canonical_json_bytes(&body).expect("canonical body");
    assert!(public_key.verify(&body_bytes, &signature));

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(seed_path);
}

#[test]
fn certify_verify_accepts_signed_artifact() {
    let scenarios_dir = unique_path("chio-certify-verify-scenarios", "");
    let results_dir = unique_path("chio-certify-verify-results", "");
    let output_path = unique_path("chio-certify-verify-artifact", ".json");
    let seed_path = unique_path("chio-certify-verify-seed", ".txt");

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        "demo-server",
        Some("Demo Server"),
    );

    let verify = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "verify",
            "--input",
            output_path.to_str().expect("artifact path"),
        ])
        .output()
        .expect("run chio certify verify");
    assert!(
        verify.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&verify.stdout),
        String::from_utf8_lossy(&verify.stderr)
    );
    let verify_body: serde_json::Value =
        serde_json::from_slice(&verify.stdout).expect("parse verify output");
    assert_eq!(verify_body["toolServerId"], "demo-server");
    assert_eq!(verify_body["verdict"], "pass");
    assert_eq!(verify_body["verified"], true);

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(seed_path);
}

#[test]
fn certify_registry_local_publish_resolve_and_revoke_work() {
    let scenarios_dir = unique_path("chio-certify-registry-local-scenarios", "");
    let results_dir = unique_path("chio-certify-registry-local-results", "");
    let output_path = unique_path("chio-certify-registry-local-artifact", ".json");
    let replacement_output_path =
        unique_path("chio-certify-registry-local-artifact-replacement", ".json");
    let seed_path = unique_path("chio-certify-registry-local-seed", ".txt");
    let registry_path = unique_path("chio-certify-registry-local", ".json");

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        "demo-server",
        Some("Demo Server"),
    );
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &replacement_output_path,
        &seed_path,
        "demo-server",
        Some("Demo Server Replacement"),
    );

    let publish = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "publish",
            "--input",
            output_path.to_str().expect("artifact path"),
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification publish");
    assert!(
        publish.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&publish.stdout),
        String::from_utf8_lossy(&publish.stderr)
    );
    let publish_body: serde_json::Value =
        serde_json::from_slice(&publish.stdout).expect("parse publish output");
    let first_artifact_id = publish_body["artifactId"]
        .as_str()
        .expect("first artifact id")
        .to_string();
    assert_eq!(publish_body["toolServerId"], "demo-server");
    assert_eq!(publish_body["status"], "active");

    let publish_replacement = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "publish",
            "--input",
            replacement_output_path
                .to_str()
                .expect("replacement artifact path"),
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run replacement certification publish");
    assert!(
        publish_replacement.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&publish_replacement.stdout),
        String::from_utf8_lossy(&publish_replacement.stderr)
    );
    let publish_replacement_body: serde_json::Value =
        serde_json::from_slice(&publish_replacement.stdout)
            .expect("parse replacement publish output");
    let replacement_artifact_id = publish_replacement_body["artifactId"]
        .as_str()
        .expect("replacement artifact id")
        .to_string();
    assert_ne!(replacement_artifact_id, first_artifact_id);
    assert_eq!(publish_replacement_body["status"], "active");

    let list = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "list",
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification list");
    assert!(
        list.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&list.stdout),
        String::from_utf8_lossy(&list.stderr)
    );
    let list_body: serde_json::Value =
        serde_json::from_slice(&list.stdout).expect("parse list output");
    assert_eq!(list_body["count"], 2);
    assert!(list_body["artifacts"]
        .as_array()
        .expect("artifacts array")
        .iter()
        .any(|entry| entry["artifactId"] == first_artifact_id && entry["status"] == "superseded"));
    assert!(
        list_body["artifacts"]
            .as_array()
            .expect("artifacts array")
            .iter()
            .any(|entry| entry["artifactId"] == replacement_artifact_id
                && entry["status"] == "active")
    );

    let get = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "get",
            "--artifact-id",
            &replacement_artifact_id,
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification get");
    assert!(
        get.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&get.stdout),
        String::from_utf8_lossy(&get.stderr)
    );
    let get_body: serde_json::Value =
        serde_json::from_slice(&get.stdout).expect("parse get output");
    assert_eq!(get_body["artifactId"], replacement_artifact_id);
    assert_eq!(get_body["status"], "active");

    let resolve = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "resolve",
            "--tool-server-id",
            "demo-server",
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification resolve");
    assert!(
        resolve.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&resolve.stdout),
        String::from_utf8_lossy(&resolve.stderr)
    );
    let resolve_body: serde_json::Value =
        serde_json::from_slice(&resolve.stdout).expect("parse resolve output");
    assert_eq!(resolve_body["state"], "active");
    assert_eq!(
        resolve_body["current"]["artifactId"],
        replacement_artifact_id
    );

    let revoke = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "revoke",
            "--artifact-id",
            &replacement_artifact_id,
            "--reason",
            "operator-revoked",
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification revoke");
    assert!(
        revoke.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&revoke.stdout),
        String::from_utf8_lossy(&revoke.stderr)
    );
    let revoke_body: serde_json::Value =
        serde_json::from_slice(&revoke.stdout).expect("parse revoke output");
    assert_eq!(revoke_body["artifactId"], replacement_artifact_id);
    assert_eq!(revoke_body["status"], "revoked");
    assert_eq!(revoke_body["revokedReason"], "operator-revoked");

    let resolve_after_revoke = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "resolve",
            "--tool-server-id",
            "demo-server",
            "--certification-registry-file",
            registry_path.to_str().expect("registry path"),
        ])
        .output()
        .expect("run local certification resolve after revoke");
    assert!(
        resolve_after_revoke.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&resolve_after_revoke.stdout),
        String::from_utf8_lossy(&resolve_after_revoke.stderr)
    );
    let resolve_after_revoke_body: serde_json::Value =
        serde_json::from_slice(&resolve_after_revoke.stdout)
            .expect("parse resolve after revoke output");
    assert_eq!(resolve_after_revoke_body["state"], "revoked");
    assert_eq!(
        resolve_after_revoke_body["current"]["artifactId"],
        replacement_artifact_id
    );

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(replacement_output_path);
    let _ = fs::remove_file(seed_path);
    let _ = fs::remove_file(registry_path);
}

#[test]
fn certify_registry_remote_publish_list_get_resolve_and_revoke_work() {
    let scenarios_dir = unique_path("chio-certify-registry-remote-scenarios", "");
    let results_dir = unique_path("chio-certify-registry-remote-results", "");
    let output_path = unique_path("chio-certify-registry-remote-artifact", ".json");
    let seed_path = unique_path("chio-certify-registry-remote-seed", ".txt");
    let registry_path = unique_path("chio-certify-registry-remote", ".json");
    let tool_server_id = "demo/server?mode=remote#1";

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Demo Server Remote"),
    );

    let listen = reserve_listen_addr();
    let service_token = "certify-registry-remote-token";
    let _service = spawn_trust_service(
        listen,
        service_token,
        Some(&registry_path),
        None,
        None,
        None,
    );
    let client = Client::builder().build().expect("build reqwest client");
    let base_url = format!("http://{listen}");
    wait_for_trust_service(&client, &base_url);

    let publish = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "publish",
            "--input",
            output_path.to_str().expect("artifact path"),
        ])
        .output()
        .expect("run remote certification publish");
    assert!(
        publish.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&publish.stdout),
        String::from_utf8_lossy(&publish.stderr)
    );
    let publish_body: serde_json::Value =
        serde_json::from_slice(&publish.stdout).expect("parse publish output");
    let artifact_id = publish_body["artifactId"]
        .as_str()
        .expect("artifact id")
        .to_string();
    assert_eq!(publish_body["toolServerId"], tool_server_id);
    assert_eq!(publish_body["status"], "active");

    let health_after_publish = client
        .get(format!("{base_url}/health"))
        .send()
        .expect("send health request after publish");
    assert_eq!(health_after_publish.status(), reqwest::StatusCode::OK);
    let health_after_publish: serde_json::Value = health_after_publish
        .json()
        .expect("health json after publish");
    assert_eq!(
        health_after_publish["federation"]["certifications"]["configured"],
        true
    );
    assert_eq!(
        health_after_publish["federation"]["certifications"]["count"],
        1
    );
    assert_eq!(
        health_after_publish["federation"]["certifications"]["activeCount"],
        1
    );

    let list = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "list",
        ])
        .output()
        .expect("run remote certification list");
    assert!(
        list.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&list.stdout),
        String::from_utf8_lossy(&list.stderr)
    );
    let list_body: serde_json::Value =
        serde_json::from_slice(&list.stdout).expect("parse list output");
    assert_eq!(list_body["count"], 1);
    assert_eq!(list_body["artifacts"][0]["artifactId"], artifact_id);

    let get = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "get",
            "--artifact-id",
            &artifact_id,
        ])
        .output()
        .expect("run remote certification get");
    assert!(
        get.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&get.stdout),
        String::from_utf8_lossy(&get.stderr)
    );
    let get_body: serde_json::Value =
        serde_json::from_slice(&get.stdout).expect("parse get output");
    assert_eq!(get_body["artifactId"], artifact_id);

    let resolve = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "resolve",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run remote certification resolve");
    assert!(
        resolve.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&resolve.stdout),
        String::from_utf8_lossy(&resolve.stderr)
    );
    let resolve_body: serde_json::Value =
        serde_json::from_slice(&resolve.stdout).expect("parse resolve output");
    assert_eq!(resolve_body["state"], "active");
    assert_eq!(resolve_body["current"]["artifactId"], artifact_id);

    let revoke = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url,
            "--control-token",
            service_token,
            "certify",
            "registry",
            "revoke",
            "--artifact-id",
            &artifact_id,
            "--reason",
            "remote-revocation",
        ])
        .output()
        .expect("run remote certification revoke");
    assert!(
        revoke.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&revoke.stdout),
        String::from_utf8_lossy(&revoke.stderr)
    );
    let revoke_body: serde_json::Value =
        serde_json::from_slice(&revoke.stdout).expect("parse revoke output");
    assert_eq!(revoke_body["artifactId"], artifact_id);
    assert_eq!(revoke_body["status"], "revoked");
    assert_eq!(revoke_body["revokedReason"], "remote-revocation");

    let health_after_revoke = client
        .get(format!("{base_url}/health"))
        .send()
        .expect("send health request after revoke");
    assert_eq!(health_after_revoke.status(), reqwest::StatusCode::OK);
    let health_after_revoke: serde_json::Value = health_after_revoke
        .json()
        .expect("health json after revoke");
    assert_eq!(
        health_after_revoke["federation"]["certifications"]["count"],
        1
    );
    assert_eq!(
        health_after_revoke["federation"]["certifications"]["activeCount"],
        0
    );
    assert_eq!(
        health_after_revoke["federation"]["certifications"]["revokedCount"],
        1
    );

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(seed_path);
    let _ = fs::remove_file(registry_path);
}

#[test]
fn certify_registry_discover_reports_per_operator_public_state() {
    let scenarios_dir = unique_path("chio-certify-discover-scenarios", "");
    let results_dir = unique_path("chio-certify-discover-results", "");
    let output_path = unique_path("chio-certify-discover-artifact", ".json");
    let seed_path = unique_path("chio-certify-discover-seed", ".txt");
    let registry_a_path = unique_path("chio-certify-discover-registry-a", ".json");
    let registry_b_path = unique_path("chio-certify-discover-registry-b", ".json");
    let network_path = unique_path("chio-certify-discovery-network", ".json");

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        "demo-server-discovery",
        Some("Demo Server Discovery"),
    );

    let listen_a = reserve_listen_addr();
    let listen_b = reserve_listen_addr();
    let token_a = "certify-discover-token-a";
    let token_b = "certify-discover-token-b";
    let _service_a =
        spawn_trust_service(listen_a, token_a, Some(&registry_a_path), None, None, None);
    let _service_b =
        spawn_trust_service(listen_b, token_b, Some(&registry_b_path), None, None, None);
    let client = Client::builder().build().expect("build reqwest client");
    let base_url_a = format!("http://{listen_a}");
    let base_url_b = format!("http://{listen_b}");
    wait_for_trust_service(&client, &base_url_a);
    wait_for_trust_service(&client, &base_url_b);

    let publish_a = publish_remote_certification(&base_url_a, token_a, &output_path);
    let publish_b = publish_remote_certification(&base_url_b, token_b, &output_path);
    assert_eq!(publish_a["status"], "active");
    let artifact_id = publish_b["artifactId"]
        .as_str()
        .expect("artifact id")
        .to_string();
    revoke_remote_certification(&base_url_b, token_b, &artifact_id, "discovery-revoked");

    write_discovery_network(
        &network_path,
        &[
            ("alpha", &base_url_a, token_a, true),
            ("beta", &base_url_b, token_b, true),
        ],
    );

    let discover = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "discover",
            "--tool-server-id",
            "demo-server-discovery",
            "--certification-discovery-file",
            network_path.to_str().expect("network path"),
        ])
        .output()
        .expect("run certification discovery");
    assert!(
        discover.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&discover.stdout),
        String::from_utf8_lossy(&discover.stderr)
    );
    let discover_body: serde_json::Value =
        serde_json::from_slice(&discover.stdout).expect("parse discovery output");
    assert_eq!(discover_body["peerCount"], 2);
    assert_eq!(discover_body["reachableCount"], 2);
    assert_eq!(discover_body["activeCount"], 1);
    assert_eq!(discover_body["revokedCount"], 1);
    assert!(discover_body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .any(|peer| peer["operatorId"] == "alpha" && peer["resolution"]["state"] == "active"));
    assert!(discover_body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .any(|peer| peer["operatorId"] == "beta" && peer["resolution"]["state"] == "revoked"));

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(seed_path);
    let _ = fs::remove_file(registry_a_path);
    let _ = fs::remove_file(registry_b_path);
    let _ = fs::remove_file(network_path);
}

#[test]
fn certify_registry_publish_network_and_remote_discover_work() {
    let scenarios_dir = unique_path("chio-certify-network-publish-scenarios", "");
    let results_dir = unique_path("chio-certify-network-publish-results", "");
    let output_path = unique_path("chio-certify-network-publish-artifact", ".json");
    let seed_path = unique_path("chio-certify-network-publish-seed", ".txt");
    let registry_a_path = unique_path("chio-certify-network-publish-registry-a", ".json");
    let registry_b_path = unique_path("chio-certify-network-publish-registry-b", ".json");
    let aggregator_registry_path =
        unique_path("chio-certify-network-publish-aggregator-registry", ".json");
    let network_path = unique_path("chio-certify-network-publish-network", ".json");
    let tool_server_id = "demo/server?mode=network#1";

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Demo Server Network Publish"),
    );

    let listen_a = reserve_listen_addr();
    let listen_b = reserve_listen_addr();
    let listen_aggregator = reserve_listen_addr();
    let token_a = "certify-network-token-a";
    let token_b = "certify-network-token-b";
    let aggregator_token = "certify-network-aggregator-token";
    let _service_a =
        spawn_trust_service(listen_a, token_a, Some(&registry_a_path), None, None, None);
    let _service_b =
        spawn_trust_service(listen_b, token_b, Some(&registry_b_path), None, None, None);
    let client = Client::builder().build().expect("build reqwest client");
    let base_url_a = format!("http://{listen_a}");
    let base_url_b = format!("http://{listen_b}");
    wait_for_trust_service(&client, &base_url_a);
    wait_for_trust_service(&client, &base_url_b);

    write_discovery_network(
        &network_path,
        &[
            ("alpha", &base_url_a, token_a, true),
            ("beta", &base_url_b, token_b, true),
        ],
    );

    let base_url_aggregator = format!("http://{listen_aggregator}");
    let _aggregator = spawn_trust_service(
        listen_aggregator,
        aggregator_token,
        Some(&aggregator_registry_path),
        Some(&network_path),
        None,
        None,
    );
    wait_for_trust_service(&client, &base_url_aggregator);

    let publish_network = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            aggregator_token,
            "certify",
            "registry",
            "publish-network",
            "--input",
            output_path.to_str().expect("artifact path"),
        ])
        .output()
        .expect("run certification network publish");
    assert!(
        publish_network.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&publish_network.stdout),
        String::from_utf8_lossy(&publish_network.stderr)
    );
    let publish_network_body: serde_json::Value =
        serde_json::from_slice(&publish_network.stdout).expect("parse publish network output");
    assert_eq!(publish_network_body["peerCount"], 2);
    assert_eq!(publish_network_body["successCount"], 2);

    let discover_network = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            aggregator_token,
            "certify",
            "registry",
            "discover",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run remote certification discovery");
    assert!(
        discover_network.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&discover_network.stdout),
        String::from_utf8_lossy(&discover_network.stderr)
    );
    let discover_network_body: serde_json::Value =
        serde_json::from_slice(&discover_network.stdout).expect("parse discovery network output");
    assert_eq!(discover_network_body["peerCount"], 2);
    assert_eq!(discover_network_body["activeCount"], 2);
    assert!(discover_network_body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .all(|peer| peer["resolution"]["state"] == "active"));

    let resolve_a = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_a,
            "--control-token",
            token_a,
            "certify",
            "registry",
            "resolve",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run remote certification resolve alpha");
    assert!(resolve_a.status.success());
    let resolve_a_body: serde_json::Value =
        serde_json::from_slice(&resolve_a.stdout).expect("parse resolve alpha");
    assert_eq!(resolve_a_body["state"], "active");

    let resolve_b = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_b,
            "--control-token",
            token_b,
            "certify",
            "registry",
            "resolve",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run remote certification resolve beta");
    assert!(resolve_b.status.success());
    let resolve_b_body: serde_json::Value =
        serde_json::from_slice(&resolve_b.stdout).expect("parse resolve beta");
    assert_eq!(resolve_b_body["state"], "active");

    let _ = fs::remove_dir_all(scenarios_dir);
    let _ = fs::remove_dir_all(results_dir);
    let _ = fs::remove_file(output_path);
    let _ = fs::remove_file(seed_path);
    let _ = fs::remove_file(registry_a_path);
    let _ = fs::remove_file(registry_b_path);
    let _ = fs::remove_file(aggregator_registry_path);
    let _ = fs::remove_file(network_path);
}

#[test]
fn certify_registry_discover_fails_closed_on_stale_and_mismatched_public_metadata() {
    let scenarios_dir = unique_path("chio-certify-public-metadata-scenarios", "");
    let results_dir = unique_path("chio-certify-public-metadata-results", "");
    let output_path = unique_path("chio-certify-public-metadata-artifact", ".json");
    let seed_path = unique_path("chio-certify-public-metadata-seed", ".txt");
    let registry_good = unique_path("chio-certify-public-metadata-registry-good", ".json");
    let registry_stale = unique_path("chio-certify-public-metadata-registry-stale", ".json");
    let registry_mismatch = unique_path("chio-certify-public-metadata-registry-mismatch", ".json");
    let network_path = unique_path("chio-certify-public-metadata-network", ".json");
    let tool_server_id = "demo-server-public-metadata";

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Demo Server Public Metadata"),
    );

    let listen_good = reserve_listen_addr();
    let listen_stale = reserve_listen_addr();
    let listen_mismatch = reserve_listen_addr();
    let token_good = "certify-public-metadata-good";
    let token_stale = "certify-public-metadata-stale";
    let token_mismatch = "certify-public-metadata-mismatch";
    let base_url_good = format!("http://{listen_good}");
    let base_url_stale = format!("http://{listen_stale}");
    let base_url_mismatch = format!("http://{listen_mismatch}");
    let _service_good = spawn_trust_service(
        listen_good,
        token_good,
        Some(&registry_good),
        None,
        Some(&base_url_good),
        None,
    );
    let _service_stale = spawn_trust_service(
        listen_stale,
        token_stale,
        Some(&registry_stale),
        None,
        Some(&base_url_stale),
        Some(0),
    );
    let _service_mismatch = spawn_trust_service(
        listen_mismatch,
        token_mismatch,
        Some(&registry_mismatch),
        None,
        Some("https://mismatch.example"),
        None,
    );
    let client = Client::builder().build().expect("build reqwest client");
    wait_for_trust_service(&client, &base_url_good);
    wait_for_trust_service(&client, &base_url_stale);
    wait_for_trust_service(&client, &base_url_mismatch);

    let publish_good = publish_remote_certification(&base_url_good, token_good, &output_path);
    let publish_stale = publish_remote_certification(&base_url_stale, token_stale, &output_path);
    let publish_mismatch =
        publish_remote_certification(&base_url_mismatch, token_mismatch, &output_path);
    assert_eq!(publish_good["status"], "active");
    assert_eq!(publish_stale["status"], "active");
    assert_eq!(publish_mismatch["status"], "active");

    write_discovery_network(
        &network_path,
        &[
            ("good", &base_url_good, token_good, true),
            ("stale", &base_url_stale, token_stale, true),
            ("mismatch", &base_url_mismatch, token_mismatch, true),
        ],
    );

    let discover = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "certify",
            "registry",
            "discover",
            "--tool-server-id",
            tool_server_id,
            "--certification-discovery-file",
            network_path.to_str().expect("network path"),
        ])
        .output()
        .expect("run marketplace discovery");
    assert!(
        discover.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&discover.stdout),
        String::from_utf8_lossy(&discover.stderr)
    );
    let body: serde_json::Value =
        serde_json::from_slice(&discover.stdout).expect("parse discovery output");
    assert_eq!(body["peerCount"], 3);
    assert_eq!(body["activeCount"], 1);
    assert!(body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .any(|peer| peer["operatorId"] == "good"
            && peer["metadataValid"] == true
            && peer["resolution"]["state"] == "active"));
    assert!(body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .any(|peer| peer["operatorId"] == "stale"
            && peer["metadataValid"] == false
            && peer["error"]
                .as_str()
                .expect("stale error")
                .contains("expired")));
    assert!(body["peers"]
        .as_array()
        .expect("peers array")
        .iter()
        .any(|peer| peer["operatorId"] == "mismatch"
            && peer["metadataValid"] == false
            && peer["error"]
                .as_str()
                .expect("mismatch error")
                .contains("does not match expected")));
}

#[test]
fn certify_marketplace_search_transparency_consume_and_dispute_work() {
    let scenarios_dir = unique_path("chio-certify-marketplace-scenarios", "");
    let results_dir = unique_path("chio-certify-marketplace-results", "");
    let output_path = unique_path("chio-certify-marketplace-artifact", ".json");
    let seed_path = unique_path("chio-certify-marketplace-seed", ".txt");
    let registry_alpha = unique_path("chio-certify-marketplace-registry-alpha", ".json");
    let registry_beta = unique_path("chio-certify-marketplace-registry-beta", ".json");
    let aggregator_registry = unique_path("chio-certify-marketplace-registry-aggregator", ".json");
    let network_path = unique_path("chio-certify-marketplace-network", ".json");
    let tool_server_id = "demo-server-marketplace";

    write_scenario(&scenarios_dir, "initialize");
    write_results(&results_dir, "initialize", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Demo Server Marketplace"),
    );

    let listen_alpha = reserve_listen_addr();
    let listen_beta = reserve_listen_addr();
    let listen_aggregator = reserve_listen_addr();
    let token_alpha = "certify-marketplace-alpha";
    let token_beta = "certify-marketplace-beta";
    let token_aggregator = "certify-marketplace-aggregator";
    let base_url_alpha = format!("http://{listen_alpha}");
    let base_url_beta = format!("http://{listen_beta}");
    let base_url_aggregator = format!("http://{listen_aggregator}");
    let _service_alpha = spawn_trust_service(
        listen_alpha,
        token_alpha,
        Some(&registry_alpha),
        None,
        Some(&base_url_alpha),
        None,
    );
    let _service_beta = spawn_trust_service(
        listen_beta,
        token_beta,
        Some(&registry_beta),
        None,
        Some(&base_url_beta),
        None,
    );
    let client = Client::builder().build().expect("build reqwest client");
    wait_for_trust_service(&client, &base_url_alpha);
    wait_for_trust_service(&client, &base_url_beta);

    write_discovery_network(
        &network_path,
        &[
            ("alpha", &base_url_alpha, token_alpha, true),
            ("beta", &base_url_beta, token_beta, true),
        ],
    );
    let _aggregator = spawn_trust_service(
        listen_aggregator,
        token_aggregator,
        Some(&aggregator_registry),
        Some(&network_path),
        Some(&base_url_aggregator),
        None,
    );
    wait_for_trust_service(&client, &base_url_aggregator);

    let publish_network = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "publish-network",
            "--input",
            output_path.to_str().expect("artifact path"),
        ])
        .output()
        .expect("run network publish");
    assert!(publish_network.status.success());

    let beta_listing = publish_remote_certification(&base_url_beta, token_beta, &output_path);
    let beta_artifact_id = beta_listing["artifactId"]
        .as_str()
        .expect("beta artifact id")
        .to_string();
    revoke_remote_certification(
        &base_url_beta,
        token_beta,
        &beta_artifact_id,
        "beta-revoked",
    );

    let search = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "search",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run marketplace search");
    assert!(search.status.success());
    let search_body: serde_json::Value =
        serde_json::from_slice(&search.stdout).expect("parse search");
    assert_eq!(search_body["count"], 2);
    assert!(search_body["results"]
        .as_array()
        .expect("results array")
        .iter()
        .any(
            |result| result["publisher"]["publisherId"] == base_url_alpha
                && result["entry"]["status"] == "active"
        ));
    assert!(search_body["results"]
        .as_array()
        .expect("results array")
        .iter()
        .any(|result| result["publisher"]["publisherId"] == base_url_beta
            && result["entry"]["status"] == "revoked"));

    let transparency = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "transparency",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run marketplace transparency");
    assert!(transparency.status.success());
    let transparency_body: serde_json::Value =
        serde_json::from_slice(&transparency.stdout).expect("parse transparency");
    assert!(transparency_body["events"]
        .as_array()
        .expect("events array")
        .iter()
        .any(|event| event["kind"] == "published"
            && event["publisher"]["publisherId"] == base_url_alpha));
    assert!(transparency_body["events"]
        .as_array()
        .expect("events array")
        .iter()
        .any(|event| event["kind"] == "revoked"
            && event["publisher"]["publisherId"] == base_url_beta));

    let consume = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "consume",
            "--tool-server-id",
            tool_server_id,
        ])
        .output()
        .expect("run marketplace consume");
    assert!(consume.status.success());
    let consume_body: serde_json::Value =
        serde_json::from_slice(&consume.stdout).expect("parse consume");
    assert_eq!(consume_body["admittedCount"], 1);
    assert_eq!(consume_body["rejectedCount"], 1);
    assert!(consume_body["decisions"]
        .as_array()
        .expect("decisions array")
        .iter()
        .any(|decision| decision["operatorId"] == "alpha" && decision["accepted"] == true));
    assert!(consume_body["decisions"]
        .as_array()
        .expect("decisions array")
        .iter()
        .any(|decision| decision["operatorId"] == "beta"
            && decision["accepted"] == false
            && decision["reasons"]
                .as_array()
                .expect("reasons array")
                .iter()
                .any(|reason| reason.as_str().expect("reason").contains("revoked"))));

    let alpha_listing = publish_remote_certification(&base_url_alpha, token_alpha, &output_path);
    let alpha_artifact_id = alpha_listing["artifactId"]
        .as_str()
        .expect("alpha artifact id")
        .to_string();
    let dispute = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_alpha,
            "--control-token",
            token_alpha,
            "certify",
            "registry",
            "dispute",
            "--artifact-id",
            &alpha_artifact_id,
            "--state",
            "resolved-revoked",
            "--note",
            "operator dispute resolved as revoked",
        ])
        .output()
        .expect("run certification dispute");
    assert!(dispute.status.success());
    let dispute_body: serde_json::Value =
        serde_json::from_slice(&dispute.stdout).expect("parse dispute");
    assert_eq!(dispute_body["status"], "revoked");
    assert_eq!(dispute_body["dispute"]["state"], "resolved-revoked");

    let consume_after_dispute = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "consume",
            "--tool-server-id",
            tool_server_id,
            "--operator-id",
            "alpha",
        ])
        .output()
        .expect("run marketplace consume after dispute");
    assert!(consume_after_dispute.status.success());
    let consume_after_dispute_body: serde_json::Value =
        serde_json::from_slice(&consume_after_dispute.stdout).expect("parse consume after dispute");
    assert_eq!(consume_after_dispute_body["admittedCount"], 0);
    assert!(consume_after_dispute_body["decisions"]
        .as_array()
        .expect("decisions array")
        .iter()
        .any(|decision| decision["operatorId"] == "alpha"
            && decision["accepted"] == false
            && decision["reasons"]
                .as_array()
                .expect("reasons array")
                .iter()
                .any(|reason| reason.as_str().expect("reason").contains("revoked"))));

    let transparency_after_dispute = Command::new(env!("CARGO_BIN_EXE_chio"))
        .current_dir(workspace_root())
        .args([
            "--json",
            "--control-url",
            &base_url_aggregator,
            "--control-token",
            token_aggregator,
            "certify",
            "registry",
            "transparency",
            "--tool-server-id",
            tool_server_id,
            "--operator-id",
            "alpha",
        ])
        .output()
        .expect("run transparency after dispute");
    assert!(
        transparency_after_dispute.status.success(),
        "stdout={}\nstderr={}",
        String::from_utf8_lossy(&transparency_after_dispute.stdout),
        String::from_utf8_lossy(&transparency_after_dispute.stderr)
    );
    let transparency_after_dispute_body: serde_json::Value =
        serde_json::from_slice(&transparency_after_dispute.stdout)
            .expect("parse transparency after dispute");
    assert!(transparency_after_dispute_body["events"]
        .as_array()
        .expect("events array")
        .iter()
        .any(|event| event["kind"] == "dispute-resolved-revoked"));
}

#[test]
fn certify_public_generic_registry_namespace_and_listings_project_current_actor_families() {
    let scenarios_dir = unique_path("chio-generic-registry-scenarios", "");
    let results_dir = unique_path("chio-generic-registry-results", "");
    let output_path = unique_path("chio-generic-registry-artifact", ".json");
    let seed_path = unique_path("chio-generic-registry-seed", ".txt");
    let receipt_db_path = unique_path("chio-generic-registry-receipts", ".sqlite");
    let authority_db_path = unique_path("chio-generic-registry-authority", ".sqlite");
    let registry_path = unique_path("chio-generic-registry-certifications", ".json");
    let tool_server_id = "demo-server-generic-listing";
    let provider_id = "carrier-generic";
    let service_token = "generic-registry-token";

    write_scenario(&scenarios_dir, "generic-listing");
    write_results(&results_dir, "generic-listing", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Generic Listing Server"),
    );
    issue_local_liability_provider(&receipt_db_path, &authority_db_path, provider_id);

    let listen = reserve_listen_addr();
    let base_url = format!("http://{listen}");
    let _service = spawn_trust_service_with_public_registry(
        listen,
        service_token,
        Some(&registry_path),
        &base_url,
        &receipt_db_path,
        &authority_db_path,
    );
    let client = Client::new();
    wait_for_trust_service(&client, &base_url);

    let publish = publish_remote_certification(&base_url, service_token, &output_path);
    assert_eq!(publish["toolServerId"], tool_server_id);

    let namespace_response = client
        .get(format!("{base_url}/v1/public/registry/namespace"))
        .send()
        .expect("fetch public generic namespace");
    assert_eq!(namespace_response.status(), reqwest::StatusCode::OK);
    let namespace_body: serde_json::Value = namespace_response
        .json()
        .expect("parse public generic namespace");
    assert_eq!(
        namespace_body["body"]["schema"],
        "chio.registry.namespace.v1"
    );
    assert_eq!(namespace_body["body"]["ownership"]["namespace"], base_url);
    assert_eq!(namespace_body["body"]["ownership"]["ownerId"], base_url);
    assert_eq!(namespace_body["body"]["boundary"]["visibilityOnly"], true);
    assert_eq!(
        namespace_body["body"]["boundary"]["automaticTrustAdmission"],
        false
    );

    let listing_response = client
        .get(format!("{base_url}/v1/public/registry/listings/search"))
        .send()
        .expect("fetch public generic listings");
    assert_eq!(listing_response.status(), reqwest::StatusCode::OK);
    let listing_body: serde_json::Value = listing_response
        .json()
        .expect("parse public generic listings");
    assert_eq!(listing_body["schema"], "chio.registry.listing-report.v1");
    assert_eq!(listing_body["namespace"]["namespace"], base_url);
    assert_eq!(listing_body["publisher"]["role"], "origin");
    assert_eq!(listing_body["publisher"]["operatorId"], base_url);
    assert_eq!(listing_body["publisher"]["registryUrl"], base_url);
    assert_eq!(
        listing_body["searchPolicy"]["algorithm"],
        "freshness-status-kind-actor-published-at-v1"
    );
    assert_eq!(listing_body["searchPolicy"]["reproducibleOrdering"], true);
    assert_eq!(listing_body["searchPolicy"]["visibilityOnly"], true);
    assert_eq!(
        listing_body["searchPolicy"]["explicitTrustActivationRequired"],
        true
    );
    assert_eq!(listing_body["freshness"]["maxAgeSecs"], 300);
    assert!(
        listing_body["freshness"]["validUntil"]
            .as_u64()
            .expect("freshness validUntil")
            > listing_body["generatedAt"].as_u64().expect("generatedAt")
    );
    assert_eq!(listing_body["summary"]["matchingListings"], 4);
    assert_eq!(listing_body["summary"]["returnedListings"], 4);

    let listings = listing_body["listings"].as_array().expect("listing array");
    assert!(listings.iter().any(|listing| {
        listing["body"]["subject"]["actorKind"] == "tool_server"
            && listing["body"]["subject"]["actorId"] == tool_server_id
            && listing["body"]["compatibility"]["sourceSchema"] == "chio.certify.check.v1"
    }));
    assert!(listings.iter().any(|listing| {
        listing["body"]["subject"]["actorKind"] == "credential_issuer"
            && listing["body"]["compatibility"]["sourceSchema"] == "chio.public-issuer-discovery.v1"
    }));
    assert!(listings.iter().any(|listing| {
        listing["body"]["subject"]["actorKind"] == "credential_verifier"
            && listing["body"]["compatibility"]["sourceSchema"]
                == "chio.public-verifier-discovery.v1"
    }));
    assert!(listings.iter().any(|listing| {
        listing["body"]["subject"]["actorKind"] == "liability_provider"
            && listing["body"]["subject"]["actorId"] == provider_id
            && listing["body"]["compatibility"]["sourceSchema"] == "chio.market.provider.v1"
    }));
    assert!(listings.iter().all(|listing| {
        listing["body"]["namespace"] == base_url
            && listing["body"]["namespaceOwnership"]["ownerId"] == base_url
            && listing["body"]["boundary"]["visibilityOnly"] == true
            && listing["body"]["boundary"]["explicitTrustActivationRequired"] == true
            && listing["body"]["boundary"]["automaticTrustAdmission"] == false
    }));

    let provider_only = client
        .get(format!(
            "{base_url}/v1/public/registry/listings/search?actorKind=liability_provider"
        ))
        .send()
        .expect("fetch provider-only listings");
    assert_eq!(provider_only.status(), reqwest::StatusCode::OK);
    let provider_only_body: serde_json::Value =
        provider_only.json().expect("parse provider-only listings");
    assert_eq!(provider_only_body["summary"]["matchingListings"], 1);
    assert_eq!(provider_only_body["summary"]["returnedListings"], 1);
    assert_eq!(
        provider_only_body["listings"][0]["body"]["subject"]["actorId"],
        provider_id
    );
}

#[test]
fn certify_generic_registry_trust_activation_requires_explicit_local_activation_and_fails_closed() {
    let scenarios_dir = unique_path("chio-generic-activation-scenarios", "");
    let results_dir = unique_path("chio-generic-activation-results", "");
    let output_path = unique_path("chio-generic-activation-artifact", ".json");
    let seed_path = unique_path("chio-generic-activation-seed", ".txt");
    let receipt_db_path = unique_path("chio-generic-activation-receipts", ".sqlite");
    let authority_db_path = unique_path("chio-generic-activation-authority", ".sqlite");
    let registry_path = unique_path("chio-generic-activation-certifications", ".json");
    let tool_server_id = "demo-server-generic-activation";
    let provider_id = "carrier-generic-activation";
    let service_token = "generic-activation-token";

    write_scenario(&scenarios_dir, "generic-activation");
    write_results(&results_dir, "generic-activation", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Generic Activation Server"),
    );
    issue_local_liability_provider(&receipt_db_path, &authority_db_path, provider_id);

    let listen = reserve_listen_addr();
    let base_url = format!("http://{listen}");
    let _service = spawn_trust_service_with_public_registry(
        listen,
        service_token,
        Some(&registry_path),
        &base_url,
        &receipt_db_path,
        &authority_db_path,
    );
    let client = Client::new();
    wait_for_trust_service(&client, &base_url);

    let publish = publish_remote_certification(&base_url, service_token, &output_path);
    assert_eq!(publish["toolServerId"], tool_server_id);

    let listing_response = client
        .get(format!("{base_url}/v1/public/registry/listings/search"))
        .send()
        .expect("fetch public generic listings");
    assert_eq!(listing_response.status(), reqwest::StatusCode::OK);
    let listing_body: serde_json::Value = listing_response
        .json()
        .expect("parse public generic listings");
    let generated_at = listing_body["generatedAt"]
        .as_u64()
        .expect("listing generatedAt");
    let valid_until = listing_body["freshness"]["validUntil"]
        .as_u64()
        .expect("listing validUntil");
    let tool_server_listing = listing_body["listings"]
        .as_array()
        .expect("listing array")
        .iter()
        .find(|listing| {
            listing["body"]["subject"]["actorKind"] == "tool_server"
                && listing["body"]["subject"]["actorId"] == tool_server_id
        })
        .cloned()
        .expect("tool-server listing");

    let fresh_context = serde_json::json!({
        "publisher": listing_body["publisher"].clone(),
        "freshness": {
            "state": "fresh",
            "ageSecs": 0,
            "maxAgeSecs": 300,
            "validUntil": valid_until,
            "generatedAt": generated_at
        }
    });

    let approved_request = serde_json::json!({
        "listing": tool_server_listing,
        "admissionClass": "reviewable",
        "disposition": "approved",
        "eligibility": {
            "allowedActorKinds": ["tool_server"],
            "allowedPublisherRoles": ["origin"],
            "allowedStatuses": ["active"],
            "requireFreshListing": true,
            "policyReference": "policy/open-registry/default"
        },
        "reviewContext": fresh_context,
        "requestedBy": "ops@chio.example",
        "reviewedBy": "reviewer@chio.example",
        "requestedAt": generated_at,
        "reviewedAt": generated_at + 1,
        "expiresAt": generated_at + 120,
        "note": "explicit local activation for tool server listing"
    });

    let approved_activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/issue"))
        .bearer_auth(service_token)
        .json(&approved_request)
        .send()
        .expect("issue approved trust activation");
    assert_eq!(
        approved_activation_response.status(),
        reqwest::StatusCode::OK
    );
    let approved_activation: serde_json::Value = approved_activation_response
        .json()
        .expect("parse approved activation");
    assert_eq!(approved_activation["body"]["admissionClass"], "reviewable");
    assert_eq!(approved_activation["body"]["disposition"], "approved");

    let approved_evaluation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": approved_request["listing"].clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "currentFreshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            },
            "activation": approved_activation.clone(),
            "evaluatedAt": generated_at + 2
        }))
        .send()
        .expect("evaluate approved activation");
    assert_eq!(
        approved_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let approved_evaluation: serde_json::Value = approved_evaluation_response
        .json()
        .expect("parse approved evaluation");
    assert_eq!(approved_evaluation["admitted"], true);
    assert!(
        approved_evaluation["findings"].is_null()
            || approved_evaluation["findings"] == serde_json::json!([])
    );

    let stale_evaluation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": approved_request["listing"].clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "currentFreshness": {
                "state": "stale",
                "ageSecs": 400,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            },
            "activation": approved_activation.clone(),
            "evaluatedAt": generated_at + 400
        }))
        .send()
        .expect("evaluate stale activation");
    assert_eq!(stale_evaluation_response.status(), reqwest::StatusCode::OK);
    let stale_evaluation: serde_json::Value = stale_evaluation_response
        .json()
        .expect("parse stale evaluation");
    assert_eq!(stale_evaluation["admitted"], false);
    assert_eq!(stale_evaluation["findings"][0]["code"], "listing_stale");

    let public_untrusted_request = serde_json::json!({
        "listing": approved_request["listing"].clone(),
        "admissionClass": "public_untrusted",
        "disposition": "approved",
        "eligibility": {
            "allowedActorKinds": ["tool_server"],
            "allowedPublisherRoles": ["origin"],
            "allowedStatuses": ["active"],
            "requireFreshListing": true,
            "policyReference": "policy/open-registry/public-only"
        },
        "reviewContext": {
            "publisher": listing_body["publisher"].clone(),
            "freshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            }
        },
        "requestedBy": "ops@chio.example",
        "reviewedBy": "reviewer@chio.example",
        "requestedAt": generated_at,
        "reviewedAt": generated_at + 1,
        "expiresAt": generated_at + 120,
        "note": "visibility only; do not widen runtime trust"
    });

    let public_untrusted_activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/issue"))
        .bearer_auth(service_token)
        .json(&public_untrusted_request)
        .send()
        .expect("issue public_untrusted activation");
    assert_eq!(
        public_untrusted_activation_response.status(),
        reqwest::StatusCode::OK
    );
    let public_untrusted_activation: serde_json::Value = public_untrusted_activation_response
        .json()
        .expect("parse public_untrusted activation");

    let public_untrusted_evaluation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": public_untrusted_request["listing"].clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "currentFreshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            },
            "activation": public_untrusted_activation,
            "evaluatedAt": generated_at + 2
        }))
        .send()
        .expect("evaluate public_untrusted activation");
    assert_eq!(
        public_untrusted_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let public_untrusted_evaluation: serde_json::Value = public_untrusted_evaluation_response
        .json()
        .expect("parse public_untrusted evaluation");
    assert_eq!(public_untrusted_evaluation["admitted"], false);
    assert_eq!(
        public_untrusted_evaluation["findings"][0]["code"],
        "admission_class_untrusted"
    );
}

#[test]
fn certify_generic_registry_governance_charters_and_cases_enforce_bounded_open_governance() {
    let scenarios_dir = unique_path("chio-generic-governance-scenarios", "");
    let results_dir = unique_path("chio-generic-governance-results", "");
    let output_path = unique_path("chio-generic-governance-artifact", ".json");
    let seed_path = unique_path("chio-generic-governance-seed", ".txt");
    let receipt_db_path = unique_path("chio-generic-governance-receipts", ".sqlite");
    let authority_db_path = unique_path("chio-generic-governance-authority", ".sqlite");
    let registry_path = unique_path("chio-generic-governance-certifications", ".json");
    let tool_server_id = "demo-server-generic-governance";
    let provider_id = "carrier-generic-governance";
    let service_token = "generic-governance-token";

    write_scenario(&scenarios_dir, "generic-governance");
    write_results(&results_dir, "generic-governance", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Generic Governance Server"),
    );
    issue_local_liability_provider(&receipt_db_path, &authority_db_path, provider_id);

    let listen = reserve_listen_addr();
    let base_url = format!("http://{listen}");
    let _service = spawn_trust_service_with_public_registry(
        listen,
        service_token,
        Some(&registry_path),
        &base_url,
        &receipt_db_path,
        &authority_db_path,
    );
    let client = Client::new();
    wait_for_trust_service(&client, &base_url);

    let publish = publish_remote_certification(&base_url, service_token, &output_path);
    assert_eq!(publish["toolServerId"], tool_server_id);

    let listing_response = client
        .get(format!("{base_url}/v1/public/registry/listings/search"))
        .send()
        .expect("fetch public generic listings");
    assert_eq!(listing_response.status(), reqwest::StatusCode::OK);
    let listing_body: serde_json::Value = listing_response
        .json()
        .expect("parse public generic listings");
    let generated_at = listing_body["generatedAt"]
        .as_u64()
        .expect("listing generatedAt");
    let valid_until = listing_body["freshness"]["validUntil"]
        .as_u64()
        .expect("listing validUntil");
    let publisher_operator_id = listing_body["publisher"]["operatorId"]
        .as_str()
        .expect("publisher operatorId");
    let tool_server_listing = listing_body["listings"]
        .as_array()
        .expect("listing array")
        .iter()
        .find(|listing| {
            listing["body"]["subject"]["actorKind"] == "tool_server"
                && listing["body"]["subject"]["actorId"] == tool_server_id
        })
        .cloned()
        .expect("tool-server listing");

    let activation_request = serde_json::json!({
        "listing": tool_server_listing.clone(),
        "admissionClass": "reviewable",
        "disposition": "approved",
        "eligibility": {
            "allowedActorKinds": ["tool_server"],
            "allowedPublisherRoles": ["origin"],
            "allowedStatuses": ["active"],
            "requireFreshListing": true,
            "requiredListingOperatorIds": [publisher_operator_id],
            "policyReference": "policy/open-registry/default"
        },
        "reviewContext": {
            "publisher": listing_body["publisher"].clone(),
            "freshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            }
        },
        "requestedBy": "ops@chio.example",
        "reviewedBy": "reviewer@chio.example",
        "requestedAt": generated_at,
        "reviewedAt": generated_at + 1,
        "expiresAt": generated_at + 300,
        "note": "local trust activation for governance test"
    });
    let activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/issue"))
        .bearer_auth(service_token)
        .json(&activation_request)
        .send()
        .expect("issue activation");
    assert_eq!(activation_response.status(), reqwest::StatusCode::OK);
    let activation: serde_json::Value = activation_response.json().expect("parse activation");

    let charter_request = serde_json::json!({
        "authorityScope": {
            "namespace": tool_server_listing["body"]["namespace"].clone(),
            "allowedListingOperatorIds": [publisher_operator_id],
            "allowedActorKinds": ["tool_server"],
            "policyReference": "policy/governance/default"
        },
        "allowedCaseKinds": ["dispute", "freeze", "sanction", "appeal"],
        "escalationOperatorIds": ["network-audit.chio.example"],
        "issuedBy": "governance@chio.example",
        "issuedAt": generated_at + 2,
        "expiresAt": generated_at + 600,
        "note": "default open-registry governance charter"
    });
    let charter_response = client
        .post(format!("{base_url}/v1/registry/governance/charters/issue"))
        .bearer_auth(service_token)
        .json(&charter_request)
        .send()
        .expect("issue governance charter");
    assert_eq!(charter_response.status(), reqwest::StatusCode::OK);
    let charter: serde_json::Value = charter_response.json().expect("parse charter");

    let freeze_request = serde_json::json!({
        "charter": charter.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "kind": "freeze",
        "state": "enforced",
        "subjectOperatorId": publisher_operator_id,
        "evidenceRefs": [{
            "kind": "trust_activation",
            "referenceId": activation["body"]["activationId"].clone()
        }],
        "issuedBy": "governance@chio.example",
        "openedAt": generated_at + 3,
        "updatedAt": generated_at + 3,
        "expiresAt": generated_at + 120,
        "note": "temporary freeze pending review"
    });
    let freeze_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&freeze_request)
        .send()
        .expect("issue freeze case");
    assert_eq!(freeze_response.status(), reqwest::StatusCode::OK);
    let freeze_case: serde_json::Value = freeze_response.json().expect("parse freeze case");

    let freeze_evaluation_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation.clone(),
            "charter": charter.clone(),
            "case": freeze_case.clone(),
            "evaluatedAt": generated_at + 4
        }))
        .send()
        .expect("evaluate freeze case");
    assert_eq!(freeze_evaluation_response.status(), reqwest::StatusCode::OK);
    let freeze_evaluation: serde_json::Value = freeze_evaluation_response
        .json()
        .expect("parse freeze evaluation");
    assert_eq!(freeze_evaluation["effectiveState"], "frozen");
    assert_eq!(freeze_evaluation["blocksAdmission"], true);
    assert!(
        freeze_evaluation["findings"].is_null()
            || freeze_evaluation["findings"] == serde_json::json!([])
    );

    let missing_activation_evaluation_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "charter": charter.clone(),
            "case": freeze_case.clone(),
            "evaluatedAt": generated_at + 4
        }))
        .send()
        .expect("evaluate freeze without activation");
    assert_eq!(
        missing_activation_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let missing_activation_evaluation: serde_json::Value = missing_activation_evaluation_response
        .json()
        .expect("parse missing activation evaluation");
    assert_eq!(
        missing_activation_evaluation["findings"][0]["code"],
        "missing_activation"
    );

    let expired_charter_request = serde_json::json!({
        "authorityScope": charter_request["authorityScope"].clone(),
        "allowedCaseKinds": ["freeze", "appeal"],
        "escalationOperatorIds": ["network-audit.chio.example"],
        "issuedBy": "governance@chio.example",
        "issuedAt": generated_at + 2,
        "expiresAt": generated_at + 3,
        "note": "short-lived charter"
    });
    let expired_charter_response = client
        .post(format!("{base_url}/v1/registry/governance/charters/issue"))
        .bearer_auth(service_token)
        .json(&expired_charter_request)
        .send()
        .expect("issue expired charter");
    assert_eq!(expired_charter_response.status(), reqwest::StatusCode::OK);
    let expired_charter: serde_json::Value = expired_charter_response
        .json()
        .expect("parse expired charter");

    let expired_case_request = serde_json::json!({
        "charter": expired_charter.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "kind": "freeze",
        "state": "enforced",
        "subjectOperatorId": publisher_operator_id,
        "evidenceRefs": [{
            "kind": "listing",
            "referenceId": tool_server_listing["body"]["listingId"].clone()
        }],
        "issuedBy": "governance@chio.example",
        "openedAt": generated_at + 3,
        "updatedAt": generated_at + 3,
        "expiresAt": generated_at + 120,
        "note": "freeze under expired charter"
    });
    let expired_case_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&expired_case_request)
        .send()
        .expect("issue case under expired charter");
    assert_eq!(expired_case_response.status(), reqwest::StatusCode::OK);
    let expired_case: serde_json::Value = expired_case_response.json().expect("parse expired case");

    let expired_charter_evaluation_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation.clone(),
            "charter": expired_charter,
            "case": expired_case,
            "evaluatedAt": generated_at + 10
        }))
        .send()
        .expect("evaluate expired charter");
    assert_eq!(
        expired_charter_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let expired_charter_evaluation: serde_json::Value = expired_charter_evaluation_response
        .json()
        .expect("parse expired charter evaluation");
    assert_eq!(
        expired_charter_evaluation["findings"][0]["code"],
        "charter_expired"
    );

    let appeal_request = serde_json::json!({
        "charter": charter.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "kind": "appeal",
        "state": "open",
        "subjectOperatorId": publisher_operator_id,
        "evidenceRefs": [{
            "kind": "external",
            "referenceId": "appeal-1"
        }],
        "appealOfCaseId": freeze_case["body"]["caseId"].clone(),
        "issuedBy": "governance@chio.example",
        "openedAt": generated_at + 5,
        "updatedAt": generated_at + 5,
        "expiresAt": generated_at + 120,
        "note": "appeal of enforced freeze"
    });
    let appeal_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&appeal_request)
        .send()
        .expect("issue appeal case");
    assert_eq!(appeal_response.status(), reqwest::StatusCode::OK);
    let appeal_case: serde_json::Value = appeal_response.json().expect("parse appeal case");

    let appeal_evaluation_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing,
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation,
            "charter": charter,
            "case": appeal_case,
            "priorCase": freeze_case,
            "evaluatedAt": generated_at + 6
        }))
        .send()
        .expect("evaluate appeal case");
    assert_eq!(appeal_evaluation_response.status(), reqwest::StatusCode::OK);
    let appeal_evaluation: serde_json::Value = appeal_evaluation_response
        .json()
        .expect("parse appeal evaluation");
    assert_eq!(appeal_evaluation["effectiveState"], "appealed");
    assert_eq!(appeal_evaluation["blocksAdmission"], false);
    assert!(
        appeal_evaluation["findings"].is_null()
            || appeal_evaluation["findings"] == serde_json::json!([])
    );
}

#[test]
fn certify_open_market_fee_schedules_and_slashing_require_explicit_bounded_authority() {
    let scenarios_dir = unique_path("chio-open-market-scenarios", "");
    let results_dir = unique_path("chio-open-market-results", "");
    let output_path = unique_path("chio-open-market-artifact", ".json");
    let seed_path = unique_path("chio-open-market-seed", ".txt");
    let receipt_db_path = unique_path("chio-open-market-receipts", ".sqlite");
    let authority_db_path = unique_path("chio-open-market-authority", ".sqlite");
    let registry_path = unique_path("chio-open-market-certifications", ".json");
    let tool_server_id = "demo-server-open-market";
    let provider_id = "carrier-open-market";
    let service_token = "open-market-token";

    write_scenario(&scenarios_dir, "open-market");
    write_results(&results_dir, "open-market", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Open Market Server"),
    );
    issue_local_liability_provider(&receipt_db_path, &authority_db_path, provider_id);

    let listen = reserve_listen_addr();
    let base_url = format!("http://{listen}");
    let _service = spawn_trust_service_with_public_registry(
        listen,
        service_token,
        Some(&registry_path),
        &base_url,
        &receipt_db_path,
        &authority_db_path,
    );
    let client = Client::new();
    wait_for_trust_service(&client, &base_url);

    let publish = publish_remote_certification(&base_url, service_token, &output_path);
    assert_eq!(publish["toolServerId"], tool_server_id);

    let listing_response = client
        .get(format!("{base_url}/v1/public/registry/listings/search"))
        .send()
        .expect("fetch public generic listings");
    assert_eq!(listing_response.status(), reqwest::StatusCode::OK);
    let listing_body: serde_json::Value = listing_response
        .json()
        .expect("parse public generic listings");
    let generated_at = listing_body["generatedAt"]
        .as_u64()
        .expect("listing generatedAt");
    let valid_until = listing_body["freshness"]["validUntil"]
        .as_u64()
        .expect("listing validUntil");
    let publisher_operator_id = listing_body["publisher"]["operatorId"]
        .as_str()
        .expect("publisher operatorId");
    let tool_server_listing = listing_body["listings"]
        .as_array()
        .expect("listing array")
        .iter()
        .find(|listing| {
            listing["body"]["subject"]["actorKind"] == "tool_server"
                && listing["body"]["subject"]["actorId"] == tool_server_id
        })
        .cloned()
        .expect("tool-server listing");

    let activation_request = serde_json::json!({
        "listing": tool_server_listing.clone(),
        "admissionClass": "bond_backed",
        "disposition": "approved",
        "eligibility": {
            "allowedActorKinds": ["tool_server"],
            "allowedPublisherRoles": ["origin"],
            "allowedStatuses": ["active"],
            "requireFreshListing": true,
            "requireBondBacking": true,
            "requiredListingOperatorIds": [publisher_operator_id],
            "policyReference": "policy/open-market/default"
        },
        "reviewContext": {
            "publisher": listing_body["publisher"].clone(),
            "freshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            }
        },
        "requestedBy": "ops@chio.example",
        "reviewedBy": "reviewer@chio.example",
        "requestedAt": generated_at,
        "reviewedAt": generated_at + 1,
        "expiresAt": generated_at + 300,
        "note": "bond-backed activation for open-market economics"
    });
    let activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/issue"))
        .bearer_auth(service_token)
        .json(&activation_request)
        .send()
        .expect("issue trust activation");
    assert_eq!(activation_response.status(), reqwest::StatusCode::OK);
    let activation: serde_json::Value = activation_response.json().expect("parse activation");

    let charter_request = serde_json::json!({
        "authorityScope": {
            "namespace": tool_server_listing["body"]["namespace"].clone(),
            "allowedListingOperatorIds": [publisher_operator_id],
            "allowedActorKinds": ["tool_server"],
            "policyReference": "policy/open-market/governance"
        },
        "allowedCaseKinds": ["sanction", "appeal"],
        "issuedBy": "governance@chio.example",
        "issuedAt": generated_at + 2,
        "expiresAt": generated_at + 600,
        "note": "open-market governance charter"
    });
    let charter_response = client
        .post(format!("{base_url}/v1/registry/governance/charters/issue"))
        .bearer_auth(service_token)
        .json(&charter_request)
        .send()
        .expect("issue governance charter");
    assert_eq!(charter_response.status(), reqwest::StatusCode::OK);
    let charter: serde_json::Value = charter_response.json().expect("parse charter");

    let sanction_request = serde_json::json!({
        "charter": charter.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "kind": "sanction",
        "state": "enforced",
        "subjectOperatorId": publisher_operator_id,
        "evidenceRefs": [{
            "kind": "trust_activation",
            "referenceId": activation["body"]["activationId"].clone()
        }],
        "issuedBy": "governance@chio.example",
        "openedAt": generated_at + 3,
        "updatedAt": generated_at + 3,
        "expiresAt": generated_at + 500,
        "note": "sanction for unverifiable listing behavior"
    });
    let sanction_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&sanction_request)
        .send()
        .expect("issue sanction case");
    assert_eq!(sanction_response.status(), reqwest::StatusCode::OK);
    let sanction_case: serde_json::Value = sanction_response.json().expect("parse sanction case");

    let fee_schedule_request = serde_json::json!({
        "scope": {
            "namespace": tool_server_listing["body"]["namespace"].clone(),
            "allowedListingOperatorIds": [publisher_operator_id],
            "allowedActorKinds": ["tool_server"],
            "allowedAdmissionClasses": ["bond_backed"],
            "policyReference": "policy/open-market/default"
        },
        "publicationFee": {
            "units": 100,
            "currency": "USD"
        },
        "disputeFee": {
            "units": 2500,
            "currency": "USD"
        },
        "marketParticipationFee": {
            "units": 500,
            "currency": "USD"
        },
        "bondRequirements": [{
            "bondClass": "listing",
            "requiredAmount": {
                "units": 5000,
                "currency": "USD"
            },
            "collateralReferenceKind": "credit_bond",
            "slashable": true
        }],
        "issuedBy": "market@chio.example",
        "issuedAt": generated_at + 4,
        "expiresAt": generated_at + 700,
        "note": "bounded open-market fee schedule"
    });
    let fee_schedule_response = client
        .post(format!("{base_url}/v1/registry/market/fees/issue"))
        .bearer_auth(service_token)
        .json(&fee_schedule_request)
        .send()
        .expect("issue fee schedule");
    assert_eq!(fee_schedule_response.status(), reqwest::StatusCode::OK);
    let fee_schedule: serde_json::Value = fee_schedule_response.json().expect("parse fee schedule");

    let penalty_request = serde_json::json!({
        "feeSchedule": fee_schedule.clone(),
        "charter": charter.clone(),
        "case": sanction_case.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "abuseClass": "unverifiable_listing_behavior",
        "bondClass": "listing",
        "action": "slash_bond",
        "state": "enforced",
        "penaltyAmount": {
            "units": 2500,
            "currency": "USD"
        },
        "evidenceRefs": [{
            "kind": "governance_case",
            "referenceId": sanction_case["body"]["caseId"].clone()
        }],
        "subjectOperatorId": publisher_operator_id,
        "issuedBy": "market@chio.example",
        "openedAt": generated_at + 5,
        "updatedAt": generated_at + 5,
        "expiresAt": generated_at + 700,
        "note": "slash listing bond for sustained unverifiable behavior"
    });
    let penalty_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/issue"))
        .bearer_auth(service_token)
        .json(&penalty_request)
        .send()
        .expect("issue market penalty");
    assert_eq!(penalty_response.status(), reqwest::StatusCode::OK);
    let penalty: serde_json::Value = penalty_response.json().expect("parse market penalty");

    let evaluation_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": fee_schedule.clone(),
            "listing": tool_server_listing.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation.clone(),
            "charter": charter.clone(),
            "case": sanction_case.clone(),
            "penalty": penalty.clone(),
            "evaluatedAt": generated_at + 6
        }))
        .send()
        .expect("evaluate market penalty");
    assert_eq!(evaluation_response.status(), reqwest::StatusCode::OK);
    let evaluation: serde_json::Value =
        evaluation_response.json().expect("parse market evaluation");
    assert_eq!(evaluation["effectiveState"], "bond_slashed");
    assert_eq!(evaluation["blocksAdmission"], true);
    assert_eq!(evaluation["publicationFee"]["units"], 100);
    assert_eq!(evaluation["bondRequirement"]["bondClass"], "listing");
    assert!(evaluation["findings"].is_null() || evaluation["findings"] == serde_json::json!([]));

    let expired_fee_schedule_request = serde_json::json!({
        "scope": fee_schedule_request["scope"].clone(),
        "publicationFee": fee_schedule_request["publicationFee"].clone(),
        "disputeFee": fee_schedule_request["disputeFee"].clone(),
        "marketParticipationFee": fee_schedule_request["marketParticipationFee"].clone(),
        "bondRequirements": fee_schedule_request["bondRequirements"].clone(),
        "issuedBy": "market@chio.example",
        "issuedAt": generated_at + 4,
        "expiresAt": generated_at + 5,
        "note": "already expired schedule for fail-closed check"
    });
    let expired_fee_schedule_response = client
        .post(format!("{base_url}/v1/registry/market/fees/issue"))
        .bearer_auth(service_token)
        .json(&expired_fee_schedule_request)
        .send()
        .expect("issue expired fee schedule");
    assert_eq!(
        expired_fee_schedule_response.status(),
        reqwest::StatusCode::OK
    );
    let expired_fee_schedule: serde_json::Value = expired_fee_schedule_response
        .json()
        .expect("parse expired fee schedule");

    let expired_evaluation_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": expired_fee_schedule,
            "listing": tool_server_listing.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation.clone(),
            "charter": charter.clone(),
            "case": sanction_case.clone(),
            "penalty": penalty.clone(),
            "evaluatedAt": generated_at + 6
        }))
        .send()
        .expect("evaluate expired schedule");
    assert_eq!(
        expired_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let expired_evaluation: serde_json::Value = expired_evaluation_response
        .json()
        .expect("parse expired evaluation");
    assert_eq!(
        expired_evaluation["findings"][0]["code"],
        "fee_schedule_expired"
    );

    let dispute_only_fee_schedule_request = serde_json::json!({
        "scope": fee_schedule_request["scope"].clone(),
        "publicationFee": fee_schedule_request["publicationFee"].clone(),
        "disputeFee": fee_schedule_request["disputeFee"].clone(),
        "marketParticipationFee": fee_schedule_request["marketParticipationFee"].clone(),
        "bondRequirements": [{
            "bondClass": "dispute",
            "requiredAmount": {
                "units": 5000,
                "currency": "USD"
            },
            "collateralReferenceKind": "credit_bond",
            "slashable": true
        }],
        "issuedBy": "market@chio.example",
        "issuedAt": generated_at + 4,
        "expiresAt": generated_at + 700,
        "note": "dispute-only bond requirement"
    });
    let dispute_only_fee_schedule_response = client
        .post(format!("{base_url}/v1/registry/market/fees/issue"))
        .bearer_auth(service_token)
        .json(&dispute_only_fee_schedule_request)
        .send()
        .expect("issue dispute-only fee schedule");
    assert_eq!(
        dispute_only_fee_schedule_response.status(),
        reqwest::StatusCode::OK
    );
    let dispute_only_fee_schedule: serde_json::Value = dispute_only_fee_schedule_response
        .json()
        .expect("parse dispute-only fee schedule");

    let dispute_penalty_request = serde_json::json!({
        "feeSchedule": dispute_only_fee_schedule.clone(),
        "charter": charter.clone(),
        "case": sanction_case.clone(),
        "listing": tool_server_listing.clone(),
        "activation": activation.clone(),
        "abuseClass": "unverifiable_listing_behavior",
        "bondClass": "listing",
        "action": "hold_bond",
        "state": "enforced",
        "penaltyAmount": {
            "units": 1000,
            "currency": "USD"
        },
        "evidenceRefs": [{
            "kind": "governance_case",
            "referenceId": sanction_case["body"]["caseId"].clone()
        }],
        "subjectOperatorId": publisher_operator_id,
        "issuedBy": "market@chio.example",
        "openedAt": generated_at + 5,
        "updatedAt": generated_at + 5,
        "expiresAt": generated_at + 700,
        "note": "hold listing bond without matching bond requirement"
    });
    let dispute_penalty_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/issue"))
        .bearer_auth(service_token)
        .json(&dispute_penalty_request)
        .send()
        .expect("issue mismatch penalty");
    assert_eq!(dispute_penalty_response.status(), reqwest::StatusCode::OK);
    let dispute_penalty: serde_json::Value = dispute_penalty_response
        .json()
        .expect("parse mismatch penalty");

    let mismatch_evaluation_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": dispute_only_fee_schedule,
            "listing": tool_server_listing,
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": activation,
            "charter": charter,
            "case": sanction_case,
            "penalty": dispute_penalty,
            "evaluatedAt": generated_at + 6
        }))
        .send()
        .expect("evaluate mismatch penalty");
    assert_eq!(
        mismatch_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let mismatch_evaluation: serde_json::Value = mismatch_evaluation_response
        .json()
        .expect("parse mismatch evaluation");
    assert_eq!(
        mismatch_evaluation["findings"][0]["code"],
        "bond_requirement_missing"
    );
}

#[test]
fn certify_adversarial_multi_operator_open_market_preserves_visibility_without_trust() {
    let scenarios_dir = unique_path("chio-adversarial-open-market-scenarios", "");
    let results_dir = unique_path("chio-adversarial-open-market-results", "");
    let output_path = unique_path("chio-adversarial-open-market-artifact", ".json");
    let seed_path = unique_path("chio-adversarial-open-market-seed", ".txt");
    let receipt_db_path = unique_path("chio-adversarial-open-market-receipts", ".sqlite");
    let authority_db_path = unique_path("chio-adversarial-open-market-authority", ".sqlite");
    let registry_path = unique_path("chio-adversarial-open-market-certifications", ".json");
    let tool_server_id = "demo-server-adversarial-open-market";
    let provider_id = "carrier-adversarial-open-market";
    let service_token = "adversarial-open-market-token";

    write_scenario(&scenarios_dir, "adversarial-open-market");
    write_results(&results_dir, "adversarial-open-market", "pass");
    run_certify_check(
        &scenarios_dir,
        &results_dir,
        &output_path,
        &seed_path,
        tool_server_id,
        Some("Adversarial Open Market Server"),
    );
    issue_local_liability_provider(&receipt_db_path, &authority_db_path, provider_id);

    let listen = reserve_listen_addr();
    let base_url = format!("http://{listen}");
    let _service = spawn_trust_service_with_public_registry(
        listen,
        service_token,
        Some(&registry_path),
        &base_url,
        &receipt_db_path,
        &authority_db_path,
    );
    let client = Client::new();
    wait_for_trust_service(&client, &base_url);

    let publish = publish_remote_certification(&base_url, service_token, &output_path);
    assert_eq!(publish["toolServerId"], tool_server_id);

    let listing_response = client
        .get(format!("{base_url}/v1/public/registry/listings/search"))
        .send()
        .expect("fetch public generic listings");
    assert_eq!(listing_response.status(), reqwest::StatusCode::OK);
    let listing_body: serde_json::Value = listing_response
        .json()
        .expect("parse public generic listings");
    let origin_report: GenericListingReport =
        serde_json::from_value(listing_body.clone()).expect("parse origin listing report");
    let generated_at = origin_report.generated_at;
    let valid_until = origin_report.freshness.valid_until;
    let publisher_operator_id = origin_report.publisher.operator_id.clone();
    let tool_server_listing_value = listing_body["listings"]
        .as_array()
        .expect("listing array")
        .iter()
        .find(|listing| {
            listing["body"]["subject"]["actorKind"] == "tool_server"
                && listing["body"]["subject"]["actorId"] == tool_server_id
        })
        .cloned()
        .expect("tool-server listing");
    let mut tampered_mirror = origin_report.clone();
    tampered_mirror.publisher.role = GenericRegistryPublisherRole::Mirror;
    tampered_mirror.publisher.operator_id = "mirror-a".to_string();
    tampered_mirror.publisher.operator_name = Some("Mirror A".to_string());
    tampered_mirror.publisher.registry_url = "https://mirror-a.chio.example".to_string();
    tampered_mirror.publisher.upstream_registry_urls = vec![base_url.clone()];
    let tampered_listing = tampered_mirror
        .listings
        .iter_mut()
        .find(|listing| {
            listing.body.subject.actor_kind == GenericListingActorKind::ToolServer
                && listing.body.subject.actor_id == tool_server_id
        })
        .expect("tampered mirror listing");
    tampered_listing.body.status = GenericListingStatus::Revoked;

    let mut divergent_indexer = origin_report.clone();
    divergent_indexer.publisher.role = GenericRegistryPublisherRole::Indexer;
    divergent_indexer.publisher.operator_id = "indexer-a".to_string();
    divergent_indexer.publisher.operator_name = Some("Indexer A".to_string());
    divergent_indexer.publisher.registry_url = "https://indexer-a.chio.example".to_string();
    divergent_indexer.publisher.upstream_registry_urls = vec![base_url.clone()];
    let divergent_listing = divergent_indexer
        .listings
        .iter_mut()
        .find(|listing| {
            listing.body.subject.actor_kind == GenericListingActorKind::ToolServer
                && listing.body.subject.actor_id == tool_server_id
        })
        .expect("divergent indexer listing");
    let mut divergent_body = divergent_listing.body.clone();
    divergent_body.compatibility.source_artifact_sha256 = "sha256-divergent-source".to_string();
    *divergent_listing = SignedGenericListing::sign(divergent_body, &Keypair::generate())
        .expect("sign divergent indexer listing");

    let aggregated = aggregate_generic_listing_reports(
        &[origin_report, tampered_mirror, divergent_indexer],
        &GenericListingQuery {
            actor_kind: Some(GenericListingActorKind::ToolServer),
            actor_id: Some(tool_server_id.to_string()),
            ..GenericListingQuery::default()
        },
        generated_at + 10,
    );
    assert_eq!(aggregated.peer_count, 3);
    assert_eq!(aggregated.reachable_count, 2);
    assert_eq!(aggregated.stale_peer_count, 0);
    assert_eq!(aggregated.result_count, 0);
    assert_eq!(aggregated.divergence_count, 1);
    assert!(aggregated.errors.iter().any(
        |error| error.operator_id == "mirror-a" && error.error.contains("signature is invalid")
    ));
    assert!(aggregated.divergences.iter().any(|divergence| {
        divergence.actor_id == tool_server_id
            && divergence
                .publisher_operator_ids
                .contains(&publisher_operator_id)
            && divergence
                .publisher_operator_ids
                .contains(&"indexer-a".to_string())
    }));

    let activation_request = serde_json::json!({
        "listing": tool_server_listing_value.clone(),
        "admissionClass": "bond_backed",
        "disposition": "approved",
        "eligibility": {
            "allowedActorKinds": ["tool_server"],
            "allowedPublisherRoles": ["origin"],
            "allowedStatuses": ["active"],
            "requireFreshListing": true,
            "requireBondBacking": true,
            "requiredListingOperatorIds": [publisher_operator_id],
            "policyReference": "policy/adversarial-open-market/default"
        },
        "reviewContext": {
            "publisher": listing_body["publisher"].clone(),
            "freshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            }
        },
        "requestedBy": "ops@chio.example",
        "reviewedBy": "reviewer@chio.example",
        "requestedAt": generated_at,
        "reviewedAt": generated_at + 1,
        "expiresAt": generated_at + 300,
        "note": "bond-backed local activation for adversarial qualification"
    });
    let activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/issue"))
        .bearer_auth(service_token)
        .json(&activation_request)
        .send()
        .expect("issue activation");
    assert_eq!(activation_response.status(), reqwest::StatusCode::OK);
    let activation: SignedGenericTrustActivation =
        activation_response.json().expect("parse activation");

    let admitted_activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing_value.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "currentFreshness": {
                "state": "fresh",
                "ageSecs": 0,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            },
            "activation": serde_json::to_value(&activation).expect("serialize activation"),
            "evaluatedAt": generated_at + 2
        }))
        .send()
        .expect("evaluate admitted activation");
    assert_eq!(
        admitted_activation_response.status(),
        reqwest::StatusCode::OK
    );
    let admitted_activation: serde_json::Value = admitted_activation_response
        .json()
        .expect("parse admitted activation evaluation");
    assert_eq!(admitted_activation["admitted"], false);
    assert_eq!(
        admitted_activation["findings"][0]["code"],
        "bond_backing_required"
    );

    let divergent_activation_response = client
        .post(format!("{base_url}/v1/registry/trust-activations/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing_value.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "currentFreshness": {
                "state": "divergent",
                "ageSecs": 5,
                "maxAgeSecs": 300,
                "validUntil": valid_until,
                "generatedAt": generated_at
            },
            "activation": serde_json::to_value(&activation).expect("serialize activation"),
            "evaluatedAt": generated_at + 2
        }))
        .send()
        .expect("evaluate divergent activation");
    assert_eq!(
        divergent_activation_response.status(),
        reqwest::StatusCode::OK
    );
    let divergent_activation: serde_json::Value = divergent_activation_response
        .json()
        .expect("parse divergent activation evaluation");
    assert_eq!(divergent_activation["admitted"], false);
    assert_eq!(
        divergent_activation["findings"][0]["code"],
        "listing_divergent"
    );

    let charter_request = serde_json::json!({
        "authorityScope": {
            "namespace": tool_server_listing_value["body"]["namespace"].clone(),
            "allowedListingOperatorIds": [publisher_operator_id.clone()],
            "allowedActorKinds": ["tool_server"],
            "policyReference": "policy/adversarial-open-market/governance"
        },
        "allowedCaseKinds": ["sanction", "appeal"],
        "issuedBy": "governance@chio.example",
        "issuedAt": generated_at + 2,
        "expiresAt": generated_at + 600,
        "note": "local open-market governance charter"
    });
    let charter_response = client
        .post(format!("{base_url}/v1/registry/governance/charters/issue"))
        .bearer_auth(service_token)
        .json(&charter_request)
        .send()
        .expect("issue governance charter");
    assert_eq!(charter_response.status(), reqwest::StatusCode::OK);
    let charter: SignedGenericGovernanceCharter =
        charter_response.json().expect("parse governance charter");

    let mut forged_activation_body = activation.body.clone();
    forged_activation_body.local_operator_id = "https://remote-governor.chio.example".to_string();
    forged_activation_body.local_operator_name = Some("Remote Governor".to_string());
    let forged_activation =
        SignedGenericTrustActivation::sign(forged_activation_body, &Keypair::generate())
            .expect("sign forged activation");

    let forged_case_issue_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "listing": tool_server_listing_value.clone(),
            "activation": serde_json::to_value(&forged_activation).expect("serialize forged activation"),
            "kind": "sanction",
            "state": "enforced",
            "subjectOperatorId": publisher_operator_id.clone(),
            "evidenceRefs": [{
                "kind": "trust_activation",
                "referenceId": activation.body.activation_id.clone()
            }],
            "issuedBy": "governance@chio.example",
            "openedAt": generated_at + 3,
            "updatedAt": generated_at + 3,
            "expiresAt": generated_at + 500,
            "note": "forged remote activation should fail"
        }))
        .send()
        .expect("issue forged governance case");
    assert_eq!(
        forged_case_issue_response.status(),
        reqwest::StatusCode::BAD_REQUEST
    );
    assert!(forged_case_issue_response
        .text()
        .expect("read forged governance case error")
        .contains("issued by the governing operator"));

    let sanction_case_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/issue"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "listing": tool_server_listing_value.clone(),
            "activation": serde_json::to_value(&activation).expect("serialize activation"),
            "kind": "sanction",
            "state": "enforced",
            "subjectOperatorId": publisher_operator_id.clone(),
            "evidenceRefs": [{
                "kind": "trust_activation",
                "referenceId": activation.body.activation_id.clone()
            }],
            "issuedBy": "governance@chio.example",
            "openedAt": generated_at + 3,
            "updatedAt": generated_at + 3,
            "expiresAt": generated_at + 500,
            "note": "local sanction case"
        }))
        .send()
        .expect("issue local sanction case");
    assert_eq!(sanction_case_response.status(), reqwest::StatusCode::OK);
    let sanction_case: SignedGenericGovernanceCase =
        sanction_case_response.json().expect("parse sanction case");

    let forged_governance_evaluation_response = client
        .post(format!("{base_url}/v1/registry/governance/cases/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "listing": tool_server_listing_value.clone(),
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": serde_json::to_value(&forged_activation).expect("serialize forged activation"),
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "case": serde_json::to_value(&sanction_case).expect("serialize sanction case"),
            "evaluatedAt": generated_at + 4
        }))
        .send()
        .expect("evaluate sanction with forged activation");
    assert_eq!(
        forged_governance_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let forged_governance_evaluation: serde_json::Value = forged_governance_evaluation_response
        .json()
        .expect("parse forged governance evaluation");
    assert_eq!(
        forged_governance_evaluation["findings"][0]["code"],
        "activation_mismatch"
    );

    let fee_schedule_request = serde_json::json!({
        "scope": {
            "namespace": tool_server_listing_value["body"]["namespace"].clone(),
            "allowedListingOperatorIds": [publisher_operator_id.clone()],
            "allowedActorKinds": ["tool_server"],
            "allowedAdmissionClasses": ["bond_backed"],
            "policyReference": "policy/adversarial-open-market/default"
        },
        "publicationFee": {
            "units": 100,
            "currency": "USD"
        },
        "disputeFee": {
            "units": 2500,
            "currency": "USD"
        },
        "marketParticipationFee": {
            "units": 500,
            "currency": "USD"
        },
        "bondRequirements": [{
            "bondClass": "listing",
            "requiredAmount": {
                "units": 5000,
                "currency": "USD"
            },
            "collateralReferenceKind": "credit_bond",
            "slashable": true
        }],
        "issuedBy": "market@chio.example",
        "issuedAt": generated_at + 4,
        "expiresAt": generated_at + 700,
        "note": "adversarial qualification fee schedule"
    });
    let fee_schedule_response = client
        .post(format!("{base_url}/v1/registry/market/fees/issue"))
        .bearer_auth(service_token)
        .json(&fee_schedule_request)
        .send()
        .expect("issue fee schedule");
    assert_eq!(fee_schedule_response.status(), reqwest::StatusCode::OK);
    let fee_schedule: SignedOpenMarketFeeSchedule =
        fee_schedule_response.json().expect("parse fee schedule");

    let forged_penalty_issue_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/issue"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": serde_json::to_value(&fee_schedule).expect("serialize fee schedule"),
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "case": serde_json::to_value(&sanction_case).expect("serialize sanction case"),
            "listing": tool_server_listing_value.clone(),
            "activation": serde_json::to_value(&forged_activation).expect("serialize forged activation"),
            "abuseClass": "unverifiable_listing_behavior",
            "bondClass": "listing",
            "action": "slash_bond",
            "state": "enforced",
            "penaltyAmount": {
                "units": 2500,
                "currency": "USD"
            },
            "evidenceRefs": [{
                "kind": "governance_case",
                "referenceId": sanction_case.body.case_id.clone()
            }],
            "subjectOperatorId": publisher_operator_id.clone(),
            "issuedBy": "market@chio.example",
            "openedAt": generated_at + 5,
            "updatedAt": generated_at + 5,
            "expiresAt": generated_at + 700,
            "note": "forged remote activation should fail"
        }))
        .send()
        .expect("issue forged market penalty");
    assert_eq!(
        forged_penalty_issue_response.status(),
        reqwest::StatusCode::BAD_REQUEST
    );
    assert!(forged_penalty_issue_response
        .text()
        .expect("read forged market penalty error")
        .contains("issued by the governing operator"));

    let penalty_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/issue"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": serde_json::to_value(&fee_schedule).expect("serialize fee schedule"),
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "case": serde_json::to_value(&sanction_case).expect("serialize sanction case"),
            "listing": tool_server_listing_value.clone(),
            "activation": serde_json::to_value(&activation).expect("serialize activation"),
            "abuseClass": "unverifiable_listing_behavior",
            "bondClass": "listing",
            "action": "slash_bond",
            "state": "enforced",
            "penaltyAmount": {
                "units": 2500,
                "currency": "USD"
            },
            "evidenceRefs": [{
                "kind": "governance_case",
                "referenceId": sanction_case.body.case_id.clone()
            }],
            "subjectOperatorId": publisher_operator_id.clone(),
            "issuedBy": "market@chio.example",
            "openedAt": generated_at + 5,
            "updatedAt": generated_at + 5,
            "expiresAt": generated_at + 700,
            "note": "local market penalty"
        }))
        .send()
        .expect("issue local market penalty");
    assert_eq!(penalty_response.status(), reqwest::StatusCode::OK);
    let penalty: SignedOpenMarketPenalty = penalty_response.json().expect("parse penalty");

    let forged_penalty_evaluation_response = client
        .post(format!("{base_url}/v1/registry/market/penalties/evaluate"))
        .bearer_auth(service_token)
        .json(&serde_json::json!({
            "feeSchedule": serde_json::to_value(&fee_schedule).expect("serialize fee schedule"),
            "listing": tool_server_listing_value,
            "currentPublisher": listing_body["publisher"].clone(),
            "activation": serde_json::to_value(&forged_activation).expect("serialize forged activation"),
            "charter": serde_json::to_value(&charter).expect("serialize charter"),
            "case": serde_json::to_value(&sanction_case).expect("serialize sanction case"),
            "penalty": serde_json::to_value(&penalty).expect("serialize penalty"),
            "evaluatedAt": generated_at + 6
        }))
        .send()
        .expect("evaluate market penalty with forged activation");
    assert_eq!(
        forged_penalty_evaluation_response.status(),
        reqwest::StatusCode::OK
    );
    let forged_penalty_evaluation: serde_json::Value = forged_penalty_evaluation_response
        .json()
        .expect("parse forged penalty evaluation");
    assert_eq!(
        forged_penalty_evaluation["findings"][0]["code"],
        "activation_mismatch"
    );

    let subject_key = Keypair::generate().public_key().to_hex();
    let local_summary = SignedPortableReputationSummary::sign(
        build_portable_reputation_summary_artifact(
            &base_url,
            &PortableReputationSummaryIssueRequest {
                subject_key: subject_key.clone(),
                since: Some(generated_at.saturating_sub(600)),
                until: Some(generated_at),
                issued_at: Some(generated_at),
                expires_at: Some(generated_at + 600),
                note: Some("local reputation summary".to_string()),
            },
            &sample_portable_reputation_scorecard(&subject_key, 0.82),
            PortableReputationSummaryArtifactContext {
                issuer_operator_name: Some("Origin Operator".to_string()),
                effective_score: 0.82,
                probationary: false,
                imported_signal_count: Some(0),
                accepted_imported_signal_count: Some(0),
                issued_at: generated_at,
            },
        )
        .expect("build local reputation summary"),
        &Keypair::generate(),
    )
    .expect("sign local reputation summary");
    let remote_negative_event = SignedPortableNegativeEvent::sign(
        build_portable_negative_event_artifact(
            "https://malicious-issuer.chio.example",
            Some("Malicious Issuer".to_string()),
            &PortableNegativeEventIssueRequest {
                subject_key: subject_key.clone(),
                kind: PortableNegativeEventKind::FraudSignal,
                severity: 0.9,
                observed_at: generated_at.saturating_sub(30),
                published_at: Some(generated_at.saturating_sub(10)),
                expires_at: Some(generated_at + 600),
                evidence_refs: vec![PortableNegativeEventEvidenceReference {
                    kind: PortableNegativeEventEvidenceKind::External,
                    reference_id: "fraud-case-1".to_string(),
                    uri: Some("https://malicious-issuer.chio.example/cases/1".to_string()),
                    sha256: None,
                }],
                note: Some("malicious remote negative signal".to_string()),
            },
            generated_at,
        )
        .expect("build remote negative event"),
        &Keypair::generate(),
    )
    .expect("sign remote negative event");
    let reputation_evaluation = evaluate_portable_reputation(
        &PortableReputationEvaluationRequest {
            subject_key: subject_key.clone(),
            summaries: vec![local_summary],
            negative_events: vec![remote_negative_event],
            weighting_profile: PortableReputationWeightingProfile {
                profile_id: "local-only".to_string(),
                allowed_issuer_operator_ids: vec![base_url.clone()],
                issuer_weights: BTreeMap::new(),
                max_summary_age_secs: 3600,
                max_event_age_secs: 3600,
                reject_probationary: false,
                negative_event_weight: 0.5,
                blocking_event_kinds: vec![PortableNegativeEventKind::FraudSignal],
            },
            evaluated_at: Some(generated_at + 10),
        },
        generated_at + 10,
    )
    .expect("evaluate portable reputation");
    assert_eq!(reputation_evaluation.accepted_summary_count, 1);
    assert_eq!(reputation_evaluation.accepted_negative_event_count, 0);
    assert_eq!(reputation_evaluation.rejected_negative_event_count, 1);
    assert_eq!(
        reputation_evaluation.findings[0].code,
        PortableReputationFindingCode::IssuerNotAllowed
    );
    assert!(reputation_evaluation.effective_score.is_some());
}
