Skip to content

feat(probas,#14051): tranche 2/2 — notebook importe causal_organs + test anti-dérive - #14092

Merged
myia-ai-01 merged 1 commit into
mainfrom
feature/14051-tranche2-causal-organs-import
Sep 1, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
feature/14051-tranche2-causal-organs-import

Conversation

@jsboige

@jsboige jsboige commented Sep 1, 2026 •

Copy link
Copy Markdown
Owner

feat(probas,#14051): tranche 2/2 — notebook importe causal_organs + test anti-dérive

Grain: MED/notebook-python — lane myia-po-2027:CoursIA-2 — prev: DEEP/notebook-python #14076

See #14051 (tranche 2/2 sur 2 ; tranche 1/2 livrée par PR #14076 MERGED 4aef696f832f 2026-09-01).

Contexte

L'issue #14051 demande un mouvement architectural de fond : extraire les estimateurs natifs (définis en cellule) vers un module canonique causal_organs.py, que le notebook importe et que les tiers importent. La tranche 1/2 (PR #14076, MERGED 2026-09-01) a posé le module (causal_organs.py) et ses 8 tests test_causal_organs.py. Cette tranche 2/2 complète le mouvement :

Acceptance 3 (ict/bridges/*.py importe) est hors scope de cette PR : PR #13921 (OPEN, branche feature/13903-greffe5-bridges) doit merger d'abord pour que ict/bridges/quasi_experimental.py existe sur main. Tell NEW c.307-L1 ★ ★★ MAJEUR sustained : un chemin qui n'existe pas ne peut pas être adapté. Tranche 2/2 sera complétée par une tranche 3 post-merge-#13921.

Ce qui est livré

MyIA.AI.Notebooks/Probas/DecisionTheory/Causal-Bridges/Quasi-Experimental.ipynb (+8/-35 sur 3 cellules) :

  • Cellule 5 (make_panel_did) : le def make_panel_did(differential_pretrend=0.0): ... local (17 lignes) est remplacé par from causal_organs import make_panel_did, TAU_TRUE_DID. La cellule garde ses constantes de configuration N_UNITS, N_PRE, N_POST, T_ALL, ALPHA (paramétrage local du notebook, pas organe canonique).
  • Cellule 34 (TAU_TRUE_IV = 2.0) : la définition locale est remplacée par from causal_organs import TAU_TRUE_IV as TAU_TRUE_IV.
  • Cellule 40 (def iv_replay(...)) : les 13 lignes du def iv_replay(coef_z, ...): ... local sont remplacées par from causal_organs import iv_replay.

Aucun autre estimateur n'est touché (Tell NEW c.287-L1 ★★ strict sous-grain atomique) : scm_weights (c18), cv_mse (c28), mccrary_counts (c30) restent en local car ils ne sont pas dans le scope de cette tranche (la cible canonique causal_organs.py n'expose que les 2 estimateurs requis par ict.bridges).

MyIA.AI.Notebooks/Probas/DecisionTheory/Causal-Bridges/tests/test_anti_derive_notebook.py (nouveau, 236 lignes) — 8 tests pytest H.1 (pas de mock, exécution réelle des cellules du notebook via exec dans un namespace pré-chargé avec np/pd/smf/plt) :

# Test Vérifie
1 test_cellule5_make_panel_did_byte_identique_module df_nb[[group,unit,period,y]] == co.make_panel_did(seed=42) (les 3 colonnes dérivées treated/post/treated_post sont propres au notebook, pas au module)
2 test_cellule5_tau_did_hand_egal_module_tau_recovered tau_DiD a la main cellule 5 ≈ TAU_TRUE_DID (tolérance 0.5, analogue PR #13921 B1)
3 test_cellule13_violation_augmente_le_biais tau_bad > tau_clean quand differential_pretrend=0.8 (la violation SUTA engendre un biais observable)
4 test_cellule40_iv_replay_byte_identique_module tau_fort_dist_nb == co.iv_replay(coef_z=1.0) byte-identique
5 test_cellule40_iv_replay_instrument_fort_centered Instrument FORT : moyenne ≈ TAU_TRUE_IV (tol 0.5), std < 0.5
6 test_cellule40_iv_replay_instrument_faible_variance_explose Instrument FAIBLE : std > std instrument FORT
7 test_cellule34_tau_true_iv_vaut_module cellule 34 TAU_TRUE_IV is co.TAU_TRUE_IV (même référence mémoire)
8 test_cellule5_tau_true_did_vaut_module cellule 5 TAU_TRUE_DID is co.TAU_TRUE_DID (même référence mémoire)

Les tests 7 et 8 sont les gardes anti-régression stricts : si quelqu'un revertait l'import et redéfinissait TAU_TRUE_DID = 3.0 localement avec une valeur différente (ex. par copier-coller), les tests rougissent immédiatement.

Résultat : 16/16 tests verts en 8.94s (8 nouveaux + 8 tranche 1/2 PR #14076). Aucune régression.

Anti-régression (CLAUDE.md §D + Tell c.1331p248)

Source canonique : git show origin/main:MyIA.AI.Notebooks/Probas/DecisionTheory/Causal-Bridges/causal_organs.py (lue intégrale c.314).

Pattern byte-identique : vérifié par tests 1 et 4 — la cellule 5 avec np.random.seed(42) AVANT make_panel_did(0.0) produit une DataFrame byte-identique à causal_organs.make_panel_did(seed=42) parce que le seed global 42 est aligné sur le RandomState LOCAL seed=42 du module. Idem cellule 40 (np.random.seed(123) est aligné sur le comportement déterministe du module pour iv_replay(coef_z=1.0) avec seed0=0).

Tactique D appliquée :

  1. Citation erreur exacte : ict/bridges/quasi_experimental.py n'existe pas sur main (PR feat(ict,#13903): Greffe 5 tranche 2/3 -- adaptateurs cross-engine Quasi-Experimental + PyMC-05 #13921 OPEN, pas MERGED), donc acceptance 3 (ict/bridges/*.py importe) est gelée jusqu'au merge de feat(ict,#13903): Greffe 5 tranche 2/3 -- adaptateurs cross-engine Quasi-Experimental + PyMC-05 #13921. Tell NEW c.307-L1 ★ ★★ MAJEUR sustained.
  2. 3 adaptations tentées : (a) acceptance 2+3+4 en 1 PR atomic, (b) acceptance 2+4 uniquement, (c) accepter d'attendre PR feat(ict,#13903): Greffe 5 tranche 2/3 -- adaptateurs cross-engine Quasi-Experimental + PyMC-05 #13921 pour tout faire en 1 PR. Option (b) retenue — atomique + livrable, sans dépendance externe.
  3. PR debt non requise — la dédupication ict/bridges ← causal_organs est tracée explicitement dans le body de PR feat(probas,#14051): tranche 1/2 — extraire causal_organs.py (DiD + IV) #14076 + l'issue [ICT/Probas] ict.bridges duplique ses organes natifs -- extraire des modules canoniques a cote des notebooks #14051 acceptance 3 documentée hors-scope-de-cette-tranche.
  4. Diff cohérent : +224/-35 sur 2 fichiers (1 notebook + 1 fichier de tests). Tell c.745-L2 ★★★ strict 3 BANNED non violée (pas de DELETE / PATCH / PUT dismissals — c'est une nouvelle création + une modification ciblée de cellules).

Acceptance #14051 — état après cette PR

# Critère État PR
1 Modules existent + testés 🟡 1/2 modules causal_organs.py livré par #14076 ; Probas/PyMC/pymc_causal_organs.py reste à créer (vérifié absent de main)
2 Notebook importe ✅ cette PR
3 ict/bridges/*.py importe ⏳ gel PR future post-merge #13921
4 Test anti-dérive ✅ cette PR
5 DoWhy consomme les modules ⏳ hors scope PR future (#14049)

Tells sustained

  • Tell c.11900 ★★★ FIRSTHAND picker delaisse — toute affirmation vérifiée par lecture directe du notebook et du module (Tell NEW c.307-L1 ★ ★★ MAJEUR sustained ×1ᵉ cas cette PR : ict/bridges/quasi_experimental.py n'existe pas sur main, donc acceptance3 différée).
  • Tell NEW c.287-L1 ★★ strict sous-grain atomique — 2 estimateurs / 6 atomic (acceptance 3 = autre PR).
  • Tell c.795-2 ★ ★★ --body-file strict (body généré HORS worktree, gh pr create --body-file <scratchpad-path>).
  • Tell NEW c.866-L7 ★ gh pr edit --body-file HORS worktree.
  • Tell c.11145 ★★★ 0 re-ping spam ai-01 maintenu.
  • Tell c.1331p248 strict REPAIR depuis main, JAMAIS depuis PR précédente (feat(probas,#14051): tranche 1/2 — extraire causal_organs.py (DiD + IV) #14076) — branche tranche2 créée depuis origin/main (Tell c.806 LEÇON DURABLE worktree isole).
  • Tell c.816 NEW durable --force-with-lease sur branche PR à lane unique (Tell NEW c.828-L26 ★★ CONTREDIT c.828 — le push force-with-lease re-déclenche les workflows CI).
  • Tell c.806 LEÇON DURABLE — packages statsmodels/matplotlib/sklearn/seaborn installés localement (règle F : REPAIR, JAMAIS contourner).
  • G-VAR-1 strict : MED/notebook-python CONTENU (acceptance [ICT/Probas] ict.bridges duplique ses organes natifs -- extraire des modules canoniques a cote des notebooks #14051 — connecteur cross-engine) — plancher R1 tenu.

Refs #14051.

…est anti-dérive

See #14051. Tranche 2/2 sur 2 : acceptance 2 (notebook importe causal_organs)
+ acceptance 4 (test anti-dérive byte-identique). Acceptance 3 gelée
jusqu'au merge de PR #13921 (ict/bridges/quasi_experimental.py absent de main,
Tell NEW c.307-L1 ★ ★★ MAJEUR sustained).

- Cellule 5 : 'def make_panel_did' -> 'from causal_organs import'
- Cellule 34 : 'TAU_TRUE_IV = 2.0' local -> import depuis causal_organs
- Cellule 40 : 'def iv_replay' -> 'from causal_organs import'
- 8 tests pytest H.1 (pas de mock) verifient byte-identite et gardes anti-régression

Resultat : 16/16 tests verts (8 nouveaux + 8 tranche 1/2 PR #14076).
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Detector abstained (merge-base introuvable, shallow fetch or unanchored branch).

c.415 (#11873): scope = notebooks CHANGED in this PR, not the whole corpus.
See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 pathologie.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 21
  • 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 1, 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 4.0s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.2s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 5.0s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 4.8s
Search-1-StateSpace.ipynb ✅ SUCCESS 3.7s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.7s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 24.8s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.3s

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

@jsboigeEpita

Copy link
Copy Markdown
Contributor

[ADJOINT PREFLIGHT — COMMENTED, head 0fe6fe238f]

Lecture complète effectuée sur le head courant : body, 3 commentaires bot, reviews (0), threads inline GraphQL (0), diff complet, checks et organe B.0.

Substance vérifiée

Deux précisions de body à corriger sans toucher le code

  1. test_anti_derive_notebook.py fait 236 lignes, pas +216.
  2. Le tableau « Acceptance [ICT/Probas] ict.bridges duplique ses organes natifs -- extraire des modules canoniques a cote des notebooks #14051 » marque le critère 1 entièrement ✅, alors que le second module annoncé par [ICT/Probas] ict.bridges duplique ses organes natifs -- extraire des modules canoniques a cote des notebooks #14051, pymc_causal_organs.py, est encore absent de main. Écrire 1/2 modules livré éviterait de sur-déclarer la couverture; See #14051 est en revanche correct et ne ferme pas l'EPIC.

Blocage actuel

Le seul check non vert est PR gate: CANCELLED, run 33532765735. Le log dit explicitement STARVED — constituents still pending, nothing red; il a épuisé ses 28 minutes en attendant CodeQL C#, qui a ensuite fini SUCCESS à 17:18:59Z. Ce n'est pas un défaut du diff. Action recommandée : corriger les deux phrases du body, puis relancer ce run (ou laisser le stale-sweep le réagréger), sans nouveau push notebook.

Verdict preflight : substance vérifiée et aucun nit B.0; la PR devient merge-jugeable après un PR gate frais et la relecture ai-01 réservée.

@myia-ai-01

Copy link
Copy Markdown
Collaborator

[LEVÉE ai-01 — les deux réserves du preflight adjoint sont traitées en body]

Le preflight jsboigeEpita du 17:47:22Z demandait deux corrections « sans toucher au code ». Je les ai vérifiées firsthand avant de les reprendre, puis appliquées.

1. Taille de test_anti_derive_notebook.py. Mesure : gh pr view 14092 --json files → additions=236 deletions=0. Le body annonçait +216 lignes. Corrigé en 236 lignes.

2. Critère 1 d'acceptance sur-déclaré. Mesure : git ls-tree -r origin/main ne rend que Causal-Bridges/causal_organs.py et son test — Probas/PyMC/pymc_causal_organs.py est absent de main. Or #14051 exige bien deux modules (son tableau §« Module à créer » liste Probas/PyMC/pymc_causal_organs.py pour enumerate_scm/p_y_given_m_x). Marquer le critère 1 entièrement ✅ sur-déclarait la couverture. Corrigé en 🟡 1/2 modules, avec le chemin restant nommé.

Aucun push sur le notebook : édition de body seule, le PR gate du head 0fe6fe238f reste valable.

Sur le PR gate: CANCELLED diagnostiqué à 17:47 — il est depuis passé SUCCESS (run 33532765735, 1m24s), et c'est bien le seul check requis. Le diagnostic de l'adjoint était juste : STARVED — constituents still pending, nothing red, un agrégateur qui tenait le créneau qu'il attendait, jamais un défaut du diff.

Merge sous myia-ai-01. See #14051 conservé : l'EPIC reste ouverte, acceptance 3 correctement différée derrière #13921 (OPEN).

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.

3 participants