diff --git a/crates/registry-evidence/src/cli.rs b/crates/registry-evidence/src/cli.rs index 4ef811b4f..bcf86306f 100644 --- a/crates/registry-evidence/src/cli.rs +++ b/crates/registry-evidence/src/cli.rs @@ -41,6 +41,9 @@ pub enum Command { /// Bundle-relative fixture path referenced by exactly one requirement. #[arg(long)] fixture: PathBuf, + /// Evaluate only the case with this exact identifier. + #[arg(long)] + case: Option, /// Print the per-stage trace of what each case actually did. /// /// A failure names the contract that broke and nothing else, which says @@ -71,9 +74,15 @@ pub enum Command { bundle: PathBuf, #[arg(long)] fixture: PathBuf, + #[arg(long)] + case: Option, /// Print the same value-free per-stage trace as deployment evaluation. #[arg(long)] explain: bool, + /// Render the trace as the same single machine-readable document as + /// deployment evaluation. + #[arg(long, value_enum, requires = "explain")] + explain_format: Option, }, /// Internal Evidencectl seam for deterministic provider-publication compilation. #[command(hide = true)] diff --git a/crates/registry-evidence/src/main.rs b/crates/registry-evidence/src/main.rs index 10d021ec2..0770b4a30 100644 --- a/crates/registry-evidence/src/main.rs +++ b/crates/registry-evidence/src/main.rs @@ -26,8 +26,9 @@ use registry_evidence::{ ArtifactFault, Bundle, BundleError, DeploymentInputs, RuntimeDocument, SourceExtract, }, config::{ - AcquisitionConfig, ArtifactPath, AssuranceProfile, ConfigError, EvidenceConfig, - OutboundTlsConfig, SchemaFault, SelectorInput, StageRole, + AcquisitionConfig, ArtifactPath, AssuranceProfile, ConceptForm, ConfigError, + EvidenceConfig, OutboundTlsConfig, RequirementConfig, SchemaFault, SelectorInput, + StageRole, }, kernel::{ EvidenceConstruction, EvidenceScope, KernelError, KernelOutcome, OfflineKernel, @@ -57,7 +58,10 @@ use registry_evidence::{ StatementExtract, StatementInputs, }, source_sqlite::{cause as sqlite_cause, check_statement_offline, materialize_seed_extract}, - trace::{json_type, name_list, object_keys, FixtureReport, FixtureTrace, Stage, StageStatus}, + trace::{ + json_type, name_list, object_keys, CategoryClass, FindingCode, FixtureReport, FixtureTrace, + ReasonCode, ResultClass, ResultClassification, Stage, StageStatus, ValueClass, + }, verifier::{ verify_flattened_jws, verify_flattened_jws_report, verify_sd_jwt_vc_presentation_report, verify_sd_jwt_vc_report, EvidenceVerificationPolicy, EvidenceVerificationPolicyDocument, @@ -205,6 +209,7 @@ async fn run(cli: Cli) -> Result { } Command::Evaluate { fixture, + case, explain, explain_format, } => { @@ -216,8 +221,16 @@ async fn run(cli: Cli) -> Result { })?; let source_plans = compile_source_plans(&bundle, &runtime)?; let mut trace = FixtureTrace::default(); - let summary = - evaluate_fixture(&bundle, &kernel, &source_plans, &fixture, true, &mut trace).await; + let summary = evaluate_fixture( + &bundle, + &kernel, + &source_plans, + &fixture, + case.as_deref(), + true, + &mut trace, + ) + .await; // Checked here rather than at the end of the evaluation, and before // the render below. A run that stopped on an error never reaches // that end, and it is the run whose trace gets read; a trace found @@ -269,7 +282,9 @@ async fn run(cli: Cli) -> Result { Command::BundleEvaluate { bundle, fixture, + case, explain, + explain_format, } => { let bundle = Arc::new(Bundle::load(&bundle).map_err(deployment_load_error)?); let kernel = OfflineKernel::compile(Arc::clone(&bundle)).map_err(|error| { @@ -280,15 +295,29 @@ async fn run(cli: Cli) -> Result { // type and privacy-canary gate as deployment evaluation so an // editable project can be diagnosed before it has a runtime file. let mut trace = FixtureTrace::default(); - let summary = - evaluate_fixture(&bundle, &kernel, &source_plans, &fixture, false, &mut trace) - .await; + let summary = evaluate_fixture( + &bundle, + &kernel, + &source_plans, + &fixture, + case.as_deref(), + false, + &mut trace, + ) + .await; validate_trace_canaries(&trace)?; if explain { if let Err(error) = &summary { trace.fail(error.0); } - print!("{}", trace.render()); + match explain_format.unwrap_or_default() { + ExplainFormat::Text => print!("{}", trace.render()), + ExplainFormat::Json => { + println!("{}", fixture_report_json(&trace, summary.as_ref())?); + summary?; + return Ok(ExitCode::SUCCESS); + } + } } let summary = summary?; println!( @@ -1027,7 +1056,10 @@ fn fixture_report_json( ) -> Result { let report = FixtureReport { passed: summary.is_ok(), - evaluated_cases: summary.ok().map(|summary| summary.evaluated_cases), + evaluated_cases: summary + .ok() + .map(|summary| summary.evaluated_cases) + .or_else(|| (trace.case_count() > 0).then(|| trace.case_count())), trace, }; serde_json::to_string_pretty(&report) @@ -1106,6 +1138,7 @@ async fn evaluate_fixture( kernel: &OfflineKernel, source_plans: &BTreeMap, fixture_path: &Path, + selected_case: Option<&str>, exercise_signing: bool, trace: &mut FixtureTrace, ) -> Result { @@ -1156,7 +1189,7 @@ async fn evaluate_fixture( source_plans, signer.as_ref(), requirement, - object, + (object, selected_case), trace, ) .await; @@ -1178,6 +1211,13 @@ async fn evaluate_fixture( if cases.is_empty() || cases.len() > 256 { return Err(CliError("fixture case count is invalid")); } + if selected_case.is_some_and(|selected| { + !cases + .iter() + .any(|case| case.get("id").and_then(Value::as_str) == Some(selected)) + }) { + return Err(CliError("selected fixture case is unavailable")); + } let mut summary = FixtureSummary::default(); let mut successful_values = Vec::new(); @@ -1190,6 +1230,9 @@ async fn evaluate_fixture( .and_then(Value::as_str) .filter(|value| is_renderable_case_identifier(value)) .ok_or(CliError("fixture case identifier is invalid"))?; + if selected_case.is_some_and(|selected| selected != id) { + continue; + } trace.begin_case(id); if case.get("subjects").is_some() { @@ -1212,6 +1255,12 @@ async fn evaluate_fixture( StageStatus::Ok, "the selector was refused before any source, as the case states", ); + trace.diagnose( + ResultClassification::new(ResultClass::SelectorRefused, Vec::new()), + ResultClassification::new(ResultClass::SelectorRefused, Vec::new()), + ReasonCode::SelectorRefused, + None, + ); summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -1287,7 +1336,8 @@ async fn evaluate_fixture( observed_at, trace, )?; - if let Some(values) = validate_case_outcome(case, outcome, trace)? { + let categories = category_diagnostic_catalog(bundle, requirement); + if let Some(values) = validate_case_outcome(case, outcome, trace, &categories)? { successful_values.push( sign_and_verify_fixture_evidence( bundle, @@ -1318,6 +1368,12 @@ async fn evaluate_fixture( if let Some(injected) = case.get("injected_derivation") { validate_injected_rejection(kernel, requirement, injected, trace)?; require_expected(case, "output-gate-rejection")?; + trace.diagnose( + ResultClassification::new(ResultClass::ServiceUnavailable, Vec::new()), + ResultClassification::new(ResultClass::ServiceUnavailable, Vec::new()), + ReasonCode::OutputRefused, + None, + ); summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -1333,6 +1389,12 @@ async fn evaluate_fixture( source_failure.as_str().unwrap_or("an unnamed category") ), ); + trace.diagnose( + ResultClassification::new(ResultClass::SourceUnavailable, Vec::new()), + ResultClassification::new(ResultClass::SourceUnavailable, Vec::new()), + ReasonCode::SourceFailureFixture, + None, + ); summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -1348,6 +1410,12 @@ async fn evaluate_fixture( companion.as_str().unwrap_or_default() ), ); + trace.diagnose( + ResultClassification::new(ResultClass::BundleRefused, Vec::new()), + ResultClassification::new(ResultClass::BundleRefused, Vec::new()), + ReasonCode::CompanionBundleRefused, + None, + ); summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2003,9 +2071,10 @@ async fn evaluate_reference_fixture( source_plans: &BTreeMap, signer: Option<&EvidenceSigner>, requirement: ®istry_evidence::config::RequirementConfig, - fixture: &JsonMap, + fixture_selection: (&JsonMap, Option<&str>), trace: &mut FixtureTrace, ) -> Result { + let (fixture, selected_case) = fixture_selection; // Asked before the fixture is read at all, because the requirement decides // this on its own and an author who has written an unprovable stage should // be told that, not that some key their case shape cannot supply is missing. @@ -2083,6 +2152,14 @@ async fn evaluate_reference_fixture( let mut successful_values = Vec::new(); let mut summary = FixtureSummary::default(); + if selected_case.is_some_and(|selected| { + !cases + .iter() + .any(|case| case.get("id").and_then(Value::as_str) == Some(selected)) + }) { + return Err(CliError("selected fixture case is unavailable")); + } + for case in cases { let case = case .as_object() @@ -2112,6 +2189,9 @@ async fn evaluate_reference_fixture( .and_then(Value::as_str) .filter(|id| is_renderable_case_identifier(id) && identifiers.insert(*id)) .ok_or(CliError("reference fixture case identifier is invalid"))?; + if selected_case.is_some_and(|selected| selected != id) { + continue; + } trace.begin_case(id); let expected = case .get("expected") @@ -2197,6 +2277,14 @@ async fn evaluate_reference_fixture( StageStatus::Ok, format!("the {mutation:?} bundle mutation is refused, as the case requires"), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::BundleRefused, + ReasonCode::BundleRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2211,6 +2299,14 @@ async fn evaluate_reference_fixture( StageStatus::Ok, format!("the {mutation:?} statement mutation is refused, as the case requires"), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::BundleRefused, + ReasonCode::BundleRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2229,6 +2325,14 @@ async fn evaluate_reference_fixture( StageStatus::Ok, format!("the {mutation:?} request mutation is refused, as the case requires"), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::SelectorRefused, + ReasonCode::SelectorRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2262,13 +2366,14 @@ async fn evaluate_reference_fixture( StageStatus::Failed, "the overridden selectors are refused before the credential boundary", ); - validate_reference_error(expected, error, false)?; + validate_reference_error(expected, error.clone(), false)?; if expected.get("rejectedBefore").and_then(Value::as_str) != Some("credential") { return Err(CliError( "reference preparation rejection boundary did not match", )); } require_reference_request_count(expected, 0)?; + diagnose_reference_kernel_error(trace, expected, bundle, requirement, error)?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2316,6 +2421,14 @@ async fn evaluate_reference_fixture( )); } require_reference_request_count(expected, 1)?; + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::Match, + ReasonCode::UniqueMatch, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2338,6 +2451,14 @@ async fn evaluate_reference_fixture( StageStatus::Failed, format!("the source failed as {failure:?}, which the case states"), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::SourceUnavailable, + ReasonCode::SourceFailureFixture, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2349,6 +2470,14 @@ async fn evaluate_reference_fixture( StageStatus::Unresolved, "the source returned its exact declared unresolved outcome", ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::EvidenceUnavailable, + ReasonCode::SourceProtocolRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2366,6 +2495,14 @@ async fn evaluate_reference_fixture( StageStatus::Ok, format!("the {mutation:?} derivation mutation is refused, as the case requires"), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::ServiceUnavailable, + ReasonCode::OutputRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2391,6 +2528,14 @@ async fn evaluate_reference_fixture( name_list(&mutation.keys().cloned().collect::>()) ), ); + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::ServiceUnavailable, + ReasonCode::OutputRefused, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2431,6 +2576,14 @@ async fn evaluate_reference_fixture( ); validate_reference_source_error(expected, &error)?; require_reference_request_count(expected, 1)?; + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::SourceUnavailable, + ReasonCode::SourceFailureFixture, + )?; summary.evaluated_cases += 1; trace.pass_case(); continue; @@ -2491,9 +2644,25 @@ async fn evaluate_reference_fixture( Err(settled) => { match settled { Ok(KernelOutcome::NoMatch) => { + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::NoMatch, + ReasonCode::NoMatch, + )?; validate_reference_unresolved(expected, "no_match")? } Ok(KernelOutcome::Ambiguous) => { + diagnose_reference_fixed( + trace, + expected, + bundle, + requirement, + ResultClass::Ambiguous, + ReasonCode::Ambiguous, + )?; validate_reference_unresolved(expected, "ambiguous")? } Ok(KernelOutcome::Match(_)) => { @@ -2501,7 +2670,16 @@ async fn evaluate_reference_fixture( "reference search settled on an unreachable outcome", )); } - Err(error) => validate_reference_error(expected, error, false)?, + Err(error) => { + diagnose_reference_kernel_error( + trace, + expected, + bundle, + requirement, + error.clone(), + )?; + validate_reference_error(expected, error, false)? + } } require_reference_request_count(expected, 1)?; summary.evaluated_cases += 1; @@ -2561,6 +2739,13 @@ async fn evaluate_reference_fixture( name_list(&object_keys(&projected_fetch)) )], ); + diagnose_reference_kernel_error( + trace, + expected, + bundle, + requirement, + KernelError::SourceProtocol, + )?; validate_reference_error(expected, KernelError::SourceProtocol, false)?; require_reference_request_count(expected, 2)?; summary.evaluated_cases += 1; @@ -2578,6 +2763,13 @@ async fn evaluate_reference_fixture( name_list(&object_keys(&projected_fetch)) )], ); + diagnose_reference_kernel_error( + trace, + expected, + bundle, + requirement, + error.clone(), + )?; validate_reference_error(expected, error, false)?; require_reference_request_count(expected, 2)?; summary.evaluated_cases += 1; @@ -2671,10 +2863,26 @@ async fn validate_reference_lookup( let facts = match record_lookup(trace, lookup, protected_response) { Ok(facts) => facts, Err(Ok(KernelOutcome::NoMatch)) => { + diagnose_reference_fixed( + trace, + expected, + context.bundle, + context.requirement, + ResultClass::NoMatch, + ReasonCode::NoMatch, + )?; validate_reference_unresolved(expected, "no_match")?; return Ok(None); } Err(Ok(KernelOutcome::Ambiguous)) => { + diagnose_reference_fixed( + trace, + expected, + context.bundle, + context.requirement, + ResultClass::Ambiguous, + ReasonCode::Ambiguous, + )?; validate_reference_unresolved(expected, "ambiguous")?; return Ok(None); } @@ -2684,6 +2892,13 @@ async fn validate_reference_lookup( )); } Err(Err(error)) => { + diagnose_reference_kernel_error( + trace, + expected, + context.bundle, + context.requirement, + error.clone(), + )?; validate_reference_error(expected, error, false)?; return Ok(None); } @@ -2723,15 +2938,38 @@ async fn validate_reference_lookup( )); } Err(error) => { + diagnose_reference_kernel_error( + trace, + expected, + context.bundle, + context.requirement, + error.clone(), + )?; validate_reference_error(expected, error, true)?; return Ok(None); } }; + diagnose_reference_match( + trace, + expected, + context.bundle, + context.requirement, + &values, + None, + )?; if expected.get("derivationRuns").and_then(Value::as_bool) != Some(true) { return Err(CliError("reference derivation execution did not match")); } if let Some(exact) = expected.get("value") { if values.as_slice().len() != 1 || public_json(&values.as_slice()[0].value)? != *exact { + diagnose_reference_match( + trace, + expected, + context.bundle, + context.requirement, + &values, + Some(FindingCode::ResultValueMismatch), + )?; return Err(CliError("reference scalar value did not match")); } } @@ -2740,6 +2978,14 @@ async fn validate_reference_lookup( .as_object() .ok_or(CliError("reference concept map is invalid"))?; if values.as_slice().len() != exact.len() { + diagnose_reference_match( + trace, + expected, + context.bundle, + context.requirement, + &values, + Some(FindingCode::ResultShapeMismatch), + )?; return Err(CliError("reference concept value did not match")); } for (concept, expected_value) in exact { @@ -2749,6 +2995,14 @@ async fn validate_reference_lookup( .find(|value| value.provides_value_for == *concept) .ok_or(CliError("reference concept value did not match"))?; if public_json(&disclosed.value)? != *expected_value { + diagnose_reference_match( + trace, + expected, + context.bundle, + context.requirement, + &values, + Some(FindingCode::ResultValueMismatch), + )?; return Err(CliError("reference concept value did not match")); } } @@ -3733,7 +3987,10 @@ fn validate_case_outcome( case: &serde_json::Map, outcome: Result, trace: &mut FixtureTrace, + categories: &[CategoryDiagnosticEntry], ) -> Result, CliError> { + let expected = classify_expected_result(case, categories)?; + let (observed, reason) = classify_observed_result(&outcome, categories); // What the case says it expects, beside what the pipeline just did. The // pipeline half of it is already recorded above this line. let declared = format!( @@ -3744,6 +4001,12 @@ fn validate_case_outcome( stated_flag(optional_boolean(case, "signed_success")?) ); let compared = compare_case_outcome(case, outcome); + trace.diagnose( + expected, + observed, + reason, + compared.as_ref().err().map(expectation_finding_code), + ); trace.record( Stage::Expect, if compared.is_ok() { @@ -3756,6 +4019,378 @@ fn validate_case_outcome( compared } +/// Reduce one authored expectation to the same closed vocabulary used for an +/// observed result. Values become only bounded shape classes. In particular, +/// strings, integers, entity references, and structured values never reach the +/// trace as authored material. +fn classify_expected_result( + case: &serde_json::Map, + categories: &[CategoryDiagnosticEntry], +) -> Result { + let expected_lookup = optional_string(case, "expected_lookup")?; + let expected_problem = optional_string(case, "expected_public_problem")?; + let class = match expected_lookup { + Some("no_match") => ResultClass::NoMatch, + Some("ambiguous") => ResultClass::Ambiguous, + Some("match") | None => match expected_problem { + Some("evidence.unavailable") => ResultClass::EvidenceUnavailable, + Some("source.unavailable") => ResultClass::SourceUnavailable, + Some("service.unavailable") => ResultClass::ServiceUnavailable, + Some(_) => return Err(CliError("fixture public problem expectation is invalid")), + None => ResultClass::Match, + }, + Some(_) => return Err(CliError("fixture lookup expectation is invalid")), + }; + let mut values = Vec::new(); + let mut category_classes = Vec::new(); + if class == ResultClass::Match { + if let Some(value) = case.get("expected_value") { + values.push(classify_json_value(value)); + if categories.len() == 1 { + if let Some(category) = classify_expected_category(&categories[0], value) { + category_classes.push(category); + } + } + } + if let Some(map) = case.get("expected_values").and_then(Value::as_object) { + values.extend(map.values().map(classify_json_value)); + category_classes.extend(categories.iter().filter_map(|category| { + map.get(&category.concept_id) + .and_then(|value| classify_expected_category(category, value)) + })); + } + } + Ok(ResultClassification::new(class, values).with_category_classes(category_classes)) +} + +/// Reduce the current reference-fixture `expected` object to the same closed +/// vocabulary used for legacy coequal fixtures. The two fixture dialects are +/// authoring surfaces only; they share one authoritative result taxonomy. +fn classify_reference_expected_result( + expected: &JsonMap, + categories: &[CategoryDiagnosticEntry], +) -> Result { + let lookup = expected.get("lookup").and_then(Value::as_str); + let public_problem = expected.get("publicProblem").and_then(Value::as_str); + let class = match lookup { + Some("no_match") => ResultClass::NoMatch, + Some("ambiguous") => ResultClass::Ambiguous, + Some("match") | None => match public_problem { + Some("evidence.unavailable") => ResultClass::EvidenceUnavailable, + Some("source.unavailable") => ResultClass::SourceUnavailable, + Some("service.unavailable") => ResultClass::ServiceUnavailable, + Some(_) => return Err(CliError("reference public problem expectation is invalid")), + None if expected.get("bundle").and_then(Value::as_str) == Some("rejected") => { + ResultClass::BundleRefused + } + None if expected.contains_key("rejectedBefore") => ResultClass::SelectorRefused, + None if expected.contains_key("outputGate") || expected.contains_key("error") => { + ResultClass::ServiceUnavailable + } + None => ResultClass::Match, + }, + Some(_) => return Err(CliError("reference lookup expectation is invalid")), + }; + let mut values = Vec::new(); + let mut category_classes = Vec::new(); + if class == ResultClass::Match { + if let Some(value) = expected.get("value") { + values.push(classify_json_value(value)); + if categories.len() == 1 { + if let Some(category) = classify_expected_category(&categories[0], value) { + category_classes.push(category); + } + } + } + if let Some(map) = expected.get("values").and_then(Value::as_object) { + values.extend(map.values().map(classify_json_value)); + category_classes.extend(categories.iter().filter_map(|category| { + map.get(&category.concept_id) + .and_then(|value| classify_expected_category(category, value)) + })); + } + if expected.contains_key("entityReferenceCount") { + values.push(ValueClass::List); + } + } + Ok(ResultClassification::new(class, values).with_category_classes(category_classes)) +} + +fn reference_diagnostic_finding( + expected: &ResultClassification, + observed: &ResultClassification, +) -> Option { + if expected == observed { + return None; + } + if expected.class != observed.class { + return Some( + if matches!( + expected.class, + ResultClass::NoMatch | ResultClass::Ambiguous + ) || matches!( + observed.class, + ResultClass::NoMatch | ResultClass::Ambiguous + ) { + FindingCode::LookupOutcomeMismatch + } else { + FindingCode::PublicProblemMismatch + }, + ); + } + Some(if expected.value_classes != observed.value_classes { + FindingCode::ResultShapeMismatch + } else { + FindingCode::ResultValueMismatch + }) +} + +fn diagnose_reference_fixed( + trace: &mut FixtureTrace, + expected: &JsonMap, + bundle: &Bundle, + requirement: &RequirementConfig, + observed_class: ResultClass, + reason: ReasonCode, +) -> Result<(), CliError> { + let categories = category_diagnostic_catalog(bundle, requirement); + let expected = classify_reference_expected_result(expected, &categories)?; + let observed = ResultClassification::new(observed_class, Vec::new()); + let finding = reference_diagnostic_finding(&expected, &observed); + trace.diagnose(expected, observed, reason, finding); + Ok(()) +} + +fn diagnose_reference_kernel_error( + trace: &mut FixtureTrace, + expected: &JsonMap, + bundle: &Bundle, + requirement: &RequirementConfig, + error: KernelError, +) -> Result<(), CliError> { + let categories = category_diagnostic_catalog(bundle, requirement); + let expected = classify_reference_expected_result(expected, &categories)?; + let (observed, reason) = classify_observed_result(&Err(error), &categories); + let finding = reference_diagnostic_finding(&expected, &observed); + trace.diagnose(expected, observed, reason, finding); + Ok(()) +} + +fn diagnose_reference_match( + trace: &mut FixtureTrace, + expected: &JsonMap, + bundle: &Bundle, + requirement: &RequirementConfig, + values: &ValidatedValues, + finding_override: Option, +) -> Result<(), CliError> { + let categories = category_diagnostic_catalog(bundle, requirement); + let expected = classify_reference_expected_result(expected, &categories)?; + let (observed, reason) = + classify_observed_result(&Ok(KernelOutcome::Match(values.clone())), &categories); + let finding = finding_override.or_else(|| reference_diagnostic_finding(&expected, &observed)); + trace.diagnose(expected, observed, reason, finding); + Ok(()) +} + +fn classify_observed_result( + outcome: &Result, + categories: &[CategoryDiagnosticEntry], +) -> (ResultClassification, ReasonCode) { + match outcome { + Ok(KernelOutcome::Match(values)) => ( + ResultClassification::new( + ResultClass::Match, + values + .as_slice() + .iter() + .map(|value| classify_public_value(&value.value)) + .collect(), + ) + .with_category_classes( + values + .as_slice() + .iter() + .filter_map(|value| { + categories + .iter() + .find(|category| category.concept_id == value.provides_value_for) + .and_then(|category| classify_observed_category(category, &value.value)) + }) + .collect(), + ), + ReasonCode::UniqueMatch, + ), + Ok(KernelOutcome::NoMatch) => ( + ResultClassification::new(ResultClass::NoMatch, Vec::new()), + ReasonCode::NoMatch, + ), + Ok(KernelOutcome::Ambiguous) => ( + ResultClassification::new(ResultClass::Ambiguous, Vec::new()), + ReasonCode::Ambiguous, + ), + Err(error) => { + let (class, reason) = match error { + KernelError::Extraction => ( + ResultClass::EvidenceUnavailable, + ReasonCode::ExtractionRefused, + ), + KernelError::DerivationInput => ( + ResultClass::EvidenceUnavailable, + ReasonCode::DerivationInputRefused, + ), + KernelError::SourceProtocol => ( + ResultClass::SourceUnavailable, + ReasonCode::SourceProtocolRefused, + ), + KernelError::Script => (ResultClass::ServiceUnavailable, ReasonCode::ScriptRefused), + KernelError::Output => (ResultClass::ServiceUnavailable, ReasonCode::OutputRefused), + KernelError::Bundle | KernelError::Artifact(_) => { + (ResultClass::ServiceUnavailable, ReasonCode::BundleRefused) + } + KernelError::Requirement => ( + ResultClass::ServiceUnavailable, + ReasonCode::RequirementRefused, + ), + KernelError::Evidence => ( + ResultClass::ServiceUnavailable, + ReasonCode::EvidenceConstructionRefused, + ), + KernelError::Preparation => { + (ResultClass::ServiceUnavailable, ReasonCode::ScriptRefused) + } + }; + (ResultClassification::new(class, Vec::new()), reason) + } + } +} + +struct CategoryDiagnosticEntry { + concept_id: String, + concept_ordinal: usize, + allowed_outputs: Vec, +} + +fn category_diagnostic_catalog( + bundle: &Bundle, + requirement: &RequirementConfig, +) -> Vec { + requirement + .concepts + .iter() + .enumerate() + .filter(|(_, concept)| concept.form == ConceptForm::ControlledCategory) + .filter_map(|(concept_ordinal, concept)| { + let path = concept + .constraints + .get("codelist") + .and_then(serde_norway::Value::as_str)?; + let codelist = bundle.codelists.get(path)?; + let allowed_outputs = match codelist { + registry_evidence::bundle::Codelist::Codes { codes, .. } => codes.clone(), + registry_evidence::bundle::Codelist::Mapping { + allowed_outputs, .. + } => allowed_outputs.clone(), + }; + Some(CategoryDiagnosticEntry { + concept_id: concept.id.clone(), + concept_ordinal, + allowed_outputs, + }) + }) + .collect() +} + +fn classify_expected_category( + category: &CategoryDiagnosticEntry, + value: &Value, +) -> Option { + let value = value.as_str()?; + category + .allowed_outputs + .iter() + .position(|allowed| allowed == value) + .map(|value_ordinal| CategoryClass { + concept_ordinal: category.concept_ordinal, + value_ordinal, + }) +} + +fn classify_observed_category( + category: &CategoryDiagnosticEntry, + value: &PublicValue, +) -> Option { + let PublicValue::String(value) = value else { + return None; + }; + category + .allowed_outputs + .iter() + .position(|allowed| allowed == value) + .map(|value_ordinal| CategoryClass { + concept_ordinal: category.concept_ordinal, + value_ordinal, + }) +} + +fn classify_json_value(value: &Value) -> ValueClass { + match value { + Value::Bool(false) => ValueClass::BooleanFalse, + Value::Bool(true) => ValueClass::BooleanTrue, + Value::Number(_) => ValueClass::Integer, + Value::String(_) => ValueClass::String, + Value::Array(_) => ValueClass::List, + Value::Object(object) => match object.get("form").and_then(Value::as_str) { + Some("date-bucket" | "time-bucket") => ValueClass::Bucket, + Some("audience-scoped-entity-reference") => ValueClass::EntityReference, + _ => ValueClass::Structured, + }, + Value::Null => ValueClass::Structured, + } +} + +fn classify_public_value(value: &PublicValue) -> ValueClass { + match value { + PublicValue::Boolean(false) => ValueClass::BooleanFalse, + PublicValue::Boolean(true) => ValueClass::BooleanTrue, + PublicValue::Integer(_) => ValueClass::Integer, + PublicValue::String(_) => ValueClass::String, + PublicValue::Bucket(_) => ValueClass::Bucket, + PublicValue::EntityReference(_) => ValueClass::EntityReference, + PublicValue::Structured(_) => ValueClass::Structured, + PublicValue::List(_) => ValueClass::List, + } +} + +/// Convert the fixed comparison error vocabulary into one closed repair code. +/// The returned code, unlike the operator sentence, is a stable machine input. +fn expectation_finding_code(error: &CliError) -> FindingCode { + match error.0 { + "fixture lookup outcome did not match its contract" | "fixture expected a unique match" => { + FindingCode::LookupOutcomeMismatch + } + "fixture kernel failure did not match its public problem" + | "unresolved fixture public problem is not exact" + | "fixture evaluation failed unexpectedly" => FindingCode::PublicProblemMismatch, + "unresolved fixture must deny derivation and signed success" + | "failing fixture execution expectations did not match" + | "matched fixture cannot deny derivation execution" + | "matched fixture must require derivation and signed success" => { + FindingCode::DerivationExpectationMismatch + } + "matched fixture cannot deny signed-success eligibility" => { + FindingCode::SigningExpectationMismatch + } + "fixture value did not match its contract" => FindingCode::ResultValueMismatch, + "fixture value set did not match its contract" => FindingCode::ResultShapeMismatch, + "fixture lookup expectation is invalid" + | "matched fixture must require an exact match" + | "matched fixture must declare exactly one value expectation" + | "fixture value-set expectation is invalid" => FindingCode::InvalidExpectation, + _ => FindingCode::UnexpectedToolOutcome, + } +} + /// Decide whether the outcome one case declared is the outcome it got. fn compare_case_outcome( case: &serde_json::Map, @@ -4537,6 +5172,59 @@ mod tests { } } + #[test] + fn arbitrary_strings_never_become_category_diagnostic_identity() { + let category = CategoryDiagnosticEntry { + concept_id: "urn:example:concept:category".to_owned(), + concept_ordinal: 0, + allowed_outputs: vec!["allowed".to_owned()], + }; + assert_eq!( + classify_expected_category(&category, &Value::String("arbitrary".to_owned())), + None + ); + assert_eq!( + classify_observed_category(&category, &PublicValue::String("arbitrary".to_owned())), + None + ); + let case = serde_json::json!({"expected_value": "arbitrary"}); + let classified = classify_expected_result(case.as_object().expect("object"), &[]) + .expect("a generic string remains classifiable"); + assert_eq!(classified.value_classes, vec![ValueClass::String]); + assert!(classified.category_classes.is_empty()); + } + + #[test] + fn nested_reference_expectations_use_governed_category_ordinals() { + let category = CategoryDiagnosticEntry { + concept_id: "urn:example:concept:category".to_owned(), + concept_ordinal: 2, + allowed_outputs: vec!["approved".to_owned(), "pending".to_owned()], + }; + let expected = serde_json::json!({ + "lookup": "match", + "value": "pending", + "derivationRuns": true, + "signed": true + }); + let classified = + classify_reference_expected_result(expected.as_object().expect("object"), &[category]) + .expect("the nested reference expectation is classifiable"); + assert_eq!(classified.class, ResultClass::Match); + assert_eq!(classified.value_classes, vec![ValueClass::String]); + assert_eq!( + classified.category_classes, + vec![CategoryClass { + concept_ordinal: 2, + value_ordinal: 1, + }] + ); + let serialized = serde_json::to_string(&classified).expect("classification serializes"); + assert!(!serialized.contains("approved")); + assert!(!serialized.contains("pending")); + assert!(!serialized.contains("urn:example:concept:category")); + } + #[test] fn public_unavailability_requires_an_extraction_failure() { let case = serde_json::json!({ @@ -4548,13 +5236,15 @@ mod tests { assert!(validate_case_outcome( case, Ok(KernelOutcome::NoMatch), - &mut FixtureTrace::default() + &mut FixtureTrace::default(), + &[], ) .is_err()); assert!(validate_case_outcome( case, Err(registry_evidence::kernel::KernelError::Script), &mut FixtureTrace::default(), + &[], ) .is_err()); assert_eq!( @@ -4562,6 +5252,7 @@ mod tests { case, Err(registry_evidence::kernel::KernelError::Extraction), &mut FixtureTrace::default(), + &[], ), Ok(None) ); @@ -4580,6 +5271,7 @@ mod tests { case, Err(registry_evidence::kernel::KernelError::Script), &mut FixtureTrace::default(), + &[], ), Ok(None) ); @@ -4587,6 +5279,7 @@ mod tests { case, Err(registry_evidence::kernel::KernelError::Extraction), &mut FixtureTrace::default(), + &[], ) .is_err()); } @@ -4609,6 +5302,7 @@ mod tests { declaration.as_object().expect("object"), Ok(KernelOutcome::NoMatch), &mut FixtureTrace::default(), + &[], ) .is_err()); } @@ -4847,7 +5541,7 @@ mod tests { &source_plans, Some(&signer), requirement, - fixture.as_object().expect("fixture is an object"), + (fixture.as_object().expect("fixture is an object"), None), &mut trace, ) .await, @@ -4856,6 +5550,40 @@ mod tests { }) ); + let selected = fixture["cases"][0]["id"].as_str().expect("case id"); + assert_eq!( + evaluate_reference_fixture( + &bundle, + &kernel, + &source_plans, + Some(&signer), + requirement, + ( + fixture.as_object().expect("fixture is an object"), + Some(selected) + ), + &mut FixtureTrace::default(), + ) + .await, + Ok(FixtureSummary { evaluated_cases: 1 }) + ); + assert_eq!( + evaluate_reference_fixture( + &bundle, + &kernel, + &source_plans, + Some(&signer), + requirement, + ( + fixture.as_object().expect("fixture is an object"), + Some("private-case-canary") + ), + &mut FixtureTrace::default(), + ) + .await, + Err(CliError("selected fixture case is unavailable")) + ); + let rendered = serde_json::to_string(&trace).expect("trace is representable"); assert!(rendered.contains("unresolved")); for prohibited in ["fixture-canary", "fixture.canary", "no-match case"] { @@ -5138,7 +5866,7 @@ mod tests { &BTreeMap::new(), None, requirement, - fixture.as_object().expect("the fixture is an object"), + (fixture.as_object().expect("the fixture is an object"), None), &mut FixtureTrace::default(), ) .await @@ -5560,6 +6288,7 @@ mod tests { &kernel, &source_plans, fixture, + None, true, &mut FixtureTrace::default(), ) @@ -5702,6 +6431,7 @@ mod tests { &kernel, &source_plans, fixture, + None, true, &mut FixtureTrace::default() ) @@ -5716,6 +6446,82 @@ mod tests { } } + #[cfg(unix)] + #[tokio::test] + async fn coequal_fixture_selection_evaluates_one_exact_case_value_free() { + let directory = tempfile::tempdir().expect("temporary bundle"); + let source = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../products/evidence/fixtures/acceptance/adult-status"); + copy_tree(&source, directory.path()); + set_tree_mode(directory.path(), 0o555, 0o444); + + let bundle = Arc::new(Bundle::load(directory.path()).expect("acceptance bundle loads")); + let kernel = OfflineKernel::compile(Arc::clone(&bundle)).expect("kernel compiles"); + let source_plans = compile_source_plans_with_runtime( + &bundle.config, + &source_statements(&bundle, None).expect("statement sources bind"), + "/run/secrets/evidence", + &OutboundTlsConfig { + system_roots: true, + trust_profiles: Default::default(), + }, + &Default::default(), + ) + .expect("source plans compile"); + let fixture = Path::new( + bundle.config.requirements[0] + .fixtures + .as_ref() + .expect("acceptance fixture is declared") + .as_str(), + ); + + let mut trace = FixtureTrace::default(); + assert_eq!( + evaluate_fixture( + &bundle, + &kernel, + &source_plans, + fixture, + Some("positive"), + true, + &mut trace, + ) + .await, + Ok(FixtureSummary { evaluated_cases: 1 }) + ); + let rendered = trace.render(); + assert!( + rendered.contains("positive"), + "selected case is absent: {rendered}" + ); + assert!( + !rendered.contains("negative-false-is-success"), + "another case ran: {rendered}" + ); + + let unknown = "private-case-selector-canary"; + let error = evaluate_fixture( + &bundle, + &kernel, + &source_plans, + fixture, + Some(unknown), + true, + &mut FixtureTrace::default(), + ) + .await + .expect_err("unknown case must be refused"); + assert_eq!(error, CliError("selected fixture case is unavailable")); + assert!( + !error.0.contains(unknown), + "case selector leaked: {}", + error.0 + ); + + set_tree_mode(directory.path(), 0o755, 0o444); + } + #[cfg(unix)] #[tokio::test] async fn offline_cli_evaluates_the_combined_acceptance_bundle() { @@ -5752,6 +6558,7 @@ mod tests { &kernel, &source_plans, fixture, + None, true, &mut FixtureTrace::default() ) @@ -5818,6 +6625,7 @@ mod tests { &kernel, &source_plans, fixture, + None, true, &mut FixtureTrace::default() ) @@ -5898,6 +6706,7 @@ mod tests { &kernel, &source_plans, fixture, + None, true, &mut FixtureTrace::default() ) diff --git a/crates/registry-evidence/src/trace.rs b/crates/registry-evidence/src/trace.rs index 9114fa047..60af783aa 100644 --- a/crates/registry-evidence/src/trace.rs +++ b/crates/registry-evidence/src/trace.rs @@ -15,6 +15,116 @@ use serde::Serialize; +/// The closed public-facing class of one fixture result. +/// +/// These are deliberately coarser than runtime errors. They are sufficient to +/// distinguish a unique result, an unresolved lookup, and the three public +/// availability classes without exposing the values or implementation detail +/// that produced one. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum ResultClass { + Match, + NoMatch, + Ambiguous, + EvidenceUnavailable, + SourceUnavailable, + ServiceUnavailable, + BundleRefused, + SelectorRefused, +} + +/// A bounded classification of a governed result value, never the value. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum ValueClass { + BooleanFalse, + BooleanTrue, + Integer, + String, + Bucket, + EntityReference, + Structured, + List, +} + +/// Why the observed result reached its closed class. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum ReasonCode { + UniqueMatch, + NoMatch, + Ambiguous, + ExtractionRefused, + DerivationInputRefused, + SourceProtocolRefused, + ScriptRefused, + OutputRefused, + BundleRefused, + RequirementRefused, + EvidenceConstructionRefused, + SelectorRefused, + SourceFailureFixture, + CompanionBundleRefused, +} + +/// A closed repair finding. Absence means the expected and observed result +/// classifications agreed. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum FindingCode { + LookupOutcomeMismatch, + PublicProblemMismatch, + DerivationExpectationMismatch, + SigningExpectationMismatch, + ResultValueMismatch, + ResultShapeMismatch, + InvalidExpectation, + UnexpectedToolOutcome, +} + +/// A controlled-category identity expressed only as governed positions. +/// +/// `concept_ordinal` is the concept's position in the requirement and +/// `value_ordinal` is the value's position in that concept's captured +/// codelist. Neither ordinal is derived from source or selector data. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CategoryClass { + pub concept_ordinal: usize, + pub value_ordinal: usize, +} + +/// One expected or observed result with values reduced to a closed shape. +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ResultClassification { + pub class: ResultClass, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub value_classes: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub category_classes: Vec, +} + +impl ResultClassification { + pub fn new(class: ResultClass, mut value_classes: Vec) -> Self { + value_classes.sort_unstable(); + value_classes.dedup(); + Self { + class, + value_classes, + category_classes: Vec::new(), + } + } + + pub fn with_category_classes(mut self, mut category_classes: Vec) -> Self { + category_classes.sort_unstable(); + category_classes.dedup(); + self.category_classes = category_classes; + self + } +} + /// One step of the offline pipeline, named in generic pipeline vocabulary. /// /// The names describe what the runtime does, never what an acceptance @@ -95,12 +205,26 @@ pub struct StageRecord { /// One fixture case: its identifier, the stages it reached, and its verdict. #[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] pub struct CaseTrace { pub id: String, pub stages: Vec, /// The fixed operator message that ended the case, when one did. #[serde(skip_serializing_if = "Option::is_none")] pub failure: Option, + /// The case's authored result reduced to the closed diagnostic vocabulary. + #[serde(skip_serializing_if = "Option::is_none")] + pub expected_result: Option, + /// What the authoritative evaluator produced, reduced the same way. + #[serde(skip_serializing_if = "Option::is_none")] + pub observed_result: Option, + /// The value-free cause of the observed result. + #[serde(skip_serializing_if = "Option::is_none")] + pub reason_code: Option, + /// Closed repair findings. This list is bounded by the one comparison the + /// fixture harness performs for a case. + #[serde(skip_serializing_if = "Vec::is_empty")] + pub finding_codes: Vec, /// Whether the case reached a verdict. Not part of the rendered value; it /// only decides which case a later failure belongs to. #[serde(skip)] @@ -143,6 +267,10 @@ pub struct FixtureReport<'a> { const FIXTURE_SCOPE: &str = "(fixture)"; impl FixtureTrace { + pub fn case_count(&self) -> usize { + self.cases.len() + } + /// Declare what this trace must never contain. /// /// Declared as soon as the fixture is read, before any case runs, so the @@ -162,10 +290,29 @@ impl FixtureTrace { id: id.to_owned(), stages: Vec::new(), failure: None, + expected_result: None, + observed_result: None, + reason_code: None, + finding_codes: Vec::new(), settled: false, }); } + /// Attach the closed expected-versus-observed comparison to the open case. + pub fn diagnose( + &mut self, + expected: ResultClassification, + observed: ResultClassification, + reason: ReasonCode, + finding: Option, + ) { + let case = self.open_case(); + case.expected_result = Some(expected); + case.observed_result = Some(observed); + case.reason_code = Some(reason); + case.finding_codes = finding.into_iter().collect(); + } + /// Record a stage against the open case. pub fn record(&mut self, stage: Stage, status: StageStatus, note: impl Into) { self.record_with(stage, status, note, Vec::new()); @@ -440,6 +587,65 @@ mod tests { assert_eq!(serialized["cases"][0]["id"], serde_json::json!("positive")); } + #[test] + fn a_result_diagnostic_is_closed_bounded_and_value_free() { + let mut trace = FixtureTrace::default(); + trace.begin_case("wrong-governed-answer"); + trace.diagnose( + ResultClassification::new( + ResultClass::Match, + vec![ValueClass::BooleanFalse, ValueClass::BooleanFalse], + ) + .with_category_classes(vec![ + CategoryClass { + concept_ordinal: 1, + value_ordinal: 2, + }, + CategoryClass { + concept_ordinal: 0, + value_ordinal: 1, + }, + CategoryClass { + concept_ordinal: 1, + value_ordinal: 2, + }, + ]), + ResultClassification::new(ResultClass::Match, vec![ValueClass::BooleanTrue]), + ReasonCode::UniqueMatch, + Some(FindingCode::ResultValueMismatch), + ); + trace.fail("fixture value did not match its contract"); + + let serialized = serde_json::to_value(&trace).expect("trace serializes"); + let case = &serialized["cases"][0]; + assert_eq!(case["expectedResult"]["class"], serde_json::json!("match")); + assert_eq!( + case["expectedResult"]["valueClasses"], + serde_json::json!(["boolean-false"]) + ); + assert_eq!(case["observedResult"]["class"], serde_json::json!("match")); + assert_eq!( + case["expectedResult"]["categoryClasses"], + serde_json::json!([ + {"conceptOrdinal": 0, "valueOrdinal": 1}, + {"conceptOrdinal": 1, "valueOrdinal": 2} + ]) + ); + assert_eq!( + case["observedResult"]["valueClasses"], + serde_json::json!(["boolean-true"]) + ); + assert_eq!(case["reasonCode"], serde_json::json!("unique-match")); + assert_eq!( + case["findingCodes"], + serde_json::json!(["result-value-mismatch"]) + ); + let rendered = serialized.to_string(); + for prohibited in ["synthetic-person-001", "2000-01-01", "SELECT", "token-"] { + assert!(!rendered.contains(prohibited)); + } + } + #[test] fn a_failing_report_omits_the_count_and_keeps_the_message_on_the_case_that_failed() { let mut trace = FixtureTrace::default(); diff --git a/crates/registry-evidence/tests/cli.rs b/crates/registry-evidence/tests/cli.rs index 49b37077e..c2f1ae5e7 100644 --- a/crates/registry-evidence/tests/cli.rs +++ b/crates/registry-evidence/tests/cli.rs @@ -916,15 +916,22 @@ fn explaining_a_failing_fixture_as_json_keeps_its_exit_code_and_keeps_its_messag let stdout = std::str::from_utf8(&output.stdout).expect("stdout is UTF-8"); let report: Value = serde_json::from_str(stdout).expect("stdout is one JSON document"); assert_eq!(report["passed"], json!(false)); + // `no-match` is the ninth case in the fixture's `cases.yaml`, so the run + // reaches nine cases before the mutation stops it. A reader counts what the + // run got through, whether or not it got through all of them. assert_eq!( - report.get("evaluatedCases"), - None, - "a failed run reported an evaluated-case count" + report["evaluatedCases"], + json!(9), + "a failed run lost its evaluated-case count" ); - let failed = report["cases"] - .as_array() - .expect("cases is an array") + let cases = report["cases"].as_array().expect("cases is an array"); + assert_eq!( + report["evaluatedCases"], + json!(cases.len()), + "the count and the traced cases disagree" + ); + let failed = cases .iter() .find(|case| case.get("failure").is_some()) .expect("the document names the case that failed"); diff --git a/crates/registry-evidencectl/src/fixtures.rs b/crates/registry-evidencectl/src/fixtures.rs index 3a4851d30..edd48eb44 100644 --- a/crates/registry-evidencectl/src/fixtures.rs +++ b/crates/registry-evidencectl/src/fixtures.rs @@ -10,6 +10,7 @@ use std::{ use anyhow::{anyhow, bail, Context, Result}; use clap::{Args, Subcommand}; use serde::Serialize; +use serde_json::Value as JsonValue; use serde_norway::Value as YamlValue; use crate::authoring::{compile_fixture_project, CompiledFixtureProject}; @@ -31,28 +32,32 @@ pub struct RunArgs { #[arg(long)] pub evidence_bin: Option, + /// Run only the exact bundle-relative fixture path named here. + #[arg(long)] + pub fixture: Option, + + /// Run only the exact case identifier in the selected fixture. + #[arg(long, requires = "fixture")] + pub case: Option, + /// Emit one machine-readable JSON report on standard output. #[arg(long)] pub json: bool, - /// Ask `evidence` to explain each evaluation, and relay the trace it prints. - /// - /// The trace can name what a source returned, so it is relayed only when it - /// is asked for. For the structured form, run `evidence evaluate --explain - /// --explain-format json` against the fixture directly. + /// Ask `evidence` for each structured value-free evaluation diagnostic and + /// relay it without interpreting Evidence semantics. #[arg(long)] pub explain: bool, } -/// The result of one `evidence` invocation: whether it exited zero, what it -/// printed on standard output, when it failed its captured stderr for the -/// operator to read, and, for a fixture run, how many cases that fixture -/// evaluated. +/// The result of one `evidence` invocation: whether it exited zero, when it +/// failed its captured stderr for the operator to read, and, for a fixture run, +/// how many cases that fixture evaluated. struct StepOutcome { passed: bool, - stdout: String, stderr: Option, evaluated_cases: Option, + trace: Option, } #[derive(Debug, Serialize)] @@ -74,7 +79,7 @@ struct FixtureReport { /// What `evidence evaluate --explain` printed, verbatim, and only when a /// trace was asked for. #[serde(skip_serializing_if = "Option::is_none")] - trace: Option, + trace: Option, } #[derive(Debug, Serialize)] @@ -130,7 +135,7 @@ fn run_fixtures(args: RunArgs) -> Result { _staging: staging, } }; - let fixture_paths = target.fixture_paths(); + let fixture_paths = select_fixture_paths(target.fixture_paths(), args.fixture.as_deref())?; let check_outcome = target.check(&evidence_bin); let check_passed = check_outcome.passed; @@ -140,13 +145,18 @@ fn run_fixtures(args: RunArgs) -> Result { let mut fixtures = Vec::new(); if check_passed { for fixture_path in fixture_paths { - let outcome = target.evaluate(&evidence_bin, fixture_path, args.explain); + let outcome = target.evaluate( + &evidence_bin, + fixture_path, + args.case.as_deref(), + args.explain, + ); fixtures.push(FixtureReport { path: fixture_path.to_owned(), passed: outcome.passed, stderr: outcome.stderr, evaluated_cases: outcome.evaluated_cases, - trace: args.explain.then_some(outcome.stdout), + trace: outcome.trace, }); } } @@ -181,6 +191,23 @@ fn run_fixtures(args: RunArgs) -> Result { }) } +/// Preserve the bundle's declared order for a full run, or select one exact +/// referenced path. The rejected value is deliberately absent from the error: +/// fixture selectors are operator input and diagnostics stay value-free. +fn select_fixture_paths<'a>( + fixture_paths: &'a [String], + selected: Option<&str>, +) -> Result> { + match selected { + None => Ok(fixture_paths.iter().map(String::as_str).collect()), + Some(selected) => fixture_paths + .iter() + .find(|fixture| fixture.as_str() == selected) + .map(|fixture| vec![fixture.as_str()]) + .ok_or_else(|| anyhow!("selected fixture is not referenced by the project")), + } +} + /// The two project shapes adopters work with. Deployment projects carry a /// runtime binding; editable projects compile to a private bundle and use the /// runtime's bundle-only fixture seam. @@ -219,19 +246,31 @@ impl FixtureTarget { } } - fn evaluate(&self, evidence_bin: &Path, fixture: &str, explain: bool) -> StepOutcome { + fn evaluate( + &self, + evidence_bin: &Path, + fixture: &str, + case: Option<&str>, + explain: bool, + ) -> StepOutcome { match self { Self::Deployment { runtime_path, .. } => { let mut args = vec!["evaluate", "--fixture", fixture]; + if let Some(case) = case { + args.extend(["--case", case]); + } if explain { - args.push("--explain"); + args.extend(["--explain", "--explain-format", "json"]); } run_evidence_step(evidence_bin, &["--runtime"], Some(runtime_path), &args) } Self::Editable { compilation, .. } => { let mut args = vec!["--fixture", fixture]; + if let Some(case) = case { + args.extend(["--case", case]); + } if explain { - args.push("--explain"); + args.extend(["--explain", "--explain-format", "json"]); } run_evidence_step( evidence_bin, @@ -350,28 +389,51 @@ fn run_evidence_step( match command.output() { Ok(output) if output.status.success() => { let stdout = String::from_utf8_lossy(&output.stdout).into_owned(); + let trace = structured_trace(&stdout); StepOutcome { passed: true, - evaluated_cases: evaluated_cases(&stdout), - stdout, + evaluated_cases: structured_evaluated_cases(trace.as_ref()) + .or_else(|| evaluated_cases(&stdout)), stderr: None, + trace, + } + } + Ok(output) => { + let stdout = String::from_utf8_lossy(&output.stdout).into_owned(); + let trace = structured_trace(&stdout); + StepOutcome { + passed: false, + evaluated_cases: structured_evaluated_cases(trace.as_ref()) + .or_else(|| evaluated_cases(&stdout)), + trace, + stderr: Some(String::from_utf8_lossy(&output.stderr).into_owned()), } } - Ok(output) => StepOutcome { - passed: false, - stdout: String::from_utf8_lossy(&output.stdout).into_owned(), - stderr: Some(String::from_utf8_lossy(&output.stderr).into_owned()), - evaluated_cases: None, - }, Err(error) => StepOutcome { passed: false, - stdout: String::new(), stderr: Some(format!("failed to run {}: {error}", evidence_bin.display())), evaluated_cases: None, + trace: None, }, } } +fn structured_evaluated_cases(trace: Option<&JsonValue>) -> Option { + trace + .and_then(|trace| trace.get("evaluatedCases")) + .and_then(JsonValue::as_u64) + .and_then(|count| usize::try_from(count).ok()) +} + +fn structured_trace(stdout: &str) -> Option { + serde_json::from_str(stdout.trim()) + .ok() + .filter(|value: &JsonValue| { + value.get("passed").is_some_and(JsonValue::is_boolean) + && value.get("cases").is_some_and(JsonValue::is_array) + }) +} + /// Read the case count out of `Evidence fixture passed (N evaluated cases)`. /// /// This driver makes no semantic decision, so the count is `evidence`'s own @@ -405,8 +467,13 @@ fn print_diagnostics(report: &RunReport, to_stderr: bool) { lines.push(line); // The trace comes before the diagnostic, the order `evidence` itself // prints them in: how far the run got, then what stopped it. - if let Some(trace) = fixture.trace.as_deref() { - lines.extend(indented(Some(trace))); + if let Some(trace) = &fixture.trace { + // The trace was parsed out of `evidence` standard output, so it is + // already a valid document; rendering it back cannot fail. An empty + // default here would read as "no trace", which is a different fact. + let rendered = serde_json::to_string_pretty(trace) + .expect("a trace parsed from JSON renders back to JSON"); + lines.extend(indented(Some(&rendered))); } if !fixture.passed { lines.extend(indented(fixture.stderr.as_deref())); diff --git a/crates/registry-evidencectl/tests/fixtures.rs b/crates/registry-evidencectl/tests/fixtures.rs index 38b3cedb5..1324453a3 100644 --- a/crates/registry-evidencectl/tests/fixtures.rs +++ b/crates/registry-evidencectl/tests/fixtures.rs @@ -60,12 +60,16 @@ printf '===\n' >> "$ARGV_LOG" fixture="" prev="" +explain_json="false" for arg in "$@"; do if [ "$prev" = "--fixture" ]; then fixture="$arg" fi prev="$arg" done +case " $* " in + *" --explain-format json "*) explain_json="true" ;; +esac step="check" for arg in "$@"; do @@ -82,6 +86,11 @@ if [ "$step" = "${FAIL_STEP:-}" ]; then exit 1 fi +if [ "$explain_json" = "true" ]; then + printf '{"passed":true,"evaluatedCases":%s,"cases":[]}\n' "${CASES:-0}" + exit 0 +fi + printf 'stub ok for %s\n' "$step" if [ -n "$fixture" ] && [ -n "${CASES:-}" ]; then printf 'Evidence fixture passed (%s evaluated cases)\n' "$CASES" @@ -155,6 +164,89 @@ fn happy_path_runs_check_then_each_fixture_and_reports_pass() { ); } +#[test] +fn fixture_selection_runs_only_one_exact_referenced_fixture() { + let dir = tempfile::tempdir().expect("tempdir"); + let project = write_project(dir.path(), &["fixtures/a.yaml", "fixtures/ab.yaml"]); + let stub = write_stub_evidence(dir.path()); + let argv_log = dir.path().join("argv.log"); + + let output = evidencectl() + .args(["fixtures", "run", "--project"]) + .arg(&project) + .args(["--fixture", "fixtures/a.yaml"]) + .args(["--case", "positive"]) + .arg("--evidence-bin") + .arg(&stub) + .arg("--json") + .env("ARGV_LOG", &argv_log) + .env("CASES", "3") + .env_remove("FAIL_STEP") + .output() + .expect("run selected fixture"); + + assert!(output.status.success(), "{}", stderr_of(&output)); + let report: serde_json::Value = + serde_json::from_str(stdout_of(&output).trim()).expect("parse JSON report"); + assert_eq!(report["passed"], serde_json::Value::Bool(true)); + assert_eq!(report["evaluated_cases"], serde_json::json!(3)); + let fixtures = report["fixtures"].as_array().expect("fixtures array"); + assert_eq!(fixtures.len(), 1); + assert_eq!(fixtures[0]["path"], "fixtures/a.yaml"); + + let runtime_path = project.join("runtime.yaml"); + let runtime_path = runtime_path.to_str().expect("runtime path is utf8"); + assert_eq!( + read_argv_log(&argv_log), + vec![ + vec!["--runtime", runtime_path, "check"], + vec![ + "--runtime", + runtime_path, + "evaluate", + "--fixture", + "fixtures/a.yaml", + "--case", + "positive", + ], + ] + ); +} + +#[test] +fn fixture_selection_refuses_non_exact_names_without_rendering_them() { + let dir = tempfile::tempdir().expect("tempdir"); + let project = write_project(dir.path(), &["fixtures/a.yaml"]); + let stub = write_stub_evidence(dir.path()); + let argv_log = dir.path().join("argv.log"); + let unreferenced = "fixtures/a.yaml-private-canary"; + + let output = evidencectl() + .args(["fixtures", "run", "--project"]) + .arg(&project) + .args(["--fixture", unreferenced]) + .arg("--evidence-bin") + .arg(&stub) + .arg("--json") + .env("ARGV_LOG", &argv_log) + .output() + .expect("refuse unreferenced fixture"); + + assert!(!output.status.success()); + let stdout = stdout_of(&output); + let stderr = stderr_of(&output); + assert!(stdout.is_empty(), "unexpected report: {stdout}"); + assert!( + stderr.contains("selected fixture is not referenced by the project"), + "{stderr}" + ); + assert!(!stderr.contains(unreferenced), "selector leaked: {stderr}"); + assert!( + read_argv_log(&argv_log).is_empty(), + "an invalid selection must not reach Evidence" + ); +} + #[test] fn editable_sqlite_starter_compiles_and_runs_through_bundle_only_seams() { let dir = tempfile::tempdir().expect("tempdir"); @@ -449,7 +541,7 @@ fn explain_is_asked_of_every_evaluation_and_the_trace_is_relayed() { assert!(output.status.success(), "{}", stderr_of(&output)); let stdout = stdout_of(&output); assert!( - stdout.contains("stub ok for evaluate:fixtures/a.yaml"), + stdout.contains("\"cases\": []"), "the trace never reached the operator: {stdout}" ); // Relaying the trace must not cost the count, which is read from the @@ -472,7 +564,9 @@ fn explain_is_asked_of_every_evaluation_and_the_trace_is_relayed() { "evaluate", "--fixture", "fixtures/a.yaml", - "--explain" + "--explain", + "--explain-format", + "json" ], vec![ "--runtime", @@ -480,7 +574,9 @@ fn explain_is_asked_of_every_evaluation_and_the_trace_is_relayed() { "evaluate", "--fixture", "fixtures/b.yaml", - "--explain" + "--explain", + "--explain-format", + "json" ], ], "unexpected evidence invocations" @@ -560,10 +656,7 @@ fn an_explained_json_run_carries_each_trace_in_its_report() { serde_json::from_str(stdout_lines[0]).expect("parse JSON report"); let fixtures = report["fixtures"].as_array().expect("fixtures array"); assert!( - fixtures[0]["trace"] - .as_str() - .expect("an explained fixture carries its trace") - .contains("stub ok for evaluate:fixtures/a.yaml"), + fixtures[0]["trace"]["cases"] == serde_json::json!([]), "{}", fixtures[0] ); diff --git a/docs/site/src/content/docs/reference/cli/evidence-oid4vci.mdx b/docs/site/src/content/docs/reference/cli/evidence-oid4vci.mdx index 4786f076b..0537147a0 100644 --- a/docs/site/src/content/docs/reference/cli/evidence-oid4vci.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence-oid4vci.mdx @@ -18,7 +18,7 @@ Registry Stack wallet delivery front end for Evidence credentials. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/check.mdx b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/check.mdx index e8c574bb0..be357d836 100644 --- a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/check.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/check.mdx @@ -18,7 +18,7 @@ Load and validate the configuration and the client key, then exit. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/inspect.mdx b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/inspect.mdx index 5777e06f5..d1638c132 100644 --- a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/inspect.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/inspect.mdx @@ -18,7 +18,7 @@ Validate the deployment and print its derived protocol metadata. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/openapi.mdx b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/openapi.mdx index c60f18caa..056b1b816 100644 --- a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/openapi.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/openapi.mdx @@ -18,7 +18,7 @@ Render the deterministic OpenAPI 3.1 contract, then exit. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/serve.mdx b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/serve.mdx index cc0f5983f..345ae04a2 100644 --- a/docs/site/src/content/docs/reference/cli/evidence-oid4vci/serve.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence-oid4vci/serve.mdx @@ -18,7 +18,7 @@ Serve the delivery endpoints until terminated. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence.mdx b/docs/site/src/content/docs/reference/cli/evidence.mdx index 1a577120b..6e1e13b1f 100644 --- a/docs/site/src/content/docs/reference/cli/evidence.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence.mdx @@ -18,7 +18,7 @@ Evidence Gateway Version 1. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence/check.mdx b/docs/site/src/content/docs/reference/cli/evidence/check.mdx index 270775be9..38fb96529 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/check.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/check.mdx @@ -18,7 +18,7 @@ Validate and compile the complete immutable bundle, and validate the mounted sec ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence/evaluate.mdx b/docs/site/src/content/docs/reference/cli/evidence/evaluate.mdx index f0f7359aa..bfe825e83 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/evaluate.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/evaluate.mdx @@ -18,7 +18,7 @@ Evaluate one bundle-owned fixture without source or credential access. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage @@ -37,6 +37,7 @@ evidence evaluate [OPTIONS] --fixture | Option | Always required | Default | Values | Environment | Description | | --- | --- | --- | --- | --- | --- | | `--fixture ` | Yes | n/a | n/a | n/a | Bundle-relative fixture path referenced by exactly one requirement | +| `--case ` | No | n/a | n/a | n/a | Evaluate only the case with this exact identifier | | `--explain` | No | n/a | n/a | n/a | Print the per-stage trace of what each case actually did. A failure names the contract that broke and nothing else, which says that a case failed but never why. The trace says how far each case got, what shape the response and facts had, and which declared concept the output gate was checking. It reports shapes, counts, and identifiers, never document values, and it never changes an outcome, an exit code, or a message. | | `--explain-format ` | No | n/a | `text`, `json` | n/a | Render the `--explain` trace for a machine reader instead of a person. The JSON form is the whole of standard output, so the summary line's verdict and evaluated-case count move inside the document rather than trailing it | | `--runtime ` | No | `/etc/registry-evidence/runtime.yaml` | n/a | `REGISTRY_EVIDENCE_RUNTIME` | One closed operator runtime file that binds the governed bundle | diff --git a/docs/site/src/content/docs/reference/cli/evidence/serve.mdx b/docs/site/src/content/docs/reference/cli/evidence/serve.mdx index 22842472e..01073ad5c 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/serve.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/serve.mdx @@ -18,7 +18,7 @@ Start the native Evidence Gateway HTTP service. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidence/verify-audit.mdx b/docs/site/src/content/docs/reference/cli/evidence/verify-audit.mdx index 3526ce8f3..6e0ff384b 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/verify-audit.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/verify-audit.mdx @@ -18,7 +18,7 @@ Run a full out-of-band verification pass over the audit chain. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Description diff --git a/docs/site/src/content/docs/reference/cli/evidence/verify-presentation.mdx b/docs/site/src/content/docs/reference/cli/evidence/verify-presentation.mdx index caf524b45..4127c54cc 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/verify-presentation.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/verify-presentation.mdx @@ -18,7 +18,7 @@ Re-verify one stored holder-bound presentation offline against a pinned key set. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Description diff --git a/docs/site/src/content/docs/reference/cli/evidence/verify.mdx b/docs/site/src/content/docs/reference/cli/evidence/verify.mdx index 3c9749001..5c1d3f93f 100644 --- a/docs/site/src/content/docs/reference/cli/evidence/verify.mdx +++ b/docs/site/src/content/docs/reference/cli/evidence/verify.mdx @@ -18,7 +18,7 @@ Re-verify one stored signed response offline against a pinned key set. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Description diff --git a/docs/site/src/content/docs/reference/cli/evidencectl.mdx b/docs/site/src/content/docs/reference/cli/evidencectl.mdx index 217a39a83..65807337b 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl.mdx @@ -18,7 +18,7 @@ Evidence adopter tooling: keys, source authoring, fixture runs. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access.mdx index 3db7e2b85..c5c252748 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access.mdx @@ -18,7 +18,7 @@ Manage local caller access policies and clients. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/client.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/client.mdx index d88a59c39..7b94c4986 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/client.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/client.mdx @@ -18,7 +18,7 @@ Register and revoke local Evidence Gateway clients. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/add.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/add.mdx index 1e1a81cae..1a91247c3 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/add.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/add.mdx @@ -18,7 +18,7 @@ Add one local client and generate its private key. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/list.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/list.mdx index 26fcddb17..9d8aafdc0 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/list.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/list.mdx @@ -18,7 +18,7 @@ List local clients and their policy membership. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/revoke.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/revoke.mdx index 1d4f09556..853be3b6e 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/client/revoke.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/client/revoke.mdx @@ -18,7 +18,7 @@ Revoke one local client. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy.mdx index 66cd56938..0f7d7c5fa 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy.mdx @@ -18,7 +18,7 @@ Define which authored questions a policy may request. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/add.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/add.mdx index f6c68e782..e13e790db 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/add.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/add.mdx @@ -18,7 +18,7 @@ Add one governed access policy. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/list.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/list.mdx index 9b40da790..fcb8a5531 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/list.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/access/policy/list.mdx @@ -18,7 +18,7 @@ List governed access policies. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/audit.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/audit.mdx index 1efa03ef6..a4c9ca6d1 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/audit.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/audit.mdx @@ -18,7 +18,7 @@ Inspect stopped local audit history. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/audit/show.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/audit/show.mdx index c779da8b3..86241b612 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/audit/show.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/audit/show.mdx @@ -18,7 +18,7 @@ Show a minimized view of stopped local audit history. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/build.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/build.mdx index 7dc48c7c2..521ca209c 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/build.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/build.mdx @@ -18,7 +18,7 @@ Compile an editable project into a reviewed deployment candidate. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/client.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/client.mdx index 748b7470f..98f116e0f 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/client.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/client.mdx @@ -18,7 +18,7 @@ Configure progressive relying-party clients and fetch contract candidates. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts.mdx index 8d32028eb..0bdb7e3f4 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts.mdx @@ -18,7 +18,7 @@ Fetch requester-scoped contract candidates for review. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts/fetch.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts/fetch.mdx index 713ceea06..253131d1d 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts/fetch.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/client/contracts/fetch.mdx @@ -18,7 +18,7 @@ Fetch a closed requester-scoped contract candidate. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/client/profile.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/client/profile.mdx index 6d003b336..55a6c030f 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/client/profile.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/client/profile.mdx @@ -18,7 +18,7 @@ Create and inspect relying-party client profiles. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/client/profile/create.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/client/profile/create.mdx index bb7d5f35f..f9437b832 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/client/profile/create.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/client/profile/create.mdx @@ -18,7 +18,7 @@ Create a strict profile containing only references to local key material. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/dev.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/dev.mdx index 41857c5de..165680227 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/dev.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/dev.mdx @@ -18,7 +18,7 @@ Run the private local Registry Mint and Evidence Gateway pair. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/dev/clean.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/dev/clean.mdx index 5c8e903a6..279a55371 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/dev/clean.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/dev/clean.mdx @@ -18,7 +18,7 @@ Remove one completed stopped local generation. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/dev/stop.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/dev/stop.mdx index 5a4177fe0..27d5af63f 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/dev/stop.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/dev/stop.mdx @@ -18,7 +18,7 @@ Stop the active local Registry Mint and Evidence Gateway pair. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/doctor.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/doctor.mdx index 5677b7e9f..645f08c6f 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/doctor.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/doctor.mdx @@ -18,7 +18,7 @@ Report every project artifact whose mode or owner the runtime refuses. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/fixtures.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/fixtures.mdx index fe75c0f53..688142df5 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/fixtures.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/fixtures.mdx @@ -18,7 +18,7 @@ Drive the evidence binary across a project's bundle fixtures. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/fixtures/run.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/fixtures/run.mdx index 6a38422ca..27b53f75d 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/fixtures/run.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/fixtures/run.mdx @@ -18,7 +18,7 @@ Run `evidence check` and every bundle fixture through `evidence evaluate`. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage @@ -26,15 +26,23 @@ This page is generated from the public Clap command tree for Registry Stack sour evidencectl fixtures run [OPTIONS] --project ``` +## Constraints + +| Condition | Requirement | +| --- | --- | +| `--case ` is present | `--fixture ` is required. | + ## Options | Option | Always required | Default | Values | Environment | Description | | --- | --- | --- | --- | --- | --- | | `--project ` | Yes | n/a | n/a | n/a | Deployment project directory containing runtime.yaml and bundle/ | | `--evidence-bin ` | No | n/a | n/a | n/a | Path to the evidence binary; defaults to `evidence` on PATH | +| `--fixture ` | No | n/a | n/a | n/a | Run only the exact bundle-relative fixture path named here | +| `--case ` | No | n/a | n/a | n/a | Run only the exact case identifier in the selected fixture | | `--json` | No | n/a | n/a | n/a | Emit one machine-readable JSON report on standard output | -| `--explain` | No | n/a | n/a | n/a | Ask `evidence` to explain each evaluation, and relay the trace it prints. The trace can name what a source returned, so it is relayed only when it is asked for. For the structured form, run `evidence evaluate --explain --explain-format json` against the fixture directly. | -| `-h, --help` | No | n/a | n/a | n/a | Print help (see a summary with '-h') | +| `--explain` | No | n/a | n/a | n/a | Ask `evidence` for each structured value-free evaluation diagnostic and relay it without interpreting Evidence semantics | +| `-h, --help` | No | n/a | n/a | n/a | Print help | ## Generation contract diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/jwks.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/jwks.mdx index 21878069e..7d75de842 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/jwks.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/jwks.mdx @@ -18,7 +18,7 @@ Assemble a public JWKS document from public JWK files. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen.mdx index 7d4e587c8..e70868701 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen.mdx @@ -18,7 +18,7 @@ Generate Evidence Gateway deployment key material as owner-only files. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/client-assertion.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/client-assertion.mdx index c9500bafa..2d84a51d2 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/client-assertion.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/client-assertion.mdx @@ -18,7 +18,7 @@ Keypair a source's `clientAssertionKeyRef` points at, for a token endpoint that ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/holder.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/holder.mdx index f931c90fb..23f31966a 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/holder.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/holder.mdx @@ -18,7 +18,7 @@ P-256 ES256 holder keypair for SD-JWT VC confirmation binding. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/secret.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/secret.mdx index 64161de06..9828018b2 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/secret.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/secret.mdx @@ -18,7 +18,7 @@ One random raw secret file, 32 bytes (audit or subject-binding HMAC). ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Description diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/signing.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/signing.mdx index c3dbe3514..4f89c95d0 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/signing.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/signing.mdx @@ -18,7 +18,7 @@ P-256 ES256 signing keypair as private and public JWK files. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/token.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/token.mdx index ca3e886b6..ca2bca0d2 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/keygen/token.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/keygen/token.mdx @@ -18,7 +18,7 @@ One random bearer token file, printable and header-safe. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/new.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/new.mdx index e7a7e1b39..4d5b4ed45 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/new.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/new.mdx @@ -18,7 +18,7 @@ Start an editable Evidence Gateway project from OpenAPI or a SQLite extract. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/request.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/request.mdx index f4f082fc4..e14c8b12e 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/request.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/request.mdx @@ -18,7 +18,7 @@ Prepare a closed request for the active local project. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/request/prepare.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/request/prepare.mdx index 0e86f456f..57d416ac2 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/request/prepare.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/request/prepare.mdx @@ -18,7 +18,7 @@ Prepare the request, authorization header, and verification context. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/request/verify.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/request/verify.mdx index 8f1a00c3b..f22c3080d 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/request/verify.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/request/verify.mdx @@ -18,7 +18,7 @@ Verify one retained Evidence Gateway response offline. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source.mdx index d88a64dc5..55adfa1bb 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source.mdx @@ -18,7 +18,7 @@ Work with a project's sources, starting from their own API documents. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock.mdx index 54a2892f0..868e0d110 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock.mdx @@ -18,7 +18,7 @@ Generate, inspect, and serve a local synthetic source API. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/check.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/check.mdx index 7e3297040..23c75a344 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/check.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/check.mdx @@ -18,7 +18,7 @@ Validate edited configuration and response bodies without writing or binding. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/generate.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/generate.mdx index f950c8078..cc6c269ab 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/generate.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/generate.mdx @@ -18,7 +18,7 @@ Materialize or extend editable mock cases from OpenAPI. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/serve.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/serve.mdx index 05bc794a2..fd502fe38 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/serve.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source/mock/serve.mdx @@ -18,7 +18,7 @@ Serve schema-valid synthetic responses from OpenAPI or exact edited cases. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/source/suggest.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/source/suggest.mdx index 6b13d2a81..6f7ac7f13 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/source/suggest.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/source/suggest.mdx @@ -18,7 +18,7 @@ Suggest source configuration from an OpenAPI document. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/tooling.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/tooling.mdx index e69c356ff..778a5a817 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/tooling.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/tooling.mdx @@ -18,7 +18,7 @@ Advanced: editor and tooling integration surfaces. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/tooling/editor.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/tooling/editor.mdx index 6774d6686..859f4772c 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/tooling/editor.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/tooling/editor.mdx @@ -18,7 +18,7 @@ Write project-local schema mappings for a YAML-aware editor. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/tooling/language-server.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/tooling/language-server.mdx index 16d1b871b..f0a21488b 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/tooling/language-server.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/tooling/language-server.mdx @@ -18,7 +18,7 @@ Run cross-file navigation over the Language Server Protocol. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/evidencectl/verify.mdx b/docs/site/src/content/docs/reference/cli/evidencectl/verify.mdx index 5e017f63a..8ab0a27e8 100644 --- a/docs/site/src/content/docs/reference/cli/evidencectl/verify.mdx +++ b/docs/site/src/content/docs/reference/cli/evidencectl/verify.mdx @@ -18,7 +18,7 @@ Verify one retained Evidence Gateway response offline. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/index.mdx b/docs/site/src/content/docs/reference/cli/index.mdx index 2aed4dab4..429c771a5 100644 --- a/docs/site/src/content/docs/reference/cli/index.mdx +++ b/docs/site/src/content/docs/reference/cli/index.mdx @@ -18,7 +18,7 @@ Use these generated references for exact command syntax, arguments, options, def ## Contract status -The pages in this section are generated from the public Clap command trees for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +The pages in this section are generated from the public Clap command trees for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Registry Relay diff --git a/docs/site/src/content/docs/reference/cli/mint.mdx b/docs/site/src/content/docs/reference/cli/mint.mdx index ac8a6e1af..7c53cea33 100644 --- a/docs/site/src/content/docs/reference/cli/mint.mdx +++ b/docs/site/src/content/docs/reference/cli/mint.mdx @@ -18,7 +18,7 @@ Registry Stack token issuer. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/check.mdx b/docs/site/src/content/docs/reference/cli/mint/check.mdx index ca96e8ff7..db4e3429b 100644 --- a/docs/site/src/content/docs/reference/cli/mint/check.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/check.mdx @@ -18,7 +18,7 @@ Load the configuration, keys, audit chain, and client registry, then exit. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/client-secret.mdx b/docs/site/src/content/docs/reference/cli/mint/client-secret.mdx index 031b750ce..a183c7f78 100644 --- a/docs/site/src/content/docs/reference/cli/mint/client-secret.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/client-secret.mdx @@ -18,7 +18,7 @@ Provision high-entropy credentials for compatible managed clients. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/client-secret/generate.mdx b/docs/site/src/content/docs/reference/cli/mint/client-secret/generate.mdx index a93427610..2ab485d01 100644 --- a/docs/site/src/content/docs/reference/cli/mint/client-secret/generate.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/client-secret/generate.mdx @@ -18,7 +18,7 @@ Generate one credential file and print its non-secret fingerprint. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/healthcheck.mdx b/docs/site/src/content/docs/reference/cli/mint/healthcheck.mdx index 749abd070..0ce078aa1 100644 --- a/docs/site/src/content/docs/reference/cli/mint/healthcheck.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/healthcheck.mdx @@ -18,7 +18,7 @@ Probe a numeric private readiness endpoint without ambient proxy use. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/serve.mdx b/docs/site/src/content/docs/reference/cli/mint/serve.mdx index e12960cdb..5c8484731 100644 --- a/docs/site/src/content/docs/reference/cli/mint/serve.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/serve.mdx @@ -18,7 +18,7 @@ Serve the token endpoint until terminated. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/mint/token.mdx b/docs/site/src/content/docs/reference/cli/mint/token.mdx index fe0bac532..43f64c6d6 100644 --- a/docs/site/src/content/docs/reference/cli/mint/token.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/token.mdx @@ -18,7 +18,7 @@ Obtain an access token from a running token endpoint, as a client would. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Description diff --git a/docs/site/src/content/docs/reference/cli/mint/verify-audit.mdx b/docs/site/src/content/docs/reference/cli/mint/verify-audit.mdx index 142e8647d..72b6d11e5 100644 --- a/docs/site/src/content/docs/reference/cli/mint/verify-audit.mdx +++ b/docs/site/src/content/docs/reference/cli/mint/verify-audit.mdx @@ -18,7 +18,7 @@ Verify the retained keyed Mint audit chain named by the configuration. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relay.mdx b/docs/site/src/content/docs/reference/cli/relay.mdx index fc339ffe2..f59b59a63 100644 --- a/docs/site/src/content/docs/reference/cli/relay.mdx +++ b/docs/site/src/content/docs/reference/cli/relay.mdx @@ -18,7 +18,7 @@ Compiled read-only Registry Relay runtime. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relay/check.mdx b/docs/site/src/content/docs/reference/cli/relay/check.mdx index 1db2cba29..1c93618e6 100644 --- a/docs/site/src/content/docs/reference/cli/relay/check.mdx +++ b/docs/site/src/content/docs/reference/cli/relay/check.mdx @@ -18,7 +18,7 @@ Validate the sealed package and every deployment dependency without taking the l ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relay/healthcheck.mdx b/docs/site/src/content/docs/reference/cli/relay/healthcheck.mdx index 38cebe328..eedcec463 100644 --- a/docs/site/src/content/docs/reference/cli/relay/healthcheck.mdx +++ b/docs/site/src/content/docs/reference/cli/relay/healthcheck.mdx @@ -18,7 +18,7 @@ Probe an unauthenticated Relay liveness endpoint. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relay/serve.mdx b/docs/site/src/content/docs/reference/cli/relay/serve.mdx index 7ecab1a5e..27bebc2c3 100644 --- a/docs/site/src/content/docs/reference/cli/relay/serve.mdx +++ b/docs/site/src/content/docs/reference/cli/relay/serve.mdx @@ -18,7 +18,7 @@ Verify and activate one sealed Registry package, then serve it. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl.mdx b/docs/site/src/content/docs/reference/cli/relayctl.mdx index 3334dcb36..2147b7cc0 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl.mdx @@ -18,7 +18,7 @@ Relay V2 project authoring, validation, and packaging. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/check.mdx b/docs/site/src/content/docs/reference/cli/relayctl/check.mdx index c22ed9f13..18b574723 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/check.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/check.mdx @@ -18,7 +18,7 @@ Compile and validate an authoring project. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/diff.mdx b/docs/site/src/content/docs/reference/cli/relayctl/diff.mdx index 2579eb3a4..419d2b9d8 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/diff.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/diff.mdx @@ -18,7 +18,7 @@ Classify meaning, disclosure, and security changes between projects. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/generate.mdx b/docs/site/src/content/docs/reference/cli/relayctl/generate.mdx index 782ed195f..b78cfc8fe 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/generate.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/generate.mdx @@ -18,7 +18,7 @@ Generate deterministic artifacts from the compiled project. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/init.mdx b/docs/site/src/content/docs/reference/cli/relayctl/init.mdx index 3dc766f27..3ac893546 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/init.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/init.mdx @@ -18,7 +18,7 @@ Initialize a complete authoring project with unreviewed starters. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/inspect.mdx b/docs/site/src/content/docs/reference/cli/relayctl/inspect.mdx index b5f921949..f32dde934 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/inspect.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/inspect.mdx @@ -18,7 +18,7 @@ Inspect SQLite structure without reading row values. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/package.mdx b/docs/site/src/content/docs/reference/cli/relayctl/package.mdx index 995868595..503fec1e6 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/package.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/package.mdx @@ -18,7 +18,7 @@ Build a deterministic sealed deployment package. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/test.mdx b/docs/site/src/content/docs/reference/cli/relayctl/test.mdx index 40c5b4cc5..3e6a6411f 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/test.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/test.mdx @@ -18,7 +18,7 @@ Run the project's offline fixture cases through the shared kernel. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/tooling.mdx b/docs/site/src/content/docs/reference/cli/relayctl/tooling.mdx index fd6551b13..8ca157fee 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/tooling.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/tooling.mdx @@ -18,7 +18,7 @@ Advanced editor and language-server integration surfaces. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/tooling/editor.mdx b/docs/site/src/content/docs/reference/cli/relayctl/tooling/editor.mdx index a3e2f30e2..5548d525d 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/tooling/editor.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/tooling/editor.mdx @@ -18,7 +18,7 @@ Write project-local schema mappings for VS Code and Zed. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/content/docs/reference/cli/relayctl/tooling/language-server.mdx b/docs/site/src/content/docs/reference/cli/relayctl/tooling/language-server.mdx index 71de74373..888047c59 100644 --- a/docs/site/src/content/docs/reference/cli/relayctl/tooling/language-server.mdx +++ b/docs/site/src/content/docs/reference/cli/relayctl/tooling/language-server.mdx @@ -18,7 +18,7 @@ Run Relay V2 authoring support over the Language Server Protocol. ## Contract status -This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `20feac3bc5b4f456c6d11ce0a6da4ff04a781a4faabb558b55a648c894774ff4`. Hidden implementation commands are omitted. +This page is generated from the public Clap command tree for Registry Stack source version `0.24.0` and catalog SHA-256 `603a0b0e6c8d110f8d37f9c6ac4725f2b4bec299c1a6eb018120c969ccd39392`. Hidden implementation commands are omitted. ## Usage diff --git a/docs/site/src/data/generated/cli-reference.json b/docs/site/src/data/generated/cli-reference.json index 758cb2abc..2664922fa 100644 --- a/docs/site/src/data/generated/cli-reference.json +++ b/docs/site/src/data/generated/cli-reference.json @@ -100,6 +100,15 @@ "possible_values": [], "environment": null }, + { + "display": "--case ", + "description": "Evaluate only the case with this exact identifier", + "always_required": false, + "repeatable": false, + "default_values": [], + "possible_values": [], + "environment": null + }, { "display": "--explain", "description": "Print the per-stage trace of what each case actually did. A failure names the contract that broke and nothing else, which says that a case failed but never why. The trace says how far each case got, what shape the response and facts had, and which declared concept the output gate was checking. It reports shapes, counts, and identifiers, never document values, and it never changes an outcome, an exit code, or a message.", @@ -1507,6 +1516,24 @@ "possible_values": [], "environment": null }, + { + "display": "--fixture ", + "description": "Run only the exact bundle-relative fixture path named here", + "always_required": false, + "repeatable": false, + "default_values": [], + "possible_values": [], + "environment": null + }, + { + "display": "--case ", + "description": "Run only the exact case identifier in the selected fixture", + "always_required": false, + "repeatable": false, + "default_values": [], + "possible_values": [], + "environment": null + }, { "display": "--json", "description": "Emit one machine-readable JSON report on standard output", @@ -1518,7 +1545,7 @@ }, { "display": "--explain", - "description": "Ask `evidence` to explain each evaluation, and relay the trace it prints. The trace can name what a source returned, so it is relayed only when it is asked for. For the structured form, run `evidence evaluate --explain --explain-format json` against the fixture directly.", + "description": "Ask `evidence` for each structured value-free evaluation diagnostic and relay it without interpreting Evidence semantics", "always_required": false, "repeatable": false, "default_values": [], @@ -1527,7 +1554,7 @@ }, { "display": "-h, --help", - "description": "Print help (see a summary with '-h')", + "description": "Print help", "always_required": false, "repeatable": false, "default_values": [], @@ -1535,7 +1562,15 @@ "environment": null } ], - "constraints": [], + "constraints": [ + { + "kind": "requires_all", + "when": "--case ", + "arguments": [ + "--fixture " + ] + } + ], "subcommands": [] } ] diff --git a/products/evidence/reference/request-adapter/deployment-projects/FIXTURES.md b/products/evidence/reference/request-adapter/deployment-projects/FIXTURES.md index 9b765ee30..362afd8d3 100644 --- a/products/evidence/reference/request-adapter/deployment-projects/FIXTURES.md +++ b/products/evidence/reference/request-adapter/deployment-projects/FIXTURES.md @@ -435,6 +435,22 @@ summary line to strip, and the verdict and evaluated-case count that line carries move inside it as `passed` and `evaluatedCases`. The exit code and the operator message on standard error are the same in both forms. +Each case can also carry a closed expected-versus-observed diagnosis. A result +has one of `match`, `no-match`, `ambiguous`, `evidence-unavailable`, +`source-unavailable`, `service-unavailable`, `bundle-refused`, or +`selector-refused`. A matched value is reduced to a bounded classification such +as `boolean-true`, `integer`, or `structured`. `reasonCode` says which closed +evaluator outcome produced the observation, and `findingCodes` says which +authored expectation disagreed. None of these fields carries a source, +selector, SQL, credential, or governed result value. + +For a controlled-category concept only, `categoryClasses` identifies an +allowed result by its zero-based concept position in the requirement and its +zero-based value position in that concept's captured governed codelist. The +field appears only after the output is proven to belong to that codelist. An +arbitrary string remains only the shape `string`; the trace never substitutes +raw category text or a concept identifier for an ordinal. + ```sh evidence --runtime "/runtime.yaml" \ evaluate --fixture "" --explain --explain-format json \ @@ -442,11 +458,11 @@ evidence --runtime "/runtime.yaml" \ ``` `evidencectl fixtures run --project --explain` asks the same of -every fixture a project references and relays each trace verbatim: under the -step line in the human report, and as that fixture's `trace` string under -`--json`. The driver asks for the text form only, because the case count it -totals is read from the summary line the structured form replaces. Run -`evidence evaluate` against one fixture directly for the document itself. +every fixture a project references using the JSON form. The human report +pretty-prints each value-free document under its step line; `--json` places the +same document at that fixture's `trace` field. The driver totals +`evaluatedCases` from those documents and does not interpret Evidence +semantics. A fixture's own `diagnosticsExclude` canaries are checked against both rendered forms of the trace on every run, including a run that stopped on an