commit de48b1a1168deb1fa722cb8fe2020e2032b21473
parent c381a89464838a475129a3174766ffc3b661b43f
Author: triesap <tyson@radroots.org>
Date: Wed, 1 Jul 2026 11:19:56 +0000
cli: surface validation receipt trust state
- carry worker validation authority and commitment confidence into CLI JSON
- separate local-only and SP1 execute evidence from production verification success
- render validation receipt terminal output with explicit trust labels
- align listing idempotency conflict tests with the current SDK error contract
Diffstat:
3 files changed, 432 insertions(+), 83 deletions(-)
diff --git a/src/out/terminal/renderers/validation.rs b/src/out/terminal/renderers/validation.rs
@@ -97,6 +97,8 @@ fn push_proof_fields(document: &mut TerminalDocument, result: &Value) {
};
common::push_field(document, "Proof", proof_state_label(proof));
common::push_path_field(document, "Proof system", proof, &["proof_system"]);
+ common::push_path_field(document, "Authority", proof, &["validation_authority"]);
+ common::push_path_field(document, "Confidence", proof, &["commitment_confidence"]);
common::push_bool_field(
document,
"Cryptographic proof",
@@ -171,6 +173,25 @@ fn push_relay_field(document: &mut TerminalDocument, result: &Value) {
}
fn proof_state_label(proof: &Value) -> String {
+ match common::string(proof, &["state"]).as_deref() {
+ Some("local_only_deterministic_receipt") => return "local-only deterministic".to_owned(),
+ Some("pending_rhi_validation") => return "pending RHI".to_owned(),
+ Some("trusted_service_validated") => return "trusted service".to_owned(),
+ Some("trusted_service_and_proof_verified") => return "trusted service + proof".to_owned(),
+ Some("sp1_inline_proof_verified") => return "cryptographic proof".to_owned(),
+ Some("cryptographic_proof_verified") => return "cryptographic proof".to_owned(),
+ Some("sp1_execute_checked") => return "SP1 execute checked".to_owned(),
+ Some("worker_evidence_trust_metadata_missing") => {
+ return "trust metadata missing".to_owned();
+ }
+ Some("worker_evidence_trust_metadata_mismatch") => {
+ return "trust metadata mismatch".to_owned();
+ }
+ Some("validation_receipt_worker_evidence_invalid") => {
+ return "worker evidence invalid".to_owned();
+ }
+ _ => {}
+ }
if common::bool_path(proof, &["cryptographic_proof_verified"]) == Some(true) {
return "verified".to_owned();
}
@@ -182,8 +203,16 @@ fn proof_state_label(proof: &Value) -> String {
fn proof_summary_from_summary(receipt: &Value) -> String {
match common::string(receipt, &["proof_verification_state"]).as_deref() {
- Some("deterministic_receipt_verified") => "not required".to_owned(),
- Some("sp1_execute_checked") => "not required".to_owned(),
+ Some("local_only_deterministic_receipt") => "local-only".to_owned(),
+ Some("pending_rhi_validation") => "pending RHI".to_owned(),
+ Some("trusted_service_validated") => "trusted service".to_owned(),
+ Some("trusted_service_and_proof_verified") => "trusted+proof".to_owned(),
+ Some("sp1_inline_proof_verified") => "proof verified".to_owned(),
+ Some("cryptographic_proof_verified") => "proof verified".to_owned(),
+ Some("sp1_execute_checked") => "execute checked".to_owned(),
+ Some("worker_evidence_trust_metadata_missing") => "trust missing".to_owned(),
+ Some("worker_evidence_trust_metadata_mismatch") => "trust mismatch".to_owned(),
+ Some("validation_receipt_worker_evidence_invalid") => "invalid".to_owned(),
Some(_) => "available".to_owned(),
None => String::new(),
}
@@ -260,4 +289,71 @@ mod tests {
assert!(rendered.contains("Proof unverified"));
assert!(!rendered.contains("Proof verified"));
}
+
+ #[test]
+ fn proof_output_renders_local_only_trust_state() {
+ let envelope = success_envelope(
+ "validation.receipt.verify",
+ json!({
+ "state": "invalid",
+ "receipt_event_id": "receipt_test",
+ "order_id": "trade_test",
+ "validation_state": "invalid",
+ "proof_verification": {
+ "state": "local_only_deterministic_receipt",
+ "proof_system": "none",
+ "validation_authority": "dev_deterministic_only",
+ "commitment_confidence": "local_only",
+ "production_verification": false,
+ "cryptographic_proof_required": false,
+ "cryptographic_proof_verified": false,
+ "verifier": "radroots_cli_validation_receipt_v1"
+ },
+ "actions": []
+ }),
+ );
+ let document = VALIDATION_RENDERER.render(&envelope, &TerminalRenderContext::default());
+ let rendered = render_terminal_document(&document, &TerminalRenderContext::default());
+
+ assert!(rendered.contains("Proof local-only deterministic"));
+ assert!(rendered.contains("Authority dev_deterministic_only"));
+ assert!(rendered.contains("Confidence local_only"));
+ assert!(!rendered.contains("Proof verified"));
+ }
+
+ #[test]
+ fn receipt_list_summarizes_trust_state() {
+ let envelope = success_envelope(
+ "validation.receipt.list",
+ json!({
+ "state": "listed",
+ "order_id": "trade_test",
+ "count": 2,
+ "valid_count": 2,
+ "invalid_count": 0,
+ "receipts": [
+ {
+ "receipt_event_id": "receipt_local",
+ "result": "valid",
+ "proof_verification_state": "local_only_deterministic_receipt",
+ "receipt_type": "trade_transition"
+ },
+ {
+ "receipt_event_id": "receipt_trusted",
+ "result": "valid",
+ "proof_verification_state": "trusted_service_validated",
+ "receipt_type": "trade_transition"
+ }
+ ],
+ "invalid_receipts": [],
+ "actions": []
+ }),
+ );
+ let document = VALIDATION_RENDERER.render(&envelope, &TerminalRenderContext::default());
+ let rendered = render_terminal_document(&document, &TerminalRenderContext::default());
+
+ assert!(rendered.contains("local-only"));
+ assert!(rendered.contains("trusted service"));
+ assert!(!rendered.contains("not required"));
+ }
}
diff --git a/src/runtime/validation_receipt.rs b/src/runtime/validation_receipt.rs
@@ -10,6 +10,7 @@ use radroots_sdk::{
use radroots_sp1_host_trade::RadrootsSp1TradeHostError;
use radroots_sp1_host_trade::verify_order_acceptance_validation_receipt_inline_sp1_proof;
use radroots_trade::validation_receipt::{
+ RadrootsTradeCommitmentConfidence, RadrootsTradeValidationAuthority,
RadrootsTradeValidationReceipt, RadrootsValidationReceiptProofSystem,
RadrootsValidationReceiptResult, RadrootsValidationReceiptType,
};
@@ -128,6 +129,9 @@ pub struct ValidationReceiptProofVerificationView {
pub state: String,
pub verifier: String,
pub proof_system: String,
+ pub validation_authority: Option<String>,
+ pub commitment_confidence: Option<String>,
+ pub production_verification: bool,
pub public_values_hash_binding: String,
pub proof_metadata_binding: String,
pub cryptographic_proof_required: bool,
@@ -147,6 +151,8 @@ pub struct ValidationReceiptProofVerificationView {
pub struct ValidationReceiptWorkerEvidenceView {
pub result_event_id: String,
pub author: String,
+ pub validation_authority: Option<String>,
+ pub commitment_confidence: Option<String>,
pub status: String,
pub prover_backend: String,
pub proof_mode: String,
@@ -175,6 +181,9 @@ pub struct ValidationReceiptSummaryView {
pub result: String,
pub proof_system: String,
pub proof_verification_state: String,
+ pub validation_authority: Option<String>,
+ pub commitment_confidence: Option<String>,
+ pub production_verification: bool,
pub event_set_root: String,
pub reducer_output_root: String,
pub public_values_hash: String,
@@ -390,7 +399,8 @@ fn inspected_event_view(
!proof_state_is_invalid(proof_verification.state.as_str())
}
ValidationReceiptCommandIntent::Verify => {
- proof_state_is_verification_success(proof_verification.state.as_str())
+ proof_verification.production_verification
+ && proof_state_is_verification_success(proof_verification.state.as_str())
}
};
if !accepted {
@@ -724,6 +734,167 @@ fn tags_view(tags: &TradeValidationReceiptTags) -> ValidationReceiptTagsView {
}
}
+struct ValidationReceiptTrustSummary {
+ state: &'static str,
+ validation_authority: Option<String>,
+ commitment_confidence: Option<String>,
+ production_verification: bool,
+ reason_code: Option<&'static str>,
+ reason: Option<&'static str>,
+}
+
+fn local_only_trust_summary() -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state: "local_only_deterministic_receipt",
+ validation_authority: Some(
+ RadrootsTradeValidationAuthority::DevDeterministicOnly
+ .as_str()
+ .to_owned(),
+ ),
+ commitment_confidence: Some(
+ RadrootsTradeCommitmentConfidence::LocalOnly
+ .as_str()
+ .to_owned(),
+ ),
+ production_verification: false,
+ reason_code: None,
+ reason: None,
+ }
+}
+
+fn sp1_execute_checked_trust_summary() -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state: "sp1_execute_checked",
+ validation_authority: None,
+ commitment_confidence: None,
+ production_verification: false,
+ reason_code: Some("validation_receipt_trust_metadata_missing"),
+ reason: Some(
+ "trusted worker evidence reports SP1 execution but omits validation authority or commitment confidence",
+ ),
+ }
+}
+
+fn missing_trust_metadata_summary() -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state: "worker_evidence_trust_metadata_missing",
+ validation_authority: None,
+ commitment_confidence: None,
+ production_verification: false,
+ reason_code: Some("validation_receipt_trust_metadata_missing"),
+ reason: Some("trusted worker evidence omits validation authority or commitment confidence"),
+ }
+}
+
+fn mismatched_trust_metadata_summary() -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state: "worker_evidence_trust_metadata_mismatch",
+ validation_authority: None,
+ commitment_confidence: None,
+ production_verification: false,
+ reason_code: Some("validation_receipt_trust_metadata_mismatch"),
+ reason: Some(
+ "trusted worker evidence validation authority does not match commitment confidence",
+ ),
+ }
+}
+
+fn invalid_worker_evidence_summary() -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state: "validation_receipt_worker_evidence_invalid",
+ validation_authority: None,
+ commitment_confidence: Some(
+ RadrootsTradeCommitmentConfidence::Invalid
+ .as_str()
+ .to_owned(),
+ ),
+ production_verification: false,
+ reason_code: Some("validation_receipt_worker_evidence_invalid"),
+ reason: Some("trusted worker evidence marks the validation receipt invalid"),
+ }
+}
+
+fn trusted_worker_summary(
+ state: &'static str,
+ authority: &str,
+ confidence: &str,
+ production_verification: bool,
+) -> ValidationReceiptTrustSummary {
+ ValidationReceiptTrustSummary {
+ state,
+ validation_authority: Some(authority.to_owned()),
+ commitment_confidence: Some(confidence.to_owned()),
+ production_verification,
+ reason_code: None,
+ reason: None,
+ }
+}
+
+fn none_proof_trust_summary(
+ worker_evidence: &ValidationReceiptWorkerEvidenceSelection,
+) -> ValidationReceiptTrustSummary {
+ let Some(evidence) = worker_evidence.trusted.as_ref() else {
+ return local_only_trust_summary();
+ };
+ let authority = evidence.validation_authority.as_deref();
+ let confidence = evidence.commitment_confidence.as_deref();
+ if authority.is_none() && confidence.is_none() {
+ return if evidence.sp1_execute_checked {
+ sp1_execute_checked_trust_summary()
+ } else {
+ local_only_trust_summary()
+ };
+ }
+ let (Some(authority), Some(confidence)) = (authority, confidence) else {
+ return missing_trust_metadata_summary();
+ };
+ match (authority, confidence) {
+ ("dev_deterministic_only", "local_only") => local_only_trust_summary(),
+ ("trusted_rhi_service_key", "pending_rhi") => {
+ trusted_worker_summary("pending_rhi_validation", authority, confidence, false)
+ }
+ ("trusted_rhi_service_key", "committed_by_trusted_service") => {
+ trusted_worker_summary("trusted_service_validated", authority, confidence, true)
+ }
+ ("cryptographic_proof_verified", "committed_by_cryptographic_proof") => {
+ trusted_worker_summary("cryptographic_proof_verified", authority, confidence, true)
+ }
+ ("trusted_service_and_proof_verified", "committed_by_trusted_service_and_proof") => {
+ trusted_worker_summary(
+ "trusted_service_and_proof_verified",
+ authority,
+ confidence,
+ true,
+ )
+ }
+ (_, "invalid") => invalid_worker_evidence_summary(),
+ _ => mismatched_trust_metadata_summary(),
+ }
+}
+
+fn verified_sp1_trust_summary(
+ worker_evidence: &ValidationReceiptWorkerEvidenceSelection,
+) -> ValidationReceiptTrustSummary {
+ if let Some(evidence) = worker_evidence.trusted.as_ref()
+ && evidence.validation_authority.as_deref() == Some("trusted_service_and_proof_verified")
+ && evidence.commitment_confidence.as_deref()
+ == Some("committed_by_trusted_service_and_proof")
+ {
+ return trusted_worker_summary(
+ "trusted_service_and_proof_verified",
+ "trusted_service_and_proof_verified",
+ "committed_by_trusted_service_and_proof",
+ true,
+ );
+ }
+ trusted_worker_summary(
+ "sp1_inline_proof_verified",
+ "cryptographic_proof_verified",
+ "committed_by_cryptographic_proof",
+ true,
+ )
+}
+
fn proof_verification_view_for_receipt(
receipt: &RadrootsTradeValidationReceipt,
worker_evidence: ValidationReceiptWorkerEvidenceSelection,
@@ -731,19 +902,14 @@ fn proof_verification_view_for_receipt(
let proof = &receipt.proof;
let cryptographic_proof_required = proof.system != RadrootsValidationReceiptProofSystem::None;
if proof.system == RadrootsValidationReceiptProofSystem::None {
- let state = if worker_evidence
- .trusted
- .as_ref()
- .is_some_and(|evidence| evidence.sp1_execute_checked)
- {
- "sp1_execute_checked"
- } else {
- "deterministic_receipt_verified"
- };
+ let trust = none_proof_trust_summary(&worker_evidence);
return ValidationReceiptProofVerificationView {
- state: state.to_owned(),
+ state: trust.state.to_owned(),
verifier: "radroots_cli_validation_receipt_v1".to_owned(),
proof_system: proof.system.as_str().to_owned(),
+ validation_authority: trust.validation_authority,
+ commitment_confidence: trust.commitment_confidence,
+ production_verification: trust.production_verification,
public_values_hash_binding: "verified".to_owned(),
proof_metadata_binding: "not_required".to_owned(),
cryptographic_proof_required,
@@ -755,8 +921,8 @@ fn proof_verification_view_for_receipt(
inline_proof_present: proof.inline_proof_base64.is_some(),
worker_evidence: worker_evidence.trusted,
untrusted_worker_evidence: worker_evidence.untrusted,
- reason_code: None,
- reason: None,
+ reason_code: trust.reason_code.map(str::to_owned),
+ reason: trust.reason.map(str::to_owned),
};
}
if proof.proof_reference.is_some() {
@@ -794,24 +960,30 @@ fn proof_verification_view_for_receipt(
}
match verify_inline_sp1_receipt(receipt) {
- Ok(()) => ValidationReceiptProofVerificationView {
- state: "sp1_inline_proof_verified".to_owned(),
- verifier: "radroots_cli_validation_receipt_v1".to_owned(),
- proof_system: proof.system.as_str().to_owned(),
- public_values_hash_binding: "verified".to_owned(),
- proof_metadata_binding: "verified".to_owned(),
- cryptographic_proof_required,
- cryptographic_proof_verified: true,
- mode: proof.mode.clone(),
- program_hash: proof.program_hash.clone(),
- verifying_key_hash: proof.verifying_key_hash.clone(),
- proof_reference: proof.proof_reference.clone(),
- inline_proof_present: proof.inline_proof_base64.is_some(),
- worker_evidence: worker_evidence.trusted,
- untrusted_worker_evidence: worker_evidence.untrusted,
- reason_code: None,
- reason: None,
- },
+ Ok(()) => {
+ let trust = verified_sp1_trust_summary(&worker_evidence);
+ ValidationReceiptProofVerificationView {
+ state: trust.state.to_owned(),
+ verifier: "radroots_cli_validation_receipt_v1".to_owned(),
+ proof_system: proof.system.as_str().to_owned(),
+ validation_authority: trust.validation_authority,
+ commitment_confidence: trust.commitment_confidence,
+ production_verification: trust.production_verification,
+ public_values_hash_binding: "verified".to_owned(),
+ proof_metadata_binding: "verified".to_owned(),
+ cryptographic_proof_required,
+ cryptographic_proof_verified: true,
+ mode: proof.mode.clone(),
+ program_hash: proof.program_hash.clone(),
+ verifying_key_hash: proof.verifying_key_hash.clone(),
+ proof_reference: proof.proof_reference.clone(),
+ inline_proof_present: proof.inline_proof_base64.is_some(),
+ worker_evidence: worker_evidence.trusted,
+ untrusted_worker_evidence: worker_evidence.untrusted,
+ reason_code: trust.reason_code.map(str::to_owned),
+ reason: trust.reason.map(str::to_owned),
+ }
+ }
Err(error) => {
let mapped = proof_state_from_sp1_error(&error);
let reason = error.to_string();
@@ -842,6 +1014,9 @@ fn sp1_unverified_proof_view(
state: state.to_owned(),
verifier: "radroots_cli_validation_receipt_v1".to_owned(),
proof_system: proof.system.as_str().to_owned(),
+ validation_authority: None,
+ commitment_confidence: None,
+ production_verification: false,
public_values_hash_binding: public_values_hash_binding.to_owned(),
proof_metadata_binding: proof_metadata_binding.to_owned(),
cryptographic_proof_required: proof.system != RadrootsValidationReceiptProofSystem::None,
@@ -987,13 +1162,18 @@ fn proof_state_is_invalid(state: &str) -> bool {
| "sp1_program_hash_mismatch"
| "sp1_verifying_key_hash_mismatch"
| "sp1_proof_invalid"
+ | "validation_receipt_worker_evidence_invalid"
+ | "worker_evidence_trust_metadata_mismatch"
)
}
fn proof_state_is_verification_success(state: &str) -> bool {
matches!(
state,
- "deterministic_receipt_verified" | "sp1_execute_checked" | "sp1_inline_proof_verified"
+ "trusted_service_validated"
+ | "cryptographic_proof_verified"
+ | "trusted_service_and_proof_verified"
+ | "sp1_inline_proof_verified"
)
}
@@ -1024,6 +1204,12 @@ fn worker_evidence_view(
ValidationReceiptWorkerEvidenceView {
result_event_id: evidence.result_event_id.as_str().to_owned(),
author: evidence.author.as_str().to_owned(),
+ validation_authority: evidence
+ .validation_authority
+ .map(|authority| authority.as_str().to_owned()),
+ commitment_confidence: evidence
+ .commitment_confidence
+ .map(|confidence| confidence.as_str().to_owned()),
status: evidence.status,
prover_backend: evidence.prover_backend,
proof_mode: evidence.proof_mode,
@@ -1085,6 +1271,9 @@ fn summary_view(
result: receipt_result_label(receipt.result).to_owned(),
proof_system: receipt.proof.system.as_str().to_owned(),
proof_verification_state: proof_verification.state.clone(),
+ validation_authority: proof_verification.validation_authority.clone(),
+ commitment_confidence: proof_verification.commitment_confidence.clone(),
+ production_verification: proof_verification.production_verification,
event_set_root: receipt.event_set_root.clone(),
reducer_output_root: receipt.new_state_root.clone(),
public_values_hash: receipt.public_values_hash.clone(),
@@ -1106,8 +1295,8 @@ fn receipt_result_label(value: RadrootsValidationReceiptResult) -> &'static str
mod tests {
use super::{
ValidationReceiptWorkerEvidenceSelection, ValidationReceiptWorkerEvidenceView,
- proof_state_from_sp1_error, proof_state_is_invalid, proof_verification_view_for_receipt,
- validation_receipt_invalid_reason_code,
+ proof_state_from_sp1_error, proof_state_is_invalid, proof_state_is_verification_success,
+ proof_verification_view_for_receipt, validation_receipt_invalid_reason_code,
};
use radroots_sp1_host_trade::RadrootsSp1TradeHostError;
use radroots_trade::validation_receipt::{
@@ -1173,14 +1362,45 @@ mod tests {
})
}
+ fn worker_evidence(
+ validation_authority: Option<&str>,
+ commitment_confidence: Option<&str>,
+ sp1_execute_checked: bool,
+ ) -> ValidationReceiptWorkerEvidenceView {
+ ValidationReceiptWorkerEvidenceView {
+ result_event_id: "result-1".to_owned(),
+ author: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_owned(),
+ validation_authority: validation_authority.map(str::to_owned),
+ commitment_confidence: commitment_confidence.map(str::to_owned),
+ status: "succeeded".to_owned(),
+ prover_backend: "local_execute".to_owned(),
+ proof_mode: "none".to_owned(),
+ proof_system: "none".to_owned(),
+ proof_generated: false,
+ sp1_execute_checked,
+ sp1_execute_public_values_hash: sp1_execute_checked.then(|| {
+ "0x5555555555555555555555555555555555555555555555555555555555555555".to_owned()
+ }),
+ cryptographic_proof_verified: false,
+ public_values_hash:
+ "0x5555555555555555555555555555555555555555555555555555555555555555".to_owned(),
+ }
+ }
+
#[test]
- fn none_receipts_report_deterministic_verification_without_crypto_claim() {
+ fn none_receipts_report_local_only_without_crypto_claim() {
let view = proof_verification_view_for_receipt(
&deterministic_receipt(),
ValidationReceiptWorkerEvidenceSelection::default(),
);
- assert_eq!(view.state, "deterministic_receipt_verified");
+ assert_eq!(view.state, "local_only_deterministic_receipt");
+ assert_eq!(
+ view.validation_authority.as_deref(),
+ Some("dev_deterministic_only")
+ );
+ assert_eq!(view.commitment_confidence.as_deref(), Some("local_only"));
+ assert!(!view.production_verification);
assert!(!view.cryptographic_proof_required);
assert!(!view.cryptographic_proof_verified);
}
@@ -1190,68 +1410,105 @@ mod tests {
let view = proof_verification_view_for_receipt(
&deterministic_receipt(),
ValidationReceiptWorkerEvidenceSelection {
- trusted: Some(ValidationReceiptWorkerEvidenceView {
- result_event_id: "result-1".to_owned(),
- author: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- .to_owned(),
- status: "succeeded".to_owned(),
- prover_backend: "local_execute".to_owned(),
- proof_mode: "none".to_owned(),
- proof_system: "none".to_owned(),
- proof_generated: false,
- sp1_execute_checked: true,
- sp1_execute_public_values_hash: Some(
- "0x5555555555555555555555555555555555555555555555555555555555555555"
- .to_owned(),
- ),
- cryptographic_proof_verified: false,
- public_values_hash:
- "0x5555555555555555555555555555555555555555555555555555555555555555"
- .to_owned(),
- }),
+ trusted: Some(worker_evidence(None, None, true)),
untrusted: None,
},
);
assert_eq!(view.state, "sp1_execute_checked");
+ assert_eq!(
+ view.reason_code.as_deref(),
+ Some("validation_receipt_trust_metadata_missing")
+ );
+ assert!(!view.production_verification);
assert!(!view.cryptographic_proof_required);
assert!(!view.cryptographic_proof_verified);
}
#[test]
+ fn none_receipts_surface_trusted_service_confidence_as_production_verification() {
+ let view = proof_verification_view_for_receipt(
+ &deterministic_receipt(),
+ ValidationReceiptWorkerEvidenceSelection {
+ trusted: Some(worker_evidence(
+ Some("trusted_rhi_service_key"),
+ Some("committed_by_trusted_service"),
+ false,
+ )),
+ untrusted: None,
+ },
+ );
+
+ assert_eq!(view.state, "trusted_service_validated");
+ assert_eq!(
+ view.validation_authority.as_deref(),
+ Some("trusted_rhi_service_key")
+ );
+ assert_eq!(
+ view.commitment_confidence.as_deref(),
+ Some("committed_by_trusted_service")
+ );
+ assert!(view.production_verification);
+ assert!(proof_state_is_verification_success(view.state.as_str()));
+ }
+
+ #[test]
+ fn invalid_worker_evidence_marks_receipt_invalid() {
+ let view = proof_verification_view_for_receipt(
+ &deterministic_receipt(),
+ ValidationReceiptWorkerEvidenceSelection {
+ trusted: Some(worker_evidence(
+ Some("trusted_rhi_service_key"),
+ Some("invalid"),
+ false,
+ )),
+ untrusted: None,
+ },
+ );
+
+ assert_eq!(view.state, "validation_receipt_worker_evidence_invalid");
+ assert!(proof_state_is_invalid(view.state.as_str()));
+ assert!(!view.production_verification);
+ }
+
+ #[test]
fn untrusted_worker_evidence_does_not_upgrade_deterministic_receipts() {
let view = proof_verification_view_for_receipt(
&deterministic_receipt(),
ValidationReceiptWorkerEvidenceSelection {
trusted: None,
- untrusted: Some(ValidationReceiptWorkerEvidenceView {
- result_event_id: "result-1".to_owned(),
- author: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- .to_owned(),
- status: "succeeded".to_owned(),
- prover_backend: "local_execute".to_owned(),
- proof_mode: "none".to_owned(),
- proof_system: "none".to_owned(),
- proof_generated: false,
- sp1_execute_checked: true,
- sp1_execute_public_values_hash: Some(
- "0x5555555555555555555555555555555555555555555555555555555555555555"
- .to_owned(),
- ),
- cryptographic_proof_verified: false,
- public_values_hash:
- "0x5555555555555555555555555555555555555555555555555555555555555555"
- .to_owned(),
- }),
+ untrusted: Some(worker_evidence(
+ Some("trusted_rhi_service_key"),
+ Some("committed_by_trusted_service"),
+ true,
+ )),
},
);
- assert_eq!(view.state, "deterministic_receipt_verified");
+ assert_eq!(view.state, "local_only_deterministic_receipt");
+ assert!(!view.production_verification);
assert!(view.worker_evidence.is_none());
assert!(view.untrusted_worker_evidence.is_some());
}
#[test]
+ fn production_verification_success_excludes_local_only_and_sp1_execute_checked() {
+ assert!(!proof_state_is_verification_success(
+ "local_only_deterministic_receipt"
+ ));
+ assert!(!proof_state_is_verification_success("sp1_execute_checked"));
+ assert!(proof_state_is_verification_success(
+ "trusted_service_validated"
+ ));
+ assert!(proof_state_is_verification_success(
+ "sp1_inline_proof_verified"
+ ));
+ assert!(proof_state_is_verification_success(
+ "trusted_service_and_proof_verified"
+ ));
+ }
+
+ #[test]
fn sp1_receipts_with_references_report_unresolved_without_crypto_claim() {
let mut receipt = receipt_with_proof(sp1_proof_with_material());
receipt.proof.inline_proof_base64 = None;
diff --git a/tests/target_cli.rs b/tests/target_cli.rs
@@ -3501,12 +3501,8 @@ fn listing_publish_idempotency_conflict_maps_sdk_partial_mutation_recovery() {
assert!(!output.status.success());
assert_eq!(conflict["operation_id"], "listing.publish");
- assert_eq!(conflict["errors"][0]["code"], "partial_local_mutation");
- assert_eq!(conflict["errors"][0]["detail"]["class"], "local_mutation");
- assert_eq!(
- conflict["errors"][0]["detail"]["detail"]["failure"],
- "outbox_idempotency_conflict"
- );
+ assert_eq!(conflict["errors"][0]["code"], "idempotency_conflict");
+ assert_eq!(conflict["errors"][0]["detail"]["class"], "request");
assert_eq!(
conflict["errors"][0]["detail"]["actions"][0],
"radroots listing publish"