pub mod net;
pub mod validate;
use serde_json::{json, Value};
use net::WriteMultiplier;
pub const HISTORY_KEEP_MESSAGES: usize = 6;
pub const STRIP_MARKER: &str = "[[OL-STRIP]]";
const TOKEN_BYTES: usize = 4;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Lever {
HistoryTrim,
PromptEdit,
}
impl Lever {
pub fn as_str(self) -> &'static str {
match self {
Lever::HistoryTrim => "history_trim",
Lever::PromptEdit => "prompt_edit",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Outcome {
Applied,
SkippedNetNegative,
SkippedInvalid,
SkippedStage,
}
impl Outcome {
pub fn as_str(self) -> &'static str {
match self {
Outcome::Applied => "applied",
Outcome::SkippedNetNegative => "skipped_net_negative",
Outcome::SkippedInvalid => "skipped_invalid",
Outcome::SkippedStage => "skipped_stage",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LadderStage {
Observe,
}
impl LadderStage {
pub fn as_str(self) -> &'static str {
match self {
LadderStage::Observe => "observe",
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct TransformDecision {
pub rule_id: String,
pub lever: Lever,
pub outcome: Outcome,
pub rule_version: u32,
pub bundle_revision: u32,
pub ladder_stage: LadderStage,
pub write_multiplier: WriteMultiplier,
pub tokens_gross: u64,
pub tokens_net_hundredths: i128,
}
pub const TRANSFORM_WIRE_KEYS: [&str; 9] = [
"ai.openlatch.transform.rule_id",
"ai.openlatch.transform.lever",
"ai.openlatch.transform.outcome",
"ai.openlatch.transform.rule_version",
"ai.openlatch.transform.bundle_revision",
"ai.openlatch.transform.ladder_stage",
"ai.openlatch.transform.write_multiplier",
"ai.openlatch.transform.tokens_gross",
"ai.openlatch.transform.tokens_net",
];
impl TransformDecision {
pub fn to_wire_object(&self) -> Value {
json!({
"ai.openlatch.transform.rule_id": self.rule_id,
"ai.openlatch.transform.lever": self.lever.as_str(),
"ai.openlatch.transform.outcome": self.outcome.as_str(),
"ai.openlatch.transform.rule_version": self.rule_version,
"ai.openlatch.transform.bundle_revision": self.bundle_revision,
"ai.openlatch.transform.ladder_stage": self.ladder_stage.as_str(),
"ai.openlatch.transform.write_multiplier": self.write_multiplier.value(),
"ai.openlatch.transform.tokens_gross": self.tokens_gross,
"ai.openlatch.transform.tokens_net": net::hundredths_to_numeric(self.tokens_net_hundredths),
})
}
}
enum RuleKind {
HistoryTrim { keep: usize },
PromptEdit { marker: &'static str },
}
pub struct Rule {
id: &'static str,
lever: Lever,
rule_version: u32,
bundle_revision: u32,
kind: RuleKind,
}
impl Rule {
pub fn id(&self) -> &'static str {
self.id
}
fn evaluate(&self, body: &Value, w: WriteMultiplier) -> Option<TransformDecision> {
let (gross, retained_tail, valid) = match &self.kind {
RuleKind::HistoryTrim { keep } => measure_history_trim(body, *keep)?,
RuleKind::PromptEdit { marker } => measure_prompt_edit(body, marker)?,
};
Some(self.decide(gross, retained_tail, w, valid))
}
fn decide(
&self,
tokens_gross: u64,
retained_tail: u64,
w: WriteMultiplier,
valid: bool,
) -> TransformDecision {
let (outcome, tokens_net_hundredths) =
classify_outcome(tokens_gross, retained_tail, w, valid);
TransformDecision {
rule_id: self.id.to_string(),
lever: self.lever,
outcome,
rule_version: self.rule_version,
bundle_revision: self.bundle_revision,
ladder_stage: LadderStage::Observe,
write_multiplier: w,
tokens_gross,
tokens_net_hundredths,
}
}
}
fn measure_history_trim(body: &Value, keep: usize) -> Option<(u64, u64, bool)> {
let messages = body.get("messages")?.as_array()?;
if messages.len() <= keep {
return None; }
let split = messages.len() - keep;
let (removed, retained) = messages.split_at(split);
let gross: u64 = removed.iter().map(estimate_tokens).sum();
let retained_tail: u64 = retained.iter().map(estimate_tokens).sum();
let valid = validate::history_trim_is_valid(retained);
Some((gross, retained_tail, valid))
}
fn measure_prompt_edit(body: &Value, marker: &str) -> Option<(u64, u64, bool)> {
let system = body.get("system")?.as_array()?;
let idx = system
.iter()
.position(|b| block_text_starts_with(b, marker))?;
let gross = estimate_tokens(&system[idx]);
let after_system: u64 = system[idx + 1..].iter().map(estimate_tokens).sum();
let messages_tokens: u64 = body
.get("messages")
.and_then(Value::as_array)
.map(|m| m.iter().map(estimate_tokens).sum())
.unwrap_or(0);
Some((gross, after_system + messages_tokens, true))
}
pub const BASELINE_RULES: &[Rule] = &[
Rule {
id: "OL-ECO-001",
lever: Lever::HistoryTrim,
rule_version: 1,
bundle_revision: 0,
kind: RuleKind::HistoryTrim {
keep: HISTORY_KEEP_MESSAGES,
},
},
Rule {
id: "OL-ECO-002",
lever: Lever::PromptEdit,
rule_version: 1,
bundle_revision: 0,
kind: RuleKind::PromptEdit {
marker: STRIP_MARKER,
},
},
];
pub fn evaluate_would_have(body: &Value) -> Option<TransformDecision> {
evaluate_would_have_with(body, &[])
}
pub fn evaluate_would_have_with(
body: &Value,
authored: &[crate::generated::types::PolicyRule],
) -> Option<TransformDecision> {
let w = net::write_multiplier_for(body);
let decisions: Vec<TransformDecision> = if authored.is_empty() {
BASELINE_RULES
.iter()
.filter_map(|rule| rule.evaluate(body, w))
.collect()
} else {
authored
.iter()
.filter_map(|rule| evaluate_authored(rule, body, w))
.collect()
};
decisions
.into_iter()
.max_by(|a, b| {
a.tokens_net_hundredths
.cmp(&b.tokens_net_hundredths)
.then_with(|| b.rule_id.cmp(&a.rule_id))
})
}
fn evaluate_authored(
rule: &crate::generated::types::PolicyRule,
body: &Value,
w: WriteMultiplier,
) -> Option<TransformDecision> {
if !select_matches(rule.select.as_ref(), body) {
return None;
}
let params = rule.params.as_ref();
let (lever, measured) = match rule.action.as_str() {
"history_trim" => {
let keep = usize::try_from(params?.keep_messages?).ok()?;
(Lever::HistoryTrim, measure_history_trim(body, keep)?)
}
"prompt_edit" => {
let marker = params?.marker.as_deref()?;
(Lever::PromptEdit, measure_prompt_edit(body, marker)?)
}
_ => return None,
};
let (gross, retained_tail, valid) = measured;
let (outcome, tokens_net_hundredths) = classify_outcome(gross, retained_tail, w, valid);
Some(TransformDecision {
rule_id: rule.rule_id.clone(),
lever,
outcome,
rule_version: u32::try_from(rule.rule_version.unwrap_or(1)).unwrap_or(1),
bundle_revision: 0,
ladder_stage: LadderStage::Observe,
write_multiplier: w,
tokens_gross: gross,
tokens_net_hundredths,
})
}
fn select_matches(
select: Option<&crate::generated::types::PolicyRuleSelect>,
body: &Value,
) -> bool {
let Some(select) = select else {
return true;
};
if !select.model_in.is_empty() {
let model = body.get("model").and_then(Value::as_str);
match model {
Some(m) if select.model_in.iter().any(|allowed| allowed == m) => {}
_ => return false,
}
}
if let Some(min) = select.min_messages {
let len = body
.get("messages")
.and_then(Value::as_array)
.map(|m| m.len())
.unwrap_or(0);
if i64::try_from(len).unwrap_or(i64::MAX) < min {
return false;
}
}
true
}
fn classify_outcome(
tokens_gross: u64,
retained_tail: u64,
w: WriteMultiplier,
structurally_valid: bool,
) -> (Outcome, i128) {
let net = net::tokens_net_hundredths(tokens_gross, retained_tail, w);
let outcome = if !structurally_valid {
Outcome::SkippedInvalid
} else if net <= 0 {
Outcome::SkippedNetNegative
} else {
Outcome::SkippedStage
};
(outcome, net)
}
fn estimate_tokens(v: &Value) -> u64 {
text_len(v).div_ceil(TOKEN_BYTES) as u64
}
fn text_len(v: &Value) -> usize {
match v {
Value::String(s) => s.len(),
Value::Array(a) => a.iter().map(text_len).sum(),
Value::Object(o) => o
.iter()
.map(|(k, val)| match k.as_str() {
"text" | "content" => text_len(val),
"input" => val.to_string().len(),
_ => 0,
})
.sum(),
_ => 0,
}
}
fn block_text_starts_with(block: &Value, marker: &str) -> bool {
block
.get("text")
.and_then(Value::as_str)
.is_some_and(|t| t.starts_with(marker))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classify_5m_boundary_skips_at_and_below_break_even_fires_above() {
let w = WriteMultiplier::FiveMinute;
assert_eq!(
classify_outcome(22, 2, w, true).0,
Outcome::SkippedNetNegative
);
assert_eq!(
classify_outcome(23, 2, w, true).0,
Outcome::SkippedNetNegative
);
assert_eq!(classify_outcome(24, 2, w, true).0, Outcome::SkippedStage);
}
#[test]
fn classify_1h_boundary_skips_at_and_below_break_even_fires_above() {
let w = WriteMultiplier::OneHour;
assert_eq!(
classify_outcome(37, 2, w, true).0,
Outcome::SkippedNetNegative
);
assert_eq!(
classify_outcome(38, 2, w, true).0,
Outcome::SkippedNetNegative
);
assert_eq!(classify_outcome(39, 2, w, true).0, Outcome::SkippedStage);
}
#[test]
fn structural_invalidity_beats_a_positive_net() {
let w = WriteMultiplier::FiveMinute;
let (outcome, net) = classify_outcome(10_000, 1, w, false);
assert_eq!(outcome, Outcome::SkippedInvalid);
assert!(net > 0, "net is still recorded regardless of outcome");
}
#[test]
fn phase1_never_applies() {
let w = WriteMultiplier::FiveMinute;
for (g, s, valid) in [
(0u64, 0u64, true),
(24, 2, true),
(22, 2, true),
(99, 1, false),
] {
assert_ne!(classify_outcome(g, s, w, valid).0, Outcome::Applied);
}
}
fn msg(role: &str, content: &str) -> Value {
json!({ "role": role, "content": content })
}
fn trimmable_body(large: usize, big_len: usize) -> Value {
let mut messages = Vec::new();
for _ in 0..large {
messages.push(msg("user", &"a".repeat(big_len)));
}
for _ in 0..HISTORY_KEEP_MESSAGES {
messages.push(msg("user", "hi"));
}
json!({ "model": "claude-opus-4-8", "messages": messages })
}
#[test]
fn history_trim_matches_and_reports_positive_net_as_skipped_stage() {
let body = trimmable_body(2, 400);
let d = evaluate_would_have(&body).expect("a matching L-1 rule");
assert_eq!(d.rule_id, "OL-ECO-001");
assert_eq!(d.lever, Lever::HistoryTrim);
assert_eq!(d.outcome, Outcome::SkippedStage);
assert_eq!(d.ladder_stage, LadderStage::Observe);
assert_eq!(d.write_multiplier, WriteMultiplier::FiveMinute);
assert!(d.tokens_gross > 0);
assert!(
d.tokens_net_hundredths > 0,
"positive net is recorded, not skipped as negative"
);
}
#[test]
fn history_trim_with_large_tail_is_net_negative() {
let mut messages = vec![msg("user", "x")]; for _ in 0..HISTORY_KEEP_MESSAGES {
messages.push(msg("user", &"b".repeat(400))); }
let body = json!({ "messages": messages });
let d = evaluate_would_have(&body).expect("a matching L-1 rule");
assert_eq!(d.outcome, Outcome::SkippedNetNegative);
assert!(d.tokens_net_hundredths <= 0);
}
#[test]
fn history_trim_does_not_match_a_short_conversation() {
let mut messages = Vec::new();
for _ in 0..HISTORY_KEEP_MESSAGES {
messages.push(msg("user", "hi"));
}
let body = json!({ "messages": messages });
assert!(evaluate_would_have(&body).is_none());
}
#[test]
fn one_hour_ttl_is_read_from_the_request() {
let mut messages = vec![
msg("user", &"a".repeat(400)),
msg("assistant", &"a".repeat(400)),
];
for _ in 0..HISTORY_KEEP_MESSAGES {
messages.push(msg("user", "hi"));
}
let body = json!({
"system": [
{ "type": "text", "text": "sys", "cache_control": { "type": "ephemeral", "ttl": "1h" } }
],
"messages": messages
});
let d = evaluate_would_have(&body).expect("matching rule");
assert_eq!(d.write_multiplier, WriteMultiplier::OneHour);
assert_eq!(
d.to_wire_object()["ai.openlatch.transform.write_multiplier"],
2.0
);
}
#[test]
fn prompt_edit_matches_a_marked_system_block() {
let body = json!({
"system": [
{ "type": "text", "text": format!("{STRIP_MARKER} verbose boilerplate {}", "z".repeat(400)) },
{ "type": "text", "text": "keep me" }
],
"messages": [ msg("user", "hi") ]
});
let d = evaluate_would_have(&body).expect("a matching L-2 rule");
assert_eq!(d.rule_id, "OL-ECO-002");
assert_eq!(d.lever, Lever::PromptEdit);
assert!(d.tokens_gross > 0);
}
mod l0_no_event {
use super::*;
#[test]
fn a_reorder_only_request_yields_no_transform_decision() {
let body = json!({
"model": "claude-opus-4-8",
"system": [ { "type": "text", "text": "stable system prompt" } ],
"messages": [ msg("user", "hello"), msg("assistant", "hi") ]
});
assert!(evaluate_would_have(&body).is_none());
}
#[test]
fn no_baseline_rule_is_a_reorder_lever() {
for rule in BASELINE_RULES {
assert_ne!(rule.lever.as_str(), "prefix_reorder");
assert_ne!(rule.lever.as_str(), "model_downgrade");
}
}
}
#[test]
fn evaluate_leaves_the_parsed_body_unchanged() {
let body = trimmable_body(2, 400);
let before = body.clone();
let _ = evaluate_would_have(&body);
assert_eq!(
body, before,
"the parsed clone must be untouched by evaluation"
);
}
#[test]
fn wire_object_carries_the_frozen_enums_and_no_finding_id() {
let body = trimmable_body(2, 400);
let d = evaluate_would_have(&body).unwrap();
let w = d.to_wire_object();
assert_eq!(w["ai.openlatch.transform.rule_id"], "OL-ECO-001");
assert_eq!(w["ai.openlatch.transform.lever"], "history_trim");
assert_eq!(w["ai.openlatch.transform.outcome"], "skipped_stage");
assert_eq!(w["ai.openlatch.transform.rule_version"], 1);
assert_eq!(w["ai.openlatch.transform.bundle_revision"], 0);
assert_eq!(w["ai.openlatch.transform.ladder_stage"], "observe");
assert_eq!(w["ai.openlatch.transform.write_multiplier"], 1.25);
assert!(w["ai.openlatch.transform.tokens_gross"].as_u64().unwrap() > 0);
assert!(w.get("ai.openlatch.transform.finding_id").is_none());
}
#[test]
fn wire_object_keys_match_the_null_key_list() {
use std::collections::BTreeSet;
let d = evaluate_would_have(&trimmable_body(2, 400)).expect("a matching rule");
let wire = d.to_wire_object();
let object_keys: BTreeSet<&str> = wire
.as_object()
.expect("to_wire_object is a JSON object")
.keys()
.map(String::as_str)
.collect();
let list_keys: BTreeSet<&str> = TRANSFORM_WIRE_KEYS.iter().copied().collect();
assert_eq!(
object_keys, list_keys,
"to_wire_object keys must exactly match TRANSFORM_WIRE_KEYS"
);
}
#[test]
fn evaluation_is_deterministic() {
let body = trimmable_body(3, 512);
let first = evaluate_would_have(&body)
.unwrap()
.to_wire_object()
.to_string();
for _ in 0..50 {
assert_eq!(
evaluate_would_have(&body)
.unwrap()
.to_wire_object()
.to_string(),
first
);
}
}
use crate::generated::types::{
PolicyRule, PolicyRuleMode, PolicyRuleParams, PolicyRuleSelect, PolicyRuleSeverity,
};
fn authored_trim(select: Option<PolicyRuleSelect>) -> PolicyRule {
PolicyRule {
rule_id: "OL-ECO-AUTH".to_string(),
kind: "request".to_string(),
action: "history_trim".to_string(),
conditions: Vec::new(),
match_pattern: None,
mode: PolicyRuleMode::Observe,
severity: PolicyRuleSeverity::Low,
reason: "authored".to_string(),
rule_version: Some(4),
select,
params: Some(PolicyRuleParams {
keep_messages: Some(2),
..Default::default()
}),
}
}
#[test]
fn an_authored_rule_is_evaluated_and_carries_its_own_identity() {
let body = trimmable_body(8, 512);
let d =
evaluate_would_have_with(&body, &[authored_trim(None)]).expect("authored rule matches");
assert_eq!(d.rule_id, "OL-ECO-AUTH");
assert_eq!(
d.rule_version, 4,
"the authored version, not the baseline's"
);
assert_eq!(d.lever, Lever::HistoryTrim);
}
#[test]
fn authored_rules_displace_the_baseline() {
let body = trimmable_body(8, 512);
let d = evaluate_would_have_with(&body, &[authored_trim(None)]).unwrap();
assert_eq!(d.rule_id, "OL-ECO-AUTH");
assert!(!d.rule_id.starts_with("OL-ECO-00"), "not a baseline rule");
}
#[test]
fn an_empty_authored_set_falls_back_to_the_baseline() {
let body = trimmable_body(8, 512);
assert_eq!(
evaluate_would_have_with(&body, &[]).map(|d| d.rule_id),
evaluate_would_have(&body).map(|d| d.rule_id),
);
}
#[test]
fn model_in_narrows_by_model() {
let mut body = trimmable_body(8, 512);
body["model"] = json!("claude-opus-5");
let matching = PolicyRuleSelect {
model_in: vec!["claude-opus-5".to_string()],
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(matching))]).is_some());
let other = PolicyRuleSelect {
model_in: vec!["claude-haiku-4-5".to_string()],
..Default::default()
};
assert!(
evaluate_would_have_with(&body, &[authored_trim(Some(other))]).is_none(),
"a rule scoped to another model must not evaluate"
);
}
#[test]
fn a_model_scoped_rule_does_not_apply_to_an_unreadable_model() {
let body = trimmable_body(8, 512); let select = PolicyRuleSelect {
model_in: vec!["claude-opus-5".to_string()],
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(select))]).is_none());
}
#[test]
fn min_messages_is_a_floor_that_keeps_short_sessions_untouched() {
let body = trimmable_body(8, 512);
let below = PolicyRuleSelect {
min_messages: Some(40),
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(below))]).is_none());
let met = PolicyRuleSelect {
min_messages: Some(4),
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(met))]).is_some());
}
#[test]
fn select_keys_are_anded() {
let mut body = trimmable_body(8, 64);
body["model"] = json!("claude-opus-5");
let both = PolicyRuleSelect {
model_in: vec!["claude-opus-5".to_string()],
min_messages: Some(4),
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(both))]).is_some());
let one = PolicyRuleSelect {
model_in: vec!["claude-haiku-4-5".to_string()],
min_messages: Some(4),
..Default::default()
};
assert!(evaluate_would_have_with(&body, &[authored_trim(Some(one))]).is_none());
}
#[test]
fn a_rule_missing_its_required_params_produces_no_decision() {
let mut rule = authored_trim(None);
rule.params = None;
assert!(evaluate_would_have_with(&trimmable_body(8, 512), &[rule]).is_none());
}
#[test]
fn prefix_reorder_produces_no_decision() {
let mut rule = authored_trim(None);
rule.action = "prefix_reorder".to_string();
assert!(evaluate_would_have_with(&trimmable_body(8, 512), &[rule]).is_none());
}
#[test]
fn authored_evaluation_is_deterministic() {
let mut body = trimmable_body(8, 512);
body["model"] = json!("claude-opus-5");
let select = PolicyRuleSelect {
model_in: vec!["claude-opus-5".to_string()],
..Default::default()
};
let rules = [authored_trim(Some(select))];
let first = evaluate_would_have_with(&body, &rules)
.unwrap()
.to_wire_object()
.to_string();
for _ in 0..50 {
assert_eq!(
evaluate_would_have_with(&body, &rules)
.unwrap()
.to_wire_object()
.to_string(),
first
);
}
}
#[test]
fn prompt_text_never_appears_in_the_recorded_decision() {
const SENTINEL: &str = "OPENLATCH-SELECT-SENTINEL-DEADBEEF";
let mut body = trimmable_body(8, 64);
body["model"] = json!("claude-opus-5");
body["system"] = json!([{"type": "text", "text": format!("prefix {SENTINEL} suffix")}]);
let select = PolicyRuleSelect {
model_in: vec!["claude-opus-5".to_string()],
..Default::default()
};
let wire = evaluate_would_have_with(&body, &[authored_trim(Some(select))])
.expect("the rule matches on the model")
.to_wire_object()
.to_string();
assert!(
!wire.contains(SENTINEL),
"prompt text leaked into the transform decision: {wire}"
);
}
}