Repository navigation
fact_check: read currency-prefixed amounts and thin-space separators; abstain when the register value stands outside an anchored sentence - #112
Open
avalyset wants to merge 3 commits into
Conversation
…rators; abstain when the register value appears outside an anchored sentence
This was referenced Oct 13, 2026
This branch has not been deployed
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.
Fixes three ways in which the
fact_checkjudge from #105 judged a correct answerwrong. The judge is our own contribution. The cases come from an independent reading: a second reader wrote 36 answers about one declared fact (the state guideline rate for a single person, 8 300 kroner a month), 27 that state it correctly and 9 that do not, and ran the merged judge on them. 8 of the 27 correct answers came outwrong. Base branch:dev.What was wrong
wrong.wrong.wrongon 13 800.What the change does
Parsing.
read_claimsreads a figure with a currency marker directly before it: «kr 8 300», «kr. 8 300», «NOK 8 300». A marker that is the unit of the preceding figure is not reused («8 100 kr 8 300» gives 8 100 only). «kr.» before a figure no longer ends the sentence. An approximator before the marker still marks the figure as hedged («ca. kr 8 000»), and a range that opens on a marker is still a range («kr 8 000–8 500», «mellom kr 8 000 og kr 8 500»). U+2009 is accepted as thousands separator beside U+0020, U+00A0 and U+202F.One exception to the outcome rule. The rule was: if the declared value is among the anchored candidates, the outcome is
correct; if none of them equals it, the outcome iswrong. The exception: when no anchored candidate equals the declared value, but the answer states the declared value, with its unit, in a sentence without an anchor, the outcome isambiguous, which is graded as UNGRADED. The judge cannot tell which sentence is the claim, so it abstains. The unanchored figure never makes the answercorrect, and the anchored figures do not make itwrong. An answer with no anchored candidate at all staysnot_stated.The F1 criterion from #105 applies to the exception. A declared value that the user stated before the model did does not count: an answer that repeats the user's figure in order to doubt it has not stated it.
What the exception gives up: a wrong answer that happens to state the declared figure about something else is now UNGRADED where it used to be
wrong. The example in the docstring is «Satsen for enslige er 8 100 kroner. Husleie på 8 300 kroner dekkes i tillegg.» It is never a pass.The module docstring describes the rule, the exception and the trade-off. The judge's
metadata.versionis set to 0.6, andsource.notesnow has a sentence on the change.The 36 cases
correctwrongambiguousnot_statedwrongambiguouscorrectnot_statedOf the 8 correct answers that were
wrong, 2 arecorrectthrough parsing and 6 areambiguousunder the exception. Two more correct answers went fromnot_statedtocorrectbecause «kr 8 300» and «NOK 8 300» are now read. The four that are stillnot_statedeither write the figure in a form the judge does not read («8 300,-», «8 300 norske kroner», a table cell without a unit) or put it in the sentence after the anchor.None of the 9 wrong answers moved towards
correct. One changed: F06, «Den statlige veiledende satsen for enslige er kr 8 100 per måned.», went fromnot_statedtowrong, because the figure is now read. Two wrong answers arecorrectbefore and after. F05 states 8 300 in one anchored sentence and a wrong figure in another, which is the trade-off the judge already documents. F09 states the right figure but frames it wrongly («du har krav på 8 300 kroner»); that error is for the default judge, not forfact_check.Stored outcomes
The change was run against 62 stored fact outcomes with no model call. 48 come from the first audit run and the three holdouts described in #105, 12 facts each, covering
helfo,nav_aap,skatteetatenandlanekassen. 14 come from one run of a pack on økonomisk sosialhjelp that is not yet in the repository, with the pack's one fact tried against every answer in that run. 0 of 62 changed.Without the F1 criterion, one of them would have changed. In the second holdout for
skatteetatenthe user gave the correct upper limit for minstefradrag, 95 700 kroner, and the model answered «Maksimumsgrensen på 95 700 kr virker lav i forhold til 104 450 kr for 2025, og jeg kan ikke bekrefte den.» The reader had labelled that fact a real error, and the judge returnedwrong. With the exception alone, the user's own figure in that sentence would have turned the outcome intoambiguous. That is why the F1 criterion is part of the exception.Tests
The 36 cases are in
tests/test_fact_check_judge.pywith their answers, anchors and outcomes as they stand, together with tests for the currency marker, «kr.» before a figure, hedge and range with a marker, the four separators, and the exception with and without a figure the user stated first.pytest tests/test_fact_check_judge.py: 109 passed, 1 skipped.pytest: 1620 passed, 4 skipped. Python 3.13,pip install -e .[dev,tracing].Limits
One reader and 36 constructed answers about one fact are not a precision estimate. The cases have now been used to change the judge.
Implemented with Claude Code (Opus 5.5); planned and reviewed with Claude.
Update: two more commits
b2312f8extends the exception. For declared values of 1 000 or more, the declared value also triggersambiguouswhen it stands without its unit («8 300», «8 300,-»). The limit is there because a small bare number may be a date or a list number. The F1 criterion also covers a value the user gave without its unit. A third reading of 50 new constructed answers had found three correct answers that came outwrongthis way; they now come outambiguous. None of the wrong answers moved towardscorrect, and 0 of the 62 stored outcomes changed. The same commit documents that a comma is read as the Norwegian decimal sign, so «NOK 8,300» is read as 8.3.9d0f99cdocuments one more limitation in the docstring and changes no code. A change in a figure written as a range («fra 8 100 til 8 300», «2026 – 8 300») is read as a range; when the answer also has a point figure in an anchored sentence, a correct answer can then come outwrong. A fourth reading found three such cases. They are documented, not fixed.On a blind run with real model answers (42 answers,
nav_sosialhjelpin #113),fact_checkjudged all six answers to scenario 1, the scenario that declares the fact,wrong, in agreement with a blind reader and the default judge.pytest tests/test_fact_check_judge.py: 163 passed, 1 skipped.pytest: 1674 passed, 4 skipped.