#![allow(dead_code)]
use serde::Serialize;
use crate::root_cause_taxonomy::RootCauseFamily;
use crate::search::incident_categories::IncidentCategory;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub(crate) struct IssueClassFixture {
pub issue_id: &'static str,
pub title: &'static str,
pub root_cause_family: RootCauseFamily,
pub category: IncidentCategory,
pub expected_behavior: &'static str,
pub safe_next_command: &'static str,
pub proof_command: &'static str,
}
static CORPUS: &[IssueClassFixture] = &[
IssueClassFixture {
issue_id: "#110",
title: "chunked FTS rebuild OOM risk",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::QuarantineOom,
expected_behavior: "rebuild bounds memory and quarantines the poison chunk rather than OOM-killing the run",
safe_next_command: "cass diag --json --quarantine",
proof_command: "cargo test --lib indexer::quarantine",
},
IssueClassFixture {
issue_id: "#120",
title: "remote auth fallback",
root_cause_family: RootCauseFamily::RemoteTransportAuth,
category: IncidentCategory::RemoteSyncAuth,
expected_behavior: "auth/transport failure surfaces a stable err.kind with a reconnect hint; no destructive local action",
safe_next_command: "cass sources list --json",
proof_command: "cargo test --test e2e_sources",
},
IssueClassFixture {
issue_id: "#137",
title: "current:0 stream misread as stalled",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::IndexStallProgress,
expected_behavior: "a current:0 stream with live forward progress reads as building, not stalled",
safe_next_command: "cass status --json",
proof_command: "cargo test --lib search::liveness_fixtures",
},
IssueClassFixture {
issue_id: "#196",
title: "lock heartbeat without forward progress",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::IndexStallProgress,
expected_behavior: "heartbeat-without-progress reads as stalled/waiting-on-lock and prompts attach, not an open-ended wait",
safe_next_command: "cass status --json",
proof_command: "cargo test --lib search::liveness_fixtures",
},
IssueClassFixture {
issue_id: "#247",
title: "historical salvage zero-new loop",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::WatchSalvageIssues,
expected_behavior: "a zero-new bundle is skipped via the granular ledger instead of a 5-12 minute re-scan",
safe_next_command: "cass status --json",
proof_command: "cargo test --lib search::salvage_ledger",
},
IssueClassFixture {
issue_id: "#248",
title: "watch OOM restart loop",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::WatchSalvageIssues,
expected_behavior: "after an OOM-kill a bounded checkpointed recovery is chosen; sparse detection never forces a full rebuild loop",
safe_next_command: "cass status --json",
proof_command: "cargo test --lib search::watch_recovery",
},
IssueClassFixture {
issue_id: "#250",
title: "watch exit code 9 with no reason",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::WatchSalvageIssues,
expected_behavior: "watch exit emits a parseable envelope (kind/subsystem/retryability/next command), not a bare code 9",
safe_next_command: "cass health --json",
proof_command: "cargo test --lib search::watch_exit_envelope",
},
IssueClassFixture {
issue_id: "#257",
title: "semantic progress/checkpoint/quality tier",
root_cause_family: RootCauseFamily::SemanticAssets,
category: IncidentCategory::Semantic,
expected_behavior: "semantic backfill exposes ordered progress events; a tier is never published if it would lie about DB coverage",
safe_next_command: "cass status --json",
proof_command: "cargo test --lib search::semantic_publish_safety",
},
IssueClassFixture {
issue_id: "#258",
title: "legacy quarantine retry carry-over",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::QuarantineOom,
expected_behavior: "a legacy quarantine record (no version) is retry-eligible, not silently orphaned forever",
safe_next_command: "cass diag --json --quarantine",
proof_command: "cargo test --lib indexer::quarantine",
},
IssueClassFixture {
issue_id: "openread-fts-messages",
title: "OpenRead / fts_messages cursor failure",
root_cause_family: RootCauseFamily::FrankensqliteStorage,
category: IncidentCategory::StorageBusyCorrupt,
expected_behavior: "an OpenRead/FTS failure is classified openread_failed/fts_metadata_failed with archive-risk handling, not generic stale-index advice",
safe_next_command: "cass doctor --json",
proof_command: "cargo test --lib search::storage_integrity",
},
IssueClassFixture {
issue_id: "database-busy",
title: "database busy / locked",
root_cause_family: RootCauseFamily::FrankensqliteStorage,
category: IncidentCategory::StorageBusyCorrupt,
expected_behavior: "a busy lock is reported busy_or_locked with the check skipped (not_checked), canonical rows still trustworthy",
safe_next_command: "cass doctor --json",
proof_command: "cargo test --lib search::storage_integrity",
},
IssueClassFixture {
issue_id: "missing-lexical-metadata",
title: "missing lexical metadata",
root_cause_family: RootCauseFamily::CassDerivedState,
category: IncidentCategory::IndexStaleMissing,
expected_behavior: "absent lexical metadata reads as missing (repair lexical), distinct from stale-but-searchable",
safe_next_command: "cass index --full",
proof_command: "cargo test --lib search::readiness",
},
IssueClassFixture {
issue_id: "workspace-mismatch",
title: "workspace/source-path mismatch zero-hit",
root_cause_family: RootCauseFamily::WorkspaceProvenance,
category: IncidentCategory::SearchZeroWorkspace,
expected_behavior: "a zero-result workspace filter suggests canonical workspaces rather than reading as a true empty",
safe_next_command: "cass sources list --json",
proof_command: "cargo test --lib search::workspace_source_fixtures",
},
IssueClassFixture {
issue_id: "noisy-dependency-logging",
title: "noisy dependency logging / attribution",
root_cause_family: RootCauseFamily::Unknown,
category: IncidentCategory::DependencyAttribution,
expected_behavior: "dependency-attribution incidents are gated behind explicit trace surfaces and attributed, not silently noisy",
safe_next_command: "cass diag --json",
proof_command: "cargo test --lib search::incident_categories",
},
];
pub(crate) fn regression_corpus() -> &'static [IssueClassFixture] {
CORPUS
}
pub(crate) fn issue_fixture(issue_id: &str) -> Option<&'static IssueClassFixture> {
CORPUS.iter().find(|f| f.issue_id == issue_id)
}
#[cfg(test)]
mod tests {
use super::*;
const REQUIRED: &[&str] = &[
"#110",
"#120",
"#137",
"#196",
"#247",
"#248",
"#250",
"#257",
"#258",
"openread-fts-messages",
"database-busy",
"missing-lexical-metadata",
"workspace-mismatch",
"noisy-dependency-logging",
];
#[test]
fn corpus_covers_every_required_issue_class() {
for id in REQUIRED {
assert!(
issue_fixture(id).is_some(),
"regression corpus is missing required issue class {id}"
);
}
assert_eq!(regression_corpus().len(), REQUIRED.len());
}
#[test]
fn every_fixture_states_root_cause_category_behavior_and_proof() {
for f in regression_corpus() {
assert!(!f.title.is_empty(), "{} title", f.issue_id);
assert!(!f.expected_behavior.is_empty(), "{} behavior", f.issue_id);
assert!(
!f.safe_next_command.is_empty(),
"{} next command",
f.issue_id
);
assert!(!f.proof_command.is_empty(), "{} proof command", f.issue_id);
let _ = f.category; }
}
#[test]
fn safe_next_and_proof_commands_are_never_bare_and_never_destructive() {
for f in regression_corpus() {
for cmd in [f.safe_next_command, f.proof_command] {
assert_ne!(cmd.trim(), "cass", "{} bare cass", f.issue_id);
assert_ne!(cmd.trim(), "bv", "{} bare bv", f.issue_id);
assert!(
cmd.starts_with("cass ") || cmd.starts_with("cargo "),
"{}: command must be a concrete cass/cargo invocation: {cmd}",
f.issue_id
);
for bad in ["rm ", "rm -", "--force-clean", "DROP ", "delete "] {
assert!(!cmd.contains(bad), "{} destructive: {cmd}", f.issue_id);
}
}
}
}
#[test]
fn liveness_classes_attribute_to_cass_derived_state() {
for id in ["#137", "#196", "#247", "#248", "#250"] {
assert_eq!(
issue_fixture(id).unwrap().root_cause_family,
RootCauseFamily::CassDerivedState,
"{id}"
);
}
}
#[test]
fn storage_classes_attribute_to_frankensqlite_storage() {
for id in ["openread-fts-messages", "database-busy"] {
assert_eq!(
issue_fixture(id).unwrap().root_cause_family,
RootCauseFamily::FrankensqliteStorage,
"{id}"
);
}
}
#[test]
fn report_specific_attributions_are_correct() {
assert_eq!(
issue_fixture("#120").unwrap().root_cause_family,
RootCauseFamily::RemoteTransportAuth
);
assert_eq!(
issue_fixture("#257").unwrap().category,
IncidentCategory::Semantic
);
assert_eq!(
issue_fixture("workspace-mismatch").unwrap().category,
IncidentCategory::SearchZeroWorkspace
);
assert_eq!(
issue_fixture("noisy-dependency-logging").unwrap().category,
IncidentCategory::DependencyAttribution
);
}
#[test]
fn fixture_serializes_with_snake_case_enums() {
let f = issue_fixture("#248").unwrap();
let json = serde_json::to_string(f).unwrap();
assert!(json.contains("\"issue_id\":\"#248\""));
assert!(json.contains("\"category\":\"watch_salvage_issues\""));
assert!(json.contains("\"root_cause_family\":\"cass-derived-state\""));
assert!(json.contains("\"proof_command\":\"cargo test --lib search::watch_recovery\""));
}
#[test]
fn corpus_is_deterministic_in_order() {
let a: Vec<&str> = regression_corpus().iter().map(|f| f.issue_id).collect();
let b: Vec<&str> = regression_corpus().iter().map(|f| f.issue_id).collect();
assert_eq!(a, b);
assert_eq!(a.first(), Some(&"#110"));
assert_eq!(a.last(), Some(&"noisy-dependency-logging"));
}
}