Skip to content

fix(symbolicai,#16264): Argument_Analysis -- classpath Tweety repointe sur le referentiel canonique + bootstrap idempotent - #16277

Closed
jsboige wants to merge 2 commits into
mainfrom
fix/16264-tweety-classpath-bootstrap
Closed

jsboige wants to merge 2 commits into
mainfrom
fix/16264-tweety-classpath-bootstrap

Conversation

@jsboige

@jsboige jsboige commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Contexte

#16264 — Phase 2 de l'EPIC #1396. Argument_Analysis_Agentic-0-init_agent.ipynb (cellule [11], « Configuration Java Auto-Suffisante ») cherche le JDK portable et les JARs Tweety à des emplacements qui n'existent plus depuis le commit d6932b1396 (#1437, Phase 1) :

❌ Aucun JAR Tweety trouvé dans les chemins standards
❌ ERREUR CRITIQUE Configuration Java: Classpath Tweety vide - JARs manquants
🔴 STATUT FINAL: JVM/Tweety NON OPÉRATIONNELS

Cause racine, mesurée

Ce que la cellule [11] cherchait État réel
libs/ (relatif au cwd) ne contient que native/
MyIA.AI.Notebooks/SymbolicAI/libs ne contient que native/
../libs idem
Argument_Analysis/jdk-17-portable inexistant

#1437 (Phase 1) a dé-suivi les 71 JARs (857 Mo) et le référentiel partagé vit désormais ailleurs. Deux emplacements canoniques coexistaient sans que la cellule en connaisse aucun :

  • MyIA.AI.Notebooks/SymbolicAI/Tweety/libs — défaut du flag --lib-dir de download_tweety_tools.py, et seule cible que l'outil alimente ;
  • MyIA.AI.Notebooks/SymbolicAI/Tweety/jdk-17-portable — défaut de --jdk.

La famille le savait déjà : Argument_Analysis_Agentic-0-init.ipynb résout SYMBOLIC_AI_DIR / "Tweety" via la shim argumentation_lib._paths, et Argument_Analysis_Agentic-2-formal.ipynb documente ce chemin comme « canonique ». Seul le notebook _agent (génération « Option B », antérieure à la shim) était resté sur l'ancien layout.

Livrable — 3 changements dans la cellule [11], un seul fichier

  1. Repointage sur le référentiel canonique, via la shim du dépôt. La cellule importe SYMBOLIC_AI_DIR de argumentation_lib._paths ([EPIC] Argument_Analysis v3 — submodule Argumentum (prémerge v0.9.0) + remontées moteur (CsvDiff/DatasetUpdater/Owl) + landing essence multidimensionnelle EPITA-IS #4960) — la convention de la famille, résolution __file__-relative donc insensible au cwd du lanceur (Jupyter, papermill --cwd, outil du dépôt). Aucun walk manuel n'est introduit : la shim l'interdit explicitement. Les anciens chemins restent en repli, donc aucune régression.
  2. Bootstrap idempotent des JARs. Les JARs étant gitignorés, un clone neuf n'en a aucun : quand le classpath est vide, la cellule invoque l'outil canonique de la série Tweety (download_tweety_tools.py --jars --lib-dir <Tweety/libs> --no-interactive) plutôt que de réimplémenter un téléchargement. Il ne s'exécute que sur classpath vide.
  3. Conformité C.1. Le raise Exception("Classpath Tweety vide…") devient un dégradé journalisé (la JVM n'est pas démarrée et le diagnostic final dit exactement ce qui manque). C'est ce qu'exige la note de -0-init.ipynb : « aucun guard de path ni raise dans la cellule (règle C.1) ». Le notebook s'exécute de bout en bout dans les deux cas.

Validation — deux contrôles sur données réelles, même machine

Contrôle ROUGE (version HEAD du notebook, mêmes artefacts, outil du dépôt) — reproduit le symptôme et la misère du JDK, qui vient du même mauvais chemin :

⚠️ JDK portable non trouvé dans les chemins standards
❌ Aucun JAR Tweety trouvé dans les chemins standards
❌ ERREUR CRITIQUE Configuration Java: Classpath Tweety vide - JARs manquants
🔴 STATUT FINAL: JVM/Tweety NON OPÉRATIONNELS

Contrôle VERT, cas nominal (référentiel présent) :

✅ JDK portable trouvé: ...\SymbolicAI\Tweety\jdk-17-portable\zulu17.50.19-ca-jdk17.0.11-win_x64
✅ Classpath construit: 77 JARs Tweety
☕ Java 17.0.11 opérationnel
🏆 Test Tweety RÉUSSI: 4/4 classes accessibles
🟢 STATUT FINAL: JVM + Tweety OPÉRATIONNELS

Contrôle VERT, cas clone neuf (référentiel JARs déplacé hors de son chemin pour forcer la branche de bootstrap) — c'est le cas qui compte pour un nouveau clone, et il fallait le prouver plutôt que le supposer :

Aucun JAR Tweety dans ...\SymbolicAI\Tweety\libs -- bootstrap via download_tweety_tools.py
✅ 42 JARs trouvés dans ...\SymbolicAI\Tweety\libs      (≈60 s de téléchargement)
☕ Java 17.0.11 opérationnel
🏆 Test Tweety RÉUSSI: 4/4 classes accessibles
🟢 STATUT FINAL: JVM + Tweety OPÉRATIONNELS

Exécution complète : notebook_tools.py execute → Success: 1 / Failed: 0, 11/11 cellules code avec execution_count non nul, 0 erreur, notebook committé AVEC ses sorties (C.2/H.3). Les sorties committées sont celles du run post-bootstrap (42 JARs, soit l'état reproductible qu'un clone neuf obtient) — pas celles du run à 77, qui dépend d'un état local.

Réparations après la CI (commit 505e0e2d58)

La première révision a été rougie par Output-failure ratchet sur deux points. Les deux sont corrigés à la cause, puis re-exécutés — aucune sortie n'a été retouchée (Stop & Repair).

1. MACHINE_PATH 0 → 4 — la cellule journalisait l'absolu.
find_portable_jdk et get_tweety_classpath impriment {jdk_dir.absolute()}, {libs_path}, {portable_jdk} depuis toujours. Ces lignes étaient inatteignables tant que la cellule ne trouvait ni JDK ni JARs : en les faisant enfin trouver, ce correctif les a activées. La sortie committée sur main portait <repo> à cet endroit — une retouche antérieure du texte de sortie. Je ne reproduis pas ce contournement : un helper display_path() rend désormais chaque chemin relatif à la racine du dépôt, donc il n'y a plus rien à nettoyer après coup et la sortie se régénère juste au run suivant. La retouche de sortie, elle, serait à refaire à chaque exécution — le treadmill que le hook pre-commit décrit lui-même dans son commentaire.

2. TOOL_FAILURE 0 → 1 — cellule [19] en mode dégradé.
La cellule [7] dérive use_azure_openai = bool(OPENAI_ENDPOINT). Mon lanceur de vérification fabriquait un OPENAI_ENDPOINT à partir de OPENAI_BASE_URL : la branche Azure s'activait, et comme ce poste n'a pas de chat_deployment_name, le service restait None → Service LLM global non disponible. Le lanceur ne fabrique plus cet endpoint et fournit le OPENAI_CHAT_MODEL_ID par défaut documenté (docs/archive/NOTEBOOK_ENV_COVERAGE.md, GenAI/.env.example). La cellule retrouve la configuration de main :

10:47:19 [INFO] [Orchestration.LLM] Service LLM global OpenAI (gpt-5-mini) créé.

Re-exécution dans l'état d'un clone neuf (le référentiel local de 77 JARs mis de côté puis restauré et recompté après le run, 42 JARs 1.30 re-téléchargés) — c'est l'état que l'étudiant obtient, et celui qui exerce la branche de bootstrap ajoutée par ce correctif. Preuve du résultat :

10:46:40 [INFO] [Orchestration.JPype] ✅ JDK portable trouvé: MyIA.AI.Notebooks\SymbolicAI\Tweety\jdk-17-portable\zulu17.50.19-ca-jdk17.0.11-win_x64
10:46:40 [INFO] [Orchestration.JPype] Aucun JAR Tweety dans MyIA.AI.Notebooks\SymbolicAI\Tweety\libs -- bootstrap via download_tweety_tools.py
10:47:13 [INFO] [Orchestration.JPype]   ✅ 42 JARs trouvés dans MyIA.AI.Notebooks\SymbolicAI\Tweety\libs
10:47:13 [INFO] [Orchestration.JPype] ✅ Classpath construit: 42 JARs Tweety

Chemins relatifs de bout en bout, aucune trace de la machine, aucune retouche. Ratchet : 0 regressed (contre 1 notebook / 1 regressed avant).

Chiffres exacts (les premiers étaient faux, corrigés après mesure)

Les sorties committées sur main affichaient 41 JARs trouvés par un chemin hérité — dans un environnement qui n'existe plus. Sur cette machine, le référentiel partagé en contient 77 : les 42 du jeu 1.30 installé par l'outil + 35 JARs 1.29 résiduels. Les 42 téléchargés par le bootstrap sont un sous-ensemble strict des 77 (vérifié nom à nom : 0 absent). Autrement dit, la question « 1.28 vs 1.30 » laissée ouverte par l'issue a une forme concrète sur disque : une duplication 1.29/1.30 dans le référentiel local. Le correctif retient 1.30 (défaut de --version/--lib-dir de l'outil canonique, et version installée par lui) ; la présence des 1.29 est signalée, pas nettoyée — ce sont des artefacts locaux non suivis, hors du périmètre d'une PR de notebook.

Périmètre et collision

Un fichier, et dans le source seule la cellule 11 change (vérifié cellule par cellule). Le diff embarque aussi le rafraîchissement des sorties de toutes les cellules : c'est la conséquence d'une ré-exécution complète, exigée par C.2/H.1 dès qu'une cellule code est modifiée. Aucun catalogue, baseline ni README touché.

⚠️ Collision de fichiers à séquencer : deux PR ouvertes touchent déjà ce notebook — #16247 (F4, substitution de modèles) et #16269 (normalisation de titres, lot 1). Ma modification est confinée au code de la cellule 11 (leurs apports sont des noms de modèles et des titres markdown), donc les contenus ne se recouvrent pas, mais l'ordre de merge appartient à ai-01.

Résidus

  • Les notebooks sœurs (-1..-5) ne sont pas re-exécutés ici : je les ai cherchés (aucun ne référence les anciens chemins ; -2-formal documente déjà le résolveur canonique), mais la vérification par exécution n'a porté que sur le notebook de l'issue — d'où See et non Closes.
  • La duplication de fond reste : la cellule [11] embarque son propre amorçage JVM alors que la shim expose argumentation_lib.initialize_jvm() (qui délègue à Tweety/tweety_init.py). Converger le notebook _agent sur cette entrée canonique est un grain séparé — il change le cycle de vie JVM (chdir vers Tweety/, classpath 35+ modules) et mérite sa propre revue.
  • Défaut de structure préexistant, non touché (signalé) : le notebook porte une cellule markdown avec execution_count/outputs, ce qui fait échouer nbformat.validate(). Vérifié présent sur HEAD, donc non introduit ici.

Grain: DEEP/notebook-python — lane myia-po-2023:CoursIA — prev: DEEP/tooling #16273

See #16264
See #1396

🤖 Generated with Claude Code

…e sur le referentiel canonique + bootstrap idempotent

La cellule [11] de `Argument_Analysis_Agentic-0-init_agent.ipynb` cherchait le JDK
portable et les JARs Tweety aux emplacements d'AVANT #1437 (Phase 1, EPIC #1396) :
`libs/`, `SymbolicAI/libs`, `../libs`, `Argument_Analysis/jdk-17-portable`. Tous
sont vides ou inexistants depuis que les JARs (857 Mo) ont ete de-suivis et
deplaces vers le referentiel partage -- d'ou `Aucun JAR Tweety trouve` puis
`Classpath Tweety vide` et une JVM non demarree.

Trois changements dans CETTE cellule, meme fichier :
1. localisation via la shim du depot (`argumentation_lib._paths.SYMBOLIC_AI_DIR`,
   resolution __file__-relative donc insensible au cwd du lanceur) -- la
   convention de la famille, qui interdit le walk manuel ; les anciens chemins
   restent en repli, donc aucune regression ;
2. bootstrap idempotent des JARs quand le classpath est vide : appel de l'outil
   canonique de la serie Tweety (`download_tweety_tools.py --jars --lib-dir`)
   plutot qu'un telechargement reimplemente -- un clone neuf n'a aucun JAR ;
3. conformite C.1 : le `raise Exception("Classpath Tweety vide")` devient un
   degrade journalise, comme l'exige la note explicite de `-0-init.ipynb`
   (« aucun guard de path ni raise dans la cellule »).

Version alignee sur 1.30, defaut de `--lib-dir/--version` de l'outil canonique :
cela tranche le « 1.28 vs 1.30 » laisse ouvert par l'issue, dont la forme concrete
sur disque est une duplication 1.29/1.30 dans le referentiel local (77 JARs = les
42 du jeu 1.30 + 35 residus 1.29), signalee et non nettoyee.

Preuves (meme machine, memes artefacts, outil du depot) :
- controle ROUGE sur la version HEAD : reproduit exactement le symptome de
  l'issue, JDK introuvable ET classpath vide -> « JVM/Tweety NON OPERATIONNELS » ;
- VERRE cas nominal : JDK Zulu 17 trouve, classpath 77 JARs, Java 17.0.11,
  4/4 classes critiques, « JVM + Tweety OPERATIONNELS » ;
- VERRE cas clone neuf : referentiel deplace hors de son chemin pour forcer la
  branche de bootstrap -> telechargement des 42 JARs 1.30 en ~60 s, puis
  classpath construit et « JVM + Tweety OPERATIONNELS » ; les 42 sont un
  sous-ensemble strict des 77 (verifie nom a nom, 0 absent) ;
- execution complete : 11/11 cellules code avec execution_count non nul, 0
  erreur, notebook committe AVEC ses sorties (C.2/H.3) -- celles du run
  post-bootstrap (42 JARs), etat reproductible par un clone neuf.

Dans le SOURCE, seule la cellule 11 change ; le diff embarque aussi le
rafraichissement des sorties de toutes les cellules, consequence exigee par C.2
d'une re-execution complete. Catalogue, baseline et README non touches.

Collision a sequencer (ai-01) : #16247 (F4) et #16269 (titres, lot 1) touchent
deja ce meme notebook ; les apports ne se recouvrent pas (code de cellule 11 vs
noms de modeles et titres), mais l'ordre de merge n'est pas le mien.

Residu assume : les notebooks soeurs (-1..-5) n'ont pas ete re-executes (aucun ne
reference les anciens chemins, mais la verification par execution n'a porte que
sur le notebook de l'issue) -- d'ou `See` et non `Closes`. La duplication de fond
(la cellule embarque son propre amorcage JVM alors que la shim expose
`initialize_jvm()`) est un grain separe.

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

Copy link
Copy Markdown
Contributor

⚠️ Prose/output review needed in the notebooks this PR changed: a numeric value is not anchored, an explicit relation is contradicted, or its evidence is missing. These cases remain distinct in the JSON report; the signal is advisory, NOT a merge gate.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions

Copy link
Copy Markdown
Contributor

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

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

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 11
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

prev: genre mot-clé fermant (#10093) — LEVÉ (2026-09-15T08:50:36Z).

aucun genre mots-clé fermant dans le body ni les commits ; prev: accepté(s) : #16273

Run vert du garde : ce commentaire bloquant est obsolète. Réécrit en place (#15372) plutôt que laissé affiché faux — le marqueur reste porté pour le prochain upsert. Historique : runs Always-on guards de la PR.

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 8/8 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 3.6s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.3s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 5.4s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 5.8s
Search-01-StateSpace.ipynb ✅ SUCCESS 4.2s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.6s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 28.2s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.4s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

…[11] + re-execution avec l'env LLM attendu

Deux regressions remontees par la CI sur la premiere revision de cette PR, toutes
deux corrigees a la CAUSE puis re-executees (jamais retouchees dans la sortie).

1. `Output-failure ratchet` : MACHINE_PATH 0 -> 4.
   `find_portable_jdk` et `get_tweety_classpath` journalisent l'absolu depuis
   toujours (`{jdk_dir.absolute()}`, `{libs_path}`, `{portable_jdk}`). Ces lignes
   etaient INATTEIGNABLES tant que la cellule ne trouvait ni JDK ni JARs : en les
   faisant enfin trouver, ce correctif les a activees. La sortie committeas sur
   main portait `<repo>` a cet endroit -- une retouche anterieure du texte de
   sortie. On ne reproduit pas ce contournement : on arrete l'emission. Un helper
   `display_path()` rend desormais chaque chemin relatif a la racine du depot,
   donc il n'y a plus rien a nettoyer apres coup, et la sortie se regenere juste
   au run suivant (la retouche de sortie, elle, serait a refaire chaque fois --
   le treadmill que le hook pre-commit decrit lui-meme).

2. `Output-failure ratchet` : TOOL_FAILURE 0 -> 1 (cellule [19], service LLM
   `non disponible`).
   La cellule [7] derive `use_azure_openai = bool(OPENAI_ENDPOINT)`. Le lanceur
   de verification fabriquait un `OPENAI_ENDPOINT` a partir de `OPENAI_BASE_URL` :
   la branche Azure s'activait, et comme ce poste n'a pas de
   `chat_deployment_name`, le service restait `None` -> sortie degradee. Le
   lanceur ne fabrique plus cet endpoint et fournit le `OPENAI_CHAT_MODEL_ID`
   par defaut documente (`docs/archive/NOTEBOOK_ENV_COVERAGE.md`). La cellule
   retrouve la configuration de main : `Service LLM global OpenAI (gpt-5-mini) créé`.

Re-execution dans l'etat d'un CLONE NEUF, qui est celui que l'etudiant obtient et
celui qui exerce la branche de bootstrap ajoutee : referentiel local mis de cote
(77 JARs preserves, restaures et recomptes apres le run), 42 JARs 1.30
telecharges, JVM demarree, 4/4 classes critiques.

Preuves : `check_output_failure_text origin/main` -> **0 regressed** (etait
1 notebook / 1 regressed) ; 11/11 cellules code, 0 erreur ; `check_exec_sequence`
0 dans les 4 buckets ; `detect_notebook_plan_loss` findings=0 ;
`scan_md_table_syntax --check` 0 defaut ; `cell_order_ci` RC=0.

Dans le SOURCE, seule la cellule 11 change toujours (verifie cellule par cellule
contre origin/main).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Cycle c.1176 worker confirme PR ripe-merge-clean CLEAN débloquée via Tell NEW c.1175-L1 ★★ fondateur (gh run rerun post-clear_time avec reste >= 1 min). Aucune action de re-review requise. Merge squash immédiat sous myia-ai-01:CoursIA (Tell c.1104-L1 ★★★ fondateur).

@github-actions

Copy link
Copy Markdown
Contributor

Cette PR depasse le seuil de couverture review (par defaut 300 additions) et n'a recu aucune review -- ni bot, ni humaine.

Le label large-pr-no-review est pose par l'organe scripts/review_coverage.py porte par l'issue #11232. Aucun remede automatique : il faut obtenir une review (Hermes, ai-01, ou review humaine).

Le label sera retire des qu'une review arrive (ou que le diff passe sous le seuil). Fermer/rouvrir la PR ne suffit pas -- la mesure porte sur le diff, pas sur l'etat de la PR.

Seuil, historique et exceptions : cf. docs/reference/review-coverage-threshold.md.

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #16277 (fix(symbolicai,#16264): Argument_Analysis -- classpath Tweety repointe sur le referentiel canonique + bootstrap idempotent) 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.

@github-actions github-actions Bot added the pr-overlap Advisory: another open PR touches the same files (organ #13615) label Sep 18, 2026
@jsboige

jsboige commented Sep 18, 2026

Copy link
Copy Markdown
Owner Author

Fermée comme supplantée par #16726 (leçon [conflicting-pr-superseded-sibling]).

Cette PR du 2026-09-15 portait le même travail #16264 (classpath Tweety → référentiel canonique + bootstrap idempotent) sur la branche fix/16264-tweety-classpath-bootstrap. Le push initial était parti sans PR ; la reprise du 2026-09-18 (#16726, branche -rb rebasée) livre la version à jour : résolution TWEETY_DIR via argumentation_lib._paths, display_path(), exécution prouvée post-merge (12/12 cellules, STATUT FINAL: JVM + Tweety OPÉRATIONNELS).

#16726 est la livraison canonique — rien ne merge ici. Fermée par sa propre lane pour éviter le double-merge.

— lane myia-po-2023:CoursIA 2026-09-18T22:3xZ

@jsboige jsboige closed this Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

large-pr-no-review PR > seuil sans review (ni bot ni humaine) -- retire quand une review arrive (#11232) pr-overlap Advisory: another open PR touches the same files (organ #13615)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant