What happens when a PDF has no text layer?
It's refused as a text source. If a whole document carries fewer than 40 letter-or-digit characters, that's not a text layer — a scanner's stray page stamp doesn't count — and the file falls through to the OCR tier instead of being guessed at.
src/Trove.Extract/PdfStatement.cs:48
Where does OCR actually run?
On the in-box Windows engine (Windows.Media.Ocr) — nothing downloads, nothing leaves the machine. It exposes no per-word confidence, so every OCR value carries a flat 0.9, and that number is exactly what arms the strict validators.
src/Trove.Extract/OcrStatement.cs:21
Why PdfPig and not PDFium?
Text-layer extraction is pure managed code — no native binaries to audit. Rasterization concerns never apply, because Trove reads the PDF's text layer and never renders the page.
src/Trove.Extract/PdfStatement.cs:2
How can a valid CUSIP check digit still lie?
The checksum is blind to 5↔S swaps at odd positions — the doubled digit-sums differ by exactly ten. So on scanned input, if a plausible misread also yields a valid CUSIP, the check digit proves nothing and Trove abstains. A unit test pins a concrete pair where both readings validate.
src/Trove.Core/Validation.cs:64 · ValidationTests.cs:28
What is the strongest single check?
Gross − Federal − State = Net, decimal-exact to the cent. If the quartet doesn't reconcile, all four amounts abstain together — you can't tell which one was misread, so none of them may claim to be right.
src/Trove.Core/Validation.cs:249
What does "abstain" look like in code?
A status plus a human-readable reason — the value itself is never edited. Validators can only downgrade a field (Ok → Low → Abstain); nothing in the engine can promote a doubtful value back up.
src/Trove.Core/Validation.cs:297
Is a format regex enough to auto-fill from a scan?
No. A recognized field stays confident only with checksum-grade proof: an unambiguous valid CUSIP, or an amount whose full quartet reconciles — the equation is the checksum. Everything else drops to an amber best-guess the agent must confirm by hand.
src/Trove.Core/Validation.cs:175
Why is fill a real paste, not UIA SetValue?
SetValue writes the DOM but bypasses framework state — React's value tracker never sees it, and the form posts empty. That was proven against a live React mock, server-side, and the receipt stayed in the test suite. A real paste (focus, Ctrl+A, Ctrl+V) produces the same events a human does.
src/Trove.Forms/FormFiller.cs:140
How are labels found on pages with none?
Geometry. Prefer text on the same row to the left (gap under 260px); otherwise text directly above (gap under 44px); ties go to the smallest gap. That resolves hostile legacy pages with zero accessible names.
src/Trove.Forms/FormReader.cs:115
What if I alt-tab in the middle of a fill?
The run aborts. Between focusing a field and sending the paste chord, Trove re-checks that the target window is still foreground — if focus moved, the rest of the plan is equally unsafe, so nothing more is written and the overlay shows a red "stopped early", never a green done.
src/Trove.Forms/FormFiller.cs:150
How does a correction become permanent?
Remapping a row records (form fingerprint, field signature) → key in a local mappings.json. After three confirmations it's promoted — and a promoted mapping beats every heuristic from then on. It stores field names, never document values.
src/Trove.Forms/MappingStore.cs:11
How is every write verified?
By reading it back. After the paste, the control's value is re-read up to 12 times, 40ms apart. Outcomes are typed — "Pasted" only ever means verified, and a control that offers no readback is reported honestly as "PastedUnverified".
src/Trove.Forms/FormFiller.cs:126
Does the log ever contain document values?
No. The diagnostic log records field keys, counts and outcomes only — the filler's comments are explicit: never log the value — and it truncates itself at 512KB so an unattended machine can't accumulate an unbounded record.
src/Trove/MainWindow.xaml.cs:28
Can clipboard history leak a statement?
Staged values are marked with all three Windows opt-out formats — no history, no cloud sync, no monitor processing. Clips already marked sensitive (a password manager's) are never captured at all, and the agent's original clipboard is restored after the fill.
src/Trove/ClipboardSafety.cs:19
How is "zero network calls" provable?
By absence. Search src/ for HttpClient, Socket or WebRequest: zero hits. Extraction is a string parser, managed PdfPig and the in-box OCR engine — nothing in the shipped code can open a connection. The compliance doc publishes the grep as its own reproduction step.
docs/COMPLIANCE.md:42
Could Trove ever click Submit?
There is no code path to a button. The filler exposes no Invoke on anything clickable — the only submit press in the entire repository lives in the test harness, which exists to verify what a human's submit would actually post.
docs/COMPLIANCE.md:9 · tools/Smoke/Program.cs:229
What do the 36 validation tests actually pin?
The refusal machinery: real published CUSIPs (Apple, Microsoft, Amazon), the 5↔S checksum blindness, amount reconciliation including zero withholding, date ordering, and label matching — 16 facts plus 20 theory cases, run on every push.
tests/Trove.Core.Tests/ValidationTests.cs:13
Why is reading handwriting correctly a test failure?
Because Trove promises not to read it. The hand-completed tier marks the handwritten fields as must-abstain; if the engine extracts them anyway, the scorer counts it as false confidence — and false confidence must be zero or the build fails.
tools/Score/Program.cs:45
What does the echo server prove?
What actually posted — not what was typed. The end-to-end harness fills a real form window, submits, then checks the server's own record: all 17 fields must arrive exactly as extracted, on all three mock forms, including the React one.
tools/Smoke/Program.cs:233
What runs when code is pushed?
A Windows runner builds the entire solution and runs the full core test suite — 125 tests — on every push and pull request. The badge on the README is that check — green in about two minutes.
.github/workflows/ci.yml:1
Why is the CI-built installer unsigned?
Because the signing key never leaves the machine. Tag builds produce an unsigned QA installer for smoke-testing only; shipping builds are signed locally — the exe first, then the installer wrapped around it.
.github/workflows/release.yml:1