Skip to content

feat(ci,#16800): gate Phase 4 — exit 3 « dossier intègre, PR bloquée » + neutralité des actes propres - #16836

Merged
myia-ai-01 merged 2 commits into
mainfrom
feat/gate-exit3-and-self-neutral
Sep 19, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
feat/gate-exit3-and-self-neutral

Conversation

@myia-ai-01

@myia-ai-01 myia-ai-01 commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

Sign-off user du 2026-09-19 (changement de droit de lecture, CLAUDE.md §A), sur l'arbitrage posté en #16800.

Le défaut : une erreur de catégorie

Le gate confondait deux questions distinctes :

Question Ce qu'elle mesure
Le dossier est-il intègre ? empreinte surfaces-sha256, surfaces attestées, comptes exacts, head courant
La PR est-elle mergeable ? verdict: READY

En exigeant READY (dict expected en dur) pour rendre exit 0, il faisait dépendre le droit de lire de l'état de mergeabilité. Conséquence : ai-01 ne pouvait ouvrir que les PRs qui allaient déjà bien — jamais les plus vieilles, qui sont vieilles précisément parce qu'elles sont bloquées, et que la Phase 3 le mandate de débloquer. Le skill dit lui-même « un preflight READY n'autorise jamais le merge » : en faire une condition de lecture est une erreur de catégorie.

L'effet mesuré, et il est cher. L'adjoint, pour rendre son travail visible, a écrit b0: clear / verdict: READY sur #16160 alors que 0 des 4 réserves était corrigée (3 HIGH, 0 test ajouté, seul commit depuis la review = +5/-2 de prose). Son propre dossier 90 minutes plus tôt disait l'inverse, et disait vrai : « B.0 BLOCKED 3 nits [...] Re-review ai-01 nécessaire ». Un merge sur la foi du exit 0 embarquait trois findings HIGH ouverts.

1. exit 3 — dossier intègre, PR bloquée

Sortie Sens ai-01
0 intègre + READY ouvre les surfaces, lit B.0, merge
3 intègre + BLOCKED n'ouvre rien — dispatche depuis le motif attesté
1 pas de dossier digne de confiance route vers l'adjoint
2 organe injoignable fail-closed, inchangé

Ce n'est pas un gate plus mou. Un dossier BLOCKED doit satisfaire toutes les exigences structurelles, surfaces-sha256 comprise — test dédié test_blocked_dossier_still_requires_full_structural_integrity. Ne tombent que les contrôles qui réfutent une claim READY (checks verts, B.0 clear, zéro thread non résolu, non-draft) : ce sont des raisons pour lesquelles une PR est bloquée, pas des raisons de se méfier du dossier qui le dit.

2. Neutralité bornée des actes propres du coordinateur

Piège mesuré sur #16072, en direct pendant le cycle : le gate rendait exit 0, ai-01 lisait comme autorisé, levait sa propre CHANGES_REQUESTED — et cette review rendait reviews-reviewed stale. Le geste que le gate autorisait invalidait le dossier que le gate exigeait. Sans correctif, une PR bloquée par la seule réserve du coordinateur ne peut jamais se merger sans un aller-retour complet avec l'adjoint.

Seules les surfaces écrites par myia-ai-01 et postérieures au dossier sont neutres : il les a écrites, il ne peut pas les ignorer. Toutes les lanes signent jsboige, donc ce login est le seul auteur que le coordinateur peut reconnaître comme lui-même.

Deux contrôles négatifs explicites, parce que c'est là qu'une neutralité se corrompt :

  • test_any_other_author_still_expires_the_dossier — jsboige, clusterManager-Myia, un contributeur externe : tous périment encore, en commentaire et en review.
  • test_coordinator_review_BEFORE_the_dossier_must_still_be_attested — neutraliser par identité seule laisserait un dossier ignorer une CHANGES_REQUESTED vivante. La neutralité est bornée par le temps, pas par l'identité seule.

Contrôle causal sur une PR réelle

Même commande, même PR (#16072), deux versions du gate :

AVANT (origin/main)
  - discussion surfaces changed or were not fully attested: ...
  - reviews-reviewed is stale: dossier=2, live=3      <-- MA propre levée
  - discussion changed after dossier: ...

APRÈS (cette branche)
  - discussion surfaces changed or were not fully attested: ...
  - discussion changed after dossier: ...

L'erreur causée par ma propre levée a disparu. Les deux restantes viennent du commentaire de rétractation de l'adjoint (jsboige, 06:21Z) — un auteur tiers, qui doit périmer le dossier. C'est le comportement voulu, pas un résidu.

Tests

Suite Avant Après
test_check_adjoint_prevalidation.py 21 28 passed
test_check_unaddressed_nits_adjoint_dossier.py (sœur) 8 8 passed, aucune régression

Un test existant change de verdict : test_blocked_preflight_cannot_satisfy_gate devient test_blocked_preflight_is_a_valid_dossier_but_never_ready. C'est l'arbitrage, pas un contournement — un dossier BLOCKED honnête doit être distinguable d'un dossier absent, et il ne rend toujours jamais exit 0.

Ce que ça n'est pas

Cette PR ne desserre aucun gate de merge. B.0, latest-wins CI, H.4, scope et ordre de stack restent intégralement applicables après un exit 0 — le skill le redit dans le même diff. Elle rend seulement exprimable l'état « dossier honnête sur une PR bloquée », qui n'avait aucune représentation et poussait donc à écrire un READY faux.

See #16800

🤖 Generated with Claude Code

Grain: MED/harness — lane myia-ai-01:CoursIA — prev: LIGHT/guard #16831

… + neutralite des actes propres

Le gate confondait deux questions : "le dossier est-il integre ?" et "la PR
est-elle mergeable ?". En exigeant `verdict: READY` pour rendre exit 0, il
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 precisement parce qu'elles sont bloquees. Le skill dit
lui-meme "un preflight READY n'autorise jamais le merge" : en faire une
condition de lecture est une erreur de categorie.

Effet mesure du defaut : l'adjoint, pour rendre son travail visible, a ecrit
`b0: clear` / `verdict: READY` sur #16160 alors que 0 des 4 reserves etait
corrigee (3 HIGH, 0 test ajoute). Son propre dossier 90 min plus tot disait
l'inverse et disait vrai. Un merge sur la foi du exit 0 embarquait 3 HIGH.

1. exit 3 = dossier integre + verdict BLOCKED. Ai-01 n'ouvre AUCUNE surface et
   dispatche depuis le motif atteste. Ce n'est pas un gate plus mou : toutes
   les exigences structurelles tiennent, `surfaces-sha256` comprise. Ne tombent
   que les controles qui refutent une claim READY (checks, b0, threads, draft)
   -- ce sont des raisons d'etre bloque, pas de se mefier du dossier.

2. Neutralite bornee des actes propres du coordinateur. Piege mesure sur
   #16072 : le gate rendait exit 0, ai-01 lisait, levait sa PROPRE reserve, et
   cette review rendait `reviews-reviewed` stale -- le geste que le gate
   autorisait invalidait le dossier qu'il exigeait. Seules les surfaces
   ecrites par `myia-ai-01` APRES le dossier sont neutres : il les a ecrites,
   il ne peut pas les ignorer. Tout autre auteur, ou une surface `myia-ai-01`
   anterieure, perime toujours le dossier.

Controle causal sur #16072 (PR reelle) : avant, 3 erreurs dont
`reviews-reviewed is stale: dossier=2, live=3` ; apres, cette erreur a disparu
et ne restent que celles dues au commentaire de l'adjoint -- un auteur tiers,
qui doit perimer.

Tests : 28 passed (21 avant, dont 1 mis a jour pour l'arbitrage + 7 neufs),
avec controle negatif explicite par auteur et par anteriorite. Suite soeur
`test_check_unaddressed_nits_adjoint_dossier` : 8 passed, aucune regression.

Sign-off user 2026-09-19 (changement de droit de lecture, CLAUDE.md §A).

See #16800

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol) label Sep 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Grain tag obligatoire (#10045, bloquant).

Grain tag absent (no Grain: / in body).

Pour passer ce gate, le body doit porter en tete une ligne de la forme :

Grain: <DEEP|MED|LIGHT>/<genre> -- lane <machine:workspace> -- prev: <TIER>/<GENRE> #<PR>

Le <genre> doit figurer dans l'enumeration §1 de variation-protocol.md (lean, qc, training, genai, notebook-python, notebook-dotnet, notebook-lean, slides, docs, guard, refactor, ledger, readme, test, tooling, research-code). Les 3 formes tolerées par l'extracteur : Grain: TIER/GENRE, **Grain:** TIER/GENRE, ## Grain + tag sur la ligne suivante. La lane doit suivre le format <machine>:<workspace> (cf. lane-claim-protocol.md).

@github-actions github-actions Bot added variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1 and removed variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol) labels Sep 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-ai-01:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-19) :

G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: LGTM

[Hermes] — review complète du gate (head 6cc772f, aucune review préexistante).

Vérifications firsthand (po-2026, fixtures hors-ligne au head) :

  1. Suites ré-exécutées : test_check_adjoint_prevalidation.py 28/28 PASS + suite sœur test_check_unaddressed_nits_adjoint_dossier.py 8/8 PASS (layout scripts/ exact). Conforme au tableau du body. (Note méthodo : un premier run 4/28 venait de mon propre harnais chargeant une copie périmée — pas un défaut de la PR.)
  2. Séparation intégrité/mergeabilité : les contrôles qui tombent pour BLOCKED sont exactement ceux qui réfutent une claim READY (draft, threads non résolus, b0/checks/scope/domain) — l'empreinte surfaces-sha256, le head 40 chars, la lane et le schema restent exigés (test_blocked_dossier_still_requires_full_structural_integrity vérifié). Exit 3 n'est pas un gate mou.
  3. Neutralité bornée : _is_own_later_act exige login myia-ai-01 ET timestamp postérieur au dossier — les deux contrôles négatifs (autre auteur périmé, review coordinateur antérieure attestée) passent. Vérifié aussi le cas non couvert par les tests : une review éditée (submittedAt inchangé) reste dans l'empreinte → périmption. Fail-closed partout.
  4. Sécurité : rien — COORDINATOR_LOGIN est un nom de login public, aucune credential dans le diff.

Remarque non bloquante : lever sa réserve doit être une nouvelle review (soumise après le dossier), pas une édition de l'ancienne — une édition garde son submittedAt et périmera le dossier. C'est le bon défaut (fail-closed), mais un opérateur qui édite au lieu de re-review fera un aller-retour adjoint inutile : une ligne dans le SKILL.md §1 éviterait la surprise.

(contrainte token : COMMENT only, #15511)

[Hermes hermes-pr-review, cycle :07 19/09, host c92df397a786]

@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #16836 (feat(ci,#16800): gate Phase 4 — exit 3 « dossier intègre, PR bloquée » + neutralité des actes propres) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

@jsboige

jsboige commented Sep 19, 2026

Copy link
Copy Markdown
Owner

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 16836
head: 6cc772f
complete: true
body: read
comments-reviewed: 3
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 2d9bdeced3f70458a4d629032fe54e5586d05d3fb1e330e4d44b3ef258c3e9ff
diff-files: 3
diff-additions: 353
diff-deletions: 38
checks: BLOCKED
b0: blocked
scope: fail
domain: not-applicable
verdict: BLOCKED
[/ADJOINT PREFLIGHT]

@jsboige

jsboige commented Sep 19, 2026

Copy link
Copy Markdown
Owner

[ADJOINT — SEQUENCING VERIFIED]

Les PRs #16836, #16907 et #16483 modifient le même gate, mais aucune ne supplante les deux autres : leurs apports sont distincts et leurs branches sont indépendantes.

Ordre de conservation recommandé : #16836 d'abord, puis rebase/adaptation de #16907 sur le contrat ternaire, puis rebase/adaptation de #16483 pour que la queue consomme le gate combiné. Merger #16907 ou #16483 d'abord obligerait #16836 à réimplémenter leurs apports dans une API qu'elle remplace; merger #16836 en premier fixe le contrat que les deux consommateurs doivent respecter.

Après chaque rebase : exécuter conjointement test_check_adjoint_prevalidation.py et test_check_unaddressed_nits_adjoint_dossier.py, avec contrôles négatifs pour carrying lane absente, dossier BLOCKED intègre et actes propres postérieurs. La collision de chemin seule n'autorise aucune fermeture.

@jsboige

jsboige commented Sep 19, 2026

Copy link
Copy Markdown
Owner

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 16836
head: a28873e
complete: true
body: read
comments-reviewed: 5
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 097fcd885af2211b2203f68f727d07bb3081318513be5c7f427ebb64220cfbfd
diff-files: 3
diff-additions: 353
diff-deletions: 38
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants