From 92945d5350f62d48f832096a353852ec0e0cb8b1 Mon Sep 17 00:00:00 2001 From: Jens Holdgaard Pedersen Date: Wed, 29 Jul 2026 02:17:06 +0200 Subject: [PATCH 1/3] feat(querier): plan-time body-literal candidate matcher (RFC 0044 slice 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit body_literal_candidates tokenizes a body == literal with the miner's own tokenizer and unifies it position-wise against every registered (template_id, version): Fixed tokens byte-equal, Wildcard positions capture the implied parameter values, output deterministically sorted. The result is the template arm's prunable candidate superset — exact per-record equality (separators, overflow-spilled params) settles at scan time in the compile slice. A tokenizer-rejected literal (embedded NUL) matches no template, which is exact: the parse-failure ingest path always retains such bodies, so the physical arm alone covers them. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen --- crates/ourios-querier/src/body_match.rs | 177 ++++++++++++++++++++++++ crates/ourios-querier/src/lib.rs | 1 + 2 files changed, 178 insertions(+) create mode 100644 crates/ourios-querier/src/body_match.rs diff --git a/crates/ourios-querier/src/body_match.rs b/crates/ourios-querier/src/body_match.rs new file mode 100644 index 000000000..93995f897 --- /dev/null +++ b/crates/ourios-querier/src/body_match.rs @@ -0,0 +1,177 @@ +//! Plan-time resolution of a `body ==` literal against the tenant's +//! template registry (RFC 0044 §3.1, the template arm's candidate set). +//! +//! The literal is tokenized with the miner's own tokenizer and unified +//! position-wise against every registered `(template_id, version)`'s +//! canonical tokens: `Fixed` tokens must match byte-for-byte, `Wildcard` +//! positions capture the literal's token as the implied parameter value. +//! The result is a *candidate superset*: separators and stored parameter +//! values (overflow spills, RFC 0023) are per-record, so exact equality +//! is settled at scan time against the candidates — but only ever inside +//! row groups the candidate `template_id`s admit, which is what keeps +//! the arm prunable. Soundness of the whole inversion rests on the +//! `CLAUDE.md` §3.3 bit-identical reconstruction invariant. + +use ourios_miner::tokenize::tokenize; +use ourios_miner::tree::OwnedToken; + +use crate::template_registry::TemplateRegistry; + +/// One template the literal could have mined to: the version-qualified +/// id plus the parameter values implied by the literal's tokens at the +/// template's wildcard positions (in wildcard order). +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BodyLiteralMatch { + pub template_id: u64, + pub template_version: u32, + /// The literal's tokens at the template's `Wildcard` positions. + /// Empty for a zero-parameter template — the whole-body-is-the- + /// template case (event-name-bodied `GenAI` records). + pub params: Vec, +} + +/// Resolve `literal` to every registry entry it unifies with. +/// +/// A literal the tokenizer rejects (embedded NUL — the parse-failure +/// path at ingest, which always retains the body) matches no template: +/// such records are only ever reachable through the physical body arm, +/// so an empty candidate set is exact, not lossy. +#[must_use] +pub fn body_literal_candidates( + registry: &TemplateRegistry, + literal: &str, +) -> Vec { + let Ok(tokenized) = tokenize(literal) else { + return Vec::new(); + }; + let mut matches: Vec = registry + .iter() + .filter_map(|(&(template_id, template_version), tokens)| { + unify(tokens, &tokenized.tokens).map(|params| BodyLiteralMatch { + template_id, + template_version, + params, + }) + }) + .collect(); + // Deterministic plan output: registry iteration order is a HashMap's. + matches.sort_by_key(|m| (m.template_id, m.template_version)); + matches +} + +/// Position-wise unification: same arity, every `Fixed` equal, every +/// `Wildcard` capturing. Returns the captured parameter values in +/// wildcard order. +fn unify(template: &[OwnedToken], literal_tokens: &[&str]) -> Option> { + if template.len() != literal_tokens.len() { + return None; + } + let mut params = Vec::new(); + for (token, &literal_token) in template.iter().zip(literal_tokens) { + match token { + OwnedToken::Fixed(fixed) if fixed == literal_token => {} + OwnedToken::Fixed(_) => return None, + OwnedToken::Wildcard => params.push(literal_token.to_owned()), + } + } + Some(params) +} + +#[cfg(test)] +mod tests { + use super::*; + use ourios_miner::tree::parse_template; + + fn registry(entries: &[((u64, u32), &str)]) -> TemplateRegistry { + entries + .iter() + .map(|&(key, canonical)| (key, parse_template(canonical))) + .collect() + } + + #[test] + fn zero_param_template_matches_its_exact_body() { + let reg = registry(&[((7, 1), "claude_code.api_request")]); + assert_eq!( + body_literal_candidates(®, "claude_code.api_request"), + vec![BodyLiteralMatch { + template_id: 7, + template_version: 1, + params: Vec::new(), + }], + ); + } + + #[test] + fn parameterized_template_captures_the_implied_params_in_order() { + let reg = registry(&[((3, 2), "user <*> logged in from <*>")]); + assert_eq!( + body_literal_candidates(®, "user 4711 logged in from 10.0.0.3"), + vec![BodyLiteralMatch { + template_id: 3, + template_version: 2, + params: vec!["4711".to_owned(), "10.0.0.3".to_owned()], + }], + ); + } + + #[test] + fn a_literal_may_unify_with_several_templates_deterministically() { + let reg = registry(&[ + ((9, 1), "user <*> logged in"), + ((2, 1), "<*> <*> logged in"), + ((5, 1), "user rooted logged out"), + ]); + assert_eq!( + body_literal_candidates(®, "user 42 logged in"), + vec![ + BodyLiteralMatch { + template_id: 2, + template_version: 1, + params: vec!["user".to_owned(), "42".to_owned()], + }, + BodyLiteralMatch { + template_id: 9, + template_version: 1, + params: vec!["42".to_owned()], + }, + ], + ); + } + + #[test] + fn arity_and_fixed_token_mismatches_do_not_unify() { + let reg = registry(&[((1, 1), "user <*> logged in")]); + assert!(body_literal_candidates(®, "user 42 logged out").is_empty()); + assert!(body_literal_candidates(®, "user 42 logged in twice").is_empty()); + assert!(body_literal_candidates(®, "user 42").is_empty()); + } + + #[test] + fn versions_of_one_template_are_independent_candidates() { + let reg = registry(&[((4, 1), "job <*> finished"), ((4, 2), "job <*> <*>")]); + assert_eq!( + body_literal_candidates(®, "job 8 finished"), + vec![ + BodyLiteralMatch { + template_id: 4, + template_version: 1, + params: vec!["8".to_owned()], + }, + BodyLiteralMatch { + template_id: 4, + template_version: 2, + params: vec!["8".to_owned(), "finished".to_owned()], + }, + ], + ); + } + + #[test] + fn a_nul_bearing_literal_matches_no_template() { + // The parse-failure ingest path retains such bodies verbatim, so + // the physical arm alone is exact for them. + let reg = registry(&[((1, 1), "claude_code.api_request")]); + assert!(body_literal_candidates(®, "claude\0code").is_empty()); + } +} diff --git a/crates/ourios-querier/src/lib.rs b/crates/ourios-querier/src/lib.rs index 19b2a76f2..53420c2b8 100644 --- a/crates/ourios-querier/src/lib.rs +++ b/crates/ourios-querier/src/lib.rs @@ -39,6 +39,7 @@ mod alias_store; mod audit_scan; +pub mod body_match; mod compile; mod drift; pub mod dsl; From 63ad166eed986e2da2f6e08718ccb98d1b523e18 Mon Sep 17 00:00:00 2001 From: Jens Holdgaard Pedersen Date: Wed, 29 Jul 2026 02:23:09 +0200 Subject: [PATCH 2/3] refactor(querier): export the body matcher via pub use, module private Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen --- crates/ourios-querier/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/ourios-querier/src/lib.rs b/crates/ourios-querier/src/lib.rs index 53420c2b8..bd1850e77 100644 --- a/crates/ourios-querier/src/lib.rs +++ b/crates/ourios-querier/src/lib.rs @@ -39,7 +39,7 @@ mod alias_store; mod audit_scan; -pub mod body_match; +mod body_match; mod compile; mod drift; pub mod dsl; @@ -49,6 +49,7 @@ mod template_map; mod template_registry; pub use alias_store::derive_alias_map; +pub use body_match::{BodyLiteralMatch, body_literal_candidates}; pub use audit_scan::StoreRef; pub use drift::{DriftResult, DriftRow}; pub use log_row::{LogBody, LogRow, render_log_body}; From a32727e429ae3eda4a981d51b811d9b5e1fbf9c5 Mon Sep 17 00:00:00 2001 From: Jens Holdgaard Pedersen Date: Wed, 29 Jul 2026 02:23:25 +0200 Subject: [PATCH 3/3] style: rustfmt import order Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen --- crates/ourios-querier/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ourios-querier/src/lib.rs b/crates/ourios-querier/src/lib.rs index bd1850e77..12d02c841 100644 --- a/crates/ourios-querier/src/lib.rs +++ b/crates/ourios-querier/src/lib.rs @@ -49,8 +49,8 @@ mod template_map; mod template_registry; pub use alias_store::derive_alias_map; -pub use body_match::{BodyLiteralMatch, body_literal_candidates}; pub use audit_scan::StoreRef; +pub use body_match::{BodyLiteralMatch, body_literal_candidates}; pub use drift::{DriftResult, DriftRow}; pub use log_row::{LogBody, LogRow, render_log_body}; pub use template_map::{