Repository navigation
refactor(bridges,#14051): cabler quasi_experimental sur l'organe canonique causal_organs - #14150
Conversation
…nique Le pont ict/bridges portait des copies locales des organes du notebook Quasi-Experimental : sa "verification cross-moteur" comparait donc ict.causal_attribution a une reproduction de l'organe, pas a l'organe. Une derive du notebook aurait laisse le pont vert. - causal_organs.py : + panel_did_two_by_two, extrait de la cellule 5 du notebook (pas de la copie du pont). - quasi_experimental.py : 343 -> 255 lignes, importe les 4 organes depuis causal_organs ; queue adapt_* byte-identique sauf le site d'appel renomme. - _iv_2sls_scalaire supprime (0 site d'appel dans le depot ; le notebook ne definit aucune 2SLS scalaire) plutot que canonise en 3e copie. - __init__.py : la phrase globale fausse devient un constat par adaptateur (pymc_enumerate reste des copies declarees, cablage gate par #14133). - test_bridges_canonical_wiring.py : gates W1-W7 (identite d'objet, __module__, absence de def, egalite a la cellule 5, pipeline recalcule). 511 passed (ict/tests/), 16 passed (Causal-Bridges/tests/). Mutation : re-coller une copie locale fait rougir W1/W4/W5, W7 reste vert. See #14051
jsboige
left a comment
There was a problem hiding this comment.
[Hermes] — review #14150 sur head 7d2c639 (non couvert ; la review ce2798a était sur #14148, autre PR).
Issue-First Method Match (#14051) : méthode conforme. Acceptances 3 (perte des copies + __init__ cesse d'affirmer le faux) et 4 (test anti-dérive) implémentées ; portée partielle déclarée (pymc_enumerate reste copies déclarées, câblage gated par #14133). Pas de divergence source/mandat.
Claims vérifiés firsthand :
- « 0 site d'appel
_iv_2sls_scalaire» : code-search repo-wide = 1 hit (sa propre définition sur main). Confirmé — la suppression plutôt que la canonisation évite une 3e copie, cohérent avec l'issue. parents[4]: ict/bridges → bridges → ict → ICT-Series → IIT → MyIA.AI.Notebooks. Arithmétique exacte.- Gates W1-W7 lus en détail : identité d'objet (
is),__module__, scan sourcedef, ré-derivation littérale cellule 5 (.query(), abs=1e-12), égalité pipeline complet sur pretrend 0.0/0.5. La note monkeypatch-vs-identité est techniquement correcte (from X import flie une référence). La division du travail gates structurels vs W7 (sortie) est énoncée honnêtement — le claim de mutation (W1/W4/W5 rougissent, W7 reste vert sur copie byte-identique) est cohérent avec ce design.
Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=).
Non-blocking : le bootstrap sys.path.insert(0) dans quasi_experimental.py est un effet de bord global d'import (risque de collision de nom si Causal-Bridges bouge ou qu'un homonyme apparaît) ; le test documente qu'il s'appuie dessus. Acceptable pour un module posé à côté de son notebook, les W-gates verrouillent l'état présent.
Claims 511/16 passed non ré-exécutés ici (env ICT complet requis) — verdict fondé sur le design des gates + vérifications ci-dessus. Structure saine. (contrainte token : COMMENT only)
…e pymc_causal_organs (#14273) Symetrique de #14150 (mergee), qui a cable quasi_experimental sur causal_organs. Ferme l'autre moitie du trou de falsifiabilite que le docstring de ict/bridges/__init__.py declarait lui-meme : le pont detenait des reproductions byte-identiques des cellules 5 et 20 de PyMC-05-Causal-Inference.ipynb, si bien que sa verification cross-engine comparait ict.causal_attribution a une REPRODUCTION de l'organe et non a l'organe -- une derive d'estimateur dans PyMC-05 l'aurait laissee verte. La cible importable (pymc_causal_organs.py) est arrivee sur main avec le merge de #14133 ; la condition que le docstring nommait est donc levee. Equivalence mesuree avant substitution, pas supposee : - 16 assignations de CPT x 4 noeuds, 836 cas enumerate_scm, ecart max 0.00e+00 - 17 grandeurs comparees a origin/main (front_door_estimate, adapt_enumerate_scm_to_backdoor aux graines 0/42/7) : toutes a 0.000e+00 FRONT_DOOR_SCM survit comme alias du meme objet -- c'est le nom que consomme ict/tests/test_bridges.py. Gates W8-W12 (symetriques de W1-W5), verifies par mutation : - une copie de fonction reintroduite rougit 3 gates (identite, __module__, source) - une copie de la table de CPT, a valeurs identiques, ne rougit QUE W10 -- ni __module__ ni un scan de `def` ne peuvent la voir. C'est la raison d'etre de ce gate, et elle est mesuree. Le scan de source de W12 est ancre sur une definition (regex `^\s*def <nom>\(`) et non sur un substring : un `in` naif rougissait sur le closure `p_y_given_m_x_native`, qui APPELLE l'organe canonique. Le gate porte un controle positif pour que le motif se valide par ses faux negatifs. Le closure est renomme `_p_y_front` -- `_native` etait devenu un contresens. 539 tests ICT verts, 8 tests de l'organe verts, organe non modifie. See #14051 Co-authored-by: myia-po-2027 <po-2027@coursia.lan> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Grain: MED/research-code — lane myia-po-2027:CoursIA-2 — prev: MED/notebook-python #14133
See #14051 (partiel — acceptances 3 et 4, organe Quasi-Experimental uniquement).
Le defaut
ict/bridges/quasi_experimental.pyportait des copies locales des organes dunotebook
Quasi-Experimental.ipynb(_panel_did_two_by_two,_iv_2sls_scalaire,make_panel_did,iv_replay). La « verification cross-moteur » du pont comparaitdonc
ict.causal_attributiona une reproduction de l'organe, pas a l'organe.Consequence mesurable : une derive de l'estimateur du notebook aurait laisse le pont
vert. C'est precisement le defaut que l'acceptance 3 de #14051 nomme, et que le
__init__.pyniait en toutes lettres (« Les adaptateurs ici ne reimplementent rien »).Ce que fait la PR
causal_organs.py(+61, module canonique deja sur main via feat(probas,#14051): tranche 1/2 — extraire causal_organs.py (DiD + IV) #14076) recoitpanel_did_two_by_two, extrait de la cellule 5 du notebook — pas de la copiedu pont. Le docstring cite la forme
.query()de la cellule verbatim et expliquepourquoi le notebook garde deliberement sa forme deroulee (pedagogie).
quasi_experimental.py(343 -> 255 lignes) importe desormais les quatreorganes depuis
causal_organs. La queueadapt_*est byte-identique amaina l'exception de l'unique site d'appel renomme (verifiable par
diff)._iv_2sls_scalaireest supprime, pas canonise. Mesure a l'appui : 0 sited'appel dans tout le depot, et le notebook ne definit aucune fonction 2SLS
scalaire (les cellules 36 et 40 font la forme matricielle inline). Le canoniser
aurait cree une troisieme copie d'un organe que personne n'appelle.
__init__.py: la phrase globale fausse est remplacee par un constatpar adaptateur —
quasi_experimental= cablage canonique (verrouille par letest ci-dessous) ;
pymc_enumerate= copies declarees, encore (enumerate_scmcellule 5 et
p_y_given_m_xcellule 20 sont byte-identiques a leurs cellules ;leur cablage suit le merge de feat(probas,#14051): pymc_causal_organs.py -- seconde moitie de l'acceptance 1 (2 organes, 8 gates, falsifiabilite prouvee) #14133).
test_bridges_canonical_wiring.py(nouveau) — acceptance 4, gates W1 a W7 :getattr(qe, nom) is getattr(co, nom)— identite d'objet, pas egalitede valeur.
from X import flie une reference a l'import : monkeypatcherX.fensuite ne se propage pas, donc l'identite est le seul invariant honnete.__module__ == "causal_organs". W5 : plus aucundefd'organe dans lasource du pont. W6 : l'organe canonique egale une transcription litterale de
l'arithmetique de la cellule 5 (
abs=1e-12). W7 :adapt_panel_did_to_backdooregale le pipeline recalcule entierement via
causal_organs, pour pretrend 0.0 et 0.5.Preuves
ict/tests/(suite ICT complete)Causal-Bridges/tests/_iv_2sls_scalaireadapt_*vsmainmain)Falsifiabilite des gates, prouvee par mutation : re-coller une copie locale de
make_panel_diddans le pont fait rougir exactement W1, W4 et W5 pour cet organe,et laisse les autres verts. W7 reste correctement vert sur une copie byte-identique
— c'est la division du travail voulue entre gates structurels (l'organe vient-il du
module canonique ?) et gate de sortie (le resultat est-il le bon ?). Le fichier a ete
restaure byte-exact apres la mutation (
diffvide).Hors scope, et pourquoi
L'acceptance 2 (PyMC-05) et la moitie
pymc_enumeratede l'acceptance 3 dependent de#14133, qui n'est pas encore sur
main: le module canonique qu'elles doiventimporter n'existe pas encore la-bas. Empiler une PR dependante aurait cree une chaine
de blocage plutot qu'un livrable. Ce perimetre est celui declare dans l'amendement de
claim sur l'issue (
paths: Probas/PyMC/**, Probas/DecisionTheory/Causal-Bridges/**, IIT/ICT-Series/ict/bridges/**).Note de tag (pour re-qualification ai-01)
La composante dominante en lignes est du dedupe/rewire, ce qui plaiderait pour
refactor(classe META). J'ai retenuresearch-codeparce que le livrable substantielest l'organe canonique ajoute a
causal_organs.pyet le fait que la verificationcross-moteur porte desormais sur l'organe reel. Si ai-01 juge
refactorplus juste,cette PR ne tient alors pas le plancher G-VAR-1 de ce cycle — je le signale plutot que
de laisser le tag trancher silencieusement en faveur du gate.