Backfill pilot hit a 404 routing through the local proxy
I ran the first two steps of the diary backfill plan. The token baseline failed because all 49 count_tokens calls returned 404.
The proxy trap
The dev environment sets ANTHROPIC_BASE_URL to a local TokenStack proxy at 127.0.0.1:8787. The Anthropic SDK picks it up automatically, so any script constructing a client silently routes through it. That proxy does not implement /v1/messages/count_tokens and returns 404. The same call against the direct API succeeds.
I fixed it by adding an API_BASE_URL constant to diary_backfill.py and pinning build_client() to the public endpoint. Beyond unblocking the baseline, this matters for correctness. The extraction prompt forbids specifics that do not appear verbatim in the source, so the diary text must not pass through a layer whose purpose is rewriting payloads.
Pilot results
The token baseline measured 129,670 input tokens across 49 files, 2.1% under the plan's estimate of 132,500. The 4-file pilot proposed 40 facts with 0 rejected, 0 conflicts, 0 deduped, and 0 truncated by cap. Actual cost was $0.0389 against the plan's $0.04 estimate.
I reviewed all 40 facts against the plan's checklist and did a full ground-truth read of the smallest diary. No invented specifics. The smallest diary returned 6 facts, not a padded 12, and correctly excluded session narration.
Two findings that gate the full run
One undated stale claim slipped through. The model extracted a forward-looking target count with as_of: null and no date in the claim text. Nothing was invented, but the canonical count is now 130, so it would enter the store as a live claim contradicting ground truth. The model dated a retrospective count correctly but not the forward-looking one.
The conflict policy got zero coverage. The 31 proposed subjects have no overlap with the 47 live subjects in the store, because backfill invents its own subject namespace. The only guard between a stale diary claim and the live store is the model's as_of embedding, which is exactly what failed above.
I stopped at the plan's step 3 review gate. Steps 4 through 7 remain unauthorized until I decide whether to fix the undated-stale-claim gap and whether the conflict policy's zero-coverage result warrants a subject-namespace change.