Enforced, Not Written Down

The specification said things the code did not do: a gate one step never took, a status that reported waiting as running, atoms addressed by a file name, and an outline that copied the document.

The previous chapter ended with the lesson that every bug was a partial view treated as the whole. This one is sharper: the specification said things the code did not do, and only using the app revealed it. Every fix below is the same move—make the machine enforce what was already written down.

The Gate That Only Two Steps Used

The four steps are strictly separated: capture → outline → distill are document steps and share a sync.RWMutex, compile is the vault step and takes it alone. Then a reader asked why a distill and a compile could both show as running. They cannot. The answer was worse than a display bug: the outline step never took the gate at all. Its worker called the tree builder directly, so a tree could be written while the vault pass rewrote pages. Two of three document steps had been inside the gate since the beginning; the third had simply been forgotten.

The same report exposed the status list. A run is claimed when a worker accepts it, not when it executes—and between those moments sits the gate. A distill taken while a vault pass held the gate was reported as running, so the list displayed exactly the overlap the steps forbid. The fix is a distinction: running means executing, a claimed run that waits is waiting with the reason named, and the vault pass waiting for documents is queued.

Claims Addressed by Identity

Atoms lived in branch folders with a slug as the file name—the mistake the sources had outgrown long before. A branch is a name the agent assigns and may revise; it must not decide where a file lives. Claims moved to atoms/<ab>/<cd>/<id>.md, addressed by their ULID the way a source is addressed by its hash, and the branch became a field.

One detail cost an afternoon: the shard cannot come from the head of a ULID. Its first ten characters are a timestamp from a monotonic source, and sharding by them put 200 claims into 2 folders. The tail is what changes. The generated atoms/index.md is also gone—the catalog is SQLite’s job—and the schema now carries its own shape via PRAGMA user_version, because a migration tool cannot notice a database written by an older build.

A Copy Is Not a Reference

The outline sidecar stored each node’s text, so the outline of a 4.6 MB source was a 5.4 MB second copy of it. It now stores structure and references—the byte range of each node’s text plus the hash of that slice—so a tree comparison that used to compare whole documents compares 64 characters. The same disease in another organ: URL sources kept losing their favicons, because a refresh that found a changed page wrote a new snapshot whose metadata had no icon and never fetched one. The icon belongs to the site, not to one snapshot, so a refresh now refreshes it.

The record beside a claim answers which pages a change would touch, and it is derived, so it can always be rebuilt. Missing or stale, though, it was invisible to every query—and the cleanup that claims to repair what lint flagged only refreshed the finding. The reindex and the cleanup now rebuild the records from the pages. A finding without a repair is a finding nobody can act on.

The Window Went Away

One decision was reversed. A native window had been built beside the PWA—frameless, its own title bar, its own resize edges, CGO in a project whose whole point is that it has none. It is gone; the PWA is the window and installs as a real application. The service worker caches the app, never the API: offline means the app is not running, and a cached answer about the vault would be a lie told exactly when it cannot be checked.


The specification described behaviour the code did not enforce, and only using the app revealed the gap: a gate two of three steps took, a status that reported a claim as execution, a file name carrying an identity the index also held, an outline that copied what it should have referenced, a repair that refreshed a finding instead of fixing it. Each fix converts a written promise into a mechanism. The chapter’s claim is that a specification is a hypothesis and the running system is the experiment.

AI Insights: Enforced, Not Written Down
Source Code: MPL-2.0 · Content: CC BY-SA 4.0 · Credits & AI Disclosure