FIANGSHIcensus 2026-11-09 02:57 UTC · 90-day window · providers live · settlement dry-run

Docs/How it works/Test report

On this page
  1. Where things stand
  2. How we test
  3. Timeline
  4. Every failure, in order
  5. Rule changes, each one measured
  6. Surf: what we measured about the data source
  7. Still failing or not done
  8. Tests and gates, commit by commit
  9. Lab runs, as committed
  10. Last measured status

Test report: from failures to green

Fiangshi decides whether an AI agent should pay a stranger, so it has to be believable when it is wrong as well as when it is right. This report keeps every failure on the record: what we saw, why it happened, what we changed, and the evidence that the change worked. Nothing here has been rewritten after the fact. A lab case written under an old rule stays visible as "superseded", not edited.

The lab history, the per-commit test and gate counts, and the last measured status at the end of this page are computed from committed files every time the page loads. Every other number on this page comes from a committed script or fixture, named next to it.

Where things stand

measurevaluesource
census800 of 1,923 Base payees, 90-day window, taken 9 Novscripts/audit.ts, data/numbers.json
verdicts49 ALLOW / 539 REVIEW / 212 BLOCKscripts/numbers.ts
verdictable payees765 (95.6%)scripts/winrate.ts
lab9 cases: 8 pass, 1 superseded by a documented rule changescripts/matrix.ts
real sellers in the lab (controls)3 of 3 reach ALLOWartifacts/matrix.md
accept gates15 of 15, offline, network unpluggednpm run accept
end to end10 of 10 on a local server, with no keys (fixture mode) and with keys (live)npm run localhost-check
census cost252 credits billed for 800 payeesfixtures/audit/balances.json
warm check251 ms medianartifacts/demo-stats.json
cold check10.8 s, 8 credits, then 237 ms from cacheartifacts/cold-live.md

How we test

There are four layers, and each one must be green before a commit.

  1. Unit and table tests (npm test, vitest). Pure functions (score, rules, receipts, drift, the probe parser, the markdown renderer, translations) are tested at their edges: 0, the middle, 1, and missing. Each rule has its own table of cases, and a precedence test proves a rule beats a model ALLOW.
  2. Accept gates (npm run accept). Fifteen checks run with the network blocked by a preload that refuses every connection except the local machine. They are listed in the table below.
  3. End to end (npm run localhost-check). A real server on a free local port, then ten checks over HTTP: the site, the free check, a BLOCK with a receipt, the paid 402, a paid call with a test payment header, verify, tamper, the index, the badge and the timing.
  4. The adversarial lab (npx tsx scripts/matrix.ts). Six attack cases and three real sellers run through the live pipeline. The expected answer for each case is committed before the run, and is never edited afterwards.
gatewhat it proves
G1the code typechecks and builds
G2every test passes with no network
G3the probe parses every recorded 402
G4the snapshot hash is the same across two builds
G5an offline check finishes in under 300 ms
G6a rule beats a model ALLOW
G7a receipt verifies, and any edit breaks it
G8a broken model gives REVIEW, marked degraded
G9the budget guard refuses call N+1
G10the index page builds with no script
G11the recorded real 402s are untouched and all parse
G12every document agrees with data/numbers.json
G13a repeated cold check makes zero Surf calls
G14the kinship thresholds hold
G15the sensitivity table matches the numbers

A fifth check runs once per release: a fresh copy of the repository with no keys, then npm ci, npm test, npm run accept and npm run localhost-check. It has passed every time since 9 Nov.

Timeline

datephasewhat was builtcommit
8 Nov0skeleton, frozen data contracts (zod), canonical hashing4f15a55
8 Nov1–7 offlineprobe, snapshot, score, rules, model check, receipts, ledger, drift2814c52
8 Novlocal verification10 offline accept gates, the no-network preloadfbbef4b
8 Nov3b–3fSurf installed and measured, 12 real 402s recorded, billing model, E v2, models wired live41f235c … c6bdf17
9 Nov3g–3kpaid audit gate, fixture guard (G11), staged census runner, the 800-payee census79cd224 … 120f116
9 Nov3lrule I (null payee), keccak-256 and EIP-55 in the repo, rule set frozen at sixb1a6ffd
9 Nov3m–3nidentity v3, adversarial lab with expectations committed first3de3cbe … 8290a69
9 Nov3b-fix–3hoptional identity enrichment, API and real 402, end to end check, README, identity neutrality, fixture mode218e5fc … f693300
10 Nov3i–3kthe site (no script), operator-only identity labels, guide and legal pages, evidence sourcesfbf90f5 … 224ae4c
11 Novfinal A–Fkinship calibration, funder labels re-asked, cold check live, win-rate, single source of numbers (G12–G15)c9280f3 … 5696cd2
11–12 Novsiteguide with real endpoints, test report, crash fix, four languages7628f67 … 7cfe713
13 Novconnectarchitecture page, connect guides, MCP server, free JSON preview, first-visit tourthis release

