use crate::ir_nodes::IRProgram;
use super::generate::{
artifact_digest, derive_capability_containment_witness,
derive_capability_isolation_witness, derive_compliance_coverage_witness,
derive_effect_row_soundness_witness, derive_endpoint_retry_witness,
derive_shield_halt_witness, derive_socket_credit_witness,
derive_tool_call_soundness_witness,
};
use super::proof_term::{ProofTerm, PropertyClass, ResourceBoundsWitness, Witness};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CheckOutcome {
Verified,
Refuted { reason: String },
DigestMismatch,
UnknownProperty,
}
pub fn check_proof(proof: &ProofTerm, ir: &IRProgram) -> CheckOutcome {
if proof.artifact_digest != artifact_digest(ir) {
return CheckOutcome::DigestMismatch;
}
match (&proof.property, &proof.witness) {
(PropertyClass::ComplianceCoverage, Witness::ComplianceCoverage(w)) => {
check_compliance_coverage(w, ir)
}
(PropertyClass::EffectRowSoundness, Witness::EffectRowSoundness(w)) => {
check_effect_row_soundness(w, ir)
}
(PropertyClass::CapabilityIsolation, Witness::CapabilityIsolation(w)) => {
check_capability_isolation(w, ir)
}
(PropertyClass::ResourceBounds, Witness::ResourceBounds(w)) => {
check_resource_bounds(w, ir)
}
(PropertyClass::ShieldHaltGuarantee, Witness::ShieldHaltGuarantee(w)) => {
check_shield_halt_guarantee(w, ir)
}
(PropertyClass::CapabilityContainment, Witness::CapabilityContainment(w)) => {
check_capability_containment(w, ir)
}
(PropertyClass::ToolCallSoundness, Witness::ToolCallSoundness(w)) => {
check_tool_call_soundness(w, ir)
}
_ => CheckOutcome::UnknownProperty,
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProofCheck {
pub index: usize,
pub property: PropertyClass,
pub subject: String,
pub outcome: CheckOutcome,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BundleReport {
pub results: Vec<ProofCheck>,
}
impl BundleReport {
pub fn all_verified(&self) -> bool {
self.results
.iter()
.all(|r| r.outcome == CheckOutcome::Verified)
}
pub fn refutations(&self) -> Vec<&ProofCheck> {
self.results
.iter()
.filter(|r| r.outcome != CheckOutcome::Verified)
.collect()
}
}
pub fn check_bundle(bundle: &super::proof_term::ProofBundle, ir: &IRProgram) -> BundleReport {
let results = bundle
.proofs
.iter()
.enumerate()
.map(|(index, proof)| ProofCheck {
index,
property: proof.property.clone(),
subject: proof.witness.subject_name().to_string(),
outcome: check_proof(proof, ir),
})
.collect();
BundleReport { results }
}
fn check_compliance_coverage(
claimed: &super::proof_term::ComplianceCoverageWitness,
ir: &IRProgram,
) -> CheckOutcome {
let ep = match ir.endpoints.iter().find(|e| e.name == claimed.endpoint_name) {
Some(e) => e,
None => {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' not present in artifact",
claimed.endpoint_name
),
}
}
};
let actual = derive_compliance_coverage_witness(
&ep.name,
&ep.compliance,
&ep.shield_ref,
ir,
);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if !actual.shield_present {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' declares compliance {:?} but has no resolvable shield (shield_ref={:?})",
actual.endpoint_name, actual.required_classes, actual.shield_ref
),
};
}
if !actual.unknown_classes.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' declares unknown regulatory class(es) {:?} (not in the closed registry)",
actual.endpoint_name, actual.unknown_classes
),
};
}
if !actual.uncovered_classes.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' requires regulatory class(es) {:?} that its shield '{}' does not provide (shield provides {:?})",
actual.endpoint_name,
actual.uncovered_classes,
actual.shield_ref,
actual.provided_classes
),
};
}
CheckOutcome::Verified
}
fn check_effect_row_soundness(
claimed: &super::proof_term::EffectRowSoundnessWitness,
ir: &IRProgram,
) -> CheckOutcome {
let tool = match ir.tools.iter().find(|t| t.name == claimed.tool_name) {
Some(t) => t,
None => {
return CheckOutcome::Refuted {
reason: format!(
"tool '{}' not present in artifact",
claimed.tool_name
),
}
}
};
let ext_members = super::generate::extension_effect_members(ir);
let actual =
derive_effect_row_soundness_witness(&tool.name, &tool.effect_row, &ext_members);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if !actual.unknown_bases.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"tool '{}' declares effect entr(ies) with unknown base(s) {:?} (not in the closed effect catalog)",
actual.tool_name, actual.unknown_bases
),
};
}
if !actual.missing_qualifier.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"tool '{}' declares qualifier-requiring effect(s) {:?} without a qualifier (bare stream/trust is unenforceable)",
actual.tool_name, actual.missing_qualifier
),
};
}
if !actual.invalid_stream_qualifier.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"tool '{}' declares stream effect(s) {:?} with an invalid backpressure policy qualifier",
actual.tool_name, actual.invalid_stream_qualifier
),
};
}
if actual.purity_violation {
return CheckOutcome::Refuted {
reason: format!(
"tool '{}' declares `pure` alongside other effects {:?} — a pure tool cannot be effectful",
actual.tool_name, actual.declared_effects
),
};
}
CheckOutcome::Verified
}
fn check_capability_isolation(
claimed: &super::proof_term::CapabilityIsolationWitness,
ir: &IRProgram,
) -> CheckOutcome {
let store = match ir
.axonstore_specs
.iter()
.find(|s| s.name == claimed.store_name)
{
Some(s) => s,
None => {
return CheckOutcome::Refuted {
reason: format!(
"axonstore '{}' not present in artifact",
claimed.store_name
),
}
}
};
let actual = derive_capability_isolation_witness(&store.name, &store.capability);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if actual.malformed {
return CheckOutcome::Refuted {
reason: format!(
"axonstore '{}' declares a malformed capability gate {:?} (not a valid §32.g scope: ^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$)",
actual.store_name, actual.capability
),
};
}
CheckOutcome::Verified
}
fn check_resource_bounds(
claimed: &ResourceBoundsWitness,
ir: &IRProgram,
) -> CheckOutcome {
match claimed {
ResourceBoundsWitness::EndpointRetry { endpoint_name, .. } => {
let ep = match ir.endpoints.iter().find(|e| e.name == *endpoint_name) {
Some(e) => e,
None => {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' not present in artifact",
endpoint_name
),
}
}
};
let actual = derive_endpoint_retry_witness(&ep.name, ep.retries);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if let ResourceBoundsWitness::EndpointRetry { retries, in_bounds, .. } = &actual {
if !in_bounds {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' declares retries={} outside the bound [0, {}] (negative is nonsensical; above the ceiling is a retry storm)",
ep.name,
retries,
super::proof_term::MAX_RETRIES
),
};
}
}
CheckOutcome::Verified
}
ResourceBoundsWitness::SocketCredit { socket_name, .. } => {
let socket = match ir.sockets.iter().find(|s| s.name == *socket_name) {
Some(s) => s,
None => {
return CheckOutcome::Refuted {
reason: format!(
"socket '{}' not present in artifact",
socket_name
),
}
}
};
let credit = match socket.backpressure_credit {
Some(k) => k,
None => {
return CheckOutcome::Refuted {
reason: format!(
"socket '{}' has no declared backpressure credit in the artifact, but the witness claims one (forged or stale proof)",
socket_name
),
}
}
};
let actual = derive_socket_credit_witness(&socket.name, credit);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if let ResourceBoundsWitness::SocketCredit { credit, positive, .. } = &actual {
if !positive {
return CheckOutcome::Refuted {
reason: format!(
"socket '{}' declares backpressure credit({}) — a window < 1 deadlocks the §Fase 41.b typed-resource gate",
socket.name, credit
),
};
}
}
CheckOutcome::Verified
}
}
}
fn check_shield_halt_guarantee(
claimed: &super::proof_term::ShieldHaltGuaranteeWitness,
ir: &IRProgram,
) -> CheckOutcome {
let shield = match ir.shields.iter().find(|s| s.name == claimed.shield_name) {
Some(s) => s,
None => {
return CheckOutcome::Refuted {
reason: format!(
"shield '{}' not present in artifact",
claimed.shield_name
),
}
}
};
let actual =
derive_shield_halt_witness(&shield.name, &shield.on_breach, &shield.scan);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if !actual.known_policy {
return CheckOutcome::Refuted {
reason: format!(
"shield '{}' declares an unknown on_breach policy {:?} (not in the closed breach-policy catalog)",
actual.shield_name, actual.on_breach
),
};
}
if actual.vacuous_halt {
return CheckOutcome::Refuted {
reason: format!(
"shield '{}' declares `on_breach: halt` but an empty `scan: []` — the halt can never fire (no scan ⟹ no breach ⟹ no halt): a vacuous guarantee",
actual.shield_name
),
};
}
CheckOutcome::Verified
}
fn check_capability_containment(
claimed: &super::proof_term::CapabilityContainmentWitness,
ir: &IRProgram,
) -> CheckOutcome {
let ep = match ir.endpoints.iter().find(|e| e.name == claimed.endpoint_name) {
Some(e) => e,
None => {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' not present in artifact",
claimed.endpoint_name
),
}
}
};
let actual = derive_capability_containment_witness(
&ep.name,
&ep.execute_flow,
&ep.requires_capabilities,
ir,
);
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if !actual.flow_resolved {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' executes flow '{}' which is not present in the artifact — cannot certify capability containment",
actual.endpoint_name, actual.execute_flow
),
};
}
if !actual.uncovered_gates.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"endpoint '{}' reaches store(s) gated by capabilit(ies) {:?} that its declared `requires:` {:?} does not cover — a capability leak (a request satisfying the declared requires could reach a store it is not authorized for)",
actual.endpoint_name, actual.uncovered_gates, actual.declared_requires
),
};
}
CheckOutcome::Verified
}
fn check_tool_call_soundness(
claimed: &super::proof_term::ToolCallSoundnessWitness,
ir: &IRProgram,
) -> CheckOutcome {
let actual = match derive_tool_call_soundness_witness(
&claimed.flow_name,
claimed.call_index,
ir,
) {
Some(w) => w,
None => {
return CheckOutcome::Refuted {
reason: format!(
"flow '{}' has no structured `use` call at index {} in this artifact",
claimed.flow_name, claimed.call_index
),
}
}
};
if actual != *claimed {
return CheckOutcome::Refuted {
reason: "witness disagrees with artifact re-derivation (forged or stale proof)"
.to_string(),
};
}
if !actual.schema_present {
return CheckOutcome::Verified;
}
if !actual.unknown_args.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"call to tool '{}' in flow '{}' passes argument(s) {:?} the tool does not declare (declared parameters: {:?})",
actual.tool_name, actual.flow_name, actual.unknown_args, actual.declared_params
),
};
}
if !actual.duplicate_args.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"call to tool '{}' in flow '{}' supplies duplicate argument(s) {:?}",
actual.tool_name, actual.flow_name, actual.duplicate_args
),
};
}
if !actual.missing_required.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"call to tool '{}' in flow '{}' omits required argument(s) {:?}",
actual.tool_name, actual.flow_name, actual.missing_required
),
};
}
if !actual.type_mismatches.is_empty() {
return CheckOutcome::Refuted {
reason: format!(
"call to tool '{}' in flow '{}' has literal-argument type mismatch(es) {:?} (each `arg:expected:got`)",
actual.tool_name, actual.flow_name, actual.type_mismatches
),
};
}
CheckOutcome::Verified
}