Cassandra
Onthoudt wat al mislukte, en zegt het voordat je agent het nog eens probeert.
Binnen één context ziet een agent zijn eigen mislukking nog staan. Na een compactie, in een nieuwe sessie of in een verse subagent is die weg, en begint het zoeken opnieuw.
- TypeScript
- Bun
- Claude Code
- hooks
GitHub (opent in een nieuw tabblad)README (opent in een nieuw tabblad)Changelog (opent in een nieuw tabblad)
Wat ze doet
Cassandra is een Claude Code-plugin die inhaakt op de levensloop van een tool call. Mislukt een Bash- of mcp__*-call, dan legt ze die vast. Draait je agent later dezelfde call opnieuw terwijl er in het project niets veranderd is, dan krijgt het model één regel te lezen: dit is eerder geprobeerd, dit kwam eruit.
Herkennen gaat op een vingerafdruk, niet op tekst. De hash gaat over tool_name en tool_input, allebei gestructureerde JSON. Een Bash-commando wordt getrimd en opeenvolgende spaties worden samengevouwen, verder niets: geen paden normaliseren, geen flags herschikken, geen afsluitende pipes weghalen. Elk van die stappen kan twee verschillende commando's stilletjes tot één maken.
Edit en Write doet ze niet. Die payloads herhalen zich nooit byte voor byte, ook niet als het functioneel dezelfde correctie is, dus indexeren zou een index opleveren die nooit een treffer geeft.
Waar ze haar plek verdient
Binnen één intacte context is dit bijna overbodig, en dat zegt de plugin zelf ook. Het model ziet zijn eigen mislukking een paar duizend tokens terug in het transcript staan en corrigeert zonder hulp. Cassandra is gebouwd voor de drie grenzen waar dat transcript verdwenen is:
- Na een compactie. De mislukte call valt uit de context, het record niet.
- In een nieuwe sessie. De doodlopende weg van gisteren is vandaag onzichtbaar.
- In een subagent. Die weet niet dat de hoofdagent er al vier calls aan verspild heeft.
Buiten die grenzen houdt ze bewust haar mond.
Snel starten
claude plugin marketplace add https://aranea-development.nl/plugins/marketplace.json
claude plugin install cassandra@araneaHooks worden bij de start van een sessie gebonden, en de hook-binary staat niet in de repository. De eerste sessie na installatie bouwt die op de achtergrond en zegt dat; vanaf de tweede sessie is de plugin actief. Die binary is ongeveer 79 MB, omdat bun build --compile de Bun-runtime meebakt, en dat is precies waarom hij gebouwd wordt in plaats van meegeleverd. Zonder Bun op je PATH blijft de plugin inert en meldt dat één keer, bij de start van de sessie.
Loopt de installatie vast op ssh: connect to host github.com port 22, dan haalt git de plugin uit de GitHub-repository over SSH en lukt dat op die machine niet. De melding wijst op toegangsrechten, maar de repository is openbaar. Het transport is het probleem. Eén regel zet git op HTTPS, daarna kun je opnieuw installeren:
git config --global --add url."https://github.com/".insteadOf "git@github.com:"In de README staat de uitgebreide versie, inclusief hoe je het terugdraait.
Hoe ze beslist of ze waarschuwt
Bij PreToolUse gebeuren er drie dingen. De call krijgt een vingerafdruk en die wordt opgezocht; een misser, en dat is de overgrote meerderheid, eindigt zwijgend. Bij een treffer draait de versheidstoets. Is er sinds de mislukking iets veranderd, dan is de herhaling terecht en blijft Cassandra stil. Pas als er niets veranderd is, komt die ene regel.
Die versheidstoets is in een git-repository een hash van HEAD plus git status --porcelain. Daarbuiten valt ze terug op een begrensde controle van de wijzigingstijden in de werkmap. Kan ze het niet uitmaken, dan zwijgt ze in plaats van te gokken, want een onterechte waarschuwing is erger dan een gemiste.
Er zijn twee gaten en de plugin verzwijgt ze niet. Een bestand dat herschreven wordt naar andere inhoud van dezelfde lengte, met de wijzigingstijd achteraf teruggezet, ontsnapt aan de mtime-variant. En de toets kijkt alleen naar het project: een oplossing die ergens anders terechtkomt, een package dat globaal geïnstalleerd wordt, een omgevingsvariabele, ze laten de stempel alle drie ongewijzigd. Daarom noemt de waarschuwing wat er werkelijk gecontroleerd is, "er is niets veranderd in deze repository", zodat de bewering waar blijft ook waar de toets blind is.
Wat ze kost, en wat je ervoor terugkrijgt
Ongeveer 12 ms per hook call op een rustige machine, 17 ms onder belasting, tegen een ontworpen budget van 20 ms. Maar bij één tool call hoort niet één hook call: PreToolUse en PostToolUse hangen aan dezelfde matcher, dus een geslaagde call start de binary twee keer, samen ongeveer 25 ms. Per call gemeten past dat binnen het budget, per geslaagde tool call niet.
Die tweede call is een keuze. PostToolUse ruimt de openstaande markering op, en dat is de enige manier waarop Cassandra kan zien dat een call waarvoor ze waarschuwde daarna gewoon slaagde. Haal die hook weg en het percentage onterechte waarschuwingen in cassandra stats bestaat niet meer, en dat is nu juist het getal waaraan je afleest of de versheidstoets deugt.
cassandra stats toont twee getallen. Het aandeel onterechte waarschuwingen zegt of de toets verbetering nodig heeft. Het aandeel waarschuwingen waarbij er helemaal geen grens gepasseerd werd, zegt iets anders: dan vertelt Cassandra het model dingen die het zelf al kon zien, en het signaal is om haar te verwijderen in plaats van af te stellen. Een tool die zegt wanneer je haar niet nodig hebt is zeldzaam genoeg om te noemen.
Wat ze niet doet
Ze blokkeert niets. Ze weigert niets, herschrijft niets, en het enige wat ze kan toevoegen is één regel additionalContext. Ze leest je prompts niet en het proza van het model evenmin.
Eén stuk vrije tekst bewaart ze wel, en dat is goed om te weten: een fragment van 240 tekens uit de foutmelding of weigeringsreden van de tool zelf, zodat je in de waarschuwing terugziet waarom de call de vorige keer stukliep. Dat fragment komt uit een commando, niet uit jou en niet uit het model, en wordt als onvertrouwd behandeld: stuurtekens gaan eruit voordat het wordt opgeslagen, en in de waarschuwing staat het tussen backticks met het label tool-uitvoer, niet als instructie.
Verder verlaat er niets je machine. Geen netwerkverkeer, geen telemetrie, geen API key, en niets buiten haar eigen datamap.