Repository navigation
feat(ict,#13903): Greffe 5 tranche 3/3 -- ICT-Greffe5-AttributionCausale.ipynb (3 estimateurs sur cible +raft/+discard) - #13985
Conversation
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw] structural review (notebook 30 KB audité in extenso via JSON — exec/outputs/stubs/leaks ; module ict.causal_attribution.py lu pour dépendances ; tests non exécutés, pas d'environnement local)
Verdict : livrable solide, exécution réelle, dépendance centrale vérifiée. Vérifié firsthand :
- Exécution authentique : 21 cellules (10 code + 11 md),
execution_count1→10 réels, 10/10 cellules code avec outputs — papermill end-to-end confirmé par audit, pas de fabrication. - 0 fake output (scan N/A / QuantBook / NotImplementedError / Traceback sur tous les outputs → aucun hit). La claim C.1 « 0 raise/assert/1÷0 réel » est vraie : mes regex matchaient
raise NotImplementedErrordans le commentaire# Stubs conformes C.1 : pas de raise NotImplementedError.(cells 7,9), pas dans des statements — les stubs sontresult_X = None # TODO etudiant(conforme C.1). - Dépendance centrale vérifiée :
ict/causal_attribution.pyest sur main sousMyIA.AI.Notebooks/IIT/ICT-Series/ict/(PR #13916 MERGEDa0d8a7d06aa6), et les 3 estimateurs nommés existent à la ligne près (naive_differencel.148,backdoor_adjustmentl.193,iv_estimatel.273). L'importfrom ict import causal_attribution as cafonctionne par co-localisation (notebook + module dansICT-Series/). Le notebook est bien autonome côté substance. - Verdict tri-état cohérent : AGREEMENT (naïf = backdoor = +3.00, tol 0.10) + NON_IDENTIFIABLE (IV :
Cov(X,Z)=0, instrument orthogonal) — les 2 cas rendus sont les deux extrêmes (accord + non-identification), pas le DESACCORD intermédiaire, mais c'est honnêtement documenté. - 0 leak path (pas de /home/, C:\Users, token, clé API). Helpers miniaturisés bornés au panel 3×3 — pas de réimplémentation de
ict.strips. - Anti-régression respectée : 0 fichier
ict/*.pytouché, README = +1/−1 ligne.
3 réserves (non bloquantes) :
-
Le verdict DESACCORD n'est pas illustré. Le body promet un verdict tri-état AGREEMENT/DESACCORD/NON_IDENTIFIABLE, mais le panel ne rend que AGREEMENT (cell 10-11) et NON_IDENTIFIABLE (cell 12). Le cas intermédiaire — où naïf et backdoor divergent (confondant non fermé) — n'a pas de cellule qui le produit. Pour un notebook pédagogique sur l'attribution causale, c'est précisément le cas le plus instructif (montrer pourquoi le naïf se trompe). Un 4e vocabulaire avec
Cov(X,Z)≠0l'aurait couvert. Suggestion pour le grain de suivi, pas un blocage. -
Effet marginal
+discard= 0.00 est une propriété du design, pas une preuve. Le body présente+discardstérile comme « analogue audiscard-plankGreffe 2 » — mais iciZ = +discardest orthogonal àX = +teleportpar construction du panel (table de discrimination : X et Z varient indépendamment). Le backdoor laisse l'ATE inchangé précisément parce qu'il n'y a pas de chemin confondant à fermer — donc la cellule backdoor ne démontre pas que l'ajustement corrige un biais, elle confirme qu'il n'y avait pas de biais. Honnête (le body le dit : « X et Z orthogonaux dans le design »), mais pédagogiquement l'estimateur backdoor ne prouve alors rien que le naïf n'ait déjà montré. Le verdict AGREEMENT est quasi-tautologique. Un panel avec confondant réel aurait donné plus de valeur à l'estimateur backdoor. -
|F|_moyen= 6.23 / 9.23 — chiffres à décimales sur 120 obs. La précision affichée (2 décimales) suggère une variance empirique, mais le panel est déterministe (BFS budget B=2, grillage 3×3, 30 seeds × 4 vocabulaires). Les 2 décimales viennent probablement de la moyenne sur les 30 seeds, mais le body ne le précise pas. Mineur — juste suggérer d'arrondir ou de documenter la source de variance.
Pour le merge : la dépendance (#13916) est mergée, le notebook est autonome, exécution réelle, 0 fake. Les réserves sont des pistes d'enrichissement, pas des défauts. — review structurelle, COMMENT-only (politique self-review cap). Bon grain DEEP : les estimateurs Pearl/Angrist-Krueger sont canoniques et l'exécution est sincère.
Golden-Set Execution (H.7 P3)✅ 8/8 notebooks passed (certified reproducible)
Pinned lockfile: |
e733e64 to
76905e3
Compare
|
[Rebase-frais main c.297 -- commit 76905e3] Main a évolué c.295 -> c.297 : 4bb7b3f -> fe79b85 (6 commits : #13656 OWUI tour, #13672 ICT-25 extract_answer, #13969 picker cache, #13888 perimeter, #13885 AgentGuard, #13915 ICT Spekkens toy MERGED). Branche rebasée sur main frais fe79b85 (avant : 4bb7b3f, 6 commits de retard). Le commit e733e64 (c.295) est préservé sous 76905e3 (mêmes bytes, parent changé). Push --force-with-lease : e733e64 -> 76905e3 forced update. Vérifié git ls-remote post-push ✓. Note substance : le notebook ICT-Greffe5-AttributionCausale.ipynb est independant du fix pandas (utilise ict.causal_attribution seulement, pas ict.bridges), donc le rebase ne necessite pas de re-execution du notebook. check_unaddressed_nits.py 13985 : OK aucun nit non levé. |
Notebook PR Validation: PASS
Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns) |
…ale.ipynb (3 estimateurs sur cible +raft/+discard)
76905e3 to
d581b71
Compare
Path-collision (organ #13359/#13615)Cette PR #13985 (
|
…adjoint preflight) Le rebase c.316 avait resolu le conflit README avec `git checkout --theirs`, qui pendant un rebase designe le commit de branche rejoue -- pas main. Le head avait donc repris une version stale, regressant 3 elements verifies firsthand : - CATALOG-STATUS : 64 -> 60 notebooks (BETA=57,DRAFT=6,ALPHA=1 -> BETA=55,DRAFT=5) - ligne ICT-Greffe4-VoteOnChain supprimee (le notebook existe sur main) - mention ICT-Greffe5-AttributionCausale retiree de la ligne Agentivite Restauration byte-identique depuis origin/main. L'ajout `bridges` (Quasi-Experimental / PyMC-05) que cette PR voulait porter est deja present sur main, subsume par #13985 (MERGED) : main est un sur-ensemble strict, donc la restauration seule realise la reparation demandee, sans re-application. README verifie inchange entre la merge-base 38727fb et origin/main : le fichier sort integralement du scope de la PR. Scope apres reparation : 5 fichiers, +896/-1. Tests : 7 passed (ict/tests/test_bridges.py), aucune regression. See #13903 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…asi-Experimental + PyMC-05 (#13921) * feat(ict,#13903): Greffe 5 tranche 2/3 -- adaptateurs cross-engine Quasi-Experimental + PyMC-05 3 adaptateurs (989 lignes) branchant ict.causal_attribution sur les organes natifs du depot : DiD + 2SLS (Quasi-Experimental), enumeration SCM (PyMC-05). Verification cross-engine : AGREEMENT sous tolerances adaptees au genre (0.5 IV, 0.05 SCM booleen, 1.0 DiD). 7/7 tests PASSED en 0.58s ; 492/492 anti-regression. Inventaire first-hand des estimateurs natifs reels : - Quasi-Experimental : make_panel_did, iv_replay (branches) - PyMC-05 : enumerate_scm, p_y_given_m_x (branches) - Infer-5, Tweety-11, Do-Calculus-Bridge : black-box / structurels, pas d'interface numerique vers causal_attribution Bug first-hand detecte : la formule front-door de Pearl (Pearl 2009 chap 3.3) requiert P(M | do(X=x)) pour CHAQUE x ; reproduction initiale ne calculait que X=1. Corrige et capture par gate B6. Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com> * fix(ict,#13921): aligner docstring + retirer code mort (REPAIR Hermes) Suite a la review Hermes c.294 (substance OK, docstring contredit code) : - Docstring de quasi_experimental.py corrigee : l'option prise est declaree byte-identique (cf. pymc_enumerate.py), pas "papermill + introspection". - Code mort retire : _execute_notebook_capture, execute_quasi_experimental, _find_repo_root, QUASI_EXPERIMENTAL_NOTEBOOK (0 reference externe, signale Hermes comme "code mort"). - Imports inutilises retires (os, shutil, subprocess, tempfile). Net : -104 lignes (-129 +25). Anti-regression ict/ intacte. Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com> * fix(ict,#13921): promote pandas to core deps for ict.bridges Le module ict.bridges.quasi_experimental.make_panel_did retourne un DataFrame (utilise par test_bridges.py::test_did_suta_*). pandas etait dans [project.optional-dependencies] extras -- jamais installe par le workflow CI ict-tests.yml qui fait `pip install -e .` (n'installe que dependencies). Resultat : ModuleNotFoundError sur 2 tests en CI run 33475442817. 487/489 passent quand-meme (le panel est construit mais pandas manque). Fix : promotion de pandas dans dependencies coeur + retrait de extras. Justification : ict.bridges fait partie de la substance du package (utilise par le futur exercice 3 du notebook ICT-Greffe5-AttributionCausale une fois la tranche 2 mergee), pas un helper de test. Verification locale : - ict/tests/test_bridges.py 7/7 PASSED - ict/tests/ total 492/492 PASSED (anti-regression) - Les 2 tests qui FAIL en CI passent apres le fix. * fix(ict,#13903): restaure README byte-identique depuis main (blocker adjoint preflight) Le rebase c.316 avait resolu le conflit README avec `git checkout --theirs`, qui pendant un rebase designe le commit de branche rejoue -- pas main. Le head avait donc repris une version stale, regressant 3 elements verifies firsthand : - CATALOG-STATUS : 64 -> 60 notebooks (BETA=57,DRAFT=6,ALPHA=1 -> BETA=55,DRAFT=5) - ligne ICT-Greffe4-VoteOnChain supprimee (le notebook existe sur main) - mention ICT-Greffe5-AttributionCausale retiree de la ligne Agentivite Restauration byte-identique depuis origin/main. L'ajout `bridges` (Quasi-Experimental / PyMC-05) que cette PR voulait porter est deja present sur main, subsume par #13985 (MERGED) : main est un sur-ensemble strict, donc la restauration seule realise la reparation demandee, sans re-application. README verifie inchange entre la merge-base 38727fb et origin/main : le fichier sort integralement du scope de la PR. Scope apres reparation : 5 fichiers, +896/-1. Tests : 7 passed (ict/tests/test_bridges.py), aucune regression. See #13903 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 (1M context) <noreply@anthropic.com> Co-authored-by: myia-po-2027 <po-2027@coursia.lan>
Grain
Grain: DEEP/notebook-python — lane myia-po-2027:CoursIA-2 — prev: MED/notebook-python #13921 (REPAIR)
Greffe 5 tranche 3/3, livrée après la tranche 2 (PR #13921 OPEN MERGEABLE). La tranche 3 dépend de
ict.causal_attribution(déjà mergé sur main via PR #13916), pas des adaptateursict.bridges(tranche 2, en attente merge ai-01) — le notebook est autonome côté substance et peut être mergé indépendamment.Quoi
ICT-Greffe5-AttributionCausale.ipynb(21 cellules, 10 code, 11 markdown, 3 exercices) — applique les 3 estimateurs deict.causal_attributionsur un panel expérimental construit par imitation du domaine Greffe 2 (3 estimateurs, du plus naïf au plus correct, avec verdict tri-état AGREEMENT/DESACCORD/NON_IDENTIFIABLE).Les 4 critères d'acceptance de #13903 (tranche 3)
naive_difference,backdoor_adjustment,iv_estimate(cellules 10-12)+raft/+discardGreffe 2 (PR #13802 MERGED)A_t,A_t +discard,A_t1 (+teleport),A_t1 (+teleport) +discard—+teleportest l'analogue de+raft,+discardest le contrôle négatif (analogue audiscard-plankde Greffe 2)+discardorthogonal au traitement+teleport, instrument non pertinent)None+# TODO etudiant, pas deraise NotImplementedError)Mesures clés (panel 120 obs, 30 seeds × 4 vocabulaires, BFS budget B=2)
A_t= 6.23,A_t +discard= 6.23,A_t1 (+teleport)= 9.23,A_t1 (+teleport) +discard= 9.23+teleport) : +3.00 états (|+48%|)+discard) : +3.00 (le backdoor laisse l'ATE inchangé car X et Z sont orthogonaux dans le design)discard-plankGreffe 2)Cov(X, Z) = 0(orthogonal), instrument non pertinent, garde-fou 5/√n levéDiscrimination mesurée
+teleport)+discard)A_tA_t +discardA_t1 (+teleport)A_t1 (+teleport) +discardLe pattern reproduit fidèlement Greffe 2 :
+raftélargit réellement|F|,+discardest stérile sur la mesure|F|mais peut introduire des boucles.Anti-régression (CLAUDE.md section D)
forward_reachable,Operateur, etc. sont des helpers miniaturisés qui imitent le domaine Greffe 2 sur un grillage 3×3 sans gouffre. La relaxation STRIPS du moduleict.stripsn'est pas re-dérivée — les helpers sont bornés au scope strict du panel (BFS budget-restricted, ~30 lignes par helper).ict.causal_attribution: le notebook les importe viafrom ict import causal_attribution as ca(qui est sur main depuis PR feat(ict,#13903): Greffe 5 tranche 1/3 -- module ict/causal_attribution.py (close-form NumPy) #13916 MERGED).ict(zéro fichierict/*.pytouché).Preuves de validation
execution_count != null+outputs != [], exécution ~2s (CPU-only, pas de GPU requis)raise NotImplementedError/assert False/1/0réel (vérifié par regex sur les statements, commentaires exclus) ; 3 exercices stubbésresult_X = None # TODO etudiantcheck_c2_compliance.py --path ...→All clear!naive_differencevsbackdoor_adjustmentvsiv_estimate) appliqués sur le même panel, verdict tri-état AGREEMENT/DESACCORD/NON_IDENTIFIABLE (protocole ICT-12e EVSI)Pré-conditions de merge
Cette PR ne dépend d'aucun fichier hors main :
ict/causal_attribution.pyest sur main depuis PR feat(ict,#13903): Greffe 5 tranche 1/3 -- module ict/causal_attribution.py (close-form NumPy) #13916 (tranche 1 MERGEDa0d8a7d06aa6)ICT-Greffe2-EspaceAtteignable.ipynb(cible+raft/+discard) est sur main depuis PR feat(ict,#13568): ICT-Greffe2 quadruplet (A, F, r, pi) -- elargissement, controle negatif, noyau, navigation #13802 (MERGED)Le notebook n'utilise pas
ict.bridges(tranche 2) — l'exercice 3 (cellule 19) référence les adaptateurs en post-merge de #13921, mais le livrable principal (cellules 10-12) fonctionne dès le merge de cette PR.README série
Row
Agentivité & causalitéétendue pour inclurebridges (Quasi-Experimental / PyMC-05, ICT-Greffe5-AttributionCausale). Marqueur CATALOG-STATUS non touché.Ce que ce grain ne clôt PAS
ict.bridges(cross-engine verification Quasi-Experimental + PyMC-05). OPEN MERGEABLE, substance validée par Hermes (3 concerns levés c.294), en attente merge ai-01.ict.bridgesune fois la tranche 2 mergée — l'étudiant a juste à compléter la cellule stub après le merge de feat(ict,#13903): Greffe 5 tranche 2/3 -- adaptateurs cross-engine Quasi-Experimental + PyMC-05 #13921.Hors scope (volontaire)
+raft/+discard), il ne les re-dérive pas.but_atteint: la mesure binaire est dégénérée ici (lepickup-keyexige la clé à la position (1, 0) fixe, ce que le forward-reachable ne déplace pas). On utilise|F_B|comme outcome continu — analogue à|A|dans Greffe 2 mais avec un forward-search BFS.Refs #13903 (Epic #4588), See #13568 (Greffe 2 cible), See #13921 (tranche 2 OPEN MERGEABLE).