Quando «fatto» deve lasciare una ricevuta
bevis è una piccola job board Python che non chiude un lavoro senza comando, exit code e output salvati — ed è insolitamente chiara su ciò che quella prova non può dimostrare.

Su GitHub c’è un progetto Python con due stelle, zero fork e un nome svedese che significa «prova». Fa una cosa sola, con una certa ostinazione: un lavoro sulla sua board non può passare a closed se non è stato eseguito un comando, se non è uscito con codice zero, e se non ha lasciato un output salvato dove il prossimo lettore può vederlo.
Si chiama bevis — pip install bevis, licenza Apache-2.0, su PyPI come 0.2.1. Il tip del repository si dichiara già 0.3.0 e non è ancora su PyPI; per chi installa dal registro conta la versione pubblicata. Il CLI centrale non ha dipendenze di runtime. Non chiama alcun modello linguistico. Gli adapter che ci attacchi possono farlo; il pacchetto no, e un test attraversa gli import per tenerlo così.
Il README è insolitamente diretto sul motivo: sentirsi dire che un compito era finito quando non era stato toccato, era stato verificato sulla cosa sbagliata, o non era stato verificato affatto — solo affermato. La risposta non è un altro framework per agenti. È un cancello.
I job sono righe in un file SQLite locale. Gli stati sono pochi: open, claimed, running, blocked, failed, closed, verified. Non puoi impostare closed o verified con un generico cambio di stato: sono protetti. La chiusura passa da una sola funzione, close_job(). Il docstring del modulo afferma che non esiste un flag «force» che spegne la regola, e che trovarne uno sarebbe il tipo di bug da CVE. Abbiamo controllato il percorso di enforcement nel codice; non abbiamo cercato di forzarne uno.
Per chiudere, bevis vuole tre cose sul job: il comando, exit code zero e un output non vuoto. La forma forte è bevis close <id> --run "…", in cui bevis esegue il comando e registra ciò che ha visto. C’è anche una forma trascritta per evidenze nate altrove — più debole di proposito, perché lo strumento si fida di ciò che digiti.
Di default c’è anche un controllo di vacuità a basso costo: se l’output dice, con una lista breve di frasi, che non è stato misurato nulla — «Ran 0 tests», «collected 0 items» e simili — la chiusura viene rifiutata, a meno che lo stesso log non riporti altrove un conteggio diverso da zero. È un lessico di frasi, non comprensione. Il README lo dice.
Chiudere e verificare sono atti distinti. Dopo la chiusura, un’altra stringa di attore può segnare il job come verified. Chi ha chiuso non può verificare la propria chiusura. L’autore indica anche il punto debole: gli attori sono ciò che dicono $BEVIS_ACTOR o --actor. È una disciplina che lo strumento sostiene, non un sistema di identità.
Se usi il dispatcher opzionale, un adapter — un comando qualsiasi — può fare il lavoro. L’exit code dell’adapter non chiude il job. Lo fanno i check. Un job senza check finisce blocked con una ragione esplicita, invece di contare in silenzio come concluso. Quella separazione — chi lavora contro chi decide — è più interessante della superficie del CLI.
I codici di uscita non rispondono a una domanda su se stessi: questo comando avrebbe detto qualcosa di diverso se il lavoro non fosse stato fatto? Uno scanner che stampa FAIL e torna comunque 0, o un runner che non ha trovato test, resta verde in entrambi i casi.
--negative-control è il modo di chiederlo. Accanto al comando di verifica indichi un caso che deve fallire. bevis esegue entrambi, nello stesso ambiente, senza etichettare quale delle due run sia il controllo. Se anche il controllo esce 0, la chiusura viene rifiutata: il check è una costante. Anche i codici che significano che il controllo non è partito vengono rifiutati. Comando, exit e output del controllo restano accanto all’evidenza, non confusi con essa.
È opt-in. L’autore non inventa un controllo al posto tuo: un controllo scelto dallo strumento sarebbe esattamente il check finto che lo strumento vuole impedire. In una prova locale sull’albero non pubblicato 0.3.0 abbiamo visto reggere la storia del leakcheck del README: scanner rotto più segreto piantato → rifiuto; scanner corretto → chiusura con il fallimento del controllo a verbale.
La rilevanza non è risolta. La sezione Limitations dice che bevis close 3 --run "echo done" chiude comunque il job 3. Abbiamo ripetuto quella forma in locale su HEAD: ha chiuso. bevis rende una bugia sottile piccola, specifica e attaccata al job. Non la rende impossibile.
Fuori ambito, nella lista dell’autore: non è un workflow engine, non è un framework di agenti, non è distribuito, non è un artefatto di compliance. Su 0.2.1 pubblicato il log eventi non era dichiarato tamper-evident; su git HEAD 0.3.0 c’è una catena di hash che resta non tamper-proof. Se ti interessa quel dettaglio, fissa la versione.
I criteri di accettazione sono obbligatori in creazione, ma sono prosa, non eseguiti. I check valgono quanto i comandi che ci attacchi. Il negative control non si applica ai check, solo a close --run.
L’idea sta in testa, e la documentazione dedica energia insolita a ciò che lo strumento non vede. Poche decine di download a settimana su PyPI, diciassette commit, nato in due giorni a fine agosto 2026, poi silenzio. Alpha. Oscuro per davvero.
Se passi lavoro a script o agenti su più di una seduta, e «fatto» deve significare la stessa cosa dopo, un cancello che conserva la ricevuta è uno strumento piccolo e sensato. Se sei una persona sola davanti al terminale, non ti serve — lo dice anche il README.
Qui «fatto» non diventa sacro. Diventa scomodo da affermare senza lasciare un comando dietro. Basta per essere interessante.
bevis
Una job board Python solo stdlib in cui closed richiede l’esito salvato di un comando. Controllato su repository, PyPI 0.2.1 e una prova locale del tip non pubblicato 0.3.0 il 29 settembre 2026.
Visita il repository Vedi la release attuale su PyPI (0.2.1)Licenza: Apache-2.0