Skip to main content

probe_read_freshness

Function probe_read_freshness 

Source
pub fn probe_read_freshness(msgs: &[ChatMessage]) -> ReadFreshness
Expand description

The A8 disk-probe pre-pass, deliberately kept OUTSIDE project_messages so the pure projection core never touches the filesystem itself (SPEC.md A8’s purity requirement). Call this with the exact same msgs slice about to be projected — indices must line up — and thread the result through ReductionPolicy::read_freshness before calling project_messages (or project_messages); it is only ever consulted when policy.elide_stale_reads is set, so callers that never enable A8 can skip calling this entirely.

Staleness check. For each detect_reads hit, this re-reads the file and compares content_hash(“hash of the current bytes, lossy-UTF8-decoded”) against the hash of the tool result’s recorded content — exactly the transform read_file itself applies for a plain whole-file read (tools/builtins.rs:70-97, no offset/limit, file under MAX_READ_BYTES). This one comparison also naturally covers the two harder cases without duplicating read_file’s own decoration/slicing logic (which lives in a file this change does not touch):

  • a sliced read (offset/limit given): the recorded content is a line slice, never byte-identical to a raw whole-file re-read, so the hash mismatches and the read is (correctly, conservatively) never fresh;
  • a read whose original result already carried read_file’s own oversize-truncation notice: same reasoning, the recorded content is not raw file bytes, so it never matches a raw re-read.

Both are the documented SPEC.md A8 fallback (“mtime+len only, document”) taken to its simplest safe form: this implementation’s fallback for anything it cannot cheaply verify is “treat as changed” (never elide), which only ever under-elides, never over-elides — the safe direction.

Unreadable/deleted files are likewise never fresh. mtime is recorded for ReadLogEntry::mtime whenever the file’s metadata is readable, even when the freshness verdict itself is false.