Skip to content

fix: persist hook cascade cadence and cool down misses (W2-4) - #486

Merged
cdeust merged 13 commits into
mainfrom
fix/green-hook-cooldowns
Sep 6, 2026
Merged

cdeust merged 13 commits into
mainfrom
fix/green-hook-cooldowns

Conversation

@cdeust

@cdeust cdeust commented Sep 6, 2026

Copy link
Copy Markdown
Owner

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_counter dé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 finally d'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 maintenant CORTEX_CLAUDE_DIR/methodology/hook-cooldowns/ ; sans override, leurs chemins historiques /tmp sont 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_calls et completed restent 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 par git show sur 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.main avec 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.

bash /private/tmp/cortex-green-command-isolated.sh .venv/bin/python -S /private/tmp/cortex-green-w2-4-exact-before.py
bash /private/tmp/cortex-green-unit-isolated.sh tests_py.hooks.test_cascade_counter_processes tests_py.hooks.test_miss_cooldowns tests_py.infrastructure.test_hook_counter_lock tests_py.shared.test_hook_state_paths
bash /private/tmp/cortex-green-local-gates.sh w2-4-final tests_py/hooks/ tests_py/infrastructure/ tests_py/shared/ tests_py/invariants/

Le premier lancement du probe root ne trouvait pas le checkout depuis son chemin /tmp et 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_memories et _bump_heat_for_symbols restent 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 final 1292984d804e2e1f44afa4de75dc43eb22803730. 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.

@cdeust
cdeust changed the base branch from fix/green-log-rotation to main September 6, 2026 21:53
@cdeust
cdeust merged commit ae73b42 into main Sep 6, 2026
29 checks passed
@cdeust
cdeust deleted the fix/green-hook-cooldowns branch September 8, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant