Skip to content

A date is written at the precision it was recorded - #414

Merged
WaylandYang merged 2 commits into
devfrom
feat/time-precision
Sep 5, 2026
Merged

A date is written at the precision it was recorded#414
WaylandYang merged 2 commits into
devfrom
feat/time-precision

Conversation

@WaylandYang

Copy link
Copy Markdown
Contributor

Follow-up to #373, which put the record clock's full instant into the changes tool. The world axis had the mirror problem, and had it everywhere: every chat-tool line printed a date as %Y-%m-%d, whatever the stored precision — a fact recorded as "2023" read as 1 January, a fact the text says has ended with no date read as → now, and a moment the model passed as at was echoed back as a day.

One rule, one formatter. time_text in the server: a world-axis bound is written at exactly its own precision (2023, 2023-06, 2023-06-01); a bound with no precision — a moment (at, as_of, recorded_at, doc_time) or an anchored end from 0022 — is written as a full RFC3339 instant; an undated ending is written as ended by <instant> from holds_to, never now; a fact with no stated start is written attested <instant> → … so the model knows where its evidence begins. fact_line, change_line, entity_facts_detail, read_document's header and remember's echo all go through it. parse_when accepts YYYY and YYYY-MM too, changes takes since/until at year or month precision (a year runs to 31 December), remember takes a date at any precision or an instant. The tool descriptions and the system prompt say so, and tell the model that 2023 means the year, not a day.

The write side stops inventing days. Review's "close at", conflict resolution and the violation queue's fact_closed hard-coded "day"; the inputs only accepted YYYY-MM-DD, so "ended in June 2023" had to become 1 June. The three routes take valid_to_precision / close_at_precision (year, month, day; day when absent, so old clients behave as before), conflict resolution without an explicit date closes the old fact at the new fact's start with that start's precision, and the Review inputs use the same parseDateInput as the graph page's interval editor — write as many digits as you know. fmtTime and parseDateInput move from Graph.tsx to web/src/time.ts so there is one copy.

Not changed: what extraction parses (parse_time already keeps year/month/day) and the schema's three precisions — sub-day precision on the world axis is a separate question.

Tests: time_text unit tests for each precision, the fractional instant, and the four span shapes; change_line at year precision and with an undated ending; the window's last day for year/month; parse_when on 2023 and 2023-06. Existing tool tests updated to the new instants. Full suite and clippy green.

🤖 Generated with Claude Code

WaylandYang and others added 2 commits September 6, 2026 07:18
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang
WaylandYang merged commit 92e07f4 into dev Sep 5, 2026
4 checks passed
@WaylandYang
WaylandYang deleted the feat/time-precision branch September 5, 2026 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant