Skip to content

check_adjoint_prevalidation: exposer le motif attesté sur exit 3 (le gate demande de dispatcher depuis un motif qu'il ne rend pas) #17290

Description

@jsboige

Le défaut

scripts/check_adjoint_prevalidation.py rend exit 3 = « dossier intègre + verdict: BLOCKED ». La règle attachée à ce code (CLAUDE.md / skill coordinate, Phase 4 point 1) est explicite :

3 — dossier intègre + verdict: BLOCKED → n'ouvrir AUCUNE surface — dispatcher à la lane auteur depuis le motif attesté par le dossier, et passer à la candidate suivante

Or --json n'expose aucun motif. Sur exit 3, la sortie complète est :

{"pr": 16219, "head": "292badb745ef...", "ready": false, "verdict": "BLOCKED", "errors": []}

Le dossier porte pourtant les champs qui sont le motif — b0, checks, scope, domain, threads, draft — et le gate les a lus pour statuer. Il les jette.

Pourquoi ça coûte

Le coordinateur qui suit la règle à la lettre n'a que deux issues, toutes deux mauvaises :

  1. Re-parser le commentaire-dossier à la main. C'est ce que j'ai fait au cycle 23 pour 13 PRs : un script jetable qui re-télécharge comments, filtre [ADJOINT PREFLIGHT], et ré-extrait des champs que le gate venait de parser. Chaque lane réécrira le sien.
  2. Ouvrir les surfaces de la PR — précisément ce que exit 3 interdit.

Et un dispatch sans motif est un dispatch vide : « ta PR est bloquée » n'est pas actionnable.

Mesure (cycle 23, 2026-09-21)

13 PRs en rc=3. Après extraction manuelle du dossier, le motif se scinde nettement — et 6 sur 13 avaient un motif déjà mort :

Motif attesté PRs Mesure de l'après-midi
checks: BLOCKED, b0: clear #16406, #16470, #16471 0 check non-ok (latest-wins)
b0: blocked #16393, #16467 check_unaddressed_nits.py rend rc=0
b0: blocked #16350 rc=0 après levée de la réserve ai-01
checks: BLOCKED (réel) #16219, #16376, #16405 vrais rouges CI, gestes distincts
b0: blocked (réel) #16352, #16391, #16464, #16517 réserves tierces non levées

Le motif décide du destinataire ET du geste : un checks mort part à l'adjoint pour un --template, un b0 réel part à la lane porteuse pour une phrase de levée, un rouge CI réel part pour un re-run ou une réparation. Sans motif exposé, ces trois dispatches sont indiscernables.

Ce qui est demandé

Sur exit 3 (et idéalement sur exit 0), que --json porte les champs du dossier déjà parsés :

{"pr": 16219, "head": "292badb745ef...", "ready": false, "verdict": "BLOCKED",
 "errors": [],
 "dossier": {"lane": "myia-po-2025:CoursIA-2", "b0": "clear", "checks": "BLOCKED",
             "scope": "pass", "domain": "not-applicable",
             "comment_id": 5765…, "created_at": "2026-09-21T10:57:41Z"},
 "blocking_fields": ["checks"]}

blocking_fields est le cœur : la liste des champs qui portent le BLOCKED. C'est ce qui rend le tri automatisable, donc le dispatch groupable.

Acceptance

Hors scope

Grain: MED/guard -- lane myia-ai-01:CoursIA

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions