use crate::core::archive::authority::ArchiveAuthority;
use crate::core::archive::bindings::{self, Item};
use crate::core::context_admission::stored::SourceRef;
use super::SessionState;
impl SessionState {
pub fn add_finding_for_file(&mut self, file: Option<&str>, line: Option<u32>, summary: &str) {
self.add_finding(file, line, summary);
self.bind_last_finding(|project| bindings::sources_at(project, &[file?], "ctx_session"));
}
pub fn add_finding_from_call(
&mut self,
file: Option<&str>,
summary: &str,
call_sources: Option<&ArchiveAuthority>,
) {
self.add_finding(file, None, summary);
self.bind_last_finding(|_| bindings::sources_of_call(call_sources?));
}
fn bind_last_finding(&self, sources: impl FnOnce(&str) -> Option<Vec<SourceRef>>) {
let (Some(project), Some(finding)) = (self.project_root.as_deref(), self.findings.last())
else {
return;
};
let Some(sources) = sources(project) else {
return;
};
bindings::bind(
&Item::SessionFinding {
session: &self.id,
file: finding.file.as_deref(),
},
&finding.summary,
project,
sources,
);
}
pub fn finding_served(&self, finding: &super::types::Finding) -> bool {
bindings::serve(
&Item::SessionFinding {
session: &self.id,
file: finding.file.as_deref(),
},
&finding.summary,
self.project_root.as_deref(),
)
.is_ok()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::archive::delivered::LineageRefusal;
use crate::core::context_admission::stored::lineage_support::{
deliver, governed, project, reusable,
};
use crate::core::policy::runtime::TestPolicyOverride;
fn delivered(root: &str, session: &SessionState) -> (String, usize) {
let finding = session.findings.last().expect("a finding").clone();
let id = session.id.clone();
deliver(root, || {
let item = Item::SessionFinding {
session: &id,
file: finding.file.as_deref(),
};
match bindings::serve(&item, &finding.summary, Some(root)) {
Ok(()) => format!("finding: {}", finding.summary),
Err(withheld) => withheld.notice(),
}
})
}
#[test]
fn a_finding_is_bound_to_its_file_only_when_the_file_is_admitted() {
let _data = governed();
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
std::fs::write(format!("{root}/pool.rs"), "pub fn lease() {}\n").expect("source");
std::fs::write(format!("{root}/plan.md"), "*** TOP SECRET ***\nlaunch\n").expect("marked");
let mut session = SessionState::new();
session.project_root = Some(root.clone());
session.add_finding_for_file(Some("pool.rs"), Some(1), "the pool leaks one lease");
let (reply, recorded) = delivered(&root, &session);
assert!(reply.contains("leaks one lease"), "{reply}");
assert_eq!(recorded, 1);
assert_eq!(reusable(&root, &reply), Ok(()));
for (file, summary) in [
(None, "noted without a file"),
(Some("missing.rs"), "noted for a missing file"),
(Some("plan.md"), "noted for a restricted file"),
] {
session.add_finding_for_file(file, None, summary);
assert_eq!(
session
.findings
.last()
.map(|finding| finding.summary.as_str()),
Some(summary),
"the finding is recorded either way"
);
let (unbound, recorded) = delivered(&root, &session);
assert_eq!(recorded, 0, "{summary}");
assert_eq!(reusable(&root, &unbound), Err(LineageRefusal::Unknown));
}
std::fs::remove_file(format!("{root}/pool.rs")).expect("delete");
assert_eq!(
reusable(&root, &reply),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
}
#[test]
fn a_call_finding_takes_the_sources_of_its_call() {
let _data = governed();
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
let path = format!("{root}/build.rs");
std::fs::write(&path, "fn main() { panic!(\"linker\") }\n").expect("source");
let admitted =
crate::core::rooted_read::read_file_for_tool_rooted(&path, &root, "ctx_read")
.expect("admitted read");
let capture =
ArchiveAuthority::file(std::path::Path::new(&root), &path, "ctx_read", &admitted)
.expect("protection is active: the read is bound");
let mut session = SessionState::new();
session.project_root = Some(root.clone());
session.add_finding_from_call(Some("build.rs"), "build.rs panics", Some(&capture));
let (reply, recorded) = delivered(&root, &session);
assert_eq!(recorded, 1);
assert_eq!(reusable(&root, &reply), Ok(()));
session.add_finding_from_call(Some("build.rs"), "from an undeclared tool", None);
let (_, recorded) = delivered(&root, &session);
assert_eq!(recorded, 0);
let mut old: SessionState =
serde_json::from_str(&serde_json::to_string(&session).expect("serialize"))
.expect("a session state without bindings loads");
old.id = "a-session-written-before-bindings".to_owned();
assert_eq!(old.findings.len(), 2);
let (_, recorded) = delivered(&root, &old);
assert_eq!(recorded, 0, "no register entry: originless");
}
#[test]
fn the_renderers_deliver_findings_under_their_current_sources() {
let _data = governed();
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
std::fs::write(format!("{root}/pool.rs"), "pub fn lease() {}\n").expect("source");
let mut session = SessionState::new();
session.project_root = Some(root.clone());
session.add_finding_for_file(Some("pool.rs"), Some(1), "the pool leaks one lease");
let summary =
|session: &SessionState| deliver(&root, || session.format_compact_delivered());
let (reply, recorded) = summary(&session);
assert!(reply.contains("the pool leaks one lease"), "{reply}");
assert_eq!(recorded, 1);
assert_eq!(reusable(&root, &reply), Ok(()));
let mut mixed = session.clone();
mixed.add_finding_for_file(None, None, "noted without a file");
let (unknown, recorded) = summary(&mixed);
assert!(unknown.contains("noted without a file"), "{unknown}");
assert_eq!(recorded, 0, "one finding without a source: unknown");
assert_eq!(reusable(&root, &unknown), Err(LineageRefusal::Unknown));
let mut decided = session.clone();
decided.add_decision("lease from the pool only", None);
assert_eq!(summary(&decided).1, 0, "a decision has no source: unknown");
std::fs::write(
format!("{root}/pool.rs"),
"*** TOP SECRET ***\npub fn lease() {}\n",
)
.expect("mark");
assert_eq!(
reusable(&root, &reply),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
for rendered in [
session.format_compact(),
session.build_compaction_snapshot(),
session.build_resume_block(),
] {
assert!(!rendered.contains("the pool leaks one lease"), "{rendered}");
}
assert!(mixed.format_compact().contains("noted without a file"));
std::fs::remove_file(format!("{root}/pool.rs")).expect("delete");
assert_eq!(
reusable(&root, &reply),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
let (withheld, recorded) = summary(&session);
assert!(!withheld.contains("the pool leaks one lease"), "{withheld}");
assert_eq!(recorded, 0);
}
}