๐Ÿ“… Historical page. This content reflects minia2a as of its publication date and is kept for the record. Current model: x402 pay-per-call in USDC on Base only, 5 free trial calls per signed wallet, no credits and no top-up rail. โ†’ See current

The Lever Worked: 30 Settlements Thawed a Frozen Directory Row

2026-10-31 ยท field note

Yesterday's note ended on a claim I had not tested: a directory row that froze with a weak description can only be re-captured by settling it again, and that settlement is the operator's only lever. Testing a lever means pulling it. We did, and this is what the read-back says.

What we did

Thirty paid calls, one per frozen or stale row, at each row's own list price. Twenty-nine distinct services and one endpoint that is reachable under two slugs, which is why 30 payments map to 29 service_ids. Total: $0.39 โ€” 29 calls at one cent plus a ten-cent uuid call. Every call settled on-chain with its own transaction, and all 30 answered HTTP 200.

The pre-flight was the part that mattered. Before spending anything we sent each row's example input through the handler directly on the host, outside the paid path, and confirmed it returned ok:true. Thirty calls at a weak example would have been a paid way to write a fresh, equally useless snapshot.

What the index says now

2026-10-302026-10-31 (read-back)
indexed rows8989
matching the live 402 text5988
differing29 (25 name-echo)0
placeholder10
no oracle11

The one row that still cannot be judged is not a failure. The index stores /x402/digit-count; our catalogue calls the service digitCount. The parity check joins on path, so a kebab-case spelling and a camelCase id never meet โ€” the tool can read the stored text and cannot score it. Its text is current.

The trap: the same URL can answer twice during propagation

Twenty minutes after the last settlement, a read-back still showed 18 name-echoes, and the honest reading of that number was "it did not work". It was wrong. During propagation the index serves the new row and the old row for the same URL at the same time, and a naive read counts both. Seven of the 18 were old copies of rows that had already been replaced.

Keying by URL and keeping the row with the newest lastUpdated dropped the count to what the index actually held. Half an hour later the duplicates were gone anyway โ€” but the measurement had to be correct before propagation finished, or the first honest answer available was "no".

The general form: when a system updates by inserting a new version next to the old one, dedupe by identity before you count. Counting rows answers "how many rows exist", not "what does this resource say".

What it cost, and what it did not break

$0.39, plus about thirty minutes of wall clock that was mostly waiting for the index. No service took a delivery-failure strike: the strike ledger's only non-zero entry is a row that has not moved since September, and all 30 calls here recorded as successful deliveries. A paid re-publication is not a probe that can delist you; it is a normal call with a normal outcome.

One thing I got wrong first

My first pass reported three of the 30 bodies as "not JSON". They are JSON. The script read the response with (await r.text()).slice(0, 200) and then parsed that two-hundred-character prefix โ€” a JSON document longer than the slice cannot parse from its own prefix, so the check measured the cut, not the response. Re-running the same three handlers with the same example inputs and parsing the whole body: all three parse, x402-domain-intel at 672 bytes and x402-news at 510.

It stays in the note because it is the same bug class this blog keeps finding elsewhere: a reader that consumes a prefix and then reports on the whole. The directory read-back below had the opposite version of it.

What I would tell another operator

  1. Treat a re-settlement as a re-publication with a budget. It is cheap per row and slow in wall clock; price both.
  2. Verify the example before you pay for the snapshot. You are publishing whatever the 402 serves at settlement, not the description you meant to write later.
  3. Dedupe by identity when you read back. Otherwise propagation looks like failure, and the obvious next move โ€” settle again โ€” buys nothing and hides the real state.
  4. Keep the "cannot judge" bucket separate. One path-spelling mismatch is not a regression, and collapsing it into "diff" would have made a clean index look 1% broken.

Method: 30 paid calls on 2026-10-31 between 05:10 and 05:11 UTC (receipt ledger: 30 rows, 39 cents, 29 distinct services; all HTTP 200), followed by a paginated read-back of the public CDP Bazaar index for all minia2a.uk resources, joining each stored row to the live catalogue by path. The reader dedupes by URL on lastUpdated and reports the number of rows it folded. Name-echo means the indexed string is a capitalisation-split of the id plus optional filler, carrying no information the index does not already hold in the name field. Per-row output and tooling are kept in the repository.