diff --git a/.custodian-brief.md b/.custodian-brief.md index 216babd..2784301 100644 --- a/.custodian-brief.md +++ b/.custodian-brief.md @@ -2,16 +2,15 @@ # Custodian Brief — assembly-economics **Domain:** communication -**Last synced:** 2026-10-12 04:39 UTC +**Last synced:** 2026-10-12 05:33 UTC **State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* ## Active Workstreams ### GADM-0.3: global sensitivity, power channels, cohorts -Progress: 3/6 done | workplan_id: `23e33ee7-cb27-52bc-819c-704f44f91663` +Progress: 4/6 done | workplan_id: `23e33ee7-cb27-52bc-819c-704f44f91663` **Open tasks:** -- · Separate wealth from power `99e702d7` - · Strengthen attention dynamics and the full organism grid `f56e20b4` - · Life-cycle cohorts `2b749127` diff --git a/AGENTS.md b/AGENTS.md index 797f695..04fa022 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,6 +22,7 @@ cd simulations/gadm02 && python3 run_scenarios.py && python3 sensitivity.py cd simulations/gadm02 && python3 gsa.py # global sensitivity, ~5 min cd simulations/gadm02 && python3 -B power_channels.py # GADM-0.3 power channels (T03 stage) cd simulations/gadm02 && python3 -B wealth.py # GADM-0.3 wealth vs. power +cd simulations/gadm02 && python3 -B organism_grid.py # GADM-0.3 organism grid ``` Use `python3 -B` after quick edits; a stale bytecode cache once masked a change. diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 70ddb25..dbfc919 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -43,6 +43,6 @@ | task | ASSEMBLY-WP-0005-T01 | done | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | | task | ASSEMBLY-WP-0005-T02 | done | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | | task | ASSEMBLY-WP-0005-T03 | done | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | -| task | ASSEMBLY-WP-0005-T04 | todo | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | +| task | ASSEMBLY-WP-0005-T04 | done | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | | task | ASSEMBLY-WP-0005-T05 | todo | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | | task | ASSEMBLY-WP-0005-T06 | todo | — | workplans/ASSEMBLY-WP-0005-gadm-0.3.md | diff --git a/models/GADM-0.2.md b/models/GADM-0.2.md index 95b6a69..3b34054 100644 --- a/models/GADM-0.2.md +++ b/models/GADM-0.2.md @@ -292,7 +292,8 @@ Readings: which is WS-14 work. - A single population with no cohorts, sectors or regions. - Attention dynamics are weak: in the attention oligopoly, A falls only to - 0.55. `aext` may be underestimated. + 0.55. `aext` may be underestimated. *Resolved in GADM-0.3* (`GADM-0.3.md` + § 4.1: `aext` recalibrated to 0.275 against time-use evidence). - Euler integration, dt = 0.1. No stiffness issues were observed at these rates. diff --git a/models/GADM-0.3.md b/models/GADM-0.3.md index cda29db..484bf26 100644 --- a/models/GADM-0.3.md +++ b/models/GADM-0.3.md @@ -7,8 +7,9 @@ the code is the reference if the two ever disagree. # Generative Assembly Dynamics Model — GADM-0.3 **Status:** in progress, exploratory. Implemented so far: power channels -(§ 2, ASSEMBLY-WP-0005-T03) and wealth separated from power (§ 3, T04). -Planned: attention dynamics and the organism grid (T05), cohorts (T06). +(§ 2, ASSEMBLY-WP-0005-T03), wealth separated from power (§ 3, T04), +attention recalibration and the organism grid (§ 4, T05). Planned: cohorts +(T06). GADM-0.3 builds on GADM-0.2 (`GADM-0.2.md`). Everything not described here is unchanged; the implementation reuses `gadm02.py`. Time unit: one year. @@ -257,10 +258,96 @@ value): although it plausibly could (through acquisitions). This is a deliberate simplification to make P3 testable, and it biases the result toward P3. +--- + +## 4. Attention recalibration and the organism grid (T05) + +### 4.1 Attention extraction against time-use evidence + +GADM-0.2 flagged attention dynamics as too weak: under its `aext` = 0.12, +baseline attention headroom A *rose* from 0.50 to 0.65. + +Evidence used as the calibration anchor: + +- **American Time Use Survey 2023:** about 5.2 hours of leisure per day, of + which TV takes about 2.7 hours, over half (BLS). +- **Social media:** roughly 2 h 20 min to 2 h 25 min per day for the average + internet user worldwide (DataReportal/GWI, Statista). + +Together these suggest that engagement-funded media already claim around half +of discretionary time. Target: baseline A ≈ 0.45–0.5 (current state), +falling to about 0.3 under an extraction regime. + +Solving the A equilibrium for these targets gives **`aext` = 0.275**: + +| Scenario | A (GADM-0.2 aext) | A (recalibrated) | +|---|---|---| +| Baseline | 0.69 | 0.49 | +| Attention oligopoly | 0.57 | 0.37 | +| Generative regime | 0.77 | 0.60 | +| Generative, attention extraction | 0.44 | 0.26 | + +VFAC falls by 0.015–0.04 across scenarios. P and the scenario ordering are +unchanged. This is an order-of-magnitude anchor, not an estimate: the +mapping from hours of engagement media to "unclaimed attention" is itself an +assumption (see the Goodhart note in `metrics/MetricsCatalog.md`, A). + +The T03 and T04 stages remain reproducible (`t03_params()`, +`t04_params()`), verified by identical output. + +### 4.2 The 2 × 2 × 2 organism grid + +Axes (from `InformationOrganismsInGADM.md` § 5): **lineage ownership** +(concentrated: L = lin_open = 0.1 / diffuse: 0.8), **membrane control** +(operator: m = 0.2 / user-community: 0.8), **attention regime** (extraction: +x_att = 0.9 / protected: 0.2). Each grid is run on the baseline and the +generative background. Full tables: +`simulations/gadm02/results/organism_grid.md`. + +Factorial effects (average change from the first to the second level): + +| Effect | VFAC, baseline bg. | VFAC, generative bg. | P, baseline bg. | P, generative bg. | +|---|---|---|---|---| +| lineage diffuse | **+0.130** | **+0.127** | −0.242 | −0.340 | +| membrane user-controlled | +0.090 | +0.089 | −0.175 | −0.216 | +| attention protected | +0.046 | +0.060 | −0.009 | +0.002 | +| lineage × membrane | +0.040 | −0.005 | −0.093 | −0.032 | +| other interactions | ≤ 0.011 | ≤ 0.006 | ≤ 0.006 | ≤ 0.005 | + +Consistency check: the (diffuse, user, protected) corner on the generative +background reproduces the generative regime exactly (VFAC 0.672). + +### 4.3 Readings + +1. **Lineage ownership is the strongest organism lever,** ahead of membrane + control, on both backgrounds. This agrees with the GADM-0.2 Sobol + results only partly: there, `m` ranked above `L`. In the channel model, + lineage concentration feeds a self-reinforcing channel with learning with + use (P2), which strengthens its effect. +2. **Lineage and membrane governance are complements where governance is + otherwise weak.** On the baseline background, doing both is worth +0.04 + VFAC beyond the sum of the parts. On the generative background, the + interaction vanishes. +3. **Attention protection improves VFAC but not power.** It acts through + attention headroom A, not through domination. In this model the attention + regime and discovery concentration are separate levers. The + attention-oligopoly scenario sets both. +4. **Better organism governance increases attention pressure unless attention + is protected.** Under extraction, A is lowest in the best-governed corner + (0.29 versus 0.36 at baseline), because better-governed organisms grow + larger, and extraction scales with K_Ω. Organism governance and attention + protection have to go together. +5. **Organism governance alone does not reach the generative regime.** On the + baseline background, the best organism corner (VFAC 0.560) closes about 70 % + of the gap to the full generative regime (0.672). The discovery channel + stays at about 0.6, because it depends on discovery concentration, which + is not an organism lever. + ## Reproduce ```bash python3 -B -m unittest discover -s simulations/gadm02 cd simulations/gadm02 && python3 -B power_channels.py # T03 stage (wealth off) cd simulations/gadm02 && python3 -B wealth.py # T04: P3 and scenarios +cd simulations/gadm02 && python3 -B organism_grid.py # T05: 2 × 2 × 2 organism grid ``` diff --git a/models/README.md b/models/README.md index 0aaf570..0e7657d 100644 --- a/models/README.md +++ b/models/README.md @@ -11,7 +11,7 @@ exploratory: they generate hypotheses and are not established results. | [InformationOrganismsInGADM.md](InformationOrganismsInGADM.md) | mapping note v0.1 | ASSEMBLY-WP-0003-T03; input for GADM-0.2 (ASSEMBLY-WP-0004) | | [GADM-CLD.md](GADM-CLD.md) | v0.1 | causal-loop diagram, loops, signed link table (ASSEMBLY-WP-0004-T01/T02) | | [GADM-0.2.md](GADM-0.2.md) | GADM-0.2 | extensions decision, equations, scenario and sensitivity findings (ASSEMBLY-WP-0004) | -| [GADM-0.3.md](GADM-0.3.md) | in progress | power channels (P1/P2) and wealth separated from power (P3) (ASSEMBLY-WP-0005-T03/T04) | +| [GADM-0.3.md](GADM-0.3.md) | in progress | power channels (P1/P2) wealth separated from power (P3), attention recalibration and organism grid (ASSEMBLY-WP-0005-T03–T05) | | [GADM-0.3-Candidates.md](GADM-0.3-Candidates.md) | outline | life-cycle and power extensions, deferred items (ASSEMBLY-WP-0004-T08) | ## Conventions diff --git a/simulations/README.md b/simulations/README.md index 3a9115a..82cdde1 100644 --- a/simulations/README.md +++ b/simulations/README.md @@ -6,7 +6,7 @@ model version it implements. | Directory | Model | Entry points | |-----------|-------|--------------| | `gadm02/` | GADM-0.2 (`models/GADM-0.2.md`) | `run_scenarios.py`, `sensitivity.py`, `gsa.py`, `test_gadm02.py` | -| `gadm02/gadm03.py` | GADM-0.3: power channels, wealth (`models/GADM-0.3.md`) | `power_channels.py`, `wealth.py`, `test_gadm03.py` | +| `gadm02/gadm03.py` | GADM-0.3: power channels, wealth (`models/GADM-0.3.md`) | `power_channels.py`, `wealth.py`, `organism_grid.py`, `test_gadm03.py` | Python 3.10+, standard library only. Use `python3 -B` after quick edits: a stale bytecode cache can mask same-size changes made within the same second. diff --git a/simulations/gadm02/gadm03.py b/simulations/gadm02/gadm03.py index 89bd91c..34945c8 100644 --- a/simulations/gadm02/gadm03.py +++ b/simulations/gadm02/gadm03.py @@ -59,6 +59,10 @@ PARAMS.update({ "t_w": 0.10, # wealth-tax effectiveness "wtax": 0.20, # wealth-tax lever (0..1) "k_w": 0.04, # wealth → market/political control conversion + # attention extraction recalibrated against time-use evidence (T05): + # GADM-0.2's 0.12 let baseline attention headroom rise to 0.65; 0.275 keeps + # it near 0.45 (engagement media already take ~half of leisure time). + "aext": 0.275, # counter coefficients: calibrated, see calibrate() "c_m": 0.0794, "c_i": 0.3117, "c_d": 0.2815, "c_mem": 0.1354, "c_lin": 0.1372, "c_pol": 0.4011, }) @@ -134,7 +138,12 @@ def calibrate(params: dict | None = None, init: dict | None = None) -> dict: def t03_params() -> dict: """Parameter overrides that reproduce the T03 power-channel model (no wealth).""" - return {"wealth_on": 0.0, **calibrate({"wealth_on": 0.0})} + return {"wealth_on": 0.0, "aext": g2.PARAMS["aext"], **calibrate({"wealth_on": 0.0})} + + +def t04_params() -> dict: + """Parameter overrides that reproduce the T04 stage (wealth, old attention).""" + return {"aext": g2.PARAMS["aext"]} def simulate(params: dict | None = None, init: dict | None = None, diff --git a/simulations/gadm02/organism_grid.py b/simulations/gadm02/organism_grid.py new file mode 100644 index 0000000..59b8dcb --- /dev/null +++ b/simulations/gadm02/organism_grid.py @@ -0,0 +1,81 @@ +"""Full 2 x 2 x 2 organism scenario grid (InformationOrganismsInGADM.md § 5). + +Axes: lineage ownership (concentrated / diffuse), membrane control (operator / +user-community), attention regime (extraction / protected). Each corner is run +on two backgrounds (baseline and generative regime), and analysed as a 2^3 +factorial design: main effects and interactions on final VFAC and P. + +Usage: python3 -B simulations/gadm02/organism_grid.py +""" + +from __future__ import annotations + +import itertools +import sys +from pathlib import Path + +sys.dont_write_bytecode = True + +import gadm03 as g # noqa: E402 +from scenarios import load_all # noqa: E402 + +OUT = Path(__file__).resolve().parent / "results" +AXES = { + "lineage": ({"L": 0.1, "lin_open": 0.1}, {"L": 0.8, "lin_open": 0.8}), # concentrated / diffuse + "membrane": ({"m": 0.2}, {"m": 0.8}), # operator / user + "attention": ({"x_att": 0.9}, {"x_att": 0.2}), # extraction / protected +} +LABELS = {"lineage": ("concentrated", "diffuse"), "membrane": ("operator", "user"), + "attention": ("extraction", "protected")} + + +def effects(results: dict, key: str) -> list[tuple[str, float]]: + """2^3 factorial effects (high minus low level, averaged) for output `key`.""" + names = list(AXES) + out = [] + for r in range(1, 4): + for combo in itertools.combinations(range(3), r): + total = 0.0 + for levels, res in results.items(): + sign = 1 + for i in combo: + sign *= 1 if levels[i] == 1 else -1 + total += sign * res[key] + out.append((" × ".join(names[i] for i in combo), total / 4)) + return out + + +def main() -> None: + OUT.mkdir(exist_ok=True) + scs = load_all() + lines = [f"# {g.MODEL_VERSION}: 2 × 2 × 2 organism grid", "", + "Generated by `simulations/gadm02/organism_grid.py`. Full GADM-0.3 (power", + "channels, wealth, recalibrated attention). Final values at t = 100 years.", + "Effects: average change from the first to the second level (diffuse,", + "user-controlled, protected); interactions in the standard 2^k sense.", ""] + for bg in ("baseline", "generative_regime"): + sc = scs[bg] + results = {} + lines += [f"## Background: {sc['title']}", "", + "| Lineage | Membrane | Attention | VFAC | P | A | membrane ch. | lineage ch. | discovery ch. |", + "|---|---|---|---|---|---|---|---|---|"] + for levels in itertools.product((0, 1), repeat=3): + params = dict(sc["params"]) + for axis, lv in zip(AXES, levels): + params.update(AXES[axis][lv]) + r = g.simulate(params, sc["init"])[-1] + results[levels] = r + lab = [LABELS[a][lv] for a, lv in zip(AXES, levels)] + lines.append(f"| {lab[0]} | {lab[1]} | {lab[2]} | {r['VFAC']:.3f} | {r['P']:.2f} | {r['A']:.2f} | " + f"{r['Pmem']:.2f} | {r['Plin']:.2f} | {r['Pd']:.2f} |") + lines += ["", "| Effect | on VFAC | on P |", "|---|---|---|"] + ev, ep = effects(results, "VFAC"), dict(effects(results, "P")) + for name, v in sorted(ev, key=lambda t: -abs(t[1])): + lines.append(f"| {name} | {v:+.3f} | {ep[name]:+.3f} |") + lines.append("") + (OUT / "organism_grid.md").write_text("\n".join(lines) + "\n") + print("\n".join(lines)) + + +if __name__ == "__main__": + main() diff --git a/simulations/gadm02/results/organism_grid.md b/simulations/gadm02/results/organism_grid.md new file mode 100644 index 0000000..530cf7f --- /dev/null +++ b/simulations/gadm02/results/organism_grid.md @@ -0,0 +1,53 @@ +# GADM-0.3-power: 2 × 2 × 2 organism grid + +Generated by `simulations/gadm02/organism_grid.py`. Full GADM-0.3 (power +channels, wealth, recalibrated attention). Final values at t = 100 years. +Effects: average change from the first to the second level (diffuse, +user-controlled, protected); interactions in the standard 2^k sense. + +## Background: Baseline (current trends) + +| Lineage | Membrane | Attention | VFAC | P | A | membrane ch. | lineage ch. | discovery ch. | +|---|---|---|---|---|---|---|---|---| +| concentrated | operator | extraction | 0.291 | 0.82 | 0.36 | 0.85 | 0.93 | 0.70 | +| concentrated | operator | protected | 0.322 | 0.82 | 0.71 | 0.85 | 0.93 | 0.70 | +| concentrated | user | extraction | 0.338 | 0.74 | 0.35 | 0.04 | 0.93 | 0.69 | +| concentrated | user | protected | 0.376 | 0.74 | 0.70 | 0.04 | 0.93 | 0.68 | +| diffuse | operator | extraction | 0.372 | 0.68 | 0.34 | 0.85 | 0.04 | 0.66 | +| diffuse | operator | protected | 0.422 | 0.67 | 0.68 | 0.86 | 0.05 | 0.66 | +| diffuse | user | extraction | 0.495 | 0.41 | 0.29 | 0.06 | 0.06 | 0.60 | +| diffuse | user | protected | 0.560 | 0.40 | 0.64 | 0.06 | 0.06 | 0.62 | + +| Effect | on VFAC | on P | +|---|---|---| +| lineage | +0.130 | -0.242 | +| membrane | +0.090 | -0.175 | +| attention | +0.046 | -0.009 | +| lineage × membrane | +0.040 | -0.093 | +| lineage × attention | +0.011 | -0.006 | +| membrane × attention | +0.005 | -0.001 | +| lineage × membrane × attention | +0.002 | -0.000 | + +## Background: Generative regime + +| Lineage | Membrane | Attention | VFAC | P | A | membrane ch. | lineage ch. | discovery ch. | +|---|---|---|---|---|---|---|---|---| +| concentrated | operator | extraction | 0.395 | 0.68 | 0.28 | 0.86 | 0.95 | 0.08 | +| concentrated | operator | protected | 0.447 | 0.67 | 0.63 | 0.86 | 0.95 | 0.08 | +| concentrated | user | extraction | 0.486 | 0.49 | 0.27 | 0.08 | 0.95 | 0.07 | +| concentrated | user | protected | 0.544 | 0.50 | 0.62 | 0.08 | 0.95 | 0.08 | +| diffuse | operator | extraction | 0.522 | 0.37 | 0.26 | 0.86 | 0.12 | 0.07 | +| diffuse | operator | protected | 0.584 | 0.37 | 0.61 | 0.87 | 0.12 | 0.08 | +| diffuse | user | extraction | 0.602 | 0.12 | 0.25 | 0.09 | 0.13 | 0.08 | +| diffuse | user | protected | 0.672 | 0.13 | 0.60 | 0.09 | 0.14 | 0.08 | + +| Effect | on VFAC | on P | +|---|---|---| +| lineage | +0.127 | -0.340 | +| membrane | +0.089 | -0.216 | +| attention | +0.060 | +0.002 | +| lineage × attention | +0.006 | +0.005 | +| lineage × membrane | -0.005 | -0.032 | +| membrane × attention | +0.004 | +0.004 | +| lineage × membrane × attention | +0.001 | -0.002 | + diff --git a/simulations/gadm02/results/wealth.md b/simulations/gadm02/results/wealth.md index a658826..4507090 100644 --- a/simulations/gadm02/results/wealth.md +++ b/simulations/gadm02/results/wealth.md @@ -1,6 +1,7 @@ # GADM-0.3-power + wealth: hypothesis P3 and scenarios -Generated by `simulations/gadm02/wealth.py`. Full GADM-0.3 (wealth_on = 1). +Generated by `simulations/gadm02/wealth.py`. T04 stage of GADM-0.3 (wealth on, +GADM-0.2 attention extraction). Final values at t = 100 years. ## P3: wealth tax sweep diff --git a/simulations/gadm02/wealth.py b/simulations/gadm02/wealth.py index b998196..0342f4a 100644 --- a/simulations/gadm02/wealth.py +++ b/simulations/gadm02/wealth.py @@ -4,6 +4,9 @@ P3: wealth taxation alone does not bound domination P when the membrane channel dominates. Test: sweep the wealth-tax lever wtax in [0, 1] in three settings and compare wealth W with the channels it can and cannot reach. +Runs the T04 stage (gadm03.t04_params(): attention extraction as in GADM-0.2) +so the results in models/GADM-0.3.md § 3 stay reproducible after T05. + Usage: python3 -B simulations/gadm02/wealth.py """ @@ -30,7 +33,8 @@ def main() -> None: OUT.mkdir(exist_ok=True) scs = load_all() lines = [f"# {g.MODEL_VERSION} + wealth: hypothesis P3 and scenarios", "", - "Generated by `simulations/gadm02/wealth.py`. Full GADM-0.3 (wealth_on = 1).", + "Generated by `simulations/gadm02/wealth.py`. T04 stage of GADM-0.3 (wealth on,", + "GADM-0.2 attention extraction).", "Final values at t = 100 years.", "", "## P3: wealth tax sweep", ""] for name, title in CASES: @@ -39,7 +43,7 @@ def main() -> None: "| wtax | W | market | political | membrane | lineage | P | VFAC |", "|---|---|---|---|---|---|---|---|"] for t in TAX: - r = g.simulate({**sc["params"], "wtax": t}, sc["init"])[-1] + r = g.simulate({**sc["params"], **g.t04_params(), "wtax": t}, sc["init"])[-1] lines.append(f"| {t:.2f} | {r['W']:.2f} | {r['Pm']:.2f} | {r['Ppol']:.2f} | " f"{r['Pmem']:.2f} | {r['Plin']:.2f} | {r['P']:.2f} | {r['VFAC']:.3f} |") lines.append("") @@ -48,7 +52,7 @@ def main() -> None: "|---|---|---|---|---|---|---|---|"] for name, sc in scs.items(): a = g.simulate({**sc["params"], **g.t03_params()}, sc["init"])[-1] - b = g.simulate(sc["params"], sc["init"])[-1] + b = g.simulate({**sc["params"], **g.t04_params()}, sc["init"])[-1] lines.append(f"| {sc['title']} | {a['P']:.2f} | {b['P']:.2f} | {b['W']:.2f} | {b['Pm']:.2f} | " f"{b['Ppol']:.2f} | {a['VFAC']:.3f} | {b['VFAC']:.3f} |") (OUT / "wealth.md").write_text("\n".join(lines) + "\n") diff --git a/workplans/ASSEMBLY-WP-0005-gadm-0.3.md b/workplans/ASSEMBLY-WP-0005-gadm-0.3.md index df54be5..fd9473e 100644 --- a/workplans/ASSEMBLY-WP-0005-gadm-0.3.md +++ b/workplans/ASSEMBLY-WP-0005-gadm-0.3.md @@ -77,7 +77,7 @@ with a check-dependent conversion into P. Test hypothesis P3. ```task id: ASSEMBLY-WP-0005-T05 -status: todo +status: done priority: medium state_hub_task_id: "f56e20b4-33b5-5a6e-9e4c-fca63f99bbe1" ```