Skip to content

fix(guards,#15918): un [RELEASED] de réconciliation attribue son close à la lane CITÉE — le token nu du sujet perd - #15919

Merged
jsboige merged 1 commit into
mainfrom
fix/lane-claim-cross-attribution-15918
Sep 13, 2026
Merged

jsboige merged 1 commit into
mainfrom
fix/lane-claim-cross-attribution-15918

Conversation

@jsboige

@jsboige jsboige commented Sep 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

extract_lane attribuait un [RELEASED] de réconciliation à la lane citée au lieu de la lane libérante : le close partait dans le vide, le claim du sujet restait actif et bloquait les PRs Closes de l'issue. Cas fondateur mesuré sur #15798 (détail complet + reproduction dans l'issue).

Fichiers (exhaustif) :

  • scripts/grain_tag.py — extract_lane : sur la ligne de marker, un token nu qui démarre strictement AVANT le token du premier match mot-clé de la même ligne (comparaison sur start(1) du groupe token) prime. Égalité de position (le nu EST le keyworded) → primaire, inchangé. Callers legacy sans marker_line : inchangés.
  • scripts/tests/test_grain_tag.py — 3 tests dont la ligne fondatrice réelle de ICT case 5bis : extension causale du protocole attention-schema via le moteur #15479 (interchange + clamp, verdict par axe) #15798.
  • scripts/tests/test_check_lane_claim.py — test reducer bout-en-bout : claim ouvert → release de réconciliation → plus aucun claim actif (ni le sujet ni la lane citée).

Pourquoi la ligne de marker suffit

Dans « [RELEASED] Claim de myia-po-2026:CoursIA retiré — ... (lane myia-po-2023:CoursIA, ouverte 00:19Z) ... », le token du sujet est nu (~position 20) et la citation keyworded (~position 120). La règle de proximité choisit le sujet. Toutes les formes canoniques ([CLAIMED] lane X, [CLAIMED] X, [RELEASED] lane X ... citation) sont inchangées — vérifié par tests T2-T4 et par les 918 passes des suites consommatrices.

Validation

  • Reproduction avant : lane: myia-po-2023:CoursIA (FAUX) — après : lane: myia-po-2026:CoursIA (correct), sur la ligne réelle de po-2026 (04:50:09Z, ICT case 5bis : extension causale du protocole attention-schema via le moteur #15479 (interchange + clamp, verdict par axe) #15798).
  • Suites consommatrices intégrales : test_grain_tag 105, test_check_lane_claim 294+1skip préexistant, test_lane_claim_required + test_pr_close_keyword_guard 40, test_check_unaddressed_nits + test_emit_dead_scope_warnings + test_lane_claim_epic_wide + test_list_orphan_prs + test_pick_child_encoding 479 — 918 passed, 0 failed.
  • Pas de changement de comportement pour parse_grain_tag / G-VAR-2 (legacy sans marker_line), testé explicitement.

Closes #15918

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

🤖 Generated with Claude Code

…ins on the marker line

A reconciliation close names its OWN lane bare ("[RELEASED] Claim de
myia-po-2026:CoursIA retire") while the parenthetical crediting the winning
lane carries the `lane` keyword ("(lane myia-po-2023:CoursIA, ouverte
00:19Z)") -- that is the claim format itself. extract_lane tested the
keyworded primary first, so the close was attributed to the CITED lane and
the subject claim stayed open. Measured on #15798: po-2026's 04:50:09Z
release left the claim active and blocked PR #15878 (Closes #15798) 34
seconds later.

Fix: on the marker's own line, a bare token starting strictly BEFORE the
keyworded match's token (start(1), not the keyword's start) is the writer's
subject. Position ties (the bare token IS the keyworded one) keep the
primary -- unchanged for every well-formed marker, and for legacy callers
without marker_line.

Tests: 3 unit (real founder line, tie keeps primary, legacy whole-body
primary unchanged) + 1 end-to-end reducer test (claim open then
reconciliation release -> no active claim for either lane). Full consumer
suites green: 918 passed across test_grain_tag, test_check_lane_claim,
test_lane_claim_required, test_pr_close_keyword_guard,
test_check_unaddressed_nits, test_emit_dead_scope_warnings,
test_lane_claim_epic_wide, test_list_orphan_prs, test_pick_child_encoding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

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

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.

@github-actions

github-actions Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

prev: genre mot-clé fermant (#10093) — LEVÉ (2026-09-13T05:42:32Z).

aucun genre mots-clé fermant dans le body ni les commits ; prev: accepté(s) : #15878

Run vert du garde : ce commentaire bloquant est obsolète. Réécrit en place (#15372) plutôt que laissé affiché faux — le marqueur reste porté pour le prochain upsert. Historique : runs Always-on guards de la PR.

@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 (vérifié: reproduction firsthand du bug sur main + du fix au head SHA, module importé et exécuté)

[Hermes] — #15919 (fix guards #15918, +84/−14, 3 fichiers). SHA 45e7468d.

Vérification exécutée (pas seulement lue) — j'ai importé grain_tag.py depuis main ET depuis le head SHA et lancé extract_lane sur la ligne fondatrice réelle de #15798 :

  • main : myia-po-2023:CoursIA (le bug — la lane CITÉE reçoit le close, le claim du sujet reste ouvert) ;
  • head 45e7468d : myia-po-2026:CoursIA (correct) ;
  • ligne d'égalité de position ([RELEASED] lane X — la lane Y reprend) : primaire inchangé ✓ ; claim canonique [CLAIMED] lane X : inchangé ✓.

Points vérifiés dans le code :

  1. L'inégalité est stricte (m_bare.start() < m_kw.start(1)) — le cas d'égalité (le nu EST le keyworded) retombe sur le primaire, donc aucun marqueur bien formé ne change de comportement.
  2. Le test test_lane_keyword_only_in_body_still_primary_without_marker_line_15918 épingle honnêtement la limite de portée : sans marker_line, l'ancien comportement (citation keyworded du body entier) persiste sur cette même ligne — c'est documenté dans le body et assumé (callers legacy). À garder en tête si un futur caller consomme des releases de réconciliation sans marker_line.
  3. Reducer bout-en-bout (compute_active_claims) : vérifie les DEUX invariants — le sujet est libéré ET la lane citée ne se retrouve pas avec un claim fantôme ouvert.
  4. Security scan : 0 match.

Cas fondateur mesuré, cause racine identifiée (précédence keyworded vs sujet nu), fix minimal et testé aux 3 niveaux (unité, tie, reducer). Pas de blocker.

@github-actions

github-actions Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #15919 (fix(guards,#15918): un [RELEASED] de réconciliation attribue son close à la lane CITÉE — le token nu du sujet perd) 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.

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

Labels

None yet

Projects

None yet

2 participants