Skip to content

A date the text spells out is read as a date - #689

Merged
WaylandYang merged 3 commits into
devfrom
fix/a-written-date-is-read
Sep 13, 2026
Merged

WaylandYang merged 3 commits into
devfrom
fix/a-written-date-is-read

Conversation

@WaylandYang

Copy link
Copy Markdown
Contributor

Closes #688. When the model copies a date the way a contract writes it ("June 23, 2020", "17 Mar. 2020", "March 2020"), the server now reads it as a date. Before, it dropped the value as attr_datatype. A numeric date whose day/month order is ambiguous is still refused.

Why

Rule 8a asks the model for YYYY-MM-DD, and it often writes the contract's own form anyway. On the lease bench, the two runs on #679 at 98a3d20 dropped 21 deadline facts this way, and the two runs at b2facea dropped 15. It was the largest single loss. The timelines built from the values that did land were right.

What changes

utopia_extract::written_date reads two families, with precision taken from what is written. A date written only to the month gets month precision; no day is invented.

  • Month spelled out: month-first or day-first, optional comma, optional period after an abbreviation. Examples: March 17, 2020, 17 March 2020, Mar. 17 2020, March 2020. chrono's %B / %b recognise the name (full name or three-letter abbreviation, any case).
  • Year first, numeric: 2020/03/17, 2020.3.17, 2020年3月17日, 2020年3月.

Refused:

  • Numeric forms without the year first (03/04/2020, 3.4.2020), where the form itself doesn't say which is the month.
  • 2020/03.
  • Anything not a real day (February 30, 2020).
  • Anything else (45 days after the Trigger Date, Q3 2020).

Where it applies:

  • read_time: parse_time, or else a written date. It is used where the server reads a model reply: valid_from / valid_to, the "a time as subject or object" normalizations, and literal detection.
  • normalize_attr_value("date"): stores a written date in rule 3's form ("2020-06-23", "2020-03"), so the same day has one spelling for comparison and dedupe. This is the shared datatype path, so edge qualifiers (rule 8c) get the same behaviour. A value already in rule 3's form is kept as is.
  • Unchanged: parse_time still accepts only the contract format. Chat tool arguments (at, as_of) and the UI keep their existing contract, where "August 2024" is refused (a_moment_is_a_date_or_an_rfc3339_stamp_and_nothing_else).
  • Prompt: rule 8a drops "the server keeps a date only in that format, and a date written any other way is lost", which is no longer true. It still asks for rule 3's format.

Checks

  • a_written_date_is_read_only_when_its_form_says_which_day: 13 written forms read as 2020-03-17, and 3 month-only forms as 2020-03. ISO values are kept as written. It covers 4 ambiguous numeric forms and 9 non-dates; qualifiers and interval ends go through the same parser.
  • parse_time_precisions: parse_time still refuses a written date, and read_time accepts one.
  • End to end with a scripted model endpoint (no LLM). The fake reply writes an attribute "June 23, 2020" with valid_from "June 8, 2020", an attribute "March 2020", an attribute "08/13/2020", and a relation with qualifier signed_on: "17 Mar. 2020".
    • This branch: option_deadline = "2020-06-23" from 2020-06-08 (day); rent_commencement = "2020-03"; signed_on = "2020-03-17" on the edge. Only 08/13/2020 is dropped (attr_datatype).
    • Build without this change: all four values dropped (three attr_datatype, one qualifier_datatype).
  • Tests: cargo test -p utopia-extract 52 passed; -p utopia-server --bins 272 passed.
  • Lint: clippy -D warnings and fmt are clean.

This touches rule 8a's date sentence, which #679 also edits; whichever merges second resolves it.

🤖 Generated with Claude Code

WaylandYang and others added 3 commits September 14, 2026 05:32
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang
WaylandYang force-pushed the fix/a-written-date-is-read branch from 2ff7d45 to 7a10105 Compare September 13, 2026 21:38
@WaylandYang

Copy link
Copy Markdown
Contributor Author

Rebased onto dev after #679 merged (the session that opened this ended, so I did the rebase). It picks up the review follow-ups that were prepared on top of #679:

Checks on 7a10105 (fresh database migrated to 0057): store, server and extract pass 595 tests with 0 failures; clippy -D warnings is clean.

Scripted-endpoint end to end with a declared date attribute:

  • "June 23, 2020" with valid_from "June 8, 2020" is stored as 2020-06-23 from 2020-06-08, day precision;
  • "March 2020" is stored as 2020-03;
  • "08/13/2020" is dropped as attr_datatype.

🤖 Generated with Claude Code

@WaylandYang
WaylandYang merged commit 0306d0c into dev Sep 13, 2026
4 checks passed
@WaylandYang
WaylandYang deleted the fix/a-written-date-is-read branch September 13, 2026 21:42
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.

A date the text spells out is read as a date

1 participant