Naar inhoud

Kairos

Het juiste moment, gepakt voordat het voorbij is.

Kairos (καιρός) is het Oudgriekse woord voor het juiste moment, tegenover chronos, de tijd die simpelweg verstrijkt. Verpersoonlijkt is hij een jonge god met een lange lok haar over zijn voorhoofd en achterop niets: je kunt hem grijpen als hij op je afkomt, en nooit meer zodra hij voorbij is.

Wat het doet

Claude Code hanteert een gebruikslimiet van vijf uur en waarschuwt daar niet voor. Het werk valt stil middenin een taak, op een moment dat de limiet kiest in plaats van jij, en het enige teken is de foutmelding zelf.

Kairos houdt bij hoeveel van het venster je hebt uitgegeven, voorspelt wat je volgende beurt gaat kosten, en weigert de prompt voordat die beurt je door de muur heen duwt. Word je tegengehouden, dan vraagt Kairos wat je wilt: wachten tot het venster reset, toch versturen, of laten vallen.

Nergens op je machine staat hoeveel van de limiet je hebt verbruikt, of waar de limiet ligt. Allebei worden ze gereconstrueerd uit de transcripten die Claude Code toch al wegschrijft.

Aan de slag

bash
claude plugin marketplace add https://aranea-development.nl/plugins/marketplace.json
claude plugin install kairos@aranea

Hooks binden bij het starten van een sessie, dus begin een nieuwe sessie voordat Kairos iets doet. Een sessie die al draait pikt het niet meer op. Je hebt bash en jq nodig, en ontbreekt jq, dan zegt Kairos dat één keer en doet verder niets.

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 naar toegangsrechten, maar de repository is openbaar. Het transport is het probleem. Eén regel zet git op HTTPS, daarna kun je opnieuw installeren:

bash
git config --global --add url."https://github.com/".insteadOf "git@github.com:"

In de README staat de uitgebreide versie, inclusief hoe je het terugdraait.

Wat het weet, en wat niet

De reconstructie is exact voor het verbruik en niet exact voor het plafond, dus het plafond wordt gerapporteerd als een bereik, met het bewijs dat eronder ligt. Eén vastgelegde weigering geeft een breed bereik, drie geven een smaller.

Een account waarvan Kairos nooit een weigering heeft gezien, krijgt helemaal geen bereik, en wordt nooit tegengehouden. Het meet, het rapporteert, en het blijft uit de weg tot het een muur van dat account zelf heeft waargenomen.

Dat is een keuze, geen omissie. Een eerdere versie vulde een aannemelijk bereik alvast in op basis van waargenomen data. Toen elk venster in diezelfde geschiedenis werd nagerekend, bleken er vensters van 16,5 miljoen tokens te zijn zonder ook maar één weigering, terwijl die aanname bij 5,7 miljoen ophield. Die getallen beschreven één abonnement, niet de vorm van de limiet. Een geraden plafond zou op een groter abonnement voortdurend onderbreken en ondertussen doen alsof het iets wist dat het nooit had gezien.

Twee abonnementen

Heb je meer dan één Claude-abonnement en wissel je ertussen, dan houdt Kairos ze uit elkaar. Alles wat het vastlegt is per account gescheiden, een sessie volgt het account dat daadwerkelijk betaalt ook als je halverwege wisselt, en een Max 5x wordt onderscheiden van een Max 20x, want hun plafonds schelen ongeveer een factor vier en dat onderscheid is nu juist het punt.

In de transcripten staat nergens welk account voor een bericht betaald heeft, dus dit valt niet met terugwerkende kracht op te lossen. Kairos begint bij een nieuw account met niets en wordt beter naarmate het draait.

Hoe de getallen tot stand komen

Verbruik telt input-tokens, cache-aanmaak en output. Cache-reads tellen niet mee, en dat is gemeten. Ze op nul wegen past bij de vastgelegde weigeringen, en ze meetellen maakt de fout bij elk gewicht vier keer zo groot. Een meter die ze meetelde, zat er ongeveer een factor honderd naast.