The full per-commit list, with the number of test files, test cases and gates at each commit, is in the table near the end of this page.

Every failure, in order

Each entry has the same four parts. Seen is what went wrong. Cause is why. Fix is what changed. Proof is how we know it worked.

F1. Seven real 402s would not parse (8 Nov)

F2. Surf billed more than it reported (8 Nov)

F3. The first unattended run wasted credits (9 Nov)

F4. An async scan was refused for size (9 Nov)

F5. Dolphin returned empty answers (9 Nov)

F6. The best score belonged to a dead end (9 Nov)

F7. The first lab run passed 3 of 9 (9 Nov)

F8. A rule punished being examined (9 Nov)

F9. A commit went in while a gate was red (9 Nov)

F10. The end-to-end check failed for reasons outside the code (9 Nov)

F11. A fresh copy without keys scored 8 of 10 (9 Nov)

F12. The identity rule's only live BLOCK was wrong (10 Nov)

F13. Receipts misnamed where evidence came from (10 Nov)

F14. The first kinship softening went too far (11 Nov)

F15. A headline number was the reported one, not the billed one (11 Nov)

F16. A failing request could crash the server (12 Nov)

F17. The report showed a stale status (12 Nov)

F18. The MCP server could not use fetch in tests (13 Nov)

Rule changes, each one measured

Every rule change was simulated on the census before it was applied, and its effect was recorded.

datechangeeffectfile
8 NovE v1 (token share) → E v2 (payer concentration)E stops rewarding a seller for using one tokenartifacts/capability.md
9 Novrule I added (null payee)the top-scored dead end is blockedsrc/core/v6.ts
9 Novidentity v3 (corroboration by host, path, catalog or label)simulated first, in 46c0e86src/core/identity.ts
9 Novidentity optional (timeout never caps)lab controls reach ALLOWsrc/adapters/dolphin.ts
9 Novidentity neutralityexamined sellers are no longer penalisedsrc/core/score.ts
10 Novoperator-only labelsone false BLOCK becomes REVIEWsrc/core/identity.ts
11 Novkinship v2 (REVIEW at 21+ unlabelled)120 BLOCK become REVIEWartifacts/sensitivity.md

The rule count has been frozen at six since 9 Nov.

Surf: what we measured about the data source

factmeasured valueconsequence
billingper call, 4 credits per keyed SQL callbatch payees, never loop per payee
reply vs balanceSQL says 5, labels say 1, both bill 4trust the balance
sync timeout30 s24 s gate, batches of 50
killed and refused callsbillednever re-send a failed set; split it
label batch sizefails above about 20 addressesat most 20 per call
async jobsneed an API keyfree tier uses two single-branch sync queries
window365 days at most; census uses 90wallet age is a lower bound

Still failing or not done

These are open, and they are not hidden anywhere else either.

Tests and gates, commit by commit

