use std::collections::{HashMap, HashSet};
use serde::{Deserialize, Serialize};
use crate::kv::TriggeredRef;
use crate::triggers;
pub const DEFAULT_BUDGET: usize = 2;
const DERIVED_FRAGMENT_MAX: usize = 200;
pub const FIRED_KEY: &str = "doors_fired";
#[derive(Debug, Deserialize)]
pub struct HookInput {
#[serde(default, deserialize_with = "lenient_string")]
pub session_id: String,
#[serde(default, deserialize_with = "lenient_string")]
pub prompt: String,
}
fn lenient_string<'de, D>(d: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match serde_json::Value::deserialize(d)? {
serde_json::Value::String(s) => s,
serde_json::Value::Null => String::new(),
other => other.to_string(),
})
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct FiredDoor {
pub key: String,
pub id: String,
pub trigger: String,
pub fragment: String,
pub dig: String,
}
impl FiredDoor {
pub fn render(&self) -> String {
format!(
"\u{1f6aa} {} \u{2192} {} (dig: {})",
self.trigger, self.fragment, self.dig
)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Selection {
pub fired: Vec<FiredDoor>,
pub deferred: usize,
}
pub fn strip_channel_tags(prompt: &str) -> String {
let mut out = String::with_capacity(prompt.len());
let bytes = prompt.as_bytes();
let mut i = 0;
while i < prompt.len() {
let rest = &prompt[i..];
if let Some(after) = rest.strip_prefix("</channel>") {
out.push(' ');
i += rest.len() - after.len();
continue;
}
if rest.starts_with("<channel")
&& rest[8..]
.chars()
.next()
.is_some_and(|c| c.is_whitespace() || c == '>')
{
let mut j = i + 8;
let mut in_quote = false;
let mut closed = false;
while j < prompt.len() {
match bytes[j] {
b'"' => in_quote = !in_quote,
b'>' if !in_quote => {
j += 1;
closed = true;
break;
}
_ => {}
}
j += 1;
}
if closed {
out.push(' ');
i = j;
continue;
}
out.push_str(&prompt[i..]);
break;
}
let ch = rest.chars().next().unwrap();
out.push(ch);
i += ch.len_utf8();
}
out
}
const HARNESS_BLOCKS: [&str; 2] = ["task-notification", "system-reminder"];
const LOCAL_COMMAND_PREFIX: &str = "local-command-";
fn harness_name(s: &str) -> Option<&str> {
if let Some(name) = HARNESS_BLOCKS.into_iter().find(|n| s.starts_with(n)) {
return Some(name);
}
let suffix = s.strip_prefix(LOCAL_COMMAND_PREFIX)?;
let n = suffix
.bytes()
.take_while(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || *b == b'-')
.count();
(n > 0).then(|| &s[..LOCAL_COMMAND_PREFIX.len() + n])
}
enum TagKind {
Open,
SelfClosing,
Close,
}
struct Tag<'a> {
start: usize,
end: usize,
kind: TagKind,
name: &'a str,
}
fn bare_tag(s: &str) -> Option<(TagKind, &str, usize)> {
let s = s.strip_prefix('<')?;
let (closing, s) = match s.strip_prefix('/') {
Some(s) => (true, s),
None => (false, s),
};
let name = harness_name(s)?;
let after = &s[name.len()..];
let lead = 1 + usize::from(closing) + name.len();
if after.starts_with('>') {
let kind = if closing {
TagKind::Close
} else {
TagKind::Open
};
Some((kind, name, lead + 1))
} else if !closing && after.starts_with("/>") {
Some((TagKind::SelfClosing, name, lead + 2))
} else {
None
}
}
pub fn strip_harness_blocks(prompt: &str) -> String {
let bytes = prompt.as_bytes();
let tags: Vec<Tag<'_>> = prompt
.match_indices('<')
.filter_map(|(start, _)| {
let (kind, name, len) = bare_tag(&prompt[start..])?;
let end = start + len;
let quoted = match kind {
TagKind::Open | TagKind::SelfClosing => start > 0 && bytes[start - 1] == b'`',
TagKind::Close => bytes.get(end) == Some(&b'`'),
};
(!quoted).then_some(Tag {
start,
end,
kind,
name,
})
})
.collect();
let mut block_end: Vec<Option<usize>> = vec![None; tags.len()];
let mut open: HashMap<&str, usize> = HashMap::new();
for (i, tag) in tags.iter().enumerate() {
match tag.kind {
TagKind::Open => {
open.insert(tag.name, i);
}
TagKind::Close => {
if let Some(o) = open.remove(tag.name) {
block_end[o] = Some(tag.end);
}
}
TagKind::SelfClosing => {}
}
}
let mut out = String::with_capacity(prompt.len());
let mut pos = 0;
for (i, tag) in tags.iter().enumerate() {
if tag.start < pos {
continue;
}
out.push_str(&prompt[pos..tag.start]);
out.push(' ');
pos = match tag.kind {
TagKind::Open => block_end[i].unwrap_or(tag.end),
TagKind::SelfClosing | TagKind::Close => tag.end,
};
}
out.push_str(&prompt[pos..]);
out
}
pub fn derive_fragment(value: &str, fragment: Option<&str>) -> String {
if let Some(f) = fragment {
let f = f.trim();
if !f.is_empty() {
return f.to_string();
}
}
let first_line = value.split('\n').next().unwrap_or("").trim();
if first_line.chars().count() > DERIVED_FRAGMENT_MAX {
let kept: String = first_line.chars().take(DERIVED_FRAGMENT_MAX - 1).collect();
format!("{}\u{2026}", kept)
} else {
first_line.to_string()
}
}
pub fn dig_pointer(key: &str, id: &str, memory: Option<&str>) -> String {
match memory {
Some(m) if !m.trim().is_empty() => format!("{}/kv-{}, {}", key, id, m.trim()),
_ => format!("{}/kv-{}", key, id),
}
}
const MIN_TRIGGER_TOKEN_CHARS: usize = 3;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TriggerVerdict {
Dead,
Broad { matched_as: String },
Fine { matched_as: String },
}
pub fn matched_form(trigger: &str) -> String {
triggers::tokens(trigger, false).join(" ")
}
pub fn inspect_trigger(trigger: &str) -> TriggerVerdict {
let toks = triggers::tokens(trigger, false);
if toks.is_empty() {
return TriggerVerdict::Dead;
}
let matched_as = toks.join(" ");
if toks.len() == 1 && toks[0].chars().count() < MIN_TRIGGER_TOKEN_CHARS {
TriggerVerdict::Broad { matched_as }
} else {
TriggerVerdict::Fine { matched_as }
}
}
fn specificity(trigger: &str) -> (usize, usize) {
(
triggers::tokens(trigger, false).len(),
trigger.chars().count(),
)
}
pub fn select(
prompt: &str,
candidates: &[TriggeredRef<'_>],
already_fired: &HashSet<(String, String)>,
fire_counts: &HashMap<(String, String), u64>,
budget: usize,
) -> Selection {
let text = strip_channel_tags(&strip_harness_blocks(prompt));
let message_tokens = triggers::tokens(&text, false);
if message_tokens.is_empty() {
return Selection {
fired: Vec::new(),
deferred: 0,
};
}
let mut matched: Vec<(u64, &str, FiredDoor)> = Vec::new();
for cand in candidates {
let pair = (cand.key.to_string(), cand.id.to_string());
if already_fired.contains(&pair) {
continue;
}
let hits = triggers::match_triggers(&message_tokens, cand.triggers, false);
let Some(trigger) = hits.into_iter().reduce(|best, t| {
if specificity(&t) > specificity(&best) {
t
} else {
best
}
}) else {
continue;
};
let count = fire_counts.get(&pair).copied().unwrap_or(0);
matched.push((
count,
cand.ts,
FiredDoor {
key: pair.0,
id: pair.1,
trigger,
fragment: derive_fragment(cand.value, cand.fragment),
dig: dig_pointer(cand.key, cand.id, cand.memory),
},
));
}
matched.sort_by(|a, b| {
a.0.cmp(&b.0)
.then_with(|| a.1.cmp(b.1))
.then_with(|| a.2.key.cmp(&b.2.key))
.then_with(|| a.2.id.cmp(&b.2.id))
});
let total = matched.len();
let fired: Vec<FiredDoor> = matched.into_iter().take(budget).map(|m| m.2).collect();
let deferred = total - fired.len();
Selection { fired, deferred }
}
#[cfg(test)]
mod tests {
use super::*;
const CHANNEL: &str = concat!(
r#"<channel source="matrix" chat_id="!r:s" message_id="$e" user="tester" "#,
r#"user_id="@j:s" room_name="delta">"#,
"\ngood morning widget\n</channel>"
);
fn cand<'a>(
key: &'a str,
id: &'a str,
value: &'a str,
ts: &'a str,
triggers: &'a [String],
) -> TriggeredRef<'a> {
TriggeredRef {
key,
id,
value,
ts,
triggers,
fragment: None,
memory: None,
}
}
#[test]
fn strip_channel_removes_tag_and_keeps_body() {
let out = strip_channel_tags(CHANNEL);
assert!(out.contains("good morning widget"));
assert!(
!out.contains("tester"),
"attributes must not survive: {out}"
);
assert!(!out.contains("delta"));
assert!(!out.contains("channel"));
}
#[test]
fn strip_channel_attribute_alone_does_not_fire_a_door() {
let trig = vec!["tester".to_string()];
let cands = [cand("facts", "aaa", "x", "2026-01-01T00:00:00Z", &trig)];
let sel = select(CHANNEL, &cands, &HashSet::new(), &HashMap::new(), 2);
assert!(
sel.fired.is_empty(),
"user=\"tester\" must not open a tester door"
);
}
#[test]
fn strip_channel_tolerates_gt_inside_an_attribute() {
let out = strip_channel_tags(r#"<channel room_name="a > b">hi</channel>"#);
assert_eq!(out.trim(), "hi");
}
#[test]
fn unterminated_channel_tag_does_not_swallow_the_turn() {
let out = strip_channel_tags("<channel source=\"matrix\" oops widget is here");
assert!(out.contains("widget"), "body survived: {out}");
let out = strip_channel_tags("<channel user=\"unclosed widget");
assert!(out.contains("widget"), "body survived: {out}");
}
#[test]
fn unterminated_channel_tag_still_fires_doors() {
let trig = vec!["widget".to_string()];
let cands = [cand("facts", "aaa", "v", "2026-01-01T00:00:00Z", &trig)];
let sel = select(
"<channel user=\"unclosed good morning widget",
&cands,
&HashSet::new(),
&HashMap::new(),
2,
);
assert_eq!(sel.fired.len(), 1, "a malformed tag must not lose the door");
}
#[test]
fn most_specific_trigger_is_reported() {
let trig = vec!["gerf".to_string(), "gerf_slips".to_string()];
let cands = [cand(
"doors",
"aaa",
"Gerf is GEOFF",
"2026-01-01T00:00:00Z",
&trig,
)];
let sel = select(
"gerf_slips is permanent",
&cands,
&HashSet::new(),
&HashMap::new(),
2,
);
assert_eq!(sel.fired[0].trigger, "gerf_slips");
let sel = select("ask gerf", &cands, &HashSet::new(), &HashMap::new(), 2);
assert_eq!(sel.fired[0].trigger, "gerf");
}
#[test]
fn dead_triggers_are_recognised() {
assert_eq!(inspect_trigger("\u{1f98a}"), TriggerVerdict::Dead);
assert_eq!(inspect_trigger("!!!"), TriggerVerdict::Dead);
assert_eq!(inspect_trigger("---"), TriggerVerdict::Dead);
}
#[test]
fn punctuation_names_collapse_to_a_broad_single_token() {
for (raw, becomes) in [("c++", "c"), ("c#", "c"), ("F#", "f")] {
assert_eq!(
inspect_trigger(raw),
TriggerVerdict::Broad {
matched_as: becomes.to_string()
},
"{raw} must be flagged"
);
}
}
#[test]
fn ordinary_triggers_are_fine_and_report_what_they_match() {
assert_eq!(
inspect_trigger("widget"),
TriggerVerdict::Fine {
matched_as: "widget".to_string()
}
);
assert_eq!(
inspect_trigger("ayo-"),
TriggerVerdict::Fine {
matched_as: "ayo".to_string()
}
);
assert_eq!(matched_form("gerf_slips"), "gerf slips");
assert_eq!(matched_form(".NET"), "net");
}
#[test]
fn lenient_string_accepts_a_numeric_session_id() {
let input: HookInput =
serde_json::from_str(r#"{"session_id": 12345, "prompt": "hi widget"}"#).unwrap();
assert_eq!(input.session_id, "12345");
assert_eq!(input.prompt, "hi widget");
}
#[test]
fn hook_input_tolerates_missing_null_and_unknown_fields() {
let input: HookInput = serde_json::from_str(
r#"{"prompt": "hi", "session_id": null, "something_new": {"a": 1}}"#,
)
.unwrap();
assert_eq!(input.session_id, "");
assert_eq!(input.prompt, "hi");
let bare: HookInput = serde_json::from_str("{}").unwrap();
assert_eq!(bare.prompt, "");
}
#[test]
fn specificity_prefers_more_tokens_then_more_characters() {
assert!(specificity("kon kon") > specificity("widget"));
assert!(specificity("gerf_slips") > specificity("gerf"));
assert_eq!(specificity("alpha"), specificity("bravo"));
}
#[test]
fn strip_channel_leaves_ordinary_angle_brackets() {
let out = strip_channel_tags("if a < b and c > d");
assert_eq!(out, "if a < b and c > d");
}
fn fired_on(prompt: &str, triggers: &[&str]) -> Vec<String> {
let owned: Vec<Vec<String>> = triggers.iter().map(|t| vec![t.to_string()]).collect();
let cands: Vec<TriggeredRef<'_>> = owned
.iter()
.enumerate()
.map(|(n, t)| TriggeredRef {
key: "d",
id: triggers[n],
value: "v",
ts: "2026-01-01T00:00:00Z",
triggers: t,
fragment: None,
memory: None,
})
.collect();
let mut fired: Vec<String> = select(
prompt,
&cands,
&HashSet::new(),
&HashMap::new(),
triggers.len(),
)
.fired
.into_iter()
.map(|f| f.trigger)
.collect();
fired.sort();
fired
}
#[test]
fn harness_blocks_are_removed_with_their_body() {
for (prompt, gone) in [
(
"a <task-notification>\n<status>done</status> secret\n</task-notification> b",
"secret",
),
("a <system-reminder>secret</system-reminder> b", "secret"),
(
"a <local-command-stdout>secret</local-command-stdout> b",
"secret",
),
(
"a <local-command-stderr>secret</local-command-stderr> b",
"secret",
),
(
"a <local-command-caveat>secret</local-command-caveat> b",
"secret",
),
] {
let out = strip_harness_blocks(prompt);
assert!(!out.contains(gone), "body must go: {out:?}");
assert!(!out.contains('<'), "tags must go: {out:?}");
assert_eq!(triggers::tokens(&out, false), vec!["a", "b"], "{out:?}");
}
}
#[test]
fn trigger_inside_a_harness_block_does_not_fire_but_human_text_does() {
let prompt = concat!(
"<task-notification>agent quoted widget and gizmo</task-notification>",
"<system-reminder>gizmo widget sprocket</system-reminder>",
"<local-command-stdout>sprocket</local-command-stdout>",
"\nwhat about the widget?"
);
assert_eq!(
fired_on(prompt, &["widget", "gizmo", "sprocket"]),
vec!["widget"]
);
}
#[test]
fn tag_name_trigger_does_not_fire_off_the_tag() {
assert!(
fired_on(
"<system-reminder>note</system-reminder> hi",
&["system-reminder", "task-notification"]
)
.is_empty()
);
assert!(
fired_on(
"hi </system-reminder> <system-reminder/>",
&["system-reminder"]
)
.is_empty()
);
}
#[test]
fn near_miss_names_are_not_harness_tags() {
let prompt = "<system-reminderz>keep</system-reminderz> <System-Reminder>keep2</System-Reminder> <local-command->keep3</local-command-> <local-command-Stdout>keep4</local-command-Stdout>";
let out = strip_harness_blocks(prompt);
assert_eq!(out, prompt, "only exact lowercase names are stripped");
}
#[test]
fn unclosed_opener_keeps_the_rest_as_text() {
let out = strip_harness_blocks("hi <system-reminder oops widget");
assert!(out.contains("widget"), "{out:?}");
assert_eq!(
fired_on("hi <system-reminder oops widget", &["widget"]),
vec!["widget"]
);
assert_eq!(
fired_on(
"hi <system-reminder oops widget <system-reminder>gizmo</system-reminder>",
&["widget", "gizmo"]
),
vec!["widget"]
);
}
#[test]
fn only_bare_tags_are_harness_tags() {
for prompt in [
"<system-reminder note=\"x\">widget</task-notification-not>",
"<system-reminder >widget",
"<System-Reminder>widget</System-Reminder>",
"<local-command-é>widget</local-command-é>",
"<task-notification id=\"1\"/>widget",
] {
assert_eq!(strip_harness_blocks(prompt), prompt);
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"], "{prompt:?}");
}
}
#[test]
fn prose_mention_of_a_tag_keeps_the_human_text() {
let prompt = "the <system-reminder thing keeps opening keurig -> please fix";
assert_eq!(strip_harness_blocks(prompt), prompt);
assert_eq!(fired_on(prompt, &["keurig"]), vec!["keurig"]);
}
#[test]
fn attributed_or_split_openers_are_literal_text() {
let prompt = "<system-reminder a=\">\" b=\"<\">widget</system-reminder>\n<task-notification\n id=\"1\"\n>widget</task-notification> gizmo";
assert_eq!(
strip_harness_blocks(prompt),
"<system-reminder a=\">\" b=\"<\">widget \n<task-notification\n id=\"1\"\n>widget gizmo"
);
assert_eq!(
fired_on(prompt, &["widget", "gizmo"]),
vec!["gizmo", "widget"]
);
assert_eq!(
fired_on("<system-\nreminder>widget</system-\nreminder>", &["widget"]),
vec!["widget"]
);
}
#[test]
fn opener_with_no_closing_tag_loses_only_the_tag() {
let prompt = "<system-reminder>so about the widget";
let out = strip_harness_blocks(prompt);
assert_eq!(out, " so about the widget");
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
}
#[test]
fn report_quoting_its_own_opener_in_backticks_is_removed_whole() {
let prompt = concat!(
"<task-notification>\n<status>completed</status>\n",
"<result>Ran kv update on keurig, then stripped `<task-notification>` blocks.</result>\n",
"</task-notification>\nhi"
);
assert_eq!(strip_harness_blocks(prompt), " \nhi");
assert!(fired_on(prompt, &["keurig"]).is_empty());
assert_eq!(fired_on(prompt, &["keurig", "hi"]), vec!["hi"]);
}
#[test]
fn unpaired_opener_loses_only_its_tag_between_blocks() {
let prompt = "<system-reminder>a <system-reminder>b</system-reminder> widget <system-reminder>c</system-reminder>";
assert_eq!(strip_harness_blocks(prompt), " a widget ");
}
#[test]
fn backtick_quoted_closer_inside_a_report_is_literal() {
let prompt =
"<task-notification>the `</task-notification>` closer, sprocket</task-notification>";
assert_eq!(strip_harness_blocks(prompt), " ");
assert!(fired_on(prompt, &["sprocket"]).is_empty());
}
#[test]
fn known_edge_unbackticked_quoted_closer_ends_the_block_early() {
let prompt =
"<task-notification>the </task-notification> closer, sprocket</task-notification>";
assert_eq!(strip_harness_blocks(prompt), " closer, sprocket ");
assert_eq!(fired_on(prompt, &["sprocket"]), vec!["sprocket"]);
}
#[test]
fn known_edge_human_bare_opener_and_later_bare_closer_remove_the_text_between() {
let prompt = "my <system-reminder> said keurig, and that </system-reminder> was odd widget";
assert_eq!(strip_harness_blocks(prompt), "my was odd widget");
assert_eq!(fired_on(prompt, &["keurig", "widget"]), vec!["widget"]);
}
#[test]
fn known_edge_closer_quoted_in_another_block_pairs_with_a_human_opener() {
let prompt = "I typed <task-notification> keurig <system-reminder>quote </task-notification> x</system-reminder>";
assert_eq!(strip_harness_blocks(prompt), "I typed x ");
assert!(fired_on(prompt, &["keurig"]).is_empty());
}
#[test]
fn unbackticked_quotes_in_two_reports_keep_the_human_between() {
let prompt = "<task-notification>r1 stripped <task-notification> blocks</task-notification>\nHUMAN keurig\n<task-notification>r2 the </task-notification> closer</task-notification>";
assert_eq!(
strip_harness_blocks(prompt),
" r1 stripped \nHUMAN keurig\n closer "
);
assert_eq!(fired_on(prompt, &["keurig"]), vec!["keurig"]);
}
#[test]
fn bare_mention_before_a_report_quoting_a_closer_keeps_the_human_text() {
let prompt = "I pasted <task-notification> earlier, keurig please <task-notification>report mentions </task-notification> lol</task-notification>";
assert_eq!(
strip_harness_blocks(prompt),
"I pasted earlier, keurig please lol "
);
assert_eq!(fired_on(prompt, &["keurig"]), vec!["keurig"]);
}
#[test]
fn human_bare_closer_after_an_unbackticked_report_keeps_the_human_text() {
let prompt = "<task-notification>stripped <task-notification> blocks</task-notification>\nkeurig: the </task-notification> closer is weird";
assert_eq!(fired_on(prompt, &["keurig"]), vec!["keurig"]);
}
#[test]
fn backticks_inside_a_real_body_do_not_quote_its_tags() {
let prompt = "<local-command-stdout>`widget`</local-command-stdout> gizmo";
assert_eq!(strip_harness_blocks(prompt), " gizmo");
assert_eq!(fired_on(prompt, &["widget", "gizmo"]), vec!["gizmo"]);
}
#[test]
fn backtick_adjacent_opener_is_literal_and_does_not_pair() {
let prompt = "`<system-reminder>` widget</system-reminder> gizmo";
assert_eq!(
strip_harness_blocks(prompt),
"`<system-reminder>` widget gizmo"
);
assert_eq!(
fired_on(prompt, &["widget", "gizmo"]),
vec!["gizmo", "widget"]
);
}
#[test]
fn backtick_adjacent_closer_is_literal_and_does_not_pair() {
let prompt = "<system-reminder>note `</system-reminder>` widget";
assert_eq!(
strip_harness_blocks(prompt),
" note `</system-reminder>` widget"
);
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
}
#[test]
fn backtick_adjacent_self_closing_is_literal() {
let prompt = "`<system-reminder/>` widget `<local-command-caveat/>`";
assert_eq!(strip_harness_blocks(prompt), prompt);
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
}
#[test]
fn human_bare_opener_before_a_real_block_keeps_the_human_text() {
let prompt = "why does <system-reminder> keep firing keurig\n<system-reminder>harness note</system-reminder>";
assert_eq!(
strip_harness_blocks(prompt),
"why does keep firing keurig\n "
);
assert_eq!(fired_on(prompt, &["keurig", "harness"]), vec!["keurig"]);
}
#[test]
fn quoted_opener_and_quoted_closer_in_two_reports_keep_the_human_between() {
let prompt = concat!(
"<task-notification>r1 stripped `<task-notification>` blocks</task-notification>",
"\nHUMAN keurig\n",
"<task-notification>r2 the `</task-notification>` closer</task-notification>"
);
assert_eq!(strip_harness_blocks(prompt), " \nHUMAN keurig\n ");
assert_eq!(
fired_on(prompt, &["keurig", "stripped", "closer"]),
vec!["keurig"]
);
}
#[test]
fn human_bare_closer_after_a_report_loses_only_the_tag() {
let prompt = "<task-notification>stripped `<task-notification>` blocks</task-notification>\nkeurig: the </task-notification> closer is weird";
assert_eq!(
strip_harness_blocks(prompt),
" \nkeurig: the closer is weird"
);
assert_eq!(fired_on(prompt, &["keurig", "stripped"]), vec!["keurig"]);
}
#[test]
fn backticked_mention_before_a_real_block_keeps_the_human_text() {
let prompt = "why does `<system-reminder>` keep firing keurig? <system-reminder>harness note</system-reminder>";
let out = strip_harness_blocks(prompt);
assert!(out.contains("keep firing keurig"), "{out:?}");
assert!(!out.contains("harness note"), "{out:?}");
assert_eq!(fired_on(prompt, &["keurig", "harness"]), vec!["keurig"]);
}
#[test]
fn bare_mention_before_a_real_block_keeps_the_human_text() {
let prompt = "I pasted <task-notification> earlier, keurig please <task-notification>report</task-notification>";
let out = strip_harness_blocks(prompt);
assert!(out.contains("keurig please"), "{out:?}");
assert!(!out.contains("report"), "{out:?}");
assert_eq!(fired_on(prompt, &["keurig", "report"]), vec!["keurig"]);
}
#[test]
fn stray_closer_is_removed_and_text_survives() {
let prompt = "the widget</task-notification>works";
assert_eq!(strip_harness_blocks(prompt), "the widget works");
assert_eq!(
fired_on(prompt, &["widget", "works"]),
vec!["widget", "works"]
);
}
#[test]
fn self_closing_tag_is_removed_alone() {
let prompt = "the<system-reminder/>widget <local-command-caveat/>works";
assert_eq!(strip_harness_blocks(prompt), "the widget works");
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
}
#[test]
fn self_closing_tag_does_not_open_a_block() {
let prompt = "<system-reminder/> widget </system-reminder> gizmo";
assert_eq!(strip_harness_blocks(prompt), " widget gizmo");
assert_eq!(
fired_on(prompt, &["widget", "gizmo"]),
vec!["gizmo", "widget"]
);
}
#[test]
fn known_edge_nested_same_name_leaks_the_outer_text() {
let prompt =
"<system-reminder>a<system-reminder>b</system-reminder>c</system-reminder> widget";
assert_eq!(strip_harness_blocks(prompt), " a c widget");
assert!(fired_on(prompt, &["b"]).is_empty());
}
#[test]
fn nested_different_name_goes_with_the_outer_body() {
let prompt = concat!(
"<task-notification>report <system-reminder>inner</system-reminder> ",
"<local-command-stdout>echo</local-command-stdout> tail</task-notification> widget"
);
assert_eq!(strip_harness_blocks(prompt), " widget");
assert_eq!(
fired_on(prompt, &["widget", "inner", "echo", "tail"]),
vec!["widget"]
);
}
#[test]
fn adjacent_blocks_each_go() {
let prompt = "<system-reminder>a</system-reminder><system-reminder>b</system-reminder><task-notification>c</task-notification>widget";
assert_eq!(strip_harness_blocks(prompt), " widget");
}
#[test]
fn removed_block_leaves_a_token_boundary() {
let out = strip_harness_blocks("foo<system-reminder>x</system-reminder>bar");
assert_eq!(out, "foo bar");
assert_eq!(triggers::tokens(&out, false), vec!["foo", "bar"]);
assert!(fired_on("foo<system-reminder>x</system-reminder>bar", &["foobar"]).is_empty());
}
#[test]
fn mismatched_local_command_close_does_not_swallow_the_turn() {
let prompt = "<local-command-stdout>out</local-command-stderr> widget";
assert_eq!(strip_harness_blocks(prompt), " out widget");
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
}
#[test]
fn deep_nesting_balanced() {
let n = 5_000;
let prompt = format!(
"{}widget{} gizmo",
"<system-reminder>".repeat(n),
"</system-reminder>".repeat(n)
);
assert_eq!(fired_on(&prompt, &["widget", "gizmo"]), vec!["gizmo"]);
}
#[test]
fn multibyte_hugging_tags() {
let prompt = "é<system-reminder>🦊</system-reminder>ß<local-command-stdout>\u{200b}</local-command-stdout>🦊widget";
assert_eq!(strip_harness_blocks(prompt), "é ß 🦊widget");
assert_eq!(fired_on(prompt, &["widget"]), vec!["widget"]);
for literal in [
"<system-reminder",
"<system-reminder/",
"<local-command-",
"",
] {
assert_eq!(strip_harness_blocks(literal), literal);
}
assert!(
fired_on(
"<system-reminder>widget</system-reminder><task-notification>widget</task-notification>",
&["widget"]
)
.is_empty()
);
}
#[test]
fn fuzz_multibyte_around_tags_never_panics() {
const PIECES: [&str; 22] = [
"<",
"</",
">",
"/>",
"\"",
" ",
"\n",
"x",
"é",
"🦊",
"\u{200b}",
"ß",
"system-reminder",
"task-notification",
"local-command-stdout",
"local-command-",
"local-command-é",
"<system-reminder",
"</system-reminder>",
"<channel",
"</channel>",
"<task-notification>",
];
let mut seed: u64 = 0x5eed_b0bb;
let mut next = || {
seed = seed
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
seed >> 33
};
for _ in 0..20_000 {
let len = next() % 24;
let s: String = (0..len)
.map(|_| PIECES[(next() % PIECES.len() as u64) as usize])
.collect();
let _ = strip_channel_tags(&strip_harness_blocks(&s));
let _ = fired_on(&s, &["x", "system-reminder"]);
}
}
#[test]
fn many_unbalanced_openers_stay_linear() {
use std::time::{Duration, Instant};
for unit in ["<system-reminder>x ", "<local-command-stdout>x "] {
let prompt = format!("{} widget", unit.repeat(60_000));
let t = Instant::now();
let out = strip_harness_blocks(&prompt);
let took = t.elapsed();
assert!(out.ends_with(" widget"));
assert!(
took < Duration::from_millis(500),
"{} KB of {unit:?} took {took:?}",
prompt.len() / 1024
);
}
}
#[test]
fn channel_body_still_fires_next_to_a_harness_block() {
assert_eq!(fired_on(CHANNEL, &["widget", "tester"]), vec!["widget"]);
let prompt = format!(
"<system-reminder>gizmo tester</system-reminder>{CHANNEL}<task-notification>gizmo</task-notification>"
);
assert_eq!(
fired_on(&prompt, &["widget", "gizmo", "tester"]),
vec!["widget"]
);
}
#[test]
fn harness_blocks_are_stripped_before_channel_tags() {
let prompt = concat!(
"<system-reminder>quoted <channel oops</system-reminder>",
r#"<channel source="matrix" user="tester">widget</channel>"#
);
assert_eq!(
fired_on(prompt, &["widget", "quoted", "tester"]),
vec!["widget"]
);
}
#[test]
fn authored_fragment_is_verbatim_however_long() {
let long = "z".repeat(400);
assert_eq!(derive_fragment("value", Some(&long)), long);
}
#[test]
fn derived_fragment_is_the_first_line() {
assert_eq!(
derive_fragment(" first line \nsecond line", None),
"first line"
);
}
#[test]
fn derived_fragment_cuts_on_a_char_boundary() {
let mut line = "a".repeat(198);
line.push('é');
line.push_str(&"b".repeat(60));
let out = derive_fragment(&line, None);
assert_eq!(out.chars().count(), DERIVED_FRAGMENT_MAX);
assert!(out.ends_with('\u{2026}'));
assert!(out.contains('é'), "the boundary char must survive intact");
}
#[test]
fn empty_authored_fragment_falls_back_to_first_line() {
assert_eq!(derive_fragment("the value", Some(" ")), "the value");
}
#[test]
fn dig_pointer_shapes() {
assert_eq!(dig_pointer("doors", "2gRwr9", None), "doors/kv-2gRwr9");
assert_eq!(
dig_pointer("doors", "2gRwr9", Some("kn-02e73234")),
"doors/kv-2gRwr9, kn-02e73234"
);
}
#[test]
fn widget_fires_from_inside_a_channel_block() {
let trig = vec!["widget".to_string()];
let cands = [cand(
"facts",
"3gtR1J",
"A sample fragment for the widget door.",
"2026-01-01T00:00:00Z",
&trig,
)];
let sel = select(CHANNEL, &cands, &HashSet::new(), &HashMap::new(), 2);
assert_eq!(sel.fired.len(), 1);
assert_eq!(sel.fired[0].trigger, "widget");
assert_eq!(sel.fired[0].dig, "facts/kv-3gtR1J");
assert_eq!(
sel.fired[0].render(),
"\u{1f6aa} widget \u{2192} A sample fragment for the widget door. (dig: facts/kv-3gtR1J)"
);
}
#[test]
fn already_fired_entry_is_skipped() {
let trig = vec!["widget".to_string()];
let cands = [cand("facts", "aaa", "v", "2026-01-01T00:00:00Z", &trig)];
let fired: HashSet<(String, String)> = [("facts".to_string(), "aaa".to_string())]
.into_iter()
.collect();
let sel = select("hi widget", &cands, &fired, &HashMap::new(), 2);
assert!(sel.fired.is_empty());
assert_eq!(
sel.deferred, 0,
"a deduped door is not deferred, it is done"
);
}
#[test]
fn dedup_tuple_includes_the_key() {
let trig = vec!["widget".to_string()];
let cands = [
cand("facts", "same01", "a", "2026-01-01T00:00:00Z", &trig),
cand("doors", "same01", "b", "2026-01-02T00:00:00Z", &trig),
];
let fired: HashSet<(String, String)> = [("facts".to_string(), "same01".to_string())]
.into_iter()
.collect();
let sel = select("widget", &cands, &fired, &HashMap::new(), 2);
assert_eq!(sel.fired.len(), 1);
assert_eq!(sel.fired[0].key, "doors");
}
#[test]
fn budget_overflow_defers_the_most_fired() {
let trig = vec!["widget".to_string()];
let cands = [
cand("d", "aaa", "a", "2026-01-01T00:00:00Z", &trig),
cand("d", "bbb", "b", "2026-01-01T00:00:00Z", &trig),
cand("d", "ccc", "c", "2026-01-01T00:00:00Z", &trig),
];
let counts: HashMap<(String, String), u64> = [
(("d".to_string(), "aaa".to_string()), 7),
(("d".to_string(), "bbb".to_string()), 1),
(("d".to_string(), "ccc".to_string()), 0),
]
.into_iter()
.collect();
let sel = select("widget", &cands, &HashSet::new(), &counts, 2);
assert_eq!(sel.deferred, 1);
let ids: Vec<&str> = sel.fired.iter().map(|f| f.id.as_str()).collect();
assert_eq!(ids, vec!["ccc", "bbb"], "least-fired first");
}
#[test]
fn tie_on_fire_count_breaks_to_oldest_ts() {
let trig = vec!["widget".to_string()];
let cands = [
cand("d", "new", "n", "2026-06-01T00:00:00Z", &trig),
cand("d", "old", "o", "2020-01-01T00:00:00Z", &trig),
];
let sel = select("widget", &cands, &HashSet::new(), &HashMap::new(), 1);
assert_eq!(sel.fired.len(), 1);
assert_eq!(sel.fired[0].id, "old");
}
#[test]
fn no_match_is_an_empty_selection() {
let trig = vec!["widget".to_string()];
let cands = [cand("d", "aaa", "a", "2026-01-01T00:00:00Z", &trig)];
let sel = select("hello there", &cands, &HashSet::new(), &HashMap::new(), 2);
assert!(sel.fired.is_empty());
assert_eq!(sel.deferred, 0);
}
#[test]
fn stemming_is_off_so_tagalog_ayos_does_not_open_the_ayo_door() {
let trig = vec!["ayo-".to_string()];
let cands = [cand(
"d",
"aaa",
"shell alias",
"2026-01-01T00:00:00Z",
&trig,
)];
assert!(
select("ayos lang", &cands, &HashSet::new(), &HashMap::new(), 2)
.fired
.is_empty()
);
assert_eq!(
select(
"switched to ayo-mirage",
&cands,
&HashSet::new(),
&HashMap::new(),
2
)
.fired
.len(),
1
);
}
}