## [2026-06-12T14:58:02.450Z]
Introduced ObservationRecorder and wired it into the structure-aspect runner. The runner now collects result-bearing observations during each check.mjs run — recording what each fs.read, fs.list, fs.exists, and graph-node access returned, not merely which paths were touched. This is required for correct verdict caching: a stored deterministic verdict is only reusable if every probe returned the same value, so the hash of observations must change when any returned value changes, including negative existence probes and directory listings. The recorder enforces first-observation-wins with a taint flag when the same path is observed with different content mid-run, because such a run is unreproducible and its result must never be cached. RunStructureAspectResult gains two new additive fields: observations (sorted key/hash pairs) and observationsTainted (boolean). Existing fields and all current consumers are unchanged.
## [2026-06-13T05:33:45.354Z]
The deterministic verifier now records and re-checks the result of every probe a check makes beyond its own subject files — directory listings, negative existence checks, graph-set membership, and sibling reads. The recorded observation carries the actual result that was seen, so a cached pass cannot survive a change to anything the check actually observed, only to its own subject files. This closes the gap where a check could read a directory or test for a sibling's existence, pass, and then keep passing after that surrounding state changed.
