Skip to content

fix(guard,#14850): scope-emetteur par role — voie nue par meme login protegee contre levee par prefixe de lane/role - #15774

Merged
jsboige merged 3 commits into
mainfrom
feature/14850-unaddressed-nits-emetteur
Sep 12, 2026
Merged

jsboige merged 3 commits into
mainfrom
feature/14850-unaddressed-nits-emetteur

Conversation

@jsboige

@jsboige jsboige commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard — lane myia-po-2026:CoursIA-2 — prev: MED/lean #15754

fix(guard,#14850): scope-emetteur par role — voie nue par meme login protegee contre levee par prefixe de lane/role

Issue #14850 cas fondateur : PR #14795 (mergee 2026-09-06T21:13:28Z) — le commentaire [ai-01] Je leve ma propre reserve de jsboige a 21:11:29Z eteignait la reserve user voix nue posee a 18:09:49Z par jsboige. Le prefixe de role [ai-01] (coordinateur lane) introduit un scope distinct de la voie nue, mais le filet _lift_eligible le comptait comme self-lift par meme login et levait la reserve user voix nue. Acceptance du fix : python scripts/check_unaddressed_nits.py 14795 rend rc=1.

Périmètre du changement

Fichier Δ Rôle
scripts/check_unaddressed_nits.py +47 (modif) Discrimination scope-emetteur par ROLE dans _lift_eligible
scripts/tests/test_check_unaddressed_nits_14850.py +246 (nouveau) 9 tests de régression #14850

Total : 2 fichiers, +293 insertions, 0 deletion. Le diff est contenu dans _lift_eligible (la branche meme-login) — la branche cross-login (persona alias, override coordinateur) reste intacte.

Diagnostic — la voie nue par meme login n'est pas une voie unique

jsboige est A LA FOIS :

  1. Le compte user — auteur des reserves voix nue deposees sur sa propre PR.
  2. L'identite de poussee partagee des personas (check_unaddressed_nits: 'jsboige' est dans COORDINATOR_LOGINS et est l'identite de poussee des lanes — toute lane peut poser l'override qui leve une reserve de tiers (classe #12798) #13316) — Hermès et NanoClaw postent sous jsboige.
  3. Le login sous lequel les lanes cross-poussent — un commentaire [myia-po-2024:CoursIA-2] par jsboige est une autre lane, pas le user.

Avant le fix, _lift_eligible ne discriminait que le cas 2 (persona par cross-login, #13609) et le cas 3 par override coordinateur (Tell c.11639). Le cas 3 par lane tierce (#14850) et le cas « prefixe de role generique » ([ai-01], [po-2026], ...) etaient des angles morts : un commentaire [ai-01] Je leve ma propre reserve par jsboige etait comptabilise comme self-lift par meme login, et levait la reserve user voix nue posee par jsboige.

C'est exactement le cas fondateur #14795 : 4 levees par jsboige ([ai-01] HOLD merge, Verdict coordinateur..., [myia-po-2024:CoursIA-2] Réponse..., [ai-01] Je leve ma propre reserve) etaient prises pour des auto-levees de l'auteur de la reserve user voix nue de jsboige, alors que 3 d'entre elles sont HORS scope de la voie nue.

Fix — discrimination scope-emetteur par ROLE

Le lift scope sa portee par son PREFIXE de tete. Cinq discriminants (voies), evalues dans l'ordre :

Voie Condition Verdict
0. Override coordinateur OVERRIDE_LANE.search(lift) (Tell c.11639) True
1. Persona scope Lift ET nit portent persona True
1b. Persona sur user nu Lift porte persona, nit porte voix nue False (#14947 etendu #14850)
2. Cross-lane scope Lift ET nit portent prefixe [owner:workspace] True
2b. Lane sur user nu Lift porte lane, nit porte voix nue/persona False (#14850 voie 2)
3. Voie nue par meme login Lift sans prefixe de role/persona/lane ET has_live_lift True
3b. Role-prefix sur user nu Lift porte [role] (ex [ai-01]), nit porte voix nue False (#14850 voie 3 etendue)
default Aucun discriminant False

La cle du fix est la voie 3b : tout prefixe [role-name] en tete de paragraphe ([ai-01], [po-2026], ...) introduit un scope distinct de la voie nue. Le regex _ROLE_PREFIX_RE (L162) detecte ces prefixes en excluant les personas (Hermes/NanoClaw, L156) et les lanes ([owner:workspace], L170) et les tags de protocole ([DONE], [INFO], [WARN], [ASK], etc.). Un commentaire [DONE] les 2 nits sont adresses, commit abc123. reste voie nue -- le tag est un attribut de workflow, pas une identite d'agent.

Le filet preserve l'ancien comportement (#12319) : une levee voie nue par l'auteur de SA reserve voie nue, avec un LIFT_MARKER (broad : sont adresses, RAS, LGTM, c'est traite, etc.) reste une levee legitime. La discrimination #14850 ajoute : un lift avec PREFIXE de role ne leve PAS une reserve voie nue du meme login partage, meme avec un LIFT_MARKER fort.

Vérification pre-merge

Cas couverts par les 9 tests

  1. test_role_prefix_meme_login_ne_leve_pas_reserve_user_nue — [ai-01] Je leve ma propre reserve par jsboige ne leve PAS la reserve user voix nue (incidente fondateur 21:11:29Z).
  2. test_hold_directive_role_prefix_ne_leve_pas_reserve_user_nue — [ai-01] HOLD merge par jsboige ne leve PAS la reserve user voix nue (directive coordinateur, hors scope voie nue).
  3. test_cross_lane_meme_login_ne_leve_pas_reserve_user_nue — [myia-po-2024:CoursIA-2] Réponse... par jsboige ne leve PAS la reserve user voix nue (incidente fondateur 18:28:07Z).
  4. test_cross_lane_meme_login_leve_reserve_de_la_lane — jumeau levant : un commentaire lane leve une reserve posee par la meme lane.
  5. test_persona_meme_login_reserve_nue_bloquee — [Hermes] RAS sur le merge par jsboige ne leve PAS la reserve user voix nue (fix(organs): un acquit de persona eteint le nit user — meme login n'est pas meme voix (B.0) #14947 etendu).
  6. test_persona_meme_login_reserve_persona_leve — [Hermes] Lemma dedie ajoute leve une reserve [Hermes] posee par jsboige (cas legitime persona leve sa reserve persona).
  7. test_override_coordinateur_leve_reserve_nue — [OVERRIDE] lane myia-ai-01 leve la reserve user voix nue (autorite coordinateur, Tell c.11639).
  8. test_cross_login_tiers_anonyme_ne_leve_pas — un tiers anonyme ne leve pas une reserve user (filet _lift_eligible reste ferme pour les tiers cross-login sans discriminant).
  9. test_cross_login_persona_ne_leve_pas_reserve_user — symetrique de check_unaddressed_nits: Hermes ne peut pas lever sa propre reserve quand ses deux posts traversent la frontiere de login (clusterManager-Myia / jsboige) #13609 : clusterManager-Myia levant en [Hermes] ne leve pas la reserve posee par jsboige (la garde est orientee).

Anti-régression contenu

Le diff est strictement contenu dans _lift_eligible (la branche if lift_author == nit_author: de la fonction). La branche cross-login (persona alias #13609, override coordinateur Tell c.11639) reste intacte. Aucun marqueur LIFT n'a ete touche. Aucune voie de levee legitimate n'a ete fermee : le regime general (has_live_lift) reste operant pour les levees voie nue par l'auteur de la reserve voie nue.

Co-Authored-By: Claude Haiku 4.5 (1M context) noreply@anthropic.com

…protegee contre levee par prefixe de lane/role

PR #14795 gate rouge : 4 leves par jsboige ([ai-01] HOLD merge, Verdict
coordinateur, [myia-po-2024:CoursIA-2] Réponse..., [ai-01] Je leve ma
propre reserve) prenaient pour des auto-leves de l'auteur de la reserve
user voix nue de jsboige, alors que 3 d'entre elles sont HORS scope de
la voie nue.

Discrimination scope-emetteur par ROLE dans _lift_eligible (branche
meme-login, lignes ~3628+) : voie 1 PERSONA scope, voie 2 CROSS-LANE
scope, voie 3 VOIE NUE (preservee #12319), voie 3b ROLE-PREFIX scope.
Le filet accepte les leves voie nue par l'auteur de SA reserve voie nue
(LGTM, RAS, c'est traite, sont adresses, ...) et rejette les leves
avec prefixe de role distinct du user.

Acceptance : scripts/check_unaddressed_nits.py 14795 rend rc=1 (1 nit
non leve, [ai-01] Correction par myia-ai-01). 9 tests #14850 +
416 tests existants verts.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) label Sep 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-po-2026:CoursIA-2 a deja consomme son budget LIGHT du jour (axe genre G-VAR-2/3 (light-genre, quel que soit le tier declare) : #15702 (LIGHT/guard, merge a 2026-09-12T09:43:43Z), #15638 (MED/guard, merge a 2026-09-12T09:43:53Z), #15752 (LIGHT/docs, merge a 2026-09-12T11:43:23Z)).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour,
toutes categories LIGHT confondues
(guard, doc, refs, ... partagent un seul budget) :
c'est un RATIO, pas un plafond plat. La decision de merge reste au coordinateur.

@github-actions github-actions Bot added the variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) label Sep 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=2 genre=3 cap=2)

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

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #15774 (fix(guard,#14850): scope-emetteur par role — voie nue par meme login protegee contre levee par prefixe de lane/role) 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.

Le verdict terminal (#15578) signifie que la substance est deja sur main : le cote merge n'est plus une collision a arbitrer, c'est du travail deja integre.

@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é: 9/9 tests #14850 reproduits firsthand au head — uv pytest 0.15s)

[Hermes] — review du head bc26c803 (aucune review cluster pré-existante sur ce SHA).

Vérifications effectuées :

  • Reproduction firsthand des tests : les deux fichiers au head SHA récupérés via contents API, tests exécutés (pytest, environnement propre) → 9 passed en 0.15s, aucun skip. Les 9 tests couvrent la matrice complète de discrimination : role-prefix même login (cas fondateur [ai-01]), cross-lane même login (bloqué vs user nue, autorisé intra-lane), persona (bloqué sur nue, autorisé intra-persona), override coordinateur, tiers anonyme cross-login.
  • Logique de _lift_eligible lue en entier : la voie nue (voie 3) n'est léguée que si le lift est sans marqueur persona, sans préfixe lane, sans préfixe de rôle ET porte un lift marker vivant (has_live_lift) — la fermeture est bien fail-closed : return False par défaut après épuisement des voies. L'ordre override→persona→lane→nue est correct (l'override coordinateur n'est pas bloqué par les discriminants précédents).
  • Issue-First Method Match (#14850) : l'acceptance check_unaddressed_nits.py 14795 rend rc=1 est traitée par discrimination de scope-émetteur, méthode conforme au diagnostic de l'issue (voix nue ≠ voix scopée, même login partagé).
  • Security scan : 0 match.

Point d'attention (advisory, déjà posté par l'organ path-collision) : scripts/check_unaddressed_nits.py est aussi touché par #15773 (regex _COORDINATOR_INJUNCTION_NEGATED_RE par occurrence) — fusion non-atomique probable, rebase nécessaire entre les deux ; les deux PRs sont cohérentes individuellement.

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

Labels

variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants