design: world-time flows from the claim's window (D107) - #362
Conversation
D106 fixed the observation adjudicator reading the wrong clock; the follow-up audit at 02b7990 found the same confusion in sixteen more places: relations' valid_from is never seeded (valid_at is a no-op on the relation side), the relation supersession prompt judges "the same period" without seeing one, undated supersessions cap at now() (histories depend on ingest wall-clock), the two adjudicators orient undated testimony in opposite directions, retrieval dedupes identical text across dates, the K fact sheet prints chat dates under "valid since", the timeline aggregate buckets by ingest year, and day-precision windows are zero-width points. Record the audit (plan/analysis/time_handling_audit.md), decide one contract (D107 + plan/designs/temporal_clocks_design.md): every stage reads the claim's resolved D41 window first; said-on time is provenance and at most an upper bound; a missing time stays missing. Fact windows are seeded by kind with a validity_basis column, widen only earlier, close at the successor's world-time start else said-on else coexist; one shared ordering comparator; the D106 two-clock block in every temporal prompt; window-aware dedupe; half-open precision ends; all four D41 kinds taught. Sequence it in plan/plans/temporal_clocks.md and banner the six affected designs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
…nly (D107 review) Codex's review of the first revision found four mechanisms that contradict decisions this design must live inside: seeding valid_from from the said-on date (provenance is not validity), seeding a measurement's end from its claim (D43 never caps a fixed-period figure), widening the verdict start on evidence (a reduction over claim columns, D41), and half-open storage (empties `instant`), plus a merged ordering key that conflated D90's total processing order with temporal succession. Replace them: a fact carries an adjudicated verdict window (seeded once by kind, per-endpoint bases, changed only by recorded verdicts — cap, extend_start, date_undated, D55) and a derived, non-authoritative occurrence window that widens with evidence; measurements and events are believed from their occurrence start and never capped; interval-aware evidence-target matching for bounded slices under the GiST EXCLUDE; temporal succession separate from D90 order, requiring world-time starts, else coexist; precision honoured at comparison time with storage unchanged; statements canonical and dated labels derived; the full D41 tuple in dedupe keys; the envelope/operation/protocol roll enumerated. Narrow five audit findings to what the code shows and add the consumption skill's wrong claims_as_of definition as 4.18. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Independent review — round 1 — Codex (
|
Review triage — round 1 (Codex), dispositions applied in 5065ef7Codex's verdict on the first revision was "not mergeable as written", and it was right on the substance: four mechanisms in the first cut contradicted decisions this design must live inside. The revision replaces them rather than patching wording. Every finding was re-read against the cited code before acting.
A second Codex round runs against the revision. |
…on, canonical bounds (D107 round 2) Codex's second review showed revision two still broke on its own terms: matching every fact by verdict-window overlap makes an occurrence's open window overlap every later occurrence (recreating the D106 collapse and colliding with the relations EXCLUDE); an automatic extend_start is min() over claim columns (D41); "+ one unit" over-expands normalised year ends and fact windows had no precision; the D90 re-split compared asserted_at to a world-time cap; succession between dated states only lost D106's dated-resignation-ends-undated-state case; and "current" was undefined for finite future ends. Give every fact a temporal kind (state / occurrence / undated): states are identified by verdict-window overlap under the existing EXCLUDE restricted to states; occurrences by occurrence-window overlap under their own exclusion, so recurring events are distinct rows on both planes; undated rows collapse by key (relations) or wording (observations). Seed once from the D90-first claim (recorded), never revise automatically — discrepancies become review items. Store fact windows canonical half-open from one canonical_bounds function (year 2022 -> [2022-01-01, 2023-01-01); instant a non-empty point) and canonicalise claim comparisons through the same function; claim storage unchanged. Succession caps at any world-time instant the successor supplies, including an ending occurrence. Re-split by occurrence start. One evaluated-at current predicate with an expiry sweep. Enumerate the shared-envelope version rolls (resolve_entity@2, testimony_context@2, fact_context@3, answer_context@3) and the stop-drain-migrate-rebuild-readiness cutover. Add the open-query confirmation surface as audit 4.19; narrow 4.5 and 4.15; banner the D90 design. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Independent review — round 2 — Codex (
|
Review triage — round 2 (Codex), dispositions applied in 3ec25a2Round two's verdict was again "request changes", and the three mechanical blockers were real: revision two's identity rule could not represent recurring occurrences, its
A third Codex round runs against 3ec25a2. |
…lace conversion (D107 round 3) Codex's third review: an occurrence exclusion constraint contradicts adjudicated identity (two same-day visits, or a union that grows into a neighbour); kind-routed matching made D106's ending-event cap unreachable and had no chronological guard; "review item" named no verdict schema; a replay rebuild erases D55 history and can re-pick seeds; belief-time leaked into a world-time endpoint; aggregates and predicate absence never evaluate valid_until; canonical bounds kept raw starts and had no SQL form. Drop the occurrence exclusion — occurrence identity is adjudicated under the per-key lock with overlap as a candidate filter. Define two candidate sets (same-kind for evidence; state-ending occurrences for supersede/ contradict only) and a chronological guard. Amend D24 with a temporal_window review kind and its append-only, reversible verdict schema, invariants and replay order. Convert in place from the recorded add adjudication's triggering claim (fact ids and D55 history preserved, shadow-first, resumable). Retraction with unknown source time closes only the belief interval from the persisted reconciliation instant. Canonical bounds truncate both ends and ship as memory_v1.canonical_bounds with a claims_canonical view. One evaluated-at current predicate everywhere, including aggregate/absence, with a durable expiry schedule. Audit 4.20 (aggregates) and 4.21 (claims_as_of example) added; protocol rolls listed per package; the D90 §5.5.3 rule rewritten. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Independent review — round 3 — Codex (
|
Review triage — round 3 (Codex), dispositions applied in be67e65Round three confirmed the direction (temporal kinds, occurrence-plane separation, no automatic widening, world-time re-split, evaluated-at current) and blocked on four implementability gaps. All four are closed by mechanism, not wording.
A fourth Codex round runs against be67e65. |
…nt contradiction restored (D107 round 4) Codex's fourth review: relation add adjudications never recorded a creator claim, so exact legacy seed recovery was false; keeping legacy caps preserved the said-on/now() ends D107 removes; the current predicate had no lower bound (a 2030 fact current in 2026) and no activation scheduling; an overlap-only candidate filter dropped D106's disjoint-date contradiction; state-ending candidates limited to open states could not shorten a finite-ended state; the relation write path attached evidence before any verdict; the review verdict schema lacked identity, idempotency key and a reconciled reversal rule; fact checks allowed empty half-open states; D55 withdrawal erased historical occurrence windows; D55's observation close is shape-blind; stale round-three mechanics remained in banners. Record the seed atomically on both planes going forward; convert legacy relations under a `legacy` basis with migration adjudications; recompute recoverable legacy caps, remove caps from converted occurrences, turn D55 fallback caps into belief-time closes, and route the rest to `legacy_unknown_boundary` review items readiness reports. Use the full containment current predicate everywhere with activation and expiry scheduling. Keep nomination as today and bound verdicts by temporal relation (disjoint: new or contradict). Include finite-ended states in the state-ending set with a guard on both bounds. Stage relation writes until an idempotent verdict. Define temporal_window_verdicts concretely with reversal as the documented exception. Require non-empty states; derive occurrence windows over all attached evidence; route D55 by temporal kind (audit 4.22). Align every banner. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Independent review — round 4 — Codex (
|
Review triage — round 4 (Codex), dispositions applied in b5311ecRound four affirmed the direction (verified: seed-once is D41-compatible, bases are provenance not authority, canonical formulas correct, D90 order vs succession coherent, derived labels D32/D43-safe, version rolls stated) and blocked on conversion and predicate details. One of its findings caught a factual error of mine: relation
A fifth Codex round runs against b5311ec. |
…pen items (D107 round 5) Codex's fifth review: mapping a NULL claim kind to an `undated` temporal kind conflated shape with datedness, so "is CEO" with no start was uncappable and D106's ending-event case was lost again; the verdict matrix omitted supersede for states; the observations banner still carried the withdrawn overlap-filter wording; relation_adjudications already has triggering_claim_id (populate, not add); adjudication_outcome has no `migrate` value; a D55 cap refused by the guard left a zombie fact; three audit sentences overstated; one section reference was wrong. It also named four contracts beyond this design's scope: deterministic relation seeding under D88 concurrency, locked compare-and-swap review application, cached-artifact staleness, and the D74 hard-forget inventory. Kinds are now shape only (state / occurrence / unknown) with bounds known or unknown independently; a state with unknown bounds can be ended; only an undated successor cannot supply a boundary; the guard is stated mechanically; states may supersede within the matrix; D55 closes belief time fail-closed whenever the world-time cap is unknown or refused; schema wording corrected and a postgres_schema_design amendment required; §4.3 gains the CAS precondition, order key and item uniqueness; a new §12 records the four open contracts and WP-T.1 is gated on them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Independent review — round 5 — Codex (
|
Review triage — round 5 (Codex), dispositions in 77c4a77 — and four items left open on purposeRound five's verified list now covers the predicate, activation/expiry, canonical formulas, the D90/succession separation, D49 rolls, the legacy-conversion direction, D55 by kind, and a repo-wide search that found no further clock-conflation class beyond the 22 findings. Its blockers split into defects in the text (fixed) and contracts that reach into adjacent decisions (recorded as open in a new §12 and gating WP-T.1, pending the operator's call).
The four open items are decisions that widen D107 into D88, D24's application semantics, K/profile caching, and D74; whether to resolve them inside this PR or as gating spikes before WP-T.1 is the operator's call and is left explicit in the design rather than papered over. |
…rom WP-T.1 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR
Problem
D106 fixed one instance of a pattern: a stage that has the claim's resolved D41 window available and reasons on the source's date instead. The follow-up audit at
02b79904found sixteen more, across every plane. The consequential ones: relations'valid_fromis never seeded (sovalid_at/facts_as_ofis a no-op on the relation side, against what/docs/conceptspromises); the relation supersession prompt asks the model about "the same period" while showing only document dates; undated supersessions cap atnow()(a rebuild on another day yields a different history — breaks D7); the two adjudicators orient undated testimony in opposite directions;testimony_contextdedupes identical wording across dates exactly as the adjudicator did before D106; the K fact sheet prints the chat date under "valid since";aggregate(form="timeline")buckets by ingest year; the answer agent is told to "use timestamps" without being told which; and day-precision windows are zero-width points that intraday as-of queries miss.What this PR decides (documentation only — no code)
D107 — world-time flows from the claim's window; said-on time is provenance, never validity. One contract instead of seventeen patches:
asserted_at; is-about the D41 window; believedingested_at) and two rules: world-time comes from the is-about window; a missing time stays missing — nevernow(), and undated never wins an ordering;validity_basiscolumn (world_time/said_on/unknown), widened only earlier by evidence, closed at the successor's is-about start → else said-on as an honest upper bound → else coexist with a recorded reason;said on/is about, defined) in every temporal prompt: relation supersession, T4 candidates, K writer, answer agent;undatedbucket; profiles rank by window recency, neverupdated_at;opentaught with examples; half-open precision-derived ends; full-timestamp header; the observation statement carries its resolved date (claim text stays source-faithful, D32);world_timerows.The design is written against D41's own boundary: claim windows seed fact windows; the fact window remains the adjudicator's single, monotonic verdict — never a reduction over claim columns.
Files
plan/analysis/time_handling_audit.md— the seventeen findings with file:line evidence, six patterns, and a checked-and-sound list.plan/designs/temporal_clocks_design.md— the binding design (clocks, extraction, fact windows, adjudication/retrieval, consumer labels, generations/rebuild/protocol, alternatives, non-goals).decisions.md— D107.plan/plans/temporal_clocks.md— five work packages (WP-T.1 fact windows and closing → T.2 two-clock prompts → T.3 retrieval keys/envelopes → T.4 extraction precision/vocabulary → T.5 consumer labels), each with the findings it closes, generations rolled, and acceptance criteria.e2_e3_claims_relations_design.md,observations_design.md,registries_design.md,retrieval_design.md,k_layers_design.md,locomo_benchmark_design.md.What it does not do
No code, schema, generation, or protocol changes; those land per work package with the same-PR docs the CLAUDE.md rule requires. Recurrence and anchor-relative time remain outside the single-interval model (D41).
Contributor agreement
Review
A Codex (
gpt-5.6-sol, xhigh) design review will be posted as a comment with a triage.🤖 Generated with Claude Code
https://claude.ai/code/session_016p9xB9T7VYREuVmohDPKjR