code wiki / (root) / nx_analyst_causal.nx

nx_analyst_causal.nx

buildroot/runtime/nx_analyst_causal.nx

6236 B99 linesdepth 5pulls 5 transitivereach 3 importersview sourcekind librarytopic analyst
docsdependenciesstructsconstsfunctions

about

nx_analyst_causal.nx -- F1005: the CAUSAL layer, and mostly the honesty about not having one. WHY THIS EXISTS. F1004 gave the analyst partial correlation and wired ai_confound_scan into the driver claim -- it controls for whichever candidate WEAKENS the relationship most. That is a defect, and this organ is the fix. "Control for everything, especially whatever moves the number" is a known statistical error, because a third variable's ROLE decides whether controlling for it is right, useless, or actively harmful, and no amount of correlation arithmetic can recover that role from the numbers: CONFOUNDER (z -> x, z -> y) : you MUST adjust. Not adjusting leaves a spurious association. MEDIATOR (x -> m -> y) : you must NOT adjust. Adjusting removes the very effect being measured. COLLIDER (x -> c <- y) : you must NOT adjust. Adjusting MANUFACTURES an association from nothing -- the gate demonstrates two independent columns acquiring a strong negative partial correlation purely by conditioning on their sum. All three look identical to a correlation scan. The only sound source of a role is a DECLARATION from whoever knows the domain, so that is what this organ takes -- and with no declaration it returns ASSOCIATION_ONLY and refuses to dress an argmax as a cause. SCOPE, STATED PLAINLY: this implements the backdoor rule for a DECLARED graph -- adjust for declared confounders, refuse declared colliders and mediators, refuse when nothing valid exists. It does NOT do causal discovery (learning the graph from data), instrumental variables, or sensitivity analysis to unmeasured confounding. Those are still GAP. license_tier: ORIGINAL No hardware writes (Rule 26).

dependencies 2 imports · 2 importers

nx_syscalls.nx nx_analyst_infer.nx nx_analyst_causal.nx nx_analyst_causal_gate.nx nx_analyze.nx

imports: nx_syscalls.nxnx_analyst_infer.nx

imported by: nx_analyst_causal_gate.nxnx_analyze.nx

structs

none

consts

26const AC_ROLE_UNKNOWN: i64 = 0
27const AC_ROLE_CONFOUNDER: i64 = 1
28const AC_ROLE_MEDIATOR: i64 = 2
29const AC_ROLE_COLLIDER: i64 = 3
32const AC_ASSOCIATION_ONLY: i64 = 0 // nothing declared -> no causal claim is available, full stop
33const AC_ADJUSTED: i64 = 1 // adjusted for a declared confounder: a backdoor path is blocked
34const AC_REFUSED_COLLIDER: i64 = 2 // asked to adjust for a collider -> would INDUCE association
35const AC_REFUSED_MEDIATOR: i64 = 3 // asked to adjust for a mediator -> would REMOVE the real effect
36const AC_REFUSED_NOSET: i64 = 4 // roles declared, but no confounder available to adjust for

functions

38func ac_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o + i] = s[i]; i = i + 1 } return o + i }
called by 1: ac_explain
41func ac_is_valid_control(role: i64) -> i64 { if role == AC_ROLE_CONFOUNDER { return 1 } return 0 }
44func ac_any_declared(roles: *i64, ncand: i64) -> i64
called by 1: ac_verdict
52func ac_adjustment_set(roles: *i64, ncand: i64, skip: i64, out: *i64) -> i64
called by 2: ac_verdictmain
64func ac_verdict(roles: *i64, ncand: i64, expo: i64, ctrl: i64) -> i64
80func ac_explain(verdict: i64, out: *u8) -> i64
called by 1: main calls 1: ac_cat