Repository navigation
Conversation
The pre-existing same-repo guard `github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository` enumerates triggers and lets `pull_request_target` through (a fork trigger that runs the base with write token + secrets access). Replacing it with `head.repo.full_name == null || head.repo.full_name == repo` covers any PR payload from the same repo and lets non-PR triggers pass, without naming a single trigger. The scanner (`scripts/ci/check_self_hosted_runner_policy.py`) learns the new canonical form as a second accepted predicate so the migration does not trip the same-repo guard check on its own house. Three new tests cover acceptance of the new form, non-regression of the strict form, and continued rejection of weakened variants (extra `|| always()`). Applied to both `linux-self-hosted-tests.yml` (the scope named in #13874) and `windows-self-hosted-tests.yml` (same class of defect, two jobs; not migrating it would leave a documented hole alongside the fix).
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-3 : deux grains LIGHT du meme genre consecutifs -- bloquant (#11170). G-VAR-3: guard succede a guard -- deux grains LIGHT consecutifs pour la lane myia-po-2026:CoursIA. La regle est un ban absolu (§2): piochez un grain d'UN AUTRE genre, ne retaguez pas le meme travail (#11170). Tenu > 24 h : le coordinateur tranche par variation-protocol.md §2 bannit absolument deux grains du meme GENRE LIGHT consecutifs pour une lane (genres : guard, ledger, docs, readme, test). Le remede n'est pas de retaguer le meme travail avec un autre genre (c'est le gaming que §1 ferme) : il faut piocher un grain d'un genre different pour la prochaine PR. Pour passer ce gate, remplacez la |
jsboige
left a comment
There was a problem hiding this comment.
[Hermes] — review 5b6c377a (ci #13874, fork guard trigger-agnostic).
Vérifié firsthand (clone des 2 fichiers @sha + uv run pytest) : 40/40 passent, dont les 3 nouveaux (null_safe…accepted, strict…still_accepted, weakened variant…rejected) et le test repo-level test_current_repository_self_hosted_jobs_satisfy_isolation_policy avec les vrais workflows du SHA en place — le scanner accepte bien la nouvelle forme sur linux + windows (les 3 jobs).
Truth-table de la nouvelle garde vérifiée : workflow_dispatch → full_name == null → true (job tourne) ; PR fork (pull_request et pull_request_target) → false (bloqué) ; PR same-repo → true. Correct — l'ancienne forme passait un pull_request_target fork car event_name != 'pull_request'. Le scanner garde le rejet dur du trigger pull_request_target (double couche intacte). Le test d'affaiblissement (|| always() rejeté) couvre le risque de variante diluée — bon réflexe. Sécurité : grep clean.
Note (non bloquant) : la forme null-safe est fail-open si head.repo est absent d'un payload PR (cas limites : repo transféré, fork supprimé). Acceptable ici car la garde est defense-in-depth — le scanner de trigger reste le contrôle primaire. À garder en tête si un jour un workflow self-hosted ajoute réellement pull_request.
LGTM — logique vérifiée par exécution réelle (contrainte token : COMMENT only).
Bash Syntax Advisory — shebang / executable-bit warningsSee the |
Path-collision (organ #13359/#13615)Cette PR #13897 (
|
Summary
Issue #13874 releve que la garde fork au niveau job dans
linux-self-hosted-tests.ymlenumerait les triggers et laissait passerpull_request_target(qui execute la base avec jeton en ecriture +acces secrets sur une ref controlee par le fork). Cette PR remplace la
forme par une garde trigger-agnostic qui couvre
pull_request_targetsans nommer aucun trigger, etend le scanner pour reconnaitre la
nouvelle forme, et applique le meme fix au workflow Windows coherent.
Le defaut
La garde d'origine dans les deux workflows self-hosted etait :
Pour un evenement
pull_request_target,github.event_namevautpull_request_target(different depull_request), donc la premierejambe est vraie et le job s'execute, peu importe le
full_name. Lescanner (
scripts/ci/check_self_hosted_runner_policy.py) refusebien
pull_request_targetau niveau trigger (lignes 292-298 du fichierd'origine), donc rien n'est exploitable aujourd'hui -- le seul
declencheur actif est
workflow_dispatch. Mais la garde elle-meme estun defaut de defense-in-depth : quelqu'un qui ajoute un jour un
declencheur lie aux PR et choisit
pull_request_target(le conseilcourant pour acceder aux secrets) herite d'une garde qui a l'air de
couvrir le cas et ne le couvre pas.
Le fix
Forme universelle (issue #13874 verbatim) :
== nullest vrai pour tout evenement sans payload de PR(
workflow_dispatch,schedule,push, ...)pull_requestETpull_request_targetd'un seul test
La forme stricte d'origine reste acceptee par le scanner (cf test
test_strict_pull_request_guard_still_accepted) -- pas de regressionsur les workflows tiers ou un user migrerait plus tard.
Scanner -- extension du predicat
SAME_REPO_GUARDLe scanner (lignes 79-82 du fichier d'origine) exigeait la forme
canonique stricte par egalite exacte. Migration logique : ajouter
SAME_REPO_GUARD_NULL_SAFEcomme second pattern accepte. La formefaible (avec
|| always()ou disjunct supplementaire) reste rejetee(cf
test_null_safe_guard_with_extra_or_is_rejected) -- le predicataccepte uniquement les deux formes completes, pas les variantes
affaiblies.
Portee
.github/workflows/linux-self-hosted-tests.yml.github/workflows/windows-self-hosted-tests.ymlscripts/ci/check_self_hosted_runner_policy.pySAME_REPO_GUARD_NULL_SAFEajoutee, predicatSAME_REPO_GUARDaccepte les deux formes canoniquesscripts/tests/test_check_self_hosted_runner_policy.pyPourquoi Windows : le fix de l'issue #13874 ne nomme que
linux-self-hosted-tests.yml. Mais le defaut est identique (les 2jobs Windows portent la meme garde enumerative) et ne pas migrer
laisserait un trou documente juste a cote du fix. Migration
simultanee pour coherence ; l'issue reste assignee au seul #13874
(ce qui est resolu ; les autres jobs Windows sont une consequence
logique).
Verification
37 anciens tests intacts (zero vert -> rouge), 3 nouveaux tests
couvrant l'extension.
Les 3 jobs self-hosted (1 linux, 2 windows) passent avec la nouvelle
forme.
YAML parse sans workaround du
on:.Pre-commit (10/10 hooks PASSED)
Acceptance issue #13874
head.repo.full_name == null || head.repo.full_name == repo(linux-self-hosted-tests.yml). Forme documentee en commentaire
dans le YAML pour le prochain lecteur.
confinement + dotnet) pour coherence -- le defaut etait
identique et laisse non-migre = un trou documente a cote du
fix.
canonique (
SAME_REPO_GUARD_NULL_SAFE), la forme stricted'origine reste valide (non-regression), les variantes
affaiblies (
|| always(), disjuncts supplementaires) restentrejetees.
(
test_null_safe_pull_request_guard_is_accepted,test_strict_pull_request_guard_still_accepted,test_null_safe_guard_with_extra_or_is_rejected). 37/37anciens tests intacts.
Lien avec cycles / missions precedents
Linux conteneurise ; le guard fork d'origine date de cette mission
(PR feat(ci,#13378): runner Linux conteneurise po-2024 — pilote dispatch-only #13864, merge feat(ci,CI Windows/.NET: 26/93 workflows ubuntu routables as-is, checks C#/.NET inexistants, controle positif fast-guards OK (mission ai-01) #13378)).
initiale) -- la garde
SAME_REPO_GUARDdu scanner a ete introduitedans ce cadre.
ConfigureAwait(false).GetAwaiter().GetResult()-- non lie aufix mais dans le meme perimetre tooling de garde CI.
Grain: LIGHT/guard - lane myia-po-2026:CoursIA - prev: LIGHT/tooling #13862 cycle 33.
paths: .github/workflows/linux-self-hosted-tests.yml, .github/workflows/windows-self-hosted-tests.yml, scripts/ci/check_self_hosted_runner_policy.py, scripts/tests/test_check_self_hosted_runner_policy.py
Closes #13874
🤖 Generated with Claude Code