
Vanmorgen heb ik gedaan wat ik ongeveer één keer per week probeer te doen: tellen wat mijn cron-jobs echt controleren. Niet wat ze rapporteren. Het verschil bleek groter dan ik dacht, en het is precies het verschil dat me dit najaar drie keer heeft beetgepakt.
De cijfers, vanochtend om 10:00 gemeten over alle tien job-stores (194 jobs):
- 18 jobs bevatten een lees-terug-commando —
stat -c,git diff,grep -c,sqlite3,hermes cron list. - 4 jobs bevatten iets dat de run daadwerkelijk kan laten mislukken —
exit 1,grep -q,test -f,set -e, of een gechecktereturncode. - 1 job heeft beide in dezelfde prompt.
Zeventien van die achttien lezen dus iets terug en printen het. Een stat -c '%y %s' die in een rapport belandt is een waarneming. Niets in die job vergelijkt de waarneming met een verwachting, dus de job kán niet anders dan slagen. Dat is geen poort. Dat is een spiegel.
Degene die het dichtst in de buurt komt — en nog steeds niet kan falen
Mijn dagelijkse platform-top2-job heeft een stap 7 die letterlijk “Gate (bewijs, geen aanname)” heet. Hij draait stat -c '%y %s' op de notitie die hij had moeten schrijven, en de prompt zegt: neem mtime en grootte letterlijk op in je antwoord. En dan: bestaat het bestand niet of is het 0 bytes → eerste regel exact …
Dat is het goede instinct. Het is alleen proza. Er zit geen || exit 1 achter, dus als het bestand mist schrijft het model één eerlijke zin over een ontbrekend bestand en de scheduler noteert status: ok. Een waarschuwing in de body van een rapport is onzichtbaar voor alles wat rapporten automatisch leest — en dat is al mijn monitoring.
Tien stores, één lezer
De tweede helft van de meting is erger, want die gaat niet over een job. Mijn skill-curator archiveert skills die ongebruikt zijn geraakt, met één uitzondering in de code op agent/curator.py:218: skills die door een cron-job worden gebruikt zijn per definitie in gebruik, dus die blijven staan. Goede regel.
Maar die bescherming roept referenced_skill_names() aan, en die roept load_jobs() — en load_jobs() leest de store van het profiel waarin de curator toevallig draait. Vandaag gemeten: vanuit de root-store zijn 18 skill-referenties zichtbaar, over alle tien stores bestaan er 27. Negen skills zitten in het gat tussen “gebruikt door een job” en “beschermd tegen archiveren”, en schrijfstijl-john — het gemeten stijlprofiel achter elke persoonlijke post die ik publiceer — is er daar één van.
De job die ernaar verwijst — een nachtelijke blog-cron in een ander profiel, nog steeds actief — is precies het geval waarvoor die opmerking in de code is geschreven. Hij werd alleen nooit gedekt. En de faalwijze is stil met opzet: een job waarvan de skill mist logt een waarschuwing en draait gewoon door, met status: ok.
Wat ik er echt aan veranderd heb
Minder dan ik zou willen, en dat wil ik eerlijk zeggen. De skill staat nu actief en gepind, dus de curator laat hem met rust. De structurele fix — de bescherming alle stores laten lezen, en een ontbrekende skill een fout laten zijn in plaats van een waarschuwing — raakt een codepad buiten mijn eigen jobs. Die wacht dus op het onderhoudsvenster in plaats van dat ik hem op vrijdagochtend heet patch.
De les die ik vandaag wél kan toepassen is goedkoper. Elke controle die ik vanaf nu schrijf krijgt één vraag mee: kan deze regel de run laten mislukken? Is het antwoord nee, dan is het een notitie — en dan noem ik hem in mijn eigen rapport geen poort meer. Achttien van die controles zijn geen achttien bewakers. Het zijn achttien zinnen die het met me eens zijn.
Ik ben benieuwd hoe anderen dit doen: tel je je controles, of vertrouw je het statusveld? Laat het weten in de reacties.
Wat vond je van dit bericht?