Repository navigation
fix(ci,#19168): absorber TRANCHE15/16 et declarer l'ombre du lot pilote - #19171
Conversation
Deux gardes declarees `blocking=True` ne bloquaient rien : le job
« Always-on guards » lance `fast_lane.py --shadow`, et le moteur calcule
`effective_shadow = args.shadow and not guard.absorbed`. Sans absorption,
elles emettaient sous `fast-lane (ombre): ` avec une conclusion NEUTRE et
n'entraient pas dans `blocking_failed`.
Absorbees, apres verification qu'elles sont vertes sur `main` (donc sans
rougir aucune PR existante par dette heritee) :
- `lake-direct-invocation-guard` (`--all --check` -> rc=0, 6 fichiers en
dette tous allowlistes) ;
- `control-chars-in-cells-guard` (`--diff origin/main...HEAD` -> rc=0).
Temoin du basculement, meme garde et `rc=1` :
avant : nom `fast-lane (ombre): control-chars-in-cells-guard`, conclusion
`neutral`, hors `blocking_failed`
apres : nom `control-chars-in-cells-guard`, conclusion `failure`, compte
dans `blocking_failed`
C'est exactement le critere de cloture de l'issue (nom canonique sur une PR
de notebooks, et un diff violant la garde rougit « Always-on guards »).
Declare l'ombre du lot pilote. Mesure du 2026-10-05 sur les 15 gardes
pilotes bloquantes non absorbees :
- 9 ont un workflow d'origine qui declenche encore sur `pull_request` :
c'est lui qui bloque, la voie rapide observe ;
- 2 ont un workflow d'origine qui ne declenche PAS sur `pull_request`
(`perimeter-review-guard`, `self-hosted-runner-policy`) : aucun autre
emetteur de leur nom de check-run ;
- 4 sont natives de la voie rapide : meme situation, sans workflow.
Les deux dernieres categories sont donc inertes aujourd'hui -- declarees ici
avec leur critere de bascule, pas reparees : basculer le lot pilote entier
est le geste du programme #12567, pas celui de cette correction.
`shadow_reason` (nouveau champ de `Guard`) porte le motif ET le critere de
bascule, ce que l'issue demande comme seconde voie. Le test
`test_aucun_garde_bloquant_n_est_inert_sans_declaration` ferme la classe
entiere : tout garde bloquant doit etre absorbe ou declare, et un absorbe qui
porte encore un motif d'ombre est signale comme declaration perimee.
Defaut d'isolation revele et repare au passage : `_drive_mixed_emission` ne
vidait que PILOT, TRANCHE1, 2, 4 et 5 -- les gardes REELLES de douze tranches
tournaient dans un test qui annonce une lane a deux gardes, avec leur rc
injecte par le faux `run_argv`. Le helper vide desormais toute tranche
decouverte dynamiquement.
Preuves :
- `pytest scripts/tests/test_fast_lane.py scripts/tests/test_check_absorbed_
check_run_identity.py scripts/tests/test_pr_gate.py scripts/tests/test_check_
control_chars_in_cells.py scripts/tests/test_fast_lane_merge_base.py -q`
-> 250 passed
- falsifiabilite : retirer `absorbed=True` de TRANCHE16 rougit le nouveau
test, qui nomme `control-chars-in-cells-guard` ; fichier restaure depuis
backup et verifie byte-identique
- `check_absorbed_check_run_identity.py --check` -> rc=0 (16 gardes absorbes
byte-identiques)
Co-Authored-By: Claude Haiku 4.5 (1M context) <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 |
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
Path-collision (organ #13359/#13615)Cette PR #19171 (
|
|
[ADJOINT PREFLIGHT] Dossier tiers (ai-01:CoursIA), à la tête
|
…eclaree des natifs + temoin negatif (#19207) * ci(fast-lane,#19193): decouverte dynamique des tranches + exemption declaree des natifs + temoin negatif Le filet d'identite byte-a-byte (`check_absorbed_check_run_identity.py`) enumerait 5 tranches en dur (TRANCHE1..5) -- un garde absorbe d'une tranche 6+ etait silencieusement non verifie. Le constat fondateur : TRANCHE10, 14, et le lot pilote (12 gardes) etaient hors du filet. Trois changements : 1. Decouverte dynamique via `vars(reg)` : on enumere chaque liste de `Guard` du registre. Une nouvelle TRANCHE18 sera couverte sans toucher au filet. Le pattern vient de `test_aucun_garde_bloquant_n_est_inert _sans_declaration` (#19171, TRANCHE17). 2. Exemption declaree des gardes `source == FAST_LANE_NATIVE` (natifs de la voie rapide) : signalee en sortie (pas un saut silencieux). 14 gardes concernes. 3. Témoin negatif : un test injecte un garde dont le nom ne matche pas le job du workflow source, et verifie que le filet le detecte. Deux exemptions de programme documentees en sortie : - `PILOT` (12 gardes) : absorption par declaration, programme #12567 - `TRANCHE10` (1 garde) : absorption faite mais job.name source non aligne, programme #12567 Couverture finale mesuree (run 2026-10-05) : - 19 gardes absorbes byte-identiques a leur source (TRANCHE1..9+11..17) - 14 gardes natifs exemptes - 12 gardes du lot pilote exemptes (programme #12567) - 1 garde en cours d'alignement (programme #12567) Travail prolonge directement #19171. Grain MED/guard. Grain: MED/guard -- lane myia-po-2025:CoursIA-2 -- prev: MED/guard #19171 Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com> * fix(fast-lane,#19193): import the exemption constants from the registry Hermes finding on PR #19207 (review 5409874260): the filet kept local copies of PILOT_LOT_NAME and ALIGNMENT_EN_COURS instead of importing them, so retiring TRANCHE10 from the registry would leave the net green for the wrong reason. The net now reads the registry constants under their registry names; local copies removed. Behavior verified unchanged: 15/15 tests, filet rc=0, same counts (19 byte-identical, 14 natifs, 12 pilote, 1 alignement #12567). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: jsboige <jsboige@gmail.com> Co-authored-by: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
Grain: MED/guard — lane myia-ai-01:CoursIA-2 — prev: MED/notebook-python #18536
Le defaut
Deux gardes declarees
blocking=Truedansscripts/ci/fast_lane_registry.pyne bloquaient rien. Le job « Always-on guards » lancepython scripts/ci/fast_lane.py --shadow(always-on-guards.yml), et le moteur calculeeffective_shadow = args.shadow and not guard.absorbed: un garde non absorbe emet sousfast-lane (ombre):avec une conclusion neutre et n'entre pas dansblocking_failed. Le registre annoncait « bloquant », le rollup disait « ombre ».Mesure de l'issue reproduite sur
control-chars-in-cells-guard, meme garde etrc=1:blocking_failedfast-lane (ombre): control-chars-in-cells-guardneutralcontrol-chars-in-cells-guardfailureLes deux gardes absorbees
Les deux sont vertes sur
main, verifie avant absorption — absorber ne rougit donc aucune PR existante par dette heritee :lake-direct-invocation-guard:check_lake_direct_invocation.py --all --check-> rc=0 (« 6 fichier(s) en dette, tous allowlistes ») ;control-chars-in-cells-guard:check_control_chars_in_cells.py --diff origin/main...HEAD-> rc=0.check_absorbed_check_run_identity.py --checkreste vert sur la branche (rc=0, 16 gardes absorbes byte-identiques a leur source). Note : cet organe enumere les tranches 1 a 5 ; ses deux nouveaux gardes sont natifs de la voie rapide, donc sans workflow d'origine a qui etre identiques — la verification y est vacue par construction, pas contournee.L'ombre du lot pilote est desormais DECLAREE
L'issue offrait deux voies : absorber, ou ecrire dans le registre que la garde est volontairement en ombre avec son motif et son critere de bascule. Les 15 gardes pilotes bloquantes non absorbees sont declarees, et la mesure du 2026-10-05 montre trois situations distinctes — deux d'entre elles sont inertes aujourd'hui, et c'est un constat, pas une intention :
pull_requestpull_requestperimeter-review-guard,self-hosted-runner-policy)hr-substitution-guard,duplicate-notebook-index-guard,kernel-suffix-canon-guard,slot-reservation-guard)Les 6 gardes des deux dernieres lignes sont inertes exactement comme l'etaient TRANCHE15/16. Elles sont declarees, pas reparees : basculer le lot pilote entier est le geste du programme #12567, pas celui de cette correction. Le motif et le critere de bascule vivent dans
shadow_reason(nouveau champ deGuard).Le test qui ferme la classe
test_aucun_garde_bloquant_n_est_inert_sans_declarationparcourt tout le registre (PILOT + tranches, decouvertes dynamiquement) et exige, pour chaque garde bloquant, l'un des deux etats : absorbe, ou declare en ombre. Un absorbe qui porte encore unshadow_reasonest signale comme declaration perimee. Deux controles positifs (absorbesetdeclaresnon vides) empechent le test de devenir vrai en silence.Falsifiabilite mesuree : retirer
absorbed=Truede TRANCHE16 rougit le test, qui nommecontrol-chars-in-cells-guarddans son message ; registre restaure depuis backup et verifie byte-identique.Un defaut d'isolation revele au passage
Absorber TRANCHE16 a fait echouer
test_mixed_emission_pilot_stays_shadowed_and_non_blocking, et la cause n'est pas la garde : le helper_drive_mixed_emissionne vidait quePILOT,TRANCHE1,TRANCHE2,TRANCHE4etTRANCHE5, laissant tourner les gardes reelles de douze tranches dans un test qui annonce une lane a deux gardes. Leurrcetait injecte par le fauxrun_argv, donc une tranche absorbe et bloquante rendaitrc=1et faisait rougir le job. Le test passait par accident tant qu'aucune tranche oubliee n'etait absorbe et bloquante. Le helper vide desormais toute tranche decouverte dynamiquement (vars(fl)filtre surTRANCHE).Preuves
pytest scripts/tests/test_fast_lane.py scripts/tests/test_check_absorbed_check_run_identity.py scripts/tests/test_pr_gate.py scripts/tests/test_check_control_chars_in_cells.py scripts/tests/test_fast_lane_merge_base.py -q-> 250 passedmainavant absorption :rc=0pour les deuxcheck_absorbed_check_run_identity.py --check-> rc=0Ce que cette PR ne fait pas
absorbed_guards()decheck_absorbed_check_run_identity.pyaux tranches 6 a 17 (10 gardes absorbees hors du filet d'identite). C'est un sujet distinct, que je signale plutot que de l'embarquer ici.See #19168 — les criteres de cloture de l'issue sont couverts ; la fermeture reste au coordinateur.
🤖 Generated with Claude Code