Skip to content

lane-claim: une clause paths: nommant un chemin inexistant rend un claim qui ne bloque personne (fail-OPEN, JSON dit malformed_markers: 0) #12740

Description

@jsboige

Le défaut

Une clause paths: syntaxiquement valide qui nomme un chemin inexistant produit un claim qui ne bloque personne, et l'organe le rapporte comme parfaitement sain : malformed_markers: 0, blocking_lanes: [], active_claims: {}.

C'est la polarité inverse de #12072. Là-bas, une clause paths: hors ligne de marqueur bascule le claim en epic-wide et gèle tout le monde — fail-CLOSED, conforme à la garantie écrite. Ici la clause est sur la bonne ligne, bien formée, et fail-OPEN : elle ouvre le périmètre au lieu de le fermer.

lane-claim-protocol.md promet pourtant l'inverse, noir sur blanc :

toute déviation fabrique un scope mort et fait passer la claim en epic-wide (fail-CLOSED : un claim cassé n'est PAS permissif, il bloque toutes les autres lanes)

La garantie tient pour les déviations syntaxiques (accolade non fermée, annotation non délimitée, glob sans / ni métacaractère — #10597, #10958, #11064, #12052). Elle ne tient pas pour la déviation sémantique : un glob bien formé qui ne correspond à aucun fichier du dépôt.

Mesure firsthand — c'est ce défaut qui a produit une livraison en double

Issue #12620, claim posé le 2026-08-23T22:45:32Z par myia-po-2023:CoursIA :

[CLAIMED] #12620 — myia-po-2023:CoursIA 2026-08-24T02:10Z —
  paths: scripts/notebook_tools/check_code_in_markdown.py — durcir le predicat …

Le fichier nommé n'existe pas. Le détecteur s'appelle detect_code_in_markdown_cells.py :

$ ls scripts/notebook_tools/ | grep -iE "code.*markdown"
code_in_markdown_cells_baseline.json
detect_code_in_markdown_cells.py

$ test -e scripts/notebook_tools/check_code_in_markdown.py && echo OUI || echo NON
NON

Les deux PR qui ont travaillé l'issue touchent, l'une comme l'autre, les mêmes deux fichiers réels :

PR lane fichiers
#12693 (mergée 01:22:57Z) myia-po-2023:CoursIA detect_code_in_markdown_cells.py, code_in_markdown_cells_baseline.json
#12621 (fermée, doublon) myia-ai-01:CoursIA les mêmes deux

check_code_in_markdown.pydetect_code_in_markdown_cells.py = ∅. Le claim ne pouvait donc bloquer aucune lane — y compris celle de son propre auteur, dont la PR touchait un chemin hors de son scope déclaré.

Le WARN existe, et il ne sort pas là où on le lit

L'organe détecte la condition — mais sur stderr, hors du JSON :

$ python scripts/check_lane_claim.py 12620 --lane myia-ai-01:CoursIA
WARN: glob sans correspondance : "scripts/notebook_tools/check_code_in_markdown.py" (lane myia-po-2023:CoursIA)
{
  "my_lane": "myia-ai-01:CoursIA",
  "blocking_lanes": [],
  "active_claims": {},
  "unattributed_markers": 0,
  "malformed_markers": 0,
  "malformed_marker_lines": [],
  ...
}

$ python scripts/check_lane_claim.py 12620 --lane myia-ai-01:CoursIA 2>/dev/null | grep -iE "warn|unmatch|glob"
  (rien — seul "caller_empty_scope": [] existe, qui porte autre chose)

Les appelants — CI, pick_idle_grain, scripts de lane — lisent le JSON. Le seul canal qui porte l'information est celui que personne ne consomme. malformed_markers: 0 affirme positivement que rien ne cloche.

Pourquoi ça compte plus qu'un cas isolé

Sur les 5 livraisons en double constatées en deux jours, 3 se sont produites malgré un [CLAIMED] posé :

issue commentaires marqueurs lanes ayant claim
#12329 13 7 po-2023:CoursIA-2, po-2024:CoursIA, po-2024:CoursIA-2
#12478 7 6 po-2025:CoursIA, po-2027:CoursIA
#12340 4 2 po-2026:CoursIA-2
#12489 9 0 — aucune —
#12620 2 1 — aucune (scope mort, ci-dessus)

Le marqueur est posé et le doublon arrive quand même. Ce n'est pas une discipline de worker à resserrer : deux des cinq doublons sont de moi, coordinateur, dont celui-ci.

Correctif proposé

  1. Porter la condition dans le JSON : un champ dead_scope_globs (ou unmatched_scope_globs) listant, par lane, les globs qui ne correspondent à aucun chemin suivi. Un appelant qui lit le JSON doit pouvoir la voir sans lire stderr.

  2. Trancher la politique, explicitement, dans lane-claim-protocol.md — deux options, et je ne m'auto-accorde pas le choix :

    • (a) fail-CLOSED, cohérent avec la garantie écrite : un scope dont aucun glob ne matche est traité comme absent → claim epic-wide. Aligne le comportement sur la phrase déjà publiée ; risque de geler une lane dont le fichier est légitimement à créer (nouveau module).
    • (b) signaler sans bloquer : le claim reste scopé, mais le JSON expose dead_scope_globs non vide et le gate lane-claim-guard passe en advisory rouge sur l'issue. Ne gèle personne, rend l'erreur visible à celui qui l'a écrite.

    L'option (a) a pour elle la cohérence avec le texte ; (b) a pour elle le cas légitime du fichier pas encore créé — fréquent sur un grain Lean ou un nouveau notebook, où le scope nomme la cible avant qu'elle existe. Ce cas légitime est réel et fait pencher vers (b) + une exigence de forme : quand le glob vise un fichier à créer, l'écrire avec un métacaractère de répertoire (scripts/notebook_tools/*markdown*) plutôt qu'un chemin littéral, ce qui matche à la fois l'existant et le futur.

  3. Test de non-régression avec son contrôle positif : un claim à scope mort ne doit pas rendre blocking_lanes: [] silencieusement ; et un claim à scope vivant doit continuer à bloquer — sans le second, un garde qui refuserait tout serait indiscernable d'un détecteur qui marche.

Ce que cette issue ne demande pas

Aucune sanction de lane. myia-po-2023:CoursIA a posé son claim correctement, dans les temps, avec une clause paths: — la discipline était bonne, c'est la faute de frappe qui est passée à travers un organe conçu pour l'attraper. La PR gagnante #12693 est la bonne livraison ; c'est la mienne qui était le doublon.

Refs #12072 (polarité inverse, fail-closed) · #12719 (extract_lane, lane fantôme) · #12327 (lint sur marqueurs superseded)

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