Building tools, and writing about them honestly
I build things and write about them — partly so the work is understandable to someone who wasn't there, partly to become a better writer. Current projects:
- waitbus — a workstation-local event bus for AI coding agents
- stillpoint — a sound test for when a cascade of delegating agents has actually gone quiet
- driftbound — machine-checked floating-point error bounds for the streaming sliding-window inner product deployed as the matrix profile
- tsbootstrap — a time series bootstrap library for Python that resamples without destroying the dependence
- fired-not-fed — AI-for-security benchmarks scored on compiled code, and why their numbers cannot be recomputed
- evaluations — what agent evaluations actually measure, and what a passing test suite is not evidence of
I consult on these same problems — agent-systems reliability, eval and measurement validity, and uncertainty and numerical verification — and an engagement ends with a measured answer you can hand to whoever needs convincing: how that works.
Projects
waitbus A workstation-local event bus: your AI coding agents wait on events instead of polling — and hear each other fail. 4 articles stillpoint When agents delegate work down a chain, nothing can tell when the whole cascade is actually done — stillpoint detects that quiet point, soundly. 2 articles driftbound Forward-error bounds for the matrix profile's streaming inner product — machine-checked in Lean and Coq, validated to a real earthquake record. 6 articles tsbootstrap A time series bootstrap library for Python that resamples while preserving the dependence a plain bootstrap destroys, with conformal uncertainty. 4 articles fired-not-fed AI-for-security benchmarks that score models on compiled code can report a number nobody can recompute. We took one apart: how well obfuscation resists AI decompilers. 3 articles evaluations An agent reads a sentence about your tool and decides, on that sentence, to call it. Your tests read the function. What a passing suite is evidence of, and what it is not. 1 article
fired-not-fed
Read the whole series as one page- 01
Nobody published the denominator
AI-for-security benchmarks that score models on compiled code can report a number nobody can recompute. Of 37 papers reporting an obfuscation-strength number, exactly 1 conditions it on whether the transform actually fired — and that one is a disassembly paper, which scores nothing on re-executability. Our own do-nothing control passes the metric. - 02
The compiler did it, and my obfuscation took the credit
Two arms of the same 149 functions, neither arm obfuscated — stock LLM4Decompile v1.5, gcc-lenient scorer, native 4096-token window: GCC-built binaries recover at 27.5%, clang-built at 15.4%, paired McNemar p = 0.0029. The confound is the toolchain, and the law generalizes well past binary analysis. The three-term decomposition built to separate those effects then fails to add up, and the ~5.6-point residual is printed open. - 03
Bigger didn't break it. Knowing did.
Obfuscation dropped this decompiler's recovery from 18.8% of clean functions (28/149) to 0.0-0.9% of the functions each transform fired on (0/97, 0/63, 1/106) — gcc-lenient scorer, native 4096-token window, paired and placebo-controlled. Tripling its parameters bought no monotonic gain in the largest obfuscated cell: three points at n = 151, intervals overlapping. Fine-tuning it on the same transform family bought 12-16% back, and the headline moved from hardening to brittleness — against one modest 6.7B attacker, where every number is a floor.
- 01
Your bootstrap is lying to you
The ordinary bootstrap assumes your observations are independent. Feed it a time series and it quietly shuffles away the autocorrelation, then hands you a confidence interval too narrow to be true: a nominal 90% interval that covers the truth about half the time. Here is the failure on real numbers, and the block bootstrap that keeps the dependence and tells you most of the truth. - 02
When your errors aren’t equal
The residual bootstrap assumes your model’s errors all come from the same distribution. Feed it a series whose noise grows over time and it quietly shuffles the loud errors in among the quiet ones, averaging the variance away, and hands back a standard error at three-quarters of the truth. Here is the failure on real numbers, and the wild bootstrap: a fix so simple it sounds like a joke. Keep every residual exactly where it is. Just flip its sign at random. - 03
Count the bytes, not the FLOPs
Why tsbootstrap stopped materializing arrays and carrying state. A routine bootstrap job can materialize a 160 MB tensor whose only purpose is to be averaged and thrown away. How tsbootstrap's hot path stopped building it, including the one path where the incumbent still wins. - 04
Ten thousand series, one pass
Ten thousand series, a thousand replicates each, and the naive tensor wants 16 GB before the first statistic lands. This is the real race: three implementations, two axes, and each speedup credited to the opponent it actually outran.
- 01
Your AI coding agents can't hear each other — not even across vendors
Your Claude Code, your Cursor, your tests, your CI — all on one box, none able to hear the others finish or fail. Here's the problem, and the proof: five real LLM agents on one bus, one fails, all wake. - 02
How waitbus works: from event source to a waiting agent, over MCP
The architecture end to end — how an event gets from a source to a waiting agent in single-digit milliseconds, how an agent actually talks to the bus over MCP, and the decisions behind the build with what each one cost. - 03
The numbers and the trust trail: benchmarking waitbus honestly
Two kinds of trust in one place — the benchmark methodology that makes the speed numbers survive a skeptic (Coordinated Omission, a bimodal p99, costs published as losses), and the supply-chain trail that lets you trust the artifact you install (SLSA provenance, sigstore, reproducible builds, and an honest list of the gaps). - 04
The first file an agent reads
Coding agents read your library before they use it, and they start with the code — `__init__.py`, the type hints, the tool schemas — not your docs site. Here is how I made waitbus speak to that reader, and the one piece of documentation I deliberately did not ship.
driftbound
Read the whole series as one page- 01
Thirty-one papers, zero error analyses
A sliding-window inner product updated one product at a time is the streaming similarity engine under motif and anomaly mining — its rounding error grows linearly in stream length, and across thirty-one matrix-profile papers nobody had ever done the forward-error math, or turned the fix into a config knob. - 02
The accumulator that never moved
An adversarial input where round-to-nearest throws away every increment in the same direction while the true sum climbs — and the coin flip that breaks the adversary's one weapon, measured across 20,000 seeds. - 03
The error analysis everyone cites is for a kernel nobody runs
SCAMP and STUMPY accumulate a mean-centred covariance, not the textbook inner product — and the centred case is structurally different floating-point mathematics, not a special case at mu = 0. - 04
Green is not evidence
An experiment can validate the wrong quantity against the wrong envelope and pass, a self-test canary can fail identically whether the gate works or not, and an audit command can print nothing and exit 0 — three gate designs that read green while checking nothing. - 05
Three axioms and one disclosed seam
Four verification tools, one certificate: every machine-checked theorem mechanically reduced to three classical axioms with zero unfinished proofs — and the one place two provers cannot talk to each other, named right in the theorem statements. - 06
One earthquake pinned my error bound forever
A seismic stream, a global magnitude bound wrecked by a single mainshock, a windowed bound that heals — and a scoreboard where the headline empirical legs of two papers report zero violations.
stillpoint
Read the whole series as one page- 01
When is the swarm actually done?
Three services across a network, one dropped task, and a question nobody on the wire can answer: did the work actually get done? A copy-paste demo that exits 0 and prints SUCCESS while the real job dies unseen. - 02
Task was destroyed but it is pending
A teardown deadlock I diagnosed in Google's A2A reference SDK — Issue #1101, PR #1105 (417 added lines, 312 of them tests, CI green, merged upstream) — turned out to be one symptom of a primitive the whole agent ecosystem is missing: a sound signal that an async mesh has actually settled.