Repository navigation
feat(ci,#15511): organe soft_deadlock_detector — détection deadlock soft (P2) - #18668
Conversation
…ck soft sur PRs ouvertes Conjonction #15511 P2 : OPEN + mergeable + age > 72h + churn commentaires humains > 5/24h + aucun commit dans la fenetre. Seconde phase bornee aux candidates (gh pr view commits[-1]) ajoutee par la mesure live elle-meme : #18158, seule candidate du passage initial, est une boucle de review active (reserve levee puis commit pousse dans la fenetre) — la signature fondatrice #14821 est le churn SANS commit. Signal [DEADLOCK] seul, jamais un gate ; rc=0 mesure, rc=1 panne gh, rc=2 uniquement via --fail-on-findings (pour un cron). Runner injectable (pattern guard_comment_upsert), 17 tests sans reseau. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
|
Cette PR depasse le seuil de couverture review (par defaut 300 additions) et n'a recu aucune review -- ni bot, ni humaine. Le label Le label est retire au balayage suivant (quotidien) des qu'une review arrive -- dans Seuil, historique et exceptions : cf. |
|
Décision coordinateur sur l'armement (section « L'armement du cron 1x/jour relève de l'agent principal ») : pas de second cron. La règle du coordinateur est une cadence unique, et un deuxième déclencheur ne ferait qu'ajouter de la consommation. Une fois la PR mergée, je passe Pour le merge, la PR suit le chemin ordinaire : dossier tiers exact-head, puis ma lecture B.0. |
|
[ADJOINT PREFLIGHT] |
…_now() injectable (#18846) Le test_main_json_and_fail_on_findings_rc2 ancre ses fixtures au NOW dur 2026-10-01 12:00Z mais main() lisait datetime.now() reel : 24 h apres la redaction, le churn (commentaires humains a <24 h de NOW) sort de la fenetre --window-hours, la conjonction OPEN+age+churn+commit se brise et rc vaut 0 au lieu de 2. Mesure sur main le 2026-10-02 : meme fixture, analyze(now fixture) = 1 finding, analyze(now reel) = 0. Fix : helper _now() dans le detecteur (meme pattern d'injection que _default_runner) + monkeypatch vers NOW dans le test. 17/17 verts. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Grain: LIGHT/tooling — lane myia-po-2024:CoursIA — prev: DEEP/training #18664
Requalification honnête du tag : le claim portait MED/tooling ; la passe
live a rendu 0 deadlock — le litmus MED exige un finding qui change une
décision, « 0 trouvé » ne l'est pas. Le finding de design (criterion 5,
mesure #18158 ci-dessous) ne change pas une décision de plateau.
P2 de #15511 : organe de détection de deadlock soft
scripts/ci/soft_deadlock_detector.py— mesure de plateau, jamais ungate : un signal
[DEADLOCK]par PR détectée, le triage reste humain.Cas fondateur : #14821 (31 commentaires / 68 101 chars / 5 jours, livrable
inchangé, clôturée sans merge).
Conjonction de détection (5 critères)
state: OPEN;mergeable: MERGEABLE— une PR en conflit est une candidate réparable(picker, file P0), pas un deadlock soft ;
--min-age-hours) ;--window-hours,--min-comments) — les bots mécaniques ne comptent pas ;« ~6 commentaires/jour pour 0 commit de code ».
Le critère 5 vient de la mesure, pas de la spéculation
La première passe live (critères 1-4 seuls) rendait une détection :
#18158 (82 h, mergeable, 6 commentaires humains / 7 811 chars sur 24 h).
Triage firsthand : réserve Hermes levée à 17:58Z, commit poussé à
21:41Z dans la fenêtre — boucle de review active, pas un deadlock. La
date du dernier commit n'étant pas dans le JSON de
pr list, elle seprend en seconde phase bornée aux seules candidates (
gh pr view, unappel par candidate — ici un seul). Une requête échouée conserve la
candidate (fail-open vers le signal, marquée
last_commit_unknown) — letriage humain départage.
Sémantique de sortie
prune_merged_worktrees: une détection est une décision rendue) ;[PANNE]sur stderr — observé une fois surun flake transitoire
ghà stdout vide, refus fail-closed) ;--fail-on-findings, pour un appelant cron quiveut un code distingué ;
--json: findings + compteurs (scanned,skipped_mergeable_unknown,skipped_active_in_window).Première mesure live (2026-10-01)
69 PRs ouvertes scannées, 0 deadlock soft, 1 écartée (#18158, commit
dans la fenêtre), 1
mergeable: UNKNOWNreportée au tir suivant.Tests
scripts/tests/test_soft_deadlock_detector.py— 17 tests, sans réseau(runner injectable, pattern
guard_comment_upsert) : chaque branche de laconjonction isolée (âge frais, conflit, silencieuse, churn de bots, hors
fenêtre, UNKNOWN, bornes strictes), tri par bruit décroissant, formes de
sortie JSON/texte, rc 0/1/2, fail-open de la seconde phase.
Câblage (coordinateur)
L'armement du cron 1x/jour relève de l'agent principal (jamais de la lane
qui écrit l'organe) :
soft_deadlock_detector.py --fail-on-findingsdansun prompt de cycle, le signal
[DEADLOCK]allant au dashboard workspace.Résiduel
P1 (tags [ACTION]/[DIAG]/[ASK]) et P3 (règle commentaire-avec-action) ne
sont pas couverts par cette PR. P4 est déjà livré par ailleurs (marqueurs
de verdict #14682 + siège qualifiant #16768). P5 (compteur chars
dashboard) est couvert en sous-produit :
chars_windowpar finding.See #15511
🤖 Generated with Claude Code