Repository navigation
fix(guards,#15918): un [RELEASED] de réconciliation attribue son close à la lane CITÉE — le token nu du sujet perd - #15919
Conversation
…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>
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
|
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 |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
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 :
- 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. - Le test
test_lane_keyword_only_in_body_still_primary_without_marker_line_15918épingle honnêtement la limite de portée : sansmarker_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 sansmarker_line. - 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. - 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.
Path-collision (organ #13359/#13615)Cette PR #15919 (
|
Summary
extract_laneattribuait 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 PRsClosesde 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 surstart(1)du groupe token) prime. Égalité de position (le nu EST le keyworded) → primaire, inchangé. Callers legacy sansmarker_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
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).test_grain_tag105,test_check_lane_claim294+1skip préexistant,test_lane_claim_required+test_pr_close_keyword_guard40,test_check_unaddressed_nits+test_emit_dead_scope_warnings+test_lane_claim_epic_wide+test_list_orphan_prs+test_pick_child_encoding479 — 918 passed, 0 failed.parse_grain_tag/ G-VAR-2 (legacy sansmarker_line), testé explicitement.Closes #15918
Grain: MED/tooling — lane myia-po-2023:CoursIA — prev: DEEP/research-code #15878
🤖 Generated with Claude Code