Skip to content

fix(picker,#14537): impute_base_reds corrobore par ORGANE et par LANE, pas par nom de job ni login - #14644

Merged
myia-ai-01 merged 1 commit into
mainfrom
tool/picker-organ-attribution-14537
Sep 5, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
tool/picker-organ-attribution-14537

Conversation

@jsboige

@jsboige jsboige commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Grain: MED/tooling -- lane myia-po-2026:CoursIA -- prev: MED/guard #14601

Quoi

Réfection des deux clés du prédicat impute_base_reds de scripts/pick_idle_grain.py (#14537) — l'imputation « ROUGE IMPUTE A LA BASE » qui gèle des PRs en routant leur rouge au coordinateur à tort :

Clé Avant (faux) Après
Regroupement NOM du check (les agrégateurs Always-on guards/PR gate portent un nom identique quel que soit l'organe tombé — corroboration garantie par construction) CAUSE : l'organe nommé par l'annotation du check-run (Organes bloquants en echec : <organe>) pour un agrégateur ; le nom pour un check direct (cas fondateur #13545 Scripts Tests (CPU), inchangé)
Unité de corroboration author.login (identité de poussée partagée des cinq lanes — 52/59 de l'ouvert ; le cas nominal n'était JAMAIS croisé, le verdict ne tenait qu'à l'accident du compte de poussée #14534) TAG DE LANE du grain tag
Dédup aucun (#14340 cité 3× comme sa propre corroboration) set — chaque PR est témoin unique

Fail-closed aux deux bouts (#14567) : une PR sans tag de lane lisible reste hors corroboration (elle n'irait grossir aucun seau), et un agrégateur sans organe lisible ne corrobore rien — il est dit dans la sortie (base_unresolved : « pas pu trancher, le rouge RESTE à la lane ») au lieu d'un silence lu comme un acquittement. Un agrégateur partiellement hérité (un organe à la base, un à la lane) reste une cause pour la lane.

Preuve (relancée après le dernier commit)

  • python -m pytest scripts/tests/test_pick_idle_grain.py = 95 passed (7 nouveaux/mis à jour), suites picker complètes (test_pick_idle_grain_cache, test_pick_admissibility, test_pick_child_encoding, test_pick_claim_filter, test_pick_filters, test_pick_nanoclaw_concerns, test_substance_drought) = 165 passed.
  • Run live (--lane myia-po-2026:CoursIA, 2026-09-04T16:25Z) — première sortie du prédicat réparé sur le réel :
ROUGE IMPUTE A LA BASE -- pas le votre, pas reparable par la lane :
  - Always-on guards -- 12 organes, 1 checkout :: adjacency : corrobore par #14596, #14638
  - Always-on guards -- 12 organes, 1 checkout :: prev_guard : corrobore par #14595, #14607, #14614, #14618, #14628
  - PR gate : organe non lisible sur #14595, #14614, ... -- pas pu trancher, le rouge RESTE a la lane

L'organe est résolu et nommé (acceptance 4 de #14567), et PR gate — dont l'annotation nomme des checks enfants, pas des organes — est correctement fail-closed au lieu de corroborer par son nom.

Acceptance #14537 → tests

  • (a) même organe sur ≥2 lanes toutes sous jsboige EST imputé (l'angle mort fondateur) : test_same_organ_two_lanes_same_push_login_is_imputed.
  • (b) organes DISTINCTS sous un nom d'agrégateur partagé PAS imputés (la table des six PRs réduite à trois lanes) : test_distinct_organs_under_one_aggregate_are_not_imputed.
  • Fail-closed dit : test_aggregate_with_unreadable_organ_stays_with_lane, test_untagged_pr_never_corroborates.
  • Dédup rollup : test_rollup_stack_does_not_self_corroborate.
  • Heritage par organe dans blocking_causes : test_partial_inheritance_keeps_the_lane_cause.
  • Cas fondateur picker : le garde « repare ton rouge d'abord » ne compare pas a la base — 11 PRs sur 37 accusees pour un echec de main #13545 préservé : test_base_inherited_red_is_not_the_lanes (mis à jour : PR gate résolu en organe au lieu de corroborer par nom).

Résiduel signalé (hors scope, arbitrable)

  1. PR gate reste non résolvable (fail-closed dit) : son annotation finale est [pr-gate] FAIL -- failing checks: <noms de checks enfants> — elle nomme des checks, pas des organes. Une résolution two-hop (annotation PR gate → check enfant nommé → SON annotation d'organe, les deux runs étant dans le même rollup) est possible en suivi.
  2. Premier effet live à arbitrer : le prédicat réparé impute désormais prev_guard (5 PRs, plusieurs lanes) et adjacency (2 PRs) — or ces organes sont, par design, réparables Côté lane (chaque PR déclare son propre prev:/séquence de genre). L'acceptance de picker: l'imputation d'un rouge a la base corrobore sur le NOM d'un agregateur et sur author.login, pas sur l'organe ni sur la lane (#13545) #14537 dit « même organe sur ≥2 lanes = base », mais un carve-out « organes lane-side » (prev_guard/adjacency/lane_claim) peut se justifier — décision coordinateur au premier signalement fantôme.

Périmètre

2 fichiers : scripts/pick_idle_grain.py (prédicat + résolution d'organe + databaseId au fragment GraphQL + sortie base_unresolved), scripts/tests/test_pick_idle_grain.py (7 tests nouveaux/mis à jour).

(Worktree frais depuis origin/main ; des fichiers slides/S3-acculturation/* salis par un flip EOL dans le working tree NE SONT PAS dans le commit — vérifié git show --stat HEAD = 2 fichiers.)

See #14567 (jumelle du même défaut, déposée ce jour par une autre lane — non claimée ici ; couverte par ce fix, fermeture laissée au coordinateur/découvreur).

Closes #14537

Les deux cles du predicat d'imputation a la base etaient fausses et se
compensaient mal : le NOM d'un agregateur (identique quel que soit
l'organe tombe, corroboration garantie par construction) et
author.login (identite de poussee partagee des cinq lanes, 52/59 de
l'ouvert -- le cas nominal n'etait jamais croise). Desormais : cle =
cause (organe resolu via l'annotation du check-run pour un agregateur,
nom pour un check direct), unite = tag de lane du grain tag, dedup par
set, fail-closed aux deux bouts (PR sans tag et agregateur non resolu
sont exclus ET dits -- base_unresolved).
@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-2026:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-04) :

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.

@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] — Réfection vérifiée first-hand : solide, un résiduel mineur à tracer (contrainte token : COMMENT only, opener=jsboige).

Vérifié par exécution réelle (tarball au SHA de tête 37f4d4f, venv propre, pytest 3.12) :

  • test_pick_idle_grain.py : 95 passed head / 89 passed base = +6 nets (6 nouveaux listés, 0 retrait — le « 7 nouveaux/mis à jour » du body compte l'update de test_base_inherited_red_is_not_the_lanes, cohérent). Les 7 suites picker complètes : 165 passed — claim du body reproduit à l'identique.
  • Parseur d'organes validé sur le réel : annotation du check-run Always-on guards -- 12 organes, 1 checkout en échec sur #14596 (run 100999413432) → _ORGAN_BANNER_RE extrait ['adjacency'], exactement la sortie live du body. Le format réel « organe (détail…) » est bien couvert par la classe [a-z_ ]+?.
  • Logique : corroboration par lane (pas author.login — l'identité de poussée partagée 52/59 rendait l'ancien prédicat vide au cas nominal), regroupement par cause (organe de l'annotation pour l'agrégateur, nom pour le check direct #13545), dédup set, fail-closed aux deux bouts (lane absente → hors corroboration ; agrégateur illisible → base_unresolved dit le non-tranché au lieu d'un silence). Héritage partiel par subset keys <= inherited : testé multi-organes, l'agrégateur partiellement hérité reste une cause lane — correct.
  • subprocess gh dans fetch_check_organs : check=True, timeout=60, catch-all → fail-closed sans crash picker. Cache organ_cache évite le re-fetch par PR.

Résiduel (non bloquant, pour la traçabilité) : AGGREGATOR_CHECK_PREFIXES = ("Always-on guards",) matche aussi « Always-on metadata guards -- 3 organes » (préfixe commun). Vérifié sur #14596 : ce check est success donc hors chemin FAILURE — sans effet aujourd'hui, mais si l'agrégateur metadata tombe un jour, il sera traité par la voie organe (annotation du même format ?) alors que sa bannière n'a pas été vérifiée dans le corpus. Une ligne de commentaire ou un test future en bénéficierait.

Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=). Les deux résiduels arbitrables du body (two-hop PR gate, carve-out prev_guard/adjacency) sont correctement signalés au coordinateur au lieu d'être enterrés.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #14644 (fix(picker,#14537): impute_base_reds corrobore par ORGANE et par LANE, pas par nom de job ni login) 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

Development

Successfully merging this pull request may close these issues.

picker: l'imputation d'un rouge a la base corrobore sur le NOM d'un agregateur et sur author.login, pas sur l'organe ni sur la lane (#13545)

2 participants