fix: persist hook cascade cadence and cool down misses (W2-4) - #486
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptôme
W2-4 / H4 : un miss ne pose aucun cooldown et répète les scans. Le compteur de cascade est remis à zéro à chaque processus PostToolUse et n'atteint jamais sa cadence de 20 appels. PR empilée sur #485.
Cause racine
Le launcher exécute une seule enveloppe par nouveau processus ;
_tool_call_counterdémarre à zéro puis atteint seulement 1. Le matcher de capture reste*afin que tous les outils alimentent cette cadence. Les autres déclencheurs de cascade existent et restent inchangés : ce défaut ne justifie pas de supprimer l'algorithme.Preemptive n'écrit le cooldown que si
count>0. Impact le fait après une réponse contenant des symboles et des mémoires correspondantes ; les retours précoces restent donc non bornés.Changement
Un scan terminé, y compris sans résultat, pose le cooldown existant : 60 s pour preemptive, 30 s pour impact. Le
finallyd'impact couvre absence de symboles et erreurs sans perdre la garde de fermeture de store introduite en W2-1a. Les deux fichiers de cooldown respectent maintenantCORTEX_CLAUDE_DIR/methodology/hook-cooldowns/; sans override, leurs chemins historiques/tmpsont préservés. Aucun répertoire n'est créé à l'import.La cadence utilise un compteur JSON persistant par identité canonique de transcript, hachée pour le chemin.
tool_callsetcompletedrestent distincts. Un verrou court protège lecture/incrément/remplacement atomique ; un autre verrou d'exécution non bloquant coordonne les cascades de hooks d'une même racine. Aucun travail DB/modèle sous verrou compteur. Contention, exception ou résultat{error: ...}conservent l'échéance pour un événement futur. Une invocation traite au plus un intervalle.Sources : identité canonique
injection_receipts.session_id_from_transcript(champ événement parfois divergent, décision 4255039 correction 7) ; fcntl.flock, msvcrt.locking, os.replace, patterns existants DecisionLock/atomic_write_json. Cadence 20 conservée, provenance du réglage initial inconnue ; aucun nouveau seuil empirique inventé.Preuve
Base exacte
3243dfed51d9b1b2e243918554ea2b83213de864, Python 3.13.7, macOS ARM64. Probe source avant/private/tmp/cortex-green-w2-4-exact-before.py, sortie/private/tmp/cortex-green-w2-4-exact-before.json. Les corps sont chargés pargit showsur cette base : 40 processus / 40 PID distincts, compteur 1 partout, zéro cascade ; trois événements à début/juste avant échéance/échéance produisent trois scans dans chacun des trois scénarios miss.Après : 25 tests passent en 3,838 s, dont 40 nouveaux processus exécutant le vrai
hook.mainavec effets mémoire/cascade remplacés par espions. Ils prouvent zéro cascade aux appels 1–19, une aux appels 20–39, deux à 40 ; 40 incréments concurrents sans perte ; deux sessions indépendantes ; échéances conservées sous contention/erreur ; simulation du verrou Windows. Les trois scénarios miss réalisent désormais deux scans, reprise à l'échéance exacte. Deux nouveaux tests root exécutent les hooks réels sous deux racines explicites : écriture/lecture isolées, aucun état créé à l'import, chemin historique inchangé sans override.Le premier lancement du probe root ne trouvait pas le checkout depuis son chemin
/tmpet ne pouvait mesurer impact ; il a été corrigé avec chemin source explicite et assertions des compteurs avant de produire la preuve ci-dessus. Aucune mesure en échec n'est utilisée.Les fonctions
_prime_file_memorieset_bump_heat_for_symbolsrestent byte-identiques à la base, preuve/private/tmp/cortex-green-w2-4-writer-proof.json. Le registre invariant A3 a seulement été repointé de 145→148 et 182→184 après les imports ajoutés ; aucun writer ni exemption ajouté. Première suite complète : seul ce décalage de lignes échouait (7 683 autres tests réussis) ; ses trois tests ciblés passent après correction.Gates finaux terminés code 0 : Ruff/format 1 442 fichiers, craftsmanship, Pyright zéro diagnostic ; couches affectées 1 536 passed, 123 skipped, 13 subtests en 37,14 s ; suite complète 7 684 passed, 221 skipped, 361 subtests en 145,02 s. Journal
/private/tmp/cortex-green-w2-4-final-gates.log. Charge initiale 4,27 / 10 cœurs ; disque 60 GiB avant/après. PostgreSQL volontairement indisponible sur socket privé ; aucun accès production. SHA final1292984d804e2e1f44afa4de75dc43eb22803730. CI 34046091095 verte sur ce SHA ; les deux builds Docker sont ignorés conformément au filtre W1-4.Les fixtures n'ouvrent ni modèle ni DB. Le temps réel de la cascade désormais active n'est pas mesuré par ces espions ; aucun gain CPU/énergie extrapolé.
Conformité
Baseline diminuée d'une entrée devenue obsolète pour
_CASCADE_INTERVAL; aucun ajout. Nouveaux modules sous 300 lignes, fonctions sous 40 lignes/quatre paramètres ; infrastructure n'importe aucun handler/core. Imports et fermeture paresseux W2-1a préservés. Le commentaire historique « <200 ms » sera corrigé avec la mesure W3-1a, conformément au découpage du plan.Candidats issues
Le déclenchement est best effort : un crash après effets DB et avant acquittement peut répéter une cascade. Une échéance pendante nécessite un futur événement. L'état reste conservé pour les reprises, sans TTL inventé. Le verrou global coordonne les seules cascades de hooks, pas les déclencheurs historiques. Une suspension sous verrou compteur peut retarder un hook ; aucun délai ou retry arbitraire ajouté. Aucun ticket créé.
Runbook
Aucune opération de production. Le compteur sera créé sous
CORTEX_CLAUDE_DIR/methodology/hook-cascade/à la première enveloppe portant une identité de transcript valide. La cadence retrouvée déclenche un travail synchrone aux échéances ; la PR ne le présente pas comme gratuit. Ne pas supprimer les fichiers de verrou pendant des sessions actives.