Skip to content
2 changes: 1 addition & 1 deletion docs/reference/scripts-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Pipeline d'audit qualité et de **matrice de coût** (EPIC #8056) + audit séman
| `scripts/check_grain_free.py` | **Grounding pré-dispatch** (une commande avant d'écrire un steer) : agrège l'état de l'issue, les **contraintes de forme** de son acceptance (cases `- [ ]` portant une négation — c'est ce que #10990 interdisait), les **PRs ouvertes** et **mergées** la référençant, et délègue les claims à `check_lane_claim.py` (autorité). `--lane` obligatoire. Exit `0` CLEAR / `1` FLAGGED / `2` UNKNOWN — une surface non interrogeable rend **UNKNOWN**, jamais une liste vide : « rien trouvé » et « pas regardé » ne partagent pas de valeur de retour. Complète `check_lane_claim.py --paths`, qui exige de connaître les chemins — ce qu'on n'a pas encore au moment de dispatcher |
| `scripts/check_adjoint_prevalidation.py` | **Gate d'entrée en review ai-01** (#16442) : exige un dossier `[ADJOINT PREFLIGHT]` complet de la lane adjointe, lié au SHA exact et à une empreinte des surfaces body/comments/reviews/threads/checks. Toute absence, mutation observable des surfaces actuelles ou valeur non canonique échoue fermé ; un événement GitHub ensuite supprimé/reverté n'est pas reconstructible par cet organe stateless. `--template` génère le bloc complet (empreinte incluse) et `--fingerprint` expose l'empreinte seule. Exit `0` READY / `1` BLOCKED / `2` UNKNOWN. READY autorise la lecture finale du coordinateur, jamais le merge |
| `scripts/check_pr_perimeter.py` | **Source de vérité périmètre pour reviews** (#11268) : énumère les fichiers effectifs d'une PR (`gh pr view --json files`), nomme tout `.github/workflows/**` dans une section dédiée, détecte les **mouvements de baseline/seuil** du diff avec leur sens (`sorry-baseline` 16→14 = TIGHTEN ; un desserrement sans `--baseline-justified` => CHANGES_REQUESTED), et confronte l'assertion de périmètre du reviewer (`--assert "..."`) à la liste réelle — la review #11227 (« 2 fichiers twins uniquement » sur 3 fichiers dont un workflow) ne peut plus être produite à l'insu. `--scan-thread` scanne le body PR + les reviews top-level et confronte chaque assertion trouvée à la liste effective ; câblé par `.github/workflows/perimeter-review-guard.yml` (déclenché sur `pull_request` + `pull_request_review`) — une fausse assertion devient un check rouge bloquant. Exit `0` OK / `1` FAIL (écart assertion, workflow non nommé, desserrement nu) / `2` erreur gh. À exécuter AVANT toute assertion de périmètre dans une review |
| `scripts/coordination/debt_ledger.py` | **Reducteur du ledger de dette d'issue partage** (`issue-debt`) : schema versionne, validation stricte des observations (UTC explicite, provenance obligatoire, cles inconnues refusees), fusion par champ « plus recente observation compatible gagne » avec provenance et historique, pliage idempotent du snapshot precedent (archive-aware). Le **transport partage n'est pas un fichier** : observations = messages append-only du dashboard dedie `CoursIA-issue-debt-ledger`, snapshot ecrit par ai-01 seul en section `status` — jamais d'ecriture sous `$ROOSYNC_SHARED_PATH` (Drive : pas de verrou, `assert_local_output` refuse, sans override). CLI `init` (dry-run par defaut) / `append` (imprime l'appel MCP, n'ecrit rien) / `reduce` (artefacts locaux atomiques sous verrou). L'adaptateur de l'export producteur, le contrat de couverture `window` et le ledger `pr-actions` arrivent avec le transport. Schema et metriques : [scripts/coordination/README.md](../../scripts/coordination/README.md) ; lectures : `scripts/tests/test_debt_ledger.py`. Porte **deux kinds** depuis #16737 : `issue-debt` (cle `owner/repo#N`, EAT, closeability, follow-ups) et `gpu-reservation` (cle `<machine>#gpu<n>`, etats `held`/`released`/`stale`, resume `held_by_machine`/`holders`/`stale_holds`, dashboard dedie `CoursIA-gpu-reservation-ledger` — registre d'occupation, pas un verrou dur). Ledger `pr-actions` a venir |
| `scripts/coordination/debt_ledger.py` | **Reducteur des ledgers partages** (`issue-debt` + `gpu-reservation`) : schema versionne, validation stricte des observations (UTC explicite, provenance obligatoire, cles inconnues refusees), fusion par champ « plus recente observation compatible gagne » avec provenance et historique. La lecture se fait dans la **forme du producteur**, pas dans une forme inventee : l'export `roosync_dashboard read` imbrique son journal (`data.intercom.messages`) et son auteur est un objet (`machineId:workspace`), que l'adaptateur normalise — un lecteur qui ne regarde qu'au premier niveau voit « pas de messages » sur un export sain. Contrat de fenetre archive-aware : l'export **declare** sa couverture (`window.kind` = `full` / `incremental`, `--window-full` pour un export muet ; absent = `incremental`, fail-closed), un `incremental` sans snapshot precedent leve `MISSING_CHECKPOINT`, et le snapshot precedent est plie champ par champ comme checkpoint quand le dashboard a condense la queue. Le **transport partage n'est pas un fichier** : observations = messages append-only du dashboard dedie (un par kind), snapshot ecrit par ai-01 seul en section `status` — jamais d'ecriture sous `$ROOSYNC_SHARED_PATH` (Drive : pas de verrou, `assert_local_output` refuse, sans override). CLI `init` (dry-run par defaut) / `append` (imprime l'appel MCP, n'ecrit rien) / `reduce` (artefacts locaux atomiques sous verrou). Porte **deux kinds** depuis #16737 : `issue-debt` (cle `owner/repo#N`, EAT, closeability, follow-ups) et `gpu-reservation` (cle `<machine>#gpu<n>`, etats `held`/`released`/`stale`, resume `held_by_machine`/`holders`/`stale_holds`, dashboard dedie `CoursIA-gpu-reservation-ledger` — registre d'occupation, pas un verrou dur). Schema, contrat et metriques : [scripts/coordination/README.md](../../scripts/coordination/README.md) ; lectures : `scripts/tests/test_debt_ledger.py` |
| `scripts/ci/measure_runner_demand.py` | **Baseline exhaustive de demande GitHub Actions** (#12704) : collecte une fenêtre UTC avec bisection anti-cap 1 000 + pagination de tous les jobs, mesure attente (`started_at-created_at`), travail runner (`completed_at-started_at`), provenance same-repo/fork/unknown et dénominateurs ; replay offline par `--input`. **Co-résidence** (#15574) : bloc `co_residence` (hôte présumé du préfixe du `runner_name`, pic et moyenne de concurrence par job) et bloc `runners_inventory` (`--runners`, slots enregistrés par hôte, trois états `measured`/`unavailable`/`not_collected`, jamais un parc vide). Exit `0` mesure valide / `2` instrument ou snapshot incomplet. Procédure : [docs/ci/self-hosted-runners.md](../ci/self-hosted-runners.md) · organe : `.github/workflows/runner-coresidence-advisory.yml` |
| `scripts/ci/manage_self_hosted_runner.py` + `self_hosted_runner_profiles.json` | **Cycle de vie Windows des runners éphémères isolés** (#12704) : profils distribués po-2023..po-2026 avec archive/SHA-256 épinglés ; commandes `install`, `register`, `verify`, `teardown` en dry-run par défaut, mutations uniquement avec `--apply`; compte local dédié, ACL négatives `.secrets`/SSH/gh, tokens via `ACTIONS_RUNNER_INPUT_*`, extraction anti-Zip-Slip/ADS et teardown borné par manifeste. `register --apply` est le bouton d’activation séparé, jamais lancé pendant la préparation. Procédure : [docs/ci/self-hosted-runners.md](../ci/self-hosted-runners.md) |
| `scripts/ci/pool_review_verdicts.py` | **Vue de triage du pool : verdict lu dans les corps, pas `reviewDecision`** (#16926) : sous token COMMENT-only (#15511) le champ `reviewDecision` vaut `null` à perpétitude sur ~82 % du pool y compris les PRs portant un `VERDICT: LGTM` argumenté — trier dessus fabrique le faux compte « sans review ». L'organe balaye le pool en GraphQL paginé borné (page 50 + retry 5xx unique : les fenêtres `reviews`+`comments` font 504/502 au-delà, mesures 2026-09-20), lit le préfixe `VERDICT:` en début de ligne sur les **deux surfaces** (reviews[] + commentaires de persona, marqueur importé du canon `check_unaddressed_nits`), latest-wins, et distingue `SANS-REVIEW` (aucune voix) de `VOIX-SANS-VERDICT` et des états réels CHANGES_REQUESTED/APPROVED qui gouvernent. `--gradient` rend la répartition par quartile d'âge (l'enseignement #16926 : les PRs vieillissent parce qu'elles portent une réserve vivante). Advisory : exit 0, ou 2 si le balayage est illisible. Tests : `scripts/tests/test_pool_review_verdicts.py` |
Expand Down
Loading
Loading