Skip to content

ci(lane-claim): un [RELEASED] de réconciliation attribue son close à la lane CITÉE — le token nu du sujet perd contre « lane <token> » de la citation #15918

Description

@jsboige

Observation (mesure firsthand, 2026-09-13)

Un [RELEASED] de réconciliation sur #15798 (po-2026, 04:50:09Z) a été attribué à la lane citée au lieu de la lane libérante. Conséquence mesurée : lane_claim_required.py rend

{"guard_pass": false, "reason": "#15798: lane myia-po-2026:CoursIA holds an active claim (since 2026-09-13T04:25:31Z)"}

…et bloque la PR #15878 (Closes #15798) alors que po-2026 a explicitement libéré le grain (sa PR #15914 fermée superseded) 34 secondes avant le push.

Reproduction

import check_lane_claim as clc
comment = {'body': '[RELEASED] Claim de myia-po-2026:CoursIA retiré — réconcilié : la PR #15878 (lane myia-po-2023:CoursIA, ouverte 00:19Z) couvre le grain en surensemble.', 'author': {'login': 'jsboige'}, 'createdAt': '2026-09-13T04:50:09Z'}
print(clc._parse_claim_events(comment))
# → marker: RELEASED | action: close | lane: myia-po-2023:CoursIA   ← FAUX

Cause racine

grain_tag.extract_lane (celle du #10395 Variante 1) teste dans cet ordre :

  1. primaire _LANE_RE = lane\s*:?\s+<token> (mot-clé lane exigé) — sur la ligne, puis sur le body entier ;
  2. fallback _LANE_FALLBACK_RE = token nu — sur la ligne de marker seulement.

Dans la ligne du marker, le token du sujet (« Claim de myia-po-2026:CoursIA retiré ») est nu (pas de mot-clé devant), tandis que la citation de l'autre lane (« (lane myia-po-2023:CoursIA, ouverte 00:19Z) ») porte le mot-clé. Le primaire matche la citation → le close est attribué à la lane citée (no-op si elle n'a pas de claim), le claim du sujet reste OPEN.

Pourquoi c'est structurel

Une réconciliation de collision mentionne par nature la lane gagnante — souvent au format « lane X » (le format des claims eux-mêmes). Tout [RELEASED]/[DELIVERED] de réconciliation dont le propre token est nu est donc à risque d'attribution croisée. Le cas #15864 (point final, PR #15866) est un bug voisin de la même fonction mais distinct (résidu de période dans le token vs ordre primaire/fallback).

Fix proposé

Dans extract_lane, quand marker_line est fourni : si un token nu matche sur la ligne avant le token du premier match mot-clé de la même ligne (comparaison sur start(1) du groupe token, pas sur le début du mot-clé), le token nu prime — proximité au marker = intention du rédacteur (#10881 étendu au conflit primaire/fallback). Égalité de position (le nu EST le token keyworded) → primaire, comportement inchangé.

Activity

  1. jsboige commented on Sep 13, 2026

    @jsboige
    OwnerAuthor

    Grain: MED/tooling — lane myia-po-2023:CoursIA — prev: DEEP/research-code #15798

    [CLAIMED] myia-po-2023:CoursIA — paths: scripts/grain_tag.py, scripts/tests/test_grain_tag.py, scripts/tests/test_check_lane_claim.py — 2026-09-13T07:20Z

  2. jsboige commented on Sep 13, 2026

    @jsboige
    OwnerAuthor

    [DELIVERED] lane myia-po-2023:CoursIA — PR #15919 (fix extract_lane + 3 tests unit + 1 test reducer, 918 passed suites consommatrices). Issue entièrement résolue par la PR.

  3. added a commit that references this issue on Sep 13, 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