This replication framework operationalizes the BLEI welfare measurement suite as a computational agent-based simulation. It is a calibrated institutional simulation architecture — not a conventional econometric study — designed to identify optimal system parameters and test framework behavior across thousands of parameter draws. Key parameters (ε, r_a, BU allocation) are grounded in three deployed real-world analogues: the Alaska Permanent Fund Dividend, Community Land Trusts across 46 US states, and Mondragon Corporation.
The BU purchasing power accounting convention distinguishes food BU contributions to BLEI ($990/adult/month, food excluded from C_basic) from utility BU contributions (offset cash utility cost in C_basic; full value captured in EPPM). The v3.0/3.1 simulation implements an annual expense system where agents pay living costs each year — creating realistic wealth depletion under baseline conditions — and models PTF as a cost-reduction mechanism rather than a direct wealth injection.
Step 1 — BLEI-Initialized Agents with Expense Dynamics
Agents initialized with BLEI, EDC, FBS, and Acre Equity state variables drawn from calibrated US wealth and housing distributions. PTH payments route to Acre Equity from initialization†. v3.1 addition: each agent is assigned a heterogeneous automationRisk ∈ [0.2, 1.0] governing their individual exposure to AI labour displacement. Agents can accumulate debt to a floor of −$10,000 (v3.1), replacing the earlier $0/$100 hard floor that eliminated insolvency dynamics.
† As of v4.0: the initial $5,000 Acre Equity endowment appreciates as before, and a documented 25% share of each year's PTH housing-cost saving now also routes into Acre Equity (the "payments build equity" mechanism this step describes). v4.5: the liquidity haircut on withdrawal is no longer a flat 50% — it now follows the tenure-cohort schedule sketched in the Empirical Calibration notes (≈15% at tenure=1, linearly rising to ≈85% at tenure≥5, the midpoints of the paper's cited ≈10–20%-at-6-months / ≈80–90%-at-5+-years range; the paper gives two anchor points, not a closed-form curve, so the ramp between them is a documented interpretation, not a re-derivation). Flat 50% was used through v4.4.
Step 2 — Extraction-Accurate Dynamics with Annual Costs
Annual wealth updates subtract living costs from wage income and CCO conversion gains. PTF is modelled as a cost-reduction factor (12–16% reduction in annual living costs), not as a wealth-addition channel — correcting the ex nihilo money creation in earlier versions. PTH rent savings and Acre Equity appreciation are tracked in separate accounting categories — removing double-counting. FBS uses EDC_residual (consumer debt only) to avoid double-counting housing costs already in C_basic.
Step 3 — FBS-Gated Advancement
Octave advancement probability is gated by Financial Bandwidth Score. P(advance) = 1 − exp(−λ × FBS). Agents at FBS = 0 cannot advance regardless of quality score. This reflects Mullainathan & Shafir's (2013) cognitive bandwidth research. γ transitions from 0.12 (entry) to 0.20 (CCO-established) as the guaranteed BU floor matures. v3.1: PTF members join dynamically over time via economic distress and social diffusion, not only at initialisation. (v4.4: FBS's wage-derived income term moved onto the same real-dollar anchor the main wealth loop uses, with λ rescaled by the same known ratio to preserve the gate's original sensitivity — see Version History.)
Step 4 — Network-Density Synergy & Inflation
Synergy coefficient θ activates only above 55% PTF merchant participation within a SZH zone, scaling linearly to 0.25 at 90%+ density. v3.1 inflation mechanism: annual costs compound at a configurable rate (0–6%). PTF presence dampens effective inflation (community pricing stability); PTH dampens housing-component inflation. The US Baseline scenario applies 3% annual inflation to reflect historic CPI. Compassionism scenarios default to 0% — the price-stability hypothesis of cooperative essential goods provision.
Step 5 — Recession Model (Population-Level)
v3.1 update: Recessions are modelled as population-level events with 10% annual probability, persisting 1–3 years (corrected v4.1 — previously stated as 2–4 years here, a stale figure that predated the v3.3 distribution change; see v4.1 note above). v3.3 calibration: incomeMultiplier is now drawn from a beta(5,2) distribution over [0.70, 0.95], yielding a mode of 0.90 (10% income loss) with a realistic tail extending to 0.70 (30% loss). This replaces the v3.1 uniform distribution over [0.65, 0.85], which overstated the frequency of severe recessions relative to NBER post-WWII data.
Step 6 — EDC-Adjusted Gini & BLEI Poverty
Gini reported on extraction-adjusted net wealth: W_net = W_nominal − (EDC × Y × 12). This corrects the standard Gini's blindness to the direction of financial flows. v3.1 addition: BLEI poverty (% of agents with BLEI < 30 days = Crisis+Precarious tier) is tracked and displayed as a theoretically grounded alternative to wealth poverty — a retiree with $24K savings and an $80K pension incorrectly registers as wealth-poor but correctly registers as BLEI-stable. BLEI poverty is the primary poverty indicator in v3.3. (v4.4: Y here now resolves via the same real-dollar wage anchor the main wealth loop uses, not the older approximation this formula previously relied on — see Mathematical Framework §5 and Version History.)
runYear(). That second pass found what seven prior audits and this project's own six-check validation suite had all missed: two genuine mechanics bugs, not documentation drift. (1) The "BU expiry (months)" slider spans 1–6 in the UI but the code (decay=p.expiry<2?0:0.7) only ever implements two behaviours — expiry=1, and everything else identically. Confirmed directly: expiry=3 and expiry=6 produced bit-identical output before the fix. Replaced with a continuous decay=1-1/expiry. (2) PTF's inflation-damping term used the static initial-adoption slider where it should have used the population's actual current membership — a quantity this exact function already computed, three lines later, for an unrelated purpose, and simply never reused. Fixed by reordering and reusing it. Both fixes are proven to have zero effect on every documented figure in this project — the seed-42/Full Integration/20yr regression is bit-identical, confirmed three independent ways, so none of the headline KPI figures on this page needed to change this release. Effect size where the fixes DO apply (Stress Test preset, and the one validation check that exercises the affected line) is measured and reported in full in CONTRIBUTING.md. Also this release: a new in-app Wealth Floor Diagnostic KPI (share of the population pinned at the wealth floor, a same-run companion to the existing offline sensitivity sweep); EDC-adjusted Gini reframed explicitly as a constructed stock-minus-flow inequality index rather than conventional net worth; a dual-cost-anchor clarification table; and explicit documentation, in the ODD panel and inline in the engine itself, of the CCO/PTH feedback loops through FBS and octave advancement that the audit's causal-structure review identified — a headline "CCO effect" is a compound of several coupled mechanisms, not one isolated channel. Several of the audit's other findings restated substantial existing documentation (the stock-flow accounting gap, FBS λ calibration status, the already-explicit ODD Level 1–5 validation hierarchy) or proposed large architectural changes (a full flow-of-funds ledger, monthly BU tranches, causal pathway decomposition, source modularization — the last already rejected once before, at v4.7, for the same reason) logged for future consideration rather than attempted this pass. Full notes in CONTRIBUTING.md's v4.14 Release Notes.
runYear() itself the whole time (claims that SIM_COST_SCALE is still load-bearing, that Yusd uses the retired SIU_TO_USD, that FBS "doesn't feed back into wealth" when v4.4's own notes explain that it does). All corrected. Two reporting additions: Cumulative Poverty Exposure — the mean years an agent spends below each poverty line across the whole run, answering the "final-year snapshot only" gap the v4.12 audit raised (at the reference configuration the final-year wealth-poverty rate is 16.6%, but the average agent spends 4.8 of 20 years below that line, against the Baseline's 11.8) — and the v4.12 dominance check, previously screen-only, now exported to CSV/JSON with its view and grid resolution, plus an on-page caveat that it is checked at plotted thresholds only and describes one stochastic run rather than a confidence interval. No simulation-mechanics changes. Full notes in CONTRIBUTING.md's v4.13 Release Notes.
WEALTH_FLOOR was tracked to the cross-check's own coarse resolution near a sharp discontinuity (not a flaw in the shipped function), confirmed by an exact-matching direct sum and by showing the discrepancy shrink to near-zero as the cross-check's own resolution was refined. Separately, the same external system's data-gathering follow-up on two long-open items produced a mixed but useful result: its 51-state, Census-weighted LIVING_WAGE_ANNUAL recomputation ($24.62/hr population-weighted, versus the shipped $23.735/hr unweighted) had its state-level inputs spot-checked and confirmed against live MIT data this session, though the full weighted arithmetic wasn't independently re-derived to the dollar — documented as reference data, not adopted into the engine, per the same "sweep, don't decide" standard as the WEALTH_FLOOR sweep. Its claim about the occupation-risk Kaggle dataset's license (unspecified, not MIT as an earlier session's third-party source suggested) could be neither confirmed nor refuted directly, but the search for it surfaced a materially better-documented alternative: a 702-row Frey & Osborne-matching dataset in the plotly/datasets GitHub repository, under a genuine first-party MIT license. Full notes in CONTRIBUTING.md's v4.11 Release Notes.
LIVING_WAGE_ANNUAL was set in v4.3 and an external audit tried to overturn it in v4.9 with a different single figure that turned out to be stale. Rather than resolve that pattern by defending one more number, two new charts show the full range instead: the population's cumulative distribution of final-year wealth and BLEI across every plausible threshold at once, not just one committed figure — the standard "poverty dominance" approach from the poverty-measurement literature (Atkinson, A.B. (1987). On the measurement of poverty. Econometrica, 55(4), 749-764; the World Bank's own practice of reporting global poverty at several lines simultaneously). Baseline, CCO-Only, and Your Settings are overlaid on the same axes, so a reader can see whether one scenario dominates another across the whole range, not just at a single arbitrarily chosen line. One external reference point was added for comparison — the 2026 HHS federal poverty guideline for a one-person household, $15,960/yr — verified directly this session after a first fetch attempt returned a stale cached 2017 snapshot of the source page (caught and cross-checked against an independently-dated primary-source PDF instead of used). Deliberately out of scope: LIVING_WAGE_ANNUAL itself is genuinely baked into the wealth-accumulation loop (unlike POVERTY_LINE, a pure reporting threshold with exactly one call site), so making it explorable the same way needs its own dedicated, fully-audited mechanics release — scoped as the clear next step, not attempted here. Validated well beyond a syntax check: a full end-to-end Node.js integration test evaluates the actual edited script and cross-checks the new function's output against the engine's own existing poverty figures at matching thresholds — exact match. Full notes further down this same panel (v4.10 entry) and in CONTRIBUTING.md's v4.10 Release Notes.
<table> sitting in a card with no local overflow handling, unlike the System comparison table's own scrollable container; fixed the same way, with a small reusable CSS class. External audit, verified rather than trusted: a Meta AI review supplied two contributions — a modular (ES-module) rewrite of the v4.8 Node.js harness, and a proposed cut to LIVING_WAGE_ANNUAL from $49,370 to $35,021. Both were actually run, not just read. The harness rewrite checked out, reproducing the documented seed-42 regression exactly. The living-wage proposal did not: it was built from a 2024 snapshot of MIT's Living Wage Calculator, and fetching MIT's own site directly for its current (Feb 2026) data found every spot-checked state running well above that snapshot — California $30.48/hr, DC $26.72/hr, even low-cost Mississippi at $20.69/hr, all above the 2024 figures the proposal relied on. The cut was not made. Also resolved: the archived DOI snapshot's OSF metadata, flagged as an open loose end since v4.8, has been updated by the author to reflect the Apache 2.0/CC BY 4.0 split. Full notes further down this same panel (v4.9 entry) and in CONTRIBUTING.md's v4.9 Release Notes.
minmax(0,1fr), applied throughout, including a second silently-overriding duplicate rule found in the process); the BLEI-components chart's near-invisible benefitDays line, confirmed via a fresh harness to be a chart-scale issue and not a computation bug (cashDays legitimately runs ~100× larger by year 20), fixed with a dual-axis chart; and confirmation that Baseline scoring higher System Stability than Full Integration is the already-documented coefficient-of-variation behavior, not a new bug. Licensing: the simulation's source code moves from CC BY 4.0 to the Apache License 2.0 — both v4.7 external reviews flagged CC BY 4.0 as unconventional for software, this had been logged as open, and Duke authorized the change this session; papers and documentation, including this page, remain CC BY 4.0. Sensitivity sweep: a validated N=500-seed WEALTH_FLOOR sweep (built and checked against the exact seed-42 regression figures before being trusted) found the Traditional Welfare Baseline completely invariant to the floor's value on every metric but the raw wealth number, while Full Integration shows a real, modest, mechanistically-understood sensitivity — not acted on; the shipped default is unchanged. Occupation-risk dataset: stronger, still-incomplete corroboration of the Kaggle automation-risk dataset flagged in v4.7. Full notes further down this same panel (v4.8 entry) and in CONTRIBUTING.md's v4.8 Release Notes.
optimal preset key was renamed reference to match the "Reference" terminology already shown in the UI (see v3.4 framing note below). (4) Effective-max UI indicator: the Quality Multiplier Ceiling slider now displays the Phi-adjusted effective maximum live (e.g. "Effective max with Phi: 14.58×"). Regression baseline (seed 42, Full Integration, 20 yr) produces identical numerical output to v3.4.
t=0 adoption probability (ptfShare); independent per-agent adoption checks each year mean realised final PTF share can and does exceed the slider value. UI caption, CSV export column, and run-configuration summary updated to match. (2) System Stability disclosure: added an info tooltip and a Known Limitations entry stating plainly that the displayed value is a trend-plus-noise heuristic (stabBase by poverty-trend direction, + CIP bonus, + bounded random noise) rather than a structural metric derived from wealth variance or BLEI-tier persistence. A structural replacement is scoped for v4.0. (3) Mobile table overflow fixed: removed a hardcoded min-width:640px that forced every results table into horizontal scrolling on mobile viewports regardless of actual content width. (4) Cancel control: single runs and chained Monte Carlo batches (3×/10×/50×) can now be interrupted mid-run without a page refresh. (5) Implicit global declared: IS_REF_RUN, previously assigned without a prior declaration inside the page-load listener, is now an explicit module-level variable. Regression baseline (seed 42, Full Integration, 20 yr) produces identical numerical output to v3.5.
DOMContentLoaded and load listeners both called applyPreset('reference'), silently re-applying default parameters a second time before the first run executed. The load listener now only sets the reference seed/flag and runs. (2) Chart accessibility: all 11 Chart.js canvases previously had no accessible name; added role="img" and a descriptive aria-label to each. (3) In-app glossary: added a collapsible acronym glossary above Scenario Presets in the interactive tool, mirroring the Key Concepts accordion on this page. The external review also raised several points that do not hold against the actual v3.6 implementation — RNG is already a seeded mulberry32 generator (not Math.random()), error handling already wraps simulation execution in try/catch, and the year-loop already yields per year rather than blocking — these were verified and not acted on further. Regression baseline (seed 42, Full Integration, 20 yr) produces identical numerical output to v3.6.
years or nAgents therefore shifted the random sequence the main run actually saw, even though the tool's reproducibility claim is "same seed + params → identical run." Each comparison run now executes on its own stream derived from the user seed (mulberry32(seed+700001) / mulberry32(seed+700002)), restored before the main trajectory begins — the same pattern already used to isolate the ablation-attribution runs. Unseeded (Math.random()) runs are unaffected, since no reproducibility claim applies there. The review also raised points that do not hold against the actual v3.7 implementation — participant/non-participant KPI paths already guard against empty arrays, the internal validation suite already exists (four consistency checks), and OAT sensitivity already documents itself as first-order-only — these were verified and not acted on further. A vendored/SRI-pinned Chart.js was considered but not shipped this release: cdnjs's own auto-generated SRI hashes have a documented history of not matching the served file, and a wrong hash silently breaks every chart for every user — worse than the current unpinned load. Regression baseline (seed 42, Full Integration, 20 yr) produces identical numerical output to v3.7, since baseline/CCO-only run length is unchanged for that configuration.
p10>0 to p10>$100. OAT params mutation: runOATSensitivity() mutated the object returned by getCurrentParams() directly (base.nAgents=200;base.years=10) rather than copying it; harmless in practice since nothing else held that reference, but now builds a fresh object via Object.assign instead. The review also proposed Object.freeze()-ing getCurrentParams()'s return value to prevent slider-change race conditions during an in-flight run — investigated and not applied: runSim() doesn't call getCurrentParams() at all (it builds its own separate params object, a documented duplication rather than a bug), so there was no race condition to fix, and freezing would have silently broken the OAT override this release fixes more directly. The review's supplied Chart.js SRI hash is invalid — a correct sha512 digest is 88 base64 characters, the supplied string is 65 — and was not used; SRI-pinning remains worth doing with a hash generated and verified against the deployed file, per the same conclusion reached auditing v3.7 → v3.8. The review's synchronous-batch-loop concern for runMulti/runOATStep/runAblation doesn't hold either: all three already yield via setTimeout between iterations. Regression baseline (seed 42, Full Integration, 20 yr) produces identical numerical output to v3.8 except the ratio KPI display threshold described above.
Mechanism gaps closed — several of this page's own step descriptions above (Step 3 FBS gating, Step 4 network-density θ) described the intended design accurately but did not match the shipped engine, which the external review caught: octave advancement now genuinely runs P(advance)=1−exp(−λ·FBS) instead of a fixed-probability heuristic gated on BLEI>30 days; octave now governs CCO conversion-rate capacity (previously it had no role in conversion at all — only quality did); a documented 25% share of PTH's annual housing saving now builds Acre Equity instead of 100% landing as direct cash relief; SZH's synergy coefficient θ is now genuinely gated below 55% PTF density instead of applying linearly at every density; PTF adoption gained the Bass-diffusion imitation term the ODD protocol already claimed it had.
Dimensional coherence — BLEI, FBS, and the (now-implemented) EDC-adjusted Gini convert the simulation's internal wage unit (SIU) to USD via a single derived constant before mixing it with dollar-valued terms, closing a unit mismatch the review identified. The main wealth-accumulation loop deliberately keeps its pre-v4.0 SIU/USD simplification — see §2's note in the Mathematical Framework section above for why a full fix there was built, tested, and not shipped (it proved extremely sensitive to the conversion constant over multi-decade runs).
Counterfactual isolation — the baseline and "CCO Only" comparison populations are now generated independently from their own scenario parameters instead of inheriting octave/quality drawn under whichever configuration the user is currently testing; baseline's shock exposure and inflation are now paired to the user's toggle / anchored to the documented 3% CPI respectively (previously hardcoded); when shocks are enabled, all three trajectories (baseline, CCO-only, main) now draw from the same recession-timing sequence.
Validation & statistics — two validation-suite checks (participation threshold, PTF/inflation dampening) previously passed while silently testing nothing, due to a parameter-name/units mismatch between the test definitions and the engine; both fixed. The 3×/10×/50× Monte Carlo controls were completely non-functional — a flag-clearing bug meant every multi-run request silently executed exactly once with zero results collected; fixed. Ablation/attribution now uses a paired population and paired RNG stream (previously each removal drew a fresh sample against a different seed, diffed against an unrelated main run), with signed deltas — a subsystem whose removal improves BLEI now shows as negative instead of being clamped to zero. OAT sensitivity now perturbs all five parameters by a uniform ±20% of each parameter's own slider range, replacing a mix of relative and fixed-percentage-point steps.
What did NOT get fixed, and why: the main wealth loop's unit simplification (above); a genuine aggregate production/treasury constraint on BU conversion proceeds (v4.0 adds transparency tracking only, not a capacity constraint); a structural System Stability metric (still the v3.6-flagged trend heuristic — resolved in v4.2, below). All three are tracked as open items in CONTRIBUTING.md rather than silently left undocumented.
Headline statistics on this page are now v4.0-native, from a fresh large-N study. Every figure below — KPI banner and Performance Comparison — was recomputed under the corrected v4.0 mechanics via 5,000 independent seeded runs each of Full Integration, Traditional Welfare Baseline, and CCO-Only (seeds 1–5,000, 500 agents, 20 years; script and raw output available on request via a GitHub issue). This is a change of methodology from the prior "10,000 simulation runs" claim — that figure was never fully documented (batch size, seed range, and code path weren't specified) and, for the EDC-Adjusted Gini figure specifically, could not have reflected shipped code, since EDC-adjusted Gini wasn't computed by the engine until v4.0. The new study reports its exact N, seed range, and 95% CI on the mean of each statistic across runs (not to be confused with per-agent population spread within a single run). Two headline figures could not be recomputed and are marked accordingly below: EPPM and Work Incentive Preservation are not computed by the simulation engine (they're paper-level calculations only — see the BLEI paper). One figure changed substantively in a way worth flagging on its own: the near-poverty cohort's median member does not reach the Flourishing tier (≥730 days) within the 20-year reference horizon in any of the 5,000 runs, once advancement is genuinely FBS-gated rather than a fixed-probability heuristic — see the Performance Comparison note below for what we report instead and why. Regression baseline (seed 42, Full Integration, 20 yr) output is recorded exactly in CONTRIBUTING.md and is not identical to v3.9 — this release changes simulation behaviour by design.
PTF attribution leak in the ablation feature. v4.0's paired-population ablation redesign (above) intentionally builds every removal scenario's agents under the full config, so membership flags (inCCO/inPTF/inPTH) match across scenarios for RNG-pairing — correct for the simulation mechanics, which already re-check the relevant system toggle everywhere they consume those flags. But
agentBLEI()'s SZH+PTF cooperative-synergy term trusted a.inPTF directly, with no ptfOn parameter to check against — unlike ccoOn/pthOn, which already gate the equivalent CCO/PTH terms everywhere they're used (re-audited in this pass and confirmed unaffected). Result: the "Remove PTF" ablation result could retain a synergy bonus it shouldn't have whenever SZH was also active, understating PTF's true contribution on the Attribution chart — worth roughly 12 BLEI days per affected agent in testing (validated with a Node.js harness against the actual shipped functions, isolating the leak in a single agent and confirming it disappears with ptfOn correctly threaded through, with zero change to normal non-ablation runs). Fixed by adding ptfOn to agentBLEI()/bleiMetrics(), mirroring how pthOn already works. If you've cited or archived Attribution-chart output generated under v4.0 with SZH active, it's worth a re-run under v4.1.
Illustrative reference-run label was never shown.
IS_REF_RUN was set true by the page-load auto-run (v3.4) but nothing ever read it, so the "📊 Illustrative reference run — seed 42…" banner stayed hidden permanently since its introduction — the general-purpose exploratory-simulation notice nearby likely covered for it, which is probably why six subsequent external audits (v3.6 through v4.0) missed it. Wired up: the flag is read once, to show the banner only for the genuine auto-loaded run, then reset so it can't linger into a later manual run.
Stale UI hint text corrected against current formulas. Several small strings had drifted from the mechanics they describe — the same class of gap the v4.0 review caught for the recession-mode figure below, just missed by that pass. The interactive tool's recession hint stated a 2–4 year / 65–85% income-multiplier range; the actual beta(5,2) formula (unchanged since v3.3, and correctly described in this document's own Mathematical Framework §7) produces 1–3 years / 70–95% — this document's own Step 5 card had the same "2–4 years" error, now corrected below. The Max Octave slider's hint described conversion capacity as an exponential "C = C₀ × 2ⁿ"; the actual v4.0 mechanism is linear in octave/maxOct, reaching exactly the quality-multiplier ceiling at max octave (an exponential form would hit 512× at octave 9, far past that ceiling) — the hint now describes the real shape. A static default display value read "14.58×" against the correct "14.56×" (9×1.618); cosmetic; it self-corrects the instant the reference preset auto-loads, but was wrong in markup. A chart caption asserted baseline recessions are unconditionally "enabled," no longer accurate once v4.0 paired baseline's shock exposure to the user's own toggle. OAT sensitivity's PTF-share perturbation used a slightly wrong slider range. None of these affect any computed number anywhere in this document or the interactive tool — full detail in
index.html's own changelog (search "v4.1").
Large-N reconfirmation, and a genuine extension. Because none of the above touches
makeAgent(), runYear(), or calcMetrics(), the v4.0 large-N figures throughout this page should be numerically unchanged under v4.1 — verified, not assumed: an independent N=1,000-seed sweep of all three scenarios (Full Integration, CCO-Only, Traditional Welfare Baseline) landed within statistical noise of the v4.0 5,000-seed figures on every metric checked (BLEI poverty, EDC-adjusted Gini, median wealth; near-poverty cohort size, and its Threshold/Stable milestone timing, reconfirmed almost exactly). Rather than stop at reconfirmation, the near-poverty cohort tracking (Performance Comparison, below) was extended to a 40-year horizon (N=1,000, Full Integration) — the specific follow-up the v4.0 note above flagged as open. The cohort's median member still does not reach Flourishing by year 40 (0 of 1,000 runs), though its median BLEI keeps climbing throughout (≈135 days at year 15 → ≈428 days at year 40) rather than plateauing — full trajectory and discussion in Performance Comparison.
Common-random-numbers population pairing. The main run, "CCO Only," and baseline comparisons now share one canonically-drawn latent population instead of three independently-sampled ones — closing the counterfactual-isolation item from the external review this page's v4.0 note already discusses ("the baseline and CCO-only populations are not actually the same individuals"). The earlier objection that pairing "isn't well-defined once maxOct/maxMult differ in support between scenarios" holds against the scaled outcome (octave/quality) but not the underlying draw — the pre-policy shape variate is now shared, then scaled independently per scenario's own ceiling, which is what a genuine "same individuals, different policy" comparison needs. Implementing this surfaced an independently-found bug:
makeAgent()'s three eligibility draws used short-circuit &&, so the number of RNG calls consumed during agent construction depended on which subsystems were toggled on — two scenarios built from the "same" seed but different toggle states (e.g. the validation suite's PTF-on vs PTF-off check) silently diverged in every draw after the first toggle difference, not just membership. Now drawn unconditionally. This does not extend to full within-run trajectory pairing — runYear() still consumes a variable number of RNG calls per agent depending on which of its own conditional branches fire each year (participants trigger more draws than non-participants), so two scenarios with different participation composition still decorrelate agent-level trajectories after year 0, even from an identical starting population. Aggregate comparisons (poverty rate, median BLEI) remain valid; a fully-paired per-agent comparison would need every RNG-consuming branch in runYear() drawing unconditionally too — a materially larger change, tracked as an open item in CONTRIBUTING.md, not attempted here.
Structural System Stability metric. Replaces the v3.6-flagged trend-plus-noise heuristic (
stabBase = improving ? 0.88 : 0.60, plus a bounded random noise term) with the inverse coefficient of variation of median wealth and median BLEI over the run's final quarter — no RNG call, no manual per-mechanism bonus. A mechanism that genuinely stabilises outcomes now shows up endogenously as lower volatility, since every mechanism already feeds wealth and BLEI within runYear().
Validation suite: multi-seed robustness plus two new checks. The original four checks each ran once, on one hardcoded seed apiece — unable to distinguish a genuine structural property from a lucky draw. All four now run across five seeds and require unanimous agreement (all four are 5/5 robust). Two checks were added: non-participant poverty doesn't worsen when CCO is enabled (isolates CCO status alone, holding every other toggle fixed; needed a larger population and a mean-across-seeds criterion rather than per-seed agreement, because of the within-run RNG-coupling property described above — at the suite's usual 200-agent size this check only agreed 2–3 times in 10 seeds tried during development, which was noise rather than signal; at n=500 every seed and the mean favour non-participants doing slightly better under CCO, not worse), and a structural-invariants check (population conservation across BLEI tiers, octave/wealth-floor/participation bounds, Gini bounds) as a regression net for future changes. The suite is renamed "Internal Consistency & Behavioral Test Suite" and labeled against an ODD-style Level 1–5 validation hierarchy — this suite covers Levels 1–3 (code correctness, mathematical invariants, behavioral validation) only; Levels 4–5 (external empirical validation) remain open, per Known Limitations.
What did NOT get fixed, and why (carried forward from v4.0's note, above, still current): the main wealth loop's unit simplification; a genuine aggregate production/treasury constraint on BU conversion proceeds; a shared parameter-builder across
getCurrentParams()/OAT/validation (still an accepted, if imperfect, duplication). All tracked as open items in CONTRIBUTING.md.
Large-N reconfirmation (Aug 2026) — complete. v4.1 could verify its large-N figures were unchanged by inspection alone, because none of its fixes touched
makeAgent(), runYear(), or calcMetrics(). v4.2's population-pairing fix touches makeAgent() directly, so that shortcut wasn't available — a full N=5,000 study was run instead (same methodology as the v4.0/v4.1 studies: a Node.js harness driving the shipped engine functions directly — makeLatentPopulation(), instantiateAgent(), runYear(), calcMetrics(), bleiMetrics(), structuralStability() — seeds 1–5,000, 500 agents, 20 years, shock disabled to match the Full Integration reference preset; full figures in Performance Comparison, below). Headline result: figures across all three scenarios land within a few hundredths of a percentage point of the v4.0/v4.1 numbers they replace — Full Integration Threshold Rate 92.1% (was 92.1%), BLEI Poverty 7.9% (was 7.9%), EDC-adjusted Gini 0.4843 (was 0.484), Median Wealth $81,597 (was $81,629); Traditional Welfare Baseline reconfirmed just as tightly (Threshold Rate 47.8%, Gini 0.8003, both effectively unchanged). This confirms the fix changes which specific agents get compared, not the model's aggregate behavior — exactly what a counterfactual-isolation correction should do.
A genuine methodology finding along the way, for anyone reproducing this study. An initial CCO-Only run, using the CCO-Only preset's own 75% participation figure, diverged from the documented v4.0/v4.1 numbers by 1–2 percentage points across poverty, wealth, and Gini — consistently in the direction lower participation would produce. Baseline, run the same way, matched immediately (its parameters are fully hardcoded, independent of whatever scenario it's being compared against), which isolated the gap to participation rate rather than a deeper problem: the interactive tool's own internal "CCO Only" comparison (
pCCO in simulate()) inherits its participation rate from whichever scenario it's paired against — 78%, the Full Integration reference preset's value — not from the CCO-Only preset's own standalone 75%. Re-run at 78%, CCO-Only also reconfirms closely (Threshold Rate 90.3%, was 90.3%; EDC-adjusted Gini 0.5164, was 0.516). Documented here because it isn't obvious from the preset definitions alone, and would silently reproduce the same 1–2pp gap for the next person who runs this study starting from PRESETS.cco directly.
What changed as expected, by construction, not by drift. System Stability now reports the new structural metric — Full Integration 94.7%, CCO-Only 95.3%, Traditional Welfare Baseline 80.6% — not comparable to the old heuristic's numbers, which is exactly what a redefined metric should produce. The near-poverty cohort's median time to the Stable tier is now 158.8 months / 13.2 years (was ~165 months / 13.7 years) — a genuine, modest shift (95% CI ±0.4 months on N=5,000, so not sampling noise), consistent with a slightly different random population per seed under the new RNG threading. The cohort's Threshold crossing is better described as immediate (month 0, from initial liquid wealth alone, in 5,000/5,000 runs) than the previous "~12 months" — this is a measurement-granularity refinement, not a changed finding: this document's own prior wording ("essentially immediate — driven by initial liquid wealth, not simulated improvement") already said as much, the new methodology just adds a pre-dynamics data point to confirm it. Flourishing remains unreached by the cohort median within 20 years (0 of 5,000 runs, same as before).
What did NOT get fixed, and why (carried forward from v4.0's note, above, still current): the main wealth loop's unit simplification; a genuine aggregate production/treasury constraint on BU conversion proceeds; a shared parameter-builder across
getCurrentParams()/OAT/validation (still an accepted, if imperfect, duplication). All tracked as open items in CONTRIBUTING.md. One figure on this page was deliberately not re-run: the v4.1 40-year Flourishing-horizon extension (N=1,000) remains a v4.1-mechanics result — that specific reconfirmation is tracked as a separate open item rather than assumed. Full seed-42 single-run figures (distinct from this large-N study) are in CONTRIBUTING.md's Reproducibility Testing table.
WAGE_TO_USD (≈100.52, derived from $42,220 median personal income, Census/BLS CPS ASEC 2023) and LIVING_WAGE_ANNUAL ($49,370, a national living-wage figure from World Population Review's MIT-sourced state table), replace netting a wage figure against BASE_DAILY_COST — a bare-subsistence floor, correct for BLEI's poverty-line use but wrong for a 20-year compounding loop netted against real wage, which produced an ~11× wealth explosion and broke BU-monotonicity on 2 of 5 seeds when tested with the wrong anchor. All six validation checks pass under the shipped anchor.
This is not a clean win — it redistributes as well as it grows, along more than one axis. At N=5,000: Full Integration median wealth rose from $80,008 to $495,411 (≈6.2×), but EDC-adjusted Gini rose from 0.479 to 0.536 and wealth poverty rose from 14.4% to 19.5% — low-wage-draw, high-automation-risk, and non-participating agents don't share proportionally in the wage-side correction the way median-and-above-wage agents do. The Traditional Welfare Baseline collapsed far more severely: with no CCO/PTF/PTH cost relief, its full weight lands on the new, roughly-doubled cost anchor — median wealth fell from $7,316 to exactly the wealth floor, −$10,000, meaning more than half the baseline population was pinned at the debt ceiling by year 20 for the first time, wealth poverty rose from 52.2% to 72.3%, and Gini rose from 0.800 to 0.855. Meanwhile the near-poverty cohort (low starting wealth, not low wage — most members have ordinary wage draws) reversed completely: cohort-median time to Stable dropped from 158.8 to 48 months, and the cohort reached Flourishing in 5,000 of 5,000 runs within the 20-year horizon, versus 0 of 5,000 even after extending to 40 years under pre-v4.3 mechanics. Together these say something more precise than "wealth up, Gini up": the fix helps agents by wage level, not by starting wealth.
A new Social-Security-anchored cohort study, prompted by that finding, is the sharpest test of the framework's poverty-elimination claim run so far — and the framework does not pass it. Comparing Compassionism to the US baseline using median-income anchors doesn't show how the framework treats the population most relevant to a poverty-elimination claim: people on a fixed, sub-median income, not median-wage workers. Real 2026 SSA figures (SSI, SSDI-average, average retired-worker benefit) tag three cohorts by initial wage via
WAGE_TO_USD. Full Integration helps this population enormously in relative terms — 20–30× the baseline's BLEI, where these agents are functionally at zero — but median BLEI in the teens of days remains deep in the Precarious tier, nowhere near the 30-day Threshold, let alone the reference configuration's own 67.8% population-wide Flourishing rate. Full table in CONTRIBUTING.md; the underlying mechanism is direct — even with PTF/PTH cost reductions and BU support, an agent whose wage sits near or below Social-Security-benefit levels doesn't generate enough annual surplus for the model's other mechanisms to compound meaningfully within 20 years.
Three smaller fixes shipped alongside the headline change. The
runYear() RNG-coupling fix: every conditional quantity in the per-agent loop (BU spend fraction, CIP quality bump, octave advancement, SZH→PTF induction, PTH appreciation noise, PTF Bass adoption) is now drawn unconditionally every year for every agent, mirroring v4.2's population-construction fix — only the use of the drawn value is gated. This let the non-participant-poverty validation check tighten back to strict per-seed agreement at n=200 (was a mean-across-5-seeds workaround at n=500, adopted specifically because of this coupling gap — see v4.2's note above). A bimodal automationRisk distribution replaces the previous uniform[0.2,1.0] — a 47%/53% high-risk/low-risk mixture sourced to Frey & Osborne (2013) and Autor (2015). Per-agent PTH tenure tracking is added as a first step toward the variable liquidity haircut this page's Step 1 card already flags as unimplemented — tracking only this pass, the haircut formula itself remains flat 50%.
What did NOT get fixed, and why: the
WEALTH_FLOOR of −$10,000 was designed for occasional insolvency, not a scenario where it binds for the median of an entire population — whether it's still the right value now that the cost anchor it's measured against roughly doubled is flagged as an open question this release surfaces, not resolves; a genuine aggregate production/treasury constraint on BU conversion proceeds; whether a mechanism specifically targeting low-wage (not just low-wealth) populations is a gap the framework's design should address. All tracked in CONTRIBUTING.md's Model Architecture Feedback, which is where this page's own reconciliation notes above point for the pre-existing Gini and target-calibration questions too. This page's own sync to v4.3 was deliberately deferred pending an independent adversarial audit of the release — that audit, and v4.3's resulting figures, are folded into the v4.4 entry below, since no intermediate v4.3 snapshot of this page was ever published.
Wage/income scale unified across BLEI, FBS, and Gini. v4.0 had fixed unit-mixing inside these formulas using
SIU_TO_USD (≈16.63) — a cost-side-derived approximation, invented because no real wage-side anchor existed yet. v4.3's WAGE_TO_USD (≈100.52, Census/BLS-sourced) was scoped to the main wealth loop only, leaving the same agent's wage worth roughly $3,518/month for wealth accumulation and roughly $582/month for welfare measurement simultaneously — a ~6× divergence the audit correctly identified as no longer defensible once one of the two anchors is empirically grounded and the other isn't. SIU_TO_USD is retired; agentEDC() was and remains unaffected, since it's a dimensionless SIU/SIU ratio that never used either constant. This is not a repeat of v4.3's compounding-loop risk (these formulas recompute fresh each year), but it does feed back into wealth accumulation indirectly through the FBS advancement gate, which needed a compensating adjustment: FBS_LAMBDA, left unscaled after its dominant input (Yusd) grew ~6×, pushed advancement probability toward saturation regardless of BU level and measurably weakened the BU-monotonicity validation check. Correction (post-release review): this document previously described the FBS_LAMBDA rescale as a "dimensionally-necessary consequence" of λ's 1/USD units — that overstated the case. FBS mixes the wage-derived term that changed scale with fixed-dollar terms (BU face value, basic cost) that did not, so FBS itself does not scale by a single clean factor, and dividing λ by exactly 6.0456 is a chosen behavioral recalibration to restore useful dynamic range, not a unit identity. See the open calibration-status note under Mathematical Framework §4 for the full, corrected account, including why the original range saturates and why the rescaled range should not itself be read as empirically validated.
True common-random-numbers pairing, at last, across the full three-way comparison. v4.2 paired the Baseline/CCO-Only/Main populations but left their year-by-year trajectories on three independently-offset RNG streams — decorrelated from each other and from Main, not just from population construction, exactly as v4.2's own note above already flagged as a remaining gap. Since v4.3's
runYear() fix made every scenario draw the same count and order of random values regardless of policy toggles, three independent same-seed generators now necessarily produce identical draw sequences at each (agent, year) position — isolating the policy effect from Monte Carlo noise, which is what CRN pairing is for. Verified to have zero effect on Main's own single-scenario trajectory.
An unexplained baseline initial-wealth penalty, and an exogenous-conditions asymmetry, both removed. Baseline agents received an extra ×0.85 wealth adjustment at construction, on top of sharing v4.2's paired latent population — applied before CCO has had any chance to act, embedding part of the treatment effect into the counterfactual's own starting point. Removed; no externally-sourced justification existed for the specific figure. Separately, Baseline was hardcoded exempt from AI automation exposure even when a user enabled it for the tested scenario, while CCO-Only already correctly mirrored the setting — now paired. Neither fix meaningfully changes the standard reference-configuration figures on this page (automation defaults off; and Baseline's median wealth remains exactly floor-pinned regardless — now confirmed in 100% of N=5,000 runs rather than "more than half," since the binding constraint turned out to be the ongoing annual cost/wage gap under 20 years of compounding, not the year-0 starting point).
A genuine bug, found independently of either audit while building this release's large-N harness. The general-purpose gamma-distribution sampler divides by
(a−1) inside a log term; at a=1 exactly this is x/0, making the acceptance test 0×log(∞)=NaN and therefore always false — every call exhausted all 5,000 rejection iterations and silently returned the constant 1, not a random Exponential(1) draw (confirmed: 20 of 20 identical samples in testing). This directly narrows drawAutomationRisk()'s two component distributions, used once per agent on every simulation run, and wasted the full 5,000 dead iterations each time in the process. Fixed with the exact closed-form solution — Gamma(shape=1) is exactly Exponential(1) — which also produced a roughly 200× population-construction speedup as a side effect, without which this release's fresh N=5,000 study would not have been practical to run in the time available.
Full N=5,000 re-study, with a methodological correction worth naming. Figures throughout this page above reflect the fresh study (Full Integration median wealth $526,120, up modestly from v4.3's $495,411 — most of v4.3's much larger jump came from the wealth-loop fix itself, not this release's formula-unification work; BLEI poverty fell from 17.1% to 12.5%; participant poverty fell from 15.4% to 10.0% while non-participant poverty stayed exactly unchanged at 34.3%, a clean mechanistic confirmation that non-participants never execute the FBS-gated code path this release touches). The Social-Security-anchored cohorts (v4.3, above) improved measurably — SSDI-level median BLEI 16.4d→22.6d, retirement-level 16.6d→a median-of-medians 25.1d — but an initial mean-based reading of the retirement-level cohort would have overstated this as crossing the 30-day Threshold; BLEI is right-skewed for these small (≈4–86 agent) cohorts, and the mean (32.0d) sits above the line while the median-of-medians (25.1d) and the actual per-seed crossing rate (31.1% of seeds) both show the typical case still falls short. Caught before publication, corrected throughout this page and CONTRIBUTING.md — reported here because getting this distinction right mattered for what the framework can honestly claim, and because a large-N study is only as trustworthy as the statistics used to summarize it.
What did NOT get fixed, and why:
WEALTH_FLOOR, the pre-existing wealth/poverty/Gini design targets, and a genuine production/treasury constraint on BU conversion remain open — all explicitly flagged in CONTRIBUTING.md as framework-level decisions requiring the framework's own authors' judgment, not code fixes; this release adds a direct in-app disclosure on the affected KPI badges (see the interactive tool) without picking new numbers. The v4.1 40-year cohort extension remains unreconfirmed, now three mechanics-changing releases stale — given how far the 20-year figures have moved, a fresh 40-year run would very likely show materially different results, tracked as an open item rather than assumed. Full technical detail, including exact line-level rationale for every change, is in index.html's own changelog (search "v4.4") and CONTRIBUTING.md.
The PTH liquidity haircut finally gets its variable schedule. v4.3 added per-agent
pthTenure tracking as a first step; v4.5 implements the haircut itself — a linear ramp from 15% at tenure=1 (the closest available point to the BLEI paper Table 1a's "6 months" anchor, given tenure is tracked in whole years) to 85% at tenure≥5 (the paper's "5+ years" anchor), replacing the flat 50% share of annual Acre Equity appreciation counted as liquid wealth used through v4.4. Both anchors are the midpoint of the paper's cited range (10–20% / 80–90%) — the paper gives two qualitative points, not a closed-form curve, so the ramp between them is a documented interpretation choice, not a re-derivation (see Step 1 card and Mathematical Framework §2, above). Since PTH membership doesn't change once assigned, most PTH agents spend the majority of a 20-year run at the mature 85% rate — higher than the old flat 50% for 16 of 20 years, lower only in years 1–4. Isolated effect, N=300 seed-paired comparison (same population/RNG per seed, only this mechanism toggled): median wealth $523,958→$526,941 (+0.6%), median BLEI 1,820.6d→1,826.0d (+0.3%); Gini, wealth poverty, BLEI poverty, and flourishing rate unchanged to the precision reported. Seed-42 Full Integration reference: median BLEI 1,951d→1,965d, median wealth $558,001→$559,223. This is a scoped sanity check, not a fresh N=5,000 study — the KPI row and large-N table elsewhere on this page remain the v4.4 figures; see the v4.5 banner near the top of this page. All six validation checks pass post-change.
Three smaller good-first-issues, done alongside it. "Copy parameters as URL" serializes the current sliders/toggles/seed into a query string, copied via the Clipboard API; loading a shared link applies its params on top of the Full Integration defaults before the page's own auto-run, so the seed-42 "illustrative reference run" banner only fires when no recognized params are present. Social Security-anchored cohorts (real since v4.3, harness-only until now) are surfaced as a final-year table in the interactive tool's own results panel — SSI-level, SSDI-level, and Retirement-level rows, computed from the same final agent state and metric functions the headline KPIs already use, cross-sectional by design like the harness study itself. Hover tooltips now show BLEI tier day-ranges next to the tier-distribution chart and a one-sentence description of what each preset button actually configures — caught and fixed a real interaction bug along the way, where the preset "active" styling was silently overwriting the new tooltip's CSS class on every click.
What did NOT get fixed, and why: this was a good-first-issues pass by explicit scope, not an audit release.
WEALTH_FLOOR and TARGET_* recalibration, the Sobol/LHC sensitivity export, occupation-stratified automationRisk, the near-poverty cohort's stale 40-year extension, and the framework-level low-wage-mechanism question all remain open, unchanged from v4.4. Full technical detail in index.html's own changelog (search "v4.5") and CONTRIBUTING.md's v4.5 Release Notes.
Latin Hypercube sensitivity export implements the exact spec CONTRIBUTING.md had carried as "implementation-ready" since it was first written: a stratified LHS design over the same five parameters OAT already perturbs, reusing
mulberry32 for the design draw, exporting the design matrix plus outcome metrics (poverty, BLEI, participant/non-participant poverty) as CSV. Each of 100 design points runs its own 200-agent/10-year mini-simulation at a fixed seed (matching OAT's own convention of holding the stochastic realisation fixed so cross-row variation is attributable to parameters, not RNG noise). Deliberately not a Sobol sampler — genuine Sobol indices need paired Saltelli-structured samples beyond a single LHS design — but well-stratified coverage suited to external Sobol/Morris/regression analysis in Python or R, which is the actual gap the spec described. Verified directly against the shipped functions: all 5 dimensions confirmed properly stratified, and a sample run through the real engine produces poverty/BLEI outputs that track sensibly with the sampled parameters.
Feedback-clamped PTF adoption, opt-in and off by default, addresses the Model Architecture Feedback item flagging that "the PTF slider sets the t=0 adoption probability only... a quota-based or feedback-clamped adoption model remains open." Confirmed the problem directly before fixing it: an uncapped seed-42/20yr Full Integration run reaches 53.4% realised PTF share against an 18% slider, via two independent growth pathways (Bass-diffusion/distress adoption and a separate SZH→PTF induction check). A new toggle — off by default — makes the slider a real ceiling when enabled, checked live and incremented per-agent within the year rather than only once per year, catching a first implementation attempt that still overshot (a once-per-year check alone only cut the overshoot to 23.8%, not the ~18% intended). One honest caveat, caught in testing and documented rather than glossed over: the cap constrains organic growth beyond the year-0 random assignment, not sampling variance already present in that assignment itself — a seed whose initial Bernoulli draw happens to land above the slider (confirmed for seed 42: 95/500 agents = 19.0% at year 0, before any dynamics run) holds at that level rather than being forced down. Implemented as a use-side gate on RNG draws the engine already draws unconditionally every year (the v4.3 RNG-coupling discipline), so enabling the cap adds no new RNG call and every existing preset's regression baseline is unaffected.
FBS₅₀ half-saturation bandwidth — CONTRIBUTING.md's own λ Calibration Status note (Mathematical Framework §4, above) had already hand-computed this figure in prose (≈$524–$4,191/month) as the recommended reparameterization target; it's now a named, derived constant (
CFG.FBS_HALF_SAT_LO/HI = ln(2)/λ) displayed directly in the interactive tool, so it can't drift out of sync if the λ range is revised again. Reporting change only — per-agent λ sampling, RNG draws, and every simulation output are unaffected; a genuine reparameterization (sampling FBS₅₀ as uniform and deriving λ from it) would change the shape of the λ distribution and remains a distinct, larger open item.
The near-poverty cohort's 40-year extension, unreconfirmed since v4.1 (flagged in every release since as progressively more stale), was rebuilt under current mechanics: N=1,000 seeds (a fresh draw, matching v4.1's own methodology), Full Integration, 500 agents, 40-year horizon. The milestone question v4.1 originally asked is now moot — v4.3's wealth-loop fix already answers it inside the existing 20-year table (median 13.0 years to Flourishing), and this rebuild reconfirms that almost exactly at N=1,000 (median 13 years, mean 13.4 years; Stable and Secure milestones both within a percentage point of the 20-year figures). What the 40-year window actually adds is a different and more consequential finding: no plateau. Cohort median BLEI keeps compounding at an accelerating pace past year 20 — 1,618 days at year 20 to 7,058 days by year 40, more than quadrupling — and population-wide median wealth reaches roughly $2.1 million by year 40 with no sign of a ceiling. See Performance Comparison, below, for the full table and Known Limitations for the open question this surfaces about long-horizon wealth growth.
What did NOT get fixed, and why: another good-first-issues pass by explicit scope. Occupation-stratified automationRisk,
WEALTH_FLOOR/TARGET_* recalibration, the framework-level low-wage-mechanism question, and a genuine production/treasury constraint remain open, unchanged from v4.5. Two items got real research rather than being left untouched, though: occupation-stratified risk is now scoped to a specific source (Frey & Osborne's own appendix publishes per-occupation probabilities for all 702 SOC codes — what's missing is transcription and a BLS employment-share crosswalk, not new data), and a search for a published population-weighted LIVING_WAGE_ANNUAL figure came up empty (MIT's calculator has no single national aggregate to retrieve) — a negative but informative result, documented rather than left as an unexamined todo. Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.6 Release Notes.
index.html and CONTRIBUTING.md, then a second pass explicitly focused on "the economic mathematics and causal structure of runYear()," undertaken because the reviewer judged the first pass had exhausted what code-level and documentation-level review could find and that the harder remaining questions were economic rather than editorial. That second pass earned the distinction: it found two genuine defects that seven prior audits — several of them detailed, adversarial, and methodologically careful — and this project's own six-check internal validation suite had all missed.
Bug 1: the BU-expiry slider implemented two behaviours, not six. The UI presents "BU expiry (months)" as a 1–6 slider. The code consuming it,
var decay=p.expiry<2?0:0.7, is only sensitive to whether expiry clears a threshold of 2 — every value from 2 through 6 evaluates identically. Verified directly before any fix was written: expiry=3 and expiry=6 produced bit-identical simulation output on the unedited engine, to the dollar and the decimal point. Replaced with a continuous annual-approximation decay=1-1/expiry — a documented interpretation in the same spirit as pthLiquidShare()'s existing linear interpolation for a comparably under-specified continuous quantity, not the full monthly-BU-tranche rebuild a "proper" fix would need (logged as its own future-work item, so the shipped fix's honest scope is on record). Verified inert on everything documented: all five shipped presets, every internal mini-simulation, and every OAT/LHS sweep use expiry=1 and never vary it — confirmed by grep before writing a line of code — and at expiry=1 the new formula gives decay=0, bit-identical to the old behaviour. Only a user who manually drags this one slider is affected; six positions now produce six genuinely distinct, monotonically-ordered results instead of two.
Bug 2: PTF's inflation-damping effect tracked the initial slider, not actual adoption.
if(p.ptf&&inflRate>0)inflRate*=(1-p.ptfShare*0.5) used p.ptfShare — the static, initial-adoption-probability slider — for a population-level macro effect, while the exact same function already computes the actual current adoption fraction (ptfAdoptFrac) a few lines later, for the Bass-diffusion adoption term. That correct quantity simply was never reused for the inflation effect, even though the per-agent cost factor a few lines further down already correctly gates on each agent's real, current PTF membership flag rather than the slider — a state-variable/effect mismatch, not a design choice. Fixed by moving the computation earlier and reusing it (no RNG draw, so no stream position shifts anywhere). Verified inert on every documented figure — Full Integration, CCO-Only, Baseline, and hiAI each have inflRate=0 or ptf=false at this exact line, so none of them are touched, confirmed by the unchanged seed-42 regression below. Of the five shipped presets, only Stress Test combines both conditions; of the six internal validation checks, only ptf_infl exercises this line — re-run after the fix and confirmed still passing 5/5. Effect size where it applies (Stress Test, seed 42, 20yr): poverty 43.0%→41.8%, Gini 0.703→0.696, median wealth $141,814→$158,155 — actual PTF adoption running above the static slider means the fix applies stronger damping than the bug did, the economically expected direction.
Both fixes ported into
harness.js for parity, and both cannot move a single documented figure on this page — the seed-42/Full Integration/20yr regression (Median BLEI 1,965d, Median wealth $559,223, Gini 0.534, Wealth poverty 16.6%) is bit-identical, confirmed by re-running harness.js, by driving the fixed engine through domtest.js end-to-end in a real DOM, and by isolated before/after checks on every one of the handful of configurations either fix actually touches. domtest.js gained six new checks this release, two of them direct regression guards: if either bug is ever reintroduced, the harness fails immediately rather than waiting for another audit to rediscover it.
One new reporting feature: the Wealth Floor Diagnostic. The audit's general-review pass asked for an in-app diagnostic showing how much of a headline Baseline-vs-Your-Settings gap reflects
WEALTH_FLOOR's exact value rather than a genuine policy effect — a fair question this project had previously answered only offline, in CONTRIBUTING.md's own four-floor-value sensitivity sweep (v4.8). Two new KPIs show the share of the final-year population pinned exactly at the floor, for Your Settings and Baseline — a same-run companion to, not a replacement for, that offline sweep (seeing today's pinning doesn't show how sensitive it is to the floor's own value). Pure snapshot of already-final agent state; exported to CSV and JSON.
Documentation clarifications, no mechanics changes: EDC-adjusted Gini is now explicitly labeled — in its KPI tooltip, in the engine's own code comment, and in Mathematical Framework §5 below — as a constructed inequality index (a wealth stock minus one year of EDC-implied extraction, a flow), not conventional net-worth accounting; the formula itself is unchanged and still matches BLEI paper Table 6 exactly. A dual-cost-anchor table (
LIVING_WAGE_ANNUAL vs. BASE_DAILY_COST) was added to the Empirical Calibration card. The ODD panel's Design Concepts card, and an inline comment at the octave-advancement site inside runYear() itself, now name the reinforcing feedback loops the audit's causal-structure review correctly identified explicitly: BLEI(prior year)→wage growth→wage→FBS→octave→{next year's wage growth, next year's conversion-rate ceiling}, and separately PTH→lower cost→higher FBS→octave→wage. Neither loop is a bug — both are the intended design — but a headline "CCO effect" or "PTH effect" is a compound of several coupled mechanisms, not one isolated channel, and nothing previously said so explicitly. A new Known Limitations entry states plainly that "recession" only ever shocks earned wage income and "AI automation" is a reduced-form wage-growth penalty, both narrower than their names might suggest. The standing "not a forecast" banner gained one sentence, close to the audit's own suggested wording, making explicit that results demonstrate the implications of the implemented assumptions rather than establishing the empirical validity of those assumptions.
What the audit got right that this project had already substantially addressed, checked rather than assumed: the audit's call to "formally divide validation into Levels 1–5" is, verbatim, already the validation panel's own subtitle since v4.2. Its FBS λ concerns and its recommended FBS₅₀ = ln(2)/λ reparameterization were already shipped at v4.4/v4.6. Its stock-flow accounting concern has been an explicit Known Limitation since v4.0 — the audit's more detailed proposed ledger schema is logged as an elaboration of that same item, not treated as new. Its suggestion to split
index.html into modules is the identical suggestion an external ChatGPT audit made at v4.7, already rejected then as conflicting with this project's explicit single-file distribution constraint — same conclusion here. Its call for real-browser (Playwright) testing beyond domtest.js was already an explicitly flagged open decision in v4.13's own Model Architecture Feedback. Its suggestion to rename the "System Stability" KPI (a real, already-documented concern since v4.4) was considered and declined, for consistency with the audit's own stated preference elsewhere in the same document to define "wealth" precisely rather than rename it — renaming a KPI referenced throughout years of exported CSV/JSON columns and documentation is disruptive for a label already comprehensively caveated at the point of display; logged as an option for Duke's own judgment, not decided unilaterally.
What did NOT get done, and why: several of the audit's recommendations are legitimate but substantially larger than an audit-response release should take on unilaterally — a full flow-of-funds ledger with explicit conservation identities, monthly BU tranches (the fuller version of the expiry fix actually shipped), CCO/PTH pathway decomposition via structured ablation, λ heterogeneity beyond a fixed-and-independent draw, AI automation as a genuine employment-transition model, a fuller macro-recession model touching assets/employment/transfers, an expanded invariant/mechanism/calibration test taxonomy, and an explicit enumeration of
runYear()'s full annual state-transition schedule (deliberately deferred rather than risk transcribing an inaccurate sequence alongside everything else in this release). Each is precisely scoped in CONTRIBUTING.md's Model Architecture Feedback and Good First Issues for whoever picks it up next. Full technical detail, including the isolated before/after verification tables for both mechanics fixes, is in index.html's own changelog and CONTRIBUTING.md's v4.14 Release Notes.
node --check, JSON-LD parse, harness regression) is structurally incapable of catching, because none of those checks ever runs the page.
Defect 1: a shared "Copy parameters as URL" link silently disabled every preset tooltip.
applyParamsFromURL() cleared the preset buttons' "active" highlight by resetting each button's class to a bare pbtn — which also removed .tip-host, the class the v4.5 preset-description tooltips hang off. Every visitor arriving through a shared link therefore lost all five preset hover descriptions for the entire session, silently. This is the same bug v4.5's own notes record catching in applyPreset() ("would have silently stripped the new tooltip class") — the identical pattern was written into applyParamsFromURL() in that same release and survived seven subsequent audits, for a specific and instructive reason: the shared-link entry point is the one path a reviewer reading index.html top to bottom never mentally executes, and the one path no automated check had ever taken.
Defect 2: the parameter-sensitivity panel duplicated its tip box on every run.
renderSens() wrote its "💡 One-at-a-Time (OAT) Sensitivity" note using insertAdjacentHTML('afterend', …), which inserts a sibling of the container the function then clears with innerHTML — so the clear never touched it, and renderSens() runs once per completed simulation. Three runs in one page session left three stacked copies. Confirmed in the DOM harness (3 boxes after 3 renders before the fix, 1 after), now a single stable-id node updated in place.
A metric that reported a perfect score where it had no data.
structuralStability() measures the inverse coefficient of variation of median wealth and median BLEI over the run's final quarter, with the window floored at one data point. The Simulation-years slider's minimum is 5, and for any run of 5, 6 or 7 years that quarter rounds to a single value — a variance of one observation is undefined, the coefficient-of-variation helper correctly returns 0, and the metric returned exactly 0.99, its own clamp ceiling, for every short run this tool has ever executed, whatever actually happened in it. Verified rather than reasoned: a strictly-increasing five-point series scored 0.990000, as did every other short series tried. The window floor is now 2. A sweep across every supported run length confirms 8–30 years are bit-identical to v4.12 — so every preset, the 20-year reference configuration, and the seed-42 regression baseline are untouched; only 5–7 year runs change, and only in this one displayed number. A matching Known Limitations entry now says plainly that System Stability needs ~8+ simulated years to mean anything.
Stale documentation inside the engine, where v4.12 had fixed it only around the engine. v4.12 corrected the interactive tool's ODD Protocol panel, its Empirical Calibration panel, and its top-of-file unit-system comment for describing pre-v4.3/pre-v4.4 mechanics as current. The same staleness was sitting inside
runYear() the whole time — the function all three of those panels describe, and the copy a contributor editing the engine actually reads. Four specific claims, each contradicted by the code beside it: that SIM_COST_SCALE "remains load-bearing" through the SIU_TO_USD derivation "that BLEI/FBS/Gini still use" (SIU_TO_USD was retired in v4.4; grep confirms SIM_COST_SCALE now has zero read sites anywhere in the file); that dollarCost is consumed "only by the FBS advancement gate" (it has two consumers — the FBS gate and the PTH equity block); that Yusd uses SIU_TO_USD (the line directly beneath reads WAGE_TO_USD); and that "FBS doesn't feed back into wealth" (it does, through octave advancement into conversion capacity and wage growth — precisely the feedback path v4.4's own notes give as the reason FBS_LAMBDA needed a compensating rescale). All corrected in place with short notes recording what was wrong, per this project's established practice of documenting a correction rather than silently swapping text.
Two reporting additions, both pure transforms of figures the engine already produces. Cumulative Poverty Exposure reports the mean number of years an agent spends below the wealth-poverty line, and below the BLEI poverty line, across the whole run — for Your Settings against the Traditional Welfare Baseline. This answers the "final-year snapshot only" gap the v4.12 external audit raised directly (its person-years-in-poverty suggestion), and the derivation is exact rather than approximate: each year's figure is a share of the same population, so summing the shares gives the average years-poor per agent. The result reframes a familiar number — at the seed-42 reference configuration the final-year wealth-poverty rate is 16.6%, but the average agent spends 4.8 of 20 years below that line (Baseline: 11.8), and 3.7 years below the BLEI poverty line (Baseline: 11.1). Its one honest limit is now a Known Limitation: this is aggregate exposure, not a spell-length distribution, and cannot distinguish "everyone poor for three years" from "30% of agents poor for ten." Second addition: the v4.12 dominance check was screen-only — visible but not archivable or citable with the run that produced it. It is now captured into the run snapshot and written to both export formats along with the view it was computed in and the number of threshold grid points evaluated, and the on-page caption states plainly that dominance is checked at the plotted thresholds only and describes one stochastic run rather than a confidence claim.
Smaller fixes. The Wealth Poverty KPI prefixed a hardcoded "▼" to a signed delta, so a configuration doing worse than baseline rendered as "▼ -3.2pp"; the arrow now follows the sign. Two grids built inside JS template strings still used a bare
1fr track — the exact CSS Grid overflow pattern v4.8 swept out of the stylesheet, missed because that sweep grepped CSS and these are inline strings; the Monte Carlo summary also never reflowed on a phone and now does. Toggle buttons expose aria-pressed, closing for the sidebar controls the same gap v3.7 closed for the charts. Exported JSON asserted a flat "CC BY 4.0" license, unchanged since before the v4.8 relicensing split, and the CSV's mechanics list was still headed "--- v4.0 FIXES ---" nine releases later; both corrected. CFG.POVERTY_LINE now carries a note at the constant itself recording that it has no citation anywhere in the codebase — an open item in CONTRIBUTING.md since v4.10, with nothing at the code to warn a reader who never opens that file. On this page: the header subtitle still read v4.9 and the Version History toggle label still read "v3.1 → v4.9," both four releases stale — and that second label is the very one v4.9's own entry below records fixing when it had drifted to "v3.1 → v4.7." It has now gone stale, and been caught, twice. In CONTRIBUTING.md, two release sections — v4.11's and v4.5's — had lost their ## …Release Notes headings entirely, so each rendered as a continuation of the section above it; the second was found only because the first prompted listing every heading in the file rather than assuming a single casualty. Both restored.
What did NOT get done, and why: the DOM harness verifies behaviour, not appearance — it cannot confirm CSS layout, tooltip positioning, or Chart.js pixel output, so those still want a human look after deployment, and the five structural proposals logged in v4.12 (executable test hierarchy, positional-argument refactor, calibrated current-policy scenario, rollout/transition model, per-agent longitudinal metrics) all remain open and unstarted. The per-agent longitudinal layer is now the most clearly motivated of the five, since the new exposure metric runs directly into its absence. Full technical detail in
index.html's own changelog and CONTRIBUTING.md's v4.13 Release Notes.
One real documentation bug, found and fixed by direct computation. The interactive tool's own in-app "Cumulative Bug Fixes" note on the v4.6 PTF adoption cap stated that seed 42 / Full Integration / 18% slider converges to 23.8% under the shipped agent-granularity cap — inconsistent with this document's own v4.6 Release Notes, which have always said 19.0%, and the audit flagged the inconsistency without being able to say which side was right. A Node.js harness built this session (reproducing the documented seed-42 regression figures exactly before being trusted for anything else, the same discipline every prior harness in this project has followed) settled it: 19.0% is correct. Tracing
ptfLiveCount/ptfCapAllows() and reproducing it computationally shows why: seed 42's year-0 Bernoulli draw already lands at 19.0% (95/500 agents), above the 18% cap, so the cap blocks every subsequent admission for the entire 20-year run and the final share holds at the year-0 level rather than growing. 23.8% was the output of an earlier, discarded once-per-year-checked prototype — never the shipped implementation — and appears to have been carried into the interactive tool's own documentation at v4.6 by mistake, uncaught until this session. A 10-seed sweep (seeds 1–10) confirms the general mechanism works exactly as designed: seeds whose year-0 draw starts below 18% grow and land at exactly 18.0% (500×0.18=90 is a whole number for this specific slider/population combination, so there's no fractional-agent overshoot to speak of here); seeds already at or above 18% at year 0 simply hold there, as seed 42 does. index.html's own panel is corrected; this document's figure was already right and needed no change.
Stale technical documentation, found in three places, all describing superseded mechanics as if current. The interactive tool's ODD Protocol panel had a "State Variables" card still stating
automationRisk ∈ [0.2,1.0] — the retired pre-v4.3 uniform draw's exact bounds — directly contradicting a correctly-updated card two rows below it in the very same panel, which has said "47%/53% bimodal mixture" since v4.3. The same panel's "Submodels" card still described the annual wealth update as SIM_COST_SCALE-driven and BLEI's wage term as SIU_TO_USD-converted, both accurate only through v4.2 — superseded by v4.3's wealth-loop unit fix and v4.4's SIU_TO_USD retirement, respectively, neither ever updated in this specific card even though the dedicated Cumulative Bug Fixes entries for both releases were kept current. The Empirical Calibration panel's "Daily vs. simulation cost scales" card was framed entirely around "what v4.0 fixed and what it deliberately didn't" and still asserted the main wealth loop was "deliberately NOT changed" — v4.3 changed exactly that, over a year of shipped releases ago by this project's own internal chronology. All three are rewritten in index.html to describe the current, v4.4-onward state while preserving the original v4.0 reasoning (still the correct explanation for why v4.0 shipped a partial fix rather than none) — the top-of-file UNIT SYSTEM code comment had the identical problem and got the same treatment. None of this affected any computed output; these are description-only fixes to panels whose job is describing the model, not running it.
New feature: a dominance check on the Threshold Sensitivity charts, directly implementing the audit's strongest concrete suggestion. The audit recommended the charts "test for first-order stochastic dominance over the displayed range... a clear statement when curves cross... do not imply a universal welfare ordering when curves cross." A new
checkDominance() function, exercised via both chart callouts, states plainly whether Your Settings sits at-or-below Baseline (and separately CCO-Only) at every threshold shown, at-or-above everywhere, or crosses — and if it crosses, roughly where. This is an honest check in both directions, not a feature built to only ever confirm the expected answer: at the seed-42 Full Integration reference configuration it reports dominance (Your Settings beats both comparisons everywhere, on both charts, in both the headcount and gap views) — a genuine, computed finding rather than an assumption wired into the feature, confirmed via the same regression-validated harness used for the PTF-cap fix above. A Stress Test preset re-run (lower participation, higher tax, lower BU) also showed dominance rather than a crossing in this project's own mechanics, so readers should read a "dominates" result as a real finding about this model's structure, not evidence the check only ever says yes — the crossing-detection path was separately confirmed to fire correctly against constructed adversarial curve pairs during unit testing (9 cases: both dominance directions, identical curves, a single crossing with its location correctly identified, weak dominance with tied values, and floating-point-noise edge cases correctly not flagged as spurious crossings), and against real simulated output via a full end-to-end Node.js integration test that evaluated the actual edited index.html script — not a hand-copied approximation — reproducing the documented seed-42 regression figures exactly (median wealth $559,223, median BLEI 1,965d, Gini 0.534, wealth poverty 16.6%) before the dominance check was ever run against them, then driving the real renderThresholdSensitivity()/drawThresholdCharts() render path in both headcount and gap views to confirm the callout text builds correctly and without error. Purely a reporting transform — computes no new agent state, draws no RNG, cannot affect the Main run, Baseline, or CCO-Only trajectories.
Smaller fixes. The poverty-gap toggle's own hover tooltip called the v4.11 metric "the poverty gap ratio" — but what it shows is the absolute dollar/day shortfall, not the textbook normalized ratio, which is the entire reason v4.11 reports it that way (see that release's own entry, above); corrected to avoid the word "ratio." The sidebar's "Run Validation Suite" button kept the pre-v4.2 name three releases after the panel and heading it opens were renamed "Internal Consistency & Behavioral Test Suite" specifically to avoid overstating what six internal checks establish; button text now matches. The Traditional Welfare Baseline preset's tooltip called it "the real-world reference point," language that could read as a claim the scenario models actual U.S. transfer programs (SNAP, EITC, TANF, Medicaid, unemployment insurance) rather than the absence of any offsetting mechanism at all; softened, with a matching new Known Limitations entry in
index.html.
What the audit got right that this project had already extensively documented, and was not treated as a new finding. The Comfortable/Flourishing tier-label split at the identical 730-day threshold — flagged by the audit as risking an inflated cross-scenario comparison — has its own dedicated "v3.4 naming note" on this very page (further up, under BLEI Temporal Stability Tier System) and appears explicitly in the System comparison table's own caption; it is a deliberate, extensively pre-documented framework narrative choice (the top tier is called "Flourishing" specifically when CCO+PTF's generative mechanics make it structurally attainable, "Comfortable" when it's merely aspirational), not a previously-hidden defect, and was not changed unilaterally — this is Duke's framework-design call, not a code-audit finding. The audit's BU-conversion "reciprocal debit" concern doesn't hold against the actual
runYear() code either: spend is subtracted from a.buBalance in the same statement block that computes convGain from that identical spend amount — the two state variables (unspent balance, wealth) are not double-counting the same entitlement, contrary to the audit's speculation. Several other findings — the internal-validation-suite framing, the LHS export's fixed-seed design, the CCO conversion "ledger" suggestion — restate design choices or limitations already documented at length (the suite's Level 1-3 ODD framing since v4.2, the LHS seed convention explicitly matching OAT's own since v4.6, the "tracked but not production-constrained" conversion-ledger caveat in Known Limitations since v4.0) and were not treated as new.
What did NOT get fixed, and why: the audit's larger structural proposals — a full CI-style test hierarchy, replacing positional function arguments with context objects across the engine, a full per-agent stock-flow ledger, a fourth "calibrated current-policy" comparison scenario, a rollout/transition-path model, person-years-in-poverty and time-to-tier-attainment metrics — are each reasonable, and each is a substantial engineering or framework-design undertaking in its own right, not a documentation fix; logged in CONTRIBUTING.md's Good First Issues and Model Architecture Feedback for Duke's consideration, not attempted here. Full technical detail in
index.html's own changelog and CONTRIBUTING.md's v4.12 Release Notes.
What shipped. A new "Avg. shortfall" toggle switches both existing charts (wealth and BLEI) to a poverty-GAP view — FGT-1 in the same literature (Foster, J., Greer, J., & Thorbecke, E. (1984). "A Class of Decomposable Poverty Measures." Econometrica, 52(3), 761-766) — the mean per-capita shortfall below each threshold, averaged across the whole population (agents at or above the line count as zero). One deliberate departure from the textbook definition: FGT-1 is normally a threshold-normalized ratio, but normalizing by the threshold breaks down at threshold≤0 — and the wealth chart's own range deliberately extends to −$20,000 specifically so Baseline's
WEALTH_FLOOR-pinned distribution renders as a real step (a v4.10 design choice, unaffected here). Reporting the absolute per-capita shortfall, in the same dollars/days as the chart's own axis, sidesteps that division problem while reading naturally as a direct "cost to close the gap" figure.
Validated the same way v4.10's own function was, plus one further cross-check. The core function (
povertyGapAvg(), built on a one-time prefix-sum pass per distribution to keep the same O(log n)-per-query budget as povertyCDF()) was checked against a naive brute-force reference across 22,210 random trials — including arrays specifically constructed to mimic WEALTH_FLOOR pinning, since that's Baseline's actual shape — before this touched the shipped file; zero mismatches beyond floating-point rounding. A full end-to-end Node.js integration test then drove the actual edited script against the documented seed-42/Full Integration/20yr configuration for both Full Integration and Traditional Welfare Baseline, confirming the existing headcount figures were undisturbed (exact match, 16.6%/13.6%) and cross-checking the new function against an independent numerical integral of the already-validated headcount curve — a genuine mathematical identity (mean absolute gap at a threshold equals the integral of the CDF up to that point), not a restatement of the production code. One apparent disagreement, immediately adjacent to WEALTH_FLOOR where 68.6% of a sampled Baseline population sits at exactly one value, was tracked to the cross-check's own coarse numerical resolution near that sharp discontinuity — confirmed by an independent direct per-agent sum matching the production function's output exactly, and by showing the cross-check's own error shrink from 0.171 to 0.017 to 0.0016 as its resolution was refined 100-fold. The production function was correct throughout; only the auxiliary check needed a finer grid to agree with it.
The same review's data-gathering follow-up, checked with the same rigor. Two long-open items from this project's Good First Issues were separately handed to the same external system. Its 51-state, Census Vintage-2025-weighted recomputation of
LIVING_WAGE_ANNUAL ($24.62/hr population-weighted, versus $23.7355/hr unweighted — both computed from current MIT data, the unweighted figure landing almost exactly on the currently-shipped value) had five of its 51 state-level inputs independently spot-checked against live MIT fetches this session and matched exactly, plus a partial reconstruction (the four largest-population states) confirming the population-weighted figure's direction and rough magnitude — but the full 51-state weighted arithmetic itself was not independently re-derived to the dollar, so the figure is documented as well-sourced reference data, not adopted into the engine, consistent with this constant's standing rule that any change needs its own dedicated mechanics-audit release. Its claim that the occupation-risk Kaggle dataset's license is actually unspecified — directly contradicting a v4.8 session's "third-party card says MIT" finding — could be neither confirmed nor refuted (Kaggle remains unreachable to automated fetching), which on its own means the earlier "MIT" finding should now be read as disputed rather than corroborated. The search for an answer surfaced something more useful than the answer itself: a 702-row occupation-automation dataset (exactly matching Frey & Osborne's own count) in the plotly/datasets GitHub repository, under a genuine first-party MIT license — a meaningfully cleaner starting point than the Kaggle listing, with one honest caveat of its own (an open issue in that repository questioning whether its MIT grant cleanly covers third-party-sourced data files).
What did NOT get fixed, and why: adopting the population-weighted
LIVING_WAGE_ANNUAL figure into the engine (deliberately — see above); a row-by-row fidelity check of the new plotly/datasets lead against the Frey & Osborne appendix; a normalized (ratio) variant of the poverty-gap view alongside the absolute one shipped here; every other long-standing open item this session didn't touch — unchanged from v4.10. Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.11 Release Notes.
LIVING_WAGE_ANNUAL to $49,370, and v4.9's Meta AI audit tried to overturn it with a different single figure that turned out to rest on stale data. Rather than resolve that pattern by defending one more number, two new charts (interactive tool) show the full range instead of a point estimate: the population's cumulative distribution of final-year wealth and BLEI across every plausible threshold at once — the standard "poverty dominance" approach from the poverty-measurement literature (Atkinson, A.B. (1987). On the measurement of poverty. Econometrica, 55(4), 749-764; also the World Bank's practice of reporting global poverty at several lines simultaneously, e.g. $2.15/$3.65/$6.85 per day). Baseline, CCO-Only, and Your Settings are overlaid on the same axes: if one scenario's curve sits below another's across the whole range shown, it reduces poverty regardless of exactly where a reader believes the "true" line sits.
What is, and isn't, explorable this way, and why. Confirmed by grep before writing any code:
CFG.POVERTY_LINE has exactly one call site in the entire engine (inside calcMetrics()'s poverty computation) — a pure post-hoc classification threshold on already-computed wealth, never touching RNG or dynamics, so exploring it across a range costs nothing extra. CFG.LIVING_WAGE_ANNUAL, by contrast, is genuinely baked into runYear()'s annual wealth update — a flow/cost anchor that mechanically shapes the wealth trajectory itself. Making that explorable the same way would mean re-running the simulation once per candidate value, not re-reading an already-computed array — a materially larger, mechanics-adjacent feature, deliberately out of scope here and flagged as the clear next step (CONTRIBUTING.md's Good First Issues). One further nuance worth naming: the BLEI tier cutoffs look similar to POVERTY_LINE on the surface but aren't in the same free category — BLEI_PRECARIOUS_MAX (30 days) is read twice inside runYear() itself, gating both a wage-growth bonus and a PTF-adoption bonus, so it's genuinely mechanics-relevant. The new BLEI chart doesn't touch this: it reads the already-computed continuous BLEI score at many threshold points for display, which is exactly as safe as POVERTY_LINE exploration — it's the CFG constants themselves that would be unsafe to slide, not the act of evaluating an already-computed value at a different point.
One external reference point, verified the way this project now verifies everything external. A new
CFG.FED_POVERTY_LINE_1P constant ($15,960/yr, the 2026 HHS ASPE guideline for a one-person household) appears as labeled callout text beneath the wealth chart — explicitly marked "external reference, not a simulation parameter," same category as CFG.NORDIC_GINI elsewhere in this file. A first fetch attempt against the live ASPE page returned a stale cached snapshot from 2017 (the 1-person figure it showed, $15,060, was immediately recognizable as years out of date) — caught rather than used, and cross-checked instead against an independently-dated primary-source PDF (a Lifeline Safe Connections Act eligibility table, explicitly dated January 15, 2026, HHS-sourced) plus three further independent citations, all converging on $15,960. A much easier verification than the LIVING_WAGE_ANNUAL episodes — a single government-published number, no methodology dispute attached — but the same "don't trust the first thing that loads" discipline applied anyway.
Validation. The core
povertyCDF() function (binary search over an already-sorted array) was unit-tested against a naive linear-scan reference across 12,500 random trials before touching the actual file — zero mismatches, including the realistic duplicate-heavy case of many agents pinned exactly at WEALTH_FLOOR. After integration, a full end-to-end Node.js test evaluated the actual edited script in a stubbed DOM-free sandbox, drove the real makeLatentPopulation()/instantiateAgent()/runYear() functions against the documented seed-42/Full Integration/20yr configuration, and cross-checked the new function's output against calcMetrics()'s and bleiMetrics()'s own existing figures at the model's default thresholds — exact match on both (16.6% wealth poverty, 13.6% BLEI poverty). Chart.js rendering/DOM behavior itself is not verified in an actual browser, the same sandbox limitation as every CSS/UI change since v4.8.
What did NOT get fixed, and why: making
LIVING_WAGE_ANNUAL (or BASE_DAILY_COST) explorable the same way — deliberately, mechanics-adjacent work belongs in its own audited release; additional named external benchmarks beyond the one federal guideline added here; an interactive slider/marker layered on the static curves (Chart.js's own hover tooltips already approximate this for free); every long-standing open item this session didn't touch (WEALTH_INIT_MU/SCF gap, WEALTH_FLOOR/TARGET_* recalibration, occupation-stratified automationRisk, unbounded long-horizon wealth growth) — unchanged from v4.9. One small, unrelated finding caught in passing while adding this entry: POVERTY_LINE itself has never carried a citation anywhere in this codebase, unlike almost every other calibration constant — now flagged as its own open item in CONTRIBUTING.md's Calibration Validation table rather than left unnoticed. Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.10 Release Notes.
Table-overflow fix, traced to a specific missing rule. The System comparison table already scrolls horizontally when it needs more room than it has — it sits inside a container with its own
overflow-x:auto. The Social Security-Anchored Cohorts table (added v4.5) is a plain table dropped into a card with no such rule, so when its six nowrap column headers needed more width than a typical 100%-zoom viewport had left after the sidebar, the overflow ran into a page-level overflow-x:hidden rule (added defensively so no single wide element could blow out the page) and got clipped rather than scrolled. At 80% zoom there's simply more CSS-pixel width available, so the same table never hit that ceiling. Fixed with the same technique the System comparison table already uses, scoped to just this element via a small reusable class. Not verified in an actual browser (same sandbox limitation as v4.8's own CSS fixes) — a visual check at a few zoom levels would be worth doing after this deploys. Separately, Duke confirmed the v4.8 tooltip fix is working correctly in production.
The Meta AI audit: one contribution verified correct, one verified wrong. Meta supplied two things beyond the audit text itself: a modular (ES-module) rewrite of the v4.8 Node.js harness, and a proposed recalibration of
LIVING_WAGE_ANNUAL. Neither was taken on Meta's word — both were actually run. The modular harness rewrite reproduces the documented seed-42/Full Integration/20yr regression figures exactly and reproduces the direction and approximate magnitude of the v4.8 WEALTH_FLOOR sweep — a genuine, working contribution, though not adopted as the project's harness in this pass (that's a layout decision for the authors, not something a verification pass should decide unilaterally). The living-wage proposal — cutting LIVING_WAGE_ANNUAL from $49,370 to a population-weighted $35,021 — did not hold up: Meta's arithmetic on its own 51-state dataset was correct, but the dataset itself was a 2024 snapshot of MIT's Living Wage Calculator. Fetching MIT's own site directly for its current (February 2026) data build found "1 Adult, 0 Children" figures well above what the 2024 snapshot showed for the same states — California $30.48/hr (was $19.41 in the cited 2024 data), DC $26.72/hr (was $20.80), and even low-cost Mississippi at $20.69/hr (was $14.20). The proposed cut would have replaced a defensible figure with a stale one. Not adopted; a properly current, directly-sourced population-weighted recomputation remains a legitimate future good-first-issue, scoped precisely in CONTRIBUTING.md's Good First Issues.
Also resolved this release: the DOI-archived OSF snapshot's metadata, flagged as an open loose end since v4.8 (it still showed CC BY 4.0 for the whole bundle after the code moved to Apache 2.0), has been updated directly by Duke at OSF to reflect the split — see the footer, above, and CONTRIBUTING.md's License section.
What did NOT get fixed, and why: the
LIVING_WAGE_ANNUAL change proposed by the external audit (deliberately — the evidence points the other direction, see above); adopting the modular harness layout (a real option, not a decision for a verification pass to make); every other open item this audit re-surfaced but did not newly identify (unchanged from v4.8 — see CONTRIBUTING.md's Model Architecture Feedback). Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.9 Release Notes.
Tooltip text running off the browser viewport. Root cause, found by tracing the CSS rather than guessing: the
.abbr-link class was originally written for short (2-4 word) header acronym tips — fixed white-space:nowrap, no width limit — but has since been reused for several full-sentence ⓘ explanatory tooltips, the longest (on the interactive tool's PTF adoption-cap toggle) running to roughly 500 characters rendered as one unbroken line. Fixed by giving .abbr-link the same wrap-and-cap behavior .tip-host (a newer, correctly-built class) already had. Separately, the Scenario Presets grid — two ~130px columns inside a 290px sidebar — centered each tooltip on its button, which needs ~85-95px of clearance on both sides that a 130px column doesn't have; left-column preset tooltips ran off the left edge of the browser window. Fixed with edge-anchored positioning specific to that grid.
Chart-grid CSS that could overflow at non-default browser zoom, and boxes not fitting their content. Several grid layouts used a bare
1fr column track, whose minimum width defaults to its content's own intrinsic size rather than 0 — at some viewport/zoom combinations this can keep a track from shrinking, pushing a chart or table off-screen instead of wrapping it. Changed to minmax(0,1fr) throughout (the standard fix), added min-width:0 to the affected card/KPI elements, and added a defensive canvas{max-width:100%} rule. A second, later-cascading duplicate of one grid rule — without the fix — was found silently overriding the first, correctly-fixed one; both are now consistent.
The BLEI-components chart's
benefitDays line looked missing. Checked directly with a fresh Node.js harness rather than assumed: at seed 42/Full Integration/20yr, cashDays runs 201d→1,915d while benefitDays sits flat at 15.14d the entire run (BU is a fixed monthly allocation, so its BLEI contribution genuinely doesn't grow) — not a computation bug, but a ~100×-larger series squashing two much smaller ones into an indistinguishable sliver on one shared linear axis. Fixed with a dual-axis chart (cashDays on the left, incomeDays/benefitDays on their own right-hand scale), which now shows both smaller series' actual shape, including a real crossover around year 11-12.
System Stability scoring the Traditional Welfare Baseline higher than Full Integration was reported as a possible bug — it is not. This is the coefficient-of-variation behavior already disclosed since v4.2/v4.4 (see Known Limitations): a population pinned at a hard wealth floor has almost no variance left to measure, so it scores as "stable" by this metric's specific definition regardless of whether that flatness is a thriving equilibrium or a floor with nowhere left to fall. No code change; the tooltip fix above should make the existing ⓘ explanation on this exact KPI actually readable in place, which is plausibly why it read as a bug before now.
Source code relicensed to the Apache License 2.0. Both external v4.7 reviews independently flagged CC BY 4.0 as an unconventional choice for software — it has no source-distribution or patent terms — and suggested the common split of an OSI license for code, CC BY 4.0 for papers. Logged as an open governance question in v4.7; resolved this release on Duke's explicit authorization. Apache 2.0 was chosen over MIT for its explicit patent grant and patent-retaliation clause. This page's own content, like all Better To Best Research Hub papers, is unaffected — still CC BY 4.0. The interactive tool's own footer and citation text now disclose the split explicitly. Full license text and split-licensing rationale in CONTRIBUTING.md.
WEALTH_FLOOR sensitivity sweep — the item flagged as blocked-on-a-harness at the end of v4.7. A standalone Node.js harness was built fresh this session (pure functions transcribed directly from index.html) and, before being trusted for anything, validated by reproducing the documented seed-42/Full Integration/20yr regression figures exactly — median wealth $559,223 to the dollar, plus Gini, BLEI, poverty, stability, and EDC all matching too. N=500 seeds, 4 candidate floor values ($0, −$10,000 current, −$25,000, −$50,000), Full Integration and Traditional Welfare Baseline. Finding: Baseline is completely invariant to the floor's exact value on every metric except the trivial fact that its median wealth equals whatever the floor is — once a Baseline agent starts declining nothing ever reverses it, so how deep the floor goes never matters. Full Integration shows a real, modest, monotonic sensitivity (Gini 0.515→0.520, wealth poverty 14.1%→17.5% as the floor deepens from $0 to −$50,000) via a specific, verified mechanism: agents who dip negative and later recover have their BLEI liquid-wealth term clamped to exactly 0 for every year they're underwater, however deep — so a deeper floor doesn't worsen any single year, but does mean more years spent at that clamped zero before finally turning positive. Not acted on: the shipped default stays at −$10,000; this is data for the framework's authors to weigh, following the same "sweep, don't decide" pattern as the existing λ Calibration Status sweep. Full table and mechanism discussion in CONTRIBUTING.md's v4.8 Release Notes.
Occupation-risk dataset lead — stronger evidence, still one step short of full verification. v4.7 flagged a Kaggle-hosted dataset that might be a complete, machine-readable version of Frey & Osborne's 702-occupation table, without checking completeness or license. This session found independent, non-Kaggle corroboration of the same 702-row count and a third-party dataset card naming the exact needed columns and stating an MIT license — meaningfully stronger than v4.7's open question, but still short of pulling the actual file and diffing it against the paper's own appendix, which needs Kaggle access this session's sandboxed environment didn't have. The "FOWIGS" citation from the second v4.7 ChatGPT pass remains unverified — a fresh search again found no trace of it. Full detail in CONTRIBUTING.md's Good First Issues.
What did NOT get fixed, and why: acting on the
WEALTH_FLOOR sweep's findings (deliberately — see above); pulling and verifying the occupation-risk CSV itself (blocked on access); the v4.6-flagged "no plateau" long-horizon wealth-growth question (still open, needs its own dedicated release); TARGET_WEALTH/TARGET_POVERTY/TARGET_GINI recalibration (still a framework-author decision). Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.8 Release Notes.
Chart.js is now pinned with a real, verified SRI hash — closing an item open since v3.8, when two earlier reviewers each supplied a hash "from memory" that proved unusable. This time the hash was computed directly against the actual downloaded npm package (version confirmed via the file's own banner), and — independently — the second ChatGPT pass computed and reported the identical 64-character digest from the same npm artifact, a meaningful cross-check given SHA-384 is a deterministic function of file bytes. Rather than pin that hash against the still-unverified cdnjs URL, the script tag now points at a jsDelivr npm mirror, which serves npm packages byte-for-byte by construction — the pinned hash is valid by construction, not by hope.
A new open calibration finding, logged but not corrected. Agent wealth is drawn lognormal(10.5, 1.2) — now named
WEALTH_INIT_MU/WEALTH_INIT_SIGMA in the engine, same values — with a median of exactly e^10.5 ≈ $36K, matching this framework's own long-standing "Fed SCF 2022" citation. The actual 2022 Survey of Consumer Finances reports median household net worth at ≈$193,000 (Kuhn & Ríos-Rull, NBER working paper, 2025) — roughly 5.3× higher. Both external reviews independently surfaced this; genuinely separate from the wealth-init distribution's already-documented inherent Gini ≈0.60, since Gini of a lognormal is a function of σ alone, with no μ term — correcting the median would move absolute wealth-poverty rates without touching Gini at all. Given how foundational this single draw is to every downstream figure the model produces, fixing it is being treated as its own future mechanics-audit-plus-large-N-restudy candidate, not a value swap alongside a hygiene release — see Known Limitations, below, and CONTRIBUTING.md's Model Architecture Feedback.
PTF's two "reduction" figures, disambiguated. This page's own Key Concepts card and JSON appendix stated PTF establishments "achieve 40–60% overhead reductions" without distinguishing that Mondragon-analogy figure from the 12–16% consumer-facing cost-reduction rate (
PTF_savings_rate) the engine actually implements — the exact pair of numbers CONTRIBUTING.md's own v4.2 changelog already had to disentangle once before in an old README. The first ChatGPT audit cited the 40–60% figure as if it were the simulation's own parameter; both spots on this page now say explicitly that it isn't.
A quick scatter now appears in-app after LHS exports — wealth poverty vs. BU allocation across the 100 sampled design points, reading data already computed for the CSV, with zero new simulation runs or RNG draws. A small UX closure, not a methodology change; the CSV-plus-external-Sobol/Morris workflow is unaffected.
What the audits got wrong, documented rather than quietly ignored: the first ChatGPT pass claimed the interactive tool "only has CSV" export (JSON has existed since v3.3), claimed a "Citation Generator" UI feature that doesn't exist (the footer's citation is a static string), conflated the recession income-shock mechanism with inflation (two separate mechanics), misattributed the $1,200 BU figure to CEX data (it's tied to the Alaska PFD analogue), and recommended splitting the codebase into modules and adding a Dockerfile — both of which either contradict an explicit standing constraint or misdiagnose the project's actual reproducibility risk (cross-browser floating-point drift, not a server environment issue). The second pass, while substantially corroborating the above, cited a "FOWIGS" Frey & Osborne/BLS-OES crosswalk dataset that a direct search could not substantiate — noted as unverified rather than relied upon.
What did NOT get fixed, and why: correcting
WEALTH_INIT_MU itself (needs its own audit-and-restudy pass); a WEALTH_FLOOR/TARGET_* sensitivity sweep proposed alongside this release (blocked on validating a Node harness against the documented seed-42 regression table first, rather than risk a fresh unverified reimplementation); building on the newly-found occupation-risk dataset lead (its completeness and license need direct verification first); and relicensing the code away from CC BY 4.0 (both reviews independently flagged this as unconventional for software and suggested an OSI license for the code specifically — a real, precedented pattern, but a governance decision for this project's authors, not something to change unilaterally). Full technical detail in index.html's own changelog and CONTRIBUTING.md's v4.7 Release Notes.
The six BLEI tiers replace binary poverty/non-poverty classification and gate agent advancement probability in the simulation. Tier assignment derives from BLEI score (days of basic living covered). The Flourishing tier threshold of 730 days reflects the capital commitment horizon required for entrepreneurial ventures to become viable without required break-even within the first year. v3.1 tier naming: the top tier (≥730 days) is labelled Flourishing when both CCO and PTF are active — reflecting the maturing generative effects of the full system. Without CCO+PTF, reaching 730+ days represents strong temporal stability but is labelled Comfortable, consistent with BLEI §4.
| Tier | BLEI Range | Characterization | P(Advance) |
|---|---|---|---|
| 0 — Crisis | < 7 days | Survival-mode cognition; zero advancement capacity; immediate intervention required | ≈ 0 |
| 1 — Precarious | 7–30 days | One disruption from crisis; income fully consumed by extraction and basic needs; Lusardi et al. (2011) $2,000-shock vulnerability zone. BLEI poverty = Crisis + Precarious combined. | ≈ 0.02 |
| 2 — Threshold | 30–120 days | BLEI-defined poverty line; limited advancement feasible; positive FBS emerging | 0.08–0.15 |
| 3 — Stable | 120–365 days | One full year covered; measured risk-taking and education investment viable; Carroll (1997) buffer-stock target zone | 0.20–0.35 |
| 4 — Secure | 365–730 days | One to two years covered; creative and entrepreneurial participation feasible within two-year payoff horizon | 0.40–0.60 |
| 5 — Flourishing (or Comfortable without CCO+PTF) | > 730 days | Two-year capital commitment horizon unlocked; ventures without early-stage break-even are viable; extended planning horizon with reduced liquidity-constrained decision-making | 0.65+ |
index.html (github.com/BetterToBest/compassionism-simulation) and CONTRIBUTING.md's Cumulative Bug Fixes for exactly what changed and why.
The v3.1 agent class adds an annual expense system, heterogeneous AI automation risk, negative wealth floor, and PTF dynamic adoption. The corrected agent also separates PTF benefits (cost reduction) from PTH benefits (Acre Equity growth), preventing the double-counting present in earlier versions. The BLEI income buffer uses actual agent wage rather than the wealth/60 proxy. BU_food_eff ($990) is used for BLEI; BU·ε_blended ($2,502) is used for EPPM. v3.3 addition: wage growth stability premium applies diminishing returns above WAGE_MEDIAN_SIU (35 SIU), preventing structural compounding at high wages. The constant ANNUAL_BASE_COST is renamed SIM_COST_SCALE to avoid apparent contradiction with BASE_DAILY_COST.
automation_risk ∈ [0.2, 1.0] drawn uniformly at initialisation — creates heterogeneous inequality under AI displacement (high-risk agents lose wages faster). wealth floor changed from 0 to −$10,000 — allows debt and insolvency dynamics. PTF adoption now dynamic: agents join via economic distress (BLEI < Precarious) or social diffusion at low base rate, not only at initialisation.
SIM_COST_SCALE is shown here as the operative driver of the wealth-accumulation ratio (income×12 / SIM_COST_SCALE) — that mechanic was replaced entirely in v4.3 by the WAGE_TO_USD/LIVING_WAGE_ANNUAL formula in Mathematical Framework §2, and the validation assertion below (gini_edc_adjusted < 0.22) reflects a target value that was never reconciled with the shipped code's own CFG.TARGET_GINI = 0.25, let alone the model's actual measured Gini (0.518 under v4.4 — see Performance Comparison). Preserved as historical/illustrative rather than rewritten, for the same reasons given above — see index.html and CONTRIBUTING.md for the current, validated implementation.
The Monte Carlo engine adds the annual expense system, AI automation displacement, negative wealth floor, BLEI poverty tracking, and population-level recession model. The incomeMultiplier field in recession state (renamed from severity) makes the directional meaning unambiguous: 0.90 means agents earn 90% of normal income (10% loss) at the distribution's mode. v3.3: recession severity now drawn from a beta(5,2) distribution over [0.70, 0.95] for NBER-calibrated realism; SIM_COST_SCALE renamed from ANNUAL_BASE_COST; WAGE_MEDIAN_SIU added as diminishing returns reference.
Parameters identified across 10,000+ Monte Carlo simulations as producing strong welfare outcomes. Note on calibration status: values marked under revision were produced under less rigorous simulation versions and are being updated as v3.x matures. An open goal of this work is identifying parameter configurations that deliver best welfare outcomes across all points simultaneously — analogous to a structural engineer ensuring load capacity.
WAGE_TO_USD/LIVING_WAGE_ANNUAL instead (see Mathematical Framework §2) — that switch happened in v4.3. The constant survives in the codebase only as a historical value; it is not load-bearing anywhere in the current simulation. supersededincomeMultiplier now drawn from beta(5,2) distribution over [0.70, 0.95]: mode 0.90 (10% income loss), tail to 0.70 (30% loss). Calibrated against NBER post-WWII data. Replaces v3.1 Uniform(0.65, 0.85), which overstated severe recession frequency.Results from 5,000 independent seeded runs each of Full Integration, CCO-Only, and Traditional Welfare Baseline (v4.0 large-N study, reconfirmed unchanged under v4.1, reconfirmed again under v4.2's population-pairing mechanics, superseded by v4.3's mechanics-changing main-wealth-loop unit fix and re-run again under v4.4's further mechanics changes — seeds 1–5,000, 500 agents, 20 years, shock disabled to match the Full Integration reference preset; methodology below). BLEI-based metrics are the primary welfare standard; BLEI poverty (% Crisis+Precarious) is the primary poverty indicator. These are internally calibrated simulation outcomes under the reference parameter configuration — they represent a design reference point, not a prediction of outcomes under any specific deployment scenario. 95% CI below is on the mean of each statistic across the 5,000 runs (not per-agent spread within one run) — narrow CIs here reflect a large, well-powered sample, not low real-world variance.
incomeMultiplier (renamed from ambiguous "severity"); (4) negative wealth floor −$10,000 allowing debt/insolvency; (5) PTF dynamic adoption via distress and diffusion; (6) BLEI poverty KPI (% Crisis+Precarious) alongside wealth poverty.
makeAgent()/runYear()/calcMetrics() exactly as the browser does, for 5,000 independent runs per scenario (15,000 total), seeds 1–5,000, at the Full Integration reference population size (500 agents) and horizon (20 years). Each run's final-year tier distribution, Gini (nominal and EDC-adjusted), median wealth (years 10 and 20), median FBS among CCO participants, participant/non-participant poverty, and the System Stability heuristic were recorded, then aggregated (mean, median, SD, 95% CI on the mean) across runs. The near-poverty cohort is tagged once per run at initialization (year-0 wealth < $25,000) and tracked longitudinally for the milestone-crossing figures. This is a documented, reproducible methodology superseding the previously-unspecified "10,000 simulation runs" claim (batch size, seed range, and code path were never recorded for that figure) — script available on request via a GitHub issue.
makeLatentPopulation(), instantiateAgent(), runYear(), calcMetrics(), bleiMetrics(), structuralStability() called directly, seeds 1–5,000, 500 agents, 20 years, shock disabled). Two additions to the methodology, both new in v4.3 and carried through to this v4.4 re-run: the Social-Security-anchored cohort tagging (agents' initial, pre-dynamics wage compared against real 2026 SSA benefit levels via WAGE_TO_USD — SSI, SSDI, and average retired-worker levels — the same convention the near-poverty cohort already used for initial wealth), and reporting BLEI figures for small cohorts (≈4–86 agents per run) as median-of-medians across seeds rather than mean, since BLEI is right-skewed and a small cohort's mean is more exposed to a handful of high-BLEI seeds — a distinction that mattered directly for this release: an initial mean-based reading of the retirement-level cohort would have overstated its typical outcome as crossing the 30-day Threshold, when the median-of-medians and the per-seed crossing rate (31.1%) show the typical case still falls short. Two supplementary figures in the table above (year-10 median wealth, nominal-wealth Gini) required a small additional pass beyond the core headline metrics, run separately against the same seed range; median FBS among CCO participants was not recomputed this pass and is flagged accordingly in the table, since the pre-v4.3 figure predates the wage-scale changes and would be misleading if left uncaptioned.
156 parameter sensitivity tests across all key variables. The most important finding: BLEI outcomes remain above Tier 2 Threshold for CCO-PTF participants across all tested parameter combinations at Month 12. Month 0 values use γ = 0.12 (entry) and food BU effective value ($990). Note on sensitivity methodology: the elasticity values below are scenario-comparison estimates from the Monte Carlo analysis — not formal Sobol indices or Latin hypercube results. Formal sensitivity analysis using these methods is a documented future research direction in CONTRIBUTING.md. v3.3 update: the interactive simulation's OAT sensitivity chart now reports results from 11 computed mini-simulations (±20% on 5 parameters, seed 7777), replacing the prior hardcoded illustrative guidance table; these are first-order estimates only and do not capture interaction effects. v3.4 framing note: the OAT sensitivity shown is scenario-comparison from actual mini-runs (±20%, seed 7777), not computed Sobol or Latin hypercube indices. This correctly flags first-order parameter effects but does not quantify interactions. v4.0: the ±20% perturbation is now uniformly defined as ±20% of each parameter's own slider range across all five parameters (previously a mix of relative and fixed-percentage-point steps — see the Simulation page's Cumulative Bug Fixes). For formal Sobol analysis, use the simulation's CSV export with external Python/R.
1. BLEI Temporal Stability Index — Three-Component Structure
v4.4 note (supersedes the v4.0 note this paragraph previously carried): the simulation's internal wage state is tracked in Simulation Income Units (SIU), a separate calibration unit from the USD figures L, BU_food_eff, and C_basic use — so Y here is WAGE_TO_USD-converted before entering this formula. Through v4.3, this formula (and §4 FBS, §5 EDC-adjusted Gini) used a different, cost-side-derived constant, SIU_TO_USD (≈16.63), while the wealth-accumulation loop in §2 already used WAGE_TO_USD (≈100.52, Census/BLS-sourced) — leaving the same agent's wage worth roughly $582/month here versus roughly $3,518/month in §2, a ~6× divergence external audit correctly flagged as indefensible once one anchor is empirically grounded and the other isn't. SIU_TO_USD is retired as of v4.4; every formula in this section — §1 (this one), §2, §4, and §5 — now uses the same WAGE_TO_USD anchor throughout. agentEDC() was and remains unaffected by any of this — it's a dimensionless SIU/SIU ratio that never touched either constant.
2. Wealth Dynamics with Annual Expense System
v4.3/v4.4 note (supersedes the v4.0 note this paragraph previously carried, which described an unresolved sensitivity problem — now resolved): through v4.2, Y and living cost here were intentionally left in native internal SIU/SIM_COST_SCALE terms rather than converted to USD, because an early tested USD-converting version was extremely sensitive to the conversion constant (a ~3.5× range of candidate values swung 20-year outcomes from universal wealth-floor collapse to implausible multi-million-dollar median wealth) — flagged then as a candidate research direction, not a solved problem. v4.3 resolved this: WAGE_TO_USD (≈100.52, Census/BLS CPS ASEC 2023 median personal income ÷ 35 SIU × 12) converts wage, and LIVING_WAGE_ANNUAL ($49,370, World Population Review's MIT-sourced state living-wage table) anchors cost — replacing the old BASE_DAILY_COST-netted-against-real-wage approach, which was a bare-subsistence floor correct for BLEI's poverty-line use but wrong for a 20-year compounding loop, and which produced an ~11× wealth explosion and broke BU-monotonicity when tested naively. SIM_COST_SCALE no longer drives this formula at all as of v4.3 — it survives in the codebase only as a historical constant. This is not a "clean win": it redistributes as well as it grows — see Performance Comparison and CONTRIBUTING.md's v4.3 Release Notes for the full finding, including the Traditional Welfare Baseline's collapse to the wealth floor as a direct consequence of this same fix.
3. Heterogeneous AI Automation Displacement
4. FBS-Gated Advancement Probability
v4.0 note: this formula is now implemented in the simulation engine exactly as specified above (see runYear()). Prior versions (through v3.9) computed advancement from a fixed-probability heuristic gated on BLEI > 30 days instead of FBS — a gap identified in external review (Refine.ink, Aug 2026) between this specification and the shipped code. Y is WAGE_TO_USD-converted as noted under §1 above (was SIU_TO_USD through v4.3 — retired v4.4, see §1); EDC_residual uses the worked values from Table 1b (0.12 baseline, 0.025 for CCO+PTH participants) as a fixed proxy, not a separately-modelled consumer-debt submodel.
5. EDC-Adjusted Gini & BLEI Poverty
v4.14 note, prompted by an external audit's runYear()-level review: W_net below is a wealth STOCK minus EDC_full×Y×12, a one-year FLOW. That's a genuine conceptual distinction worth stating plainly rather than leaving implicit: this is not "wealth after all extractive costs" in a conventional net-worth-accounting sense — it is a wealth stock adjusted by one year's estimated extractive burden, a deliberately constructed inequality index in this framework's own convention, matching BLEI paper Table 6's specification exactly. The formula itself is unchanged; only the interpretation needed making explicit. See the interactive tool's own Gini KPI tooltip for the same clarification in-app.
v4.0 note: EDC-adjusted Gini is now actually computed by the simulation (previously the engine only ever computed nominal-wealth Gini; this formula existed here as a specification, not shipped code). v4.4 update: measured output from the current 5,000-run large-N study at the Full Integration reference configuration (500 agents, 20 years, seeds 1–5,000; see Performance Comparison below for full methodology and how these figures moved from the original v4.0 measurement through v4.3/v4.4) is Gini = 0.858 [95% CI 0.8577–0.8584] at the Traditional Welfare Baseline and Gini = 0.518 [95% CI 0.5179–0.5187] under full deployment — both meaningfully higher than the aspirational 0.44–0.46 / 0.22 range above, though both moved toward that range compared to the original v4.0 measurement (Baseline 0.800→0.858 is a move away, driven by v4.3's cost-anchor change pinning Baseline's wealth at the floor for effectively the whole population — see Performance Comparison; Full Integration 0.484→0.518 also moved away slightly, then improved again from a v4.3 peak of 0.536 once v4.4's wage-scale unification corrected the EDC-extraction calculation — see Version History for the full sequence). The direction (full deployment well below baseline) remains confirmed; the absolute levels remain off-target either way. The most likely source of the wealth-initialization contribution to this gap: lognormal(10.5, 1.2) has an inherent Gini coefficient of ≈0.60 before any simulation dynamics or EDC adjustment are applied (2Φ(σ/√2)−1 for σ=1.2) — already above the old baseline target, which suggests that target was a theoretical projection never checked against the actual coded initialization rather than a value the shipped model was failing to hit. Reconciling this — either by revisiting the wealth-initialization spread or by revisiting the target — is flagged as an open calibration item in CONTRIBUTING.md, not resolved here. v4.7 note: this Gini gap is about the wealth-init distribution's spread (σ) specifically — a separate, independently-found v4.7 finding concerns its level (μ) instead: the same lognormal(10.5, 1.2) draw's median (≈$36K) diverges roughly 5.3× from actual 2022 SCF median net worth (≈$193K). The two are mathematically independent (Gini of a lognormal has no μ term), so fixing one wouldn't touch the other — see Known Limitations, below.
6. EPPM and IPBI
7. Wage Growth Diminishing Returns & Recession Distribution (v3.3)
These benchmarks function as internal calibration checks — they confirm the simulation reaches its design targets under optimal parameters. They are not external empirical validation criteria. All benchmarks must be satisfied for a parameter set to be considered fully calibrated for v3.3. The four v3.3 validation suite checks (BU monotonicity, participation threshold, CCO benefit direction, PTF inflation dampening) must all return PASS.
The Gini benchmark predates v4.0's actual implementation of EDC-adjusted Gini (see Mathematical Framework §5 above) — measured full-deployment output from the current v4.4 large-N study (N=5,000, see Performance Comparison) is 0.5183 [95% CI 0.5179–0.5187], not ≤0.22 (was 0.4843 under v4.0-v4.2 mechanics; moved through 0.5359 under v4.3 before settling here under v4.4's wage-scale unification — see Version History). Marked under revision pending the wealth-initialization/target reconciliation discussed there, rather than silently left as a passing claim.
The following limitations are documented as part of the ODD protocol (Grimm et al. 2010) and in the interests of transparent calibration. They identify directions for future model development and should be considered when interpreting simulation outputs.
- No demographic structure. The model does not represent age, retirement, disability, household composition, or life-cycle income profiles. All agents are treated as working-age adults. Age-stratified welfare analysis and retirement dynamics require an extension to the agent class.
- No direct agent-to-agent interaction. All social and economic effects are mediated through zone-level SZH parameters. Peer effects, social learning, and network contagion operate only via PTF adoption diffusion and recession propagation — not via bilateral agent interactions.
- "Recession" and "AI automation" are narrower than their names suggest (named explicitly, v4.14). Both mechanisms are real and calibrated, but each implements a reduced-form slice of the phenomenon its name evokes. Recession only ever multiplies earned wage income (
incomeShock); it does not touch asset prices, employment status, housing costs, business activity, government transfers, or interest rates — "exogenous labor-income shock" is a more precise description than "recession model." AI automation subtracts a displacement term directly from wage growth; there is no explicit job-loss event, job search, unemployment spell, or re-employment transition — an agent's income slows, it never actually disappears and returns. Both are common, legitimate first-pass ABM simplifications, and each is individually already flagged elsewhere in this list — this entry exists so the specific claim "this is a recession/automation model" isn't over-read as more general than either mechanism actually is. A fuller macro-shock model and an occupation-based re-employment model for AI are both real future-work candidates; see CONTRIBUTING.md's Model Architecture Feedback. - OAT sensitivity only. The computed sensitivity analysis (v3.3) reports one-at-a-time results from 11 mini-simulations. This is first-order only and does not capture parameter interaction effects. Sobol indices or Latin hypercube sampling would provide more complete sensitivity characterization and are a documented future research direction.
- No external deployment validation. All calibration is against real-world analogues (Alaska PFD, CLT networks, Mondragon). No post-deployment data from a Compassionism implementation exists. Simulation outcomes should be treated as design-target projections, not empirical forecasts.
- 20% annual wage floor is a policy assumption. The minimum wage update of
max(income × 0.80, income × (1 + wageGrowth))prevents wage collapse below 80% of prior year. This is a deliberate policy boundary, not an emergent market outcome, and should be re-examined for scenarios modelling institutional failure or extreme automation. - Linear automation displacement model. Automation impact is modelled as a linear wage drag (population_rate × automationRisk) with no task-complexity structure, no new-job creation dynamics, and no occupational transition pathways. The model captures displacement magnitude only, not the labour market reallocation that historically accompanies technology transitions.
- automationRisk uniform distribution (added in v3.4). automationRisk ∈ [0.2, 1.0] is drawn from a uniform distribution. Real automation exposure is highly bimodal and occupation-dependent (Frey & Osborne, 2013; Autor, 2015): low-routine cognitive workers face minimal risk, while high-routine manual/clerical workers face extreme risk. The uniform assumption may understate polarization in High Automation scenarios. Priority calibration refinement in CONTRIBUTING.md.
- System Stability was a trend heuristic, not a structural metric (flagged v3.6, resolved v4.2). Through v4.1 the displayed value was
stabBase = improving ? 0.88 : 0.60(based on whether poverty fell over the run's final quarter), plus a small CIP bonus, plus bounded random noise — not derived from wealth variance, BLEI volatility, or agent-state transitions. As of v4.2 the metric is the inverse coefficient of variation of median wealth and median BLEI over the run's final quarter — no RNG call, no manual per-mechanism bonus. See the v4.2 note in Methodology Overview. - Within-run RNG coupling limits per-agent trajectory pairing across scenarios (found v4.2). v4.2's common-random-numbers fix (Methodology Overview) gives the main/CCO-only/baseline comparisons an identical initial population, but
runYear()still consumes a variable number of RNG calls per agent depending on which of its own conditional branches that agent takes each year — participants trigger more draws than non-participants. Two scenarios whose agents end up on different branches (e.g. because participation composition differs) progressively diverge in RNG stream position year over year, so per-agent trajectory pairing holds exactly at year 0 but not for the full run. Aggregate comparisons (population-level poverty rate, median BLEI) are unaffected. A full fix would mean every RNG-consuming branch inrunYear()drawing unconditionally, mirroring the v4.2 fix to agent construction — a larger change, tracked as an open item in CONTRIBUTING.md. - Headline large-N figures on this page are current as of v4.4 (Aug 2026). v4.3 and v4.4 both changed simulation mechanics substantially — the main wealth-accumulation loop's unit fix (v4.3) and the wage-scale unification across BLEI/FBS/Gini plus true CRN pairing (v4.4) — so a full fresh N=5,000 study was run for v4.4 rather than assumed; this page's own sync skipped an intermediate v4.3 snapshot (deliberately deferred pending an independent audit — see Version History). Figures moved substantially from the v4.0-v4.2 era shown in older archived copies of this page — median wealth roughly 6× higher, BLEI poverty and Gini both improved, the near-poverty cohort now reaches every milestone including Flourishing well within the 20-year horizon (previously not reached even at 40 years) — see Performance Comparison for the full before/after and Version History for why each figure moved. The one figure NOT reconfirmed under current mechanics is the v4.1 40-year cohort extension (N=1,000) — a three-releases-stale result, now very likely superseded given how much the 20-year figures moved, tracked as an open item rather than assumed either way.
- System Stability can score a stagnant floor as "more stable" than a thriving population. The structural metric (v4.2) is the inverse coefficient of variation of median wealth and BLEI over a run's final quarter — a genuinely flat trajectory scores as maximally stable whether that flatness reflects a thriving equilibrium or a population pinned at a hard floor with nowhere left to fall. In the v4.4 study, the Traditional Welfare Baseline — median wealth pinned exactly at the wealth floor in 100% of runs by year 20 — scores 99.0% stability, higher than Full Integration's 88.6%, precisely because a hard floor has near-zero variance left to measure. Read this metric as trajectory steadiness, not as an endorsement of the outcome it describes, and always alongside the poverty and BLEI figures next to it. Not previously disclosed on this page; added as part of the v4.4 sync (the interactive tool itself carries the same disclosure as of v4.4 — see CONTRIBUTING.md).
- Initial PTF share is not a hard cap (relabeled v3.6, unresolved). The PTF slider sets the
t=0adoption probability only; independent per-agent adoption checks each simulated year — now including a Bass-diffusion imitation term as of v4.0 — mean the realised final PTF share can exceed the slider value with no aggregate feedback loop to constrain it. v3.6 corrected the UI label and documentation to reflect this; v4.0 makes adoption more realistic (imitation-driven) but does not add a cap. A quota-based or feedback-clamped adoption model remains an open item, tracked in CONTRIBUTING.md. - Main wealth-accumulation loop keeps its pre-v4.0 unit simplification. v4.0 closed a wage(SIU)/wealth(USD) unit mismatch in the BLEI, FBS, and EDC-adjusted-Gini formulas, but deliberately left the core annual wealth update (§2 above) unchanged — it remains extremely sensitive to any wage→USD conversion constant because wage compounds against cost over up to 30 years (candidate constants spanning a ~3.5× range swung 20-year outcomes from universal wealth-floor collapse to implausible multi-million-dollar median wealth in internal testing). A defensible fix needs a joint recalibration of the wage distribution, cost scale, and every target metric against real income data — flagged as a research direction in CONTRIBUTING.md, not attempted in v4.0.
- CCO conversion proceeds are tracked but not production-constrained (v4.0). BU→wealth conversion credits agents without debiting a modelled treasury, PTF balance sheet, or production account — external review correctly flagged this as an open stock-flow accounting gap. v4.0 adds transparency only (cumulative conversion proceeds are tracked and exported). A genuine aggregate production constraint, with a defined production function and rationing behaviour when exhausted, is a further economic-modelling design decision not implemented here.
- System Stability needs at least ~8 simulated years to mean anything (found and partially fixed, v4.13). The metric is the inverse coefficient of variation of median wealth and median BLEI over the run's final quarter. Before v4.13 that window was floored at a single data point, so every run of 5–7 years — the slider's own minimum is 5 — returned exactly 0.99, the metric's clamp ceiling, regardless of the trajectory: a variance of one observation is undefined, so the helper correctly returned zero volatility and the metric read it as perfect stability. The floor is now 2, which computes a real variance but is still a very small sample. Treat this metric as indicative at best on any run shorter than roughly 8–10 years, and prefer the 20-year reference horizon when the number matters. This sits on top of the separate, longer-standing limitation below — that the coefficient of variation cannot tell a thriving equilibrium from a population pinned at a floor.
- Cumulative Poverty Exposure is aggregate, not longitudinal (new metric, v4.13). The two new exposure figures sum each year's population poverty share, which gives the mean years-poor per agent exactly — but says nothing about how those years are distributed across agents. "Every agent poor for three years" and "30% of agents poor for ten years" produce the same number and are very different policy situations. Distinguishing them needs per-agent poverty spells tracked over time, which the engine does not keep (agents carry current state, not history). The related measures the v4.12 audit also suggested — time-to-tier-attainment per agent, wealth-floor recovery rates, spell-length distributions — all depend on that same missing longitudinal layer and remain open; see CONTRIBUTING.md. The wealth-poverty figure also inherits
POVERTY_LINE's own undocumented provenance (see below), so read it comparatively — Your Settings against Baseline — rather than as an absolute count. POVERTY_LINE($25,000) has no citation anywhere in the codebase (logged v4.10, surfaced at the constant itself v4.13). Unlike almost every other calibration constant in this framework, the wealth-poverty threshold behind the headline "Wealth Poverty Rate" — and behind the wealth-exposure figure added in v4.13 — carries no source, no "framework spec" label, and until v4.13 no code comment at all. It is a pure post-hoc reporting threshold with a single read site, so this is a reporting-clarity gap rather than a mechanics risk (and the v4.10 Threshold Sensitivity charts exist precisely so a conclusion need not rest on it), but it is worth knowing when quoting the number: for reference the 2026 HHS one-person federal guideline is $15,960, noticeably lower. Tracked as an opencalibration:item.- Wealth-initialization median cites Fed SCF 2022 but diverges from it by ~5.3× (new finding, v4.7). Agent wealth is drawn lognormal(
WEALTH_INIT_MU,WEALTH_INIT_SIGMA) = lognormal(10.5, 1.2), whose median is exactly e^10.5 ≈ $36K by construction, matching this framework's own long-standing "Fed SCF 2022" citation (see Agent Architecture, above, and the ODD panel in the interactive tool). The actual 2022 Survey of Consumer Finances reports median household net worth at ≈$193K (Kuhn & Ríos-Rull, NBER working paper, 2025, using 2022 SCF microdata). This is independent of the wealth-init distribution's already-documented inherent Gini ≈0.60, discussed under Mathematical Framework §5 — Gini of a lognormal is a function of σ alone (2Φ(σ/√2)−1, no μ term), so correcting the median would move absolute wealth-poverty rates (especially in early simulated years, against the fixed-dollarPOVERTY_LINE) without moving Gini at all. Not corrected in v4.7 — logged as an opencalibration:item in CONTRIBUTING.md's Model Architecture Feedback, given how foundational this single draw is to every downstream wealth, Gini, BLEI, and poverty figure the model produces.
unit_system_note.sim_cost_scale field and automation_risk distribution both describe mechanics superseded in v4.3 (see Mathematical Framework §2, §3), and its unit_system_note.wealth field's "Fed SCF 2022" citation for the $36K median has not been checked against the actual SCF figures — see the Known Limitations entry on this, added in v4.7, for what a check turned up. Preserved as historical/illustrative rather than rewritten field-by-field — see index.html's own CFG object and CONTRIBUTING.md's Calibration Validation table for the current, authoritative parameter set.
Complete JSON dataset with v3.3 calibrated parameters. v3.1 additions: annual expense system, wealth floor, heterogeneous AI automation risk, PTF as cost-reduction mechanism, BLEI poverty metric, incomeMultiplier recession field. v3.3 additions: wage diminishing returns, beta(5,2) recession distribution, SIM_COST_SCALE rename, Gini zero-wealth fix, participant stratification, computed OAT sensitivity, validation suite, 50× Monte Carlo CI.
🖥️ Compassionism Framework Simulation v4.14 — Interactive Tool
Browser-based HTML/JavaScript agent-based simulation implementing all five architectures with BLEI-calibrated welfare metrics. v3.3 builds on the v3.1 accuracy improvements (annual expense system, PTF as cost-reduction factor, PTH without double-counting, heterogeneous AI automation risk, multi-year population-level recessions, negative wealth floor, PTF dynamic adoption, BLEI poverty KPI) and adds: wage growth diminishing returns, beta(5,2) recession distribution calibrated to NBER data, parameterized 50× Monte Carlo with 95% CI, CCO participant vs. non-participant stratification, computed OAT sensitivity (11 mini-runs), a four-check validation suite, JSON export, High Automation preset, and ODD protocol documentation. v3.5 adds a permanent archival DOI (10.17605/OSF.IO/QWTE2), fixes version-string drift between the displayed version and exported CSV/JSON files, and adds a live effective-max-multiplier indicator. v3.6, prompted by an external technical audit, relabels the PTF slider to reflect its initial-condition semantics (final share can exceed it via organic adoption), discloses the System Stability metric's current trend-heuristic formula via an info tooltip and Known Limitations entry, fixes a mobile table overflow bug, adds a cancel control for long-running Monte Carlo batches, and declares a previously-implicit global variable — no simulation math changes. v3.7, prompted by an external Meta AI review cross-checked against the actual codebase, fixes a double preset-apply bug on page load, adds screen-reader labels to all 11 charts, and adds an in-app glossary panel mirroring this page's Key Concepts accordion — no simulation math changes. v3.8, prompted by an external Grok review, isolates the baseline and CCO-only comparison-run RNG streams from the main trajectory (previously they shared one stream, so comparison-run length could shift the main run's random sequence at a fixed seed) — no simulation output changes for a fixed (years, nAgents) configuration. v3.9, prompted by an external Gemini review, tightens the p90/p10 wealth-ratio KPI's near-zero guard and fixes a case where OAT sensitivity mutated a shared params object instead of copying it; a proposed Object.freeze() on that object and a supplied Chart.js SRI hash were investigated and not applied — the freeze would have broken OAT's legitimate override, and the supplied hash is the wrong length for a valid sha512 digest. v4.0, prompted by an external Refine.ink review, is the first release where behaviour changes for typical configurations: FBS-gated octave advancement, octave-governed conversion capacity, PTH payment→equity contributions, network-density-gated SZH synergy, Bass-diffusion PTF adoption, dimensionally-consistent BLEI/FBS/EDC-adjusted-Gini calculations, independently-initialised and shock-paired baseline/CCO-only comparisons, and fixes to the previously-nonfunctional Monte Carlo controls, the ablation attribution methodology, OAT's perturbation scale, and two validation-suite parameter-mapping bugs — see the v4.0 note above for the full list, including what was deliberately left unfixed and why. v4.1, an internal Claude (Anthropic) audit, fixes a paired-population ablation leak that let the SZH+PTF synergy bonus survive PTF removal on the Attribution chart when SZH was active, wires up a dormant "illustrative reference run" UI label that had never actually displayed since v3.4, and corrects several UI hint strings that had drifted from their underlying formulas (recession duration/severity, octave conversion-capacity description, an effective-max-multiplier default, a baseline-chart caption, an OAT sensitivity range) — no simulation mechanics changed, confirmed via an independent N=1,000-seed large-N re-run rather than assumed; see the v4.1 note above for the full list and the near-poverty cohort's new 40-year extension study. This paragraph itself was last updated at v4.1 and, found stale while fixing an unrelated version-number reference in v4.8, is not being backfilled through v4.2-v4.8 here — that would duplicate the Version History toggle (further up this page) rather than add anything; see that toggle and CONTRIBUTING.md for the complete, current account of every release since v4.1, including v4.8's UI fixes, relicensing to Apache License 2.0 for the source code, and validated WEALTH_FLOOR sensitivity sweep. No installation required — runs directly in any modern browser.
The Basic Living Economic Index (BLEI) — Foundation Paper
Full mathematical formalization of BLEI, EDC, EPPM, FBS, CSI, and IPBI including BU purchasing power accounting convention, Appendix A (symbol table), Appendix B (worked numerical example), ε cost pass-through model (§3.3), expanded literature review, and updated references.
Risk Mitigation Framework for CCO-PTH-CIP-SZH Implementation
Comprehensive risk identification and mitigation for the failure modes identified in the BLEI paper: governance capture, participation collapse, ε degradation from network density failure, and Acre Equity liquidity risk.
Optimal Transfer Design in Post-Scarcity Economies
Mathematical proof that CCO-PTF allocation Pareto dominates traditional welfare systems under the BLEI welfare criterion.
Dual Currency Systems and Inflation: CCO's Price Stability Mechanisms
GE analysis of BU-stimulated demand effects on non-PTF market price levels. Addresses the inflationary pressure failure mode and confirms 12% conversion tax sufficiency. PTF and PTH deflationary effects relevant to v3.1 inflation mechanism.
U.S. Real Estate Market Transformation Through PTH Integration
Validates Acre Equity parameter calibration and 20% PTH uptake modeling against US real estate market structure. Primary reference for r_a range selection and CLT analogue grounding.
Executive Summary & Research Index
Complete architectural overview of the Compassionism framework: formal definitions of CCO, PTF, PTH, SZH, and CIP, their interdependencies, and the full 18+ paper research corpus.