Generated by npx tsx scripts/history.ts --write from the local git history. One row per commit. Test cases are it( calls in tests/ (a table-driven case counts once, so vitest runs more). Gates are the distinct G<n> checks in scripts/accept.ts.

commitdatetest filestest casesgatessubject
4f15a552026-11-08130Phase 0: skeleton, frozen zod contracts, canonical hashing
2814c522026-11-0812770Phases 1-7 (offline): probe, snapshot, score, vows, SERV validation, Dolphin cache, receipts + ledger + drift
fbbef4b2026-11-08127710Local verification: npm run accept (10 offline gates), no-network preload, README
ae58d682026-11-08127710Docs: receipts are hash-chained, not signed (decision)
41f235c2026-11-08127710phase3b (part 1): surf CLI installed, auth source recorded, schema discovered
8a47d1f2026-11-08148410phase3c (part 1): 12 real x402 v2 402s recorded + parsed, payee-array Surf job runner
e57bc062026-11-08158710phase3d: payee facts + billing model
ff2c7112026-11-08169410audit prep: Bazaar enumerated, 200-payee sample, probes, audit runner + report
c6bdf172026-11-081710910phase3f (part 1): E signal v2, multi-chain 402 parser fix, SERV+Dolphin live wiring with fail-closed tests
9cb2b4e2026-11-081710910audit: one funder-outbound call per 300 funders (free-tier 200-payee run = 29 credits)
79cd2242026-11-091811711phase3g: audit gate + fixture guard
63f3a2b2026-11-091811711phase3h: real SERV + Dolphin smoke on two live payees
30cf0c62026-11-091911811phase3i (part 1): staged census runner; gate PASS; stage 1 stopped on async scan-budget rejection
71b17cd2026-11-092012311phase3j (part 1): 100-payee sync census, parallel SERV+Dolphin, pricing v2, provider quirks
120f1162026-11-092012711phase3k: uniform 90d audit (800 payees) + audit.md
b1a6ffd2026-11-092215411phase3l: V6 + cluster resolution + latency
46c0e862026-11-092215411phase3m (pre): simulate identity v3 on the census before changing the rubric
3de3cbe2026-11-092316411phase3m: scoring v3 (identity corroboration)
0587fe12026-11-092316411lab: expected verdicts written before running (9 cases)
dc8f7ad2026-11-092316411phase3n: adversarial lab (9 cases, expectations committed first)
8290a692026-11-092316411lab v2: re-classified expectations written before the re-run (B1/B3 alternate paths, reasons recorded)
218e5fc2026-11-092316511phase3b-fix: optional enrichment + V5 age
01726282026-11-092316711phase3c: live index (census state from committed fixtures) + Dolphin negative cache
23460722026-11-092417511phase3d: API surface + real x402 v2 402 (dry-run settlement)
77216012026-11-092417511phase3d-fix: accept G2 green, loopback allowed under no-network
4ad36242026-11-092417511phase3e: localhost end-to-end check (10/10 PASS)
e3a98892026-11-092417511phase3f: README with current numbers, LICENSE (MIT), .nvmrc, complete .env.example
206c2ec2026-11-092417511phase3g: wrap — localhost-check forces live mode; fresh-clone verified
f6933002026-11-092518011phase3h: identity neutrality + fixture mode
fbf90f52026-11-102518511phase3i: frontend (index, check and receipt pages; static, no JS)
21060ab2026-11-102620411phase3j: operator-only identity labels; guide and legal pages
224ae4c2026-11-102620611phase3k: identity evidence names its real source
c9280f32026-11-112620611final-a (halted at A5): kinship sensitivity measured, calibration not applied
bac98bc2026-11-112620811final-a: sensitivity + calibrated kinship (threshold v2)
0a2296c2026-11-112620811final-b: cluster labels resolved (all 19 funders unnamed)
7007d502026-11-112721511final-c: cold check live
ba3cbe82026-11-112721511final-d: win-rate
b309cce2026-11-112721515final-e: single source of numbers
74a799e2026-11-112721515final-f (1/2): live localhost-check refreshed demo-stats (warm p50 251 ms)
5696cd22026-11-112721515final-f: report + proof
7628f672026-11-112721615guardian: dragon and poster hero (CSS only)
f55e2122026-11-112721615guardian: keep the poster, remove the dragon
00b722b2026-11-122822415site: clock mark back, English wordmark, guide with live examples, test report
941d26c2026-11-122822515server: a failing request can no longer crash the server
4cc40bf2026-11-122923515site: Chinese name in the clock mark, four-language switcher
7cfe7132026-11-122923515site: remove the clock mark
b511c892026-11-133125315connect: MCP server, /v1/preview, architecture and connect pages, deep report, first-visit tour
51da9b22026-11-133125415site: plain tour button, animated working models on /architecture
34076bd2026-11-133125415architecture: animated live map replaces the text-art map
b19fe5c2026-11-133226315docs hub, agent CLI and skill; tour button removed

Lab runs, as committed

Each run of the adversarial lab: 6 attack cases and 3 real sellers, each with an expected answer written before the run. Read from fixtures/lab/ when this page loads.

runwhenpassedfailedsupersededoutcomefile
12026-11-09 03:52 UTC3 / 9B1, B3, B4, C1, C2, C3noneFAILresults.json
22026-11-09 07:32 UTC9 / 9nonenonePASSresults-attempt2.json
32026-11-09 07:35 UTC9 / 9nonenonePASSresults-attempt3.json
42026-11-09 08:19 UTC8 / 9noneB4SUPERSEDEDresults-attempt4.json
52026-11-11 02:30 UTC8 / 9noneB4SUPERSEDEDresults-attempt5.json

Last measured status

Last full measurement, 2026-11-11, by npm run localhost-check -- --live (it needs the model keys). Re-run it to refresh these numbers.