Skip to content

fix(ci): tâche merge_ready lancée via un lanceur wscript masqué (plus de fenêtre qui clignote) - #17705

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/merge-ready-task-hidden-window
Sep 25, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/merge-ready-task-hidden-window

Conversation

@jsboige

@jsboige jsboige commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Grain: LIGHT/tooling -- lane myia-ai-01:CoursIA -- prev: MED/guard #17703

Résumé

Toutes les 20 minutes, la tâche planifiée CoursIA\merge_ready faisait apparaître une fenêtre de console sur le bureau interactif de la machine qui l'héberge. La cause : son action était python.exe en direct, un programme console, et le mode --run lance lui-même des enfants console (git, gh).

L'action enregistrée devient wscript.exe //B //Nologo <run_hidden.vbs>. Le lanceur VBS, écrit par --install dans %LOCALAPPDATA%\CoursIA\merge_ready\, exécute la même commande via WshShell.Run(cmd, 0, True). Trois propriétés en découlent :

  • la fenêtre 0 est masquée, et la console cachée est héritée par tous les enfants console ;
  • True attend la fin de la commande, et WScript.Quit remonte son code de sortie : la durée et le LastTaskResult restent lisibles dans le planificateur ;
  • pythonw.exe est écarté explicitement dans le docstring : sans console attachée, chaque enfant console ouvrirait sa propre fenêtre visible.

Ce qui change

  • vbs_content(repo) : génère le lanceur à partir de task_command(repo), qui reste la commande effectivement exécutée. Les guillemets sont doublés, conformément à l'échappement VBS. Une ligne de commande non-ASCII est refusée (ValueError, rc=2), parce que wscript lit les .vbs en ANSI et produirait sinon un lanceur cassé sans erreur visible.
  • task_action() : l'action enregistrée, c'est-à-dire wscript, les options //B //Nologo et le chemin du VBS.
  • --install écrit le VBS, puis enregistre la tâche.
  • --uninstall supprime le VBS seulement si la suppression de la tâche a réussi.
  • --dry-run imprime les deux, commande schtasks et contenu exact du VBS, et n'écrit rien.
  • Aucun changement au comportement de l'organe : même commande --run, même dépôt, même hold.txt, même intervalle.

Validation

  • python -m pytest scripts/tests/test_install_merge_ready_task.py scripts/tests/test_merge_ready.py -q : 56 passed, soit 15 tests de l'installeur, dont les nouveaux sur le VBS, l'échappement, le refus non-ASCII, l'ordre écriture puis enregistrement et le dry-run sans écriture, plus 41 de merge_ready.
  • Dry-run publié sur le dashboard workspace-CoursIA (cross-post global) avant le ré-enregistrement, comme l'exige la discipline dry-run des gestes planificateur.
  • Déploiement sur ai-01 depuis ce worktree, puis vérification par Get-ScheduledTask : Execute = C:\WINDOWS\System32\wscript.exe, Arguments = //B //Nologo ...\run_hidden.vbs. Le fichier VBS est présent et identique au dry-run.
  • Un tour a été déclenché à la main (Start-ScheduledTask) pour vérifier le chemin de bout en bout. Son résultat est dans le premier commentaire.

Périmètre

Harnais de coordination (scripts/coordination/) : merge par le coordinateur, pas par l'organe. Pas de notebook, pas de règle.

…ncher (no console flash)

python.exe is a console program, so the 20-minute \CoursIA\merge_ready task
flashed a terminal on the interactive desktop (fleet audit 2026-09-24). The
task action is now wscript.exe //B //Nologo run_hidden.vbs, which runs the
previous task_command(repo) line hidden via WScript.Shell.Run(..., 0, True)
and propagates its exit code with WScript.Quit. The hidden console is
inherited by the console children spawned by --run (git, gh); pythonw.exe
would have opened one NEW visible console per child.

--dry-run prints the schtasks line AND the VBS content without writing it;
--install writes the ASCII-only launcher (loud refusal on non-ASCII) before
registering; --uninstall also removes the launcher. The element-wise /TR
quoting rule (0x80070002 regression) is preserved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jsboige

jsboige commented Sep 24, 2026

Copy link
Copy Markdown
Owner Author

Vérification de bout en bout sur ai-01 après le déploiement :

  • Get-ScheduledTask : Execute = C:\WINDOWS\System32\wscript.exe, Arguments = //B //Nologo C:\Users\MYIA\AppData\Local\CoursIA\merge_ready\run_hidden.vbs.
  • Un tour déclenché à la main (Start-ScheduledTask) a démarré à 19:56:22Z et s'est terminé à 19:57:41Z, sans fenêtre visible :
    • le journal merge_ready_20260924.log porte le run start et le run end rc=0 de ce tour ;
    • le bilan est de 90 PRs évaluées et 1 merge ;
    • Get-ScheduledTaskInfo rend LastTaskResult : 0, donc le code de sortie remonte bien à travers WScript.Quit.

@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@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 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-ai-01:CoursIA a deja consomme son budget LIGHT du jour (#17398 (merge a 2026-09-24T07:02:19Z)).
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

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-ai-01:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-24) :

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.

@github-actions

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #17705 (fix(ci): tâche merge_ready lancée via un lanceur wscript masqué (plus de fenêtre qui clignote)) 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.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: LGTM

Review avec exécution réelle du head, pas lecture seule :

  1. Fonctions pures ré-exécutées localement (vbs_content, task_action, build_schtasks_install extraites du head 53ef592) : le lanceur généré pour un repo à espaces double bien les guillemets VBScript (""…""), WshShell.Run(cmd, 0, True) + WScript.Quit remontent le code de sortie, et une commande non-ASCII est refusée fort (ValueError) — le piège ANSI/wscript est réellement gardé.
  2. Ordre d'écriture correct : le VBS est écrit AVANT l'inscription schtasks (une tâche enregistrée ne pointe jamais vers un fichier absent), et l'uninstall garde le lanceur si /Delete échoue — les deux invariants ont leurs tests dédiés, qui redirigent VBS_PATH sous tmp_path (aucun test ne touche le vrai %LOCALAPPDATA%).
  3. Preuve-vive CI : Scripts Tests (CPU) et PR gate verts au head — le job qui exécute réellement ces tests a couvert les fichiers du PR.
  4. E2E déployé : la vérification de la lane (19:59Z) — Get-ScheduledTask montre wscript.exe, tour manuel 19:56:22→19:57:41 sans fenêtre visible — ferme la boucle au-delà du statique.

Note mineure : task_action() produit C:\\Windows/System32/wscript.exe ( mélange de séparateurs hérité de Path(SystemRoot)), fonctionnel sous Windows mais inélégant — pas bloquant, wscript résout les deux formes.

[Hermes hermes-pr-review, cycle :23 24/09, host f6be46d1b7a3]

@jsboige

jsboige commented Sep 25, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2023:CoursIA
pr: 17705
head: 53ef592
complete: true
body: read
comments-reviewed: 5
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: a469c2ac8297c5beaef1a19c267e8ee0fc547c6242a92f602359f3adb8afd9fe
diff-files: 2
diff-additions: 213
diff-deletions: 25
checks: latest-wins-green
b0: clear
scope: pass
domain: not-applicable
verdict: READY
[/ADJOINT PREFLIGHT]

@myia-ai-01
myia-ai-01 merged commit 4e6e359 into main Sep 25, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants