TroveFillfor Windows LOCAL ONLY Guide Flight School ✈ Developers — start here →

Copy a document. The form fills itself.

A document-to-form autofill tool for the people who re-key documents 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 document 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 vendor record arrives

Eighteen values to move into the vendor onboarding 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 vendor account record on the left, the destination form on the right. Values only move when Trove can prove them.

HARBORLINE SUPPLY CO.
VENDOR ACCOUNT RECORD · SYNTHETIC
Legal Name:MARISOL T VANCE
Company Name:Cedarline Fab LLC
Email:m.vance@example.net
Telephone:541-555-0182
Address:41 Elm St, Eugene, OR 97401
FEIN:93-4471820
Invoice No:INV-2026-4127
Bill Date:03/02/2026
Due Date:03/18/2026
Subtotal:2,021.85
Amount Due:2,184.60
PO No:PO-551903
Authorized Signer:M. T. Vance
Synthetic test data · Harborline Supply Co. is a fictional company.
Vendor Onboarding
Cobalt Ridge Procurement · supplier setup
MARISOL T VANCE✓ FILLED
m.vance@example.net✓ FILLED
541-555-0182✓ FILLED
93-4471820✓ VALID EIN
INV-2026-4127✓ FILLED
03/02/2026✓ FILLED
03/18/2026✓ FILLED
03/02/2026 ≤ 03/18/2026DUE AFTER INVOICE ✓
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.

Now see it in real action

Not a re-enactment — the real app.

The stage above is how it thinks. Below is the thing itself: the Windows app, one Ctrl + Shift + V, filling three different forms it was never taught. Every value verified by read-back — and the full SSN held for you, never auto-filled.

●  Real capture
Three forms · three copies · one gesture each. Plays silent here — press play for full-screen with controls.
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 / 5,400 fields per tier
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 validator says so in plain words: the value could be read two ways.

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. Nothing read from a scan auto-fills — every recognized value is an amber best-guess, shown beside a crop of the source, that the agent confirms.

confidence 0.9 · false-confidence 0
●  Real capture
One document · text, then its PDF, then a scan · the same form each time. What the scan reads is held for a human to confirm.
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 — 5,400 field-expectations per tier, 200 documents
100%
of corrupted & handwritten fields caught and refused by the validation engine — zero slipped through
20/20
fields verified live on the vendor form — plus a React app, a label-less legacy page and a Java Swing app, every one read back
453
unit tests pinning the refusal machinery — checksums, the sensitive-value gate, cross-field date rules and the never-submit scan

Reproduce it: dotnet run --project tools/Score  ·  dotnet run --project tools/Smoke -- "Cobalt Ridge" rec-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/PdfCapture.cs:105
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 anything below 1.0 is review-only by construction. src/Trove.Extract/OcrCapture.cs:22
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/PdfCapture.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, saying why. src/Trove.Core/Checksums.cs:234 · GenericValidation.cs:96
What is the strongest single check?
The sensitive gate. SSNs, routing and bank account numbers, card numbers and the like are extracted and validated but never auto-filled — caught by their label, or by their shape (a structurally valid SSN, a Luhn-valid card number) even under a label Trove has never seen. They are masked and wait for a human to confirm. src/Trove.Core/GenericValidation.cs:243
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/GenericValidation.cs:274
Is a format regex enough to auto-fill from a scan?
No — and on a scan nothing auto-fills at all. Every recognized value (confidence below 1.0) starts as an amber best-guess, shown beside a crop of the source pixels, that the agent must confirm. Checksums and cross-field date rules can still knock a misread down to a blank; nothing can promote it to a silent fill. src/Trove.Core/TextRecordParser.cs:119
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 document?
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 validation tests actually pin?
The refusal machinery: broken routing and EIN checksums abstain, a valid routing number stays review-only, SSN-shaped and Luhn-valid card values are gated even under unknown labels, start-after-end dates abstain together, and derived name and address parts keep their source's provenance. tests/Trove.Core.Tests/GenericValidationTests.cs:50
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 both test suites — all 453 tests — on every push and pull request. The badge on the README is that check; a run takes about two minutes, and the honest habit is to run it for the exact commit under review before relying on it. .github/workflows/ci.yml:1
Why is the CI-built installer unsigned?
Because no signing key exists in this repo at all. Every artifact here is unsigned and evaluation-only; the intended path is that the adopting company rebuilds from source and signs with its own certificate — the exe first, then the installer wrapped around it. .github/workflows/release.yml:1