lf.An independent notebookItaliano
From the notebook / 005liminalfinds.com

When “Done” Has to Leave a Receipt

bevis is a tiny Python job board that refuses to close work without a stored command, exit code and output — while being unusually clear about what that proof cannot prove.

A sketched rubber stamp presses a blank card while a perforated receipt ribbon curls away.

There is a small Python project on GitHub with two stars, no forks, and a name that is Swedish for “proof.” It does one stubborn thing: a job on its board cannot move to closed unless a command actually ran, exited zero, and left output that is stored where the next person can read it.

That is bevis — pip install bevis, Apache-2.0, published as 0.2.1 on PyPI. The git tip already labels itself 0.3.0 and is not on PyPI yet; the published package is what most people will get. The core CLI has zero runtime dependencies. It does not call a language model. Adapters you plug in might; the package itself does not, and a test walks the import graph to keep it that way.

The author’s README is unusually plain about motive: being told a task was finished when it had not been touched, had been tested against the wrong thing, or had not been tested at all — just asserted. The response is not another agent framework. It is a gate.

Jobs are rows in a local SQLite file. Statuses are few: open, claimed, running, blocked, failed, closed, verified. You cannot casually set closed or verified through a generic status command. Those two are gated. Closing goes through one function, close_job(). The module docstring claims there is no force flag that turns the rule off, and that finding one would be the kind of bug worth a CVE. We verified the enforcement path in source; we did not try to invent a bypass.

To close, bevis wants three things on the job: the command, exit code zero, and non-empty output. The strong form is bevis close <id> --run "…", where bevis runs the command and records what it saw. There is also a transcribed form for evidence that happened elsewhere — weaker on purpose, because the tool is trusting your typing.

By default it also runs a cheap vacuity check: if the output says, in a short list of phrases, that nothing was measured — “Ran 0 tests”, “collected 0 items”, and similar — the close is refused, unless the same log also reports a non-zero count somewhere else. That is a phrase list, not understanding. The README is clear about that.

Closing and verifying are different acts. After close, another actor string can mark the job verified. The closer cannot verify their own close. The author also states the soft spot: actors are whatever $BEVIS_ACTOR or --actor says. It is a discipline the tool supports, not an identity system.

If you use the optional dispatcher, an adapter — any command — can do the work. The adapter’s exit code does not close the job. Checks do. A job with no checks gets blocked with a reason that says so, rather than quietly counting as done. That separation — worker versus gate — is more interesting than the CLI surface.

Exit codes cannot answer a question about themselves: would this command have said anything different if the work had not been done? A scanner that prints FAIL and still returns 0, or a runner that found zero tests, looks green either way.

--negative-control is how you ask. Beside the verification command, you point bevis at a case that must fail. bevis runs both, in the same environment, without labeling which run is which. If the control also exits 0, the close is refused: the check is a constant. Shell codes that mean the control never started are refused too. The control’s command, exit and output are stored beside the evidence, not folded into it.

It is opt-in. The author will not invent a control for you; a control the tool chose would be the fake check the tool exists to refuse. In a local run against the unpublished 0.3.0 tree we saw the README’s leakcheck story hold: a broken scanner plus a planted secret was refused; a fixed scanner closed with the control’s failure on the record.

Relevance is not solved. The limitations section says that bevis close 3 --run "echo done" still closes job 3. We ran that shape locally on HEAD: it closed. bevis makes a thin lie small, specific and attached to the job. It does not make lying impossible.

Also out of scope, in the author’s own list: not a workflow engine, not an agent framework, not distributed, not a compliance artefact. On published 0.2.1 the event log was explicitly not tamper-evident; git HEAD 0.3.0 adds a hash chain that is still not tamper-proof. Pin the version if you care about that detail.

Acceptance criteria are required when you create a job, but they are prose, not executed. Checks are only as good as the commands you attach. Negative control does not apply to checks, only to close --run.

The idea is small enough to hold in your head, and the documentation spends unusual energy on what the tool cannot see. A few dozen downloads a week on PyPI, seventeen commits, born in a two-day burst in late August 2026, then quiet. Alpha. Obscure for real.

If you hand work to scripts or agents across more than one sitting, and “done” has to mean the same thing later, a gate that stores the receipt is a sensible little instrument. If you are one person watching the terminal, you do not need it — the README says that too.

“Done” here is not made sacred. It is made awkward to assert without leaving a command behind. That is enough to be interesting.

02 / The Find

bevis

A stdlib-only Python job board where closed requires a stored command outcome. Checked against the repository, PyPI 0.2.1 and a local run of unpublished git HEAD 0.3.0 on 29 September 2026.

Visit the repository See the current PyPI release (0.2.1)

License: Apache-2.0