fix(temporal): audit set_valid_to closes with an entity_history snapshot#374
Merged
Conversation
…hot (#373) set_valid_to enforced tighten-only semantics but wrote no entity_history snapshot, so a close was invisible to transaction-time reconstruction: as_of/bitemporal_at at a tx instant BEFORE the close reported the close anyway (the live row's valid_to was the only record and unversioned), and the #372 audited-re-assert snapshot then conflated the close into the whole pre-extension recorded window. Mirror the #371/#372 audited stamp in set_valid_to: an effective close/tighten snapshots the pre-change row (invalidated = now with the anti-zero-width bump, superseded_by = self), advances the live row's recorded_at, links supersedes, and pins a still-NULL valid_from to the old effective opening so pre-v9 rows don't shift. The tighten-only guards are untouched; a no-op call (earlier stored close kept) writes no snapshot. mimir_supersede funnels through set_valid_to and inherits the audit for free. The verbatim snapshot INSERT shared with remember_impl is factored into snapshot_live_row_to_history. Tests: set_valid_to_close_is_audited_and_noop_is_not (exactly one snapshot; bitemporal_at at a pre-close tx instant reconstructs the fact OPEN, current knowledge shows the close; same-value and would-extend no-ops add nothing) and supersede_close_inherits_the_audit_snapshot. 254 passed, 2 ignored; temporal gate 100% (20/20). Closes #373 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #373
Problem
set_valid_toenforced tighten-only semantics but wrote noentity_historysnapshot, so a close was invisible to transaction-time reconstruction:as_of/bitemporal_atat a tx instant before the close reported the close anyway — the live row'svalid_towas the only record and it wasn't versioned.valid_tofor the entire pre-extension recorded window.Fix (mirrors the #371/#372 audited stamp)
src/db.rs,set_valid_to:entity_history(invalidated =nowwith the anti-zero-width bump past the oldrecorded_at,superseded_by= self), advances the live row'srecorded_at, linkssupersedes, and pinsvalid_from_unix_ms = COALESCE(valid_from_unix_ms, <old effective from>)so NULL-valid_fromrows (pre-v9, still writable by a legacy binary) don't have their effective opening shift tonow— the same hardening as fix(temporal): audit identical-body re-asserts that move a closed valid period #372's finding 1. Snapshot + stamp run in one transaction.remember_implis factored into a private helpersnapshot_live_row_to_history(used by both; no behavior change on the remember path).mimir_supersedefunnels throughset_valid_toand inherits the audit for free.Tests (
src/tools.rs)set_valid_to_close_is_audited_and_noop_is_not— close an open fact → exactly one snapshot;bitemporal_atat a pre-close tx instant reconstructs the fact open (valid_to: null, from the snapshot), current knowledge refuses the closed-out instant and reportsvalid_to = closein-period; same-value and would-extend no-ops add nothing.supersede_close_inherits_the_audit_snapshot— default supersede writes exactly one snapshot for the old fact; pre-supersede knowledge still believes it open.Verification
cargo +stable-x86_64-pc-windows-msvc test --release: 254 passed, 0 failed, 2 ignored (baseline 252 + 2 new)python benchmark/temporal/gate.py: 100% (20/20 checks) PASS🤖 Generated with Claude Code