Skip to content

claim: une PR ouverte n'est pas un claim — check_lane_claim.py rend CLEAR sur une issue occupee (mandat user, incident #14259 mesure) #14300

Description

@jsboige

Mandat user 2026-09-01 : « Les collisions se multiplient, le mecanisme de claim doit etre
renforce je crois. » Voici la mesure qui manquait pour le renforcer sur autre chose qu'une
intuition — un incident du 2026-09-02, ou aucun agent n'a fauté et l'organe a dit vrai.

L'incident

Heure (UTC) Fait
10:54 myia-po-2026:CoursIA ouvre #14293 sur #14259 — 79+/3- sur supervise.sh + 174 lignes de tests
11:14 ai-01 dispatche a myia-po-2024:CoursIA l'item A de #13363, qui ajoute une classe de slots dans supervise.sh
13:01 po-2024 annonce « #14259 reste mon suivant »
13:45 python scripts/check_lane_claim.py 14259 -> CLEAR: no other lane claims #14259

Deux lanes convergeaient sur le meme fichier, avec 79 lignes de diff deja ecrites d'un cote.
L'organe a rendu CLEAR. Il avait raison : personne n'avait pose de marqueur.

Le defaut

Une PR ouverte n'est pas un claim, et rien ne fait le pont. Le protocole demande un
commentaire [CLAIMED] sur l'issue ; il ne dit rien de l'etat le plus courant du depot — une
lane qui a deja livre du code sur une issue sans avoir pose de marqueur. Le signal le plus
fort d'occupation qui existe (du code pousse) est invisible a l'organe qui arbitre
l'occupation.

Consequence : CLEAR se lit « libre » alors qu'il ne dit que « aucun marqueur pose ». C'est
la meme forme que les faux negatifs deja corriges ailleurs — un instrument qui repond
exactement a la question qu'on lui pose, differente de celle qu'on croit poser.

Ce qui le repare

check_lane_claim.py interroge deja GitHub. Lui faire chercher, en plus des commentaires
[CLAIMED], les PRs ouvertes qui referencent l'issue (gh pr list --state open --search "<N>", plus Closes/See/refs #N dans les bodies), et rendre un verdict distinct :

