How it works
Nothing in wallet-backend is changed or mocked except the network:1
Pinned checkout
wallet-backend is cloned into
.cache/wallet-backend at commit 3e22515 (main, 12 November 2026).2
Adapter
A small Go file,
kit/pilot/wallet-backend/adapter.go, is copied in behind a build tag. It needs the module’s internal packages, which is why it lives inside the checkout.3
Mock RPC
The mock RPC serves the corpus’s canonical ledgers, one server per network.
4
wallet-backend's own pipeline
For each fixture, the adapter builds wallet-backend’s own RPC ledger backend (
ingest.NewLedgerBackend), fetches the fixture’s ledger through getLedgers, and runs indexer.ProcessLedger, the same per-ledger function live ingestion calls. It prints what the indexer produced for the fixture’s transaction. Nothing is written to a database; the output is exactly what ingestion would hand to persistence.5
Score
kit/pilot/score.mjs compares that output with each fixture’s expectations, field by field.6
Lint
istravex-lint runs over the same checkout, and each finding is matched against a reviewed triage in kit/pilot/wallet-backend/triage.json. An untriaged finding fails CI.Results
6 of 6 correct. wallet-backend charges fee-bump fees to the right account at the charged amount, keeps the muxed ID exact (it stores
to_muxed_id as text), records the full P… signer, and indexes the SAC trustline from metadata. On every pattern in the corpus, it already does what the hardening guide asks.
Lint
One finding, triaged latent:internal/utils/ingestion_utils.go
utils.Memo returns memo text as a Go string without UTF-8 validation. Nothing outside tests calls it at this commit and no migration has a memo column, so it isn’t reachable today. It’s worth a guard before memos are stored. Because it isn’t a live bug, no upstream issue was filed.
What the pilot taught us about our own code
The first version of the pilot driver passed wallet-backend’s JSON output throughJSON.parse and reported muxed IDs off by a few hundred. wallet-backend was right. The driver was rounding them, the exact bug the corpus exists to catch. The adapter now emits every 64-bit integer as a string.