A date is written at the precision it was recorded - #414
Merged
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: WaylandYang <wayland0916@gmail.com>
This was referenced Sep 6, 2026
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.
Follow-up to #373, which put the record clock's full instant into the
changestool. 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 asatwas echoed back as a day.One rule, one formatter.
time_textin 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 asended by <instant>fromholds_to, nevernow; a fact with no stated start is writtenattested <instant> → …so the model knows where its evidence begins.fact_line,change_line,entity_facts_detail,read_document's header andremember's echo all go through it.parse_whenacceptsYYYYandYYYY-MMtoo,changestakessince/untilat year or month precision (a year runs to 31 December),remembertakes a date at any precision or an instant. The tool descriptions and the system prompt say so, and tell the model that2023means the year, not a day.The write side stops inventing days. Review's "close at", conflict resolution and the violation queue's
fact_closedhard-coded"day"; the inputs only acceptedYYYY-MM-DD, so "ended in June 2023" had to become 1 June. The three routes takevalid_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 sameparseDateInputas the graph page's interval editor — write as many digits as you know.fmtTimeandparseDateInputmove fromGraph.tsxtoweb/src/time.tsso there is one copy.Not changed: what extraction parses (
parse_timealready keeps year/month/day) and the schema's three precisions — sub-day precision on the world axis is a separate question.Tests:
time_textunit tests for each precision, the fractional instant, and the four span shapes;change_lineat year precision and with an undated ending; the window's last day for year/month;parse_whenon2023and2023-06. Existing tool tests updated to the new instants. Full suite and clippy green.🤖 Generated with Claude Code