Het vijfuursvenster wordt uit de tijdstempels in de transcripten gereconstrueerd als aaneengesloten vensters, afgerond op tien minuten. Dat model reproduceert de reset-tijden die Claude in zijn eigen weigeringen noemt, tot op de minuut.

De volgende beurt wordt voorspeld met het 75e percentiel van de recente beurten, omdat het juist de uitschieters zijn die een sessie door een limiet heen duwen. Kairos rekent tegen de ruime kant van het bereik en blijft dus stil tot zelfs een royaal plafond in zicht komt. Liever laat Kairos je een eerste keer tegen de muur lopen dan dat hij je een maand lang ten onrechte stoort.

Wat het nooit doet

Het schrijft nooit je e-mailadres naar schijf. Het voert nooit zelf /login uit; het zegt wel wanneer een ander account vrij lijkt en laat de keuze aan jou. En het blokkeert nooit een prompt omdat er iets in Kairos zelf stukging. Elk onzeker pad laat de prompt door, want je vergissen in het budget is vervelend, maar je werk stilleggen omdat de meter kapot is, is erger dan helemaal geen meter.

Als er iets misgaat

Draai /kairos. Dat toont wat de plugin op dit moment denkt, en dat is meestal genoeg om de drie stille toestanden uit elkaar te houden, want van buitenaf lijken ze op elkaar.

Nog niets vastgelegd voor dit account betekent dat er geen verbruik is ingelezen. Of jq ontbreekt, of de hooks zijn niet gebonden omdat de sessie al liep toen je installeerde. Begin een nieuwe sessie en kijk opnieuw.

Nog geen plafond vastgelegd is geen fout. Dat is de normale toestand voor een account dat nog nooit tegen een limiet is gelopen terwijl Kairos meekeek, en zo blijft het tot dat gebeurt. kairos calibrate doorzoekt je hele transcriptgeschiedenis op weigeringen die nog niet zijn gezien, en dat is na het installeren één keer de moeite.

Een getal dat niet klopt is het waard om naast kairos accounts te leggen. Gebruik je meer dan één abonnement, dan hoort het getal dat je ziet bij het account dat nu actief is, en staat het andere ernaast.

Hoe het werkt

Vier hooks, allemaal alleen in de harness, dus niets hiervan kost context van het model.

HookTaak
SessionStartHet betalende account bepalen, de sessie eraan binden, de meter bijwerken, weigeringen oogsten
UserPromptSubmitEen accountwissel halverwege volgen, de beurt voorspellen, blokkeren of doorlaten
StopVastleggen wat de beurt echt kostte, en een weigering oogsten als die net viel
SessionEndDe slotregel tonen

Verbruik wordt stapsgewijs ingelezen. Een cursor per transcript houdt bij hoeveel bytes al geteld zijn, zodat een verversing alleen leest wat er sindsdien bij kwam. Alles staat per account gescheiden onder ~/.claude/kairos/accounts/, waar ook de vastgelegde weigeringen en de beurtgeschiedenis staan.

Platformnotities

Bij elke push getest op Linux, macOS en Windows, en op macOS bovendien onder bash 3.2, want dat is wat macOS nog steeds als /bin/bash meelevert.

Twee fouten in de geschiedenis van deze plugin waren alleen op Windows te bereiken. Git zet regeleindes om bij het uitchecken, en een carriage return die op een getalsveld meelift is geen verkeerd getal maar een rekenfout. En een bestand vervangen gaat daar niet in één ondeelbare stap, dus een gelijktijdige schrijver kan er een laten verdwijnen tussen een bestaanscontrole en het lezen. Beide zijn afgevangen, en beide zijn door CI gevonden.

Wat je nodig hebt

bash en jq. Linux, macOS en Windows. De testsuite draait op alle drie, en op macOS bovendien onder bash 3.2, want dat is wat macOS nog steeds als /bin/bash meelevert.