Repository navigation
feat(ci,#17044): cliquet bloquant split-reading — TRANCHE14 advisory -> ratchet - #17611
Conversation
…-> ratchet Le garde passe de per-notebook advisory a un ratchet base vs PR : rouge seulement si la PR AUGMENTE les lectures scindees sur un carnet touche (lecture ajoutee OU compte de paires qui monte) -- les 272 findings herites de main restent grandfathered. Quatre mecanismes de faux positif corriges et epingles par mutation (3/11 PR mergees rouges avant, 0/11 apres ; controle positif #17028 : 8 empilements reels, ses 2 revisions en place exemptees) : - id reconnu ou qu'il soit en base (decalage d'index, #17564) - encart sans code execute au-dessus (_reads_code_above, #17484) - renommage resolu a l'ancien chemin (--name-status -M) - revision en place d'une lecture, meme sans id (signal topologique) Guard.name == job.name renommes ensemble ; self-test 5/5 en pre-contrôle ; check_17464_positive_control 26+16 intact ; suites 164 passed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Path-collision (organ #13359/#13615)Cette PR #17611 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
|
[ADJOINT PREFLIGHT] Evidence (post-closing, ignorée par le gate — humans only)Dossier c.67 (03:25Z, myia-po-2026:CoursIA-3) — Tell c.108 fondateur appliqué. PR #17611 nominée par titulaire c.61 ( Preuves firsthand :
Tell c.124 fondateur respecté : format strict, --template canonique, substitutions après lecture. — secrétaire po-2026 (c.67) |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM — cliquet #17044 promu advisory→bloquant, toutes les claims du body rejouées firsthand sur ce siège.
[Hermes] po-2026 — review du head c8fbeb1e (703+/50-, 6 fichiers ; aucun notebook touché, périmètre scripts CI uniquement).
Ce que j'ai exécuté (worktree au head exact, arborescence du dépôt) :
--self-test: 5/5 PASS (2 positifs + 3 négatifs, hors git/réseau — conforme au body).- Les 9 tests cliquet de
test_check_split_reading_cells.pyvia harnais stdlib (pytest absent du conteneur, stub minimal) : 9/9 PASS, y compristest_cliquet_mord_sur_une_lecture_ajoutee(rc=2 end-to-end sur empilement réel — le garde échoue si cassé) ettest_cliquet_base_irresoluble_rend_rc1(fail-loud, pas de quitus muet). - Contrôle positif #17028 rejoué au merge-base
d319c41d:rc=2, 2 carnets regressed, 8 findings —App-2b-GraphColoring-CSharp.ipynbcellules [3, 6, 11, 16, 21] +Search-05-GeneticAlgorithms.ipynb[21, 60, 83]. Chiffre pour chiffre conforme au body. - Wiring :
TRANCHE14blocking=True / needs_base=True / absorbed=True,{base_ref}fourni,--self-testen pre_argv, et invariantGuard.name == job.namevérifié dans le YAML du workflow (« Split-reading ratchet (base vs PR) » — les deux renommés ensemble). - Preuve-vive : check-runs au head —
Split-reading ratchet (base vs PR)success (le garde absorbé a réellement rendu son verdict sur cette PR),Scripts Tests (CPU)success,PR gatesuccess. Le workflow reste dispatch-only, le verdict de PR vient bien du garde absorbé.
Design : le cliquet (pas plancher) est la bonne réponse à l'objection documentée — la dette héritée (grandfathered) ne rougit pas les PR voisines, seul l'AJOUT mord. Les 3 mécanismes anti-faux-positifs (id pool décalé, bandeau sans code exécutable au-dessus, rename via --name-status -M) sont chacun épinglés par un test décisif — j'ai vérifié qu'ils s'exécutent, pas seulement qu'ils existent.
Note mineure (non bloquante) : divergence de chiffres dans les commentaires hérités — le registre cite 91 findings, le workflow 109, le body mesure 272 (après élargissement des bornes par #17134). Le body tranche correctement ; un futur passage de doc pourrait aligner les commentaires, mais aucun de ces chiffres n'est codé en dur dans la logique du cliquet.
Security scan : clean (les 2 matches « secret » sont les commentaires « aucun secret » eux-mêmes). Aucun impact cross-repo.
|
[ADJOINT PREFLIGHT] Evidence (post-closing, ignorée par le gate — humans only)Re-stamp v2 (c.69, ~02:30Z) — Tell c.108 strict après review Hermes APPROVED post-c.67. Le dossier CID 5805768271 (c.67) était périmé : Hermes a posté APPROVED à 2026-09-24T01:31:25Z, ce qui a fait passer reviews 0→1 et surfaces-sha256 a changé. Re-stamp obligatoire. Format strict du --template Tell c.124. Tell c.110 respecté : re-gate rc=0, B.0 OK (0 nit non levé), PR gate SUCCESS (29 SUCCESS / 0 FAILURE sur 30 checks). Tell c.135 fondateur : la cause de la stagnation 11h+ ai-01 n''était PAS vLLM down mais le PR gate parent en DWELL minuteur sur les têtes en souffrance. La racine Tell c.123 + Tell c.135 = où run_id = workflow run (pas check_run.id, pas job.id) et --job limite au job PR gate. Test concluant c.69 sur #16948 run 35938320196 → in_progress attempt 2. — secrétaire |
…s de lecture empilee L'organe split-reading (nouveau cliquet bloquant, #17611) refuse une cellule markdown ajoutee sous une cellule de code qui portait deja sa lecture : les deux cellules §5★-b (tableau des paliers + lecture du crossover) etaient empilees sous le code de §5.7, comme la cellule §5★ qui les precede. Remede prescrit par l'organe lui-meme (« fusionner / reecrire, pas empiler ») : le contenu de §5★-b est fusionne dans la cellule §5★, dont l'id est conserve — c'est une reecriture, pas un ajout. Aucun texte n'est perdu (+3129 caracteres dans la cellule 5★, -2 cellules). Corrige au passage la phrase de §5★ qui affirmait que le scale-up n'etait PAS rapporte dans ce notebook : il l'est desormais, en §5★-b. Modification markdown-only : exemption C.2 (aucune cellule de code touchee, outputs et execution_count inchanges). See #5105
…inoculation (#17724) * feat(training,#5105): palier 32B + graine 7 — crossover de l'inoculation Bras N et Np à 32B (4 graines 0/1/7/42, RTX 3090) : Δ(N-Np) hack_late +0.621 — le bras informé s'abstient (0.240) quand le bras secret ferme le hack (0.860). Graine 7 ajoutée aux six fichiers <=14B (additions pures, graines 0/1/42 inchangées, vérifié par script). Harnais inchangé. Notebook : deux cellules markdown 5*-b après la section 5* (tableau + lecture, régénérés par script, insertion pure 60 lignes). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(notebook,#5105): fusionne la section 5★-b dans la cellule 5★ — pas de lecture empilee L'organe split-reading (nouveau cliquet bloquant, #17611) refuse une cellule markdown ajoutee sous une cellule de code qui portait deja sa lecture : les deux cellules §5★-b (tableau des paliers + lecture du crossover) etaient empilees sous le code de §5.7, comme la cellule §5★ qui les precede. Remede prescrit par l'organe lui-meme (« fusionner / reecrire, pas empiler ») : le contenu de §5★-b est fusionne dans la cellule §5★, dont l'id est conserve — c'est une reecriture, pas un ajout. Aucun texte n'est perdu (+3129 caracteres dans la cellule 5★, -2 cellules). Corrige au passage la phrase de §5★ qui affirmait que le scale-up n'etait PAS rapporte dans ce notebook : il l'est desormais, en §5★-b. Modification markdown-only : exemption C.2 (aucune cellule de code touchee, outputs et execution_count inchanges). See #5105 * fix(notebook,#5105): reconcilie la phrase materiel de ICT-25 avec ses artefacts La cellule 39 et le body declaraient un materiel heterogene (RTX 4090 : N aux paliers 1.5B-14B ; RTX 3090 : Np tous paliers et N @32b). Or les 8/8 JSON committes portent tous gpu = "NVIDIA GeForce RTX 3090" — verifie au head. La phrase etait fausse, pas les artefacts : on corrige la prose (le materiel est homogene, toute la campagne a tourne sur une seule 3090) sans toucher aux mesures. Un JSON est la mesure du run, on ne re-etiquette pas un artefact. Finding bloquant leve (gate #17040, revue Hermes de la branche). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(notebook,#5105): retire le compteur prose « 8 fichiers » (gate #9377) La phrase materiel corrigee au commit precedent disait « les 8 fichiers disent tous RTX 3090 » — un compteur quantitatif en prose, refuse par check_prose_quantitative_claims (les donnees quantitatives sont tenues par le CI, pas par la prose). Forme corrigee : « (NVIDIA GeForce RTX 3090 partout) » — le predicat (materiel homogene) est conserve, la mesure est retiree. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…par sortie (#17843) Le constat ne depend plus de la place de la cellule mais du NOMBRE de lectures rattachees a une meme sortie de code (identifiee par la source de sa cellule de code), compare entre la base et la tete. Une sortie absente de la base est ignoree : sa premiere lecture est le geste prescrit (decision ai-01 c.5836401913). Ce que le compte remplace : les trois discriminants topologiques accumules par #17044 / #17464 / #17747, dont chacun ne mordait qu'une variante du meme geste et dont le dernier avalait une addition REELLE -- a slot de markdown occupe, l'entree etait classee en revision meme quand le compte montait. Ce qui est conserve : les exemptions de revision (id conserve, source identique au meme index, deux markdown au meme index) restent en amont, pour que les deux buckets positionnels -- EXERCISE_READING, READING_BEFORE_CODE -- gardent leur portee exacte, comme la decision le prescrit. Le compte reprend ce qu'elles laissent passer : une addition posee a cote d'une revision. Le releve final ancre le constat sur la cellule que la tete a fait ENTRER sur la sortie (sa source n'y etait pas rattachee en base), puis sur les doublons et revisions deplacees : deux constats de #17062 a la tete c80328a nomment desormais la cellule deplacee, pas la cellule pre-existante. Le verdict du cliquet est le constat lui-meme : `regressed` ne depend plus du compte agrege de paires consecutives, qu'une hausse d'encarts ou de transitions faisait rougir sans qu'aucune sortie ne gagne de lecture. Mesures (docs du body de PR) : 6/6 sites du paquet P02 verts a la tete courante de #17062 (5/6 a la tete historique c80328a, ou GT-10 porte deux constats VRAIS que le parent ne voyait pas) ; self-test 6/6, dont les trois positifs ; suite 101 passed, 1 xfailed (xfail strict pre-existant #17134) ; echantillon #17611 rejoue, 0 nouveau rouge. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…t titre de section ne sont pas des lectures (#17831) * fix(notebook-tools,#17777): carve-out d'organe -- enonce d'exercice et titre de section ne sont pas des lectures Decision ai-01 2026-09-25 (« option a, le carve-out d'organe ») : le cliquet split-reading signalait deux formes canoniques du depot. 1. Enonce d'exercice (`## Exercice N`) adjacent a son stub : sans carve-out il tombe dans READING_BEFORE_CODE (il precede son propre stub) ou dans EXERCISE_READING (il suit le stub precedent quand les paires enonce|stub s'enchainent). Mesure sur la tete de #17777 : 11 findings sur 3 carnets, tous des enonces. Replier les enonces en commentaires `#` degraderait la lecture pour satisfaire l'organe -- c'est l'option ecartee. Garde-fous : le carve-out ne couvre PAS une interpretation deguisee sous un titre d'exercice (en-tete d'interpretation dissimule dans le corps, ou citation d'une sortie). 2. Titre de section (`## 2. Tests statistiques`, `## Conclusion`, meme suivi de paragraphes) : il n'est pas une « lecture deja presente », donc `already_had_md_after` ne le compte plus. Un code suivi d'un seul titre de section n'a pas encore de lecture -- en ajouter une est le geste prescrit par le mandat, pas un doublonnage. Mesure fondatrice : cellules 7 et 13 de Oversight-Scaling-Laws-Statistics. Le discriminant est le TITRE, pas la longueur du corps (la cellule 13 porte trois paragraphes de prose). Controles (decision, 3 exiges + garde-fous) : positif #17777 (11 -> 0, mesure firsthand) ; negatifs qui restent rouges -- deux lectures reelles empilees ; interpretation deguisee sous titre d'exercice (x2 topologies). Garde-fous du volet 2 : une vraie lecture en base compte toujours, et un paragraphe non titre aussi (signature de la campagne #13410). Contre-epreuve de mutation : neutraliser chaque volet fait rougir son test. Preuves : suite de l'organe 99 passed / 1 xfailed (borne connue #17134) ; self-test cliquet 5/5 ; cliquet sur la tete de #17777 (93ac0e5) 0 en regression ; fast-lane 76 passed ; ruff check sans erreur nouvelle (16 = main). See #17777 Co-Authored-By: Claude Code <noreply@anthropic.com> * fix(ci,#17044): cliquet split-reading -- le SECOND_READING se compte par sortie (#17843) Le constat ne depend plus de la place de la cellule mais du NOMBRE de lectures rattachees a une meme sortie de code (identifiee par la source de sa cellule de code), compare entre la base et la tete. Une sortie absente de la base est ignoree : sa premiere lecture est le geste prescrit (decision ai-01 c.5836401913). Ce que le compte remplace : les trois discriminants topologiques accumules par #17044 / #17464 / #17747, dont chacun ne mordait qu'une variante du meme geste et dont le dernier avalait une addition REELLE -- a slot de markdown occupe, l'entree etait classee en revision meme quand le compte montait. Ce qui est conserve : les exemptions de revision (id conserve, source identique au meme index, deux markdown au meme index) restent en amont, pour que les deux buckets positionnels -- EXERCISE_READING, READING_BEFORE_CODE -- gardent leur portee exacte, comme la decision le prescrit. Le compte reprend ce qu'elles laissent passer : une addition posee a cote d'une revision. Le releve final ancre le constat sur la cellule que la tete a fait ENTRER sur la sortie (sa source n'y etait pas rattachee en base), puis sur les doublons et revisions deplacees : deux constats de #17062 a la tete c80328a nomment desormais la cellule deplacee, pas la cellule pre-existante. Le verdict du cliquet est le constat lui-meme : `regressed` ne depend plus du compte agrege de paires consecutives, qu'une hausse d'encarts ou de transitions faisait rougir sans qu'aucune sortie ne gagne de lecture. Mesures (docs du body de PR) : 6/6 sites du paquet P02 verts a la tete courante de #17062 (5/6 a la tete historique c80328a, ou GT-10 porte deux constats VRAIS que le parent ne voyait pas) ; self-test 6/6, dont les trois positifs ; suite 101 passed, 1 xfailed (xfail strict pre-existant #17134) ; echantillon #17611 rejoue, 0 nouveau rouge. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com>
Grain: MED/guard -- lane myia-po-2027:CoursIA -- prev: DEEP/qc #17609
Promotion du garde split-reading advisory -> cliquet bloquant (#17044). L'organe
existait sur main, testé, débranché ; la prose du STOP (#13410, 2026-09-20) n'avait pas
tenu 42 minutes. Cette PR le câble en ratchet : rouge seulement si la PR augmente ce
que l'organe voit sur un carnet qu'elle touche -- la dette héritée reste grandfathered.
See #17044
Critères d'acceptation de #17044, un à un
rc=0, le carnet est nommé sur stderr (ERREUR lecture <path>+ rappel- Corrompu.ipynb), le scan continue. Le carnetBTC-ML-Researcher/research.ipynbcité par l'issue n'est plus sur main (git cat-file -e origin/main:...-> absent) : le contrôle est rejoué avec un carnet corrompu équivalent. Le marqueur livré par #17077 estERREUR lecture/NON recensés, pas le littéralSKIPPED-- substance identique (nommé + jamais de rc non nul), tests existants épinglés.TRANCHE14dansfast_lane_registry.py, modèlecheck_source_collapse.py:pre_argv --self-test,argv --base-ref {base_ref} --head HEAD --json --fail-on-findings,needs_base=True,absorbed=True.Guard.name==job.namedu workflow (invariantcheck_absorbed_check_run_identity), les deux renommés ensemble.regressed = lecture AJOUTÉE (mode diff) OU len(detect(head)) > len(detect(base))sur les carnets touchés par la PR seulement. Contrôle :test_cliquet_ne_rougit_pas_la_dette_heritee(une cascade intacte reste verte, la PR ne touche que le code). La dette mesurée surorigin/mainest aujourd'hui de 272 findings (254 generic_pair + 18 separated_by_code) -- l'issue cite 91, mesuré avant que #17134 n'élargisse les bornes du détecteur ; les 272 restent grandfathered.origin/main->refs/remotes/pr/17028, merge-based319c41d) :rc=2, 2 carnets en régression, 8 findings --App-2b-GraphColoring-CSharp.ipynbcellules [3, 6, 11, 16, 21] etSearch-05-GeneticAlgorithms.ipynbcellules [21, 60, 83]. Les cellules de ces deux carnets sont sans id (le critère demande notebook + id de cellule ; l'identité disponible est l'index -- absence d'ids documentée, c'est elle qui motive le signal (c) ci-dessous).blocking=True(registre) +test_tranche14_split_reading_guard_is_wiredépingle le blocage, le self-test en pré-contrôle, et l'absence des formes advisory (iterates_paths,warn_rc,{changed_paths}).Quatre mécanismes de faux positif mesurés, corrigés, et épingleés
Avant correctif, le cliquet rougissait 3/11 PR notebook mergees. Chaque correctif est
décisif par mutation (le retirer rallume le rouge du test qui l'épingle), et le coût
sur le contrôle positif est mesuré :
décale les index ; le discriminant exigeait la même position. Correctif : l'id est
reconnu où qu'il soit en base, consommé une fois (borne les ids dupliqués).
Sans ce signal, le balayage re-rougit fix(notebooks,#17066): Lab12b/Lab12c — fusion des paires de lectures, markdown seul #17564 (mesuré).
amont n'a ni sortie ni execution_count n'est pas une lecture : il n'y a rien à lire.
Correctif : filtre
_reads_code_abovesur le bucket SECOND_READING après md.git diff --name-status -Mrend l'ANCIEN chemin ; lire la base aunouveau chemin rend
Noneet fait passer tout le carnet renommé pour un ajout.merge-base,
### Interpretation : PyGAD sur Rastrigindevenait### Lecture** : PyGAD minimise...au même slot : une révision (le gesteprescrit), pas un empilement. Correctif : signal topologique (même position, les deux
cellules sont des lectures). Le contrôle positif passe de 10 à 8 findings, tous des
empilements réels -- les 2 retirés étaient des faux positifs.
Le test pré-existant
test_diff_signale_reecriture_avec_nouveau_contenuexigeait qu'unerévision en place soit signalée : sous un détecteur advisory c'était de l'attention
sans conséquence ; sous un cliquet bloquant c'est punir le remède. Il devient
test_diff_exempte_reecriture_en_place_d_une_lecture, avec le raisonnement et la mesuredans le docstring. Aucun test de la suite #16786 (conservation verbatim) n'est touché.
Contrôle des faux négatifs (un détecteur se valide par ce qu'il rate)
Rejeu de #17028 avec les correctifs neutralisés : 10 findings avant, 8 après, et les
2 différences sont exactement les 2 révisions identifiées ci-dessus (inspection au
merge-base). Aucun empilement réel n'a été perdu. Contrôle positif canonique
check_17464_positive_control.py: 26 + 16, PASS, intacts.Validation
pytest scripts/tests/test_check_split_reading_cells.py scripts/tests/test_fast_lane.py:164 passed, 1 xfailed (8 tests cliquet ajoutés).
--self-test: 5/5 (les fixtures portent maintenantexecution_count/outputs--sans elles les contrôles positifs étaient vacues : une lecture sans sortie ne lit rien).
check_self_hosted_runner_policyrc=0,check_absorbed_check_run_identityrc=0(16 gardes),
check_unique_check_run_namesrc=0.check_17464_positive_control.pyPASS (26 + 16, 3 buckets exprimés).Bornes connues, déclarées
detect()(paire sous code nonexécuté) : non observé sur les 11 PR du balayage, non corrigé sans mesure qui l'exige.
(signal 4) : c'est une révision par définition ; le bras « compte » rattrape un empilement
réel qui accompagnerait ce geste.
pas traités ici, PRs étudiantes hors périmètre (règle student-pr-reviews).
🤖 Generated with Claude Code