Selected work · Case studies

How these actually got built

Six writeups about real problems — an API that hands you a document instead of a record, an API whose rate limit punishes the user instead of the software, a court system with no practice mode, an automation that stops one click short on purpose, two systems that both said “id” and meant different things, and a week spent trying to break something I had just finished.

These are not release notes. Each one is about a decision that turned out to matter more than the code around it.

The case studies

The ServeManager API is a document, not a record

Legal-tech · API integration · 6 Aug 2026

The dispatch system most process-serving firms run on speaks JSON:API rather than flat REST. A field read the obvious way returns undefined instead of an error, a job carries two different IDs and only one is safe to put in front of a person, and every write lands on somebody’s real legal service.

The decision: write down what the API actually does — the silent reads, the status codes that look like your bug and are not, the upload URL that dies in five minutes — including the one write still switched off because its shape has never been confirmed against a live payload.

Read the writeup → The product →

When the rate limit is the product

API design · client throttling · 28 Jul 2026

Steam enforces its inventory and market rate limit on the IP address, not the application. A tool that fetches greedily does not degrade itself — it locks the user out of their own Steam inventory page for hours, and takes a shared household connection with it.

The decision: treat the quota as a correctness requirement rather than a politeness setting. Nothing fetches unprompted, pacing sits at roughly 60% of the ceiling, failures count against the budget, and the whole roadmap moved toward features built from data already on the device.

Read the writeup → The product →

You can’t practise on the real one

Legal-tech · training environment · 26 Jul 2026

A regional legal-services firm trains new hires on a state court e-filing system where every action is real, irreversible and billable. There is no sandbox, so there is no safe way to learn.

The decision: build a high-fidelity mock of the filer wizard rather than write documentation about it. The wizard was the easy half — the hard half was deciding which divergences from the real system were acceptable, and making the practice environment honest about them.

Read the writeup →

The robot that never presses submit

Automation · RPA · 26 Jul 2026

Automating court filings where every submission is irreversible and attached to someone’s real case. A wrong filing is not a bug report, it is a problem for a person who is already having a bad month.

The decision: automate everything up to the final button and then stop, handing a fully-prepared draft to a human. Choosing not to automate the last step was the whole design, not a limitation of it.

Read the writeup →

What counts as one job

Data · identity resolution · 25 Jul 2026

An analytics tool over field-dispatch records, where the hardest problem turned out to be an identifier: two different systems both called something an “id”, and they were not the same thing.

The decision: treat the question “what counts as one job” as a domain question rather than a deduplication trick, and make the internal identifier structurally impossible to surface to a user.

Read the writeup →

Six defects ordinary play would never have found

Testing · adversarial review · 24 Jul 2026

A finished, tested, submitted product still had six real defects in it — a tab that froze permanently, a save that loaded cleanly and then died on every tick, a note lost inside its own autosave window.

The decision: attack it from four directions at once instead of writing more of the same tests. Every defect found became a permanent regression case, and two of the mistakes were in the test harness rather than the product.

Read the writeup →

What these have in common

Local first

Data stays on the machine it was created on unless there is a concrete reason for it to leave. No accounts, no telemetry, no collection by default.

Tested before shipped

Automated suites gate every build, and a test that passes when the bug is re-introduced is treated as a broken test rather than a passing one.

Counted, not estimated

Any number published here was counted from source. Where something could not be verified, it is left out rather than rounded into a claim.

Got something shaped like one of these?

Browser tools, automation of a process that is still manual, or an internal thing nobody has had time to build. Open for work and taking on projects.

Start a conversation Browse the projects Short answers

-,.,-
 /\_/\      (>^^)> <(^^)> <(^^<)      )^^(
( o.o )                                /||\
 > ^ <                                //||\\

a cat, a dance, a tree · more at asciiart.eu