Writing
30 posts · oldest Feb 2025
DEX5 posts · 2026
- Six hundred lines or it does not shipA 2,313-line orchestrator with a 1,073-line function is maintainable by a human with an IDE and unmaintainable by an agent. The refactor whose acceptance criterion was an agent behaviour, the CI guard that enforced it — and the fact that the guard is red as I write this.agentsarchitecturerefactoring9 min
- I built a time machine, then deleted half of itFour timeline verbs, parallel variants in git worktrees, a record mode and five branch families. Two cleanup specs removed almost all of it — including, awkwardly, the feature whose existence justified the first round of deletions.gitproductarchitecture10 min
- Three counters, three answersOne Stop click produced a UI, a state file and a git history that disagreed with each other three different ways. None of them was wrong. The reconciliation point that should have caught it was a line in a spec that said "details TBD in implementation".agentsdebuggingarchitecture7 min
- Your test suite bills by the tokenTwenty minutes and real dollars to verify a two-line UI change. A pluggable agent backend, a mock that refuses to improvise, and checkpoint replay took it to sixty seconds and zero — plus an honest account of what the mock does not buy you.agentstestingarchitecture9 min
- Nine stages, nine amnesiacsDex builds a project unattended by making sure no agent ever remembers anything. State travels through the filesystem instead — which works beautifully for artifacts and catastrophically for decisions.agentsaiarchitecture11 min
- Five months, two repos, one lesson: the model was the easy partA retrospective on OpenOperator. What I would keep, what I would redo, and why a commit called "remove hardcoded API keys" landing a year late is the most honest thing in the history.agentsinfraretrospective6 min
- Benchmarking AI agents: node pools, job queues, and cost per stepFive workload classes with five different scaling shapes, a bounded queue that fans tests into Kubernetes Jobs, and the reason your autoscaler makes terrible decisions about 30 GB virtual machines.kubernetesterraformazureobservability7 min
- One proxy pod per VM does not scaleA design that is obviously right at n=1 and obviously wrong at n=20, with no warning in between. The commit that deleted it is the best one in the repository.kubernetestraefikarchitectureinfra6 min
- Streaming helm upgrade to a browserProvisioning a VM takes three minutes. A spinner is not an acceptable answer. An async generator, a path-keyed WebSocket relay, and one design decision I would not repeat.kubernetespythonfastapiarchitecture7 min
- Forty minutes to ninety seconds: VolumeSnapshots as golden images for VMsOne Helm chart, two completely different storage topologies behind a single boolean. Plus the two bugs it cost — a StatefulSet naming convention and a substring match that matched too much.kubernetesazurehelminfra7 min
- Decoding Microsoft Bond: reading an app’s own telemetry through mitmproxyGround truth from an application with no test hooks. mitmproxy local mode against a single process, a hand-written Bond Compact Binary decoder, and the one-line AKS bug that killed a day.mitmproxyreverse-engineeringtestingpython8 min
- Shipping a 6 GB ISO to every pod (and then deleting the storage key)An initContainer that pulls once, one PVC projected into eleven mount points via subPath, and a three-month migration from a storage key to workload identity.kubernetesazuresecurityinfra7 min
- Nested virtualisation on AKS: yes, you can run KVM in a podhostPath /dev/kvm, privileged: true, and the Deployment→StatefulSet migration. Plus the annotation that stops the autoscaler evicting a forty-minute Windows install.kubernetesazureqemuinfra7 min
- MCP for mouse and keyboard: a desktop as a tool serverSix tools, one resource, and a design decision I still think is underrated — the screenshot is not a tool, it is a resource. Plus the reason we composite a cursor into every capture.mcpagentspython7 min
- "It looked like it worked": grading a non-deterministic agentThe least trustworthy signal in the system is the agent reporting success. Here is the evaluator we built instead — and the four-word commit that forced a whole second repository into existence.agentstestingevaluation7 min
- Tasks as config, not codeA JSON scenario format with lifecycle hooks, so an agent test starts from the same desktop every time — and so the person writing the test does not have to be the person who wrote the agent.agentstestingarchitecture7 min
- Four agents in four weeks: from AutoGen to a hand-rolled plan-and-solve loopThe old_agents/ directory still holds all the corpses. What each generation got wrong, and why most of a computer-use agent is not acting — it is checking whether the last action worked.agentsaiarchitecture8 min
- The bootstrap from hell: provisioning a Windows guest you cannot SSH intoNo SSH, no cloud-init, no config management. Just a .bat file, an SMB share the hypervisor provides, and one Task Scheduler flag that decides whether your screenshots are black.windowsdockerinfraautomation9 min
- Reading the screen: OmniParser as a serviceTurning a screenshot into a numbered list of clickable things — YOLOv8 for detection, Florence-2 for captions, OCR for text. And why it had to be a server, not a library.aiagentspython6 min
- We tried every vision model we could get our hands onMagma, Llama 3.2 Vision, Gemma 3, Phi-4, GPT-4o, Claude — including feeding a screen recording instead of stills. What actually moved the needle was not the model.aiagentsmodels5 min
- You cannot debug an agent from logsThe day we put noVNC in front of the guest, our mean time to diagnosis dropped by an order of magnitude. Failures in computer use are visual.agentsdebugginginfra4 min
- QEMU in Docker: a real Windows 11 VM as a containerIt is not Windows in a container. It is QEMU in a container with a Windows ISO and an unattended answer file — and the difference is three lines of compose.yml.dockerqemuwindowsinfra7 min
- The API is the screenWhy we built an agent that uses Microsoft Teams the way a person does — and why the model turned out to be the easy part.agentsaiinfra7 min