Blog

Notes on the harness, the models underneath it, and what changes when a new one lands.

Memory sync without last write wins

Two machines, one set of notes, one of them edited while the other was asleep. Every sync system answers this, and most answer it with a timestamp comparison that silently discards one side. That is fine for a draft you can retype. It is not fine for the file an agent reads before every turn, because what it discards is the line you wrote to stop something happening again.

Model ids do not belong in TypeScript

A model id is the fastest-moving fact in this entire system. Vendors rename them, retire them, ship a dated variant, quietly change what the undated alias points at, and gate half of them behind which account is asking. Compile that into a package and you have guaranteed the package is wrong within weeks — not broken in an obvious way, which would at least be a bug report, but wrong in the specific way where a picker offers someone a model their key cannot call.

A deny rule is the only boundary you get

Everything else an agent harness calls a permission is a judgement about cost. That is worth saying plainly, because the interface does not say it: an approval prompt, a mode named Auto, and a writable-roots setting all look like the same kind of thing, and only one of them is a line the system will hold no matter what.

Switching models mid-session costs nothing

And that is a design decision, not a feature. Most agent tooling is written against one vendor and adapted to others afterwards. The order sounds like an implementation detail. It is the whole thing.