Skip to content

scripts/ : 71 candidats a l'archivage ou au cablage (audit haiku du 27/09, axe D de #16473) #18153

Description

@myia-ai-01

Part of #16473 (axe D, « Scripts sprawl & doublons CLI »).

Contexte

Audit en lecture seule du 27/09 : 20 agents haiku ont passé en revue les 485 scripts Python de scripts/, puis un sceptique par lot a tenté de réfuter chaque verdict « à retirer ». L'audit n'a rien exécuté ni écrit dans le dépôt. Un inventaire préalable a compté, pour chaque script, les fichiers suivis qui citent son nom (workflows, harnais, tests, scripts, notebooks, docs).

Verdict de l'audit Nombre
vivant en CI 202
outil vivant 178
ponctuel, terminé 57
mort 34
indéterminé 14

Le sceptique a contesté 91 verdicts « ponctuel » ou « mort » : 71 survivent. ai-01 a ensuite relu les 71 : recherche du nom exact dans les fichiers suivis, marqueurs « temporaire » dans le script, chemins de machine codés en dur. Le classement ci-dessous est celui de cette relecture. Les paliers 2 à 4 restent à confirmer par la lane qui fait le geste (règle audit-reassessment, environ 60 % de faux positifs).

Correction du chapeau. Le tableau de l'axe D de #16473 cite #3323 et #295 comme sous-grains « scripts ». Sur ce dépôt, #295 est l'extension de la série Reinforcement Learning, et #3323 la fidélité de Sudoku-7 : ces numéros viennent d'un autre dépôt. La présente issue est le sous-grain réel de l'axe D.

Palier 1 — ponctuels terminés, vérifiés par ai-01

Critère : le script se déclare temporaire, ou il code en dur un chemin de machine, et son produit est déjà sur main.

Script Preuve
scripts/smartcontracts/create_sc{0,15,16,18,19}_notebook.py en-tête « temporary script, delete after use » ; notebooks SC cibles présents
scripts/smartcontracts/create_sc24_25_26.py idem, plus un chemin de machine
scripts/smartcontracts/convert_print_to_deploy.py, refactor_solidity_notebooks.py chemin de machine, 0 à 4 références (docs seules)
scripts/notebook_tools/_fix_leaks_batch{2_probas,3_sudoku,4_remaining,5_c874}.py 0 référence. Le lot 1 de la même famille est déjà archivé (scripts/notebook_tools/_archive/README.md)
scripts/notebook_tools/_fix_gt15b_compilation.py, _fix_lean34_unused_vars.py se déclarent temporaires (le second code aussi un chemin de machine)
scripts/notebook_tools/c785_insert_ackley.py, c786_insert_lean_descvisuelle.py chemin de machine ; insertion faite par #7993
scripts/notebook_tools/_exec_bdd_csharp.py, optimize_dvs.py chemin de machine

À corriger au passage. scripts/notebook_tools/_archive/README.md classe c785_insert_ackley.py et c786_insert_lean_descvisuelle.py comme « fantômes, jamais existé sur disque ». Les deux fichiers existent : ils ont été ajoutés le 2026-07-22 par #7993.

Palier 2 — probables ponctuels terminés, à confirmer

