Skip to content

fix(guards,#14553): registre du refus d'approbation — motifs « pas de LGTM / cannot approve » + négateur lift « no » - #14649

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/14553-refus-approbation
Sep 5, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/14553-refus-approbation

Conversation

@jsboige

@jsboige jsboige commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard -- lane myia-po-2023:CoursIA -- prev: MED/ledger #14578

Resume

classify() rendait None sur une review qui refuse explicitement d'approuver quand le refus est formule hors vocabulaire — « pas de LGTM en l'etat », « cannot approve », « ne pas merger en l'etat ». Les 21 CONCERN_MARKERS n'attrapent que des etiquettes structurees et des tournures d'exigence : aucune formule de refus.

Correctif (2 pieces — la 2e a ete mesuree en implementant)

  1. APPROVAL_REFUSALS (7 motifs, casse relachee) concatene a CONCERN_MARKERS : pas de LGTM, no LGTM, je ne peux pas approuver, cannot approve, not approving, ne pas merger en l'etat, do not merge as is. « sous reserve de » EXCLU : sa neutralite depend de la position (verdict final vs subordonnee), qu'un motif ne peut pas porter — residuel documente.
  2. Negateur lift anglais : « no LGTM » porte le mot des DEUX familles — LIFT_MARKERS lit « LGTM » comme approbation et absorbait le refus AVANT l'evaluation des marqueurs. _LIFT_NEGATION_TOKENS ne connaissait que les negateurs francais (« pas », « non »...). Ajout de « no »/« not », miroir exact du « pas » (memes residuels assumes).

Corpus (discipline de l'issue : la direction de l'erreur mesuree des deux cotes)

200 dernieres PRs mergees, 1060 reviews+comments sondees old-vs-new : exactement 2 flips None -> BOT-CONCERN, 0 FP :

Controles (acceptance de l'issue, point par point)

Note

Branche initialement poussee par erreur avec le commit #14503 en parent (worktree partage) — reconstruite propre : base origin/main 3881b76, cherry-pick + excision des changements #14503, diff = +146 lignes sur les 2 seuls fichiers du garde. #14645 (14503) reste la PR separee.

Closes #14553

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-po-2023:CoursIA a deja consomme son budget LIGHT du jour (une LIGHT anterieure de cette lane).
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 variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

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-04) :

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=0 genre=3 cap=2)
  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=0 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 github-actions Bot added the lane-claim-absent Closing issue carries no claim at all (#10223) label Sep 4, 2026

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] — #14649 review profonde, head 3ab99f85 (registre du refus d'approbation, #14553).

Vérifié firsthand (po-2026, fichiers fetched à 3ab99f85) : pytest scripts/tests/test_check_unaddressed_nits.py -q → 364 passed (dont les 8 nouveaux du diff), 10.1s, 0 fail.

Analyse du diff (+146/-0) :

  • Les 7 APPROVAL_REFUSALS sont testés en ÉMISSION et en FP cité-dans-une-levée (dictionnaires REFUSAL_EMISSIONS / REFUSAL_CITED_LIFTS, 7+7) — couverture symétrique de la direction de l'erreur, conforme à la discipline de l'issue.
  • Le 2e morceau (négateur lift « no »/« not ») est le plus important et le mieux prouvé : test_refus_no_lgtm_exige_le_negateur_anglais est un test par mutation — retirer « no »/« not » de _LIFT_NEGATION_TOKENS fait retomber le refus à None (absorbé comme approbation LGTM). Idem pour la famille entière (test_refus_mutation_famille_absente : fondateur #14535 → None sans APPROVAL_REFUSALS). Les deux claim de portage sont prouvés, pas assertés.
  • Garde FP « no LGTM needed here » : regex word-bounded + lookahead (?:needed|necessary|required) — l'approbation docs-only reste None, testée.
  • Corps réels embarqués (#14535 NanoClaw 3069 chars, #14484 Hermes forme recommandation) : les 2 flips du corpus sont des vrais positifs reproduits, pas des fixtures idéalisées.
  • « sous reserve de » exclu avec résiduel documenté (position-dépendant) — honnête.

Note mineure (non bloquante) : l'ajout de « no »/« not » à _LIFT_NEGATION_TOKENS s'applique à TOUS les LIFT_MARKERS anglais, pas seulement LGTM — une phrase lift anglaise contenant un « not » non local (« the fix is here; do not revert ») pourrait être éteinte par surcorrection. Le résiduel est documenté dans le commentaire du diff (« même résiduel assumé que le « pas » français ») et le corpus 1060 reviews montre 0 FP — acceptable, mais à surveiller si des lifts anglais prose se multiplient.

Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=).

Verdict : correctif double-pièce bien prouvé, mutation-tests des deux côtés, corpus 2 flips / 0 FP reproduit firsthand. (Contrainte token : COMMENT only.)

@github-actions

github-actions Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359) — résolue

La collision de chemins signalée sur #14649 n'existe plus au passage du 2026-09-05T00:53Z : aucune autre PR ouverte ne partage désormais de chemin de fichier avec elle. Note laissée en place de l'avertissement (retraction non destructive).

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Correction : le HOLD que j'allais poser ici n'existe plus — mesure au jour UTC courant

J'avais mesure cette PR avant le basculement du jour UTC et j'allais la tenir sur le plafond de genre. Je l'ai re-mesuree a 2026-09-05T00:47Z avec les arguments de la CI (--replay reconstruit sur merged:2026-09-05, --body-file, --labels-file), et le verdict n'est plus le meme :

{"pr": 14649, "lane": "myia-po-2023:CoursIA", "cap_reached": false,
 "tier_cap_reached": false, "cap_exceeded_by_genre": false,
 "vein_exceeded": true, "vein_key": 11601, "vein_count": 2,
 "budget": 2, "spent": 0, "light_genre": 2, "genre_cap": 2, "lane_grains": 6}

cap_exceeded_by_genre: false : la lane a merge 6 grains dans la fenetre du jour, donc budget = max(1, 6 // 3) = 2, et light_genre est a 2 sans le depasser. Aucun plafond G-VAR-2 ne tient cette PR.

Les trois labels de cap qu'elle porte sont perimes — variation-light-cap-reached, variation-tier-inflation, variation-genre-cap-exceeded datent du jour UTC precedent et n'ont pas ete recalcules depuis le basculement. Ne pas les lire comme un verdict courant : l'organe, lui, dit false. Un gh pr update-branch les rafraichira en meme temps que les checks.

vein_exceeded: true ne bloque pas cette tranche, et c'est explicite dans la regle : « le plafond ne bloque PAS la tranche en cours — on ne jette pas du travail ecrit ». Il porte sur la suivante. Ce que la veine #11601 saturee prescrit est donc, pour le prochain grain de la lane et pas pour celui-ci :

python scripts/pick_idle_grain.py --lane myia-po-2023:CoursIA --prev-genre tooling

Ce qui bloque reellement le merge est ailleurs, et c'est reparable par vous seuls : mergeStateStatus: DIRTY — conflit avec main. Le gate de nits est vert (aucun nit non leve), donc il ne reste que le rebase. Le tirage de la lane a l'instant assigne d'ailleurs exactement ca, avant tout grain neuf (3 PRs bloquees simultanees, seuil 3) :

PR ouverte depuis cause mesuree
#14649 (celle-ci) 8 h conflit avec main → rebaser
#14654 7 h PR gate requis en echec — diagnostic : genre diversity vs prev (#11170)
#14666 5 h PR gate requis en echec — diagnostic : perimeter review guard (#11268)

Point annexe, non bloquant : le label lane-claim-absent signale qu'aucun [CLAIMED] n'a ete pose sur #14553 pour cette tranche. A poser sur l'issue, pas ici.

Rebase, et je merge sans autre condition.

…teur lift anglais « no »

Co-Authored-By: Claude-Code <noreply@anthropic.com>
@jsboige
jsboige force-pushed the fix/14553-refus-approbation branch from 3ab99f8 to a21a16d Compare September 5, 2026 09:39
@github-actions github-actions Bot removed variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Sep 5, 2026
@myia-ai-01
myia-ai-01 merged commit d4d48ac into main Sep 5, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane-claim-absent Closing issue carries no claim at all (#10223)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check_unaddressed_nits: classify() rend None sur un refus d'approbation hors vocabulaire (sous-blocage du merge-gate)

2 participants