use contextgraph_host::{
ConsentRecord, ContextProvider, DigestVerification, DropReason, Host, HostError,
RawStdioConnection, frame_kind_name, verify_file_provenance,
};
use contextgraph_types::capability::fingerprint_dimensions;
use contextgraph_types::{
Capabilities, ConsentReceipt, ContextQuery, ContextQueryResult, ErrorCode, FrameId, FrameKind,
Grantor, ProviderInfo,
};
pub mod host_conformance;
mod report;
pub use host_conformance::{
HCHECK_BUDGET_DROP, HCHECK_COMPOSITION_AUDIT, HCHECK_CONSENT_GATE, HCHECK_CONTENT_QUOTING,
HCHECK_CRASH_ISOLATION, HCHECK_FRAME_LIMIT, HCHECK_PROVENANCE_BYTES, HCHECK_SCOPE_RECEIPT,
HCHECK_VERSION_REJECT, run_host_conformance,
};
pub use report::{CheckResult, CheckStatus, ConformanceReport};
pub const CHECK_HANDSHAKE: &str = "handshake";
pub const CHECK_CONSENT_SCOPE: &str = "consent-scope";
pub const CHECK_FRAME_VALIDITY: &str = "frame-validity";
pub const CHECK_VERIFY_HONESTY: &str = "verify-honesty";
pub const CHECK_BUDGET_HONESTY: &str = "budget-honesty";
pub const CHECK_AS_OF: &str = "as-of-temporal";
pub const CHECK_SHUTDOWN: &str = "shutdown-clean";
pub const CHECK_MALFORMED: &str = "malformed-input-tolerance";
pub const CHECK_EMBEDDING_FINGERPRINT: &str = "embedding-fingerprint";
pub const CHECK_CORRELATION: &str = "correlation";
pub const CHECK_KINDS_FILTER: &str = "kinds-filter";
pub const CHECK_ANCHOR_RELEVANCE: &str = "anchor-relevance";
pub const CHECK_PROVENANCE_FIXTURE_CONSISTENCY: &str = "provenance-fixture-consistency";
pub enum ProviderTarget {
Stdio { program: String, args: Vec<String> },
Http { url: String },
InProcess(Box<dyn ContextProvider>),
}
impl ProviderTarget {
pub fn describe(&self) -> String {
match self {
ProviderTarget::Stdio { program, args } => {
if args.is_empty() {
format!("stdio: {program}")
} else {
format!("stdio: {program} {}", args.join(" "))
}
}
ProviderTarget::Http { url } => format!("http: {url}"),
ProviderTarget::InProcess(provider) => format!("in-process: {}", provider.id()),
}
}
}
pub async fn run_conformance(target: ProviderTarget) -> ConformanceReport {
let description = target.describe();
let stdio_probe = match &target {
ProviderTarget::Stdio { program, args } => Some((program.clone(), args.clone())),
_ => None,
};
let mut checks = Vec::new();
match build_host(target).await {
Ok((host, id, info, caps)) => {
if info.name.trim().is_empty() || info.version.trim().is_empty() {
checks.push(CheckResult::fail(
CHECK_HANDSHAKE,
format!(
"provider identity incomplete: name='{}' version='{}'",
info.name, info.version
),
));
} else {
checks.push(CheckResult::pass(
CHECK_HANDSHAKE,
describe_handshake(&info, &caps),
));
}
checks.push(check_consent_scopes(&info));
run_query_and_shutdown_checks(host, &id, &caps, &mut checks).await;
}
Err(error) => {
checks.push(CheckResult::fail(
CHECK_HANDSHAKE,
format!("could not establish provider: {error}"),
));
for name in [
CHECK_FRAME_VALIDITY,
CHECK_VERIFY_HONESTY,
CHECK_CONSENT_SCOPE,
CHECK_BUDGET_HONESTY,
CHECK_AS_OF,
CHECK_KINDS_FILTER,
CHECK_ANCHOR_RELEVANCE,
CHECK_PROVENANCE_FIXTURE_CONSISTENCY,
CHECK_SHUTDOWN,
] {
checks.push(CheckResult::skip(name, "handshake failed"));
}
}
}
match stdio_probe {
Some((program, args)) => {
checks.push(malformed_stdio_probe(&program, &args).await);
checks.push(embedding_fingerprint_stdio_probe(&program, &args).await);
checks.push(correlation_stdio_probe(&program, &args).await);
}
None => {
checks.push(CheckResult::skip(
CHECK_MALFORMED,
"wire-level malformed-input probe applies to stdio providers only",
));
checks.push(CheckResult::skip(
CHECK_EMBEDDING_FINGERPRINT,
"wire-level §E1 bad_request probe applies to stdio providers only",
));
checks.push(CheckResult::skip(
CHECK_CORRELATION,
"wire-level §H4 id-echo probe applies to stdio providers only",
));
}
}
ConformanceReport {
target: description,
checks,
}
}
async fn build_host(
target: ProviderTarget,
) -> Result<(Host, String, ProviderInfo, Capabilities), HostError> {
let mut host = Host::new();
let (id, info, caps) = match target {
ProviderTarget::Stdio { program, args } => {
let id = "provider-under-test".to_string();
host.add_stdio(id.clone(), &program, &args).await?;
capture_identity(&host, &id)?
}
ProviderTarget::Http { url } => {
let id = "provider-under-test".to_string();
host.add_http(id.clone(), url, None).await?;
capture_identity(&host, &id)?
}
ProviderTarget::InProcess(provider) => {
let id = provider.id().to_string();
let info = provider.info().clone();
let caps = provider.capabilities().clone();
host.register(provider);
(id, info, caps)
}
};
if info.data_flow.egress {
host.record_consent(ConsentRecord::new(
id.clone(),
info.data_flow.clone(),
"conformance run under test",
));
}
for scope in info.data_flow.off_machine_scopes() {
host.record_receipt(ConsentReceipt::new(
id.clone(),
&info,
scope.clone(),
Grantor::Policy("conformance-suite".into()),
"2026-07-21T00:00:00Z",
));
}
Ok((host, id, info, caps))
}
fn capture_identity(
host: &Host,
id: &str,
) -> Result<(String, ProviderInfo, Capabilities), HostError> {
let provider = host
.provider(id)
.ok_or_else(|| HostError::UnknownProvider(id.to_string()))?;
Ok((
id.to_string(),
provider.info().clone(),
provider.capabilities().clone(),
))
}
async fn run_query_and_shutdown_checks(
host: Host,
id: &str,
caps: &Capabilities,
checks: &mut Vec<CheckResult>,
) {
let query = sample_query();
match host.query_provider(id, &query).await {
Ok(result) => {
let (ok, evidence) = check_frames(&result);
checks.push(CheckResult::from_bool(CHECK_FRAME_VALIDITY, ok, evidence));
checks.push(check_verify_honesty(&host, id, caps, &result).await);
let (budget_ok, budget_evidence) = check_budget(&result, &query);
checks.push(CheckResult::from_bool(
CHECK_BUDGET_HONESTY,
budget_ok,
budget_evidence,
));
}
Err(error) => {
let evidence = format!("query failed: {error}");
checks.push(CheckResult::fail(CHECK_FRAME_VALIDITY, evidence.clone()));
checks.push(CheckResult::fail(CHECK_VERIFY_HONESTY, evidence.clone()));
checks.push(CheckResult::fail(CHECK_BUDGET_HONESTY, evidence));
}
}
checks.push(check_as_of(&host, id).await);
checks.push(check_kinds_filter(&host, id, caps).await);
checks.push(check_anchor_relevance(&host, id, caps).await);
checks.push(check_provenance_fixture_consistency(&host, id).await);
let results = host.shutdown().await;
match results.iter().find(|(pid, _)| pid == id) {
Some((_, Ok(()))) => checks.push(CheckResult::pass(
CHECK_SHUTDOWN,
"provider acknowledged shutdown and tore down cleanly",
)),
Some((_, Err(error))) => checks.push(CheckResult::fail(
CHECK_SHUTDOWN,
format!("shutdown error: {error}"),
)),
None => checks.push(CheckResult::fail(
CHECK_SHUTDOWN,
"provider vanished before shutdown could be attempted",
)),
}
}
const MUTATED_SUFFIX: &str = "-contextgraph-conformance-mutated";
async fn check_verify_honesty(
host: &Host,
id: &str,
caps: &Capabilities,
result: &ContextQueryResult,
) -> CheckResult {
if !caps.verify {
return CheckResult::skip(
CHECK_VERIFY_HONESTY,
"provider does not advertise `verify`; a host falls back to re-querying its frames (§4)",
);
}
let held: Vec<FrameId> = result
.frames
.iter()
.filter(|frame| frame.content_digest.is_some())
.map(|frame| FrameId::new(id, frame.id.clone(), frame.content_digest.clone()))
.collect();
if held.is_empty() {
return CheckResult::skip(
CHECK_VERIFY_HONESTY,
"provider served no frame carrying a `content_digest`, so nothing is verifiable (§1 D4)",
);
}
let unchanged = host.verify_frames(&held).await;
if !unchanged.dropped.is_empty() {
let detail: Vec<String> = unchanged
.dropped
.iter()
.map(|dropped| format!("{} => {:?}", dropped.frame.frame_id, dropped.reason))
.collect();
return CheckResult::fail(
CHECK_VERIFY_HONESTY,
format!(
"provider advertises `verify` but did not answer `valid` for {} of {} frame(s) it had just served with unchanged digests: {}",
unchanged.dropped.len(),
held.len(),
detail.join(", ")
),
);
}
let mutated: Vec<FrameId> = held
.iter()
.map(|frame| {
FrameId::new(
id,
frame.frame_id.clone(),
frame
.content_digest
.as_ref()
.map(|digest| format!("{digest}{MUTATED_SUFFIX}")),
)
})
.collect();
let changed = host.verify_frames(&mutated).await;
if !changed.retained.is_empty() {
return CheckResult::fail(
CHECK_VERIFY_HONESTY,
format!(
"provider answered `valid` for {} frame(s) whose content digest it never served — a rubber stamp that lets a host cite stale evidence",
changed.retained.len()
),
);
}
let not_stale: Vec<String> = changed
.dropped
.iter()
.filter(|dropped| !matches!(dropped.reason, DropReason::Stale { .. }))
.map(|dropped| format!("{} => {:?}", dropped.frame.frame_id, dropped.reason))
.collect();
if !not_stale.is_empty() {
return CheckResult::fail(
CHECK_VERIFY_HONESTY,
format!(
"a digest mismatch on a frame the provider still serves MUST verify `stale` (§4 V1); got: {}",
not_stale.join(", ")
),
);
}
CheckResult::pass(
CHECK_VERIFY_HONESTY,
format!(
"provider verified {n} unchanged frame(s) `valid` and all {n} mutated digest(s) `stale`, carrying no frame bodies",
n = held.len()
),
)
}
async fn malformed_stdio_probe(program: &str, args: &[String]) -> CheckResult {
let mut conn = match RawStdioConnection::spawn(program, args).await {
Ok(conn) => conn,
Err(error) => {
return CheckResult::fail(
CHECK_MALFORMED,
format!("could not spawn provider: {error}"),
);
}
};
if let Err(error) = conn.handshake().await {
return CheckResult::fail(
CHECK_MALFORMED,
format!("handshake failed before the probe could run: {error}"),
);
}
if let Err(error) = conn.send_raw_line("this is not valid json {{{\n").await {
return CheckResult::fail(
CHECK_MALFORMED,
format!("provider closed its input on a malformed line: {error}"),
);
}
if let Err(error) = conn
.send(&contextgraph_host::Envelope::Query {
id: None,
query: sample_query(),
})
.await
{
return CheckResult::fail(
CHECK_MALFORMED,
format!("provider died after a malformed line (before a valid query): {error}"),
);
}
match conn.recv().await {
Ok(contextgraph_host::Envelope::Frames { .. }) => CheckResult::pass(
CHECK_MALFORMED,
"provider ignored a malformed line and still answered a valid query",
),
Ok(contextgraph_host::Envelope::Error {
code: Some(ErrorCode::BadRequest),
message,
..
}) => CheckResult::pass(
CHECK_MALFORMED,
format!(
"provider errored cleanly on malformed input with `bad_request` and stayed alive: {message}"
),
),
Ok(contextgraph_host::Envelope::Error { code, message, .. }) => CheckResult::fail(
CHECK_MALFORMED,
format!(
"provider stayed alive but answered malformed input with `{}` rather than the `bad_request` §R1 recommends: {message}",
code.map(|c| c.to_string())
.unwrap_or_else(|| "no code".to_string())
),
),
Ok(other) => CheckResult::fail(
CHECK_MALFORMED,
format!(
"provider replied to a valid query with an unexpected `{}` envelope",
contextgraph_host::envelope_kind(&other)
),
),
Err(HostError::ProviderCrashed { .. }) => CheckResult::fail(
CHECK_MALFORMED,
"provider crashed on a malformed line — it must error-or-ignore, not die",
),
Err(error) => CheckResult::fail(
CHECK_MALFORMED,
format!("provider mishandled malformed input: {error}"),
),
}
}
async fn embedding_fingerprint_stdio_probe(program: &str, args: &[String]) -> CheckResult {
let mut conn = match RawStdioConnection::spawn(program, args).await {
Ok(conn) => conn,
Err(error) => {
return CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
format!("could not spawn provider: {error}"),
);
}
};
let caps = match conn.handshake().await {
Ok((_, caps)) => caps,
Err(error) => {
return CheckResult::skip(
CHECK_EMBEDDING_FINGERPRINT,
format!("handshake failed before the §E1 probe could run: {error}"),
);
}
};
let Some(fingerprint) = caps.embeddings_fingerprint.clone() else {
return CheckResult::skip(
CHECK_EMBEDDING_FINGERPRINT,
"provider declares no embeddings_fingerprint, so §E1 has no dimension to contradict",
);
};
let Some(dimension) = fingerprint_dimensions(&fingerprint) else {
return CheckResult::skip(
CHECK_EMBEDDING_FINGERPRINT,
format!(
"fingerprint `{fingerprint}` declares no parseable dimension, so §E1 cannot be probed"
),
);
};
let wrong_len = if dimension == 1 { 2 } else { 1 };
let mut query = sample_query();
query.embedding = Some(vec![0.0; wrong_len]);
if let Err(error) = conn
.send(&contextgraph_host::Envelope::Query { id: None, query })
.await
{
return CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
format!("provider closed its input before the §E1 probe query: {error}"),
);
}
match conn.recv().await {
Ok(contextgraph_host::Envelope::Error {
code: Some(ErrorCode::BadRequest),
..
}) => CheckResult::pass(
CHECK_EMBEDDING_FINGERPRINT,
format!(
"provider declares {fingerprint} ({dimension}-dim) and rejected a {wrong_len}-dim embedding with `bad_request` (§E1)"
),
),
Ok(contextgraph_host::Envelope::Error { code, message, .. }) => CheckResult::pass(
CHECK_EMBEDDING_FINGERPRINT,
format!(
"provider rejected a {wrong_len}-dim embedding against {fingerprint} with `{}` rather than the `bad_request` §E1 recommends: {message}",
code.unwrap_or(ErrorCode::Internal)
),
),
Ok(contextgraph_host::Envelope::Frames { .. }) => CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
format!(
"provider declares {fingerprint} ({dimension}-dim) but scored a {wrong_len}-dim embedding into frames instead of rejecting it — meaningless similarity from a different vector space (§E1)"
),
),
Ok(other) => CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
format!(
"provider answered the §E1 probe with an unexpected `{}` envelope",
contextgraph_host::envelope_kind(&other)
),
),
Err(HostError::ProviderCrashed { .. }) => CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
"provider crashed on a dimension-mismatched embedding — §E1 asks it to reply `bad_request`, not die",
),
Err(error) => CheckResult::fail(
CHECK_EMBEDDING_FINGERPRINT,
format!("provider mishandled the §E1 probe: {error}"),
),
}
}
const CORRELATION_PROBE_ID: &str = "cgp-conformance-h4-7f3a";
async fn correlation_stdio_probe(program: &str, args: &[String]) -> CheckResult {
let mut conn = match RawStdioConnection::spawn(program, args).await {
Ok(conn) => conn,
Err(error) => {
return CheckResult::fail(
CHECK_CORRELATION,
format!("could not spawn provider: {error}"),
);
}
};
let caps = match conn.handshake().await {
Ok((_, caps)) => caps,
Err(error) => {
return CheckResult::skip(
CHECK_CORRELATION,
format!("handshake failed before the §H4 probe could run: {error}"),
);
}
};
if !caps.correlation {
return CheckResult::skip(
CHECK_CORRELATION,
"provider does not declare capabilities.correlation, so §H4 does not bind it",
);
}
let query = sample_query();
if let Err(error) = conn
.send(&contextgraph_host::Envelope::Query {
id: Some(CORRELATION_PROBE_ID.to_string()),
query,
})
.await
{
return CheckResult::fail(
CHECK_CORRELATION,
format!("provider closed its input before the §H4 probe query: {error}"),
);
}
let reply = match conn.recv().await {
Ok(reply) => reply,
Err(error) => {
return CheckResult::fail(
CHECK_CORRELATION,
format!("provider mishandled the §H4 probe: {error}"),
);
}
};
let kind = contextgraph_host::envelope_kind(&reply);
match reply.correlation_id() {
Some(echoed) if echoed == CORRELATION_PROBE_ID => CheckResult::pass(
CHECK_CORRELATION,
format!(
"provider declares correlation and echoed the request id verbatim on its `{kind}` reply (§H4)"
),
),
Some(echoed) => CheckResult::fail(
CHECK_CORRELATION,
format!(
"provider declares correlation but echoed `{echoed}` on its `{kind}` reply instead of the request's `{CORRELATION_PROBE_ID}` — a host demultiplexing on the id would match this reply to the wrong request (§H4)"
),
),
None if matches!(reply, contextgraph_host::Envelope::Frames { .. })
|| matches!(reply, contextgraph_host::Envelope::Error { .. }) =>
{
CheckResult::fail(
CHECK_CORRELATION,
format!(
"provider declares correlation but its `{kind}` reply carried no id — the host cannot match it to the request it answers, so the connection is forced back to lock-step (§H4)"
),
)
}
None => CheckResult::fail(
CHECK_CORRELATION,
format!("provider answered the §H4 probe with an unexpected `{kind}` envelope"),
),
}
}
const AS_OF_PIN: &str = "2026-07-01T00:00:00Z";
async fn check_as_of(host: &Host, id: &str) -> CheckResult {
match host.query_provider(id, &as_of_query()).await {
Ok(result) => {
let not_yet_valid: Vec<String> = result
.frames
.iter()
.filter_map(|frame| {
frame
.valid_from
.as_deref()
.filter(|valid_from| *valid_from > AS_OF_PIN)
.map(|valid_from| format!("{} (valid_from={valid_from})", frame.id))
})
.collect();
if not_yet_valid.is_empty() {
CheckResult::pass(
CHECK_AS_OF,
format!(
"as_of={AS_OF_PIN}: none of the {} returned frame(s) is dated after the pin",
result.frames.len()
),
)
} else {
CheckResult::fail(
CHECK_AS_OF,
format!(
"provider returned {} frame(s) whose valid_from is after as_of={AS_OF_PIN} — content that was not yet true at the pinned instant (§6.1): {}",
not_yet_valid.len(),
not_yet_valid.join(", ")
),
)
}
}
Err(error) => CheckResult::fail(CHECK_AS_OF, format!("as_of query failed: {error}")),
}
}
async fn check_kinds_filter(host: &Host, id: &str, caps: &Capabilities) -> CheckResult {
let Some(declared) = caps.query.kinds.first() else {
return CheckResult::skip(
CHECK_KINDS_FILTER,
"provider declares no query kinds, so §Q1 has no kind to narrow to",
);
};
let Some(kind) = frame_kind_from_wire(declared) else {
return CheckResult::skip(
CHECK_KINDS_FILTER,
format!(
"provider declares kind `{declared}`, which is outside the closed FrameKind vocabulary, so §Q1 cannot be probed"
),
);
};
let query = ContextQuery {
kinds: vec![kind],
..sample_query()
};
match host.query_provider(id, &query).await {
Ok(result) => {
let off_kind: Vec<String> = result
.frames
.iter()
.filter(|frame| frame.kind != kind)
.map(|frame| format!("{} (kind={})", frame.id, frame_kind_name(frame.kind)))
.collect();
if off_kind.is_empty() {
CheckResult::pass(
CHECK_KINDS_FILTER,
format!(
"kinds=[{declared}]: all {} returned frame(s) are of the requested kind (§Q1)",
result.frames.len()
),
)
} else {
CheckResult::fail(
CHECK_KINDS_FILTER,
format!(
"provider returned {} frame(s) outside the requested kinds=[{declared}] — content the host explicitly excluded, charged against its budget (§Q1): {}",
off_kind.len(),
off_kind.join(", ")
),
)
}
}
Err(error) => CheckResult::fail(
CHECK_KINDS_FILTER,
format!("kinds-filtered query failed: {error}"),
),
}
}
fn frame_kind_from_wire(kind: &str) -> Option<FrameKind> {
match kind {
"snippet" => Some(FrameKind::Snippet),
"symbol" => Some(FrameKind::Symbol),
"fact" => Some(FrameKind::Fact),
"doc" => Some(FrameKind::Doc),
"memory" => Some(FrameKind::Memory),
"episode" => Some(FrameKind::Episode),
"graph" => Some(FrameKind::Graph),
_ => None,
}
}
async fn check_anchor_relevance(host: &Host, id: &str, caps: &Capabilities) -> CheckResult {
if !caps.graph {
return CheckResult::skip(
CHECK_ANCHOR_RELEVANCE,
"provider does not declare capabilities.graph, so §G3/§G4 do not bind it",
);
}
let baseline = match host.query_provider(id, &sample_query()).await {
Ok(result) => result,
Err(error) => {
return CheckResult::fail(
CHECK_ANCHOR_RELEVANCE,
format!("baseline query failed: {error}"),
);
}
};
let anchor = baseline
.frames
.iter()
.find_map(|frame| frame.relations.first().map(|r| r.target_uri.clone()))
.or_else(|| baseline.frames.iter().find_map(|frame| frame.uri.clone()));
let Some(anchor) = anchor else {
return CheckResult::skip(
CHECK_ANCHOR_RELEVANCE,
"provider declares graph but served no frame carrying a uri or a relation target to anchor on",
);
};
let anchored_query = ContextQuery {
anchors: vec![anchor.clone()],
..sample_query()
};
match host.query_provider(id, &anchored_query).await {
Ok(result) => {
let anchored: Vec<&contextgraph_types::ContextFrame> = result
.frames
.iter()
.filter(|frame| frame_is_anchored(frame, &anchor))
.collect();
if anchored.is_empty() {
return CheckResult::fail(
CHECK_ANCHOR_RELEVANCE,
format!(
"provider declares capabilities.graph but returned no frame anchored on `{anchor}` — a URI drawn from its own previous answer (§G4)"
),
);
}
let first_is_anchored = result
.frames
.first()
.is_some_and(|frame| frame_is_anchored(frame, &anchor));
let ranking = if first_is_anchored {
"and ranked it first"
} else {
"though it did not rank it first (§G3 is a SHOULD)"
};
CheckResult::pass(
CHECK_ANCHOR_RELEVANCE,
format!(
"anchored on `{anchor}`: provider returned {} anchored frame(s) {ranking}",
anchored.len()
),
)
}
Err(error) => CheckResult::fail(
CHECK_ANCHOR_RELEVANCE,
format!("anchored query failed: {error}"),
),
}
}
fn frame_is_anchored(frame: &contextgraph_types::ContextFrame, anchor: &str) -> bool {
frame.uri.as_deref() == Some(anchor) || frame.relations.iter().any(|r| r.target_uri == anchor)
}
async fn check_provenance_fixture_consistency(host: &Host, id: &str) -> CheckResult {
let result = match host.query_provider(id, &sample_query()).await {
Ok(result) => result,
Err(error) => {
return CheckResult::fail(
CHECK_PROVENANCE_FIXTURE_CONSISTENCY,
format!("query failed: {error}"),
);
}
};
let mut verified = 0usize;
let mut unreadable = 0usize;
let mut mismatches = Vec::new();
for frame in &result.frames {
for (index, outcome) in verify_file_provenance(frame) {
match outcome {
DigestVerification::Verified => verified += 1,
DigestVerification::Mismatch { expected, actual } => mismatches.push(format!(
"{} provenance[{index}] declared {expected} but its bytes hash to {actual}",
frame.id
)),
DigestVerification::Unreadable { .. } => unreadable += 1,
DigestVerification::NotFileProvenance => {}
}
}
}
if !mismatches.is_empty() {
return CheckResult::fail(
CHECK_PROVENANCE_FIXTURE_CONSISTENCY,
format!(
"{} file-provenance digest(s) do not match the bytes they name — a stale or forged digest that passes §F5's grammar but not its bytes (§6.2): {}",
mismatches.len(),
mismatches.join("; ")
),
);
}
if verified == 0 {
return CheckResult::skip(
CHECK_PROVENANCE_FIXTURE_CONSISTENCY,
format!(
"no locally re-readable file provenance to verify ({unreadable} link(s) name files this host cannot see); §6.2 byte-verification is host-local"
),
);
}
CheckResult::pass(
CHECK_PROVENANCE_FIXTURE_CONSISTENCY,
format!(
"re-read and re-hashed {verified} file-provenance digest(s) against the bytes on disk — all match (§6.2)"
),
)
}
fn as_of_query() -> ContextQuery {
ContextQuery {
as_of: Some(AS_OF_PIN.into()),
..sample_query()
}
}
pub fn sample_query() -> ContextQuery {
ContextQuery {
goal: "conformance probe: return your most relevant frames".into(),
query_text: Some("conformance probe".into()),
embedding: None,
kinds: vec![],
anchors: vec![],
max_frames: 8,
max_tokens: 4096,
as_of: None,
representation_preferences: vec![],
}
}
pub fn check_frames(result: &ContextQueryResult) -> (bool, String) {
if result.frames.is_empty() {
return (
true,
"provider returned 0 frames (permitted — nothing relevant to the probe)".into(),
);
}
let mut problems = Vec::new();
for (i, frame) in result.frames.iter().enumerate() {
if !frame.has_valid_score() {
problems.push(format!("frame[{i}] score {} is outside [0,1]", frame.score));
}
if frame.title.trim().is_empty() {
problems.push(format!("frame[{i}] has an empty title"));
}
match &frame.citation_label {
Some(label) if !label.trim().is_empty() => {}
_ => problems.push(format!(
"frame[{i}] is missing a citation_label (§F3 — never a bare id)"
)),
}
if let Err(violation) = frame.representation_invariants() {
problems.push(format!("frame[{i}] {violation} (§P1–P3)"));
}
for field in frame.invalid_temporal_fields() {
problems.push(format!(
"frame[{i}] field `{field}` is not an RFC 3339 UTC timestamp (§F4)"
));
}
if !frame.has_usable_content_digest() {
problems.push(format!(
"frame[{i}] content_digest is present but not `sha256:<64 lowercase hex>` (§D1)"
));
}
for index in frame.provenance_with_unusable_digests() {
problems.push(format!(
"frame[{i}] provenance[{index}] addresses a file but its digest is missing or not `sha256:<64 lowercase hex>` (§F5)"
));
}
for (edge_index, edge) in frame.relations.iter().enumerate() {
if !edge.has_display_name() {
problems.push(format!(
"frame[{i}] relation[{edge_index}] `{}` has no display_name (§G1 — an edge is surfaced by label, never a raw id)",
edge.rel
));
}
if !edge.has_target_uri() {
problems.push(format!(
"frame[{i}] relation[{edge_index}] `{}` has an empty target_uri (§G2 — an edge to nowhere is not an edge)",
edge.rel
));
}
}
}
if problems.is_empty() {
(
true,
format!(
"{} frame(s) — scores in [0,1], titles, citation labels, honest representations, RFC 3339 timestamps, well-formed digests, labelled and targeted relations",
result.frames.len()
),
)
} else {
(false, problems.join("; "))
}
}
pub fn check_budget(result: &ContextQueryResult, query: &ContextQuery) -> (bool, String) {
let mut problems = Vec::new();
let declared = result.total_token_cost();
if declared > query.max_tokens as u64 {
problems.push(format!(
"declared cost {declared} exceeds the query budget of {} (§B1)",
query.max_tokens
));
}
let dishonest = result.frames_with_dishonest_cost();
if !dishonest.is_empty() {
let canonical = result.canonical_token_cost();
problems.push(format!(
"{} frame(s) misdeclare token_cost — {} (§B3); declared total {declared}, canonical total {canonical}",
dishonest.len(),
dishonest.join(", ")
));
}
if !result.respects_frame_limit(query.max_frames) {
problems.push(format!(
"returned {} frames against max_frames={} (§B4)",
result.frames.len(),
query.max_frames
));
}
if problems.is_empty() {
(
true,
format!(
"{} frame(s), {declared} tokens within the {} budget; every declared cost matches its canonical count",
result.frames.len(),
query.max_tokens
),
)
} else {
(false, problems.join("; "))
}
}
fn check_consent_scopes(info: &ProviderInfo) -> CheckResult {
if info.data_flow.scopes_consistent() {
let scopes: Vec<&str> = info
.data_flow
.egress_scopes
.iter()
.map(|scope| scope.as_str())
.collect();
CheckResult::pass(
CHECK_CONSENT_SCOPE,
format!(
"declared egress scopes {scopes:?} are well-formed and consistent with egress={}",
info.data_flow.egress
),
)
} else {
CheckResult::fail(
CHECK_CONSENT_SCOPE,
format!(
"egress scopes {:?} are inconsistent with egress={}: an off-machine scope alongside egress=false, or a non-namespaced custom scope (§3, C5)",
info.data_flow
.egress_scopes
.iter()
.map(|scope| scope.as_str())
.collect::<Vec<_>>(),
info.data_flow.egress
),
)
}
}
fn describe_handshake(info: &ProviderInfo, caps: &Capabilities) -> String {
format!(
"provider '{}' v{} — data-flow reads={} writes={} egress={}; query kinds={:?}, graph={}",
info.name,
info.version,
info.data_flow.reads,
info.data_flow.writes,
info.data_flow.egress,
caps.query.kinds,
caps.graph,
)
}