Notes on building payment systems — mostly about a decision and what it cost. Newest first, grouped by year.
Right column: how long a note takes to read, and how long it runs next to the longest one here.
Mostly System Design and Fintech.
Aug 24
Self-graded agents are unfalsifiable. The fix isn't a better rubric — it's a pre-registered prediction and an auditor that can't edit what it audits.
Multi-Agent · System Design · Claude Code
11 min
Aug 24
A Sharpe from a parameter sweep is an order statistic, not an estimate. How deflated Sharpe and Wilson intervals price in the search you ran.
Statistics · Backtesting · Python
12 min
Aug 24
My stock-research dashboard v1 optimised for looking sophisticated. Rebuilding it around evidence and provenance meant fixing five real UX failures.
Design System · Accessibility · Frontend
10 min
Aug 24
A momentum factor with a 1.32 Sharpe on a frozen holdout that still lost to the index — and why the negative result is the credible part.
Backtesting · Statistics · Python
9 min
Aug 24
Twelve agent skills, one rule none may override. Why an acute bad-sleep night is a hard stop while a 7-day trend defers to a live HRV reading.
System Design · AI Agents · Guardrails
9 min
Aug 24
Two skills were deleted from my portfolio rather than re-tiered. The test they failed: could a reader, in principle, prove the claim false?
Career · Engineering Culture · AI
7 min
Aug 24
Four analyst desks on separate MCP servers, an adversarial bull/bear debate, and a synthesizer that adjudicates instead of averaging.
Multi-Agent · LLM · MCP
9 min
Aug 21
Apollo's normalized cache updates a record everywhere it's referenced — except in the one place a create or delete actually breaks: the list it should now belong to, or no longer belong to.
GraphQL · Apollo Client · React
4 min
Aug 21
A 'new login kicks out old sessions' feature was wired to a cache-mapping rebuild instead of an actual authentication event. An unrelated cache eviction force-logged-out a legitimate, unrelated session.
System Design · Security · Fintech
2 min
Aug 21
Shared i18n label constants were built once at module load, before the translation library had finished initializing — permanently baking in blank labels that never recomputed once the library actually became ready.
JavaScript · TypeScript · Correctness
2 min
Aug 21
A reward system marked an entity as 'rewarded' before attempting the reward. When the attempt legitimately declined, the flag stuck — permanently locking out every future legitimate attempt, with no error anywhere.
System Design · Correctness · Fintech
2 min
Aug 21
A 'not already claimed' safety check survived a service migration with its code intact. What changed underneath it was its input — rewired to a list defined to only ever contain unclaimed records, making the check tautologically always-true.
System Design · Testing · Fintech
2 min
Aug 21
Peak-hour failures on a legacy Java/JSP payment system looked like the connection pool running dry. JMX said otherwise: the pool had capacity, and the connections in it were the problem.
Java · HikariCP · Databases
3 min
Aug 21
A duplicate-transfer guard was redesigned to key off immutable inputs, evaluated before any resolution of current state — because checking a retry against current balance and eligibility could wrongly reject a transfer that had already succeeded.
System Design · Concurrency · Fintech
2 min
Aug 21
Two branches assigned different meanings to the same enum keys. Resolving the conflict by keeping one side looked safe — it compiled — and quietly broke a boolean check somewhere else in the codebase that nobody touched.
System Design · Code Review · Testing
3 min
Aug 21
A tenant configuration lookup treated 'never configured' and 'explicitly disabled' as the same empty result, both falling through to a shared default. An operator's disable action had zero real-world effect.
System Design · Correctness · Fintech
3 min
Aug 21
A read endpoint was authorized against the permission scope of the UI module it was originally built for. A later, unrelated workflow started calling the same endpoint — and its users got silently locked out of data they had every right to see.
System Design · Security · Fintech
2 min
Aug 21
A status table stored many independent flags on one wide row. A handler that read the whole row, changed one field, and wrote the whole row back silently reverted a concurrent, unrelated column update — permanently stranding an account mid-process.
System Design · Concurrency · Databases
3 min
Aug 21
Reentrancy guards on an Ethereum dApp are cheap to add and easy to justify. Getting from 65K to 38K gas meant treating every guard, storage write, and on-chain string as something with a price, not a default.
Solidity · Ethereum · Smart Contracts
4 min
Aug 21
A payments platform runs 18 domain services that all depend on one library holding the schema, the models, and every migration. It is the deliberate inverse of database-per-service — and the tradeoff is sharper and stranger than the orthodoxy suggests.
System Design · Architecture · Databases
6 min
Aug 21
The same 'exceeds limit' check existed independently in three places. One treated a limit of exactly zero as 'no limit.' Another treated it as a real, blocking limit. Nobody noticed until a bug report surfaced the disagreement.
System Design · Correctness · Fintech
2 min
Aug 21
A 788-file route migration on a React Native app with no test suite. tsc, the bundler export, and a route-inventory diff each caught a different class of break — and each was blind to what the other two caught.
React Native · Migration · System Design
3 min
Aug 17
A double-submitted batch payment must not pay twice. There is no idempotency key anywhere in the flow — the guard is a compare-and-set on the status column, and the interesting part is what has to happen before it.
Kotlin · Concurrency · Fintech
6 min
Aug 17
One quote is locked for a whole batch, then split across rows. Round each row independently and the executed trade no longer matches the quote you locked. Largest-remainder allocation, and the subtler bug of prorating on the wrong basis.
Kotlin · Fintech · Correctness
7 min
Aug 17
A masking rule in a payments UI had to decide what to do when the field it depends on is missing. The original design said show the name. Reversing that to hide it is the whole post.
Privacy · Security · TypeScript
8 min
Aug 17
A compliance case moves between two roles that must not be the same person. Modelling that turned up three things worth writing down: a status that can't say whose turn it is, a state you have to reconstruct from the audit log, and why role separation and actor separation are different controls.
React · State Machines · Compliance
8 min
Aug 16
How outcome memory was added to a multi-agent stock-analysis pipeline: an exit-date leakage guard that keeps backtests honest, and why calibration is reported but never applied.
Python · LLM · Backtesting
7 min