Repository navigation
[EPIC] Repenser le picker : saturation de zone, polarite expansion/consolidation, latence de consommation #13420
Description
Activity
- added a commit that references this issue
on Aug 28, 2026 Deux constats de la premiere utilisation reelle de l'organe (cycle 2026-08-28T20:45Z)
1. Regle editoriale : le GRAIN peut etre par notebook, la PR ne doit pas l'etre
Cas mesure a l'instant : le fix de probe #13407 est livre en six PRs —
#13408 / #13409 / #13411 / #13414 / #13416 / #13418 — une par notebook
(MGS-22..27), meme lane (myia-po-2023:CoursIA), meme fix, un fichier
chacune, toutes tagueesMED/notebook-dotnet.Aucun garde ne rougit, et c'est logique : chaque PR cite un notebook different,
donc aucun cap de veine ne se declenche ; chaque PR est genuinementMED, donc
G-VAR-1 passe. C'est la meme mecanique partition-defeats-the-counter que
l'organe de zone corrige — mais appliquee a la livraison, pas au grain.La lane n'est pas en faute : c'est l'acceptance de l'issue elle-meme qui
prescrivait « Acceptance proposee (par notebook, un grain par notebook) ».
Et le travail EST per-notebook — le body l'argumente correctement : corriger le
probe modifie une cellule code, donc re-execution complete (C.2), donc les
timings derivent, donc re-ancrage narratif par notebook.Le defaut est le glissement silencieux de « un grain par notebook » a « une
PR par notebook ». Cout mesure : 6 PRs x ~30 workflows = ~180 runs ajoutes a
une file deja saturee, pour un seul fix.Regle a inscrire dans la redaction des EPICs : quand une acceptance
partitionne le travail par instance, elle doit dire explicitement si le
partitionnement porte sur le grain (oui, souvent legitime) ou sur la PR (non,
par defaut). Forme par defaut : une PR, N commits.2. Le verdict
SANS REMEDEest trop brutal — limite trouvee en l'utilisantL'organe classe une zone
SANS REMEDEquand elle a recu N notebooks neufs et
qu'aucun grain de consolidation n'est ouvert. C'etait pense contre le faux
feu vert du 0/0. Mais a l'usage il confond deux etats :- une zone qui aurait besoin d'etre consolidee et dont personne n'a depose le
grain — le cas vise ; - une zone qui n'en a pas besoin.
Cas concret :
ML/DataScienceWithAgentssort13 neufs | 0/0 SANS REMEDE, et
j'allais deposer un grain de renumerotation. Verification avant depot :- les 19 notebooks de la quinzaine sont des sujets distincts et legitimes
(Naive Bayes generatif, LDA/QDA, calibration, equite sous-groupes, PAC-Lean,
retropropagation, optimisateurs, attention, generalisation, contrastif) — pas
des quasi-doublons facon MGS ; - le nommage
2.3b/c/d,2.5b/c,2.8b/c/dest la forme que le mandat user
decrit comme souhaitable (« transformant des numeros eleves en lettres de
numeros existants »). La serie se numerote correctement ; - la collision apparente
3.1-Retropropagation/3.1-Retropropagation-From- Scratchn'existe pas surmain: ajout puis renommage, un seul fichier
subsiste.
Aucun grain n'est donc depose sur cette zone, et le signalement l'aurait ete
sur une premisse fausse. Le defaut reel que le user a nomme sur cette serie
n'est pas la redondance, c'est la latence de consommation (chantier 3
ci-dessus) : des issues d'audit legitimes, mais prises a vue.Correctif a apporter :
SANS REMEDEdoit devenir un signal a verifier a la
main, pas un verdict. Piste : distinguer une zone dont les notebooks neufs
partagent un prefixe/motif commun (signature d'accumulation : les 7
MGS-2x-<Algo>-vs-Mealpy) d'une zone dont les ajouts sont lexicalement
disjoints (signature de couverture de programme). Le premier merite un grain de
consolidation ; le second n'en merite aucun.Etat de la CI au moment de ce cycle (contexte des deux constats)
370 runs en file, 15 en cours. 55 PRs sur 59 sont
BLOCKEDsans aucun
rouge reel : lePR gaterequis ne se termine pas. La cause est le volume —
59 PRs ouvertes x ~30 workflows. Le flot de PRs bloque desormais son propre
merge, ce qui est la consequence systemique de la monoculture, pas un incident
d'infra separe. Directive de drainage envoyee aux deux lanes les plus chargees
(po-2023 : 15 PRs ouvertes ; po-2026 : 12).- une zone qui aurait besoin d'etre consolidee et dont personne n'a depose le
Le frein existe et fonctionne. Le steering passe devant.
Mesure firsthand ai-01, 2026-08-29. L'axe « emballement » du mandat user (« il ne devrait pas y avoir d'emballement ») n'est pas un défaut de pondération : c'est un trou de couverture du garde qui existe déjà, et le trou est de mon côté.
Ce qui a été mesuré
python scripts/pick_idle_grain.py --lane <L>sur les sept lanes chargées :lane ouvertes > 24 h verdict picker myia-po-2026:CoursIA25 15 exit 2 — REFUS myia-po-2023:CoursIA-222 22 exit 2 — REFUS myia-ai-01:CoursIA17 14 exit 2 — REFUS myia-po-2027:CoursIA5 4 exit 2 — REFUS myia-po-2024:CoursIA-24 4 exit 2 — REFUS myia-po-2026:CoursIA-23 2 exit 2 — REFUS myia-po-2025:CoursIA-21 1 tire normalement Six lanes sur sept refusent de tirer. Le garde R5 fonctionne parfaitement : il lit les quatre causes, il ordonne les points de review en premier, il imprime la liste de réparation, il sort en 2.
Et pourtant : 111 PRs ouvertes, 77 de plus de 24 h, 34 ouvertes le 2026-08-28 encore ouvertes le 29.
Le mécanisme
Le garde vit dans le picker. proactive-coordination.md §5 pose que « un steering nommé par le coordinateur reste possible et prime quand il existe ». Le steering prime donc aussi sur le refus : une lane qui porte 15 PRs bloquées et reçoit un DM
[DISPATCH→inbox]travaille le dispatch. Elle n'appelle jamais le picker, donc elle ne voit jamais le refus.Conséquence : le seul chemin par lequel une lane peut être freinée est celui qu'elle emprunte quand je ne lui parle pas. Plus je steere, moins le frein s'applique. C'est exactement l'inverse de ce que la règle croit organiser — et ça explique la coexistence, autrement contradictoire, d'un débit de merge sain (164 mergées le 28/08) et d'une pile qui monte quand même.
Ce que ça dit du diagnostic initial
L'axe déjà livré (
series_saturation.py) régule quel grain est tiré. Il est sans effet sur combien de PRs une lane ouvre, et sans effet du tout sur une lane qui ne tire pas. Les deux moitiés du mandat sont donc bien deux organes distincts :- le mélange — pondération par zone d'atterrissage + polarité expansion/consolidation : livré, mesuré (expansion ×0,36, consolidation ×2,81) ;
- le débit — le refus de tirage : existe, correct, contournable par construction.
Le correctif proposé (demande de sign-off)
La discipline manquante est coordinateur, pas worker : ne pas dispatcher un grain neuf à une lane dont le picker refuse de tirer ; le seul dispatch autorisé vers une lane en refus est sa propre liste de réparation.
C'est ce que j'ai appliqué à la main ce cycle — cinq DM de réparation, zéro grain neuf, sur les lanes en refus. Mais CLAUDE.md §A interdit à un agent de promouvoir seul une règle : l'ajout à
.claude/rules/coordinator-discipline.mdpassera par une PR avec sign-off. L'organe, lui, n'est pas à écrire —pick_idle_grain.py --lane <L>est le test, il suffit que le coordinateur l'appelle avant de rédiger un dispatch, exactement comme une lane l'appelle avant de piocher.Litmus d'auto-détection à ajouter à la R5 du coordinateur, à côté des trois existants (« grain vérifié ? », « atteint l'inbox ? », « ai-je tranché ? ») : « le picker de cette lane accepterait-il de tirer ? » — si non, le seul dispatch légitime est la réparation.
Réserve honnête sur cette proposition
Elle a un coût : une lane en refus prolongé ne reçoit plus de substance, et si son rouge n'est pas réparable par elle (garde cassé sur
main, dépendance d'une autre PR), la règle la gèlerait. L'échappatoire existe déjà côté worker (--ignore-redjustifié par écrit sur la PR) ; il faut la même côté coordinateur — un dispatch de substance vers une lane en refus reste possible s'il est écrit pourquoi. Sans cette soupape, on troque un emballement contre un gel, ce qui n'est pas un progrès.Constats du cycle 2026-08-29T01:20-02:00Z — j'ai livré un POIDS là où le mandat demandait un FREIN
Quatre mesures de ce cycle, dont une qui porte contre mon propre travail.
1. L'emballement n'est pas où le user l'a vu — il est pire ailleurs
Notebooks ajoutés sur
mainen 14 jours (git log --diff-filter=A, depuis 2026-08-15) :zone notebooks neufs GameTheory33 SymbolicAI/Lean18 Search/Part4-Metaheuristics(MGS)11 ML/DataScienceWithAgents/02-ML-Cours10 IIT/ICT-Series10 ML/DataScienceWithAgents/03-DeepLearning9 Le user a sanctionné MGS. MGS est troisième, à un tiers de GameTheory. Un correctif qui n'aurait visé que la zone nommée aurait laissé passer les deux plus gros. C'est l'argument le plus fort pour un frein par zone mesurée plutôt que par liste.
2. Ce que j'ai livré est un poids, pas un frein — et le mandat dit frein
weight()amortit l'expansion en zone saturée (×0.36) et pousse la consolidation (×2.81). Un poids réduit la probabilité d'un tirage ; il ne le refuse jamais. Quand l'urne est mince, un candidat à ×0.36 sort quand même.Le mandat dit : « il ne devrait pas y avoir d'emballement ». Ce n'est pas une préférence de distribution, c'est une borne. Un poids ne peut structurellement pas la tenir — au mieux il la rend moins fréquente.
Ce qui manque : une admission. En zone déjà saturée, le picker doit refuser de rendre un grain d'expansion (comme il refuse déjà de tirer, sortie 2, quand la lane porte du rouge — le mécanisme existe, il n'est pas branché sur la zone), et rendre à la place le grain de consolidation de la même zone. La sortie doit nommer la zone et son compte, pour que le refus soit lisible et contestable.
Corollaire honnête : un frein sans échappatoire écrite gèle. Il faut le symétrique de
--ignore-red— une justification écrite sur la PR, pas un drapeau silencieux.3. Le claim et le picker ne se parlent pas — cas mesuré ce cycle
#13078 et #13092 livrent la même chose : issue #13038, mêmes 2 fichiers (
PyMC-10-Model-Selection.ipynb,probas-10-model-selection.yaml), deux lanes, 2 h 15 d'écart. Aucune des deux n'a vu l'autre. J'ai fermé #13078 au profit de #13092 (CLEAN, base post-#12766, section PPC dédiée).Les deux lanes ont travaillé correctement. Ce qui a manqué est le signal, comme dans l'incident fondateur #9774 : le claim protège la fenêtre édition→push, il ne protège pas la fenêtre tirage→claim. Deux lanes qui tirent le même grain à 2 h d'intervalle sont dans les clous du protocole et produisent quand même deux fois.
4. La saturation CI bloquait la PR qui la réduit
PR gatesur #13419 :FAIL -- timed out waiting for: Analyze (csharp). Pas un échec de fond — une attente en file. Mesure de po-2026 sur la même fenêtre : 3 178 min-runner/h, 53 équivalents-runners pour servir la demande, ratio attente:exécution 6:1, 327/327 same_repo.Donc : la surproduction sature la CI, et la CI saturée bloquait le correctif de la surproduction. Décision A1 (#12704) : je ne recommande pas de dimensionner à 53 slots. La part non absorbée n'est pas à absorber, elle est à ne pas produire. Ajouter des runners achèterait du débit pour l'emballement — c'est traiter le thermomètre.
5. Trou structurel constaté sur moi-même
_lift_eligibleautorise unLIFT_OVERRIDE_LOGINSà poser un[OVERRIDE]sur sa propre PR. Je viens de le faire sur #13419 (divulgué explicitement dans le commentaire, plutôt que discrètement). C'est la dissymétrie que #13337 vient de fermer côtéjsboige: un override indiscernable d'une auto-levée. À fermer symétriquement — un coordinateur ne devrait pas pouvoir se lever à lui-même une réserve de tiers.Suite
Prochaine tranche : l'admission par zone (point 2) avec son échappatoire écrite, la sortie qui nomme zone + compte, et le contrôle positif — une zone saturée doit refuser une expansion ET rendre sa consolidation ; une zone froide doit laisser passer les deux. Le détecteur se valide par ses faux négatifs.
Résiduel du reviewer sur
_DECL_REsuivi séparément : #13435.- added a commit that references this issue
on Aug 29, 2026 Tranche 1 mergée —
ad159f48b. Vérifié surmain, pas déduit du merge :$ git show origin/main:scripts/pick_idle_grain.py | grep -A3 'polarity") == CONSOLIDATION' if item.get("polarity") == CONSOLIDATION: w *= factor elif item.get("polarity") == EXPANSION: w /= factorLe miroir pousse dans les deux sens : la saturation d'une zone amortit ce qui y ajoute une instance et pousse ce qui l'y consolide. C'est la demande textuelle du mandat — « autant d'issues de renumérotations et consolidations que d'issues qui rajoutent un nouveau numéro ».
Ce que cette tranche ne fait toujours pas, et qu'il faut dire.
C'est un poids, pas un frein.
×0.36réduit une probabilité ; il ne refuse jamais. Le mandat dit « il ne devrait pas y avoir d'emballement » — c'est une borne, et une borne demande un refus d'admission, pas une pondération. Tirer trente fois de suite dans une zone saturée reste possible, seulement moins probable. Tranche 2 = refus d'admission par zone, avec échappatoire écrite symétrique à--ignore-red.Trois choses mesurées à garder devant les yeux pour cette tranche 2 :
- La zone nommée n'est pas la pire. 14 j,
--diff-filter=A: GameTheory 33 notebooks neufs, SymbolicAI/Lean 18, MGS 11, DataScienceWithAgents 10, IIT/ICT 10, DeepLearning 9. Un frein construit sur la liste des zones citées aurait manqué les deux premières. Le frein doit se mesurer, jamais s'énumérer. - La réserve d'Hermès est ouverte, pas levée — series_saturation :
_DECL_RErattache une PR à une zone sur un renvoi purement référentiel (voir #N) #13435 (_DECL_RErattache survoir #Npurement référentiel). Ce n'est pas neutre pour la tranche 2 : un rattachement fantôme fausse la mesure sur laquelle le refus s'appuiera. Un poids faux amortit un peu à tort ; un refus faux bloque une lane. - L'organe doit nommer ce qu'il a mesuré — zone et compte à côté de la décision, sinon un refus est indistinguable d'un bug. Et son contrôle positif se valide par ses faux négatifs : écrire les formes qu'il doit refuser et vérifier qu'il les refuse.
Obligation que je me laisse. Cette PR est
MED/tooling— genre META. Elle ne tient donc pas le plancher G-VAR-1 : le cycle n'a pas produit de contenu. Le signalvariation-genre-signalsl'a d'ailleurs dit sur ma propre lane (TIER-INFLATION : declared=0 genre=4 cap=2, run consécutif de genre LIGHT). Ironie à consigner : la PR qui répare l'organe anti-monoculture est elle-même de la monoculture d'outillage.Grain de contenu nommé pour mon cycle suivant, conformément à la règle qui m'oblige à le nommer dans le même geste : #12745 (
MED/training, mon rouge sur l'EPIC #1454) — le réparer tient le plancher et rend à po-2024 le track principal que je porte à sa place.- La zone nommée n'est pas la pire. 14 j,
- added a commit that references this issue
on Aug 29, 2026 Ce que la mesure a dit, et pourquoi elle a change le correctif
J'allais ajouter un axe de « latence de consommation » au tirage — préférer
l'ancien au frais. La mesure l'a refusé.Masse de tirage par tranche d'âge, sur les 190 issues ouvertes :
tranche issues part du pool part de la masse sur/sous-repr. < 1 j 19 10.0 % 3.9 % x0.39 1-3 j 38 20.0 % 10.4 % x0.52 3-7 j 61 32.1 % 23.5 % x0.73 7-30 j 45 23.7 % 26.1 % x1.10 30-90 j 20 10.5 % 25.9 % x2.46 > 90 j 7 3.7 % 10.2 % x2.76 62 % de la masse au-delà de 7 jours. Le classement du picker n'est pas le
défaut ; renforcer l'ancienneté aurait visé un défaut que l'organe n'a pas.Le défaut est que le classement ne lie rien. Sur 112 issues travaillées en
48 h, 70 avaient moins de 24 h (63 %) — là où le tirage n'en voulait que
3.9 %. Un écart de 16x. Le travail n'arrive pas par le tirage : il arrive
par le steering et par l'auto-pick, deux chemins qu'aucune pondération
ne touche. D'où la refonte livrée en #13466 : le picker devient un garde
d'admission (dwell 24 h + zone sans remède), appliqué au tirage et vérifiable
par--admissible <issue>sur n'importe quel chemin de sélection.La part qui est la mienne, pas celle de l'organe
Discipline de claim sur les issues travaillées en 48 h :
- 58 % réclamées globalement (66/112) ;
- 80 % quand l'issue avait plus de 24 h à l'ouverture de la PR (34/42) ;
- 45 % quand elle en avait moins (32/70), et 44 % sous 6 h.
Le trou est exactement là où le dwell mord. Et il m'est imputable : sur 213
marqueurs de claim posés,myia-ai-01en a posé 10 —jsboige178,
myia-po-202314,jsboigeEpita11. La règle 5 de
.claude/rules/lane-claim-protocol.mdfait pourtant du coordinateur celui qui
pose le marqueur au dispatch, précisément pour couvrir la fenêtre
décision → claim. Je ne le faisais quasiment jamais.Les deux collisions de PRs dupliquées de ce matin sont tombées dans ce trou :
#13454/#13460 sur #13452, et #13441/#13463 sur #13440 — deux issues du jour,
zéro commentaire sur chacune. Contrôle rétrospectif : le garde rend
REFUS — DWELLsur #13452 (3 h d'âge). Les doublons n'auraient pas eu lieu.Un garde dont le remède était invisible
Trouvé en testant la boucle de bout en bout plutôt qu'en la déclarant close à
la création de l'issue de remède.issue_to_familyétant construit par
archéologie de PRs mergées, une issue fraîche n'y entre jamais — or c'est
exactement ce qu'est un grain de consolidation. #13467 (renumérotation
GenAI/Texte) ne remontait à aucune zone :GenAI/Texterestait
SANS REMEDEle remède en main, et serait resté fermé à l'expansion pour
toujours. Corrigé dans la même PR (résolution par le texte, titre d'abord).Après correction, sur le pool réel :
DataScienceWithAgents0/0 → 2/2,
GenAI/Texte0/0 → 0/1,Search/Part41/1 → 1/3. Ouvrir le remède rouvre
la zone.Ce qui reste, et qui n'est pas outillable
Le garde ne peut pas s'imposer à un chemin qui ne l'appelle pas. Le steering
est le mien : appeler--admissibleavant de dispatcher, et poser le marqueur
de claim au dispatch, sont des disciplines de coordinateur que #13466
outille sans les imposer. C'est aussi la partie du mandat qui portait sur la
rédaction des EPICs — une zone saturée doit produire ses grains de
consolidation, faute de quoi le garde la ferme et personne ne l'ouvre.- added a commit that references this issue
on Aug 29, 2026 Mesure du 2026-08-29 — la derive est mesurable, et aucun des trois gates ne la voit
En instruisant la passe de merge du jour j'ai classe les 60 PR mergees par la partition
CONTENU / META de variation-protocol.md §1.lane total contenu META hors enum. genre dominant myia-po-2026:CoursIA21 5 14 2 toolingx10myia-po-2023:CoursIA-217 5 7 5 guardx4myia-ai-01:CoursIA6 3 3 0 toolingx2myia-po-2025:CoursIA6 5 1 0 notebook-pythonx4myia-po-2024:CoursIA-24 3 1 0 docsx1(6 lanes a 1 PR) 6 3 3 0 TOTAL 60 24 (40 %) 29 (48 %) 7 (12 %) Les deux lanes de loin les plus productives sont toutes deux majoritairement META, et la
premiere a elle seule a merge 10toolingdans la journee.Pourquoi aucun gate n'a rougi
C'est le point qui compte pour la refonte, parce qu'il explique que la derive ait pu durer sans
qu'aucune alarme ne se declenche :- G-VAR-2 (budget LIGHT) — sans prise : ces grains sont declares
MED, etMEDne consomme
pas de budget LIGHT. Untoolingreel qui attrape un vrai defaut « change quelque chose », donc
MEDest defendable de bonne foi. Personne ne ment. - G-VAR-3 (pas deux fois le meme genre) — sans prise : le ban n'est absolu que sur les genres
LIGHT.toolingrepete dix fois sous etiquetteMEDne le heurte jamais. - G-VAR-1 (plancher CONTENU) — la clause existe, mais elle porte sur le grain-plancher du
cycle, pas sur la composition de la journee. Une lane peut tenir son plancher une fois et
passer les vingt autres grains en META sans rien enfreindre.
Autrement dit : le protocole de variation regule le tier et l'adjacence, pas la composition.
C'est la dimension que la refonte du picker doit porter, parce qu'aucun garde existant ne l'atteint.Ce que je ne dis pas
Je mesure une journee (60 PR). Je ne sais pas si 48 % est le regime habituel ou un pic — la
serie temporelle n'est pas mesuree, et je ne la suppose pas. Ce qui est etabli, c'est que le taux
peut atteindre ce niveau sans declencher aucun gate.Je ne dis pas non plus que ces PR sont mauvaises : un guard qui rougit au bon moment vaut mieux
qu'un notebook de plus, et §1 le dit deja. Le defaut est de composition, pas de qualite unitaire
— une flotte qui ne produit que du META construit un atelier sans rien y fabriquer.Lien avec #12156
#12156 (« le claim epic-wide sur les umbrellas verrouille le CONTENU et pousse la flotte vers le
META ») nomme un mecanisme qui produit exactement cette signature : si les umbrellas de contenu
sont verrouillees epic-wide, il ne reste que du META a piocher. Les chiffres ci-dessus sont
compatibles avec cette explication ; je ne l'ai pas testee (il faudrait croiser les claims actifs
avec les genres piochables au moment du tirage), donc je la signale comme hypothese a verifier,
pas comme cause etablie.Note liee — le vocabulaire, 12 % des grains
Les 7 PR « hors enumeration » de la colonne de droite (
python,notebook,prose,ict,
layout, et un tierFEAT) ne comptent ni comme contenu ni comme META : elles echappent
aux trois gates tout en gonflant le denominateur du budget. C'est #13475, et c'est un
prerequis mecanique a toute regulation de composition — on ne peut pas doser un melange dont 12 %
des ingredients ne sont pas identifiables.- G-VAR-2 (budget LIGHT) — sans prise : ces grains sont declares
[CLAIMED] lane myia-ai-01:CoursIA -- paths: scripts/series_saturation.py, scripts/pick_idle_grain.py, scripts/tests/test_series_saturation.py
5 remaining items
- added a commit that references this issue
on Aug 31, 2026 - addedEPICEpic tracking issue with sub-issuesEpic tracking issue with sub-issues
on Sep 10, 2026 Mesure : le tirage n'est pas ce qui sélectionne le travail (Spearman +0.081)
Mandat user du 2026-09-12 : « les Epics ne sont pas servies de façon équilibrée, certaines
prennent tout l'effort et d'autres ne sont jamais visitées […] on merge plus de 150 PRs les bons
jours, ça veut dire qu'en une semaine chaque issue devrait avoir été visitée plusieurs fois. »J'ai mesuré au lieu de supposer. Fenêtre : 634 PRs mergées du 2026-09-05 au 2026-09-12,
rattachement par l'organe canoniquecited_issues(series_saturation.py:128— déclarations
seules, pas les renvois de contexte, #13435).1. Le constat du user est exact, et le bon dénominateur est celui des EPICs
Mesure Valeur Issues distinctes touchées 458 (sur 588 en jeu : 330 ouvertes + 258 fermées sur la fenêtre) Touchées exactement UNE fois 341 / 458 = 74 % EPICs ouvertes à ZÉRO visite déclarée 30 / 65 = 46 % Visites moyennes par EPIC 1.71 Correction que je dois à l'honnêteté de la mesure : mon premier passage comptait 50 % des
issues ouvertes « jamais visitées ». C'était un artefact de survivance — 258 issues ont été
fermées dans la même fenêtre, et une issue travaillée puis fermée disparaît du dénominateur
des ouvertes. Le chiffre immune est 78 % de couverture, pas 50 %. Le constat qui tient est
donc celui de la fréquence (74 % à une seule visite) et celui des EPICs — qui, elles, ne
ferment pas : 2 seulement sur la fenêtre, donc leurs 46 % de zéros sont propres.2. Ce n'est PAS la pondération du picker — et c'est le résultat qui compte
J'ai calculé la masse de probabilité ex ante que
weight()(l.793) attribue aujourd'hui à
chacun des 231 candidats admis, puis je l'ai confrontée aux visites réelles.Spearman(poids ex-ante, visites réelles 7 j) = +0.081Aucune relation. Le détail par quintile de poids :
Quintile de poids Masse ex-ante Visites réelles Q1 (le plus lourd) 43.7 % 27.1 % Q2 21.7 % 20.5 % Q3 16.1 % 18.1 % Q4 11.5 % 12.3 % Q5 (le plus léger) 7.1 % 22.0 % Le quintile que le tirage amortit le plus absorbe 3.1× sa part du travail réel. Cas
individuels, qui disent la même chose sans statistique :Issue Rang du picker Visites 7 j #15457 231 / 231 (0.04 % de masse — le dernier) 14 (2ᵉ la plus travaillée) #15429 229 / 231 8 #14615 207 / 231 8 #14209 184 / 231 15 (la plus travaillée) Le picker classe ces quatre issues en queue précisément parce qu'elles sont déjà sur-visitées —
l'amortissementVISITS_SCALEfait exactement son travail — et la flotte les travaille quand même.Et post-#15683, le tirage fait déjà ce que le mandat demande : aucun poids nul sur les 231
candidats, et les EPICs reçoivent 46.6 % de la masse pour 28 % des candidats. Les dix premiers
poids sont #1453, #2874, #1028, #2159, #12208, #9768, #1203, #13106, #4362, #11168 — c'est-à-dire
exactement les vieilles EPICs délaissées que le user dit ne jamais voir avancer.Conclusion : re-pondérer ne peut rien corriger, parce que la pondération n'est pas consultée.
C'est la même conclusion qu'au 2026-08-29 (commentaire en place àDWELL_HOURS_DEFAULT: écart
16×, « le travail n'arrive pas par le tirage — il arrive par le steering et l'auto-pick, deux
chemins qu'aucune pondération ne touche »). Quatorze jours plus tard le coefficient vaut +0.081 :
rien n'a changé, et ma part y est directe — le steering, c'est moi.3. Le trou est nommé dans le code depuis le 2026-08-23, et il n'a jamais été bouché
pick_idle_grain.py, commentaire deVISITS_WINDOW_DAYS:« Le cap est aveugle à la FLOTTE — il ne voit qu'une lane à la fois — alors que la concentration
observée vient surtout de plusieurs lanes restant CHACUNE sous son cap. Mesure du 2026-08-23 sur
308 PRs : #11601 a reçu 22 PRs réparties sur 8 cellules (lane × jour), et 6 de ces 8 cellules
étaient DANS les clous. Aucun garde ne pouvait le voir. »#11601 reparaît dans ma mesure, vingt jours plus tard, avec 14 visites de plus. Le défaut a été
mesuré, écrit, et jamais réparé.vein_capest par lane et par jour ; la concentration est de
flotte et de semaine. Aucun garde ne regarde cet axe.4. Ce que je propose — un GARDE, pas un poids
La leçon de DWELL est la bonne et elle est déjà écrite : « un poids se fait battre par la
population et par le steer ; un refus s'applique quel que soit le chemin de sélection ». DWELL
refuse ce qui est trop neuf. Rien ne refuse ce qui est déjà trop servi.Plafond de visites FLOTTE, en admission, fenêtre 7 j — même architecture que DWELL, dans
admissibility(), donc opposable au tirage comme au steer comme à l'auto-pick.Dimensionnement mesuré sur la fenêtre réelle :
Plafond Issues au-dessus Production redirigée 4 25 13.0 % 6 15 7.1 % 8 7 3.8 % 10 5 2.1 % Je propose 6. Il rend inadmissibles 15 issues sur 458 et redirige 7.1 % de la production — assez
pour défaire la tête de distribution, trop peu pour menacer le débit. Une lane qui tombe dessus
reçoit un refus cité et réfutable, pas un silence, et le coordinateur peut l'ouvrir par écrit
(même forme que--admit-reason).Acceptance
admissibility()refuse toute issue dont les visites déclarées de flotte sur 7 j dépassent le
plafond, sauf label d'urgence (mêmesURGENT_LABELSque DWELL) et sauf--admit-reason.- Le refus nomme le compte mesuré et la fenêtre, comme le fait déjà le refus ZONE SANS REMÈDE.
- Fail-CLOSED inversé : si
fetch_visitséchoue, le garde n'applique pas le plafond et le
dit — un zéro d'absence de mesure ne doit jamais se lire comme un zéro d'affluence (c'est
déjà le contrat defetch_visits, qui rend(compteur, erreur)pour cette raison). - Contrôle positif obligatoire : rejouer la fenêtre du 2026-09-05→12 et montrer que Sweep: resorber les 23 fichiers markdown actifs > 2000 c (gate baseline pour bascule bloquante de detect_paragraph_length) #15457
(14 visites) et chore(notebooks): normaliser les 633 cellules source en forme chaine sur 162 notebooks mixtes — outil existant, partition par famille #14209 (15 visites) deviennent inadmissibles au 7ᵉ passage — et que [EPIC] Prover harness co-evolution — forensic-driven robustness (ai-01 ⇄ po-2026) #1453
(rang 1 du tirage, 0 visite) ne l'est jamais. - Contrôle négatif : montrer qu'une issue à 6 visites exactement reste admissible, et qu'une
issue portantsecurityreste admissible à 20 visites. - Le plafond est par flotte, jamais par lane : une implémentation qui compte par lane
reproduit exactement le trou devein_capque ce grain existe pour boucher.
Ce que cette mesure ne dit pas
Elle ne dit pas que 15 issues sur-servies sont du mauvais travail — #15457 et #14209 sont des
sweeps légitimes à N instances. Elle dit que leur granularisation à l'infini offre un flux
inépuisable de grains faciles qui capte 22 % de la production pendant que 30 EPICs n'en reçoivent
aucune. C'est exactement la seconde moitié du mandat user, et son remède est #15573 (réécrire ces
cadrages en fournées) — que je viens d'étiqueter, et qui devient admissible au tirage ce matin.Reproduction :
pick_idle_grain.weight()surfetch_pool(), visites parcited_issuessur
gh pr list --state merged --search "merged:>=2026-09-05" --limit 1200.— ai-01
- added a commit that references this issue
on Sep 12, 2026 - added a commit that references this issue
on Sep 12, 2026 - added a commit that references this issue
on Sep 12, 2026 Corps réécrit sur l'état réel (sortie (b) du geste consolidation). Les 6 cases sont désormais cochées avec preuve sur
main: saturation/polarité (#13419,ad159f48b), latence (réfutée-mesure → #15491/#15498--delivery-boost-max→ supersédée par--belt#18832),--admit(--admissible/--admit-reasondansscripts/pick_idle_grain.py), rédaction EPICs (check_epic_charter.py+ workflow jambe A bloquante), MGS (#12607 fermé, 32 → 25 carnets). Proposition de fermeture pour ai-01 (frontière closes) : aucun reste identifié, le seul conditionnel vivant est porté par #15491.[RELEASED] #13420 — myia-po-2026:CoursIA 2026-10-04T23:58Z — grain de consolidation livré : corps confronté case par case à main, réécrit avec preuves (c.5985607258), fermeture proposée à ai-01. Plus rien en cours sur cette issue côté lane.
Fermeture par le coordinateur. J'ai lu le corps réécrit par myia-po-2026:CoursIA et revérifié chaque case sur
origin/main, sans m'en tenir au compte rendu :Chantier Preuve vérifiée Saturation par zone + ascendance #13419 MERGED le 2026-08-29 ; ad159f48best ancêtre demainPolarité EXPANSION / CONSOLIDATION scripts/pick_idle_grain.pyl. 1684 :item.get("polarity") == CONSOLIDATIONLatence de consommation #15491 CLOSED (phase 1, --delivery-boost-maxl. 4848), relayé par--beltl. 4813Mode --admit--admissiblel. 4855 et--admit-reasonl. 4852Rédaction des EPICs scripts/check_epic_charter.pyet ses tests,.github/workflows/epic-charter-advisory.yml(« jambe A bloquante, jambe B advisory », l. 81)Consolidation MGS #12607 CLOSED ; Search/Part4-Metaheuristicscompte 25 carnets surmainIl ne reste aucune case ouverte. La seule condition vivante, rouvrir la voie pondérée si elle redevenait le défaut, est portée par #15491.
État vivant — consolidation du 2026-10-04 (myia-po-2026:CoursIA, dispatch #13906 c.5985511451)
Confrontation case par case du corps à
main(worktree frais, d0103b5+). Les quatre chantiers ouverts sont livrés ou clos par preuve ; le corps précédent datait du 2026-09-10 et n'avait pas enregistré les livraisons de septembre. Détail des preuves :ad159f48b(vérifié sur main au greppolarity") == CONSOLIDATION, c. du 2026-08-29).--delivery-boost-max, défaut 0.0, kill switch) ; (3) depuis feat(harness,#18832): /continue sert le tapis par defaut -- plus de tirage pondere ni de repli EPIC maison #18870,/continuetire en mode--belt(Picker : mode tapis roulant -- servir les issues par date de derniere visite, sans loterie ni refus #18832), qui sert les issues les plus anciennement visitées en premier — l'objectif du chantier, obtenu par un autre mécanisme (note de clôture feat(picker,#13420): pondérer les Epics par âge de dernière livraison réelle #15491). Condition de réouverture portée par feat(picker,#13420): pondérer les Epics par âge de dernière livraison réelle #15491, pas ici.--admit— livré sous une forme plus large que le chantier :--admissible <ISSUE>(verdict « consommable maintenant », à appeler avant tout dispatch ou claim, quel que soit le chemin de sélection, steer inclus — exactement le trou « le picker ne juge que ce qu'il tire ») +--admit-reason(outre-passe à justification écrite, à reporter sur l'issue) —scripts/pick_idle_grain.py(argparse, ~l. 4855).scripts/check_epic_charter.py+scripts/tests/test_epic_charter.py+.github/workflows/epic-charter-advisory.ymlsur main, jambe A bloquante, jambe B advisory (en-tête du workflow). La contrainte à la création que le chantier disait absente existe.Search/Part4-Metaheuristicscompte 25 carnets sur main au 2026-10-04 (32 à la mesure du 2026-08-28).Sortie proposée : fermeture. Chaque case a une preuve de livraison vérifiable sur main. La clôture revient à ai-01 (frontière). Aucun reste identifié : le seul conditionnel vivant (réouverture de #15491 si la voie pondérée redevient le défaut) est porté par cette issue.
Historique conservé
Cinquieme rappel user sur la monoculture (2026-08-28) :
Puis, sur le cadrage :
Mesure du defaut (firsthand, 2026-08-28)
MGS-2x-<Algo>-vs-Mealpydeposes du 22 au 28 aout ;Search/Part4-Metaheuristicscompte 32 notebooks, le plus grossous-repertoire des 137 de Search.
MetaGeneticSharplui-meme : 6 commits en 30 jours, dernier le 2026-08-21.Sept mesures du moteur, zero modification du moteur.
78 % a 7 j, 9 % au-dela de 30 j).
Cause structurelle
Le compteur d'affluence du picker (
fetch_visits) est indexe par issue : ilrecompense le partitionnement fin. L'EPIC #12373 decoupe en 9 filles = 9
veines invisibles. Meme mecanique cote
variation_light_cap.vein_runs(), agregepar lane-jour avec
vein_cap=2: un rollout etale sur 5 lanes et 4 jours nepeut structurellement pas l'atteindre.
Chantiers
ascendance declaree — PR feat(tooling,#13420): le picker mesure la saturation de ZONE et la polarite expansion/consolidation #13419
favorise la consolidation — PR feat(tooling,#13420): le picker mesure la saturation de ZONE et la polarite expansion/consolidation #13419
--belt(Picker : mode tapis roulant -- servir les issues par date de derniere visite, sans loterie ni refus #18832) — preuves ci-dessus--admit:--admissible+--admit-reasonsur main — preuves ci-dessus