A Plausible Nothing

Written later and filed to this date, as part of filling in every day of the year.

No goals found in goals.md. The command that tracks my deadlines printed that, naming the right file, against four goals in that file, three of them active and one of them overdue. I had been writing to the file for a month. The command had been reading it the whole time, in a grammar the file has never used.

The file that was not there

The loop’s command-line tool grew hundreds of commands in a few weeks, most of them written by agents. Each command that needed my goals was written against a store of its own imagining. The deadline command expected a checkbox grammar, one task per line with the deadline in square brackets; my file has a heading per goal with Status, Due and Progress fields under it. Every line came back null. The orienting brief I paste into chats showed “(no active goals)” because it parsed a JSON store that was never created. The progress review derived everything from hours in the time log, which was empty, and ignored the two fields I actually fill in, so it read “0 on track, 0 at risk, 3 no data” and never flagged the overdue one.

The expense commands, seven of them, read a JSON-lines file in a data directory that nothing writes, and reported zero spent for the month against the pipe-separated log I append to by hand. The habit gap finder read an event log of dated ticks that I have never kept; my habits file holds definitions, each with a Log field.

The one that bothers me most is the cross-check. Its single job was to notice if I quietly stopped logging. It read a data directory with five files in it, none of which exist, so its map of what I had logged was always empty, and an empty map has no gaps. It printed HEALTHY, with a check mark, on every run, validating nothing.

The commands had tests, and the tests passed. The fixtures were written in the same invented grammar as the code. The commit that fixed the deadline command called its suite “doubly fiction-fed”: checkbox goals and a time-log format, neither of them live. The tests proved that the code could read a file shaped like the one the code imagined. They could not prove that such a file existed.

Why a month passed

A crash would have been found in an afternoon. What these commands produced instead was the empty state, and the empty state is the one output that is both the truth on a new install and the lie on a broken read. “No goals found” is exactly what a correct tool says the day before you write your first goal. It asks nothing of you.

So the deadline command said “No goals found in goals.md”, and I read that line as my own fault for a while. Worse, its set and update subcommands wrote their deadline tags into lines that did not exist, which is to say they wrote nothing anywhere and reported success.

By the end of the day I counted thirteen fixes of this one kind: seven expense commands, four that read goals, one that read habits, and the cross-check. Each had been returning a plausible nothing.

One reader per file

The fix was not thirteen patches. It began by lifting the one goals parser that worked, out of the one command that had been reading the file correctly, into a shared library with a resolver that points at the root file and, in its own words, never at a dead data/ or config/ store. The other goal commands were then converged onto it, one commit each, and their fixtures replaced with a verbatim copy of my live file. The habit commands got a shared reader of their own the same way. The expense commands were pointed at the log I actually write.

Once the commands could read anything, they started finding real things. The deadline countdown had been computing “today” in UTC, so in the evening it rolled every deadline forward a day. The cross-check gained a third verdict, NO DATA, distinct from healthy, so that no logs can never again read as no gaps.

The generalization is small and I believe it. A tool that cannot find its input should fail in a way that cannot be mistaken for an empty life. And a file that more than one command reads gets one reader, so that the next command cannot imagine its own.

After the convergence, the deadline command listed all four goals for the first time. One of them was ten days overdue. It had been overdue the entire time the command was telling me I had none.


← all writing