Skip to content
Back to skills

Coordinate

ASecurity

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>]

  • 16 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 20, 2026
educationpythongovueexpressgitapi

Works with

  • terminal
  • cli
  • api

Security analysis

A100/100

Scanned October 5, 2026

npx -y skills add jsboige/CoursIA --skill coordinate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Coordinate?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Coordinate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jsboige-coordinate/badge)](https://www.skillsdirectory.com/skills/jsboige-coordinate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: coordinate
description: 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>]
---

# Skill: Coordinate - Cycle coordinateur ai-01

Cycle de coordination du cluster CoursIA. **Reserve au coordinateur ai-01** : un worker ne lance JAMAIS `/coordinate` (lecon #1502 phantom-merger — le cron worker execute `/continue`). Un worker ne merge pas et ne close pas l'issue d'autrui ; `gh auth switch` est autorise et necessaire (trousseau gh partage entre workspaces — mandat user 2026-08-31) : le switch n'est pas la ligne rouge, le merge/close l'est.

**Target**: `$ARGUMENTS`

## Arguments

- (sans args) : cycle complet (briefing + merges + steers + reporting)
- `--dispatch` : forcer une passe de dispatch explicite vers les lanes idle
- `--focus <topic>` : concentrer le cycle sur un sujet (texte libre : lean, genai, qc, renum, ...)

## Budget de cycle (HARD — mandat user 2026-09-14)

1. **Un cycle tient en 1 h a 1 h 30 de travail entre deux crons**, puis la session se rendort. Verbatim user : « Ca donne entre 1h et 1h30 max de travail entre 2 crons, c'est deja beaucoup je pense, et il ne faudrait pas depasser ca. Sinon c'est un defaut de delegation. »
2. **Decoupe interne des phases — EN ATTENTE DE MESURE.** Le user a recuse une decoupe chiffree posee au jugement : « sur les durees suggerees c'est au doigt mouille, hein, le mieux serait d'etudier ce qui a bien marche debut juillet quand on produisait beaucoup sans pour autant trop lesiner sur la qualite ». La mesure du regime de debut juillet (fenetre 2026-07-01 → 07-14) est deleguee a la lane `myia-ai-01:claudish` (DM `msg-20260914T195758-l93rsb`). **A REMPLACER par la decoupe mesuree — ne pas poser de chiffre au jugement.** Tant que cette mesure n'est pas rendue, aucune duree de phase n'est normative : les trois phases gardent leur ORDRE (grounding → dispatch → travail reel) sans budget chiffre.
3. **Mesurer le temps activement**, pas au ressenti : `date -u` en entree et en sortie de chaque phase ; le total du cycle est annonce dans le rapport de fin.
4. **Un depassement se traite en DELEGUANT**, jamais en rognant le grounding ou le dispatch.
5. **Tout ce qui est delegable EST delegue**, sans arbitrage au cas par cas. Attendre le cron suivant pour recuperer un resultat est gratuit — verbatim : « tu peux tout a fait attendre un cron pour economiser tes tokens, on n'est pas a 4h pres sauf crise a gerer ».
6. **Le contenu appartient au coordinateur adjoint** (`myia-po-2025:CoursIA-2`) : notebooks, series, pedagogie. ai-01 ne garde que les PRs de **CI et de harnais**. Entrer dans le corps d'une PR de contenu est par defaut une faute de budget.
7. **Les taches lourdes** (tests, builds lake, trainings, papermill) se lancent en arriere-plan **AU DEBUT de la phase de travail reel**, pour travailler en foreground pendant leur execution.
8. **Bornes de sondage (recommandées — [#16144](https://github.com/jsboige/CoursIA/issues/16144), [plan du 14/09](https://github.com/jsboige/CoursIA/issues/16144#issuecomment-5663038997), item 1) — le re-sondage d'un etat est un doublon payant.** Mesure fondatrice : 825 `gh pr view` sur 90 PRs en un cycle de 13 h, dont #15917 relue 29 fois en 6 salves pendant des attentes ; 61 % des PRs ouvertes n'ont jamais ete mergees. Deux bornes :
   - **B2 — un etat de PR lu n'est pas re-sonde avant plusieurs minutes, sauf changement d'etat signale** (notification, Monitor arme, `--watch`). La borne vise la **persistance du sondage pendant une attente**, pas la repetition dans un meme tour — la mesure du 14/09 n'a trouve aucun doublon intra-tour.
   - **B3 — ne pas rouvrir une PR dont le blocage est deja connu et date** (DWELL a echeance, reserve non levee, rouge attribue a une lane) : consulter la date une fois, pas le dossier a chaque tour.
   Les bornes B1 et B2-bis du plan d'origine (ne pas re-sonder ce qu'une surveillance couvre deja) ne se re-encodent pas ici : la regle flotte « une condition asynchrone a **un seul observateur** ; ne jamais poller en parallele d'une notification existante » (CLAUDE.md global, chargee dans chaque session) les porte deja.
   **Avertissement porte par le plan lui-meme** : la prose seule a echoue quatre fois le matin du 14/09 (lecons deja ecrites, non recuperees au moment du geste) — l'organe `scripts/check_pr_repoll.py` (item 2 du plan, forme proposee dans [#16144](https://github.com/jsboige/CoursIA/issues/16144)) reste du, decision a ai-01. Ces bornes sont le filet court-terme, pas le correctif.
9. **Lecon version-client (2026-09-12, [#16144](https://github.com/jsboige/CoursIA/issues/16144)) — CC >= 2.1.269 a retire du prompt generique les bornes implicites** (rumination, perimetre, delegation) : trois harnais distincts ont bascule a la meme minute lors du passage 2.1.268 -> 2.1.269 (1 985 -> 4 430, 1 813 -> 3 468, 1 325 -> 2 548 OUT/req en controle same-lane). Le runtime ne les reintroduira pas. **Toute montee de version future du poste client s'audite par paires same-lane avant generalisation** — le 12/09 a bascule quatre lanes d'un coup, sans prevision ni controle.

## Process

Les phases ci-dessous s'executent sous le budget defini par la section `## Budget de cycle` ci-dessus : 1 h a 1 h 30 de travail au total, tout depassement etant un defaut de delegation.

### Phase 1 - Contexte memoire

1. `~/.claude/projects/d--CoursIA/memory/MEMORY.md` — index + quick reference
2. `~/.claude/projects/d--CoursIA/memory/coordinator-durable-state.md` — axes directeurs, bloqueurs user, watches, calendrier
3. Au besoin : [docs/reference/cluster-agents.md](../../../docs/reference/cluster-agents.md) (machines, lanes, GPU), [docs/reference/teaching-context.md](../../../docs/reference/teaching-context.md) (calendrier ecoles)

### Phase 2 - Etat live

0. **Rester courant** : `python scripts/coordination/session_hygiene.py` D'ABORD (exit 1 = au moins un ROUGE), puis `git checkout main && git pull --ff-only` + `git submodule update --init` — le coordinateur travaille sur un main LOCAL a jour, jamais en grepant un working-tree stale ni en pilotant via `origin/*`. **L'organe passe avant le geste parce que le geste peut ECHOUER EN SILENCE** : mesure du 18/09, `git checkout main` refusait depuis des jours (un worktree residuel detenait `main`), l'arbre est reste parke sur une branche de feature, et l'organe B.0 qu'on y lancait avait 437 lignes de moins que celui de `main` — assez pour inverser des verdicts de merge deja publies. `session_hygiene.py` couvre branche parkee (test d'identite de contenu, robuste au squash), `main` pris en otage par un worktree, derive des organes vs `origin/main`, fichier sensible non suivi ET non ignore, inflation de worktrees et stashes. Il **ne peut pas** voir l'inbox, les dashboards, les memoires ni les ledgers : il les rappelle nommement en fin de sortie, a faire a la main.

1. **Dashboards (canal PRINCIPAL) — ENUMERER d'abord, jamais lire une liste apprise par coeur** : `roosync_dashboard(action:"list")`, puis `read` avec `section:"all"` sur **chaque cle dont le workspace declare est pertinent**. Les lanes sont co-egales ; **aucune n'est "le dashboard du coordinateur"**. Une `lane` = machine x workspace : chaque machine avec une lane CoursIA-2 a AUSSI une lane CoursIA, et le trio titulaire/secretaire/coordinateur ajoute `CoursIA-3`. Lire chacune separement pour ne rater aucun ASK/blocker.

   **Pourquoi enumerer, et pas nommer** : une skill qui sait d'avance quoi lire est **structurellement aveugle** a une cle qu'elle n'anticipe pas. Le 2026-09-21, `workspace-CoursIA (2)` — cle forkee par collision de noms Google Drive — portait **23 messages vivants** de po-2026 et po-2027, dont deux PRs debloquees en attente du merge-gate, pendant plusieurs jours sans qu'aucun cycle ne la voie. Une cle a suffixe ` (N)` dont le `workspace` declare **ne porte pas** ce suffixe est une moitie de la meme lane, pas une lane voisine : la lire, et escalader la reparation (`action:"merge"`, cf dashboard `global`).

2. **Inbox DM — drainer et EXTRAIRE, jamais survoler** : `roosync_messages(action:"inbox", status:"unread", deep:true)` — **sans `deep:true` le compte de non-lus est un faux zero**. Deux gestes, dans cet ordre. **(a) Purger les classes qui doublonnent une surface deja lue** — `bulk_mark_read(subject_contains:"Worker Report")` et `bulk_mark_read(subject_contains:"[MENTION] Dashboard")` : sans ca l'arriere se reconstruit a ~8 DM/h et noie le signal utile, qui pese moins de 10 % du volume. **(b) Extraire la liste nommee des PRs deja pre-machees** — marqueurs `[ADJOINT PREFLIGHT]`, `[ADJOINT VERIFIED]`, `[ADJOINT DECISION PACK]`, `preflight exact-head`. Cette liste est une **entree obligatoire de la Phase 3.3** : le pre-machage est produit qu'on le lise ou non ; non consomme, il est paye deux fois.
3. **GitHub** : `gh pr list --state open` (a merger) + le pool **tire, jamais scanne** — `python scripts/pick_idle_grain.py --belt --lane myia-ai-01:CoursIA` (un `gh issue list` nu plafonne a 30, tries par recence : il ne montre que ce que je viens de creer, et c'est ce biais que le steering doit eviter de reproduire).
4. **Cron** : `CronList` — si le job coordinateur a disparu (session-only), le re-armer a la cadence **courante**. Cette cadence est un **etat**, pas une regle : elle ne s'ecrit pas ici (decision user 2026-09-22 — l'etat courant se met a jour dans les memoires et les dashboards, jamais sous git). L'expression a re-armer se lit dans la memoire du coordinateur (`coordinator-handover`, section cron) et sur le dashboard. Ce qui reste durable : une minute off-`:00` (le jitter evite de frapper l'API a la meme seconde que le reste de la flotte), et une cadence unique, PAS de 2e cron ni ScheduleWakeup en plus — un cycle plus long que sa cadence annule deja ses propres declenchements, en empiler un second ne fait qu'ajouter de la conso.

### Phase 3 - Dispatchs, relances, memoire (LES 30 PREMIERES MINUTES)

**Cette phase precede la passe de merge et se ferme avant elle.** L'ordre inverse -- merger d'abord, dispatcher avec ce qui reste -- ne termine jamais : le pool de PRs est non borne et chaque PR ouvre trois surfaces a lire, donc les lanes sont affamees **par construction du cycle**, pas par negligence. Le symptome mesure : un cycle de plus de 4 h pour une cadence de 4 h, passe a rejouer le travail deja fait par l'adjoint et les bots (correction user 2026-09-14).

1. **Sweep unique, trie par anciennete** -- il sert LES DEUX phases, on ne le capture qu'une fois : `gh pr list --state open --limit 200 --json number,title,author,createdAt,mergeStateStatus,headRefOid --jq 'sort_by(.createdAt) | .[] | [.createdAt[0:10],.number,.mergeStateStatus,.title] | @tsv'`. Sans `--limit`, gh plafonne a 30, et sans tri declare il rend par recence. **Pas de champ `reviews`** (payload lourd -- 504). 200 lignes rendues = plafond touche, paginer plutot que croire la liste complete. **Jamais `reviewDecision` comme colonne de triage** (#16926) : sous token COMMENT-only il vaut `null` a perpetuite sur ~82 % du pool, y compris sur les PRs portant un `VERDICT: LGTM` argumente -- le faux compte « 169 sans review » vient de la. Le verdict se lit avec `python scripts/ci/pool_review_verdicts.py --gradient` (GraphQL pagine borné, ~3 appels, deux surfaces reviews[]+commentaires, latest-wins) qui distingue SANS-REVIEW / VOIX-SANS-VERDICT / LGTM / CONCERNS et rend le gradient d'age des reserves.
2. **Grouper LA QUEUE par lane, et dispatcher le deblocage.** Les ~20 PRs les plus vieilles, regroupees par leur tag `Grain: ... lane`, partent en mandat de deblocage a leur lane. Une PR est vieille **parce qu'**elle est bloquee : ce qui se dispatche est le deblocage, pas le merge qui s'attend. Le lot d'une lane se derive du sweep seul -- aucun re-audit prealable n'est requis pour l'envoyer.
3. **Relancer les nits bloquants, nommement.** Chaque reserve non levee (`[Hermes] COMMENT_WITH_CONCERNS`, `CHANGES_REQUESTED`, nit user, thread inline non resolu) est renvoyee a la lane de l'auteur de la PR **avec le point cite**. Une reserve qu'on ne relance pas devient un grain qu'aucune lane ne sait qu'elle doit executer -- et celles posees par ai-01 ne peuvent etre levees par personne d'autre.
4. **Le rouge sans lane est a MOI.** Le garde "reparer son rouge d'abord" ([proactive-coordination](../../rules/proactive-coordination.md) R5) renvoie chaque lane sur ses propres PRs bloquees -- mais une PR **sans tag `Grain:` lisible** n'est imputable a aucune lane et reste invisible a tous les gardes. Lire le commentaire marker-guarde `GRAIN-ORPHANS-SWEEP` sur #13086 (rafraichi via `python scripts/pick_idle_grain.py --orphans-report`) et traiter chaque orpheline nommee avec son auteur : reparer, dispatcher nommement, ou fermer en le disant. Le coordinateur est soumis au meme garde pour **sa propre** lane.
5. **Trancher les design-gates en attente** dans le cycle -- ne pas deferer une option deja investiguee. Regles : [coordinator-discipline.md](../../rules/coordinator-discipline.md) (R3 lanes independantes, R4 jamais sanctionner l'idle, R5 steer qui ATTEINT/VRAI/DECIDE).
6. **Grounder chaque grain firsthand** (`gh issue view N` / `gh pr view N`) AVANT de dispatcher -- jamais depuis un status condense.
7. **Double canal obligatoire** : DM `roosync_messages(action:"send", to:"<machine>:<workspace>", ...)` (le worker lit l'inbox en premier, le DM survit a la condensation) **+** pointeur `[DISPATCH->inbox]` sur le dashboard de la lane (sonnette persistante).
8. **Une lane sans grain = echec coordinateur** : la tete du tapis (`pick_idle_grain.py --belt`), jamais un statut terminal-idle. Chaque worker draine **tous** ses nits et reserves reparables sur **toutes** ses PRs, puis enchaine plusieurs grains DEEP/MED ; une seule PR livree ne clot pas sa session.
9. **MAJ memoire maintenant, pas en fin de cycle** : `coordinator-durable-state.md` si l'etat durable a bouge. Repoussee a la fin, elle saute quand le cycle deborde -- et le cycle suivant re-derive ce qu'il savait deja.

**Budget** : ces neuf points sont **clos avant** d'ouvrir la Phase 4. S'ils ne le sont pas a la fin des 30 minutes, ce sont eux qu'on termine -- pas le merge qu'on commence.

### Phase 3bis - Taches de fond : les deux ping-pongs (mandat user 2026-10-03)

Deux circuits asynchrones tournent **pendant** que le cycle merge. Ce sont deux circuits distincts : l'entrainement n'est pas une branche du proving. Le coordinateur ne fait pas leur travail ; il verifie a chaque cycle que chaque boucle tourne, et il relance le maillon qui manque.

| Ping-pong | Ce qui tourne | Qui lance | Qui exploite le resultat | Rendez-vous |
|---|---|---|---|---|
| **Proving** | passes du harnais prover (`agent_tests/prover`) | la lane qui tient le harnais | la forensic CoursIA, qui rend des lecons a la passe suivante | #1453 |
| **GPU** | entrainements et experiences | ai-01 sur son GPU d'experiences (grande echelle) ; les lanes a petit GPU defrichent a petite echelle | la lane qui a defriche, ou qui porte le carnet | #1454 |

1. **Lancer AU DEBUT de la phase de travail reel, en arriere-plan, puis PARTIR.** La prochaine action porte sur un autre track (merge-gate, dispatch). Jamais de poll au premier plan sur un run qu'on vient de lancer : la notification de fin est le seul observateur. Une exception : un controle de surete juste apres le lancement (le run est-il sur le bon device ?).
2. **GPU : etat, puis reservation.** Lire `nvidia-smi --query-gpu=index,memory.used,utilization.gpu,temperature.gpu --format=csv` et la derniere observation du ledger `gpu-reservation` (dashboard `CoursIA-gpu-reservation-ledger`). GPU d'experiences sous 500 MiB et aucune reservation `held` : lancer le prochain job de la file #1454 (commande remise par la lane qui defriche, ou complement multi-seed d'un run deja livre). Reserver **avant** de charger (`python scripts/coordination/debt_ledger.py append --ledger gpu-reservation`, avec echeance), puis poster l'observation ; passer en `released` a la fin.
3. **GPU : garde-fous.** Le device se pose **explicitement**, d'apres la topologie mesuree de la machine (`nvidia-smi -L`). Sur ai-01, les GPU 0+1 portent le vLLM de la flotte : un runner qui fixe lui-meme `CUDA_VISIBLE_DEVICES` se neutralise ou se contourne, jamais ne se lance tel quel. Un seul job GPU a la fois, abandon au-dela de 85 °C, worktree detache dedie, sorties hors depot.
4. **Proving : verifier la boucle, pas la refaire.** Derniere passe et sa trace sur #1453, forensic rendue ou non, lecons reinjectees ou non dans la passe suivante. Le maillon manquant se **dispatche nommement** (DM + pointeur dashboard) a la lane qui le porte.
5. **Rendre.** Un run termine produit un artefact (traces, JSONL, carnet de sortie) remis a la lane qui l'exploite, par DM et commentaire sur l'issue de rendez-vous. Il n'entre dans le depot que par la PR de la lane proprietaire du carnet ou du script.
6. **Rapport.** Le `[DONE]` porte une ligne `[BG] proving: <derniere passe / forensic> | gpu: <job, device, debut, fin prevue> ou libre`. Un GPU d'experiences vide sans raison ecrite est une dette du cycle, a lever au suivant.

### Phase 4 - Merge PAR LA QUEUE, sur dossiers premaches

**Ordre unique : du plus ancien au plus recent.** Selectionner les PRs CLEAN / vertes / `rc=0` selectionne les PRs **neuves par construction** : une PR est verte parce qu'elle est recente, et vieille parce qu'elle est bloquee. Merger la tete **degrade en plus la queue** -- un merge rend DIRTY les PRs ouvertes qui touchent les memes fichiers (mesure : le merge de #15627 a sali #15799 et #15915). Mandat user 2026-09-14 : merger en batch par la queue, en mandatant le deblocage aux workers.

**Ce que le coordinateur NE refait PAS.** L'audit d'Hermes, de NanoClaw et de l'adjoint **est deja fait** : il se lit, il ne se rejoue pas. Ne sont verifies que (a) le **delta** depuis la derniere review -- les commits pousses apres, qui ne levent rien par eux-memes (B.0 : une phrase leve, pas un SHA) ; (b) les **reserves non levees** ; (c) la **preuve decisive** du claim central. Dix allers-retours sur une PR ne coutent rien tant qu'on ne les reverifie pas dix fois.

1. **Gate d'entree AVANT toute lecture personnelle (HARD)** : pour chaque candidate oldest-first, lancer `python scripts/check_adjoint_prevalidation.py <PR>`. Le gate repond a **deux** questions distinctes — *le dossier est-il integre ?* et *la PR est-elle mergeable ?* — et ne les confond plus (arbitrage #16800, sign-off user 2026-09-19) :

   | Sortie | Sens | Ce que fait ai-01 |
   |---|---|---|
   | **0** | dossier integre + `verdict: READY` | ouvrir body, commentaires, reviews, threads, diff ; lire B.0 ; merger si les gates du point 5 passent |
   | **3** | dossier integre + `verdict: BLOCKED` | **n'ouvrir AUCUNE surface** — dispatcher a la lane auteur depuis le motif atteste par le dossier, et passer a la candidate suivante |
   | **1** | pas de dossier digne de confiance (absent, malforme, perime, mauvaise lane/auteur, empreinte cassee) | router la candidate vers une lane **TIERCE qualifiante** -- l'adjoint `myia-po-2025:CoursIA-2` en premier, mais toute autre lane du cluster qui **ne porte pas** la PR convient (#16906) --, l'exclure jusqu'a un dossier exact-head, candidate suivante |
   | **2** | organe injoignable | refus fail-closed, identique a 1 |

   **Exit 3 n'est PAS un gate plus mou** : un dossier BLOCKED doit satisfaire toutes les exigences structurelles, `surfaces-sha256` comprise. Ce qui tombe, ce sont les controles qui **refutent une claim READY** (checks verts, B.0 clear, zero thread non resolu, non-draft) — ce sont des raisons pour lesquelles une PR est bloquee, pas des raisons de se mefier du dossier qui le dit.

   **Pourquoi** : exiger READY pour `exit 0` faisait dependre le **droit de lire** de l'**etat de mergeabilite**, donc ai-01 ne pouvait ouvrir que les PRs qui allaient deja bien — jamais les plus vieilles, qui sont vieilles *parce que* bloquees. Ca poussait aussi l'adjoint a ecrire READY pour seulement rendre son travail visible, ce qui a produit un faux `b0: clear` **mesure** sur une PR portant 3 findings HIGH ouverts (#16160).

   **Deux identites sont neutres** apres le dossier, et seulement apres : `myia-ai-01` et le login partage `jsboige` (#16883, `_is_own_later_act` dans `scripts/check_adjoint_prevalidation.py`). Un **commentaire** de l'une ou l'autre, poste apres le dossier, ne le perime pas. Une **review** ne le laisse intact que si elle ne pose aucune reserve (#17039). Sans ca, le geste que le gate autorise — lire la PR, puis lever sa propre reserve — perimerait le dossier que le gate exige. Une surface de **tout autre auteur**, ou une surface **anterieure** au dossier, perime toujours.

   **Consequence** : `jsboige` est aussi le login de toutes les lanes et du user. Le gate ne voit donc pas un commentaire `jsboige` poste apres le dossier, pas meme un nit user. C'est B.0 (`check_unaddressed_nits.py`) qui l'attrape : son `rc=0` reste exige avant tout merge, dossier READY ou pas.

   Le bloc `[ADJOINT PREFLIGHT]` est genere par `python scripts/check_adjoint_prevalidation.py <PR> --template [--lane <machine:workspace>]`, puis complete par la lane emettrice -- **qui rend son PROPRE nom** : un dossier sous un nom d'emprunt defait le refus d'auto-attestation. Le compte des commentaires exclut le commentaire-dossier lui-meme. **Interdit de contourner le gate par un sous-agent, une lecture API directe ou un ancien dossier d'inbox.**
2. **Exploiter les verdicts deja poses** : `[Hermes] COMMENT_WITH_CONCERNS` (prefixe de `reviews[].body`), `EXEC_PROVED` / `STRUCTURAL_ONLY` / `SUSPECT_REGRESSION` (body). Tout finding NanoClaw suit [audit-reassessment.md](../../rules/audit-reassessment.md) avant fix (~60 % de FP).
3. **L'adjoint fabrique, ai-01 ne re-fabrique pas** : les PRs sans dossier valide partent en lots explicites issus du sweep vers l'adjoint, pas vers des sous-agents ai-01. Dossier attendu : contrat machine-lisible exact-head, trois surfaces B.0, checks latest-wins, scope, domaine et verdict ; un changement de head ou de surface le perime. L'adjoint vise **>=20 READY oldest-first par fenetre de 4 h quand >=20 candidates sont eligibles**, et remonte chaque READY immediatement : le lot n'est pas une barriere. Un dossier insuffisant repart avec UNE question precise. Le login GitHub `jsboige` etant partage, le champ `lane` est une declaration fail-closed, pas une preuve cryptographique d'identite. Ce que le gate exige est que la prevalidation soit **tierce**, pas qu'elle vienne d'une lane nommee : toute lane du cluster (`QUALIFYING_LANES`) peut emettre un dossier pour une PR **qu'elle ne porte pas**, et le gate refuse l'auto-attestation en comparant la lane du dossier au tag `Grain:` du body (#16906). Une lane hors de l'ensemble, ou malformee, echoue toujours ferme.
4. **Lecture B.0 personnelle minimale avant chaque merge -- non delegable, seulement APRES gate vert** : body + comments + reviews + diff ("Read Body Before Any Action") ; etat A L'INSTANT-T via `gh pr view N --json state,mergedAt,mergeStateStatus,reviews` (jamais depuis le dashboard ni le cycle N-1) ; organe `python scripts/check_unaddressed_nits.py <PR>` (exit 1 = ne pas merger ; son vert ne dispense pas de la lecture). Verifier seulement le dossier, le delta et la preuve decisive ; ne pas rejouer l'audit complet. Une levee porte un auteur et une heure.
5. **Gates de merge** : un preflight READY n'autorise jamais le merge. Appliquer encore B.0, latest-wins CI, H.4 (notebooks : checkout + Papermill local OU log dans le body), catalogue byte-identique a main (`gh pr view N --json files`), scope reel = titre, ordre de stack, variation et relecture de la queue de commentaires.
6. **Merge** : sous `myia-ai-01` (droit `MergePullRequest` verifie firsthand 2026-08-08), avec `gh pr merge <N> --repo jsboige/CoursIA --squash --match-head-commit <SHA>` (`--merge` preserve-SHA pour la base d'un stack), **JAMAIS `--delete-branch`**.
7. **Approuver ce qui est lu mais pas encore mergeable** (arbitrage user 2026-09-28, Q67) : une PR hors harnais et hors DEEP dont la lecture du point 4 est faite, mais dont le dossier n'est pas encore READY (minuteur DWELL, jambe a rejouer, dossier a re-tamponner), recoit une review `APPROVED` sous `myia-ai-01` a la tete lue. `merge_ready` la merge des que le dossier est pret ; un rafraichissement de base sans conflit ne perime pas cette approbation, un commit de contenu ou une resolution de conflit la perime. Sans cette review, l'organe ne merge rien : il n'est plus une voie de merge sans lecteur.

### Phase 4bis - Passe issues, sur dossiers de fermeture (mandat user 2026-09-26)

**Le pool d'issues se draine comme la file de PRs : sur dossiers tiers, a heure fixe, apres la passe de merge.** Sans cette passe, le goulot se deplace de la production vers la fermeture. Les lanes livrent, l'issue reste ouverte, et le pool grossit alors que le travail est fait. Mesure fondatrice (#17956) : des dossiers de fermeture informels (`[INFO] candidate-delivered`, avec verification firsthand) s'accumulaient sans que personne les consomme.

1. **Entree** : les issues portant un dossier de fermeture de l'adjoint ou du secretaire, du plus ancien au plus recent. Tant que le gate de #17956 n'est pas sur `main`, ce sont les commentaires `[CLOSURE PREFLIGHT]` et, a defaut, `[INFO] candidate-delivered` poses par une lane **qui n'a pas livre**. Le crible mecanique (`candidate_delivered.py` puis `verifier_cleanup.py`) sert a leur donner du travail, **jamais** de preuve : son READY rate les issues-conteneurs de serie et les acceptances partielles (precision mesuree d'environ 42 %).
2. **Lecture G.9 minimale, non delegable** : le body (chaque critere d'acceptance), le dossier, les commentaires posterieurs, la PR livrante MERGED. Un critere sans preuve, une PR ouverte qui reference l'issue, ou un arbitrage user attendu = **KEEP**, avec une phrase sur l'issue qui dit ce qui manque.
3. **Fermer en lot** sous `myia-ai-01`, un commentaire par issue qui nomme la PR et les criteres couverts. Un residu part en issue fille nommee **avant** la fermeture, ou en waiver date et falsifiable.
4. **Les Epics ne ferment pas sur une PR** : leur dette (PRs atomiques restantes, EAT) vit dans le ledger `issue-debt`. Ce ledger ne porte **que** des issues ; une `[OBS]` sur un numero de PR est une derive a signaler a son emetteur.
5. **Budget** : la passe tient dans le cycle. Ce qui n'est pas lu repart dans la tournee suivante des adjoints, pas dans une investigation.

### Phase 5 - Fin de cycle (obligatoire)

1. **Commit + PR AVANT le rapport** — ne jamais annoncer un travail non commite.
2. `[DONE]` lane-specific sur **les deux** dashboards (jamais un miroir copie-colle).
3. **Bloqueurs user** : restituer en un bloc les questions ouvertes du registre durable ; aucun re-poke intermédiaire ni liste parallèle ([user-blocker-signaling](../../rules/user-blocker-signaling.md)).
4. MAJ `coordinator-durable-state.md` si l'etat durable a change (PR#/SHA ephemeres → dashboard, pas la memoire).
5. **Une seule investigation par cycle, et en fin de session.** Toute question ouverte qui n'est **pas** un bloqueur de merge se note et attend le cycle suivant : mesurer un organe, verifier une provenance, instruire un doute de securite sont des gestes utiles et couteux, qui n'ont leur place qu'apres les dispatchs, les relances et la passe de merge. Une investigation qui deborde sur le cycle suivant est une investigation de trop -- elle a mange le temps des lanes. Si l'objet est reellement urgent, il devient un **grain dispatche**, pas une enquete du coordinateur.

## Amelioration continue des skills (mandat user 2026-09-21)

Les skills du trio — `coordinate` (ai-01), `coordinate-adjoint` (titulaire), `adjoint-secretary` (secretaire) — sont sous controle de source. **Elles se relisent et se corrigent regulierement, comme du code**, pas seulement quand elles cassent.

- **A chaque cycle, si une mesure du cycle contredit une skill, la skill se corrige dans le meme cycle** — par PR, comme tout changement de harnais (CLAUDE.md §A : PR + sign-off user pour un changement normatif substantiel ; une correction factuelle n'exige pas de sign-off supplementaire).
- **Les trois defauts a chercher en priorite**, parce qu'ils sont muets :
  1. une **liste codee en dur** de ce qu'il faut lire (dashboards, lanes, organes) — elle ne voit pas ce qu'elle n'anticipe pas ;
  2. une **reference vers une branche** plutot que `main` — elle pointe un etat perime, et devient muette si la branche disparait ;
  3. un **geste reimplemente a la main** alors que `scripts/` porte l'organe (`pr_gate.py`, `merge_dwell.py`, `count_code_sorry.py`, `check_unaddressed_nits.py`). Avant d'ecrire du jq de verdict : `git grep` le geste dans `scripts/`. Une approximation maison est biaisee vers l'accusation.
- **Une skill est datee de sa redaction**, exactement comme un body d'issue : la suspecter d'abord quand elle fait ATTENDRE ou RENONCER.
- Les suggestions faites a une skill d'autrui se postent **en commentaire de PR**, pas en `CHANGES_REQUESTED` : bloquer garderait la skill hors du controle de source, soit l'inverse du but.

## Regles importantes

- **Force push** : jamais sur `main` ; autorisé sur une branche de PR à lane unique — cf [git-workflow.md](../../rules/git-workflow.md)
- **Coordination via RooSync uniquement** — aucun fichier de coordination/rapport dans git
- **Dashboards workspace coordonnes independamment, et ENUMERES** — les cles se decouvrent par `action:"list"`, jamais par une liste codee en dur (cf Phase 2.1) ; lire et poster un contenu lane-specific sur CHACUNE a chaque cycle, jamais de broadcast miroir, jamais "le mien vs celui des workers".
- **Issues + PRs** — chaque tache = issue, chaque livraison = PR avec review
- **Priorites courantes** : vivre dans `coordinator-durable-state.md` (memoire) + dashboards — pas dans ce fichier (harness-hygiene : le skill decrit le processus, pas l'etat).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…