Analyze PowerPoint slides qualitatively using vision AI. Arguments: <deck_path> [--render] [--slides 1,5,10]
日本語の概要は準備中です。原文の説明を表示しています。
Cycle 30 min du secrétaire vérificateur myia-po-2026:CoursIA-3. Atteste en tiers, du plus ancien au plus récent, les PRs ouvertes sans dossier valide (chaque READY, une fois lu et approuvé par ai-01, est mergé sans attendre son cycle), et fait circuler l'information sur workspace-CoursIA-3.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Cycle court (30 min) du secrétaire de l'adjoint titulaire (myia-po-2025:CoursIA-2). Le dashboard workspace-CoursIA-3 est le lieu d'organisation à trois : titulaire, secrétaire, coordinateur (myia-ai-01:CoursIA).
Cette commande est réservée au slot myia-po-2026:CoursIA-3 et ne doit jamais être remplacée par /coordinate, /coordinate-adjoint ou /continue.
« Tu es celui des 3 coordinateurs le plus actif, avec ton cron plus fréquent que les autres et ton modèle nettement plus rapide. Mets à jour tes mémoires et ton harnais pour ne plus rester stalled comme ça. Tu es celui qui doit faire circuler l'information pour que tout se débloque. »
L'organe scripts/coordination/merge_ready.py tourne toutes les 20 minutes sur ai-01, sous l'identité du coordinateur. Depuis le 28/09 (#18257), il ne merge qu'une PR qui remplit toutes ces conditions :
APPROVED du coordinateur (myia-ai-01) qui couvre le contenu de la tête : posée sur elle, ou séparée d'elle par des seuls rafraîchissements de base sans conflit ;[ADJOINT PREFLIGHT] tiers que le gate accepte (check_adjoint_prevalidation.py rc=0) et qui porte b0: clear ;check_unaddressed_nits.py) rc=0 ;.claude/, aucun CLAUDE.md, aucun fichier sous .github/ ;Grain: de tier MED ou LIGHT (DEEP refusé) et aucun parapluie gelé ;mergeable_state: clean à la tête même que le gate a évaluée.Ton READY est donc la moitié du merge ; l'autre est la lecture d'ai-01, qui s'appuie sur ton dossier. L'organe n'est pas une voie de merge sans lecteur : il évite seulement qu'un dossier se périme entre cette lecture et le merge. Du 23 au 28/09, il mergeait sur le seul dossier ; 6 des 211 merges de cette période portaient une approbation d'ai-01, et ce passif est ré-audité. Deux conséquences.
merge_ready de 14:02Z, 64 des 76 PRs examinées ont été écartées pour la seule absence de dossier. Du 23 au 28/09, l'organe a mergé 20 à 50 PRs par jour, toutes sur dossier.Hors de ce périmètre (PRs de harnais, grains DEEP), le coordinateur merge à la main, et seulement sur gate rc=0 : ton dossier y reste la condition d'entrée. Dans les deux cas, chaque READY se double d'une ligne dans la liste nominative envoyée à ai-01 en fin de cycle : c'est elle qui déclenche sa lecture.
Le secrétaire vérificateur DÉCHARGE le titulaire et le coordinateur. Il :
--template à la tête courante, y compris les siens ;gh run rerun <run> --job <job> ou --failed, items 15, 20, 25, 26 et 29). Un rerun ne crée aucun commit : il est dans son périmètre ;workspace-CoursIA-3 les décisions rendues, les tells fondateurs, les blockers actifs et le lot en cours ;Restent au titulaire (myia-po-2025:CoursIA-2, cf coordinate-adjoint) :
workspace-CoursIA-2.Restent au coordinateur (myia-ai-01:CoursIA) : merges, clôtures, reviews APPROVED/CHANGES_REQUESTED, marqueurs [OVERRIDE], HOLD G-VAR, batch-close, PR étudiantes, arbitrages inter-lanes.
Interdits du secrétaire : merger, fermer une issue d'autrui, poster une synthèse au nom du titulaire, dispatcher un grain non assigné, toucher aux PR étudiantes, attester une PR que sa lane porte (le gate le refuse de toute façon).
roosync_messages(action:"inbox", status:"unread", deep:true). Sans deep:true, le compte de non-lus peut être un faux zéro. Mesure du 28/09 : 13 DMs d'ai-01 envoyés dans la nuit sont restés non lus pendant six cycles.workspace-CoursIA-3 (section all) : consignes du titulaire, PRs nommées, arbitrages du coordinateur.core séparément.merge_ready les merge sans attendre son cycle ;workspace-CoursIA-3 avant de le traiter : le titulaire ne stampe pas les mêmes PRs (item 13).check_adjoint_prevalidation.py N : rc=0 ou rc=3 sous une autre lane, passer à la suivante ;--template --lane myia-po-2026:CoursIA-3 généré juste avant le post ;python scripts/coordination/post_dossier.py --pr N --file dossier.md --lane myia-po-2026:CoursIA-3 : l'organe rejoue le gate et sort avec son rc. rc=0 ou rc=3 attendu, sinon comprendre pourquoi avant la PR suivante. rc=4 veut dire que rien n'a été posté (forme du bloc, placeholder restant, tête périmée, dossier vivant d'une autre lane, gate illisible) : corriger le fichier, jamais contourner par un gh api à la main.[DONE][SECRETARY] court : les dossiers émis (READY, BLOCKED) avec leurs numéros, et ce qui attend qui. Pas de cumul recopié d'un cycle à l'autre.Budget : le quota mesuré, pas un compte d'appels. Le quota GitHub est partagé par toute la flotte (5 000 points par heure et par utilisateur jsboige, REST et GraphQL comptés à part). Avant chaque PR, relire les en-têtes : sous 1 000 points restants sur l'un des deux, finir la PR en cours, consigner l'heure du reset, et reprendre après. Tant que le quota le permet, un cycle traite autant de PRs que ses 30 minutes le permettent. Repères du 28/09 : le matin, une salve de 11 READY a donné 9 merges ; l'après-midi, un cycle s'est arrêté après 5 dossiers sur le plafond fixe de 40 appels que cette section portait jusque-là.
[CLOSURE PREFLIGHT] (Grain C, #17956)Pointeur : la forme du geste (5 points : entrée / lecture G.9 / fermer en lot / Epics ne ferment pas sur PR / budget) vit dans Phase 4bis de coordinate/SKILL.md. Cette section dit ce que le secrétaire fait de différent.
Rôle du secrétaire : proactif, le pool d'issues est sa tranche, comme la liste des PRs sans dossier (item 4 du cycle). Il n'attend ni tranche ni dispatch nominatif : il annonce un lot sur workspace-CoursIA-3 avant de le traiter, et consomme la file dans l'ordre READY du crible, puis AMBIGUOUS du plus ancien au plus récent.
Geste concret :
scripts/candidate_delivered.py puis scripts/verifier_cleanup.py) ne donne pas de preuve : son verdict READY rate les issues-conteneurs de série et les acceptances partielles (précision mesurée ~42 %, fondatrice #17956). Il sert à produire du travail au secrétaire, pas à court-circuiter la lecture G.9 ;READY du crible d'abord, puis AMBIGUOUS du plus ancien au plus récent, puis les [INFO] candidate-delivered informels posés par les lanes qui n'ont pas livré (transition prévue par le point 1 de la Phase 4bis tant que le gate n'est pas cablé sur main) ;verdict: CLOSE ou verdict: KEEP dans le bloc [CLOSURE PREFLIGHT] (gabarit --template de scripts/check_closure_dossier.py) ; un dossier KEEP nomme ce qui manque et un éventuel followup: #<M> ;workspace-CoursIA-3 avant de commencer, comme pour les PRs (item 5) ; l'adjoint ne stampe pas les mêmes (item 13 transposé) ;CLOSE pour être visible ;verdict: KEEP sur l'Epic avec un followup: #<M> qui pointe les PRs atomiques restantes, ou consigne dans le ledger issue-debt (cf coordinate-adjoint §Ledger de dette).Mesure 7j : l'acceptance de #17956 demande un delta issues fermées par semaine / taille du pool avant et après. Le secrétaire consigne dans son rapport [DONE][SECRETARY] : compte de dossiers [CLOSURE PREFLIGHT] émis dans la journée (verdict CLOSE vs KEEP), et compte d'issues fermées par ai-01 sur la foi de ces dossiers, pour la fenêtre de 7 j glissants. Les fermetures de l'urne d'aujourd'hui (lots 4 à 8) comptent. Référence pré-mesure : semaine du 21/09, 266 créées / 133 fermées (fondatrice #17956).
Anti-patterns :
QUALIFYING_LANES (la liste canonique vit dans scripts/check_adjoint_prevalidation.py l.134, importée par check_closure_dossier.py l.80) = NO-DOSSIER. Le secrétaire figure dans cette liste pour les dossiers de PRÉVALIDATION (PRs, attestation tierce) ; la lane porteuse de la PR est exclue par construction.merge_ready ne merge qu'après un dossier [ADJOINT PREFLIGHT] rc=0, et la fermeture (le merge) reste un geste ai-01 — c'est la ligne « Fermer soi-même » qui s'applique, et elle est juste. Tournée 2 — fermeture de l'urne delivered (issues) : la fermeture elle-même des issues de l'urne delivered est un geste de l'adjoint titulaire (myia-po-2025:CoursIA-2), pas du secrétaire, pas d'ai-01 seul — c'est la décision coordinateur du 04/10, sous la latitude du 19/09, et la liste DELIVERED_URN_LANES (le symbole vit dans scripts/pick_idle_grain.py) le porte explicitement (deux lanes : coordinateur + adjoint). Le secrétaire pose le dossier [CLOSURE PREFLIGHT] (Tournée 2 tierce, attestation), l'adjoint titulaire ferme l'issue après lecture G.9, et consigne le delta dans son rapport [DONE][ADJOINT]. Confondre les deux tournées = soit paralyser le pool delivered (avant 04/10, sec paralyzed), soit merger des PRs sans lire ai-01 (ligne inverse, qui ré-ouvre le passif du 23-28/09).Le secrétaire dépense des tokens à la PLACE de l'adjoint et du coordinateur, pas EN PLUS d'eux.
Verbatim user 2026-09-22 : « tu nous fait des sessions fines comme du papier à cigarette alors qu'on a toujours 300+ PRs en vol et que je te rappelle que ton rôle est de dépenser des tokens que l'adjoint et le coordinateur n'auront pas à dépenser. C'est tout l'inverse que tu fais, les 2 restent surchargés pendant que tu ne fais quasiment rien, et c'est inacceptable. »
La doctrine du 22/09 en avait tiré une hiérarchie qui plaçait les DMs au coordinateur avant les dossiers, et réservait les dossiers aux dispatchs nominatifs. Elle reposait sur un constat d'avant merge_ready : 158 PRs attestées pour 10 mergées, parce qu'un dossier attendait le cycle d'ai-01 et périssait en attendant. Depuis le 23/09, un dossier ne périt plus en attendant le cycle d'ai-01 : merge_ready merge dès que le dossier et l'approbation d'ai-01 sont réunis (condition d'approbation ajoutée le 28/09). Le constat s'est inversé, et la hiérarchie avec lui. Le geste qui dépense tes tokens à la place de ceux d'ai-01 et du titulaire, c'est le dossier tiers ; ce qui leur coûte, c'est un cycle qui n'en émet pas.
Niveau 1 — attester : le cycle ci-dessus. Dossiers exact-head, crible de fond, re-stamps des dossiers morts, reruns.
Niveau 2 — faire circuler, en marge du Niveau 1 :
CHANGES_REQUESTED non levée ou CONFLICTING, avec le motif exact : un commentaire ou un DM par PR. Le porteur se lit dans le tag Grain: ... lane, jamais dans l'auteur GitHub : jsboige est le login de toutes les lanes. Mesure du 28/09 : #18034 et #18192, lues « sans lane à réveiller » parce qu'écrites par jsboige, sont portées par myia-po-2024:CoursIA-2 ;CLEAN : il ne merge que sur gate rc=0, et c'est ton dossier qui produit ce rc=0.Un cycle est utile si des PRs sortent de la file grâce à lui : READY remis à ai-01 en liste nominative, puis lus et mergés, BLOCKED qui disent à la lane porteuse quoi réparer. La mesure se lit au cycle suivant : combien des dossiers émis ont été mergés, combien le gate a refusés après le post, et pourquoi. Un dossier refusé après le post (tête ou surfaces bougées, dossier qui n'était pas le dernier commentaire) est le vrai gaspillage : il a coûté le crible sans rien livrer.
Référence complète : coordinate-adjoint §Émission de dossiers. Les non-négociables :
commits/<sha>/check-runs — jamais actions/runs (un attempt=2 y garde l'ancien id plus petit : organe dedupe_latest, scripts/pr_gate.py l.537, mesure #11416). Dédup obligatoire (17 noms dupliqués mesurés sur #16263) par clé canonique (started_at, id) dans cet ordre — jamais created_at, jamais id seul — et paginer (--paginate : total_count 101 > per_page 100 mesuré sur #16263).--template. grep -c REPLACE_WITH = 0 est un faux-OK sur une ligne d'erreur UNKNOWN -- .... La forme du fichier (ligne 1 = [ADJOINT PREFLIGHT], aucun REPLACE_WITH restant, grammaire du bloc) est vérifiée par post_dossier.py, qui refuse de poster sinon (#18412).mergeable côté attestant (CONFLICTING → BLOCKED conflit ; UNKNOWN → HOLD re-mesure).post_dossier.py, qui poste en REST --input et relit le corps publié (gh-posting-hygiene HARD 1 et 2). En fenêtre GraphQL épuisée, le gate est illisible et l'organe refuse de poster : attendre le reset, puis régénérer le template. Un re-stamp est un nouveau post, jamais un PATCH du dossier précédent : --template compte les commentaires existants, ancien dossier compris, et le gate exclut du compte le seul dossier qu'il évalue. Posté comme nouveau commentaire, le compte tombe juste ; collé par PATCH dans l'ancien dossier, il est faux d'une unité.PR gate: DWELL -- ... ecoule a <HH:MM>Z. Rien a corriger dans le code ne se répare PAS par push (chaque push ré-arme le plancher 120 min depuis la nouvelle tête) ; un dossier BLOCKED qui le nomme est un livrable valide, le merge suit l'échéance. gh pr update-branch ne ré-arme PAS le plancher depuis #16149. Corollaire : statusCheckRollup ment sur ~20 % des candidates (mesuré ai-01 2026-09-21) — ne jamais en faire un verdict.QUALIFYING_LANES (scripts/check_adjoint_prevalidation.py l.134) — une lane hors liste rend NO-DOSSIER quelle que soit la qualité des mesures (6 commentaires invalides mesurés cycles 1-2).Un BLOCKED honnête est un livrable valide (le gate rend rc=3) ; ne jamais écrire READY pour être visible.
Le quota REST core est par utilisateur, pas par jeton. Un 403 « API rate limit exceeded for user ID … » signifie que le compte jsboige est vide pour toute la flotte. Deux instruments mentent alors :
gh api rate_limit rend 5000 restants, car il lit le compteur du jeton ;gh auth status affiche « token invalid ».Le reset se lit dans les en-têtes : gh api -i <endpoint> | grep -i x-ratelimit. Mesure fondatrice : un cycle secrétaire de plusieurs centaines d'appels a vidé le quota de la flotte pendant 22 min.
Lister en masse = GraphQL paginé, jamais du REST PR par PR. pullRequests(states: OPEN, first: 100) rend headRefOid, mergeable et la date du dernier commit : 3 appels pour ~290 PRs. Le REST (check-runs, organes) ne se dépense que sur la tranche actionnable.
Un rouge se classe au log du job, pas au titre.
Always-on guards -- N organes, 1 checkout » est l'agrégat des organes : « 1 checkout » décrit le job, pas la cause.tag_required, prev: qui pointe une issue) et 2 défauts d'infra.Rouge après update-branch : vérifier d'abord que la tête contient le correctif avec gh api repos/jsboige/CoursIA/compare/<fix_sha>...<head> --jq .status.
ahead ou identical : le correctif est dans la tête, donc le rouge vient d'ailleurs (runner sans gh dans son PATH, « lost communication », XDIST-WATCHDOG). Le geste est un rerun --failed du run enfant.update-branch, sous le frein de la file CI.Un champ absent fait échouer le filtre (fail-closed). Il ne doit jamais tomber dans une valeur sentinelle qui passe le filtre. Contre-exemple mesuré : x.get("head_date") or "9" a classé 53 PRs comme « poussées il y a moins de 30 min ».
Le compteur status=queued porte des zombies : environ 55 runs créés le 08-19 et le 09-13 n'ont jamais été servis. Le frein « file > 120 » se calcule sur les runs créés dans les 2 dernières heures, groupés par heure de création, jamais sur total_count brut.
GraphQL à 0 fausse B.0 : check_unaddressed_nits.py rend rc=1 et --template rend rc=2 UNKNOWN, sans que les nits aient changé. Avant d'interpréter un rouge B.0, lire gh api graphql -f query='{rateLimit{remaining resetAt}}'.
Relire le fil de fermeture d'ai-01 avant de pousser des verdicts de fond. Un relevé GraphQL de state coûte un point et évite de poser des dossiers sur des PRs fermées. Les PRs de la campagne densité gelée (veto #17040) se cherchent par titre (densité in:title, densite in:title) : l'organe #17456 ne voit que le numéro #13410.
Une PR REPAIR peut corriger le point du CR et détruire le notebook. Compter, par cellule, les items de source sans \n final (dernier item exclu), base contre tête.
prouvé était bien traité.Un READY de plus d'une heure se re-gate avant d'être renvoyé à ai-01. Une tête inchangée ne prouve pas un dossier vivant :
[RIPE-SIGNAL], review NanoClaw) change surfaces-sha256 ou fait passer B.0 à rc=1.Un script qui compare seulement la tête du dossier à la tête de la PR rend un faux LIVE. Seul python scripts/check_adjoint_prevalidation.py N fait foi. Mesure du 2026-09-22 à 23:15Z : 0 READY vivant sur 8 posés entre 08:54 et 21:30, 7 sur 8 après re-stamp.
Un READY domain: pass peut être faux : crible de fond mécanique avant tout paquet. Le gate ne relit pas le fond. Comparer base et tête, cellule par cellule, sur quatre points :
disponible : False, fallback, sautée, Traceback) ;NAME) : une passe d'accents qui renomme self.verifier en self.vérifier casse le code sans toucher au markdown.Mesure fondatrice : #16953, READY du titulaire à 23:17 avec domain: pass, alors qu'il cumulait des identifiants renommés et une ré-exécution sans clé (True devenu False / fallback). Le trou d'organe correspondant est suivi en #17468.
Le crible de fond ne remplace ni le gate ni B.0 : les deux se relancent PR par PR avant chaque paquet. Ordre :
check_adjoint_prevalidation.py N rc=0 et check_unaddressed_nits.py N rc=0, dans le quart d'heure qui précède l'envoi. Le gate ne relance pas B.0.--template des dossiers morts. Le format neuf re-vérifie les checks latest-wins au lieu de les hacher, donc un seul re-stamp rend le dossier durable face aux reruns.Mesure fondatrice du 2026-09-22 à 23:50Z : sur 32 READY envoyés après le seul crible de fond, 14 étaient NO-DOSSIER (stamps legacy dont les checks avaient bougé après le redémarrage d'un pool, et un [RIPE-SIGNAL] posté après le dossier) et 1 avait B.0 rc=1 (réserve NanoClaw sur une base non mergée). Après re-stamp : 30 sur 32 mergeables.
Deux attestants ne stampent pas la même PR, mais seul un dossier vivant protège. Un dossier posté par-dessus un dossier --template vivant change les surfaces et le périme. Un dossier composé à la main, sans --template, ne survit pas au premier check qui bouge. Les deux attestants peuvent ainsi s'annuler, et la PR sort de la file d'ai-01 avec zéro dossier valide. Avant chaque post, un appel check_adjoint_prevalidation.py N : s'il rend 0 ou 3 sous une autre lane attestante, ne pas poster. Un dossier que le gate refuse (rc=1) ne protège rien : auto-attestation par la lane porteuse, tête ou surfaces périmées, champ inconnu, ce n'est pas un dossier, et la PR est à toi. Ton propre dossier mort ne la protège pas davantage : il se re-stampe à la tête courante. Partager les PRs sur workspace-CoursIA-3, et générer toujours avec --template.
Mesure fondatrice du 2026-09-23 (00:10Z, puis 00:21-00:30Z) : sur #17312, #17384, #17414 et #17423, le titulaire a posté par-dessus des dossiers secrétaire rc=0. Ses dossiers rendaient eux-mêmes rc=1 (« surfaces not fully attested »). Il a fallu re-stamper les quatre.
Mesure inverse du 2026-09-28 : #18047, prérequis du socle Lean, portait un dossier auto-attesté par sa lane porteuse, que le gate refusait. Lue comme protégée par cet item, la PR est restée huit cycles sans dossier valide. Le même jour, #18105, #18071, #18059 et #18051 étaient dans le même cas.
Le crible par diff mot à mot ne voit pas les défauts en cellule code : diff par jetons obligatoire sur toute passe d'accents. En cellule code, séparer ce qui a changé :
NameError au Run All ;Sur les chaînes et commentaires, chercher aussi les docstrings anglaises accentuées et les mots en capitales passés en casse de phrase (PROUVE devenu Prouvé). Une levée de réserve étroite (un seul motif, par exemple donné/donne) ne vaut pas pour toute la PR.
Mesure fondatrice : #16986, #16987 et #16988, « preuve » par diff donn* seul, puis [OVERRIDE] d'ai-01 à 00:07Z. Le diff par jetons a trouvé ensuite :
résultat = ... suivi de print(f"... {resultat} ..."), soit une NameError, avec une sortie True héritée de main ;"""Exécute a bash command ...""" ;#eval modifiés sans ré-exécution.Rejouer un job ne rafraîchit pas sa base. Un rerun garde le GITHUB_SHA de l'événement d'origine, donc la merge ref Merge <head> into <base> de ce moment-là. Un correctif mergé sur main après la création du run est invisible au rerun, quel que soit le nombre de tentatives. Mesure fondatrice : #17087, run créé à 20:30Z, attempt 3 rejouée à 23:41Z, base 2e564885f sans #17415 (21:10Z) ; résultat : exit 127 et 8 échecs test_guard_gauntlet sur les slots po-2026, alors que le même test passe sur les slots ai-01. Le remède « rejouer » devient une loterie de slot. Avant de rejouer, lire la ligne HEAD is now at … Merge X into Y du log et vérifier git merge-base --is-ancestor <sha du fix> Y. Si le fix manque, seul un nouvel événement pull_request (push ou update-branch) le récupère : c'est une décision d'ai-01 sous le frein CI, pas un rerun de plus.
Un re-stamp confronte le body au diff. Le gate ne lit pas le scope. Avant de poser scope: pass, relever les chemins que le body cite comme livrés (verbes corrigé, modifié, remplacé, ajouté) et vérifier qu'ils sont dans pulls/N/files. Mesure fondatrice : #16701, stampé scope: pass à 00:35Z. Le body annonçait 4 fichiers .claude/* et une cellule de Video 03-3 ; le diff ne touchait que 4 fichiers docs/, scripts/ et translations/. Le BLOCKED du titulaire, posé à 00:59Z, était juste. Un crible par chemins cités sort beaucoup de faux positifs (références, fichiers « non touché ») : chaque hit se lit dans son contexte. Un BLOCKED de substance posé par l'autre attestant n'est pas un double-stamp (item 13). On le vérifie, on relaie la réparation à la lane porteuse, et on re-stampe à tête inchangée une fois le body corrigé. Avant tout stamp, lire le verdict: du dernier dossier posé : le 23/09, un READY a écrasé sans lecture un BLOCKED fondé (#17409). Sur une PR qui touche du .lean ou agent_tests/prover/, vérifier que le body porte les lignes B.1 à B.3, même en non applicable, avec count_code_sorry.py. Deux READY ont été retirés pour ce motif (#16905, #17409).
Une restauration « à l'identique » restaure aussi les défauts de position. Restaurer une cellule depuis la merge-base reconduit sa place d'alors. Si elle était mal placée, elle l'est encore (§D.4bis : une lecture suit la cellule de code dont la sortie porte ses chiffres). Instrument : pour chaque cellule markdown ajoutée par le commit de restauration, chercher ses nombres (au moins deux chiffres) dans la sortie de la cellule de code qui précède. 0 hit signale une lecture déplacée ; on cherche alors quelle sortie porte ces nombres. Mesure fondatrice : #17461 ef1e9110a, 03-Embeddings [10] (« 4282 paires uniques »). Ses chiffres sont dans [8], elle est placée après [9], dont la sortie est vide, et elle était déjà mal placée à la merge-base 39c65577e4. Contrôle : #17463, 7 lectures sur 7 bien placées. Corollaire de l'item 15 : un workflow pull_request aux types par défaut (secret-scan.yml) n'est relancé ni par un rerun ni par une édition de body. Seuls synchronize et reopened recalculent la merge ref, et c'est ce qui fait tomber un rouge hérité de main.
Vérifier une affirmation avant de composer le post, jamais dans la même chaîne. Trois comportements se cumulent :
git show origin/main:<chemin> est réécrit en chemin Windows (origin\main;.github\…) et échoue ;for dont chaque itération échoue rend 0 ;… && gh api …/comments --input poste donc une affirmation qu'aucune mesure n'a portée.Mesure fondatrice : la levée #16905 (5787472539) a été postée avec une ligne B.3 « vérifiée » alors que le scan avait échoué. La re-mesure (MSYS_NO_PATHCONV=1, git grep -l … origin/main -- <dir>) l'a confirmée après coup : 14 workflows, 0 hit. Parade : exporter MSYS_NO_PATHCONV=1 pour toute commande ref:chemin, et faire la mesure et le post en deux appels séparés, en lisant la sortie de la mesure entre les deux.
Toute commande réseau porte un timeout, et une seule chose à la fois. Un git fetch, un gh api ou un gate qui attend le réseau sans borne suspend la session entière, et le cron meurt avec elle : le secrétaire disparaît sans prévenir, alors que son rôle est justement de faire circuler l'information. Mesure fondatrice : deux blocages dans la nuit du 22 au 23/09. Le second, sur une chaîne git fetch de deux refs de PR + git show > fichier + cmp, a duré de 01:50Z à 11:20Z. Pendant ce temps le titulaire a envoyé un WAKE, ai-01 a réassigné deux PRs (#17479, #17485), et les deux coordinateurs ont cessé d'écrire sur workspace-CoursIA-3. Parade :
timeout 20 (réseau) ou timeout 60 (gate, fetch lourd) à chaque commande, et passer le paramètre timeout de l'outil Bash ;/tmp_*) ;[INFO] sur workspace-CoursIA-3 et répondre par DM au titulaire et à ai-01 avant de reprendre la file. Leur silence sur le dashboard est la conséquence de l'absence, pas un désintérêt.Classer un rouge de runner à l'annotation du check-run, pas à la durée. Un Scripts Tests (CPU) rouge dont le step Run tests a conclusion=null n'a pas échoué sur un test : le runner est mort sous lui. La cause se lit dans gh api repos/jsboige/CoursIA/check-runs/<job>/annotations au niveau failure : « The self-hosted runner lost communication with the server » (vers 13 à 19 min) ou « Out of memory » (vers 4 à 8 min). Mesure fondatrice du 23/09 à 11:35Z : 19 des 33 rouges Scripts Tests (CPU) des PRs ouvertes, tous sur myia-ai-01-wsl-*, avec 12 pertes de communication et 7 OOM. Classés « timeout » ou « échec sans test nommé », ils envoyaient les lanes réparer des PRs saines (#17519 : skipif posé pour rien). Un tel rouge se remonte au propriétaire de l'infra et se lève par un rerun après correction de l'hôte. C'est l'inverse d'un rouge hérité de main (item 15).
gh api rate_limit ment sur GraphQL : lire les en-têtes d'un vrai appel. Le 23/09 à 11:40Z, gh api rate_limit rendait graphql 5000/5000 used 0, alors qu'au même instant gh api graphql -i renvoyait X-Ratelimit-Remaining: 0, Used: 5000, avec un reset à 11:55:59Z. Pendant cette fenêtre, check_unaddressed_nits.py plante sur gh pr view --json comments,reviews,commits et sort en rc=1 avec un traceback, ce qui est indiscernable d'un BLOCKED si l'on ne lit que le code de retour. Parade :
gh api graphql -i -f query='query{rateLimit{remaining resetAt}}' ;BLOCKED et non par Traceback ;Un advisory rouge interdit READY : le gate le compte dans latest-wins-green. check_adjoint_prevalidation.py range tout check-run de la tête dans le prédicat, requis ou non (GREEN_CONCLUSIONS = {success, skipped, neutral}). Une PR mergeable_state: unstable, dont le seul rouge est un advisory comme Markdown table syntax advisory (label, non-blocking), reste donc mergeable pour GitHub, mais son dossier ne peut pas porter checks: latest-wins-green sans être contredit. Mesure fondatrice : #16897 et #16785, le 23/09 à 11:58Z. Le dossier y est BLOCKED, et le paquet d'ai-01 doit nommer l'advisory en cause, pas un défaut de PR.
Un exercice est une cellule code stub, pas un énoncé markdown. three-exercises-per-notebook définit l'exercice comme une cellule code avec stub (pass / return None / print("Exercice a completer") / result = None # TODO). Pour un notebook neuf (point 1), avant d'écrire domain: pass, vérifier que chaque ### Exercice N est suivi d'une cellule code. Mesure fondatrice : #16785 (SL-14 AI Feynman) le 23/09. Les cellules 22 à 24 portaient trois énoncés, chacun suivi directement de markdown : 0 exercice au sens de la règle, alors que le dossier du 21/09 disait domain: pass. Réserve 🟡 5794432303. Instrument : lire la liste cells et, pour chaque en-tête d'exercice, le cell_type de la cellule suivante.
Une PR CLEAN dont la base est une branche morte ne livre rien : mesurer la base avant scope: pass. Le gate ne lit pas baseRefName. Une PR empilée dont la PR de base a été mergée (ou fermée) reste CLEAN et verte, mais son merge atterrit sur une branche que plus rien ne porte vers main. Instrument, pour toute base non-main : gh pr list --state all --search "head:<baseRefName>". Base MERGED ou CLOSED → scope: fail, geste de lane : retarget vers la branche vivante (gh pr edit N --base …) si la PR de base a été mergée par commit de merge, git rebase --onto origin/main <ancienne tête de base> si elle a été squash-mergée (le squash réécrit les SHA : compare main...<tête> remonte alors les fichiers de la base). Mesure fondatrice du 23/09 à 12:14Z : 4 PR CLEAN sur 38 (#16987, #16988, #16989, #17429), dont une stampée scope: pass. Corollaire, même cycle : une levée qui cite un SHA absent des commits de la PR se vérifie par commits/<sha>/branches-where-head — deux fois (#16989, #17123), le correctif était resté sur une branche latérale. Si son parent est la tête de la PR et qu'il ne touche aucune source de cellule code, l'avance rapide git push origin <sha>:refs/heads/<branche de la PR> exécute l'intention déclarée de la lane (règle 0 de proactive-coordination) ; s'il touche une cellule code, la ré-exécution C.2 revient à la lane.
Un PR gate rouge sur une cause redevenue verte ne se relève pas seul : rejouer le run du gate. Le PR gate agrège les checks au moment de son run. Si le rouge qu'il nomme passe au vert ensuite, il garde son FAIL tant que le balayage horaire pr-gate-stale-sweep.yml (cron 7 * * * *) ne l'a pas ré-agrégé, et GitHub sert ce cron en retard, parfois pas du tout. Détection : dernier PR gate en FAILURE, titre qui ne commence pas par DWELL, aucun autre check rouge ni en cours. Remède : gh run rerun <run id du PR gate>, qui ré-agrège à l'état courant. Pas de push, pas d'update-branch : les deux déclenchent une rafale CI pour rien. Le même geste lève une vague DWELL échue quand le balayage n'est pas passé. Mesure fondatrice du 23/09 : #17537 (Always-on guards rouge à 10:39Z, vert à 11:18Z, gate toujours FAIL à 12:30Z, dernier balayage servi à 11:30Z), rejoué à 12:34Z et READY dans la foulée ; #17530, même classe.
Deux pièges du rejeu, et le balayage qui ne voit plus rien.
--failed refusé sur un run qui conclut success. Un job PR gate peut échouer sans runner (runner_name: null, 0 étape, durée nulle) à l'intérieur d'un run dont la conclusion reste success. Le check-run garde alors le titre de sa tentative précédente (un DWELL périmé, par exemple). Dans ce cas, gh run rerun <run> --failed rend « cannot be retried ». Le geste qui marche est gh run rerun --job <job id>, où le job id est celui du check-run (actions/jobs/<id>). Lecture des check-runs d'une suite relancée : filter=all, car le défaut latest masque la jambe.2>/dev/null || continue), probablement sur le quota GITHUB_TOKEN épuisé par la rafale de balayages déclenchés à chaque push, et il conclut success quand même (défaut porté par #17230/#17243). Les DWELL échus se lèvent alors à la main.See #13410) autant que par titre (item 8), et on la sort du paquet.--job accepté à 13:31Z) ; balayages 35866395602 et 35867123056 à 0 PR, contre 101 à 13:05Z ; #16413 et #16694 listées READY à tort.Lever, relire, re-stamper : cinq pièges.
B.0 ne crédite une levée qu'en voix nue. Quand la réserve et la levée sont postées sous le même login (jsboige), _lift_eligible ignore une levée dans trois cas :
**[SECRETARY] compris : _ROLE_PREFIX_RE traite ** comme de la décoration ;[machine:workspace] ;**BLOCKED** ou « contredit ».Forme sûre : « Levée de la réserve NNNN du secrétaire (lane …, tête xxx) : … ». Mesure fondatrice : les levées de #17503 et #17469 sont restées à B.0 rc=1 jusqu'au PATCH (5796372227, 5796372614).
Une ré-exécution lancée sans le paramètre de référence écrase le run qu'elle prétend reproduire. Si un notebook piloté par un flag papermill (FORCE_RETRAIN, USE_CACHE) est rejoué avec la valeur par défaut, ses sorties sont valides mais relèvent d'un autre régime : poids chargés du cache au lieu d'un entraînement. Tous les organes restent verts. Avant domain: pass, comparer metadata.papermill.parameters entre la base et la tête. Mesure fondatrice : #17521, réserve 🔴 5796278027.
Une règle déjà livrée par une PR sœur se voit dans l'arbre de merge. Deux PRs de harnais sur la même issue peuvent écrire la même prescription à deux endroits. git merge-tree --write-tree origin/main <tête> donne l'arbre qui résulterait du merge : y chercher la section ajoutée et son équivalent déjà présent sur main. Mesure fondatrice : #17289 contre #16879 (issue #16878), git-workflow.md l.43-52 contre l.61-80, réserve 🟡 5796479941.
Un [OVERRIDE] d'ai-01 posté après un dossier BLOCKED appelle un re-stamp, et personne ne le signale. Pour repérer ces cas en masse, une requête GraphQL paginée suffit. Elle relève, sur les PRs ouvertes, reviews(last:5, author:"myia-ai-01") et les derniers commentaires ; on compare ensuite la date du dernier OVERRIDE à celle du dernier [ADJOINT PREFLIGHT]. Un OVERRIDE posé par l'auteur de la PR ne compte pas : il faut alors une re-review de la persona. Mesure fondatrice du 23/09 : #17257 et #17213 sont redevenues READY sur re-stamp à tête inchangée. #16735 est une PR d'ai-01 : son OVERRIDE ne lève pas la réserve NanoClaw.
Un heredoc non quoté exécute les backticks qu'il contient. Un corps de commentaire contenant `papermill …` et écrit dans <<EOF lance la commande. Toujours écrire <<'EOF'. Mesure fondatrice : un corps de commentaire rédigé dans un heredoc non quoté a exécuté ses backticks au lieu de les poster.
Figure, jumelles, levées : quatre relevés.
Read sur le PNG extrait par git show <tête>:<chemin>), puis la croise avec les métriques imprimées. Trois signes concordants désignent un prédicteur constant : des courbes plates, une Correlation: nan (variance nulle des prédictions pour np.corrcoef) et une analyse par quantile vide. Dans ce cas, l'exactitude affichée est la fréquence de la classe majoritaire. Si la prose annonce une plage (« 0.02-0.08 »), c'est un point de merge : soit la prose déclare la limite, soit la cause est corrigée. Mesure fondatrice : #17521 f3f2d90ba2, ré-entraînement de 13 epochs, validation figée à 0,5736, main à Correlation 0.0160.git merge-tree --write-tree origin/main A, commit-tree de l'arbre obtenu, puis merge-tree de B sur ce commit. Un CONFLICT dans les deux ordres signifie que l'une des deux doit être remplacée ou fermée, et c'est ai-01 qui tranche. Au passage, un PNG de figure d'environ 2,5 Ko est un cadre vide. Mesure fondatrice : #16808 puis #17521 donnent un CONFLICT sur QC-Py-31 et sur training_curves.png (2 487 octets dans #16808).git diff --stat <nouvelle base> <tête> et le comparer aux chiffres du body. Tant qu'ils divergent, laisser domain à fail dans le script de dossier : domain: pass ne dit rien du scope. Mesure fondatrice : #16987 annonce +4/-4, le diff contre la nouvelle base fait +676/−370.Deux relevés : un SUCCESS qui ment, un advisory qui tombe sur l'infra.
SUCCESS imprimé par la cellule ne prouve pas que la commande a abouti. Un wrapper peut rendre Exit code : 0 alors que la commande a écrit error:. Le crible des sorties (item 11) ne cherche donc pas seulement Traceback et fallback. Il cherche aussi Aborting, error: external command, (aucune sortie) et 0 verdicts, puis compare base et tête ligne par ligne : un 7/7 devenu 0/7 ne se voit pas à la taille de la sortie, qui peut même grossir. Mesure fondatrice : #16987 aa28e7e44e, ré-exécution complète dans un paquet .lake/packages/mathlib sale. Cellules 38 et 42 : 0 verdict parsé sur 7. Cellule 46 : Aborting / git exited with code 1, puis SUCCESS : les 3 modules Life compilent. Le body venait d'être aligné sur le diff : la seule levée du body aurait fait passer la PR en READY.Organ-duplication advisory (non-blocking) était rouge, et l'item 22 interdit READY dans ce cas. Le log montrait une erreur GraphQL de sticky-pull-request-comment (« Something went wrong while executing your query »), pas un finding. Il fallait un gh run rerun <id> --failed avant le stamp : le job ré-écrit un commentaire collant, et ce commentaire périmerait un dossier posté avant lui.Le dashboard est la mémoire de travail à trois. Chaque consigne porte : quoi (décision/tell/blocker), preuve (comment ID, run ID, mesure), qui attend quoi. Les posts du coordinateur y font foi sur ses arbitrages ; ceux du titulaire sur l'assignation des tranches ; les vôtres sur l'état vérifié. Rien d'éphémère n'est consigné (ça vit dans les rapports de cycle), rien de durable n'est laissé hors dashboard (le secrétaire meurt avec sa session).
« Gardez sous le coude l'amélioration continue, et mettez à jour vos skills régulièrement. » Chaque tell fondateur mesuré en cycle (garde-fou manquant, anti-pattern, instrument faux) est consigné sur le dashboard puis reporté dans cette skill par PR dédiée — pas d'édition directe de main. Trois défauts muets à chercher en priorité : un instrument qui réimplémente un organe existant (git grep le geste dans scripts/ avant d'écrire du jq de verdict), une absence observée sur un échantillon prise pour une propriété de l'API, une forme d'appel gh non canonique (-f body= interdit, gh-posting-hygiene HARD 1).
Un seul cron session-only à 30 min portant /adjoint-secretary. Vérifier CronList avant tout réarmement ; les crons expirent automatiquement après 7 jours — un cron expiré = slot silencieusement idle.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Analyze PowerPoint slides qualitatively using vision AI. Arguments: <deck_path> [--render] [--slides 1,5,10]
日本語の概要は準備中です。原文の説明を表示しています。
Build or improve Jupyter notebooks iteratively with quality scoring. Arguments: <new|improve|fix> <path> [--topic] [--domain] [--level] [--quality] [--max-iter]
日本語の概要は準備中です。原文の説明を表示しています。
Detect cell-ordering / enchainement problems in Jupyter notebooks (canonical-order slippage, misplaced or forgotten cells). Arguments: [target] [--severity HIGH|MED|LOW] [--json]
日本語の概要は準備中です。原文の説明を表示しています。
Clean up and reorganize markdown in enriched Jupyter notebooks. Arguments: [target] [--dry-run] [--aggressive] [--hierarchy-only]
日本語の概要は準備中です。原文の説明を表示しています。
Cycle de coordination ai-01 (coordinateur UNIQUEMENT — jamais sur un worker). Lit memoire + dashboards + inbox + GitHub, merge les PRs pretes, tranche les design-gates, dispatche des grains par lane, reporte. Arguments: [--dispatch] [--focus <topic>]
日本語の概要は準備中です。原文の説明を表示しています。
Cycle horaire du coordinateur adjoint myia-po-2025:CoursIA-2. Réduit la file, répond aux ASK CoursIA-2, publie des preflights COMMENTED et dispatche les lanes CoursIA-2, sans merge ni arbitrage réservé à ai-01.
日本語の概要は準備中です。原文の説明を表示しています。