use serde::{Deserialize, Serialize};
use super::authority::ArchiveAuthority;
use super::presented::{Presentation, PresentedBinding};
use super::register::{self, Register};
const MAX_LINEAGES_PER_TEXT: usize = 4;
const MAX_AGE_SECONDS: i64 = 24 * 60 * 60;
const MAX_PRESENTED: usize = 64;
const MAX_CALLS_PER_LINEAGE: usize = 32;
const MAX_CALL_ID_BYTES: usize = 128;
const MAX_PRESENTER_REFS_PER_LINEAGE: usize = 16;
const REGISTER: Register = Register {
name: "delivered",
shard_entries: 64,
max_age_seconds: MAX_AGE_SECONDS,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Lineage {
#[serde(default, skip_serializing_if = "Option::is_none")]
files: Option<ArchiveAuthority>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
presented: Vec<PresentedBinding>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
incomplete: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
calls: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
presenters: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineageRefusal {
Unknown,
SourceNotPresented,
SourceNoLongerAdmitted,
}
impl std::fmt::Display for LineageRefusal {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str(match self {
Self::Unknown => "lineage.unknown",
Self::SourceNotPresented => "lineage.source_not_presented",
Self::SourceNoLongerAdmitted => "lineage.source_no_longer_admitted",
})
}
}
impl Lineage {
#[must_use]
pub fn of_files(authority: ArchiveAuthority) -> Self {
Self {
incomplete: authority.is_incomplete(),
files: Some(authority),
presented: Vec::new(),
calls: Vec::new(),
presenters: Vec::new(),
}
}
#[must_use]
pub fn of_presented(presented: Vec<PresentedBinding>) -> Self {
let mut lineage = Self {
files: None,
presented: Vec::new(),
incomplete: presented.is_empty(),
calls: Vec::new(),
presenters: Vec::new(),
};
for binding in presented {
lineage.add_presented(binding);
}
lineage
}
fn add_presented(&mut self, binding: PresentedBinding) {
if self
.project()
.is_some_and(|project| project != binding.project())
{
self.incomplete = true;
return;
}
if let Some(known) = self
.presented
.iter_mut()
.find(|known| known.same_source(&binding))
{
*known = binding;
} else if self.presented.len() < MAX_PRESENTED {
self.presented.push(binding);
} else {
self.incomplete = true;
}
}
fn project(&self) -> Option<&str> {
self.files
.as_ref()
.map(ArchiveAuthority::project)
.or_else(|| self.presented.first().map(PresentedBinding::project))
}
pub fn join(&mut self, other: Self) {
self.incomplete |= other.incomplete;
if let (Some(mine), Some(theirs)) = (self.project(), other.project())
&& mine != theirs
{
self.incomplete = true;
return;
}
match (self.files.as_mut(), other.files) {
(Some(mine), Some(theirs)) => {
mine.absorb(theirs);
self.incomplete |= mine.is_incomplete();
}
(None, Some(theirs)) => self.files = Some(theirs),
(_, None) => {}
}
for binding in other.presented {
self.add_presented(binding);
}
}
fn note_call(&mut self, call_id: &str) {
self.calls.retain(|known| known != call_id);
self.calls.push(call_id.to_owned());
if self.calls.len() > MAX_CALLS_PER_LINEAGE {
let excess = self.calls.len() - MAX_CALLS_PER_LINEAGE;
self.calls.drain(..excess);
}
}
fn note_presenter(&mut self) {
if self.presented.is_empty() {
return;
}
let Some(reference) = super::presented::current_presenter_reference() else {
return;
};
self.presenters.retain(|known| *known != reference);
self.presenters.push(reference);
if self.presenters.len() > MAX_PRESENTER_REFS_PER_LINEAGE {
let excess = self.presenters.len() - MAX_PRESENTER_REFS_PER_LINEAGE;
self.presenters.drain(..excess);
}
}
#[must_use]
pub(super) fn recorded_for_presenter(&self) -> Self {
let mut recorded = self.clone();
recorded.calls.clear();
recorded.presenters.clear();
recorded.note_presenter();
recorded
}
pub(super) fn files_only(&self) -> Option<&ArchiveAuthority> {
self.files
.as_ref()
.filter(|_| self.presented.is_empty() && !self.incomplete)
}
pub fn publish_files(&self) {
match self.files_only() {
Some(files) => files.clone().publish(),
None => super::authority::mark_unbound(),
}
}
pub(super) fn identity_digest(&self) -> Option<String> {
if !self.is_complete() {
return None;
}
let files = match &self.files {
Some(files) => Some(files.identity_digest()?),
None => None,
};
let mut presented: Vec<String> = self
.presented
.iter()
.map(PresentedBinding::identity)
.collect();
presented.sort_unstable();
let mut hash = blake3::Hasher::new();
hash.update(b"leanctx-lineage-v1\0");
hash.update(&serde_json::to_vec(&(files, presented)).ok()?);
Some(hash.finalize().to_hex().to_string())
}
#[must_use]
pub fn presented_source_ids(&self) -> Option<Vec<String>> {
if self.files.is_some() || !self.is_complete() {
return None;
}
let mut ids: Vec<String> = self
.presented
.iter()
.map(|binding| binding.source_id().to_owned())
.collect();
ids.sort_unstable();
ids.dedup();
Some(ids)
}
#[must_use]
pub fn is_complete(&self) -> bool {
!self.incomplete
&& (self.files.is_some() || !self.presented.is_empty())
&& self
.files
.as_ref()
.is_none_or(|files| !files.is_incomplete())
}
pub fn still_admitted(&self) -> Result<(), LineageRefusal> {
if !self.is_complete() {
return Err(LineageRefusal::Unknown);
}
if self
.files
.as_ref()
.is_some_and(|files| !files.still_admitted())
{
return Err(LineageRefusal::SourceNoLongerAdmitted);
}
self.presented_still_current()
}
pub fn still_permitted(&self) -> Result<(), LineageRefusal> {
if !self.is_complete() {
return Err(LineageRefusal::Unknown);
}
if self
.files
.as_ref()
.is_some_and(|files| !files.still_permitted())
{
return Err(LineageRefusal::SourceNoLongerAdmitted);
}
self.presented_still_current()
}
fn presented_still_current(&self) -> Result<(), LineageRefusal> {
let mut not_presented = false;
for binding in &self.presented {
if !binding.matches_request() {
return Err(LineageRefusal::SourceNoLongerAdmitted);
}
match binding.presentation() {
Presentation::Current => {}
Presentation::OtherPolicy => return Err(LineageRefusal::SourceNoLongerAdmitted),
Presentation::None => not_presented = true,
}
}
if not_presented {
return Err(LineageRefusal::SourceNotPresented);
}
Ok(())
}
}
#[must_use]
pub fn digest(delivered_text: &str) -> String {
blake3::hash(delivered_text.as_bytes()).to_hex().to_string()
}
pub fn record_lineage(delivered_text_digest: &str, lineage: &Lineage) -> bool {
lineage.still_admitted().is_ok()
&& store_at(delivered_text_digest, lineage, None, register::now())
}
pub fn record_derived(derived_text_digest: &str, lineage: &Lineage) -> bool {
record_lineage(derived_text_digest, lineage)
}
#[must_use]
pub fn lineage_of(delivered_text_digest: &str) -> Option<Lineage> {
lineage_at(delivered_text_digest, register::now())
}
pub fn record_tool_delivery(
declares_every_source: bool,
is_error: bool,
capture: Option<ArchiveAuthority>,
delivered_blocks: &[&str],
) -> usize {
record_tool_delivery_for_call(
declares_every_source,
is_error,
capture,
delivered_blocks,
None,
)
}
#[must_use]
pub fn valid_call_id(call_id: &str) -> bool {
(1..=MAX_CALL_ID_BYTES).contains(&call_id.len())
&& call_id
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || byte == b'_' || byte == b'-')
}
pub fn record_tool_delivery_for_call(
declares_every_source: bool,
is_error: bool,
capture: Option<ArchiveAuthority>,
delivered_blocks: &[&str],
call_id: Option<&str>,
) -> usize {
if !declares_every_source || is_error {
return 0;
}
let Some(authority) = capture.filter(|authority| !authority.is_incomplete()) else {
return 0;
};
let lineage = Lineage::of_files(authority);
if lineage.still_admitted().is_err() {
return 0;
}
let call_id = call_id.filter(|call_id| valid_call_id(call_id));
let now = register::now();
delivered_blocks
.iter()
.filter(|block| store_at(&digest(block), &lineage, call_id, now))
.count()
}
#[must_use]
pub fn delivered_to_call(delivered_text_digest: &str, call_id: &str) -> bool {
if !valid_call_id(call_id) {
return false;
}
let Some(project) = request_project() else {
return false;
};
REGISTER
.read::<Vec<Lineage>>(delivered_text_digest, register::now())
.is_some_and(|lineages| {
lineages.iter().any(|lineage| {
lineage.is_complete()
&& lineage.project() == Some(project.as_str())
&& lineage.calls.iter().any(|known| known == call_id)
})
})
}
pub(super) fn record_verified(delivered_text_digest: &str, authority: &ArchiveAuthority) -> bool {
store_at(
delivered_text_digest,
&Lineage::of_files(authority.clone()),
None,
register::now(),
)
}
fn request_project() -> Option<String> {
crate::core::policy::runtime::REQUEST_PROJECT
.try_with(|slot| slot.borrow().clone())
.ok()
.flatten()
.and_then(|path| crate::core::pathutil::canonicalize_secure(&path).ok())
.and_then(|path| path.to_str().map(str::to_owned))
}
fn lineage_at(digest: &str, now: i64) -> Option<Lineage> {
let mut lineages: Vec<Lineage> = REGISTER
.read::<Vec<Lineage>>(digest, now)?
.into_iter()
.filter(Lineage::is_complete)
.map(|mut lineage| {
lineage.calls.clear();
lineage.presenters.clear();
lineage
})
.collect();
let scoped = crate::core::policy::runtime::REQUEST_PROJECT
.try_with(|slot| slot.borrow().is_some())
.unwrap_or(false);
if scoped {
let project = request_project()?;
return lineages
.into_iter()
.find(|lineage| lineage.project() == Some(project.as_str()));
}
(lineages.len() == 1).then(|| lineages.remove(0))
}
fn store_at(digest: &str, lineage: &Lineage, call_id: Option<&str>, now: i64) -> bool {
if !lineage.is_complete() {
return false;
}
REGISTER.update::<Vec<Lineage>>(digest, now, |known| {
let mut lineages = known.unwrap_or_default();
let position = lineages
.iter()
.position(|known| known.project() == lineage.project());
let entry = if let Some(position) = position {
lineages[position].join(lineage.clone());
&mut lineages[position]
} else if lineages.len() < MAX_LINEAGES_PER_TEXT {
let mut fresh = lineage.clone();
fresh.calls.clear();
fresh.presenters.clear();
lineages.push(fresh);
lineages.last_mut()?
} else {
return None;
};
if let Some(call_id) = call_id {
entry.note_call(call_id);
}
entry.note_presenter();
Some(lineages)
})
}
#[cfg(test)]
mod tests {
use std::path::{Path, PathBuf};
use super::*;
use crate::core::archive::presented::{self, record_presentation};
use crate::core::policy::runtime::{REQUEST_PROJECT, TestPolicyOverride};
const GOVERNED: &str = "[context_gateway]\nmode = \"governed\"\nclassification = \"warn\"\n";
fn isolated(config: &str) -> crate::core::data_dir::IsolatedDataDir {
let data = crate::core::data_dir::isolated_data_dir();
write_config(config);
data
}
fn write_config(config: &str) {
let dir = crate::core::paths::config_dir_read_only().expect("isolated config dir");
std::fs::create_dir_all(&dir).expect("config dir");
std::fs::write(dir.join("config.toml"), config).expect("config");
}
fn project() -> (tempfile::TempDir, PathBuf) {
let directory = tempfile::tempdir().expect("project");
let root = directory.path().canonicalize().expect("canonical root");
(directory, root)
}
fn scoped<T>(root: &Path, operation: impl FnOnce() -> T) -> T {
REQUEST_PROJECT.sync_scope(std::cell::RefCell::new(Some(root.to_path_buf())), operation)
}
fn authority_of(root: &Path, name: &str, content: &str) -> ArchiveAuthority {
let path = root.join(name);
std::fs::write(&path, content).expect("source");
let admitted = crate::core::rooted_read::read_file_for_tool_rooted(
path.to_str().expect("utf-8 path"),
root.to_str().expect("utf-8 root"),
"ctx_read",
)
.expect("admitted read");
ArchiveAuthority::file(
root,
path.to_str().expect("utf-8 path"),
"ctx_read",
&admitted,
)
.expect("protection is active: the read is bound")
}
fn record(delivered_text_digest: &str, authority: &ArchiveAuthority) -> bool {
record_lineage(delivered_text_digest, &Lineage::of_files(authority.clone()))
}
fn lineage_for(delivered_text_digest: &str) -> Option<ArchiveAuthority> {
lineage_of(delivered_text_digest)
.filter(|lineage| lineage.presented.is_empty())
.and_then(|lineage| lineage.files)
}
fn presented_now(root: &Path, object_ref: &str) -> PresentedBinding {
PresentedBinding::admitted_now(root, object_ref, "source-one", "sha256:aa")
.expect("policy identity available")
}
#[test]
fn a_complete_lineage_is_found_and_stops_admitting_when_its_source_is_gone() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
scoped(&root, || {
let authority = authority_of(&root, "kept.rs", "pub fn kept() {}\n");
let delivered = digest("pub fn kept() {}\n");
assert!(lineage_of(&delivered).is_none(), "nothing on record yet");
assert!(record(&delivered, &authority));
let found = lineage_of(&delivered).expect("recorded lineage");
assert_eq!(found, Lineage::of_files(authority.clone()));
assert_eq!(found.still_admitted(), Ok(()));
assert_eq!(lineage_for(&delivered), Some(authority));
assert!(lineage_of(&digest("pub fn kept() {}")).is_none());
assert!(lineage_of("not-a-digest").is_none());
assert_eq!(found.still_permitted(), Ok(()));
std::fs::write(root.join("kept.rs"), "pub fn kept() { edited() }\n")
.expect("edit the source");
assert_eq!(
found.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
assert_eq!(found.still_permitted(), Ok(()));
std::fs::write(root.join("kept.rs"), "*** TOP SECRET ***\nlaunch window\n")
.expect("restrict the source");
assert_eq!(
found.still_permitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
std::fs::remove_file(root.join("kept.rs")).expect("delete the source");
let found = lineage_of(&delivered).expect("the handle is still on record");
assert_eq!(
found.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
assert_eq!(
found.still_permitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
});
}
#[tokio::test]
async fn incomplete_and_restricted_lineages_are_not_recorded() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
let ((), incomplete) = super::super::authority::capture(async {
assert!(
ArchiveAuthority::file(&root, "/outside/of/the/project.rs", "ctx_read", "x")
.is_none()
);
})
.await;
let incomplete = incomplete.expect("an unbound read is reported");
assert!(incomplete.is_incomplete());
scoped(&root, || {
let unknown = digest("derived from an unbound source");
assert!(!record(&unknown, &incomplete));
assert!(!record_verified(&unknown, &incomplete));
assert!(!record_lineage(
&unknown,
&Lineage::of_presented(Vec::new())
));
assert_eq!(
Lineage::of_files(incomplete.clone()).still_admitted(),
Err(LineageRefusal::Unknown)
);
assert!(lineage_of(&unknown).is_none());
let restricted = authority_of(&root, "plan.md", "*** TOP SECRET ***\nlaunch window\n");
let delivered = digest("launch window");
assert!(!record(&delivered, &restricted));
assert_eq!(
record_tool_delivery(true, false, Some(restricted), &["launch window"]),
0
);
assert!(lineage_of(&delivered).is_none());
let clean = authority_of(&root, "tool.rs", "pub fn tool() {}\n");
let block = "pub fn tool() {}\n";
assert_eq!(
record_tool_delivery(false, false, Some(clean.clone()), &[block]),
0
);
assert_eq!(
record_tool_delivery(true, true, Some(clean.clone()), &[block]),
0
);
assert_eq!(record_tool_delivery(true, false, None, &[block]), 0);
assert_eq!(
record_tool_delivery(true, false, Some(incomplete.clone()), &[block]),
0
);
assert!(lineage_of(&digest(block)).is_none());
assert_eq!(
record_tool_delivery(true, false, Some(clean), &[block, "second block"]),
2
);
assert!(lineage_of(&digest(block)).is_some());
assert!(lineage_of(&digest("second block")).is_some());
});
let clean = scoped(&root, || {
authority_of(&root, "clean.rs", "pub fn clean() {}\n")
});
let delivered = digest("pub fn clean() {}\n");
assert!(
!record(&delivered, &clean),
"no request project: nothing verifies the lineage"
);
assert!(lineage_of(&delivered).is_none());
}
#[test]
fn identical_text_from_two_source_sets_needs_both() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
let (_other_directory, other_root) = project();
let delivered = digest("pub fn shared() {}\n");
scoped(&root, || {
let first = authority_of(&root, "a.rs", "pub fn shared() {}\n");
let second = authority_of(&root, "b.rs", "pub fn shared() {}\n");
assert!(record(&delivered, &first));
assert!(record(&delivered, &second));
let both = lineage_of(&delivered).expect("united lineage");
assert_ne!(both, Lineage::of_files(first.clone()));
assert_ne!(both, Lineage::of_files(second));
assert_eq!(both.still_admitted(), Ok(()));
let refreshed = authority_of(&root, "a.rs", "pub fn shared() {}\n// note\n");
assert!(record(&delivered, &refreshed));
let both = lineage_of(&delivered).expect("united lineage");
assert_eq!(both.still_admitted(), Ok(()), "superseded digest replaced");
std::fs::remove_file(root.join("b.rs")).expect("delete one source");
let both = lineage_of(&delivered).expect("still on record");
assert_eq!(
both.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted),
"one remaining set authorizes nothing"
);
assert!(refreshed.still_admitted());
});
scoped(&other_root, || {
assert!(
lineage_of(&delivered).is_none(),
"not this project's lineage"
);
let foreign = authority_of(&other_root, "c.rs", "pub fn shared() {}\n");
assert!(record(&delivered, &foreign));
assert_eq!(lineage_for(&delivered), Some(foreign));
});
assert!(
lineage_of(&delivered).is_none(),
"two projects and none in scope: ambiguous"
);
}
#[test]
fn a_presented_lineage_needs_a_current_presentation_and_a_mixed_one_needs_both() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
let (_other_directory, other_root) = project();
scoped(&root, || {
let binding = presented_now(&root, "ref-quartz");
let lineage = Lineage::of_presented(vec![binding.clone()]);
let delivered = digest("prepared context");
assert_eq!(
lineage.still_admitted(),
Err(LineageRefusal::SourceNotPresented),
"bound, but no presentation on record"
);
assert!(!record_lineage(&delivered, &lineage), "nothing recorded");
assert!(record_presentation(&binding));
assert_eq!(lineage.still_admitted(), Ok(()));
assert!(record_lineage(&delivered, &lineage));
assert_eq!(lineage_of(&delivered), Some(lineage.clone()));
assert!(
lineage_for(&delivered).is_none(),
"a presented lineage is never passed off as a file lineage"
);
let other_content =
PresentedBinding::admitted_now(&root, "ref-quartz", "source-one", "sha256:bb")
.expect("binding");
assert_eq!(
Lineage::of_presented(vec![other_content]).still_admitted(),
Err(LineageRefusal::SourceNotPresented)
);
write_config("[context_gateway]\nmode = \"sovereign\"\n");
assert_eq!(
lineage.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
let renewed = presented_now(&root, "ref-quartz");
assert!(record_presentation(&renewed));
assert_eq!(
lineage.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
let lineage = Lineage::of_presented(vec![renewed]);
assert!(record_lineage(&delivered, &lineage));
assert_eq!(
lineage_of(&delivered).expect("on record").still_admitted(),
Ok(())
);
let file = authority_of(&root, "kept.rs", "pub fn kept() {}\n");
let mut mixed = Lineage::of_files(file);
mixed.join(lineage.clone());
assert!(mixed.is_complete());
assert_eq!(mixed.still_admitted(), Ok(()));
let mixed_text = digest("file part and prepared part");
assert!(record_lineage(&mixed_text, &mixed));
std::fs::remove_file(root.join("kept.rs")).expect("delete the file source");
assert_eq!(
lineage_of(&mixed_text).expect("on record").still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
let mut crossed = lineage.clone();
crossed.join(Lineage::of_presented(vec![presented_now(
&other_root,
"ref-quartz",
)]));
assert!(!crossed.is_complete());
assert_eq!(crossed.still_admitted(), Err(LineageRefusal::Unknown));
});
scoped(&other_root, || {
let foreign = Lineage::of_presented(vec![presented_now(&root, "ref-quartz")]);
assert_eq!(
foreign.still_admitted(),
Err(LineageRefusal::SourceNoLongerAdmitted)
);
});
for refusal in [
LineageRefusal::Unknown,
LineageRefusal::SourceNotPresented,
LineageRefusal::SourceNoLongerAdmitted,
] {
let text = refusal.to_string();
assert!(
text.starts_with("lineage.") && !text.contains("quartz"),
"{text}"
);
}
assert_eq!(presented::VALIDITY_SECONDS, 600);
}
#[test]
fn the_persisted_register_is_bounded_private_and_readable_by_another_process() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
scoped(&root, || {
let authority = authority_of(&root, "kept.rs", "pub fn kept() {}\n");
let lineage = Lineage::of_files(authority);
let delivered = digest("pub fn kept() {}\n");
assert!(record_lineage(&delivered, &lineage));
let shard = REGISTER.shard_path(&delivered);
let raw = std::fs::read_to_string(&shard).expect("persisted shard");
assert!(!raw.contains("pub fn kept"), "no content in the register");
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mode = std::fs::metadata(&shard)
.expect("shard")
.permissions()
.mode();
assert_eq!(mode & 0o777, 0o600, "owner-only");
}
assert_eq!(lineage_of(&delivered), Some(lineage.clone()));
let start = register::now();
assert!(lineage_at(&delivered, start + MAX_AGE_SECONDS + 1).is_none());
let in_shard = |index: usize| format!("ab{index:062x}");
for index in 0..REGISTER.shard_entries + 3 {
let at = start + i64::try_from(index).expect("small index");
assert!(store_at(&in_shard(index), &lineage, None, at));
}
let later = start + 1_000;
let newest = in_shard(REGISTER.shard_entries + 2);
assert!(lineage_at(&in_shard(0), later).is_none(), "oldest evicted");
assert!(lineage_at(&in_shard(3), later).is_some());
assert!(lineage_at(&newest, later).is_some());
let shard = REGISTER.shard_path(&newest);
let too_large = usize::try_from(register::MAX_SHARD_BYTES).expect("fits usize") + 1;
std::fs::write(&shard, " ".repeat(too_large)).expect("write");
assert!(lineage_at(&newest, later).is_none());
std::fs::write(&shard, "{\"version\":2,\"entries\":{}}").expect("write");
assert!(lineage_at(&newest, later).is_none());
});
}
#[test]
fn a_delivery_is_on_record_for_the_call_it_answered_and_for_no_other() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
let (_other_directory, other_root) = project();
let block = "pub fn kept() {}\n";
let delivered = digest(block);
scoped(&root, || {
let authority = authority_of(&root, "kept.rs", block);
assert!(!delivered_to_call(&delivered, "toolu_X"), "nothing yet");
assert_eq!(
record_tool_delivery_for_call(
true,
false,
Some(authority.clone()),
&[block],
Some("toolu_X"),
),
1
);
assert!(delivered_to_call(&delivered, "toolu_X"));
assert!(!delivered_to_call(&delivered, "toolu_Y"));
assert!(!delivered_to_call(&digest("other text"), "toolu_X"));
assert!(!delivered_to_call("not-a-digest", "toolu_X"));
let handle = lineage_of(&delivered).expect("on record");
assert!(handle.calls.is_empty());
assert_eq!(handle, Lineage::of_files(authority.clone()));
assert_eq!(
record_tool_delivery(true, false, Some(authority.clone()), &[block]),
1
);
assert!(record(&delivered, &authority));
assert!(delivered_to_call(&delivered, "toolu_X"));
assert!(!delivered_to_call(&delivered, ""));
let second = "pub fn second() {}\n";
let second_authority = authority_of(&root, "second.rs", second);
let too_long = "x".repeat(MAX_CALL_ID_BYTES + 1);
for malformed in ["", "has space", "slash/id", too_long.as_str()] {
assert!(!valid_call_id(malformed), "{malformed:?}");
assert_eq!(
record_tool_delivery_for_call(
true,
false,
Some(second_authority.clone()),
&[second],
Some(malformed),
),
1
);
assert!(!delivered_to_call(&digest(second), malformed));
}
assert!(valid_call_id(&"x".repeat(MAX_CALL_ID_BYTES)));
assert!(valid_call_id("call_Ab-9"));
let derived = digest("[stub of the block]");
assert!(record_derived(&derived, &handle));
assert!(lineage_of(&derived).is_some());
assert!(!delivered_to_call(&derived, "toolu_X"));
let refused = "pub fn refused() {}\n";
assert_eq!(
record_tool_delivery_for_call(
true,
true,
Some(authority.clone()),
&[refused],
Some("toolu_X"),
),
0
);
assert!(!delivered_to_call(&digest(refused), "toolu_X"));
});
scoped(&other_root, || {
assert!(!delivered_to_call(&delivered, "toolu_X"));
let foreign = authority_of(&other_root, "kept.rs", block);
assert_eq!(
record_tool_delivery_for_call(true, false, Some(foreign), &[block], Some("Z")),
1
);
assert!(delivered_to_call(&delivered, "Z"));
assert!(!delivered_to_call(&delivered, "toolu_X"));
});
scoped(&root, || {
assert!(delivered_to_call(&delivered, "toolu_X"));
assert!(!delivered_to_call(&delivered, "Z"));
});
assert!(
!delivered_to_call(&delivered, "toolu_X"),
"no request project: no answer"
);
}
#[test]
fn an_entry_without_call_ids_answers_for_none_and_the_bound_evicts_the_oldest() {
let _data = isolated(GOVERNED);
let _community = TestPolicyOverride::set(None);
let (_directory, root) = project();
scoped(&root, || {
let block = "pub fn kept() {}\n";
let authority = authority_of(&root, "kept.rs", block);
let delivered = digest(block);
assert!(record(&delivered, &authority));
let shard = REGISTER.shard_path(&delivered);
let raw = std::fs::read_to_string(&shard).expect("persisted shard");
assert!(!raw.contains("\"calls\""), "{raw}");
assert_eq!(
lineage_of(&delivered),
Some(Lineage::of_files(authority.clone()))
);
assert!(!delivered_to_call(&delivered, "toolu_X"));
let record_for = |call_id: &str| {
record_tool_delivery_for_call(
true,
false,
Some(authority.clone()),
&[block],
Some(call_id),
)
};
for index in 0..MAX_CALLS_PER_LINEAGE {
assert_eq!(record_for(&format!("call_{index}")), 1);
}
assert!(delivered_to_call(&delivered, "call_0"));
assert_eq!(record_for("call_0"), 1);
assert_eq!(record_for("call_new"), 1);
assert!(delivered_to_call(&delivered, "call_0"));
assert!(!delivered_to_call(&delivered, "call_1"), "oldest evicted");
assert!(delivered_to_call(&delivered, "call_2"));
assert!(delivered_to_call(&delivered, "call_new"));
let raw = std::fs::read_to_string(&shard).expect("persisted shard");
assert!(raw.contains("\"calls\""));
assert!(!raw.contains("pub fn kept"), "no content in the register");
});
}
}