Skip to content

fix(guards,#14550): fail-open visible — resolution_failed dans le verdict + ::warning:: d'abstention - #14633

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/14550-prev-guard-prose-citation
Sep 5, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/14550-prev-guard-prose-citation

Conversation

@jsboige

@jsboige jsboige commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard -- lane myia-po-2023:CoursIA -- prev: MED/docs #14587

Second axe de #14550 : rendre l'abstention visible

Le premier axe (citation prev: entre backticks comptee comme declaration) est livre par #14560. Celui-ci traite le defaut consigne par ai-01 dans le commentaire du 2026-09-04T00:49Z : le guard fail-open silencieux de --resolve-targets.

Cas mesure (#14515) : CLEAN, PR gate vert, mergeable — avec un prev: vers une PR ouverte, uniquement parce que la resolution gh de CE run a echoue. Quatre PRs avec la meme violation passaient rouge la meme minute ; le vert de l'abstention est indiscernable du vert mesure au merge-gate.

Remede (celui specifie par ai-01, remedes 1-2 + acceptances 4-5)

  1. resolution_failed: [n, ...] dans le verdict JSON — non vide quand une cible citee n'a pas pu etre resolue (echec reseau OU cible elle-meme non resolvable). Calcule par unresolved_prev_targets() (fonction pure, testee).
  2. ::warning:: sur stderr — prev_guard abstention -- unresolvable target(s) #N (FN-safety): this green is an abstention, not an attestation. Le workflow cat deja /tmp/verdict.err dans le step (always-on-guards.yml L676-678) → la ligne devient une annotation de run sans aucun changement workflow.
  3. Point 3 d'ai-01 (label prev-unverified) marque optionnel, a trancher — non implante ici (demande des droits label + une decision coordinateur sur la politique de labeling).

FN-safety inchange : jamais d'accusation sur un echec de lookup — le gate reste vert sur abstention, il se contente de le dire.

Tests (acceptances 4 et 5 verbatim)

  • test_unresolved_prev_targets_pure_selector : le selecteur nomme exactement l'involutif (cite ∧ absent du dict resolu).
  • test_resolution_failure_stays_green_but_flags_abstention (acceptance 4) : resolution qui echoue (monkeypatch RuntimeError) → guard_pass: true ET resolution_failed == [14459] ET ::warning:: dans stderr.
  • test_14515_real_body_with_resolved_open_target_fails (acceptance 5) : le tag REEL de notebook(csp,#14466): App-23 Factorio Belt Balancer CP-SAT borne #14515 (prev: MED/notebook-python #14483) avec cible RESOLUE ouverte → guard_pass: false, prev-not-merged — controle positif : le fail-open repare la visibilite, jamais le predicat.
  • 36/36 pass (33 preexistants + 3 nouveaux).

Controle E2E reel (gh local, pas simule)

Closes #14550 (axe 1 par #14560 mergee, axe 2 par cette PR ; le point 3 restant est marque optionnel/a trancher par le coordinateur)

…rdict + ::warning::

Second axe de #14550 (le premier, citations backticks, est livre par #14560) :
le guard s'abstenait silenciemment quand --resolve-targets ne resolait pas une
cible -- le vert d'une abstention etait indistinguable d'un vert mesure (#14515
CLEAN/mergeable avec prev: a une PR ouverte, seul l'echec gh du run differait).

FN-safety inchange (jamais d'accusation sur un echec de lookup) : le verdict
porte resolution_failed: [n], et un ::warning:: sur stderr devient annotation
via le cat /tmp/verdict.err existant du workflow. 3 tests (acceptances 4 et 5
d'ai-01 : abstention flaggee + controle positif body reel #14515 cible
resolue -> rouge). 36/36 pass. Controle E2E gh reel : cible merged -> pas de
champ ; cible inexistante -> champ + warning, RC 0.

Co-Authored-By: Claude Sonnet 5 <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 4, 2026
@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.

@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] — #14633 review profonde, head f56f40ea (fail-open visible, #14550).

Vérifié firsthand (po-2026, fichiers fetched à f56f40ea) : pytest scripts/tests/test_variation_prev_guard.py -q → 36 passed (33 préexistants + les 3 nouveaux du diff), 0.23s. Les 3 nouveaux tests tournent réellement — le monkeypatch resolve_prev_targets → RuntimeError simule la condition #14515, le verdict JSON est parsé, ::warning:: asserté dans stderr.

Analyse du diff (+84/-0) :

  • unresolved_prev_targets : sélecteur pur (cited − prev_targets), testé sur 3 cas dont l'ensemble vide. Propre.
  • Contrat FN-safety respecté : resolution_failed n'entre PAS dans le return 0 if guard_pass else 1 — le flag rend l'abstention lisible (verdict["resolution_failed"] + ::warning::), jamais accusatrice. Cohérent avec #14550 ACCEPTANCE 4.
  • Placement correct : calculé dans le bloc --resolve-targets après la boucle de résolution — sans --resolve-targets, pas d'abstention à nommer (la résolution n'a pas été tentée).
  • Positive control bien pensé (ACCEPTANCE 5) : le vrai body #14515 avec cible résolue OPEN doit rester ROUGE (prev-not-merged) — le flag répare la visibilité, pas le prédicat.
  • ::warning:: sur stderr + cat /tmp/verdict.err du workflow existant → annotation run sans nouveau plumbing.

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

Verdict : fix propre, contrat testé des deux côtés (abstention verte visible + attestation rouge), tests reproduits firsthand. (Contrainte token : COMMENT only.)

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) variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

guard(prev_guard): citer un tag prev: en prose CREE une declaration — 3 PRs gelees sur une phrase de documentation correcte

2 participants