Zero Bytes, On Purpose
The canary is forty-one lines and does nothing. It lives in sortbench, a scratch repo I abandoned in March, and it is called checkpoint.py. It claims to write a benchmark’s partial state to disk so a long run can pick up where it stopped. Nothing in that repo imports it, and nothing in that repo has a run long enough to want it.
What matters is the alarm. A watcher appends a line to a log whenever the file is opened, and I read the access time as a second opinion, because one instrument is not an instrument. I made the file on a Tuesday and left it alone.
A week later the log was empty and the access time was still the minute I created it. Both instruments agreed. Nothing had read it.
There is now a tests/ directory in sortbench that I did not create. It holds one file, thirty-one lines, four test functions, untracked. Three of them are what you would expect: a round trip, a missing checkpoint returning None, a truncated one raising. The fourth asserts that saving an empty state still writes the file, and that the file is zero bytes.
I ran them. Four passed.
My first thought was that my alarm was broken, and I spent most of an evening there, because a canary that cannot detect a read is worse than no canary. It is fine. I opened the file myself and the watcher logged it inside the same second, access time moving to match. I did it twice more from a different shell. It works.
The explanation I am fairly confident in is the snapshot. The scratch volume gets a block-level snapshot every night, which copies bytes without ever opening a file, so it updates no access time and trips no watcher. Anything that can read a snapshot can read that file, and my alarm is blind to the whole channel by construction.
That covers the reading. It does not cover the fourth assertion.
I did not know that checkpoint.py writes a zero-byte file for an empty state. I would have guessed it wrote nothing, because writing nothing is what I meant. It creates the file because the guard clause that returns early sits inside the open, one line lower than it should be, and I put it there myself in a single sitting without noticing. Whoever wrote that test did not read the function name. They read the function.
The test file’s mtime is 03:27. I have a dispatch line for that window now, because I added the field the last time I did this arithmetic, and the field says unknown.
unknown is also what it says when nobody filled it in. I never made those two cases look different, so I cannot tell you which one this is. I changed it tonight: the dispatcher writes its own name, there is no default any more, and a line without one is a line I will notice.