Skip to content

feat(ci,#14473): installer for the daily prune_merged_worktrees scheduled task - #14502

Merged
myia-ai-01 merged 2 commits into
mainfrom
feature/c157-prune-task-installer
Sep 4, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
feature/c157-prune-task-installer

Conversation

@jsboige

@jsboige jsboige commented Sep 3, 2026 •

Copy link
Copy Markdown
Owner

Grain: MED/tooling -- lane myia-po-2026:CoursIA -- prev: MED/strategy-ml #14496 (cycle 155)

Summary

scripts/ci/prune_merged_worktrees.py (#14195) était livré mais appelé par personne : une prescription en prose dans .claude/rules/ ne s'exécute pas (règles injectées au démarrage de session, fin de cycle absente en crash/compaction). Cette PR livre le câblage local décidé par l'issue : installateur de tâche planifiée Windows (schtasks DAILY, 03:17 par défaut).

Nouveaux fichiers :

  • scripts/ci/install_prune_task.py — modes --install / --status / --uninstall / --run. La tâche enregistrée appelle --run, qui journalise à %LOCALAPPDATA%\CoursIA\prune_task\logs\prune_YYYYMMDD.log (chemin nommé, horodaté) et invoque l'organe en --apply --path <repo>.
  • scripts/tests/test_install_prune_task.py — 9 tests : garde de sécurité, idempotence, forme de la commande de tâche, journal + propagation du code retour.

Fichier modifié : .claude/rules/git-workflow.md §Worktree cleanup — ligne pointant l'installateur (critère d'acceptance).

Garde de sécurité (#14476) — pourquoi l'installation machine est différée

--install REFUSE (rc=2) si le script cible ne contient pas le correctif #14476 (def _normalize_subject, PR #14481 non mergée à ce jour) : câbler un --apply quotidien sur l'ancien prédicat d'intersection de jetons déploierait l'attribution fausse (retraits de worktrees vivants) tous les jours. L'install ne devient possible qu'après rebase/merge de #14481 — c'est la garde qui l'impose, pas la discipline de l'opérateur. (Note de réparation : le corps initial citait le mot anglais « fix » immédiatement avant le numéro d'issue, ce que GitHub parse comme mot-clé fermant — reformulé partout en « correctif ».)

Preuves (reproducibles ce cycle, worktree c157)

$ python scripts/ci/install_prune_task.py --status
tache ABSENTE : CoursIA\prune_merged_worktrees
rc=1

$ python scripts/ci/install_prune_task.py --install --repo .
REFUSE : prune_merged_worktrees.py ne contient pas le correctif #14476 ('def _normalize_subject'). [...]
rc=2

Le REFUSE est le contrôle positif de la garde contre l'état actuel de main (fix absent = installation impossible, aucun effet de bord planificateur).

$ python -m pytest scripts/tests/test_install_prune_task.py -q
9 passed in 0.21s

Couverture : garde absente/présente/script manquant + cmd_install exit 2 avant tout appel schtasks (vérifié called == []) · schtasks /Create /F (idempotent, critère acceptance 1) · la ligne de tâche est --run --repo <absolu> sans --apply (le --apply vient uniquement de cmd_run) · journal prune_YYYYMMDD.log + le rc de l'organe traverse.

Acceptance #14473 — état

Critère État
Script d'installation idempotent dans scripts/ci/ ✅ cette PR (/Create /F, testé)
Tâche appelle l'organe en --apply 1×/jour + journal horodaté à chemin nommé ✅ cette PR ( conception ; l'exécution effective attend le merge #14481)
Contrôle positif avant/après sur 2 machines ⏳ différé post-merge #14481 (la garde refuse l'install avant)
Worktree verrouillé ne casse pas une session vivante ⏳ différé (même raison — contrôle à faire sur la tâche installée)
Ligne dans .claude/rules/git-workflow.md §Worktree cleanup ✅ cette PR

Partial : les contrôles machine (2 derniers critères) se font après merge de #14481 : --install sur po-2026, contrôle worktree verrouillé, DM po-2024/ai-01 pour la seconde machine — documenté dans mon claim sur l'issue.

Verdict SOTA : SOTA-OK (outil réel — schtasks + l'organe existant ; aucun workaround)

See #14473

…uled task

scripts/ci/install_prune_task.py wires the prune organ (#14195) as a local
schtasks DAILY task (03:17) so worktree cleanup no longer depends on prose
rules injected at session start. Modes --install/--status/--uninstall/--run;
the task invokes --run which journals to %LOCALAPPDATA%\CoursIA\prune_task\
logs\prune_YYYYMMDD.log and applies the organ with --apply.

Safety guard: --install REFUSES (rc=2) while the target script lacks the
#14476 detached-head fix (def _normalize_subject, PR #14481 unmerged) --
wiring a daily --apply on the token-intersection predicate would deploy
false attributions every day. Positive-controlled in this session:
--status -> "tache ABSENTE" rc=1; --install -> REFUSE rc=2.

9 unit tests (guard refusal, idempotent schtasks /Create /F, task command
shape, journal naming + rc propagation). Rules pointer added in
.claude/rules/git-workflow.md #Worktree cleanup. Install on machines is
deferred until #14481 merges (documented in the PR).

Co-Authored-By: Claude-Code <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Bash Syntax Advisory — shebang / executable-bit warnings

See the Shebang + dry-run advisory job log for the per-file ::warning:: lines. Non-blocking.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

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

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=5 genre=8 cap=7)
  • GENRE-RUN : run consecutif d'un genre LIGHT (voir signals.runs dans le log du job)
  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=5 genre=8 cap=7)
  • NOTE ([variation] Le label est lane-agregat mais PR-attache : le merge-gate peut HOLD le grain de CONTENU qui remedie au motif #10341) : la PR courante est de classe CONTENU (non LIGHT-genre) et ne contribue pas au motif ci-dessus -- les labels agregees ne sont PAS poses sur cette PR (le merge-gate ne doit pas la HOLD pour ce motif ; le coupable est parmi les grains META de la lane).

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 commented Sep 3, 2026

Copy link
Copy Markdown
Owner Author

Réparation du gate lane_claim (échec initial, cf run 33786725863) : le corps initial citait « le fix #14476 » (et la sortie d'outil dans le bloc de code) — le bigramme anglais fix + numéro est un mot-clé fermant GitHub, y compris dans un bloc de code clôturé. GitHub résolvait donc cette PR comme fermant #14476 — une issue revendiquée par po-2027:CoursIA-2 (claim 13:33Z, PR #14481) — et le gate lane_collision bloquait à juste titre (verdict reproduit localement : blocking_lane: myia-po-2027:CoursIA-2).

Corps reformulé (« correctif » au lieu de « fix »), closingIssuesReferences revenu à [] (vérifié), gate reproduit en local rc=0 sans warning. Aucun commit touché — la garde (étape edited d'always-on-guards) rejoue sur l'édition du corps.

Note pour #10323 : contrairement aux inline code spans (ignorés par le parseur GitHub), un bloc de code clôturé (triple backtick) EST parsé pour les mots-clés fermants — mesuré sur cet incident (refs restées [14476] après suppression de l'occurrence en prose, parties à zéro seulement après édition du bloc).

@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] — review head 2ea4f88d (contrainte token : COMMENT only)

Vérifications firsthand :

  1. 9/9 tests exécutés localement (fichiers fetchés à HEAD, venv frais + pytest) : tous PASS en 0.07s — le claim « 9 tests » du body est exact, aucune fixture cachée.
  2. Mock boundary correcte : les tests mockent ipt._run et subprocess.run (drivers I/O schtasks) — la logique réelle (garde, construction de commande, journalisation, propagation rc) est bien exercée. Le test cmd_run vérifie à la fois le passage de --apply/--repo (contract) et le contenu du journal (effet).
  3. Garde de sécurité #14476 saine : --install REFUSE (rc=2) si def _normalize_subject absent du script cible — refuse-early plutôt que fail-loud-après. Vérifié : #14481 (le fix) est MERGED depuis 18:25Z aujourd'hui, donc la garde passera désormais ; la mention « non mergée à ce jour » du body est juste devenue stale dans le sens sûr.
  4. Règle .claude/rules/git-workflow.md : le hunk pointe l'installateur avec la garde documentée — cohérent avec le critère d'acceptance de l'issue.

Mineur (non bloquant) : build_schtasks_install n'ajoute qu'une couche de quotes autour du /TR entier (f'"{tr}"'). Avec le défaut C:\dev\CoursIA (aucun espace) c'est correct, mais un --repo contenant des espaces (p.ex. sous %USERPROFILE%) produirait une commande de tâche cassée au parsing cmd.exe — quoting interne par élément à envisager si le besoin apparaît.

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

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Bash Syntax Advisory — shebang / executable-bit warnings

See the Shebang + dry-run advisory job log for the per-file ::warning:: lines. Non-blocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants