Repository navigation
A document's date reaches the facts that cite it (#987) - #988
WaylandYang wants to merge 8 commits into
Conversation
#987: every relation of an entity read "undated" on a base built from dated reports. Reproduced on dev with a report whose first lines state 2026/09/04: time words inside sentences resolve (four of four, grade A), the document's own date is read (doc_time 2026-09-04, source content), and every fact is attested from 2026-09-28, the moment the document was processed. Extraction runs before dating. A statement is written while the document has no date yet, so `attested_from` takes now(); when the resolver later reads the date from the text it wrote it on the document and nowhere else. Reads take the lower bound of a fact with no start from `COALESCE(valid_from, attested_from)`, so a report from 2020 uploaded today had its facts read as known since today. That is the upload time entering world time, which #714 says must not happen. `documents::set_content_date` now does it in one transaction: writes the date on the document and on the version the evidence sits on (#900), locks the timelines of the facts that cite the document, moves their anchors to the earliest dated evidence (only earlier, the rule `attest_earlier` already keeps; the same for an ending said without a date), carries typed rows along with the statement they were materialised from, and recomputes those timelines, since the engine orders start-less rows by evidence date. Migration 0099 does the same for rows already written. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com>
dev reached 90 migrations with #986; this PR adds one more and the CLI test compares the constant with the number of files. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com>
|
Reviewed and ran it on a fresh database with dev merged in: store 292, server 522, CLI 13, clippy clean. The fix is the right shape: one transaction, anchors only move earlier, typed rows follow the statement they came from, the timelines are recomputed, and the dated-evidence expression is the one DATED_AT uses. One commit pushed: the description says constant 90, but dev reached 90 files with #986, so with 0100 the constant is 91. Without it the CLI schema test fails. For the second half of #987: a typed row merged from several statements follows only from_statement_id here; if its other sources are earlier, typed_fact_sources is where to look. |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com>
|
Superseded by ADR 0064 (#989). This moved |
…one with no time holds at every moment (#995) * A statement is attested by the date its own section speaks from, and one with no time holds at every moment ADR 0064 cut 3. Supersedes #988. An open statement was written with `attested_from = COALESCE(document date, now())`, and extraction runs before any date is read, so every statement was attested at the moment its document was processed. Reads take the lower bound of a row with no start from that column: a report from 2020 uploaded today had its facts read as known since today, and the panel could only say "undated" (#987). - The insert no longer falls back to now(). A statement written by extraction has no attestation unless a source system dated the document. A statement a person nodded through is still attested at the nod: the person is the evidence. - After extraction, each statement of the document is attested by the `now` entry in force at the position of its quote (the rule cut 2 uses for relative expressions), with that entry's words: `attested_by` is "提报日期 2026年9月4日". Minutes are attested by the meeting's date, not the date they were sent. Only earlier, as `attest_earlier`. - Typed rows have no evidence of their own: their attestation is the earliest of the statements they were materialised from, kept in step at the end of materialisation and after attesting. - A row with neither a valid time nor an attestation holds at every moment. An event with no date still holds at none (0022); the guard is null-safe, a statement has no predicate and its temporal kind is NULL. Reasoning reads an unattested premise as open below. - An ending said without a date needs an anchor by CHECK; with no attestation it takes the moment the ledger recorded it. - Migration 0100: `attested_from` nullable, `attested_by`; open statements move to their earliest dated evidence or to NULL, typed rows follow their sources. - The panel says "as of 2026-09-04 · 提报日期 2026年9月4日" for a fact with no interval of its own, and "undated" only when there is nothing. Time bench, three runs: as-of right 0 of 10 before, 9–10 of 10 after; no sentence without time words was given a start. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com> * The record names the pull request of cut 3 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Wayland Yang <wayland0916@gmail.com> --------- Signed-off-by: Wayland Yang <wayland0916@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Found while reproducing #987 (every relation of an entity reads "undated" on a base built from dated reports).
Reproduction on dev. A Chinese report whose first lines state
提报日期:2026/09/04, uploaded and extracted:doc_time = 2026-09-04, sourcecontentattested_fromCause. Extraction runs before dating. A statement is written while the document has no date, so
attested_fromtakesnow(). When the resolver later reads the date from the text,set_content_datewrote it on the document and nowhere else. Reads take the lower bound of a fact with no start fromCOALESCE(valid_from, attested_from), so a report from 2020 uploaded today has its facts read as known since today: the upload time entering world time, which #714 says must not happen.Fix.
documents::set_content_datedoes it in one transaction: writes the date on the document and on the version the evidence sits on (Per-object document updates lose observation-time ordering during reconciliation #900), locks the timelines of the facts that cite the document, moves their anchors to the earliest dated evidence, carries typed rows along with the statement they came from, and recomputes those timelines (the engine orders start-less rows by evidence date). Anchors only move earlier, the ruleattest_earlieralready keeps; an ending said without a date (attested_to) moves the same way. The dated-evidence expression is the onetemporal::DATED_ATuses.After the fix, the same reproduction: every fact of the report is attested from 2026-09-04.
Tests.
a_document_date_reaches_its_facts: the statement and the typed row it became move to the document's date; an anchor already earlier stays; a fact of another document is not touched; reading the same date again moves nothing. Store suite, server time tests and clippy pass.Not in this PR. The entity panel shows "undated" for a fact with no start even when it has an attested date; showing that date is the second half of #987 and comes separately.
Refs #987.
🤖 Generated with Claude Code