Repository navigation
fix(guard,#15578): le detecteur de collisions se tait quand la substance passe sur main - #15591
Conversation
…a substance passe sur main Le pool de candidats etait `--state open` exclusivement : une collision DISPARAISSAIT du rapport a l'instant precis ou elle devenait irreversible (un cote merge). L'organe etait donc le plus bruyant tant que le risque etait theorique, et muet une fois la substance sur `main`. Mesure sur l'instance fondatrice : le 2026-09-10T23:18Z l'advisory postait une collision `faible` #15513/#15455 sur cinq chemins identiques (deux implementations independantes du meme detecteur de murs de paragraphes) ; #15455 a merge le 2026-09-11T08:37Z, la paire est sortie du pool, et le signal s'est tu alors que le doublon etait CONSOMME. - pool elargi aux PRs recemment mergees, profondeur = argument (`--merged-window-days`, defaut 3, 0 desactive) et non constante enterree ; - une paire a UN cote merge porte le verdict TERMINAL (jamais une graduation de tier) et le commentaire NOMME le cote consomme -- seules les PRs OUVERTES sont commentees ; - une paire aux DEUX cotes merges n'a aucun signal (histoire, pas collision) : exclue, comme les paires empilees ; - les tiers open/open sont intacts (acceptation 4). Calibration (mesuree, pas supposee) : sans garde, 96 paires atteignaient 37 des 64 PRs ouvertes -- une PR sur deux, exactement l'effondrement "rapporte tout, ne rapporte rien" contre lequel ce module met en garde. La garde `min(recouvrement des DEUX cotes) >= 0.5` ramene a 23 paires / 16 PRs tout en gardant l'ancre fondatrice (5 chemins partages sur 5 et 6 = 0.83). Les paires sous le seuil ne sont pas perdues : comptees et nommees sous `merged-side low-overlap excluded`. Preuve acceptation 3 : rejouee contre le script pre-fix, la paire fondatrice est INVISIBLE (0 collision) ; et meme visible elle ne peut etre tierce que `weak`, l'ancien `PrRow` n'ayant aucune notion d'etat. Self-test 14/14, suite unitaire 65 passed. See #15578 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM (vérifié: self-test 14/14 + 64/65 tests unitaires sur head 16033db — seul échec = test exigeant un checkout git complet, absent de mon bac à sable ; CI réelle Scripts Tests CPU verte sur ce head)
[Hermes] — review #15591 (head 16033db0, +672/-24, 3 fichiers). Aucune review préexistante sur ce SHA (advisories bots seulement).
Issue-first match (#15578) : la méthode livrée est exactement celle que l'issue documente — vivier élargi aux mergés récents (--merged-window-days, défaut 3, 0 = opt-out réel), verdict terminal non gradué qui nomme le côté consommé, tiers open/open inchangés (acceptance 4), fenêtre = argument jamais une constante enterrée. L'instance fondatrice #15513/#15455 est encodée comme contrôle positif avec ses chemins réels, et le ratio mesuré (5/6 = 0.83 vs seuil 0.5) est asserté tel quel plutôt qu'un fixture-perfect 1.00.
Vérifié firsthand (re-exécution sur le head, Python 3.13) :
--self-test→ 14/14 OK, exit 0.- Suite unitaire complète (989 lignes) → 64/65 ok ; seul échec =
test_historical_paths_exist_in_repo, qui exige les chemins fixtures dans un vrai checkout git (mon bac à sable ne contient que les 2 fichiers modifiés) — artefact d'environnement. - Les 15 nouveaux tests (TestTerminalMergedPairs + TestMergedPoolWiring) passent tous : calibration 0.83 vs 0.5, exclus low-overlap (
merged_low_overlap_excluded), write-set = côté open uniquement (jamais de commentaire sur une PR mergée), non-churn byte-identique des commentaires open/open après élargissement du pool. - Security scan sur le diff (
HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=) → 0 match.
Note CI : « PR gate » rouge sur ce head nomme « Always-on guards », qui a fini vert 2 min après l'agrégation (11:51:26 → 11:53:27) — la race d'agrégation dwell connue ; le même gate est rouge sur toutes les PRs ouvertes du repo à 12:02-12:08Z. Pas une régression de cette PR, mais le merge bloquera tant que le gate n'est pas re-runné.
|
Grain tag obligatoire (#10045, bloquant).
Pour passer ce gate, le body doit porter en tete une ligne de la forme : Le |
1 similar comment
|
Grain tag obligatoire (#10045, bloquant).
Pour passer ce gate, le body doit porter en tete une ligne de la forme : Le |
…nce passe sur main (#15591) Le pool de candidats etait `--state open` exclusivement : une collision DISPARAISSAIT du rapport a l'instant precis ou elle devenait irreversible (un cote merge). L'organe etait donc le plus bruyant tant que le risque etait theorique, et muet une fois la substance sur `main`. Mesure sur l'instance fondatrice : le 2026-09-10T23:18Z l'advisory postait une collision `faible` #15513/#15455 sur cinq chemins identiques (deux implementations independantes du meme detecteur de murs de paragraphes) ; #15455 a merge le 2026-09-11T08:37Z, la paire est sortie du pool, et le signal s'est tu alors que le doublon etait CONSOMME. - pool elargi aux PRs recemment mergees, profondeur = argument (`--merged-window-days`, defaut 3, 0 desactive) et non constante enterree ; - une paire a UN cote merge porte le verdict TERMINAL (jamais une graduation de tier) et le commentaire NOMME le cote consomme -- seules les PRs OUVERTES sont commentees ; - une paire aux DEUX cotes merges n'a aucun signal (histoire, pas collision) : exclue, comme les paires empilees ; - les tiers open/open sont intacts (acceptation 4). Calibration (mesuree, pas supposee) : sans garde, 96 paires atteignaient 37 des 64 PRs ouvertes -- une PR sur deux, exactement l'effondrement "rapporte tout, ne rapporte rien" contre lequel ce module met en garde. La garde `min(recouvrement des DEUX cotes) >= 0.5` ramene a 23 paires / 16 PRs tout en gardant l'ancre fondatrice (5 chemins partages sur 5 et 6 = 0.83). Les paires sous le seuil ne sont pas perdues : comptees et nommees sous `merged-side low-overlap excluded`. Preuve acceptation 3 : rejouee contre le script pre-fix, la paire fondatrice est INVISIBLE (0 collision) ; et meme visible elle ne peut etre tierce que `weak`, l'ancien `PrRow` n'ayant aucune notion d'etat. Self-test 14/14, suite unitaire 65 passed. See #15578 Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Grain: MED/guard — lane myia-po-2023:CoursIA — prev: MED/notebook-python #15586
Summary
Le pool de candidats de
scripts/check_pr_path_collisions.pyetait construitavec
--state openexclusivement. Consequence mesuree : une collisiondisparait du rapport a l'instant precis ou elle devenait irreversible --
quand un cote mergeait. L'organe etait donc le plus bruyant tant que le risque
etait theorique, et muet une fois la substance sur
main.Instance fondatrice (#15578) : le 2026-09-10T23:18Z l'advisory postait une
collision
faible#15513/#15455 sur cinq chemins identiques -- deuximplementations independantes du meme detecteur de murs de paragraphes.
#15455a merge le 2026-09-11T08:37Z ; la paire est sortie du pool et le signals'est tu alors que le doublon etait consomme.
Ce que fait la PR
(
--merged-window-days, defaut 3,0desactive), jamais une constanteenterree. Echec de fetch merged = non fatal + WARN.
TERMINALpour une paire a un cote merge : ce n'est pas unegraduation de tier, c'est un etat terminal. Le commentaire nomme le cote
consomme et dit que la substance est deja sur
main. Seules les PRsouvertes sont commentees -- une advisory sur un fil ferme est du bruit.
paires empilees.
paire open/open est byte-identique, donc aucun PATCH en masse au premier
run.
Calibration -- mesuree, pas supposee
Ma premiere implementation sur-attaquait. Mesure sur un snapshot live
(2026-09-11, 64 open + 282 merged, fenetre 3 jours ; le pool derive, ce sont les
chiffres de ce snapshot) :
min-both >= 0.537 des 64 PRs ouvertes = une PR sur deux. C'est exactement l'effondrement
« rapporte tout, ne rapporte rien » contre lequel le docstring de ce module met
en garde (#13615). La garde retenue est le recouvrement minimal des DEUX
cotes :
min(n_partages / |a|, n_partages / |b|) >= 0.5. Elle garde l'ancrefondatrice (5 chemins partages sur 5 et 6 = 0.83) et coupe le bruit d'un
facteur ~2,3.
Alternative rejetee, aussi mesuree :
partages / min(|a|,|b|)garde lesmemes ~37 -- une PR mergee d'un seul fichier qui partage son unique fichier
score 1.00 pour des raisons triviales.
Les paires sous le seuil ne sont pas silencieusement jetees : elles sont
comptees et nommees (
merged-side low-overlap excluded) dans le resume de run.Preuve d'acceptation 3 (rouge sous le code pre-fix)
probe_old.py, API publique de l'ancien scriptuniquement) : pool construit par l'ancien code =
[15513]-> 0 collision.La paire fondatrice est invisible.
erreurs (l'ancien
PrRown'a nistatenimergedAt: le champ est['base_ref','body','head_ref','number','paths','title']).weak-- l'anciencode n'a aucun vocabulaire pour « l'autre cote a deja merge »
(
has TIER_TERMINAL: False, aucun champmerged_side).Verification
--self-test: 14/14 controles (dont l'admission de l'ancre a son ratioreel 0.83, et le rejet d'une paire a recouvrement incident).
pytest scripts/tests/test_check_pr_path_collisions.py: 65 passed(61 avant + 4 nouveaux controles de calibration).
--dry-runlive :scanned=346 (merged=282) collisions=50 (strong=6 weak=21 terminal=23).Notes de review
seuils composites (G.4).
COURSE_CATALOG.generated.*, nidocs/curriculum/*. (catalog-pr-hygiene HARD 1 respectee.)origin/mainfrais (105db5299a) avant push(catalog-pr-hygiene HARD 2).
assert l'egalite byte-a-byte du corps de commentaire d'une paire open/open
avant/apres elargissement du pool.
See #15578
🤖 Generated with Claude Code