Le sceptique n'a pas réfuté ces verdicts, mais ai-01 n'a pas vérifié leur produit un par un.

  • Même famille que le palier 1, sans marqueur « temporaire » : scripts/smartcontracts/create_sc{2,17,20}_notebook.py.
  • Mesures et recensements ponctuels :
    • scripts/ci/check_17464_fp_rate.py
    • scripts/ci/guard_gauntlet_smoke.py (cité dans un commentaire de scripts/tests/test_guard_gauntlet.py:557 : vérifier que rien ne l'invoque)
    • scripts/audit/detect_granular_cadrage.py (le registre de meta: recenser les issues dont le cadrage prescrit un grain unitaire et les réécrire en fournées (2e moitié du nit user sur #15515) #15573 le présente comme un instrument réutilisable : à garder si une lane l'applique encore)
    • scripts/smt/scan_z3linq_g1bis.py, scripts/smt/scan_z3linq_upstream.py
    • scripts/genai-stack/probe_minicpm5_duel.py
    • scripts/variation_volet_bc.py, scripts/variation_genre_recensement.py
    • scripts/translation/demo_t3_t4_acceptance.py
    • scripts/notebook_tools/meas_source_output_ratchet_t1.py
  • Réparations ponctuelles déjà appliquées :
    • scripts/fix_robust_dotenv.py, scripts/repair_genai_notebooks.py
    • scripts/notebook_tools/fix_qc_notebooks.py, normalize_quarto_cells.py, restructure_sw_2613.py, generate_16e.py, build_covered_csv.py
    • scripts/rebaseline_twin_pairs_post_13606.py, scripts/relabel_qc_exercises.py, scripts/remeasure_bad_pending.py
  • Vérificateurs d'un état passé :
    • scripts/quantconnect/validate_qc_project_configs.py
    • scripts/notebook_tools/verify_catalog_readme.py (15 références : vérifier qu'aucune n'est un appel)
  • Maintenance MCP : scripts/mcp-maintenance/scripts/execute_notebook_with_complex_topic.py, validate_environment.py.

Ces scripts ont souvent un test dédié. L'archivage emporte le test avec le script. Un test orphelin qui continue de passer n'est pas une raison de garder le script.

Palier 3 — à trancher par la série, pas morts en tant que tels

  • scripts/i18n/render.py, scripts/i18n/sync.py : l'EPIC d'origine est fermé. Il faut établir s'ils sont remplacés par scripts/translation/. Leur compte de références n'est pas significatif (les noms « render » et « sync » sont génériques).
  • Entraîneurs Sudoku (scripts/sudoku/ : train_classical, train_lightweight, train_v5, train_phase2_hard, train_baselines_comparison, sudoku_curriculum_train, sudoku_double_track, phase2_iterative, eval_notebook, finetune) : la série Sudoku décide lesquels portent un résultat cité par un notebook. Les autres s'archivent, avec la ligne du notebook qui cite leur résultat.
  • scripts/fallacy_detection/extract_jessynoo_fallacy.py : c'est l'extraction reproductible citée par le README de FallacyDetection (provenance du jeu de données). À garder : l'audit le classe « ponctuel » à tort.
  • scripts/audit/populate_semantickernel_cost.py : sa matrice est remplie ([#4208] Matrice coût/ressource par notebook (API $ / CPU / GPU / VRAM / compte externe / alternative gratuite) #8056), mais il est testé et documenté. À garder si la matrice doit se régénérer.

Palier 4 — outils testés et documentés, jamais câblés : câbler ou archiver

Ils ont une suite de tests et, souvent, une ligne dans docs/reference/scripts-reference.md. Mais aucun workflow, aucune skill et aucun autre script ne les appelle.

  • scripts/notebook_tools/
    • weekly_digest.py
    • scan_media_render.py
    • scan_machine_path_outputs.py
    • scan_native_both_drift.py
    • verify_kernel_env_runtime.py
    • run_composition_control.py
  • scripts/quantconnect/audit_quantbooks_output_dates.py
  • scripts/translation/check_inline_code_spans.py
  • scripts/genai-stack/commands/auto_validate.py, scripts/genai-stack/validate_all_notebooks.py
  • scripts/ci/list_orphan_prs.py
  • scripts/execute_with_env.py

Pour chacun, deux issues possibles :

  1. Le câbler : workflow advisory, skill ou appel depuis un organe vivant, en nommant le défaut qu'il attrape.
  2. L'archiver en nommant l'organe qui le remplace.

Un outil qui attrape un défaut réel mais que rien n'appelle ne protège rien.

Ce que l'audit n'a pas couvert

  • Doublons. Aucun verdict « jumeau » n'est sorti : les agents lisaient un lot de scripts chacun, sans vue d'ensemble. Une passe déterministe reste à faire : empreinte des corps de fonctions normalisés, puis regroupement des collisions entre fichiers.
  • Les 14 « indéterminés » et les 380 verdicts « vivants » n'ont pas été re-vérifiés.

Geste attendu

  • Une PR par palier ou par famille. La première peut être le palier 1, en entier.
  • Convention _archive/ (docs/reference/_archive-convention.md) :
    • déplacement vers le _archive/ du dossier, avec son test ;
    • une ligne par script dans la table du README.md (verdict, remplaçant, où le verdict est consigné) ;
    • l'en-tête de disposition dans chaque fichier.
  • Consolider n'est pas archiver : aucune suppression. Pour un script qui a un remplaçant, citer les lignes du remplaçant qui couvrent chacune de ses fonctions.
  • Avant de déplacer, relancer git grep -w <nom> et vérifier qu'aucun workflow, aucune skill ni aucun appel ne le cite.
  • Critère de fermeture : les quatre paliers sont traités (archivés, câblés, ou gardés avec une phrase de motif sur cette issue), et la passe « doublons » est livrée ou ouverte en issue fille.

Activity

  1. myia-ai-01 commented on Sep 28, 2026

    @myia-ai-01
    CollaboratorAuthor

    Passe de confirmation : palier 2 et indéterminés (28/09)

    Dix agents haiku, en lecture seule, ont repris les 41 scripts du palier 2 et des indéterminés, par lots de quatre. Pour chacun : qui l'appelle, si son produit est sur main, s'il a un test dédié. ai-01 a ensuite relancé git grep -w <nom> sur origin/main (a86aee6e2a) pour les 41, en excluant le script lui-même et son test.

    Verdict Nombre
    archiver 26
    câbler ou archiver (rejoint le palier 4) 13
    garder 1
    indéterminé 1

    Archiver : 26, confirmés

    Aucun n'est cité par un workflow ou une skill, ni appelé par un autre script. Les références restantes sont des docs ou des commentaires.

    • scripts/smartcontracts/create_sc{2,17,20}_notebook.py : les notebooks produits sont sur main (SC-02-Setup-Web3py-Python, SC-17-E2E-Verifiable-Voting-Python, SC-20-Bitcoin-Scripting-Python). Ils rejoignent le palier 1.
    • scripts/ci/check_17464_fp_rate.py, scripts/ci/guard_gauntlet_smoke.py
    • scripts/audit/detect_granular_cadrage.py : 0 appelant, une seule doc. La réserve du palier 2 tient : à garder seulement si une lane l'applique encore.
    • scripts/smt/scan_z3linq_g1bis.py, scan_z3linq_upstream.py
    • scripts/genai-stack/probe_minicpm5_duel.py
    • scripts/translation/demo_t3_t4_acceptance.py
    • scripts/variation_volet_bc.py, scripts/variation_genre_recensement.py
    • scripts/fix_robust_dotenv.py, scripts/repair_genai_notebooks.py, scripts/rebaseline_twin_pairs_post_13606.py, scripts/relabel_qc_exercises.py, scripts/remeasure_bad_pending.py
    • scripts/notebook_tools/ : fix_qc_notebooks.py, normalize_quarto_cells.py, restructure_sw_2613.py, generate_16e.py, build_covered_csv.py, meas_source_output_ratchet_t1.py, nb_view.py
    • scripts/mcp-maintenance/scripts/execute_notebook_with_complex_topic.py, validate_environment.py

    Trois points à traiter dans la PR qui les déplace :

    1. fix_robust_dotenv.py et repair_genai_notebooks.py vont ensemble. La docstring du second (ligne 3) dit qu'il répare la corruption produite par le premier.
    2. guard_gauntlet_smoke.py n'est plus cité que par un commentaire de scripts/tests/test_guard_gauntlet.py:557. Mettre ce commentaire à jour.
    3. nb_view.py est un outil de relecture (vue compacte d'un notebook pour le protocole de lecture complète), pas un ponctuel. Personne ne le cite, pas même scripts-reference.md. Verdict en confiance moyenne : l'archiver, ou le documenter si une lane s'en sert.

    Câbler ou archiver : 13, rejoignent le palier 4

    Chacun a un test dédié et aucun appelant.

    Garder : 1, retiré de la liste

    scripts/tts_verification/verify_diarization.py est l'étage 2 de la vérification des rendus TTS de #1028 : transcription, puis voix, puis prosodie (docstring de verify_prosody.py, lignes 3 à 6). L'étage 3 est appelé par le banc bakeoff_large/banc_phase_a0.py:63. L'étage 2 ne l'est pas encore, mais il appartient à ce pipeline vivant : c'est à la série audio d'en décider.

    Indéterminé : 1

    scripts/ci/resolve_pr_state.py est une lecture REST de l'état d'une PR, sans le délai d'indexation de la recherche GitHub (#13735). #13940 l'a livrée seule, sans l'intégrer, et personne ne l'a intégrée depuis. La décision revient au porteur de #13735 : l'intégrer à la garde G-VAR-3, ou l'archiver.

    Ce qui change pour le geste

    • Palier 1 : +3 (create_sc{2,17,20}).
    • Palier 2 : réduit à 23 archivages confirmés, avec les trois points ci-dessus.
    • Palier 4 : +13, dont deux paires à fusionner.
    • Avant tout déplacement, la règle reste de relancer git grep -w <nom> : cette passe date de a86aee6e2a.
  2. myia-ai-01 commented on Sep 28, 2026

    @myia-ai-01
    CollaboratorAuthor

    Passe doublons (28/09)

    C'est la passe annoncée plus haut, dans « Ce que l'audit n'a pas couvert ».

    Méthode.

    1. Une passe déterministe a lu les 485 scripts Python de scripts/ sur main. Pour chaque fonction, elle a pris l'empreinte du corps normalisé : arbre syntaxique, sans docstring ni nom de fonction. Elle a ensuite regroupé les collisions entre fichiers distincts.
    2. Le résultat : 46 groupes de corps identiques et 9 groupes quasi identiques (identiques une fois les noms de variables et les chaînes renommés).
    3. Dix-huit juges haiku, en lecture seule, ont classé les 55 groupes. Un sceptique par lot a ensuite tenté de réfuter chaque verdict « consolider ».

    Les sceptiques ont contesté 15 verdicts sur 40. Mais onze de ces contestations reposent sur un contresens : elles objectent que le module partagé proposé « n'existe pas », ce qui est le cas de toute consolidation vers un module nouveau. Aucun sceptique n'a contesté l'identité des corps. Les objections de fond sont reprises ci-dessous.

    ai-01 a vérifié à la main deux groupes :

    • check_lane_claim.py::_mask_fenced_blocks contre grain_tag.py::mask_fenced_blocks : les corps, hors docstring, ne diffèrent que par le nom du paramètre.
    • Les main() de detect_svg_broken_geometry.py et de detect_fabricated_outputs.py : ils ne diffèrent que par deux textes d'aide.

    1. Un foyer existe déjà : importer au lieu de recopier

    Copie Foyer existant
    check_lane_claim.py::_mask_fenced_blocks (56 lignes) grain_tag.py::mask_fenced_blocks
    check_exec_ratchet.py, check_papermill_ratchet.py, check_source_output_ratchet.py : changed_notebooks et EXCLUDE_MARKERS check_output_failure_text.py:348, qu'importent déjà check_output_collapse, check_output_flood, check_source_collapse et check_pr_translation_drift
    detect_papermill_{path_leak,failed_state,cell_level_state}.py::iter_notebooks notebook_walk.py:99
    extract_notebook_skeleton.py : extract_cell_preview, to_dict notebook_tools.py:404 et :276
    lean/setup_lean4_all.py::_win_to_wsl_path notebook_tools/wsl_papermill.py::win_to_wsl_path
    secrets/render_settings_json.py::read_env secrets/render_envs.py::read_env
    sudoku/train_classical.py : _eliminate, _search, _build_units_peers sudoku/core/solvers.py (seulement si la série garde cet entraîneur : palier 3)

    Réserve sur les ratchets. changed_notebooks appelle un git() local, et ce git() n'a pas le même mode d'échec d'une copie à l'autre :

    • check_exec_ratchet lève InstrumentUnavailable, en passant par fork_retry ;
    • check_papermill_ratchet rend None ;
    • check_source_output_ratchet passe par fork_retry, mais rend None sur OSError.

    Ces trois gardes sont bloquantes : les faire importer la fonction commune change leur comportement quand git est indisponible. Il faut le traiter explicitement, et non comme un simple remplacement.

    2. Un module partagé à créer : copies multiples dans des organes vivants

    • Huit détecteurs notebook_tools/detect_* ont le même main() de 38 lignes, aux textes d'aide près : detect_ascii_workaround, detect_bare_cross_dir_load, detect_fabricated_outputs, detect_quantbook_window_divergence, et les quatre detect_svg_*. Six sont câblés en CI. C'est le groupe le plus rentable.
    • pr_diff_files, en trois copies, dans check_latex_control_chars, check_math_render et check_notebook_outputs_required. Les trois sont câblés en CI, et deux commentaires citent déjà la même leçon (fix(guard,#14900): la table CTRL couvre le septieme echappement Python (BEL/a) -- 2 \approx repares #14901).
    • Accès git à une référence, dans check_render_volume_delta, detect_link_target_regression, detect_md_content_loss et detect_notebook_plan_loss : read_notebook_at_ref (3 copies), ref_resolves (3), path_exists_at_ref (2). Ne pas y ranger detect_degraded_mode.py : ses variantes ont divergé (autre signature, autre répertoire courant, pas la même garde d'erreur).
    • Détecteurs SVG : scan_notebook (3 copies), detect_cell et _cell_outputs (2), la constante _SVG_MIMES (3).
    • _gh_json, en cinq copies, dans audit/check_orphan_merged_pr, base_not_main, candidate_delivered, epic_neglect_sweep et pr_gate_missing. _repo_default a deux copies, dans check_pr_path_collisions et epic_neglect_sweep.
    • translation/extract_cells_to_csv.py et translate_csv.py : normalize. C'est la normalisation qui sert à apparier les cellules. Si les deux copies divergent, l'appariement casse sans bruit. À factoriser en priorité, même s'il n'y a que deux copies.
    • Paires, deux copies chacune :
      • check_editorial_review et check_scientific_review : parse_registry (48 lignes) et _is_real_entry ;
      • detect_quantbook_window_divergence et scan_window_drift : _split_call_args (46 lignes) ;
      • check_output_collapse et check_source_collapse : _code_cells ;
      • check_output_flood et check_source_collapse : compare ;
      • candidate_delivered et lane_claim_epic_wide : human_retraction ;
      • ci/pr_close_keyword_guard et ci/variation_prev_guard : _read_commits_file ;
      • audit/check_orphan_merged_pr et check_orphan_post_merge_commits : parse_ts, filter_by_age, run_git ;
      • detect_consecutive_code_cells et pedagogy_density : _collect_paths, _glob_notebooks ;
      • generate_catalog et regression_scan : _git_tracked_files ;
      • check_exec_sequence et check_notebook_link_render : tracked_files ;
      • lean/knot_r2connected_validation et knot_r3connected_validation : figure_eight_diagram ;
      • fix_source_newlines et fix_string_cells : _genuinely_glued. Une troisième copie est écrite en ligne dans notebook_tools.py, vers la ligne 1938.

    3. Familles ponctuelles : archiver, pas factoriser

    • _fix_leaks_batch{2,3,4} (même fix_notebook à l'identique).
    • create_sc*_notebook.py, et convert_print_to_deploy / fix_sc9_foundry / update_sc_navigation.
    • audit/populate_gametheory_cost / populate_quantconnect_cost : même décision que populate_semantickernel_cost au palier 3.

    Ces trois familles sont déjà couvertes par les paliers 1 à 3.

    4. Divergés : ne pas fusionner à l'aveugle

    La base commune des ratchets (check_exec_ratchet / check_papermill_ratchet), une seconde paire check_orphan_* et une seconde paire knot_* ont des corps proches, mais leur comportement diffère.

    Correction de mon commentaire précédent

    J'y écrivais qu'il fallait choisir entre check_density_anchor.py et check_lecture_anchor.py, puis câbler celle qu'on garde. En fait, la garde câblée existe déjà : scripts/notebook_tools/check_reading_anchor.py, issue du même #16695 et inscrite dans scripts/ci/fast_lane_registry.py. Les deux autres sont des prototypes non câblés du même défaut. Elles passent en archiver, avec check_reading_anchor.py comme remplaçant, en citant ses lignes.

    Geste

    • Une PR par famille, en commençant par les copies dans des organes câblés : les huit main(), pr_diff_files et normalize.
    • Consolider n'est pas archiver : garder le comportement exact de chaque copie, ou nommer l'écart dans le body.
    • Les tests existants de chaque organe doivent passer avant et après.
    • Ces organes relèvent du harnais CI. Les lots 1 et 2 vont à une lane qui porte les scripts, pas à une lane de contenu.
  3. jsboige commented on Sep 28, 2026

    @jsboige
    Owner

    scripts/ci/heartbeat_sweep_emit.py : à garder, il est maintenant appelé

    C'est le point que l'issue réservait à ai-01. Verdict : garder, ni archiver ni fusionner.

    Pourquoi check_scheduler_liveness.py ne le remplace pas. Les deux organes ne mesurent pas la même chose :

    • check_scheduler_liveness.py mesure l'âge du dernier run planifié, c'est-à-dire la livraison de l'événement schedule, quel que soit le résultat du run ;
    • heartbeat_sweep_emit.py mesure l'âge du dernier run réussi de pr-gate-stale-sweep.

    Le cas « le balayage se déclenche mais échoue à chaque fois » est donc vert pour le premier et rouge pour le second. De plus, la forme 1 (pr-gate-sweep-health-advisory.yml) tourne sur un runner, alors que la forme 2 existe justement pour tenir quand les runners tombent : il faut une exécution locale.

    Mesure, 28/09 vers 07:30Z, depuis ai-01 : [sweep-heartbeat] last successful pr-gate-stale-sweep.yml run: 1266s ago (OK, <3600s), rc=0. L'organe fonctionne.

    Ce qui manquait, c'était l'appel. À partir de ce cycle, ai-01 le lance en phase 2 de chaque /coordinate, avec les quatre autres organes CI, et sa ligne part dans le rapport [DONE] du dashboard.

    Ce câblage passe par la pratique du coordinateur, pas par le harnais : ajouter l'appel dans .claude/skills/coordinate/SKILL.md créerait une obligation nouvelle, donc exigerait un sign-off user. Je ne l'ouvre pas tant que la pratique n'a pas montré sa valeur.

  4. jsboige commented on Oct 1, 2026

    @jsboige
    Owner

    [CLAIMED] lane myia-po-2023:CoursIA-2 -- paths: scripts/smartcontracts/, scripts/notebook_tools/fix_leaks_batch{2,3,4,5}, scripts/notebook_tools/_fix_gt15b, scripts/notebook_tools/fix_lean34*, scripts/notebook_tools/c785*, scripts/notebook_tools/c786*, scripts/notebook_tools/_exec_bdd_csharp.py, scripts/notebook_tools/optimize_dvs.py, scripts/tests/test_convert_print_to_deploy.py -- Palier 1 archive (18 fichiers)

  5. added 3 commits that reference this issue on Oct 1, 2026
  6. added a commit that references this issue on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    auditAutomated quality audit findings

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions