You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
D107 (decisions.md; design plan/designs/temporal_clocks_design.md; analysis plan/analysis/time_handling_audit.md; sequencing plan/plans/temporal_clocks.md) was merged as a design-only PR (#362) after five independent Codex design reviews. The core contract is binding; four contracts it depends on were deliberately left open (design §12) because each widens D107 into an adjacent decision. This issue is the program tracker so the context survives sessions. UMC-side follow-ups: writeitai/ultimate-memory-cloud#433 (finish the conv-42 run) and #434 (nightly ordering watch; Antigravity reviews). Read the four documents above before touching any package; the review trail (five reviews + five triages) is on #362 and explains why every mechanism looks the way it does — several obvious-seeming alternatives were tried and withdrawn (design §10).
The one-sentence contract
Every stage reads the claim's resolved D41 window (what a statement is about) and treats the source's date (when it was said) as provenance and processing order — never as a window boundary; a missing time stays missing (never now(), never the said-on date, never belief-time).
Where the engine is today (audit at 02b79904, 22 findings)
Highest-impact: (4.1) testimony_context dedupes identical wording across dates; (4.2) relations' valid_from is never seeded so valid_at cannot exclude a fact before its beginning; (4.3) the relation supersession prompt shows only said-on dates; (4.4) supersession/retraction caps use the said-on date or now() (histories not rebuild-stable, D7); (4.5) observation statements/labels keep "last week" forever; (4.6) the answer agent is never told which clock is which; (4.10/4.11) the two adjudicators orient undated testimony in opposite directions; (4.13) day-precision windows are zero-width points; (4.20) aggregate/absence queries never evaluate valid_until; (4.22) D55's observation close is shape-blind. Full list with file:line evidence in the analysis.
Work packages (plan/plans/temporal_clocks.md — acceptance criteria there are the definition of done)
WP-T.0a — canonical bounds, engine-internal (merged 2026-09-03 via feat(temporal): canonical half-open bounds for claim windows (D107 WP-T.0a) #372 → 43c03aa7; Codex round 1 fixed a session-timezone dependence in the SQL twins): pure core/temporal.py + public SQL twins claim_canonical_start/claim_canonical_end (migration p9_26_0047) with an expression index; claims_as_of candidate scan and D106's block/disjointness on half-open canonical ends; adjudicator/flush generations and protocol Full-v22 roll.
WP-T.0b — query-space exposure (next; independent): memory_v1.canonical_bounds, the claims_canonical view with catalog fixtures and deletion-matrix cells, the shipped claims_as_of example rewritten (its unknown count is structurally zero today), open-query prose. Original scope for reference — WP-T.0 — canonical bounds.canonical_bounds(from, until, precision) → [start, end) in Python and as memory_v1.canonical_bounds + claims_canonical view; both ends truncated to the precision unit in UTC; instant → [t, t+1µs); open → unbounded; inclusive request (t, t) → point query; used by claims_as_of, D106's _windows_disjoint, the shipped claims_as_of example (fix its unknown count, which is structurally zero), open-query prose, catalog metadata. No storage change. Rolls the query-space manifest and the LoCoMo protocol (result semantics change). Independent — can start now.
WP-T.1 — fact model, matching, closing, cutover. GATED on the four spikes below. Migration (temporal_kind, valid_from_basis, valid_until_basis, occurs_from/until/precision, seed_claim_id; populate the existing relation_adjudications.triggering_claim_id on add; migrate/migration enum values; non-empty state check; EXCLUDE partial on states; fact_expiry_schedule; temporal_window review kind + temporal_window_verdicts); seed once by kind; two candidate sets with the temporal relation bounding verdicts (disjoint → new/contradict; mixed → never evidence; states may supersede); staged idempotent relation writes; succession by any successor-supplied world-time instant incl. ending occurrences, with the mechanical guard (valid_from IS NULL OR T > valid_from) AND (valid_until IS NULL OR T < valid_until); D55 by temporal kind, fail-closed on belief-time from the persisted reconciliation instant; D90 re-split by occurrence start; the full containment current predicate on every current read incl. aggregate/absence; occurrence windows over all attached evidence; in-place conversion with migration adjudications, legacy basis, legacy-cap recomputation, legacy_unknown_boundary review items, readiness gate. Requires a postgres_schema_design.md D107 amendment with full DDL first.
WP-T.2 — two clocks in every temporal prompt. Relation supersession prompt + evidence laterals (said on / is about, D106's block); T4 candidate salient facts with occurrence windows and kinds, ranked by evidence then occurrence recency (never updated_at); K writer claims carry asserted_at + D41 fields; the answer-agent prompt names the envelope fields. Depends on T.1's columns.
WP-T.3 — retrieval keys, envelopes, skill. Dedupe on the full D41 tuple (or asserted_at when unknown) with EvidenceResult.grouped_members; Validity/GraphEdge/K fact model/memory_v1 fact views gain bases, kind, occurrence; resolve_entity@2, testimony_context@2, fact_context@3, answer_context@3 (shared Envelope schema); open-query confirmation returns the full D41 tuple and fact bases/occurrence; P1 is-about claim filters + occurs fact mode; timeline by occurrence with an undated bucket; consumption skill teaches the three clocks and two fact kinds and defines claims_as_of over world-time (today it says "system time" — wrong per D41). Depends on T.1.
WP-T.4 — extraction vocabulary and anchor. Teach all four D41 kinds and open with examples + field descriptions ("has been CEO since 2019" → proposition_validity/open); full-timestamp document header ("three hours ago" resolves; "this morning" is an expressivity boundary, not a defect). Independent — can run in parallel with everything.
WP-T.5 — dated labels and consumer surfaces. Labels derived from statement + occurrence window (obs label, FactResult.label, profile lines) — statements stay canonical; K fact sheet columns by basis with about and legacy; observation history by occurs_from. Depends on T.1.
Every package: roll the generations it touches; roll the LoCoMo protocol whenever observable result semantics change (even with unchanged JSON shape); same-PR docs (concepts/API pages for valid_at, benchmark README, project-status); tests that assert the clock, not only the outcome.
The four gating spikes (design §12) — each lands as a design amendment + decision before WP-T.1
Tracked as #365 (spike 1), #366 (spike 2), #367 (spike 3), #368 (spike 4). In one line each: (1) deterministic relation seeding under D88 concurrency (durable relation staging + post-barrier per-block drain; amends D88's "commutative relation upsert"); (2) locked, ordered, stale-safe application of temporal_window review verdicts (CAS on old_* under the fact lock is already in §4.3; remaining: lock rule vs ingestion/retraction writes, replay dependency validation, compensating reversal that preserves intervening caps); (3) cached-artifact staleness (dependency tracking for not-yet-active facts, transactional schedule maintenance, drain-and-coalesce after downtime with the current instant as E, a checked stale state or D49-disclosed staleness — the read-time predicate cannot protect already-rendered text); (4) D74 hard-forget inventory for every new field/table (delete / null / recompute).
Review protocol for every follow-up PR
Independent Codex review (codex exec --yolo --model gpt-5.6-sol --config model_reasoning_effort="xhigh", review-only, against the actual code and the decisions the change must respect), posted on the PR with a triage table; Antigravity when its quota allows. The five D107 rounds show the value: each caught real defects (see #362).
Why this exists
D107 (
decisions.md; designplan/designs/temporal_clocks_design.md; analysisplan/analysis/time_handling_audit.md; sequencingplan/plans/temporal_clocks.md) was merged as a design-only PR (#362) after five independent Codex design reviews. The core contract is binding; four contracts it depends on were deliberately left open (design §12) because each widens D107 into an adjacent decision. This issue is the program tracker so the context survives sessions. UMC-side follow-ups: writeitai/ultimate-memory-cloud#433 (finish the conv-42 run) and #434 (nightly ordering watch; Antigravity reviews). Read the four documents above before touching any package; the review trail (five reviews + five triages) is on #362 and explains why every mechanism looks the way it does — several obvious-seeming alternatives were tried and withdrawn (design §10).The one-sentence contract
Every stage reads the claim's resolved D41 window (what a statement is about) and treats the source's date (when it was said) as provenance and processing order — never as a window boundary; a missing time stays missing (never
now(), never the said-on date, never belief-time).Where the engine is today (audit at
02b79904, 22 findings)Highest-impact: (4.1)
testimony_contextdedupes identical wording across dates; (4.2) relations'valid_fromis never seeded sovalid_atcannot exclude a fact before its beginning; (4.3) the relation supersession prompt shows only said-on dates; (4.4) supersession/retraction caps use the said-on date ornow()(histories not rebuild-stable, D7); (4.5) observation statements/labels keep "last week" forever; (4.6) the answer agent is never told which clock is which; (4.10/4.11) the two adjudicators orient undated testimony in opposite directions; (4.13) day-precision windows are zero-width points; (4.20) aggregate/absence queries never evaluatevalid_until; (4.22) D55's observation close is shape-blind. Full list with file:line evidence in the analysis.Work packages (plan/plans/temporal_clocks.md — acceptance criteria there are the definition of done)
43c03aa7; Codex round 1 fixed a session-timezone dependence in the SQL twins): purecore/temporal.py+ public SQL twinsclaim_canonical_start/claim_canonical_end(migrationp9_26_0047) with an expression index;claims_as_ofcandidate scan and D106's block/disjointness on half-open canonical ends; adjudicator/flush generations and protocol Full-v22 roll.memory_v1.canonical_bounds, theclaims_canonicalview with catalog fixtures and deletion-matrix cells, the shippedclaims_as_ofexample rewritten (itsunknowncount is structurally zero today), open-query prose. Original scope for reference — WP-T.0 — canonical bounds.canonical_bounds(from, until, precision) → [start, end)in Python and asmemory_v1.canonical_bounds+claims_canonicalview; both ends truncated to the precision unit in UTC;instant→[t, t+1µs);open→ unbounded; inclusive request(t, t)→ point query; used byclaims_as_of, D106's_windows_disjoint, the shippedclaims_as_ofexample (fix itsunknowncount, which is structurally zero), open-query prose, catalog metadata. No storage change. Rolls the query-space manifest and the LoCoMo protocol (result semantics change). Independent — can start now.temporal_kind,valid_from_basis,valid_until_basis,occurs_from/until/precision,seed_claim_id; populate the existingrelation_adjudications.triggering_claim_idonadd;migrate/migrationenum values; non-empty state check;EXCLUDEpartial on states;fact_expiry_schedule;temporal_windowreview kind +temporal_window_verdicts); seed once by kind; two candidate sets with the temporal relation bounding verdicts (disjoint → new/contradict; mixed → never evidence; states may supersede); staged idempotent relation writes; succession by any successor-supplied world-time instant incl. ending occurrences, with the mechanical guard(valid_from IS NULL OR T > valid_from) AND (valid_until IS NULL OR T < valid_until); D55 by temporal kind, fail-closed on belief-time from the persisted reconciliation instant; D90 re-split by occurrence start; the full containment current predicate on every current read incl. aggregate/absence; occurrence windows over all attached evidence; in-place conversion with migration adjudications,legacybasis, legacy-cap recomputation,legacy_unknown_boundaryreview items, readiness gate. Requires apostgres_schema_design.mdD107 amendment with full DDL first.said on/is about, D106's block); T4 candidate salient facts with occurrence windows and kinds, ranked by evidence then occurrence recency (neverupdated_at); K writer claims carryasserted_at+ D41 fields; the answer-agent prompt names the envelope fields. Depends on T.1's columns.asserted_atwhen unknown) withEvidenceResult.grouped_members;Validity/GraphEdge/K fact model/memory_v1fact views gain bases, kind, occurrence;resolve_entity@2,testimony_context@2,fact_context@3,answer_context@3(shared Envelope schema); open-query confirmation returns the full D41 tuple and fact bases/occurrence; P1 is-about claim filters +occursfact mode; timeline by occurrence with anundatedbucket; consumption skill teaches the three clocks and two fact kinds and definesclaims_as_ofover world-time (today it says "system time" — wrong per D41). Depends on T.1.openwith examples + field descriptions ("has been CEO since 2019" →proposition_validity/open); full-timestamp document header ("three hours ago" resolves; "this morning" is an expressivity boundary, not a defect). Independent — can run in parallel with everything.FactResult.label, profile lines) — statements stay canonical; K fact sheet columns by basis withaboutandlegacy; observation history byoccurs_from. Depends on T.1.Every package: roll the generations it touches; roll the LoCoMo protocol whenever observable result semantics change (even with unchanged JSON shape); same-PR docs (concepts/API pages for
valid_at, benchmark README, project-status); tests that assert the clock, not only the outcome.The four gating spikes (design §12) — each lands as a design amendment + decision before WP-T.1
Tracked as #365 (spike 1), #366 (spike 2), #367 (spike 3), #368 (spike 4). In one line each: (1) deterministic relation seeding under D88 concurrency (durable relation staging + post-barrier per-block drain; amends D88's "commutative relation upsert"); (2) locked, ordered, stale-safe application of
temporal_windowreview verdicts (CAS onold_*under the fact lock is already in §4.3; remaining: lock rule vs ingestion/retraction writes, replay dependency validation, compensating reversal that preserves intervening caps); (3) cached-artifact staleness (dependency tracking for not-yet-active facts, transactional schedule maintenance, drain-and-coalesce after downtime with the current instant asE, a checked stale state or D49-disclosed staleness — the read-time predicate cannot protect already-rendered text); (4) D74 hard-forget inventory for every new field/table (delete / null / recompute).Review protocol for every follow-up PR
Independent Codex review (
codex exec --yolo --model gpt-5.6-sol --config model_reasoning_effort="xhigh", review-only, against the actual code and the decisions the change must respect), posted on the PR with a triage table; Antigravity when its quota allows. The five D107 rounds show the value: each caught real defects (see #362).🤖 Generated with Claude Code