wallet: the deterministic parse must beat the model's location
ci / lint-test (push) Successful in 46s

Found by reading the backfilled rows rather than by a test. The precedence
was subtitle -> MODEL -> descriptor, so the model's answer won wherever it
had one, which is always. That defeats the entire point of parsing the
descriptor positionally: the ledger got "SAN FRANCISOUS" for the only
foreign merchant in the capture window, plus the padded "MELBOURNE   AU",
and the bare "Sydney"/"Perth" with their country codes dropped.

Correct order is subtitle -> deterministic descriptor -> model. After the
fix those rows read SAN FRANCISO US, MELBOURNE AU, Sydney AU, Perth AU,
and a subtitle-derived place still wins where one exists.

The test that should have caught this passed because its fixture omitted
`location`, so the fallback chain was never exercised — every real
interpretation carries one. Fixture now includes the model's actual
mangled answer for that row, so the test fails if the order regresses.

Re-ran the backfill on the corrected code: 21 transactions, $6,284.37
unchanged, 13 with a location. The 21 previously-written rows were deleted
first rather than superseded, which is normally forbidden on transactions
— checked before doing it that they carried zero splits, tags and
overrides, being machine-written minutes earlier by this same lane with
nothing yet attached.
This commit is contained in:
2026-08-22 16:33:56 +10:00
parent 8d1875225f
commit 3d0d75519a
2 changed files with 14 additions and 3 deletions
@@ -223,6 +223,11 @@ describe("location", () => {
await ingest(req({
...breadworldBank, event_id: 75, amount: 42.44,
merchant: "SP PEAKDESIGN",
// The model's own answer for this row, included because every real
// interpretation carries one -- omitting it is what let a wrong
// precedence order pass this test the first time, and ship
// "SAN FRANCISOUS" into the ledger.
location: "SAN FRANCISOUS",
notif_body: "$42.44 paid from Mastercard ending...8032. SP PEAKDESIGN SAN FRANCISOUS",
}));
const [t] = await txns();