Skip to content

Releases

fieldproof 0.2.7

Choose a tag to compare

@antonsoo antonsoo released this 03 Oct 01:59
pip install fieldproof

Compatibility

  • Python 3.13 and 3.14 are tested and declared. CI runs the suite on 3.14 as well, and the package's classifiers list both versions. The code is unchanged: with the newest release of every dependency, the tests pass on 3.14 and on 3.15's release candidate.

fieldproof 0.2.6

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 14:52
pip install fieldproof

Accessibility

  • The review UI, checked with axe-core (WCAG 2.1 A and AA, and its best-practice rules) in light and dark, at desktop and phone widths, on each sample document: no findings now. The faint text was 2.6:1 to 3.1:1 (light) and 3.4:1 (dark), and the "review" and "verified" labels just under 4.5:1 on their tints. The page has an h1, and the page viewer, which scrolls, can take keyboard focus.

fieldproof 0.2.5

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 13:10
pip install fieldproof

Security

  • The review UI carries a Content-Security-Policy. Scripts, styles and fonts load from the server that served the page only, and connect-src 'self' has the browser refuse to send a document, or anything read from it, to any other host, even for a script injected through a bug in how a field is rendered. Inline event handlers and eval are not allowed. Checked in Chromium and Firefox with a listener for policy violations, on the demo and on fieldproof serve through an upload, an extraction and the page images: none.

fieldproof 0.2.4

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 12:00
pip install fieldproof

Changed

  • The review UI's fonts ship in the package. fieldproof serve runs on your own machine, over documents you may not be free to share, and its page asked Google Fonts for its typography on every load (and fell back to system fonts without a connection). The same font files are now part of the wheel, with their SIL Open Font License texts (web/src/fonts/), and the page makes no request to any host but the server it came from. Nothing looks different: screenshots before and after match. The wheel grows from about 60 KB to about 530 KB.

fieldproof 0.2.3

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 11:29
pip install fieldproof

Security

  • The oldest dependency versions the package accepted had published advisories in exactly the code that reads what a stranger uploads: python-multipart 0.0.9, starlette 0.38.6 (through fastapi 0.115), pdfminer.six 20231228 (through pdfplumber 0.11.0) and Pillow 10.4 (the ocr extra), plus click 8.1.8. An ordinary install already got current versions; an install held back by another package's constraints could get those. The minimums are now the first releases without an advisory: python-multipart>=0.0.31, starlette>=1.3.1, pdfminer.six>=20251230, click>=8.3.3, Pillow>=12.3, and with them fastapi>=0.133, pdfplumber>=0.11.9, typer>=0.16. pip-audit reports nothing for the locked versions or for the minimum ones, and the tests pass on both.

fieldproof 0.2.2

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 10:26
pip install fieldproof

Fixed

  • A result or fixture JSON saved by a Windows editor or shell. Notepad's "UTF-8 with BOM" and PowerShell's -Encoding utf8 put a byte-order mark first ("not valid JSON (line 1, column 1: Unexpected UTF-8 BOM ...)"), and PowerShell's > writes UTF-16 ("is not UTF-8 text"). All three are read, by the CLI and by the review server.
  • Output written to a pipe or a file is UTF-8, so a document path outside the system's code page can be printed when stdout is redirected on Windows.

fieldproof 0.2.1

Choose a tag to compare

@antonsoo antonsoo released this 02 Oct 09:37
pip install fieldproof

Added

  • Published to PyPI: pip install fieldproof. The package includes the built review UI, so fieldproof serve works without a Node toolchain (scripts/bundle_ui.py builds it into the package before a release).
  • fieldproof --version.

Fixed

  • A value quoted from inside a longer word could be marked verified. The exact matcher refused a quote that cuts a word, and the fuzzy fallback then scored the same fragment 100/100 as a perfect partial match. On the example invoice, a vendor name of wind (inside "Northwind") and an invoice number of 0214 (inside "NW-20260214") both verified. A match now has to cover whole words; when the best fuzzy window cuts one, the quote is scored against the whole words, so those two are unsupported and 458.00 is a weak match for $2,458.00. Punctuation glued to a word may be left out of a quote (1 for 1,, 2,458.00 for $2,458.00), and every such occurrence counts when deciding whether a quote is ambiguous.
  • A string value one digit off verified: NW-20260215 for a document reading NW-20260214 is 96% similar, which passed both the grounding and the value check. Every run of digits in a string value now has to appear in the evidence as written.
  • --provider anthropic against the real SDK. The provider had only met a mocked client, which returned parsed_output=None for a reply that isn't the schema. The SDK's messages.parse raises instead: an extraction cut off at max_tokens (a long invoice) or refused came out as a pydantic traceback, Invalid JSON: EOF while parsing a string. The provider now streams the reply, reads its stop_reason and says which it was in one line: error: Claude's reply was cut off at 16000 output tokens, before the Invoice was complete; raise the limit (--max-tokens) or extract a shorter document. New --max-tokens option. The tests run the real SDK over a mocked HTTP transport.
  • The declared minimum anthropic>=0.40 had no messages.parse: AttributeError: 'Messages' object has no attribute 'parse'. The minimum is 0.77, the first release with structured outputs on the Messages API, and the provider tests pass on it.
  • Two more declared minimums did not work. With typer below 0.15.4 every command stopped (Type not yet supported: pathlib.Path | None on 0.12.0; make_metavar() takes 1 positional argument on --help with a current click), and with pydantic below 2.10 a typed result could not be built from Evidenced values. The minimums are typer>=0.15.4 and pydantic>=2.10, and CI has a job that installs the oldest allowed version of every direct dependency on the oldest supported Python and runs the tests there.
  • A match could begin or end inside a ligature (inal matched "final").
  • A result or fixture file that isn't valid JSON, isn't an object, or doesn't fit the schema printed a traceback from extract and verify, and was an unexplained 500 in the review UI. The CLI prints one line (error: result.json does not match the Invoice schema: total.value: Input should be a valid number, unable to parse string as a number) and the server answers 422 with the same message. A file that isn't a PDF, a missing API key and a failed API request are one line too.

Added

  • Seeded fuzz tests for the promise above: an exact match always covers whole words, a piece of a longer word never verifies, a value with a number the document lacks never verifies, and a damaged result file ends in a report or a one-line error.