Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 130 additions & 27 deletions crates/ourios-bench/tests/rfc0031_comparative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2078,31 +2078,112 @@ type Measured = (Vec<LineKey>, u64, LokiFetchedBytes, Option<Duration>);
struct OuriosMeasured {
answer: ourios_bench::OuriosAnswer,
latency_p50: Option<Duration>,
/// The RFC 0033 template-map acquisition outcome behind
/// `answer.registry_bytes` — cold audit fold vs warm artifact GET —
/// classified at measurement time ([`template_map_outcome`]).
/// The RFC 0033 template-map acquisition + publish-outcome label
/// behind `answer.registry_bytes` — cold audit fold vs warm
/// artifact GET, with the publish outcome the §3.2 amendment
/// requires printed explicitly ([`TemplateMapProbe`]).
template_map: String,
}

/// Classify one measurement's registry component (RFC 0033 / RFC0033.6):
/// a warm hit's acquisition equals the published artifact's byte size
/// exactly (the only registry-path GET is the artifact); anything else
/// is the cold audit fold, whose write-through publishes for the next
/// query. Read at measurement time, right after the query, so the size
/// compared is the artifact that query saw (or just published).
fn template_map_outcome(artifact: &std::path::Path, registry_bytes: u64) -> String {
match std::fs::metadata(artifact) {
Ok(meta) if meta.len() == registry_bytes => {
format!("warm (one artifact GET, {registry_bytes} B)")
/// One pair's artifact observation, taken right after its query (the
/// state changes across pairs — the first cold miss publishes for the
/// rest): a warm hit's acquisition equals the published artifact's byte
/// size exactly (the only registry-path GET is the artifact); anything
/// else is the cold audit fold. The absent arm's publish outcome —
/// `abstained` vs `error`, run #20's ambiguity — is resolved once,
/// after every pair's timed measurement
/// ([`reproduce_publish_decision`]). `lost_race` cannot occur here: the
/// harness is the store's only writer, so it is never printed.
enum TemplateMapProbe {
Warm {
artifact_bytes: u64,
},
ColdPublished {
registry_bytes: u64,
artifact_bytes: u64,
},
ColdAbsent {
registry_bytes: u64,
},
ColdUnreadable {
registry_bytes: u64,
detail: String,
},
}

impl TemplateMapProbe {
fn observe(artifact: &std::path::Path, registry_bytes: u64) -> Self {
match std::fs::metadata(artifact) {
Ok(meta) if meta.len() == registry_bytes => Self::Warm {
artifact_bytes: registry_bytes,
},
Ok(meta) => Self::ColdPublished {
registry_bytes,
artifact_bytes: meta.len(),
},
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
Self::ColdAbsent { registry_bytes }
}
Err(e) => Self::ColdUnreadable {
registry_bytes,
detail: e.to_string(),
},
}
Ok(meta) => format!(
"cold (audit fold, {registry_bytes} B; artifact on disk {} B)",
meta.len(),
),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
format!("cold (audit fold, {registry_bytes} B; no artifact published)")
}

/// The report label; `absent_outcome` is the once-computed
/// [`reproduce_publish_decision`] string (present iff any pair
/// observed absence).
fn label(&self, absent_outcome: Option<&str>) -> String {
match self {
Self::Warm { artifact_bytes } => {
format!("warm (one artifact GET, {artifact_bytes} B compressed)")
}
Self::ColdPublished {
registry_bytes,
artifact_bytes,
} => format!(
"cold (audit fold, {registry_bytes} B; published — artifact \
{artifact_bytes} B compressed)"
),
Self::ColdAbsent { registry_bytes } => format!(
"cold (audit fold, {registry_bytes} B; {})",
absent_outcome.expect("an absent probe resolves its publish outcome"),
),
Self::ColdUnreadable {
registry_bytes,
detail,
} => format!("cold (audit fold, {registry_bytes} B; artifact stat failed: {detail})"),
}
Err(e) => format!("cold (audit fold, {registry_bytes} B; artifact stat failed: {e})"),
}
}

/// Resolve run #20's abstained-vs-error ambiguity for a store left with
/// no artifact (RFC 0033 §3.2 amendment: the harness MUST print each
/// pair's publish outcome): reproduce the §3.5 publish decision — one
/// fold + serialize + compress, the exact bytes the write-through would
/// have published — against the folded audit bytes. Off the measured
/// path by construction: called once, after every pair's timed
/// measurement, and only labels.
fn reproduce_publish_decision(bucket: &std::path::Path, tenant: &TenantId) -> String {
let (map, fold_bytes) = match ourios_querier::derive_template_map(
ourios_querier::StoreRef::Local(bucket),
tenant,
) {
Ok(derived) => derived,
Err(e) => return format!("publish outcome unresolvable — refold failed: {e}"),
};
match map.to_artifact_bytes() {
Ok(bytes) if (bytes.len() as u64) < fold_bytes => format!(
"publish error — would-be artifact {} B compressed < folded audit \
{fold_bytes} B, yet nothing on the store",
bytes.len(),
),
Ok(bytes) => format!(
"abstained — would-be artifact {} B compressed >= folded audit {fold_bytes} B",
bytes.len(),
),
Err(e) => format!("publish error — serialization failed: {e}"),
}
}

Expand Down Expand Up @@ -2369,7 +2450,11 @@ fn rfc0031_indicative_comparative_run() {
ourios_parquet::percent_encode_tenant(built.tenant),
))
.join(ourios_querier::TEMPLATE_MAP_FILENAME);
let ourios: Vec<OuriosMeasured> = specs
let measured: Vec<(
ourios_bench::OuriosAnswer,
Option<Duration>,
TemplateMapProbe,
)> = specs
.iter()
.map(|spec| {
let answer = ourios_bench::ourios_query_answer(
Expand All @@ -2386,13 +2471,28 @@ fn rfc0031_indicative_comparative_run() {
"Ourios must return exactly [{}]'s expected rows",
spec.label,
);
let template_map = template_map_outcome(&artifact_path, answer.registry_bytes);
let probe = TemplateMapProbe::observe(&artifact_path, answer.registry_bytes);
// Timed reps only after the pair's Ourios correctness holds.
let latency_p50 = ourios_latency_p50(bucket.path(), &tenant, spec);
(answer, latency_p50, probe)
})
.collect();
// Publish-outcome labels resolve AFTER every timed measurement (§3.2
// amendment): reproducing the abstention decision costs a fold +
// compress, so it runs once, off the measured path, and only labels.
let absent_outcome = measured
.iter()
.any(|(_, _, probe)| matches!(probe, TemplateMapProbe::ColdAbsent { .. }))
.then(|| reproduce_publish_decision(bucket.path(), &tenant));
let ourios: Vec<OuriosMeasured> = specs
.iter()
.zip(measured)
.map(|(spec, (answer, latency_p50, probe))| {
let template_map = probe.label(absent_outcome.as_deref());
eprintln!(
"[{}] template-map acquisition (RFC 0033): {template_map}",
spec.label,
);
// Timed reps only after the pair's Ourios correctness holds.
let latency_p50 = ourios_latency_p50(bucket.path(), &tenant, spec);
OuriosMeasured {
answer,
latency_p50,
Expand Down Expand Up @@ -2602,9 +2702,12 @@ fn print_indicative_report(
answer.materialize_bytes,
answer.registry_bytes,
);
// The registry component's RFC 0033 acquisition outcome
// (RFC0033.6's channel): the artifact persists across pairs by
// design, so the cold audit fold is paid at most once per run.
// The registry component's RFC 0033 acquisition + publish
// outcome (RFC0033.6's channel, §3.2 amendment): the artifact
// persists across pairs by design, so a successful publish makes
// the cold audit fold a once-per-run cost — while an abstention
// (printed with its would-be size vs the folded bytes) leaves
// every pair cold, run #20's finding.
println!(
"ourios template-map acquisition (RFC 0033) = {}",
ours.template_map
Expand Down
7 changes: 7 additions & 0 deletions crates/ourios-querier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ chrono = { version = "0.4", default-features = false, features = ["std"] }
# on the async query path. `rt` is the blocking-pool half only; the runtime itself
# is the caller's (the server / `#[tokio::test]`).
tokio = { version = "1", default-features = false, features = ["rt"] }
# RFC 0033 §3.2 (2026-07-13 amendment) — the template-map artifact ships
# as one zstd frame. `zstd` is the ergonomic safe wrapper over
# `zstd-safe`; both bind the same bundled C library and `parquet`'s
# `zstd` feature already pulls it into the tree (via ourios-parquet, and
# ourios-bench binds it directly as the A1 reference codec), so this
# adds no new transitive crate and the version is pinned by `Cargo.lock`.
zstd = "0.13"

[dev-dependencies]
# Miner tunables (RFC 0004), their own crate so config edits recompile narrowly (RFC 0028).
Expand Down
5 changes: 3 additions & 2 deletions crates/ourios-querier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ pub use drift::{DriftResult, DriftRow};
pub use log_row::{LogBody, LogRow, render_log_body};
pub use template_map::{
ArtifactRead, CacheOutcome, MissReason, PublishOutcome, TEMPLATE_MAP_FILENAME,
TEMPLATE_MAP_FORMAT_VERSION, TemplateMap, derive_template_map, load_or_derive,
TEMPLATE_MAP_FORMAT_VERSION, TEMPLATE_MAP_V1_FILENAME, TemplateMap, derive_template_map,
load_or_derive,
};
pub use template_registry::{TemplateRegistry, derive_template_registry};

Expand Down Expand Up @@ -202,7 +203,7 @@ pub struct QueryResult {
/// obtain the body-rendering capability behind the returned `records`,
/// whatever the source — the audit-stream fold on a cache miss
/// (byte-for-byte the pre-0033 RFC 0017 §3.2 registry derivation) or
/// the `template_map.json` artifact GET on a cache hit. One
/// the `template_map.v2.json.zst` artifact GET on a cache hit. One
/// per-query acquisition serves both the registry and, for
/// `resolves_to` queries, the alias map. `0` when no rows were
/// rendered. Same additive contract as `materialize_bytes_read`
Expand Down
Loading