Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions scripts/coordination/frozen_campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
dossier READY porte par une PR gelee). Une seule definition pour les deux,
jamais deux qui derivent -- le gate ne peut pas importer merge_ready
(merge_ready importe deja le gate), donc les deux importent ce module.

Etat au 2026-10-07 : le veto #17040 couvrait deux parapluies ; #13410
(campagne densite carnets) est ROUVERT par decision user (lecons consignees
au fil de #13410), #11601 (densite QC round 2) reste gele.
"""
from __future__ import annotations

Expand All @@ -14,29 +18,34 @@
# Parapluies GELES par un veto user : une PR qui s'en reclame (titre ou body)
# sort du perimetre (b), quel que soit son dossier. Ni le gate d'entree ni B.0
# ne lisent un veto pose sur une issue : l'organe le lit ici, fail-closed.
# 13410 = campagne densite, gelee par le veto #17040 (mandat user 2026-09-20).
# #17021 y a ete mergee le 2026-09-22 sur un dossier READY et un B.0 vert :
# c'est l'incident qui fonde cette liste.
# 13410 = campagne densite, gelee par le veto #17040 (mandat user 2026-09-20)
# puis ROUVERTE par decision user du 2026-10-07 (session directe), sous les
# lecons consignees au fil de #13410 -- l'entree de campagne se fait sous
# elles. #17021 y a ete mergee le 2026-09-22 sur un dossier READY
# et un B.0 vert : c'est l'incident qui fonde cette liste.
# 11601 = densite QC round 2 (« 1200->2000+ »), gelee au meme titre le
# 2026-09-23 (#11601 c.5786602361) : sa cible EST un seuil, ce que le point 4
# de #17040 interdit.
FROZEN_UMBRELLAS = {"13410": "17040", "11601": "17040"}
# de #17040 interdit. RESTE gelee -- la reouverture du 2026-10-07 ne la
# couvre pas.
FROZEN_UMBRELLAS: dict[str, str] = {"11601": "17040"}

# Branches d'une campagne gelee dont les PRs ne citent PAS le parapluie : les
# relais g-XX de #13410 (`wt/vibe-g62-...`) n'ont #13410 ni dans le titre ni
# dans le body. 17 d'entre eux etaient ouverts et invisibles au filtre
# relais g-XX de #13410 (`wt/vibe-g62-...`) n'avaient #13410 ni dans le titre
# ni dans le body. 17 d'entre eux etaient ouverts et invisibles au filtre
# ci-dessus le 2026-09-23 (fermes au titre du veto, solde markdown net > 0).
FROZEN_BRANCH_PREFIXES = {"wt/vibe-": "13410"}
# Vide depuis la reouverture user de #13410 (2026-10-07) : `wt/vibe-*`
# n'etait gele que comme relais de cette campagne. La structure reste pour le
# prochain veto, mecanisme couvert par les tests a donnees injectees.
FROZEN_BRANCH_PREFIXES: dict[str, str] = {}

# Campagnes AUTORISEES apres le veto qui reutilisent les memes relais
# ``wt/vibe-*`` : le prefixe de branche ne dit plus a lui seul « campagne
# gelee ». 17636 = resorption des mesures d'artefact en prose markdown (GO
# ai-01 du 2026-09-27, recette #17636 c.5860054240) : elle RETIRE des chiffres,
# elle ne vise aucun seuil. Mesure fondatrice (2026-09-28) : #18252, #18283 et
# #18316 portaient `fix(prose,#17636)` en titre et aucun #13410, et restaient
# gelees par leur seule branche. La levee se lit sur le TITRE (le body peut
# citer n'importe quoi) et tombe des qu'un parapluie gele est cite.
BRANCH_PREFIX_RELEASES = {"wt/vibe-": ("17636",)}
# Campagnes AUTORISEES apres un veto a reutiliser des relais geles : la levee
# se lit sur le TITRE (le body peut citer n'importe quoi) et tombe des qu'un
# parapluie gele est cite. Mesure fondatrice (2026-09-28, prefixe wt/vibe-) :
# #18252, #18283 et #18316 portaient `fix(prose,#17636)` en titre et
# restaient gelees par leur seule branche (17636 = resorption des mesures
# d'artefact, GO ai-01 du 2026-09-27). Vide depuis la reouverture de #13410
# (2026-10-07) : plus aucun relais gele ne vit.
BRANCH_PREFIX_RELEASES: dict[str, tuple[str, ...]] = {}

# Redressements EXEMPTES du gel, sur le TITRE seul (insensible a la casse) :
# une PR qui REPREARE les degats d'une campagne gelee cite le parapluie comme
Expand Down
29 changes: 16 additions & 13 deletions scripts/tests/test_check_adjoint_prevalidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1649,10 +1649,11 @@ def test_fingerprint_refusal_names_the_live_surface_landscape():

# --- Campagnes gelees par veto user (#17040) ----------------------------------

# Titres reels (2026-09-23/24) : le second repare les degats de la campagne
# densite et cite le parapluie dans son body -- l'exemption se lit sur le
# titre seul (module partage frozen_campaigns).
FROZEN_TITLE = "Densite Lab13-Web-Search-SOTA (#13410)"
# Titres reels (2026-09-23/24) : le second repare les degats d'une campagne
# gelee et cite le parapluie dans son body -- l'exemption se lit sur le
# titre seul (module partage frozen_campaigns). #13410 ROUVERT le 2026-10-07 :
# le gel se mesure sur #11601, seul parapluie gele en vie.
FROZEN_TITLE = "enrich(qc,#11601): densite QC-Py-06b"
REDRESSEMENT_TITLE = (
"fix(semanticweb,#17066): redressement critique de SW-4-CSharp-SPARQL "
"-- reference de campagne"
Expand Down Expand Up @@ -1709,7 +1710,7 @@ def test_ready_dossier_on_frozen_campaign_returns_rc3(monkeypatch, capsys):
out = capsys.readouterr().out
assert out.startswith(
"FROZEN -- PR #123 belongs to a frozen campaign "
"(frozen:#13410(veto #17040)); do not merge, dispatch to the lane author."
"(frozen:#11601(veto #17040)); do not merge, dispatch to the lane author."
)


Expand All @@ -1722,29 +1723,31 @@ def test_ready_dossier_frozen_json_payload(monkeypatch, capsys):
payload = json.loads(capsys.readouterr().out)
assert payload["ready"] is False
assert payload["verdict"] == "FROZEN"
assert payload["frozen"] == "frozen:#13410(veto #17040)"
assert payload["frozen"] == "frozen:#11601(veto #17040)"
assert payload["dossier"]["verdict"] == "READY"


def test_ready_redressement_citing_the_umbrella_stays_rc0(monkeypatch, capsys):
"""Redressement : le titre exempte du gel, meme quand le body cite
#13410 -- sinon la PR qui REPARE les degats ne serait plus mergeable."""
#11601 -- sinon la PR qui REPARE les degats ne serait plus mergeable."""
snapshot = _snapshot_with(
title=REDRESSEMENT_TITLE,
pr_body=_base_snapshot()["body"] + "\n\nSee #13410 (campagne densite).",
pr_body=_base_snapshot()["body"] + "\n\nSee #11601 (densite QC).",
)
rc = _run_main(monkeypatch, snapshot)
assert rc == mod.EXIT_READY
assert capsys.readouterr().out.startswith("READY -- PR #123")


def test_ready_dossier_on_wt_vibe_branch_returns_rc3(monkeypatch, capsys):
"""Relais de campagne : la branche gelee suffit, sans citation aucune --
et sans exemption (ce sont des relais, jamais des redressements)."""
def test_ready_dossier_on_wt_vibe_branch_after_reopening(monkeypatch, capsys):
"""Reouverture user de #13410 (2026-10-07) : les relais wt/vibe-* ne
gelent plus -- un dossier READY sur ces branches redevient READY. Le
mecanisme de gel par prefixe reste prouve par test_frozen_campaigns
(donnees injectees)."""
snapshot = _snapshot_with(head_ref="wt/vibe-g77-search-26")
rc = _run_main(monkeypatch, snapshot)
assert rc == mod.EXIT_BLOCKED_WITH_SUBSTANCE
assert "frozen:#13410(veto #17040,branch wt/vibe-*)" in capsys.readouterr().out
assert rc == mod.EXIT_READY
assert capsys.readouterr().out.startswith("READY -- PR #123")


def test_blocked_dossier_on_frozen_campaign_keeps_its_own_message(
Expand Down
132 changes: 93 additions & 39 deletions scripts/tests/test_frozen_campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

Le module est charge par importlib (meme convention que
test_check_adjoint_prevalidation et test_merge_ready) : aucun reseau, aucun gh.
Les trois titres reels ci-dessous sont les titres mesures qui fondent
l'exemption de redressement -- ils ne se devinent pas.

Etat depuis la reouverture user du 2026-10-07 : #13410 (campagne densite
carnets) est ROUVERT, seule #11601 (densite QC round 2) reste gelee. Les
mecanismes de gel par prefixe de branche et de levee par campagne autorisee
ne sont plus exerces par les donnees de production : ils restent couverts par
les tests a donnees injectees (``_simulated_veto``) pour que le prochain veto
herite d'un mecanisme prouve.
"""

import contextlib
import importlib.util
import sys
from pathlib import Path
Expand All @@ -17,8 +23,8 @@
sys.modules["frozen_campaigns_under_test"] = fc
_spec.loader.exec_module(fc)

# Titres reels (2026-09-23/24) : les deux premiers reparent les degats de la
# campagne densite et citent le parapluie -- ils doivent rester mergeables.
# Titres reels (2026-09-23/24) : les deux premiers reparent les degats d'une
# campagne gelee et citent le parapluie -- ils doivent rester mergeables.
REVERT_TITLE = (
"revert(density,#17040): App-1-NQueens + App-14b-ConnectFour "
"restaures avant #17021 (remplissage sous veto)"
Expand All @@ -27,47 +33,55 @@
"fix(semanticweb,#17066): redressement critique de SW-4-CSharp-SPARQL "
"-- reference de campagne"
)
FROZEN_TITLE = "Densite Lab13-Web-Search-SOTA (#13410)"
FROZEN_TITLE = "enrich(qc,#11601): densite QC-Py-06b"
# Titre reel d'une PR de la campagne densite, releve avant la reouverture :
# la citation de #13410 ne gele plus depuis le 2026-10-07.
REOPENED_TITLE = "Densite Lab13-Web-Search-SOTA (#13410)"


def test_the_three_real_titles():
assert fc.frozen_umbrella_exclusion(REVERT_TITLE, "See #13410") is None
assert fc.frozen_umbrella_exclusion(REDRESSEMENT_TITLE, "See #13410") is None
assert fc.frozen_umbrella_exclusion(REVERT_TITLE, "See #11601") is None
assert fc.frozen_umbrella_exclusion(REDRESSEMENT_TITLE, "See #11601") is None
assert (
fc.frozen_umbrella_exclusion(FROZEN_TITLE, None)
== "frozen:#13410(veto #17040)"
== "frozen:#11601(veto #17040)"
)


def test_13410_reopened_by_user_decision():
# Reouverture user du 2026-10-07 : la citation du parapluie (titre OU
# body) ne gele plus, et les relais wt/vibe-* non plus. Les lecons du
# gel vivent au fil de #13410 ; #11601 reste gelee, elle.
assert fc.frozen_umbrella_exclusion(REOPENED_TITLE, None) is None
assert fc.frozen_umbrella_exclusion("fix(x): ordinaire", "See #13410", None) is None
assert (
fc.frozen_umbrella_exclusion(
"fix(search,g77): relocate 12 lectures", None, "wt/vibe-g77-search-26"
)
is None
)


def test_prefix_number_not_matched():
# #134100 ne vaut pas #13410 -- le garde-fou (?!\d) couvre le parapluie
# #116010 ne vaut pas #11601 -- le garde-fou (?!\d) couvre le parapluie
# ET le numero du veto.
assert fc.frozen_umbrella_exclusion("fix: #134100", "voir #134101") is None
assert fc.frozen_umbrella_exclusion("fix(x,#170400): titre", "See #13410") is not None
assert fc.frozen_umbrella_exclusion("fix: #116010", "voir #116011") is None
assert fc.frozen_umbrella_exclusion("fix(x,#170400): titre", "See #11601") is not None


def test_exemption_is_title_only():
# Le mot redressement dans le BODY ne suffit pas : l'exemption se lit sur
# le titre seul, sinon n'importe quelle PR de campagne s'exempterait en
# ecrivant le mot dans son body.
assert (
fc.frozen_umbrella_exclusion("fix(x): ordinaire", "redressement, voir #13410")
fc.frozen_umbrella_exclusion("fix(x): ordinaire", "redressement, voir #11601")
is not None
)


def test_exemption_is_case_insensitive():
assert fc.frozen_umbrella_exclusion("REVERT(density): restaures", "See #13410") is None
assert fc.frozen_umbrella_exclusion("Fix: REDRESSEMENT SW-4", "See #13410") is None


def test_branch_prefix_stays_frozen_despite_exempt_title():
# Les branches wt/vibe-* sont des relais de campagne : aucune exemption,
# meme sur un titre de redressement.
assert (
fc.frozen_umbrella_exclusion(REVERT_TITLE, None, "wt/vibe-g62-density-9")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)
assert fc.frozen_umbrella_exclusion("REVERT(density): restaures", "See #11601") is None
assert fc.frozen_umbrella_exclusion("Fix: REDRESSEMENT SW-4", "See #11601") is None


def test_umbrella_in_body_freezes_despite_ordinary_title():
Expand All @@ -77,6 +91,12 @@ def test_umbrella_in_body_freezes_despite_ordinary_title():
)


# --- Mecanismes de relais, a donnees injectees ---------------------------------
#
# Depuis la reouverture de #13410, aucune donnee de production n'exerce le
# gel par prefixe de branche : on rejoue ici l'etat d'avant (13410 gele +
# relais wt/vibe-*, campagne autorisee 17636) pour garder le mecanisme prouve.

# Titre reel de #18283 (2026-09-28) : relais wt/vibe-* d'une campagne
# autorisee apres le veto, sans aucune citation de #13410.
RELEASED_TITLE = (
Expand All @@ -85,31 +105,65 @@ def test_umbrella_in_body_freezes_despite_ordinary_title():
)


def test_authorized_campaign_title_releases_vibe_branch():
assert (
fc.frozen_umbrella_exclusion(RELEASED_TITLE, "See #17636", "wt/vibe-g2d-tweety")
is None
@contextlib.contextmanager
def _simulated_veto():
saved = (
fc.FROZEN_UMBRELLAS,
fc.FROZEN_BRANCH_PREFIXES,
fc.BRANCH_PREFIX_RELEASES,
)
fc.FROZEN_UMBRELLAS = {"13410": "17040", "11601": "17040"}
fc.FROZEN_BRANCH_PREFIXES = {"wt/vibe-": "13410"}
fc.BRANCH_PREFIX_RELEASES = {"wt/vibe-": ("17636",)}
try:
yield
finally:
(
fc.FROZEN_UMBRELLAS,
fc.FROZEN_BRANCH_PREFIXES,
fc.BRANCH_PREFIX_RELEASES,
) = saved


def test_branch_prefix_freezes_despite_exempt_title():
# Les branches wt/vibe-* sont des relais de campagne : aucune exemption,
# meme sur un titre de redressement.
with _simulated_veto():
assert (
fc.frozen_umbrella_exclusion(REVERT_TITLE, None, "wt/vibe-g62-density-9")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)


def test_authorized_campaign_title_releases_vibe_branch():
with _simulated_veto():
assert (
fc.frozen_umbrella_exclusion(RELEASED_TITLE, "See #17636", "wt/vibe-g2d-tweety")
is None
)


def test_release_falls_when_a_frozen_umbrella_is_cited():
# Le body cite la campagne gelee : la branche regele la PR.
assert (
fc.frozen_umbrella_exclusion(RELEASED_TITLE, "suite de #13410", "wt/vibe-g2d-tweety")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)
with _simulated_veto():
assert (
fc.frozen_umbrella_exclusion(RELEASED_TITLE, "suite de #13410", "wt/vibe-g2d-tweety")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)


def test_release_is_title_only():
# #17636 dans le body seul ne libere pas un relais muet.
assert (
fc.frozen_umbrella_exclusion("Densite Lab13", "See #17636", "wt/vibe-g62-density-9")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)
with _simulated_veto():
assert (
fc.frozen_umbrella_exclusion("Densite Lab13", "See #17636", "wt/vibe-g62-density-9")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)


def test_release_needs_exact_campaign_number():
assert (
fc.frozen_umbrella_exclusion("fix(prose,#176360): x", None, "wt/vibe-g2x")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)
with _simulated_veto():
assert (
fc.frozen_umbrella_exclusion("fix(prose,#176360): x", None, "wt/vibe-g2x")
== "frozen:#13410(veto #17040,branch wt/vibe-*)"
)
Loading
Loading