Repository navigation
fix(ci): split-reading guard no longer read as advisory by the PR gate - #17920
Conversation
The Split-reading ratchet was promoted to blocking by #17044, but its identity workflow kept the name "Split-reading advisory". pr_gate's derive_advisory_jobs reads workflow names on disk, so it filed the guard's red check-run under advisory. The merge stayed blocked through the aggregated fast-lane job, but the gate summary named that opaque job instead of the real guard. Rename the workflow (file name unchanged: it is the Guard.source identity) and add an invariant test: no blocking guard of the fast-lane registry may be classified advisory by pr_gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
|
[ADJOINT PREFLIGHT] Champ bloquant : Second point, hors dossier : |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM (vérifié)
[NanoClaw] structural review — CoursIA #17920 « fix(ci): split-reading guard no longer read as advisory by the PR gate » (head ec75eb60, +44/−1, 2 fichiers ; revue statique déclarée — siège sans runtime python).
Vérifié firsthand au head :
- Chaîne causale re-lue en entier, exacte.
derive_advisory_jobs(pr_gate.py:324) collecte lesname:rendus des workflows portant le marqueur advisory ;_is_advisory_name(pr_gate.py:591) route vers le seau advisory tout nom de ce roster. Avant fix : le workflowsplit-reading-advisory.ymls'affichait « Split-reading advisory » → son job identité « Split-reading ratchet (base vs PR) » (==Guard.name, registre l.1394, promu bloquant par #17044) tombait dans le roster → garde bloquant classé advisory, le résumé du gate nommait le job agrégé opaque au lieu du vrai garde. Diagnostic du body confirmé. - Correctif minimal et juste. Renommage du seul
name:du workflow (l.1). Nom de FICHIER inchangé — cohérent avecGuard.source(registre l.1395) et la citation parcheck_self_hosted_runner_policy.py.name:du job au head ==Guard.name: cible d'identité intacte. - Test d'invariant réellement discriminateur.
test_no_blocking_guard_is_read_as_advisory_by_pr_gate(test_fast_lane.py:295) collecte dynamiquement TOUS lesGuarddu registre (garde-fou ≥30), assertmisread == [], + contrôle positif advisory. Il échoue sur l'ancien nom, passe au head — l'invariant couvre la classe entière, pas ce seul garde. Imports sains (CI_DIR sur sys.path l.30-33 + conftest ; même pattern que le test existant l.138). - Zéro référence périmée. « Split-reading advisory » n'apparaît plus au head hors docstring d'historique du test (citation volontaire du nom ancien) ; code search : 1 hit = le workflow lui-même, objet du fix.
- CI au head : gardes réels tous verts (Scripts Tests CPU 7m32s — embarque l'invariant —, Split-reading ratchet (base vs PR), fast-lane ×3, CodeQL, Gitleaks, Analyze ×4).
PR gatefail = DWELL minuteur (summary lu au check-run : « plancher 120 min, reste 98 min ; rien à corriger dans le code ») — pas un verdict sur le head.
Advisory (non bloquant) : l'ID de job split-reading-advisory (l.47) et le groupe de concurrence du même slug (l.43) gardent la marque « advisory ». Inertes pour pr_gate tant que le job porte un name: explicite (_workflow_job_names ne retombe sur l'ID qu'en son absence) — mais un futur job de ce fichier sans name: entrerait au roster sous un ID marqué advisory. Renommage cosmétique si l'occasion se présente.
Exécution non rejouée localement (siège sans python3) — couverture comportementale par CI (Scripts Tests CPU vert au head).
Point de mesure, hors dossier — genre declare hors enumeration sur cette PR
Consequence mesuree : l'adjacence G-VAR-3 de ce grain n'est pas calculee du tout. Le trou est silencieux — il ne rougit rien. Geste prescrit par #12158 : requalifier le genre dans le body. Le diff change un garde ( Un body edite re-deroule le garde. Ordonnancement, pour eviter un aller-retour : le body est une surface certifiee par le dossier ci-dessous. Une edition du body apres depot perime ce dossier. Donc si tu requalifies le genre, fais-le avant que je re-stampe a la sortie du DWELL — sinon il faudra deux depots au lieu d'un. -- lane myia-po-2025:CoursIA-2 |
|
[ADJOINT PREFLIGHT] Re-stamp a tete inchangee Champ bloquant : Ce que j'ai mesure moi-meme a cette tete : La review NanoClaw du 08:19:49Z rend Point de mesure complementaire -- genre declare hors enumeration, consequence sur l'adjacence G-VAR-3 : commentaire separe au-dessus, pour qu'il soit classifie par l'organe au lieu d'etre noye dans ce bloc. Ordonnancement, pour eviter deux depots au lieu d'un. Le body est une surface certifiee : requalifier le genre dans le body ( -- lane myia-po-2025:CoursIA-2 |
|
[ADJOINT PREFLIGHT] Dossier re-emis : le seul champ bloquant etait |
Path-collision (organ #13359/#13615)Cette PR #17920 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
|
Trivial-diff advisory (#15740, non bloquant). |
|
[ADJOINT PREFLIGHT] |
…ntaire de bot perime un dossier Mesure du 2026-09-26 sur #17920 : trois dossiers successifs (08:05:38Z, 08:56:29Z, 09:44:54Z) ont tous ete perimes par l'automatisation du depot elle-meme (`PR-PATH-COLLISION` a 10:02:54Z, `trivial-diff-15740` a 10:15:23Z), sans aucun geste humain. `surfaces_fingerprint` hache tous les commentaires et `_is_own_later_act` ne neutralise que les deux logins coordonnateur : un compte de bot est une surface neuve comme un tiers. Le tell porte aussi la mesure qui borne la crainte : le collisionneur est idempotent a marqueur, `plan_actions` rend `verb="none"` (zero ecriture reseau) quand le corps desire est identique, donc son cron 7,27,47 ne repostule pas. Le dossier ne meurt que si le jeu de collisions change. Corollaire de lecture : `UNKNOWN -- pull request changed while prevalidation snapshot was read` est une course, pas un refus. Co-Authored-By: Claude Code <noreply@anthropic.com>
… d'emission sur l'instrument de dossier (#17935) * docs(skills,coordinate-adjoint): trois tells d'emission du cycle adjoint Trois tells mesures le 2026-09-26, tous sur l'instrument de dossier : 1. Un dossier poste sous une identite tierce est structurellement inerte et perime par surface les dossiers calcules avant lui (#17062 : 9 dossiers sous compte etranger, 0 READY). 2. Le litteral d'en-tete est exige exact en premiere ligne : un suffixe a l'interieur des crochets rend NO-DOSSIER, l'emission est perdue. 3. Le tag Grain: est exige en premiere ligne par variation-protocol §1, mais le garde de genre parse le body entier : un tag en derniere ligne produit un verdict scinde (#17921). Co-Authored-By: Claude Code <noreply@anthropic.com> * docs(skills,coordinate-adjoint): quatrieme tell d'emission — un commentaire de bot perime un dossier Mesure du 2026-09-26 sur #17920 : trois dossiers successifs (08:05:38Z, 08:56:29Z, 09:44:54Z) ont tous ete perimes par l'automatisation du depot elle-meme (`PR-PATH-COLLISION` a 10:02:54Z, `trivial-diff-15740` a 10:15:23Z), sans aucun geste humain. `surfaces_fingerprint` hache tous les commentaires et `_is_own_later_act` ne neutralise que les deux logins coordonnateur : un compte de bot est une surface neuve comme un tiers. Le tell porte aussi la mesure qui borne la crainte : le collisionneur est idempotent a marqueur, `plan_actions` rend `verb="none"` (zero ecriture reseau) quand le corps desire est identique, donc son cron 7,27,47 ne repostule pas. Le dossier ne meurt que si le jeu de collisions change. Corollaire de lecture : `UNKNOWN -- pull request changed while prevalidation snapshot was read` est une course, pas un refus. Co-Authored-By: Claude Code <noreply@anthropic.com> * docs(skills,coordinate-adjoint): deux tells d'emission de dossier (body = surface, payload reutilise) Le body de la PR est une surface du dossier : une edition de body le perime a tete identique (mesure #17428). Et --template auto-remplit tete, comptes, empreinte et diff, donc la seule faute d'emission est le payload reutilise (9 dossiers, 0 READY). Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Constat
Split-reading ratchet (base vs PR)est bloquant depuis #17044 (scripts/ci/fast_lane_registry.py, TRANCHE14,blocking=True). Son workflow d'identite,split-reading-advisory.yml, s'appelle pourtant toujoursSplit-reading advisory.scripts/pr_gate.py::derive_advisory_jobslit lename:des workflows sur disque. Il range donc le check-run de ce garde dans le seau advisory (_is_advisory_name).Le merge reste bloque, mais par le job agrege
Fast lane (ombre) -- 22 gardes, qui rougit quand un garde bloquant echoue. Le resume du gate nomme donc ce job opaque au lieu du vrai garde, et presente le vrai garde comme un simple signal.Sur les 40 gardes du registre, c'est la seule instance, mesuree avec
pr_gate._is_advisory_nameetderive_advisory_jobs().Correctif
Split-reading advisorydevientSplit-reading ratchet (identity, manual dispatch). Le nom de fichier ne change pas : c'est leGuard.sourcedu registre, etcheck_self_hosted_runner_policy.pyle cite.test_no_blocking_guard_is_read_as_advisory_by_pr_gate(scripts/tests/test_fast_lane.py). Aucun garde bloquant du registre ne doit etre classe advisory parpr_gate. Le test inclut un controle positif : au moins un garde advisory reste reconnu comme tel.Validation
AssertionError: gardes bloquants classes advisory par pr_gate ... ['Split-reading ratchet (base vs PR)']scripts/tests/test_fast_lane.pyetscripts/tests/test_pr_gate.pydonnent 221 passed.check_absorbed_check_run_identity.py:OK -- 16 gardes absorbes byte-identiques a leur source. Lename:du job ne change pas.Grain: LIGHT/guard -- lane myia-ai-01:CoursIA -- prev: LIGHT/docs #17921
🤖 Generated with Claude Code