[2026-06-11] log

[2026-06-11] sim | 2022→2019 mortality harmonization + I26-I28 double-count fix

  • All cause bands re-anchored to CDC WONDER 2019 (pre-COVID): CV/cancer/neuro/infection/extrinsic re-pulled (the other 5 were already 2019); residual = 2019 all-cause − all bands − extrinsic (dense, exact).
  • Method: one subchapter×age pull/sex (D76, group V2-level1+V2-level2+V5) gives every band + all-cause; 4 precise code-pulls (K55, sepsis A40-41, dementia F01/F03, falls W00-19) for the bits subchapters can’t isolate.
  • Cardiovascular redefined as all-of-chapter-I (I00-I99, I26-I28 counted once) + K55 — fixes a pilot double-count (the original “I20-51” literal range already contained pulmonary heart I26-I28, which the pilot folded again).
  • Baseline LE re-anchored 2022→2019 (COVID removed): 75.815/80.862 → 77.459/82.118. 13 test targets re-baselined (baseline LE + intervention ΔLEs that legitimately shifted on the longer-lived baseline + the smaller 2019 extrinsic channel). 131/131; real-browser e2e 22/22.
  • Self-checks (build-app assert, HTML log, e2e baselines) + SOP/agent-brief invariant numbers + PROJECT-NOTES updated to the 2019 anchor.

[2026-06-11] schema | R53 — type:exposure (new page type)

Added a new atomic-content page type type: exposure for modifiable environmental/behavioral risk factors that fit none of the existing types (not a compound, not an intervention regimen, not a phenotype). Lives in a new top-level exposures/ directory. Surfaced while wiring node-description tooltips into the aging-simulator (viz/aging-simulator.html): the simulator’s exogenous-input nodes for smoking, alcohol, and PM2.5 air pollution had zero wiki coverage and no schema home. User chose to formalize a dedicated type (over a half-fit or leaving them link-less) — see schema-history R53 for the full rationale + frontmatter spec.

Added (schema)

  • updated: CLAUDE.md — new ### type: exposure block (frontmatter: exposure-class, agent, measure, modifiable, dose-response, target-hallmarks, target-pathways, downstream-phenotypes, mechanisms, human-evidence-level, reversibility, mendelian-randomization, literature-checked-through [required, 18mo], + verified block); exposures/ added to directory map; exposure added to the verified-required list + the literature-recency cadence table.
  • updated: schema-history.md — R53 entry.

[2026-06-11] ingest | aging-simulator node coverage — 7 pages (4 phenotype + 3 exposure), AI-extracted (verified:false)

Seeded the missing wiki entities behind the simulator’s causal-graph nodes so each node’s hover-tooltip can link to a real page. 7 parallel wiki-seeder agents (each ran the R25 date-filtered PubMed/Europe PMC recency search; all verified:false + ⚠ banner). Prompted by the viz tooltip feature; neutral research seed.

Added

  • added: phenotypes/copd.mdtype: phenotype, ICD-10 J44; COPD as accelerated lung-aging; 6-hallmark mapping; GOLD staging.
  • added: phenotypes/chronic-kidney-disease.mdtype: phenotype, ICD-10 N18; KDIGO staging; senescence/inflammaging/Klotho-FGF23; SGLT2i/finerenone landscape.
  • added: phenotypes/hypertension.mdtype: phenotype, ICD-10 I10; high-level page (Lewington log-linear SBP-risk; SPRINT/SPRINT-MIND/STEP) linking out to downstream CVD/CKD/stiffening/dementia.
  • added: phenotypes/obesity.mdtype: phenotype, ICD-10 E66; BMI vs visceral adiposity; U/J-curve + obesity-paradox dual framing; adipose senescence/SASP.
  • added: exposures/smoking.mdtype: exposure (first R53 page); Doll 2004/Jha 2013; CHRNA3/5 + GSCAN MR; epigenetic-clock acceleration; cessation reversibility.
  • added: exposures/alcohol.mdtype: exposure; J-curve-vs-MR debate (ADH1B/ALDH2) given dual framing; acetaldehyde genotoxicity; per-endpoint dose-response.
  • added: exposures/air-pollution.mdtype: exposure; PM2.5 GEMM exposure-response; CVD + the fast-moving PM2.5–dementia link; UFP translocation.

Viz (public tool, same pass)

  • updated: viz/aging-simulator.html — per-node hover description card docked at the top of the graph panel (brief plain-English “what this node simulates” + a wiki ↗ link opening the public Quartz page in a new tab); descriptions drafted via a 41-agent fan-out, each wiki path verified on disk. Also: graph-node hover/selection now highlights the matching trajectory in the node-trajectories panel; Esc / empty-click deselect; legend (i) bubbles; live-edge-weighting always-on. Model version bumped v0.4.1 → v0.5 (param-source .md + build-params.mjs sanity + params.json + inline MODEL + self-check; baseline LE male 75.81 / female 80.86 preserved).

Gaps surfaced / follow-ups

  • All 7 pages are verified:false — AI-extracted, not yet cross-checked against primary PDFs. A wiki-verifier batch is the next step (user to greenlight).
  • Candidate R54: type: phenotype has no literature-checked-through: field; three of the four phenotype seeders independently flagged that fast-moving phenotypes (CKD, hypertension, obesity) would benefit from it. Deferred to user.
  • DOI to sanity-check: obesity 10.1016/j.clnesp.2026.06.009 (future-dated 2026; confirm it resolves) — flag for the verifier.
  • Tooltip links with no dedicated page (description-only, no link): restingHR (mediator) and _mortality (terminal). dietSatFat links to molecules/compounds/palmitic-acid and LDL to pathways/lipoprotein-metabolism as the best existing proxies — a dedicated dietary-fat-quality / dyslipidemia synthesis page would be a better long-term home.
  • Stubs referenced by the new pages: [[interventions/lifestyle/smoking-cessation]], [[adipose-tissue]], [[phenotypes/alcohol-use-disorder]] (linked/mentioned, absent).

[2026-06-11] schema | R54 — type:phenotype literature-checked-through

Added optional literature-checked-through: (18mo, optional) to type: phenotype after three of the four R53 phenotype seeders independently flagged the gap. Backfilled 2026-06-11 onto copd / chronic-kidney-disease / hypertension / obesity. See schema-history R54.

  • added: exposures/dietary-fat-quality.mdtype: exposure; the dedicated fat-quality synthesis page (SFA/trans harm axis vs PUFA/MUFA replacement). Now the dietSatFat node’s link home (was the palmitic-acid proxy).
  • added: biomarkers/resting-heart-rate-biomarker.mdtype: biomarker; grounds the simulator’s resting-HR → mortality + elastin-fatigue dependencies. Now the restingHR node’s link home (was description-only).
  • R55 (resolved): modality: enum had no good value for a single-parameter resting vital sign. Added vital-sign to the type: biomarker modality enum; resting-HR page repointed physical-performance → vital-sign. See schema-history R55.

[2026-06-11] verify | wiki-verifier pass on all 9 new pages → verified:true

All 9 pages cross-checked against primary sources (parallel wiki-verifier agents), flipped to verified: true with partial verified-scope notes; ⚠ banners removed. The pass caught a striking number of AI-extraction errors — strong validation of the seed→verify discipline:

  • obesity: Lee 2022 SREBP1c–PARP1 mechanism was inverted; the future-dated Perna 2026 DOI was fabricated (corrected to the real DOI/PMID); NHANES age-split was unsourced; BMI nadir overstated.
  • smoking: Cardenas 2022 GrimAge acceleration values were inverted (current-smoker 6.36 yr, not 2.34); Doll 2004 / Jha 2013 mortality + cessation figures imprecise; one unverifiable claim removed.
  • copd: C/EBPβ fabricated as a SASP driver; TGF-β pathway wrong (Smad2 → Slug/Snail2); OR-vs-RR misattribution; prevalence understated (Adeloye 2022 age bands).
  • dietary-fat-quality: Richardson 2020 cited a wrong DOI resolving to an unrelated paper (Burkina Faso malnutrition trial); MR effect size + ApoB-vs-LDL-C conclusion corrected; Cochrane 2020 RRs + PUFA-subgroup framing corrected.
  • resting-HR: 8 wrong DOIs corrected (several resolved to unrelated papers — a chemistry-OCR paper, a remnant-cholesterol study); authorship fixes; misattributed elastin citation removed (#gap/unsourced).
  • alcohol: COSMIC SBS16 mutation signature mischaracterized (A→T transversions belong to DBS2) — corrected.
  • ckd: Grams 2023 HR 1.3 was for hospitalization, not all-cause mortality; a trial citation (Heerspink vs Wheeler) corrected; FLOW trial (2024) added as supersession.
  • hypertension: SPRINT syncope AE added; Lewington IHD effect size; Muntner population descriptor; BPROAD 2025 added to the diabetes-target limitation (supersedes the ACCORD null).
  • air-pollution: dose-response wording (sublinear → near-linear); a misleading deaths-comparison framing; WHO-guideline tag fixed.

Propagation + hygiene

  • Greps confirmed the wrong Richardson DOI (1003442) and the alcohol SBS16 error did not propagate to other pages.
  • Two stale self-referential #gap/stub notes on the hypertension page (claiming obesity/alcohol pages “don’t exist”) corrected — those pages now exist + verified.
  • Leak-gate: scrubbed private-paper-store phrasing from three verified-scope fields (replaced with “full text”); full gate clean.

Viz

  • All 41 node-tooltip wiki links resolve to real on-disk pages; dietSatFat and restingHR repointed to the two new pages. Self-check OK (v0.5).

[2026-06-11] sim | Op A pilot — fold circulatory remainder into cardiovascular band

Node-adder pilot run (Op A: extend existing band). Folded the circulatory residual codes into the cardiovascular cause-node (atherosclerosis burden). Data: CDC WONDER D76 2019, per sex × ten-year age, crude rate/100k.

Net-new codes added: hypertensive (I10, I12, I15 — excl I11/I13 already in band), pulmonary heart/embolism (I26-28), arteries incl aortic aneurysm (I70-74, I77-78), veins/lymphatic (I80-89), mesenteric infarction (K55, digestive ICD chapter but vascular mechanism), other circulatory (I95, I99).

New Rmax: M 0.059033 (was 0.054702), F 0.050486 (was 0.045587). Method: new_CV_hazard = old_CV_hazard + net_new_2019_hazard; inverse odds link → new burden; residual subtracted by exact same net-new rates.

LE: M 75.81 (target 75.815 ±0.05, PASS); F 80.84 (was 80.862; shifted 0.023 yr from PCHIP burden-curve interpolation differences between anchors; re-baselined to 80.84 ±0.05). 131/131 tests pass.

Residual reduction: M 10.5%, F 14.8% (age-weighted 20-90 sum). Hypertensive + arterial + venous + mesenteric codes removed from residual.

Re-baselined tests (6): Baseline LE female; genomic-instability freeze eff0.4 (+0.03) and eff1.0 (+0.07); atherosclerosis freeze (+0.35); chronic-inflammation freeze (+0.29); cellular-senescence freeze (+0.06). All increases physiologically correct (bigger CV band → CV-affecting interventions have larger ΔLE).

Headless render check: pre-existing failure (dataset proxy-stub limitation, not introduced by Op A). App build clean.

Open for graph-node-validator cross-check: (1) re-derive expanded CV rate from D76 2019 at net-new code list; (2) verify new Rmax = age-90 anchor of expanded rate; (3) verify burden = inverse odds link at each anchor; (4) verify total hazard at each age = old_cv_hazard + net_new_hazard + new_residual = old total. (5) I75/I76/I96-I98 were excluded as invalid in D76 v2 — validator should confirm these are genuinely unmapped (not just low-count suppressions).

[2026-06-11] sim | Op A validator pass — cardiovascular band fold verified

graph-node-validator independently cross-checked the Op A pilot (circulatory remainder → cardiovascular).

Independent CDC WONDER D76 2019 re-pull (net-new code union, aar_none, per-sex × ten-year age): rates confirmed to within WONDER’s 0.1/100k reporting precision at all 8 decade anchors (M: 0.5/2.0/6.1/14.9/33.5/66.6/146.1/433.2 per 100k; F: 0.7/1.7/4.6/9.7/21.3/50.2/136.3/490.0). Seeder used 433.1/489.9 at age 90 (one-decimal rounding difference); sub-1e-6 Rmax discrepancy, not corrected.

Rmax derivation: new_Rmax = old_Rmax + nn_h(90). Derived independently: M 0.059034 (seeder 0.059033) / F 0.050487 (seeder 0.050486). Difference ≤ 1e-6 (WONDER rounding). CONFIRMED.

Burden table: verified at all 10 atherosclerosis anchor ages (20–90 + >90 fixed). At the 8 decade anchors (where nn_h is directly measured): arithmetic exact to 1e-7. At the 2 intermediate anchors (75, 85): seeder used linear interpolation of nn_h — confirmed (implied nn_h at 75: M 106.35/100k = (66.6+146.1)/2 exactly; F 93.25/100k exactly). CONFIRMED.

Hazard invariance at anchor ages: (new_cv_h + new_res) − (old_cv_h + old_res) = 0 to 1e-9 at all 8 decade anchors for both sexes. CONFIRMED.

Excluded codes I75, I76, I96, I97, I98: independently confirmed invalid in D76 v2 via WONDER API (“Invalid ‘ICD-10 Codes’ codes were found”). Not suppressed — genuinely unmapped. CONFIRMED.

Female LE drift 80.862 → 80.84 (−0.022 yr): adjudicated as a LEGITIMATE PCHIP INTERPOLATION ARTIFACT, not an arithmetic error. Root cause: the atherosclerosis burden table has 75 and 85 as intermediate anchors (creating PCHIP slope constraints) while the residual table uses decade-only anchors. At the decade anchor points, hazard cancels exactly (1e-9); between anchors, PCHIP evaluates differently because of the differing anchor densities. Positive leak (new_cv_h + new_res > old total) concentrates at ages 71–89 with peak ~4.1e-4/yr for female at age 85; negative leak at ages 62–70 partially offsets but at higher survival weight. Net survival-weighted effect: −0.022 yr for female. Male leak is smaller (7.9% Rmax increase vs female 10.7%) and cancels more symmetrically → near-zero net. The re-baseline to 80.84 is correct. Male target 75.815 unchanged.

Provenance downgrade: seeder set provenance: "anchored" — downgraded by validator to "calibrated" because SWAP-TO-2022 is an open gap (consistent with all other D76 2019 cause nodes in the model; SOP §6 requires no open gap for anchored).

Build state: 131/131 tests pass; build-params → build-app clean; no git commit (per validator discipline).

[2026-06-11] sim | Op A batched — three band folds (neuro + liver + infection) in one pass

Node-adder batched Op A: three simultaneous folds into existing cause bands, single shared residual recompute. Data: CDC WONDER D76 2019, per sex × ten-year age, crude rate/100k (6 API requests total, ≥20 s apart). Invariant exact to ~1e-18 at all decade anchor ages ≤90.

Fold 1 — Parkinson’s + movement + systemic atrophies → neurodegeneration Net-new ICD-10: G20, G21, G23, G24, G25 (Parkinson’s disease, secondary parkinsonism, extrapyramidal/movement); G10, G11, G12, G14 (Huntington, hereditary ataxia, spinal-muscular-atrophy/ALS, post-polio). Note: G13 confirmed invalid in D76 — excluded. Net-new rates per 100k: M {20:0.1, 30:0.2, 40:0.8, 50:2.9, 60:9.0, 70:36.4, 80:157.7, 90:346.2}; F {20:0.0, 30:0.2, 40:0.5, 50:1.8, 60:5.8, 70:20.4, 80:73.3, 90:160.9}. (F age-20 suppressed <10 deaths; treated as 0.) New Rmax: M 0.026251 (was 0.022789), F 0.032590 (was 0.030981). Burden standard Gompertz-tail anchors (B=0.5 at 90, then [0.7039, 0.8497, 0.9307, 0.9696] at [100, 110, 120, 130]).

Fold 2 — viral hepatitis → liver Net-new ICD-10: B15, B16, B17, B18, B19 (acute/chronic viral hepatitis A–E). Net-new rates per 100k: M {30:0.1, 40:0.6, 50:2.0, 60:5.6, 70:5.8, 80:2.4, 90:2.0}; F {30:0.1, 40:0.3, 50:1.1, 60:2.6, 70:2.3, 80:1.9, 90:2.0}. (Both sexes age-20 suppressed; treated as 0.) New Rmax: M 0.000384 (was 0.000469), F 0.000230 (was 0.000251). Note: Rmax DECREASED for liver because viral hepatitis contributes positive hazard at age 90 (nn_liver_90 > 0) but the old liver band peaked at age 60–70 and had a hazard at 90 below the new combined peak — the >90 hazard is now flat at new_Rmax; burden >90 = 0.5 for both sexes. (Liver remains non-monotonic: peaks midlife, no Gompertz tail.)

Fold 3 — HIV + intestinal infectious → infection Net-new ICD-10: B20, B21, B22, B23, B24 (HIV disease); A00–A09 (intestinal infectious incl. C.difficile). Net-new rates per 100k: M {20:0.2, 30:1.7, 40:2.4, 50:5.0, 60:7.5, 70:8.4, 80:15.1, 90:35.9}; F {20:0.0, 30:0.6, 40:1.3, 50:2.2, 60:3.5, 70:6.0, 80:13.5, 90:39.2}. (F age-20 suppressed; treated as 0.) New Rmax: M 0.005182 (was 0.004823), F 0.003785 (was 0.003393). Burden standard Gompertz-tail anchors.

Residual update (shared recompute): New male: {20:1.34e-4, 30:3.55e-4, 40:6.59e-4, 50:1.144e-3, 60:2.391e-3, 70:4.693e-3, 80:1.090e-2, 90:3.326e-2, 100:7.960e-2, 110:1.898e-1, 120:4.517e-1, 130:1.075}. New female: {20:8.5e-5, 30:2.31e-4, 40:4.32e-4, 50:7.69e-4, 60:1.646e-3, 70:3.276e-3, 80:7.683e-3, 90:2.354e-2, 100:5.627e-2, 110:1.341e-1, 120:3.191e-1, 130:7.590e-1}.

LE: M 75.78 (target 75.815 ±0.05, PASS); F 80.81 (target 80.84 ±0.05, PASS). 131/131 tests pass.

Provenance maturity: calibrated (D76 2019 data; SWAP-TO-2022 pending as open gap).

Open for graph-node-validator cross-check: (1) re-derive nn rates for each fold from D76 2019 at the stated code lists; (2) verify new Rmax = new_band_h(90) via hazard-space mechanic; (3) verify burden inverse-odds-link at each anchor; (4) verify (new_band_h + new_residual) = (old_band_h + old_residual) to 1e-9 at all decade anchors; (5) confirm G13 invalid in D76 (genuinely unmapped, not suppressed); (6) confirm liver >90 B=0.5 derivation (new Rmax defined as new_band_h(90) = flat extrapolation → B=0.5 exactly).

[2026-06-11] sim | Op A validator pass — neuro + liver + infection batch folds verified

graph-node-validator independently cross-checked all three batched Op-A folds (Parkinson/ALS → neurodegeneration, viral hepatitis → liver, HIV + intestinal → infection). Data: CDC WONDER D76 2019 re-pulled independently via fold_pull_exact.py (O_aar=aar_none, B_1=D76.V5, F_D76.V2=individual codes, union per sex).

Independent CDC WONDER D76 2019 re-pull: all three folds confirm to within WONDER’s 0.1/100k reporting precision at all 8 decade anchors. No seeder discrepancy found.

  • Neuro M {20:0.1, 30:0.2, 40:0.8, 50:2.9, 60:9.0, 70:36.4, 80:157.7, 90:346.2}; F {20:0.0, 30:0.2, 40:0.5, 50:1.8, 60:5.8, 70:20.4, 80:73.3, 90:160.9}. CONFIRMED.
  • Liver-hep (B15-B19) M {20:0 suppressed, 30:0.1, 40:0.6, 50:2.0, 60:5.6, 70:5.8, 80:2.4, 90:2.0}; F same (20:0 suppressed, 30:0.1, 40:0.3, 50:1.1, 60:2.6, 70:2.3, 80:1.9, 90:2.0}. CONFIRMED.
  • Infection-nn (B20-B24, A00-A09) M {20:0.2, 30:1.7, 40:2.4, 50:5.0, 60:7.5, 70:8.4, 80:15.1, 90:35.9}; F {20:0.0 suppressed, 30:0.6, 40:1.3, 50:2.2, 60:3.5, 70:6.0, 80:13.5, 90:39.2}. CONFIRMED.

G13 status: confirmed genuinely invalid in D76 via direct API query — returns "Invalid 'ICD-10 Codes' codes were found: 'G13'". Not a suppression (<10 deaths), genuinely unmapped. Exclusion from neuro fold is correct.

Rmax arithmetic: derived independently from old_Rmax + nn_h(90)/100k for neuro and infection; from old_band_h(90) + nn_h(90) for liver (non-monotonic: old B(90) < 0.5, so old_h(90) < old_Rmax_peak). All new Rmax values match JSON exactly:

  • Neuro M: 0.022789 + 346.2/100k = 0.026251. JSON: 0.026251. EXACT.
  • Neuro F: 0.030981 + 160.9/100k = 0.032590. JSON: 0.032590. EXACT.
  • Infection M: 0.004823 + 35.9/100k = 0.005182. JSON: 0.005182. EXACT.
  • Infection F: 0.003393 + 39.2/100k = 0.003785. JSON: 0.003785. EXACT.
  • Liver M: old_h(90) = 0.000469 × 0.436975/(1-0.436975) = 0.000364/yr; + 2.0/100k = 0.000384. JSON: 0.000384. EXACT.
  • Liver F: old_h(90) = 0.000251 × 0.455531/(1-0.455531) = 0.000210/yr; + 2.0/100k = 0.000230. JSON: 0.000230. EXACT.

Liver reparameterization verdict (BENIGN): Rmax decreased (0.000469 → 0.000384 M; 0.000251 → 0.000230 F) because the old liver band was peak-anchored at age 60–70 (non-monotonic), so old B(90) < 0.5. After fold, new Rmax is defined as new_h(90) = old_h(90) + nn_h(90), placing B(90)=0.5 by construction. The liver HAZARD at age 90 increased by exactly +2.0/100k for both sexes. The Rmax decrease is a re-anchoring convention, not a hazard decrease. Correct in both cases.

Burden table verification: inverse-odds-link confirmed at all anchor ages (20–90 decade grid + 75/85 for neuro) for all three bands. All computed B values match JSON to ≤1e-4. Neuro age-20 rounding: true B(20)_M = 3.8e-5 (nn_h = 1.0e-6/yr vs Rmax 0.026); stored as 0 — benign, below hazard significance threshold.

Hazard invariance (vs old params): (new_band_h + new_residual) vs (old_band_h + old_residual) shows discrepancies ≤4.4e-6/yr — entirely explained by the old residual’s limited storage precision (4-5 significant figures in the decade-anchor table). The new dense residual is computed at engine float64 precision. 131/131 tests pass; LE M 75.81 / F 80.86 confirmed.

Beta cross-check: no new β edges added (pure re-bucketing Op A). Existing upstream edges (proteostasis/inflammation → neurodegeneration; immunosenescence → infection; alcohol/BMI/HbA1c → liver) unchanged.

No-age-pegging check: unaffected (no new rate laws; Op A re-buckets existing cause bands only).

Residual fraction: with the three folds, the residual contribution at age 90 is: M 0.03326/yr (was 0.03710/yr, −10.3%); F 0.02354/yr (was 0.02556/yr, −7.9%). Named mechanism fraction (covered by modeled causes) continues to grow.

Provenance: calibrated confirmed for all three (D76 2019 data; SWAP-TO-2022 open gap prevents anchored).

Build state: 131/131 tests pass; build-params → build-app clean; self-check OK (v0.5, nodes=22, edges=38). No band corrections required.

[2026-06-11] sim | Op B — new frailty cause-node (falls + malnutrition)

First Op B of the pipeline: added a new terminal-pathology cause-node frailty-mortality (“Frailty / failure-to-thrive”) to the aging-simulator, moving falls (W00-W19) and malnutrition (E40-E46) out of the residual into a named cause band. Node count 22 → 23.

Data source: CDC WONDER D76 2019, W00-W19 + E40-E46 union, per sex × ten-year age, crude rate/100k. Totals: M 24,283 / F 26,389 (matches partition doc: M 20,080 falls + 4,203 malnut; F 19,340 + 7,049). Rates per 100k:

  • Male: {20:0.7, 30:1.2, 40:2.2, 50:4.9, 60:11.2, 70:26.9, 80:97.2, 90:392.7}
  • Female: {20:0.2, 30:0.3, 40:0.8, 50:2.0, 60:5.7, 70:16.5, 80:72.4, 90:359.3}

Rmax (age-90 anchor): M 0.003927 /yr; F 0.003593 /yr.

Burden table: reserve transform B’=h/(1+h), h=rate/Rmax, at decade anchors 20–80; B=0.5 at 90; shared Gompertz-tail anchors [100,0.7039] [110,0.8497] [120,0.9307] [130,0.9696].

betaByCause.frailty = 0.8755 (reuse residual beta; behavior-invariant — pure relabel of mass already in residual with residual’s beta; falls-specific HR from Peng 2022 is deferred gap).

Residual recompute (dense, via engine): residual_new(k) = preSim.hazard[k] − (postSim.hazard[k] − postSim.decomposition[k].parts.residual) at every integer age 20→130. Dense 111-entry arrays stored. Invariant verified: LE diff male 0.00e+00, female 0.00e+00.

Render-layer changes: --cause-frailty: #e67e22 added to CSS :root and CSS_VARS static map; frailty: getCss("--cause-frailty") added to CAUSE_COLOR; frailty: "Frailty / falls" added to CAUSE_LABEL. All three maps verified consistent (CAUSE_KEYS CAUSE_COLOR keys CAUSE_LABEL keys, all 11 entries). HTML self-check updated: okNodes = (NODES.length === 23). App self-check confirms “nodes=23 edges=38; baseline LE male=75.81 female=80.86”.

LE: M 75.815 / F 80.862 (baseline invariant, exact). 131/131 tests pass with NO re-baselining.

Upstream causal hook: sarcopenia/frailty interventions bend the frailty-mortality cause via existing betaByCause.frailty = 0.8755 — the deviation-form frailtyMultFor(‘frailty’) is =1 at baseline and responds to sarcopenia deviations exactly as the residual did before.

Open for graph-node-validator cross-check: (1) re-derive W00-W19 + E40-E46 combined per-sex × ten-year-age rates from CDC WONDER D76 2019 (O_aar=aar_none, B_1=D76.V5, individual codes); (2) verify Rmax = age-90 anchor rate / 100000; (3) verify burden table = h/(1+h) where h=rate/Rmax at each decade anchor, plus >90 tail; (4) verify residual invariance: preSim.hazard[k] − (postSim.hazard[k] − postSim.residual[k]) = new_residual[k] at every age; (5) confirm betaByCause.frailty=0.8755 is the same as the residual beta (behavior-invariant requirement); (6) confirm CAUSE_KEYS, CAUSE_COLOR, CAUSE_LABEL all consistent (11 keys each, frailty present).

[2026-06-11] sim | Op B validator pass — frailty cause-node (falls + malnutrition) verified

graph-node-validator independently cross-checked the Op B fold: new frailty-mortality cause-node (W00-W19 falls + E40-E46 malnutrition).

Independent CDC WONDER D76 2019 re-pull (W00-W19 union E40-E46, O_aar=aar_none, B_1=D76.V5, per sex): rates confirmed to within WONDER’s 0.1/100k reporting precision at all decade anchors. Male death total: 24,283 (exact match). Female death total: 26,390 vs seeder 26,389 (difference of 1 — within WONDER’s suppression of <1yr infant deaths; reporting precision).

  • Male rates per 100k: {20:0.7, 30:1.2, 40:2.2, 50:4.9, 60:11.2, 70:26.9, 80:97.2, 90:392.7}. All exact matches to seeder. CONFIRMED.
  • Female rates per 100k: {20:0.2, 30:0.3, 40:0.8, 50:2.0, 60:5.7, 70:16.5, 80:72.4, 90:359.3}. All exact matches to seeder. CONFIRMED.

Rmax arithmetic: M 392.7/100000 = 0.003927 (JSON: 0.003927, exact). F 359.3/100000 = 0.003593 (JSON: 0.003593, exact). CONFIRMED.

Burden table: B = h/(1+h) where h = rate_100k/Rmax_100k, computed independently at all 8 decade anchors. All values match JSON to ≤1e-6 (machine-precision for the inverse odds-link formula). B(90)=0.5 by construction. >90 tail anchors [0.7039, 0.8497, 0.9307, 0.9696] at [100, 110, 120, 130] match the standard Gompertz-tail shared anchors used by all other bands. CONFIRMED.

betaByCause.frailty: 0.8755 confirmed, matching betaByCause.residual = 0.8755. Behavior-invariant (same beta as the slice being carved out of the residual). CONFIRMED.

Render-layer verification (enhanced-headless, Playwright not resolvable in this env): static analysis confirmed: --cause-frailty: #e67e22 present in CSS :root (line 25) and CSS_VARS (line 4803); CAUSE_KEYS = 11-key array with frailty at index 9 (before residual); CAUSE_COLOR.frailty = getCss("--cause-frailty"); CAUSE_LABEL.frailty = "Frailty / falls". Three JS maps (CSS_VARS, CAUSE_COLOR, CAUSE_LABEL) all contain frailty. App self-check block (line 6414) asserts NODES.length === 23; passed (confirmed from self-check log “nodes=23”). DAG layout: frailty-mortality has layer: "phenotype" → maps to column 6 in COL_OF_KIND; positioned via standard layoutUnified() along with the other mortality-cause nodes — no NaN-coordinate risk.

LE invariance: M 75.814722 / F 80.861714 (within 1e-3 of 75.815/80.862 target). 131/131 tests pass with NO re-baselining. Dense residual has 111 entries (ages 20–130), exact. CONFIRMED.

No-age-pegging: Op B introduces no new rate law. The frailty-mortality cause uses the same CDC-table-anchored burden + odds-link machinery as all other cause-nodes (Tier A in the audit). No new age-keyed term introduced. The frailty-mortality node folds mass that was already age-keyed in the residual into a named cause. CONFIRMED.

Residual fraction at age 90: male 18.2% of total hazard / female 14.8%; frailty fraction: male 2.4% / female 2.7%. Dense residual at age 90: M 0.029334 /yr / F 0.019942 /yr (reduced from pre-fold by frailty Rmax amount).

Provenance: calibrated confirmed. D76 2019 source; SWAP-TO-2022 and falls-specific Peng HR are open gaps; consistent with SOP §6 (any open gap blocks anchored).

Build state: build-params → test (131/131) → build-app clean. No corrections required. No git commit (per validator discipline).

[2026-06-11] sim | structural-stub infrastructure (edge-auditor) + frailty→falls restructure

Two threads. (A) Stub infrastructure (the model analogue of the wiki #stub rung): added a third causal-graph subagent edge-auditor (.claude/agents/) that surveys a node’s edges, diffs them against the verified biology (causal-graph-data.md + atomic pages), and appends kind:"stub" edges (β-pending) for the gaps. Stubs are excluded from execution at edgesByKind (engine-inert by construction — NOT by a zero magnitude, which doesn’t neutralise forms like mediatorThresholdRamp and would overwrite a frailty target), carry intendedKind, and render grey-dashed. New model/validate-graph.mjs (structural gate wired into build-params: unknown endpoints, invalid cause-targets, duplicate/colliding frailty targets, malformed forms, bad stubs) + 11 regression tests. SOP adding-causal-graph-nodes.md gained § 0a (stub schema) + § 0b (admission criteria) + the stub maturity rung.

(B) Frailty restructure (reviewer-driven; the sarcopenia→every-cause multiplier mis-attributed multi-system mortality to muscle). Steps:

  • Disconnected the 10 sarcopenia→{every cause} frailty edges. Multiplier was deviation-form (≡1 at baseline) ⇒ explained NO baseline mortality, only granted intervention benefits. Baseline LE bit-for-bit unchanged (77.458855/82.117850); sarcopenia ΔLE 4.137→0 (the entire benefit was the multiplier). Upstream interventions through stem-cell-exhaustion→sarcopenia re-baselined DOWN (chronic-inflammation 4.52→3.97, cellular-senescence 0.78→0.71, gi-eff1.0 1.98→1.89). Peng-2022 βs parked in mortality.frailty.betaByCause_DISABLED_gap (non-functional doc) — NOT transplanted.
  • Renamed the mis-named frailty cause → falls (node falls-mortality, “Falls (external injury)”); CAUSE_KEYS updated (engine + validator). Exact-invariant.
  • Populated a single, mechanistically-direct sarcopenia→falls frailty edge: β=ln(1.89)=0.6366, anchor Yeung 2019 (PMID 30993881, prospective OR 1.89). Sarcopenia ΔLE now ~0.035 yr via FALLS ONLY — two orders smaller, honest (falls ≈ 0.4% of deaths).
  • Split E40-E46 malnutrition out of the falls cause into the dense residual (graph-node-seeder Op A: CDC WONDER D76 2019 W00-W19 + E40-E46 per-sex×age; falls-only Rmax 0.003112/0.002569; dense-residual recompute). Cross-checked: falls+malnutrition Rmax = old combined exactly. Baseline LE drift ~1e-7 (residual written ~9 sig figs; gap to regenerate at full precision).
  • 142/142; build-app clean; leak-gate clean. No git commit.
  • **Deferred gaps (on the falls node + PROJECT-NOTES § frailty): external-injury merge (fold falls under a restructured terminal cause, non-fall component lifestyle-scaled); other fall drivers (balance/vision/neuropathy/hypotension/osteoporosis→fracture-fatality) as node-add candidates; a real physiologic-reserve state (observable + baseline-calibrated) for the non-specific case-fatality channel; residual full-precision regen; fall-DEATH-specific HR vs Yeung incidence OR; SWAP-TO-2022.