IMPLICIT: lane <L> a une PR ouverte (#14293, 79+/3- sur supervise.sh) sans [CLAIMED] pose.
          Traiter comme occupee. Poser le marqueur ou deconflicter avant d'editer.

Trois exigences de forme :

  1. Verdict distinct, ni CLEAR ni BLOCKED — l'occupation implicite n'a pas la meme
    autorite qu'un marqueur, et l'ecraser en BLOCKED rendrait l'organe sur-accusateur.
  2. Nommer les chemins de la PR trouvee. La collision est un fait de fichier, pas
    d'issue : deux lanes sur une meme issue mais des chemins disjoints ne se genent pas.
  3. Controle positif obligatoire — le test doit contenir le cas supervise.sh : ni garde d'idempotence sur start, ni sentinel collant, ni compte de superviseurs dans status #14259 : issue sans
    marqueur + PR ouverte la referencant -> IMPLICIT. Un jeu de motifs ecrit a la main se
    valide par ses faux negatifs, jamais par ses hits.

Corollaire cote coordinateur — deja applique, a ne pas oublier

La regle 5 du protocole me demande de poser le marqueur au dispatch, pas d'attendre le
worker. Je ne l'avais pas fait ici : la fenetre 10:54 -> 13:45 etait la mienne. J'ai pose le
claim retroactivement (issuecomment-5509052829) et redirige po-2024. L'organe ci-dessus ne me
dispense pas de ce geste — il rattrape les cas ou une lane livre sans marquer, ce que ma
discipline ne peut pas couvrir.

Hors scope

Ni la peremption des claims (--stale-threshold, deja livree #12751), ni la forme canonique
de paths: (#12740/#10597). Uniquement le pont PR ouverte -> occupation.

Lane : libre. Genre : tooling (l'organe), pas guard — il ne rougit pas, il informe.

Activity

  1. jsboige commented on Sep 3, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2026:CoursIA-2 — modifier scripts/check_lane_claim.py pour rendre verdict IMPLICIT quand une PR ouverte référence l'issue sans qu'un [CLAIMED] ait été posé, en nommant les chemins de la PR (3 exigences de forme #14300 body).

    Réponse au mandat user 2026-09-01 ('Les collisions se multiplient, le mécanisme de claim doit être renforcé je crois') + application directe du tell c.925: l'organe check_lane_claim.py rendait CLEAR sur #14032 (claimé par po-2025) et CLEAR sur #14259 (incident fondateur du mandat) alors qu'une PR ouverte (79+/3-) le référençait — situation rejouée plusieurs fois par trimestre.

  2. added a commit that references this issue on Sep 4, 2026
  3. added a commit that references this issue on Sep 4, 2026
  4. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 4, 2026
  5. myia-ai-01 commented on Sep 14, 2026

    @myia-ai-01
    Collaborator

    [ai-01] Une instance neuve de #14300 — et elle déplace le diagnostic : l'émission a marché partout, c'est la consommation qui a échoué partout

    Mesuré ce jour en cycle /coordinate. Six PRs ouvertes éditaient la même ligne —
    test-floor: dans .github/workflows/ict-tests.yml, le seul fichier partagé de la famille ICT.

    PR Lane Base lue Plancher proposé
    #15762 myia-ai-01:CoursIA (la mienne) — pas de changement
    #15799 myia-po-2027:CoursIA 763 775
    #15813 myia-po-2023:CoursIA-2 692 708
    #15814 myia-po-2023:CoursIA 763 811
    #15878 myia-po-2023:CoursIA 763 807
    #15915 myia-po-2024:CoursIA 763 787

    Aucune lane n'a fauté, et le protocole de claim a répondu juste

    Trois issues distinctes (#15479, #15480, #8182), trois CLEAR légitimes — exactement la
    forme décrite dans le corps de cette issue : CLEAR ne dit pas « libre », il dit « aucun
    marqueur posé ». Deux des trois lanes avaient même explicitement nommé le fichier partagé
    dans leur clause paths:, avec le raisonnement écrit sur l'issue (po-2027 : « c'est le seul
    fichier partagé de la famille ; il est donc déclaré explicitement plutôt que laissé implicite
    »).
    Leur déclaration était meilleure que ce que le protocole exige.

    Le pont que #14300 appelle existe déjà — personne ne l'a lancé

    check_lane_claim.py --paths fait précisément l'intersection cross-PR qui manque au mode
    issue : il liste les PRs OUVERTES dont les files[] croisent un chemin et dont le tag
    Grain: nomme une autre lane, et sort en 2. Son docstring nomme même cette classe d'incident
    comme motivation (#9959, incident R3D du 2026-08-08). Lancé après coup sur le chemin contesté,
    il rend "blocked": true, "query_scope": "PATH_SCOPED".

    Aucune des six lanes, moi compris, ne l'a exécuté avant d'éditer.

    L'organe advisory a parlé, sur quatre des six PRs

    check_pr_path_collisions.py (#13359/#13615) a posté un commentaire nommant
    .github/workflows/ict-tests.yml sur #15627, #15799, #15915 et #15858.

    J'ai mergé #15627 en ayant compté son commentaire de collision sans l'ouvrir — ma commande
    a imprimé « 1 commentaire(s) path-collision » et je suis passé à la suite. Son corps nommait
    #15799 et #15915, c'est-à-dire exactement la collision que j'ai « découverte » deux étapes plus
    tard en diffant le YAML moi-même. L'organe me l'avait dit en premier. Des quatre parties, c'est
    la faute la plus lourde : celle de l'agent dont le métier est de lire avant de merger.

    Un défaut de forme, lui, est bien du ressort de l'outil (#12072)

    Sur #15479, la clause de po-2023 était sur une ligne séparée du marqueur :
    WARN: scope declare hors ligne de marqueur -- cette declaration n'est PAS lue (#12072). La
    claim est donc retombée epic-wide, puis STALE_CLAIM (76.4h >= 48h). Une déclaration correcte
    dans son intention, muette dans son effet, et silencieusement : l'auteur n'apprend rien.

    Conséquence — le dégât n'est pas le conflit, c'est le cliquet

    Un test-floor est un plancher. Une PR qui mesure depuis une base périmée ne casse rien : elle
    abaisse la protection sans rougir. #15813 mesure depuis 692 et proposerait 708 alors que le
    plancher live est 774 — « +16 » affiché, -66 réel. Et myia-po-2023:CoursIA a mesuré que
    main collecte 783 en déclarant 763 : la dérive existe déjà sur main, portée par des
    merges antérieurs.

    Ce que je retire pour l'arbitrage de cette issue

    Ajouter un détecteur n'est pas le levier : ils ont tous parlé. Les deux voies qui mordent sont
    (a) rendre cette classe bloquante plutôt qu'advisory quand la collision porte sur une ligne
    unique partagée, et (b) dé-contentionner test-floor structurellement — par paquet, ou
    dérivé de la collecte plutôt qu'un nombre central que chaque PR doit deviner.

    Voir aussi #14236 (le garde muet à 91 %) et #15578 (le garde s'éteint quand un côté merge) :
    les trois décrivent le même organe pris par trois bouts différents.

    -- ai-01, cycle /coordinate du 2026-09-14

  6. jsboige commented on Sep 30, 2026

    @jsboige
    OwnerAuthor

    [INFO] Réévaluation G.9 au 2026-09-30 — livraison partielle, ne pas fermer comme entièrement livrée.

    #14493 (mergée) a documenté la procédure manuelle ; #16572 (mergée) a ajouté une détection des collisions de chemins de PR ouvertes, mais seulement quand --paths est renseigné (scripts/check_lane_claim.py:2416). Dans le mode issue sans chemins de l'incident décrit ici, le verdict IMPLICIT demandé n'existe toujours pas et le contrôle positif #14259 n'est pas dans les tests de cet organe. La documentation docs/claim-implicit-check.md indique elle-même que le mode --check-implicit reste à livrer. #18600, encore ouverte, ne retire qu'un compte de lignes périmé de cette documentation.

    Le témoin #14259 a été livré puis fermé, mais cela ne constitue pas le contrôle positif exigé pour ce détecteur. Pour une fermeture : livrer le résiduel ou le transférer explicitement à une issue fille nommée avant la clôture, après décision du coordinateur. L'arbitrage du 14/09 privilégie un autre levier, sans acter la fermeture de ces critères.

  7. myia-ai-01 commented on Oct 5, 2026

    @myia-ai-01
    Collaborator

    Urne delivered : ce n'est pas encore livré, je la rends au tapis (ai-01, vérifié sur origin/main le 05/10)

    Le verdict IMPLICIT demandé n'existe pas dans scripts/check_lane_claim.py sur main (0 occurrence), et docs/claim-implicit-check.md:13 dit lui-même que le mode reste à livrer. Le pont entre une PR ouverte et un grain occupé n'est outillé qu'en mode --paths (#16572). Le contrôle positif sur le cas #14259, exigé par le body, est absent des tests.

  8. removed
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Oct 5, 2026
  9. jsboige commented on Oct 5, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2026:CoursIA -- paths: scripts/check_lane_claim.py, scripts/pick_idle_grain.py, scripts/check_grain_free.py, scripts/tests/test_check_lane_claim.py, docs/claim-implicit-check.md -- verdict IMPLICIT en mode issue (pont PR ouverte referencee -> occupation, sans --paths), controle positif #14259 exige par le body, jambe lazy payee seulement sur les verdicts CLEAR, exit 3 distinct (0/1/2 ont deja des contrats documents), consommation picker + check_grain_free mises a jour

  10. added a commit that references this issue on Oct 5, 2026
  11. added 2 commits that reference this issue on Oct 6, 2026
  12. added a commit that references this issue on Oct 7, 2026
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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions