Trove for Windows LOCAL ONLY

Copy a document.
The form fills itself.

A document-to-form autofill tool for the people who re-key statements all day. It never guesses. It never submits. It never leaves the machine.

Ctrl+Shift+V on any form — that's the whole product.
Scroll
The problem

One wrong digit doesn't stay wrong once.

Agents read values off a statement and type them into a browser form, all day. People make typos. And a typo in an account number doesn't stop at the form — it travels.

09:14 AMA statement arrives

Fourteen values to move into the stop-&-reissue form. By hand.

09:16 AMOne 8 becomes a 3

Keyboard slip. The form accepts it — the format looks fine.

DAY 3Three systems downstream

The wrong number has been copied into places the agent has never seen.

WEEK 2The ripple

Hours of unwinding, calls, corrections. All from one keystroke.

Watch it work

A paste that understands the page.

This is the real flow, re-enacted: a synthetic Statement of Distribution on the left, the destination form on the right. Values only move when Trove can prove them.

MERIDIAN TRUST & REGISTRAR CO.
STATEMENT OF DISTRIBUTION · SYNTHETIC
Registered Holder:RUTH M HALVORSEN
Account Number:MT-88867271
Security:PALISADE CREEK REIT
CUSIP:7613845L6
Certificate No:C-2025-819197
Record Date:01/16/2026
Payable Date:02/13/2026
Gross Amount:6,344.86
Federal W/H:806.29
State W/H:222.08
Net Amount:5,316.49
Check Number:13510074
Reissue Payee:Ruth M Halvorsen
Retain for tax reporting purposes · Meridian Trust & Registrar Co.
Stop & Reissue Request
Form SR-114 · shareholder operations
RUTH M HALVORSEN✓ FILLED
MT-88867271✓ FILLED
7613845L6✓ CHECK DIGIT
6,344.86✓ FILLED
806.29✓ FILLED
222.08✓ FILLED
5,316.49✓ FILLED
6,344.86 − 806.29 − 222.08 = 5,316.49RECONCILES ✓
Handwritten on the source — Trove won't read handwriting. This one's yours.YOU TYPE THIS

The refusal is the feature. A blank field with a reason is safe; a confidently wrong account number is the thing that starts the ripple. Trove abstains out loud.

The constitution

Three rules break every tie.

01

It never guesses

A value is offered only when Trove can defend it — exact source text, or a checksum-grade validator vouching for a scan. Doubt renders as a blank field and a stated reason.

false-confidence: 0 / 3,120 fields
02

It never submits

Trove fills; the human checks and sends. Review before anything is written, every write verified by readback, and no code path that touches a submit button. Ever.

review → confirm → fill → verify
03

It never leaves the machine

No cloud, no account, no telemetry, no AI model at all. Extraction, matching, learning and filling happen on the agent's PC. Grep the source for HttpClient: zero hits.

network calls in src/: 0
Found by our own adversarial corpus

The checksum that lies.

A CUSIP carries its own check digit — misread one character and the math breaks. Almost. At odd positions, the checksum is blind to a 5↔S swap: the doubled digit-sums differ by exactly ten. And 5↔S is one of the most common OCR confusions there is.

A misread security number could pass validation and reach a form. So Trove adopted a rule instead of a patch: if a plausible misread also yields a valid CUSIP, the check digit proves nothing — refuse it. The test suite pins it with real published CUSIPs.

355958FD6✓ valid
3S5958FD6✓ valid
two readings, both “valid” → trove abstains
Under the lid

Three ways in. One standard of proof.

One gesture — copy — carries three payloads. Each tier declares how much it can be trusted, and the validators hold every value to the same bar before it may touch a form. Forms are read through Windows UI Automation: no browser extension, and hostile legacy pages with zero labels resolve by geometry.

TIER 1 · EXACT

On-screen text

Select-all, copy. The text is exact — no recognition step, nothing to misread. Most of an agent's day lives here.

confidence 1.0 · extraction 100%
TIER 2 · EXACT

PDF text layer

Copy the file in Explorer. Born-digital PDFs carry their text precisely; a PDF without a text layer is refused to the scan tier.

confidence 1.0 · gap vs tier 1 0.00pp
TIER 3 · RECOGNIZED

Scans, via OCR

On-device Windows OCR. Only checksum-vouched fields auto-fill — a valid unambiguous CUSIP, amounts that reconcile to the cent. Everything else is an amber best-guess the agent confirms.

confidence 0.9 · false-confidence 0
Receipts, not claims

Verified server-side, on purpose.

Every number below is reproducible from the repository — a synthetic corpus with per-field ground truth, an echo server that records what a form actually posted, and a deliberately corrupted document slice that the refusal machinery must catch.

0
false confidences across all four scoring tiers — 3,120 fields, 200 documents
100%
of corrupted & handwritten fields caught and refused by the validation engine — zero slipped through
17/17
fields server-verified on all three mock forms — including a React form and a label-less legacy page
36
validation tests pinning the refusal machinery — including real published CUSIPs for Apple, Microsoft and Amazon

Reproduce it: dotnet run --project tools/Score  ·  dotnet run --project tools/Smoke -- "…" stmt-0002 --submit

Ask the source

Answers, with receipts.

Development questions answered from the repository itself — every answer carries the file and line that make it true. Press a question.

move to orbit · press a question

Prefer it flat?

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