One hunt, in five lots
Screens from the working app, run locally against live eBay listings on October 9, 2026. Each is cropped to the part described; tap one to see the full screen.
Swipe sideways to see more →Say it in plain words
"Anything signed by Bobby Jones." A low-cost model turns the sentence into filters you can see and edit: the subject, who must have signed it, aliases, and words to rule out. It knows golfer Bobby Jones is not the basketball player of the same name.
Swipe sideways to see more →A deal board, not a search page
Code screens every listing first: wrong signer, reproductions, other sports. Survivors go to the model in batches, and every verdict must quote the listing or it's discarded. Live auction-house lots are screened in the same pass and flagged as a second hunting ground.

The price story, done in code
Cost to acquire, wholesale from approved auction comps, a sell value that always names its source, eBay fees, max to pay and margin. Here, a $331 buy against a $556.74 ceiling. With fewer than three comps the card says "thin" or "insufficient" instead of guessing.

Every number opens its records
Click any figure and the sales behind it appear: hammer, buyer's premium, shipping (actual or estimated) and a link to the original lot page. A test feeds the app a fake model that "states" prices and proves none of them reach a money field.
Swipe sideways to see more →The one agent, on a short leash
On demand it pulls a listing's claims, chooses its own searches through the auction archive, and files a report. Its test case: a lot claiming feather balls were made "until 1950." It flagged the conflict and cited an archived gutty ball from c.1865. A verdict stands only if code finds its quote in a record the agent actually fetched.
Where the AI sits, and where it doesn't
Each model job is narrow, matched to the cheapest model that does it well, and checked by code before anything is kept. Costs are from the live runs.
| Step | Done by | Guardrail in code | Live cost |
|---|---|---|---|
| Sentence to target | Haiku 5.5 | Structured output against a schema; every field shown and editable; word rules if no key. | $0.0003 |
| Screen eBay listings | Code then Haiku 5.5 | A verdict whose quote isn't in the listing becomes "unsure"; a skipped listing is asked again, never dropped. | $0.0025 per hunt |
| Read item attributes | Haiku 5.5 · Batch API | The one-time archive pass runs as a batch at half price; attributes without a verbatim quote are dropped. | ≈ $0.0002 each |
| Propose comparable sales | Sonnet 5.5 | Sees descriptions only, never prices, so it can't anchor. IDs and quotes validated; you approve or reject; rejections stick. | $0.017 per item |
| All money math | Code | Exact decimals in one module with no model client. Proven by test. | $0 |
| Research a listing's claims | The one agent | Picks its own lookups, loops, reports. Step cap and cost cap; a "conflict" needs a quote found in a record it fetched. | $0.03–0.08 per listing |
Rules the code enforces
No price from a model
Models extract, compare and cite. Arithmetic lives in one module with exact decimals, and any model-stated number on a money field fails the tests.
Quote it or drop it
Attributes, screening verdicts, comp reasons and research findings all carry the exact words they came from. Code looks for those words and discards whatever it can't find.
One agent, bounded
Only the researcher decides its own steps, because only that job needs open-ended lookups. It has a step cap and a cost cap and must cite fetched sources.
Spend is metered
Every call is costed from its token usage and logged. A counter in the app shows each run's tokens and dollars against the monthly cap.
Polite data access
Both auction houses block scripts, so nothing crawls. Pages were viewed in a browser at human pace, saved with checksums, and never re-read once a sale closed.
Marketplace rules in code
eBay data follows the API license: a daily call cap, listings shown with their age after six hours, no seller data or images stored, and a 30-day purge.
How good are the prices?
How the backtest works. Each past lot is priced only from sales dated before it, then compared with what it actually made. This run uses code-picked comps alone, with no model and no human approval: the floor, not the product.
The harder numbers. 43% of lots had a comp median within 2× of the actual price, and only 26% of the 1,219 archive lots had three or more earlier comps to price from. Thin data is the main limit, which is why the card says "thin" or "insufficient" instead of guessing.
One-off memorabilia prices vary widely, so the honest claim is a ballpark. The scorecard is built to show whether model-proposed, human-approved comps tighten it.
Finds the conflict
Flagged a lot's "until 1950" date, citing an archived c.1865 gutty ball. It took one fix: archive search now ranks partial matches.
No false alarm
On a clean feather-ball lot, every checkable claim came back consistent, each with a quoted source.
Right Bobby Jones
The basketball player dropped out. Artist-signed prints were ruled out, and author-signed books were marked "unsure".
How it's made
Decimal values stored as strings
AppFastAPI on 127.0.0.1 with a hand-written HTML, CSS and JavaScript front end; no build step
ModelsAnthropic SDK: Haiku 5.5 for bulk reading, Sonnet 5.5 for comps and research with server-side fallback, Message Batches for the archive pass
SourceseBay Browse API; TheGolfAuction and Golden Age Auctions archives, captured in a browser
Tests66 pytest tests with fake and scripted model clients, plus live runs for the researcher, screening and comps
SizeAbout 4,200 lines of Python across 21 modules and 9 test files
WorkflowOne daily command refreshes eBay, re-hunts saved targets, records live price ranges and purges old data