v0.0.9 — Audit Pass
Audit pass. Addresses the three Critical findings and all eight quick wins from the deep audit, adds a hybrid trust & correctness slice, an examples/docs regression suite, and an LLM-accuracy eval harness. Drains all open Dependabot version-bump PRs and resolves all open security alerts. 818 tests, 100% line+branch coverage enforced in CI, full ubuntu/macOS/Windows matrix on Python 3.10–3.14.
New features
1. Page provenance for every extracted row
result = smart_ingest("statement.pdf")
for tx in result.transactions:
print(tx.amount, tx.description, "page", tx.source_page)extract_text_pages() keeps per-page text instead of one joined blob, and smart_ingest attributes each text-LLM row back to the page containing its description; vision rows inherit the page from their bounding box. Untraceable rows stay None — an honest signal, never a guess. Surfaced in the ingest CSV (source_page column) and the review UI.
2. Cross-statement continuity check
from bankstatementparser.hybrid import scan_and_ingest
batch = scan_and_ingest("statements/2026/")
if batch.continuity and batch.continuity.breaks:
for b in batch.continuity.breaks:
print(f"{b.previous_label} closed at {b.previous_closing}, "
f"{b.next_label} opened at {b.next_opening} (gap {b.gap})")The closing balance of statement N must equal the opening of N+1 — the Golden Rule extended across a folder of monthly statements. A missing month, duplicated export, or hallucinated balance shows up as a ContinuityBreak.
3. Confidence-driven review: --review-below
bankstatementparser --type review --input result.json --review-below 0.8Per-row extraction confidence is now acted on, not just displayed: low-confidence rows are routed into the interactive review walk even when statement-level verification passed. Review mode also re-runs the Golden Rule after every accept/edit/delete and appends a reverify audit entry — no more stale verdicts.
4. French & Spanish CSV headers on the deterministic path
Date opération, Libellé, Montant, Solde, Devise, Fecha, Concepto, Importe, Saldo, Divisa, … now parse deterministically — no LLM fallthrough. Header normalization folds accents (NFKD), so Débit/Crédit/Référence resolve through the existing English synonyms.
5. LLM-accuracy eval harness (CI, non-blocking)
python scripts/run_llm_eval.py --mock # harness self-check
python scripts/run_llm_eval.py --model ollama/llama3 --min-f1 0.9A pure scoring module (bankstatementparser.hybrid.evaluation) compares extractions against ground-truth cases and produces deterministic precision/recall/F1 plus per-field accuracies. CI blocks on the mock self-check; the real-model eval runs non-blocking, gated on the BSP_EVAL_MODEL repo variable. Every prompt or model tweak is no longer a silent gamble.
6. Examples & docs regression suite
Every shipped example script (including the shell walkthroughs) runs end-to-end as a subprocess in CI, and every fenced code block in README/FAQ/docs is executed against repository fixtures or import-verified. It immediately caught a real bug: --type camt console output crashed on real statements — fixed.
Breaking changes
Per SemVer, anything may change while the version is 0.y.z. Migration notes for each item are in the CHANGELOG.
Pain001Parser.get_summary()raisesPain001ParseErrorinstead of returning an error dict; theerrorkey is gone fromSummaryRecord.- Garbled or missing amounts raise instead of silently becoming
0.0—Decimalend-to-end for all money fields. openpyxlmoved to the new[excel]extra; CAMT streaming no longer defaults transaction currency to"".
Correctness & security
- REST API safety floor: upload size cap, suffix allow-list, generic 422 with UUID correlation id.
value_dateis no longer silently copied frombooking_dateby the LLM extractor.- CAMT recovery-mode parsing is opt-in; the strict lxml default rejects entity-expansion attacks at parse time.
- Vision rows correctly labelled
source_method="vision"; multi-currency statements no longer report a falseDISCREPANCY. - All 20 open Dependabot version-bump PRs drained, all 18 security alerts resolved.
Install
pip install bankstatementparser==0.0.9
pip install 'bankstatementparser[hybrid-vision]' # LLM + vision extrasFull changelog: v0.0.8...v0.0.9