#![allow(clippy::expect_used, clippy::unwrap_used)]
use super::*;
use crate::db::{CreateEvidenceSpanInput, CreateSessionInput, CreateWorkspaceInput};
use serde_json::json;
struct Fixture {
workspace_id: String,
db: DbConnection,
}
impl Fixture {
fn new() -> Self {
let workspace_id =
crate::models::WorkspaceId::from_uuid(uuid::Uuid::from_u128(0x59)).to_string();
let db = DbConnection::open_memory().unwrap();
db.migrate().unwrap();
db.insert_workspace(
&workspace_id,
&CreateWorkspaceInput {
path: "/tmp/incident-card-pack".to_owned(),
name: None,
},
)
.unwrap();
Self { workspace_id, db }
}
fn session(&self, seed: u128) -> String {
let id = crate::models::SessionId::from_uuid(uuid::Uuid::from_u128(seed)).to_string();
self.db
.insert_session(
&id,
&CreateSessionInput {
workspace_id: self.workspace_id.clone(),
cass_session_id: format!("/sessions/{seed}.jsonl"),
source_path: None,
agent_name: Some("claude_code".to_owned()),
model: None,
started_at: None,
ended_at: None,
message_count: 0,
token_count: None,
content_hash: format!("blake3:{}", blake3::hash(&seed.to_le_bytes()).to_hex()),
metadata_json: None,
},
)
.unwrap();
id
}
fn line(
&self,
session_id: &str,
number: u32,
span_kind: &str,
role: &str,
record: &serde_json::Value,
) -> String {
self.excerpt(
session_id,
number,
span_kind,
Some(role),
&record.to_string(),
)
}
fn excerpt(
&self,
session_id: &str,
number: u32,
span_kind: &str,
role: Option<&str>,
excerpt: &str,
) -> String {
let digest = blake3::hash(format!("{session_id}:{number}").as_bytes());
let mut seed = [0_u8; 16];
seed.copy_from_slice(&digest.as_bytes()[..16]);
let id = EvidenceId::from_uuid(uuid::Uuid::from_bytes(seed)).to_string();
self.db
.insert_evidence_span(
&id,
&CreateEvidenceSpanInput {
workspace_id: self.workspace_id.clone(),
session_id: session_id.to_owned(),
memory_id: None,
producer_kind: crate::db::EvidenceProducerKind::CassImport,
cass_span_id: format!("{session_id}:{number}"),
span_kind: span_kind.to_owned(),
start_line: number,
end_line: number,
start_byte: None,
end_byte: None,
role: role.map(str::to_owned),
content_hash: format!("blake3:{}", blake3::hash(excerpt.as_bytes()).to_hex()),
excerpt: excerpt.to_owned(),
metadata_json: None,
inherited_redaction_classes: Vec::new(),
},
)
.unwrap();
id
}
fn incident(&self, seed: u128, explanation: &str) -> (String, String) {
let session_id = self.session(seed);
self.line(
&session_id,
1,
"tool_call",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant", "content": [
{"type": "tool_use", "id": "toolu_1", "name": "Bash", "input": {"command": "cargo build"}}
]}}),
);
let failure = self.line(
&session_id,
2,
"tool_result",
"user",
&json!({"type": "user", "message": {"role": "user", "content": [
{"type": "tool_result", "tool_use_id": "toolu_1", "is_error": true,
"content": "error[E0277]: the trait bound `Widget: Serialize` is not satisfied"}
]}}),
);
let repair = self.line(
&session_id,
3,
"message",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant", "content": [
{"type": "text", "text": explanation}
]}}),
);
self.line(
&session_id,
4,
"tool_call",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant", "content": [
{"type": "tool_use", "id": "toolu_2", "name": "Bash", "input": {"command": "cargo build"}}
]}}),
);
self.line(
&session_id,
5,
"tool_result",
"user",
&json!({"type": "user", "message": {"role": "user", "content": [
{"type": "tool_result", "tool_use_id": "toolu_2", "is_error": false,
"content": "Finished dev profile"}
]}}),
);
let report = crate::core::cass_error_recall::record_session_error_recall(
&self.db,
&self.workspace_id,
&session_id,
)
.unwrap();
assert_eq!(report.incident_cards_recorded, 1);
(
repair,
crate::core::incident_card::incident_card_id(&self.workspace_id, &failure),
)
}
fn candidate(&self, evidence_id: &str, relevance: f32) -> DirectEvidencePackCandidate {
let span = self.db.get_evidence_span(evidence_id).unwrap().unwrap();
direct_evidence_pack_candidate(span, relevance, "lexical", "widget serialize", None)
.unwrap()
}
}
#[test]
fn transcript_pack_candidates_spend_tokens_on_observed_text_and_keep_source_identity() {
let fixture = Fixture::new();
let session = fixture.session(0x45_0101);
let body = "Résumé: pin the clock in the replay fixture before hashing.";
let id = fixture.line(
&session,
17,
"message",
"assistant",
&json!({
"parentUuid": "fixture-parent", "isSidechain": false,
"promptId": "fixture-prompt", "type": "assistant",
"message": {"role": "assistant", "content": [
{"type": "thinking", "thinking": "Private reasoning. ".repeat(200)},
{"type": "text", "text": body}
]}
}),
);
let before = fixture.db.get_evidence_span(&id).unwrap().unwrap();
let candidate = fixture.candidate(&id, 0.9);
let expected = format!("assistant: {body}");
assert_eq!(candidate.item.content, expected);
assert_eq!(
candidate.item.estimated_tokens,
estimate_tokens_default(&expected)
);
assert!(candidate.item.estimated_tokens < estimate_tokens_default(&before.excerpt));
assert_eq!(candidate.item.evidence_id, id);
assert_eq!(candidate.item.session_id, session);
assert_eq!(
(candidate.item.start_line, candidate.item.end_line),
(17, 17)
);
assert_eq!(
candidate.item.entity_revision,
before.pack_entity_revision()
);
let after = fixture.db.get_evidence_span(&id).unwrap().unwrap();
assert_eq!(after.excerpt, before.excerpt);
assert_eq!(after.content_hash, before.content_hash);
}
#[test]
fn transcript_pack_candidates_refuse_a_record_without_observed_text() {
let fixture = Fixture::new();
let session = fixture.session(0x45_0102);
for (index, record) in [
json!({"type": "assistant", "content": [
{"type": "thinking", "thinking": "Unobserved repair canary"}
]}),
json!({"type": "assistant", "channel": "analysis", "content": "Unobserved analysis."}),
json!({"type": "assistant", "content": "first body", "message": "second body"}),
json!({"type": "assistant", "content": [
{"type": "unknown", "text": "Unknown block canary"}
]}),
]
.iter()
.enumerate()
{
let id = fixture.line(&session, index as u32 + 1, "message", "assistant", record);
let span = fixture.db.get_evidence_span(&id).unwrap().unwrap();
assert!(direct_evidence_pack_candidate(span, 1.0, "lexical", "repair", None).is_none());
}
}
#[test]
fn matched_turns_keep_distinct_repairs_for_the_same_error_class() {
let fixture = Fixture::new();
let (first_turn, first_card) = fixture.incident(
0x59_0101,
"Widget needs to derive Serialize because the store writes it. Added the derive in src/widget.rs.",
);
let (second_turn, second_card) = fixture.incident(
0x59_0102,
"Widget was accidentally passed to the audit serializer, so I changed src/audit.rs to serialize WidgetSummary instead.",
);
assert_ne!(first_card, second_card);
let unrelated_session = fixture.session(0x59_0103);
let unrelated = fixture.line(
&unrelated_session,
1,
"message",
"user",
&json!({"type": "user", "message": {"role": "user", "content": "Please serialize the widget cache too."}}),
);
let preferred = prefer_incident_cards(
&fixture.db,
std::slice::from_ref(&fixture.workspace_id),
&crate::models::QueryFilters::default(),
"widget serialize",
vec![
fixture.candidate(&first_turn, 0.9),
fixture.candidate(&unrelated, 0.7),
fixture.candidate(&second_turn, 0.6),
],
);
let ids = preferred
.iter()
.map(|candidate| candidate.item.evidence_id.as_str())
.collect::<Vec<_>>();
assert_eq!(
ids,
vec![
first_card.as_str(),
unrelated.as_str(),
second_card.as_str()
],
);
let card = &preferred[0];
assert!(card.incident_card);
assert_eq!(
card.item.trust.subclass.as_deref(),
Some("derived_incident_card")
);
assert_eq!(
card.item.relevance.into_inner(),
0.9,
"the card takes the turn's rank"
);
assert_eq!((card.item.start_line, card.item.end_line), (1, 5));
assert!(
card.item
.content
.starts_with(crate::core::incident_card::INCIDENT_CARD_PREFIX)
);
assert!(
card.item
.why
.contains(&format!("through its source turn {first_turn}")),
"{}",
card.item.why
);
assert!(
card.item
.why
.contains("error class rustc:E0277 was seen in 2 incidents"),
"{}",
card.item.why
);
assert!(!preferred[1].incident_card);
assert!(preferred[2].incident_card);
assert_eq!(preferred[2].item.relevance.into_inner(), 0.6);
assert!(preferred[2].item.content.contains("WidgetSummary"));
assert!(
preferred[2]
.item
.why
.contains(&format!("through its source turn {second_turn}")),
);
assert!(preferred[2].item.why.contains("seen in 2 incidents"));
assert_ne!(preferred[0].item.content, preferred[2].item.content);
let direct = prefer_incident_cards(
&fixture.db,
std::slice::from_ref(&fixture.workspace_id),
&crate::models::QueryFilters::default(),
"widget serialize",
vec![
fixture.candidate(&first_turn, 0.9),
fixture.candidate(&first_card, 0.5),
],
);
assert_eq!(direct.len(), 1);
assert_eq!(direct[0].item.evidence_id, first_card);
assert_eq!(direct[0].item.relevance.into_inner(), 0.5);
}
#[test]
fn caller_floor_preserves_a_strong_turn_hidden_by_a_weak_matched_card() {
let fixture = Fixture::new();
let (turn_id, card_id) = fixture.incident(
0x59_0201,
"Widget needs to derive Serialize because the store writes it. Added the derive in src/widget.rs.",
);
let hits = [(turn_id.as_str(), 0.9_f32), (card_id.as_str(), 0.5)]
.into_iter()
.map(|(id, final_relevance)| SearchHit {
doc_id: id.to_owned(),
score: 0.9,
source: ScoreSource::Lexical,
fast_score: None,
quality_score: None,
lexical_score: Some(0.9),
rerank_score: None,
metadata: Some(json!({
"_ee_quality_scoring": {
"schema": crate::search::scoring::SEARCH_SCORING_POLICY_V1,
"rankingBound": 2.0,
"components": { "finalScore": final_relevance * 2.0 }
}
})),
explanation: None,
})
.collect::<Vec<_>>();
assert!(
hits.iter()
.all(|hit| { crate::core::search::search_hit_meets_relevance_floor(hit, Some(0.7)) })
);
assert_eq!(hits[0].ranking_relevance_score(), 0.9);
assert_eq!(hits[1].ranking_relevance_score(), 0.5);
let mut search = SearchReport {
index_freshness: None,
status: SearchStatus::Success,
embed_backend: EmbedBackend::HashFallback,
query: "widget serialize".to_owned(),
requested_limit: 2,
results: hits,
elapsed_ms: 0.0,
errors: Vec::new(),
degraded: Vec::new(),
runtime_profile: RuntimeProfileReport::for_profile(
crate::core::profile::OperatingProfile::Workstation,
"test_fixture",
),
rerank_configured_mode: crate::config::SearchRerankMode::Auto,
rerank_configured_top_k: 50,
rerank_runtime_available: false,
relevance_floor_applied: Some(0.0),
candidates_below_floor: 0,
query_assist: None,
source_mode_requested: SearchSourceMode::LexicalOnly,
source_mode_applied: SearchSourceMode::LexicalOnly,
source_mode_fallback: false,
strict_source_mode: false,
memory_scope: MemoryScope::Swarm,
strict_scope: false,
scope_stats: MemoryScopeStats::new(MemoryScope::Swarm, false, None, 0),
};
let request = ContextRequest::new(ContextRequestInput::for_query("widget serialize")).unwrap();
for (floor, expected_relevance) in [(None, 0.5), (Some(0.7), 0.9)] {
search.relevance_floor_applied = Some(floor.unwrap_or(0.0));
let mut degraded = Vec::new();
let mut candidates = collect_direct_evidence_pack_candidates(
&fixture.db,
Path::new("/tmp/incident-card-pack"),
&search,
&request,
&crate::models::QueryFilters::default(),
floor,
&mut degraded,
)
.unwrap();
let _ = filter_context_pack_candidates_by_relevance_floor(
&mut Vec::new(),
&mut Vec::new(),
&mut candidates,
floor,
&mut degraded,
)
.unwrap();
assert_eq!(candidates.len(), 1);
assert_eq!(candidates[0].item.evidence_id, card_id);
assert_eq!(
candidates[0].item.relevance.into_inner(),
expected_relevance
);
assert!(candidates[0].incident_card);
assert_eq!(
candidates[0]
.item
.why
.contains(&format!("through its source turn {turn_id}")),
floor.is_some(),
);
if floor.is_some() {
assert!(degraded.iter().any(|entry| {
entry.code == "context_filtered_results"
&& entry.message.contains("1 imported evidence")
&& entry.message.contains("caller relevance floor 0.7000")
}));
} else {
assert!(degraded.is_empty());
}
}
}
#[test]
fn evidence_far_below_the_best_match_stays_out_of_the_pack() {
let fixture = Fixture::new();
let session = fixture.session(0x59_0201);
let mut lines = Vec::new();
for (number, text) in [
(1, "Clippy needless_borrow fails CI under -D warnings."),
(2, "Remove the borrow so encode_key takes the owned string."),
(3, "Decision: use SQLite in WAL mode for the cache."),
] {
lines.push(fixture.line(
&session,
number,
"message",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant",
"content": [{"type": "text", "text": text}]}}),
));
}
let mut candidates = vec![
fixture.candidate(&lines[0], 0.56),
fixture.candidate(&lines[1], 0.14),
fixture.candidate(&lines[2], 0.04),
];
let mut degraded = Vec::new();
apply_direct_evidence_query_relative_floor(&mut candidates, &mut degraded);
let kept = candidates
.iter()
.map(|candidate| candidate.item.evidence_id.as_str())
.collect::<Vec<_>>();
assert_eq!(kept, vec![lines[0].as_str(), lines[1].as_str()]);
assert_eq!(degraded.len(), 1);
assert_eq!(degraded[0].code, "context_evidence_below_relative_floor");
assert!(
degraded[0]
.message
.starts_with("1 imported evidence candidate(s)")
);
let mut flat = vec![
fixture.candidate(&lines[0], 0.0),
fixture.candidate(&lines[2], 0.0),
];
let mut degraded = Vec::new();
apply_direct_evidence_query_relative_floor(&mut flat, &mut degraded);
assert_eq!(flat.len(), 2);
assert!(degraded.is_empty());
}
#[test]
fn identical_projected_evidence_is_packed_once_without_merging_distinct_facts() {
let fixture = Fixture::new();
let mut ids = Vec::new();
for (seed, text) in [
(
0x59_0301,
"Published tally 1.2.0. Lesson for next time: bump the version in Cargo.toml and commit it before running cargo publish.",
),
(
0x59_0302,
"Published sprocket 0.11.0. Lesson for next time: bump the version in Cargo.toml and commit it before running cargo publish.",
),
(
0x59_0303,
"Clippy runs with -D warnings in CI, so fix needless_borrow before pushing.",
),
(
0x59_0304,
"Published tally 1.2.0. Lesson for next time: bump the version in Cargo.toml and commit it before running cargo publish.",
),
] {
let session = fixture.session(seed);
ids.push(fixture.line(
&session,
1,
"message",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant",
"content": [{"type": "text", "text": text}]}}),
));
}
let mut candidates = vec![
fixture.candidate(&ids[0], 0.56),
fixture.candidate(&ids[1], 0.56),
fixture.candidate(&ids[2], 0.40),
fixture.candidate(&ids[3], 0.30),
];
let before = ids
.iter()
.map(|id| fixture.db.get_evidence_span(id).unwrap().unwrap())
.collect::<Vec<_>>();
let mut degraded = Vec::new();
collapse_duplicate_evidence(&mut candidates, &mut degraded);
let kept = candidates
.iter()
.map(|candidate| candidate.item.evidence_id.as_str())
.collect::<Vec<_>>();
assert_eq!(
kept,
vec![ids[0].as_str(), ids[1].as_str(), ids[2].as_str()],
);
assert_eq!(candidates[0].item.relevance.into_inner(), 0.56);
assert_eq!(degraded.len(), 1);
assert_eq!(
degraded[0].code,
"context_evidence_near_duplicates_collapsed"
);
assert!(
degraded[0]
.message
.starts_with("1 imported evidence candidate(s)")
);
let mut repeated_degraded = Vec::new();
collapse_duplicate_evidence(&mut candidates, &mut repeated_degraded);
assert!(repeated_degraded.is_empty());
for span in before {
assert_eq!(fixture.db.get_evidence_span(&span.id).unwrap(), Some(span));
}
}
#[test]
fn stored_evidence_keeps_numbers_negation_command_order_and_late_qualifications() {
let fixture = Fixture::new();
let session_id = fixture.session(0x45_0401);
let shared = "The complete migration was checked against the persisted replay. ".repeat(20);
let texts = [
"Use protocol 17 after the compatibility tests pass.".to_owned(),
"Use protocol 18 after the compatibility tests pass.".to_owned(),
"The release must include checksum verification before publishing the final artifact."
.to_owned(),
"The release must not include checksum verification before publishing the final artifact."
.to_owned(),
"Use cp source.txt destination.txt for the inspected output.".to_owned(),
"Use cp destination.txt source.txt for the inspected output.".to_owned(),
format!("{shared}Only use protocol 17 in this case."),
format!("{shared}Never use protocol 17 in this case."),
];
let mut ids = Vec::new();
for (index, text) in texts.iter().enumerate() {
ids.push(fixture.line(
&session_id,
index as u32 + 1,
"message",
"assistant",
&json!({"type": "assistant", "message": {"role": "assistant", "content": text}}),
));
}
let session = fixture.db.get_session(&session_id).unwrap().unwrap();
for id in &ids {
assert!(
fixture
.db
.get_evidence_span(id)
.unwrap()
.unwrap()
.is_search_admitted_for_session(&fixture.workspace_id, &session)
);
}
let mut candidates = ids
.iter()
.map(|id| fixture.candidate(id, 0.8))
.collect::<Vec<_>>();
let before = candidates
.iter()
.map(|candidate| candidate.item.clone())
.collect::<Vec<_>>();
let mut degraded = Vec::new();
collapse_duplicate_evidence(&mut candidates, &mut degraded);
assert!(degraded.is_empty());
assert_eq!(
candidates
.iter()
.map(|candidate| &candidate.item)
.collect::<Vec<_>>(),
before.iter().collect::<Vec<_>>()
);
assert_eq!(candidates.len(), texts.len());
for (index, candidate) in candidates.iter().enumerate() {
assert_eq!(
candidate.item.content,
format!("assistant: {}", texts[index])
);
assert_eq!(candidate.item.evidence_id, ids[index]);
assert_eq!(
(candidate.item.start_line, candidate.item.end_line),
(index as u32 + 1, index as u32 + 1)
);
}
}
#[test]
fn plain_reader_bodies_retain_their_original_source_roles_and_kinds() {
let fixture = Fixture::new();
let session_id = fixture.session(0x45_0402);
let text = "The compatibility test passed after pinning the protocol version.";
let mut ids = Vec::new();
for (index, (kind, role)) in [
("message", Some("user")),
("message", Some("assistant")),
("message", None),
("summary", None),
("message", Some("assistant")),
]
.into_iter()
.enumerate()
{
ids.push(fixture.excerpt(&session_id, index as u32 + 1, kind, role, text));
}
let session = fixture.db.get_session(&session_id).unwrap().unwrap();
for id in &ids {
let row = fixture.db.get_evidence_span(id).unwrap().unwrap();
assert!(row.is_search_admitted_for_session(&fixture.workspace_id, &session));
assert_eq!(
row.reader_text(),
text,
"historical plain text has no embedded role label"
);
}
let mut candidates = ids
.iter()
.map(|id| fixture.candidate(id, 0.8))
.collect::<Vec<_>>();
let mut degraded = Vec::new();
collapse_duplicate_evidence(&mut candidates, &mut degraded);
assert_eq!(
candidates
.iter()
.map(|candidate| candidate.item.evidence_id.as_str())
.collect::<Vec<_>>(),
ids[..4].iter().map(String::as_str).collect::<Vec<_>>()
);
assert_eq!(candidates[0].source_role.as_deref(), Some("user"));
assert_eq!(candidates[1].source_role.as_deref(), Some("assistant"));
assert_eq!(candidates[2].source_role, None);
assert_eq!(candidates[3].span_kind, "summary");
assert_eq!(degraded.len(), 1);
assert!(
degraded[0]
.message
.starts_with("1 imported evidence candidate(s)")
);
}