rules-v2: midnight ends, tanker hours, bilingual completions; refuse unreadable LLM values - #100
Merged
Merged
Conversation
- "from 2pm until midnight on 11 September" was read as 11 September 00:00, before the works began (244089, 245031). A 00:00 end is now read against the "from" before its "until": a start earlier that day gives D+1 00:00, a start the day before keeps D 00:00, and no start (or an estimated completion time of midnight) abstains. - An "until" in a sentence about an alternative water supply, tankers or bottled water gave the tanker's hours as the works' end (239696). It is no longer a candidate; alone, the rules abstain. - The Irish-completion check abstained per block, so an English completion below an Irish block was never read (244925, 129 cases). An Irish completion now abstains only when the next block with text has no English completion. - "16:59pm" (245025): an hour 13-23 with "pm" reads as the 24-hour time. Shadow eval against the LLM's 10,870 hash-stable records: coverage 91.7% -> 93.3%, 17 disagreements, 15 of them the LLM's midnight reading. RULES_VERSION bumps, so CI re-answers every rules-v1 case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
- parse_response rejects a local_time, local_date or window value that is not HH:MM (00-23) or an ISO date, so the case counts as failed and is retried. "24:00", "5pm" or "28/04/2026" in the JSONL used to raise in build and fail every CI build after it. - build leaves an already-written unreadable record out with a ::warning::, and uisce-infer treats it as absent so the case is inferred again. - The inferred_cases rebuild runs in one transaction: DROP and CREATE autocommitted, so a raise after them left the table empty. - A published record uisce-infer would redo (description changed, or extractor or prompt retired) is still published but now listed in a ::warning::, decided by the same is_current the inference run uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
The rules note gets a dated 2026-09-24 section with the three rules changes, the shadow eval, the labelled replays and the rules-only run against the 2026-09-23 release. The roadmap gets the prompt line that makes the LLM read "until midnight on D" as the start of D, with the 16 affected published records, a proposed wording and the order of work, waiting on the owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
From a code review of this PR against current main: - An alternative-supply `until` was skipped, which could leave the stale original schedule as the only candidate under a revising update. It now makes the rules abstain; ALTERNATIVE_SUPPLY has word boundaries, so "wastewater station" is not a water station. - "until midnight on D" after a start on D-1 is read as D 00:00 only for a start from 18:00; a daytime start abstains. - An Irish completion reads the next block only when it is the same day's update, the Irish date taken from its opening text. - A model value that cannot be read is normalised where it has one meaning and otherwise stored as not_found with the value in its notes, instead of failing and being re-sent at temperature 0 forever. - readable_latest is the one newest-record reading, shared by inference, build and the shadow eval; unreadable newest records are redone and warned about only until they are; the stale warning reuses inference's own selection and no longer counts open by the feed's status. Re-measured: rules-v2 answers 10,082 of 10,870 LLM records (was 10,137), agreeing on 10,065, the same 17 disagreements; labelled rounds 73/73, 110/111, 113/113 as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
From a second code review of the review-fix commit:
- An unreadable model reply fails the case again. Storing it as
not_found silently replaced a good published record with none; a
failure keeps that record and shows in the run's count. The
normalisation of one-meaning near-misses stays, now type-guarded.
- After a start the day before, only a literal "12am on D" reads D
00:00; the word "midnight" abstains whatever the start time (a 6pm
start was no less ambiguous than 9am).
- The Irish block's date comes from its parsed header when there is one
("10.15rn"), else from its opening text.
- The shadow eval compares against the model's own records only.
- stale_cases shares inference's state map (current_states) and the
open connection (cases_needing_inference).
Re-measured: unchanged at 10,082 answered of 10,870 model records,
10,065 agreeing, the same 17 disagreements; replays 73/73, 110/111,
113/113. 4 rules-v1 records keep their answer until the residue run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ
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.
PR D of the fixes from the retroactive review. The LLM prompt and
PROMPT_VERSIONare unchanged. The LLM makes the same midnight mistake; the prompt fix is baz8080/uisce#102, deferred by the owner.Rules (
rules.py, nowrules-v2)untilinside a sentence about an alternative water supply, tanker, bowser, water station, bottled water or standpipe makes the rules abstain. It was emitted as the works' end for 239696 to 239698. Word boundaries keep "wastewater station" out of the match.LLM values and records (
inference.py,build.py,eval_rules_shadow.py)build.pycouldn't read. Before, one of these failed every CI build.readable_latestandcurrent_statesare the one reading of the JSONL, shared by inference, build and the shadow eval.build.pywarns about a stale published record using inference's own selection and state map.inferred_casesempty.Review
First round. A high-effort code review confirmed the
RULES_VERSIONbump is safe and found 10 things. Among them were three places where rules-v2 guessed instead of abstaining: tanker hours under a revising update, midnight after a daytime start, and an Irish completion read against an older English update.Second round. A medium review found that my first-round fixes had gone too far in places:
not_foundcould silently replace a good published record. Reverted: the case fails loudly again.Measured (release DB and committed JSONL)
The 17 disagreements, read in full:
Labelled replays:
rules-v2 abstains on 4 of the 2,691 cases whose latest record is rules-v1: 243084, 244538, 244584 and 244720. CI's
--rules-onlyrun can't replace those, so their v1 answer stands, listed in the stale warning, until the LLM residue is run by hand.JSONL growth: the version bump re-stamps about 2,700 rules-v1 cases with the same answer on the first CI build after merge, taking the file from 19.8 MB to about 21.1 MB.
Notes
rules-vs-llm-end-times.md: a dated rules-v2 section, plus the review amendments.CLAUDE.md: a rules-v2 row.roadmap.md: the prompt v4 entry, pointing to issue Prompt v4: the LLM reads "until midnight on D" as the start of D #102.Tests
test_rules.py,test_inference.pyandtest_build.py, including one for each reviewer probe text.uv run ruff checkanduv run pytestpass: 734 tests, merged with currentmain.🤖 Generated with Claude Code
https://claude.ai/code/session_0168hLW2X3mkV3Jhm26LJSwQ