Manuscript revision and pending experiment work, snapshot before restructuring

Clarity pass over the main text (36-item audit), Discussion rewrite and cut,
acknowledgements, Souly et al. as ref 62, lettered SI panels, model section
moved under Results; plus the untracked curriculum/society/compose/smol
configs, runners, figures, stats and tests that the SI already cites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y64o8FKP7rCuXzC48pxpMm
This commit is contained in:
Giorgio Gilestro 2026-09-13 16:54:09 +01:00
parent e4804adabc
commit 84124de143
450 changed files with 52813 additions and 1202 deletions

View file

@ -0,0 +1,69 @@
"""Conflict-arrival curricula (SI figure): does the declinable merge's decline rate, and the obligate
merge's collapse, follow the generation at which conflicting conventions arrive?
Left: fraction of proposed merges declined per generation (mean over seeds, 95% CI) for each
curriculum; a filled marker on the curve marks the first generation at which both conflicting
families (boolq, winogrande) are present in every lineage. Right: best-lineage all-families accuracy
of the OBLIGATE society arm per curriculum, same marker. Curricula: Latin square (conflict from
generation 5), decorrelated (from 4), conflict-early (from 2), conflict-late (from 6).
Reads the committed curriculum bundles through stats_llm_curriculum (no re-simulation).
Usage: python figures/plot_curriculum_timing.py [out_dir=results/llm_curriculum_v5_early]
"""
from __future__ import annotations
import sys
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
sys.path.insert(0, str(Path(__file__).parent))
from _figlib import mean_ci, savefig, letter_axes # noqa: E402
from stats_llm_curriculum import CONFLICT_FROM, best_lineage, decline_table, load_curriculum # noqa: E402
STYLE = {"latin": ("#7f7f7f", "Latin square"), "decor": ("#2c7fb8", "decorrelated"),
"early": ("#d62728", "conflict-early"), "late": ("#2ca02c", "conflict-late")}
OBLIGATE = {"latin": "society", "early": "early_society", "late": "late_society"}
def main(out_dir: str = "results/llm_curriculum_v5_early") -> None:
df = load_curriculum()
tab = decline_table(df)
best = best_lineage(df)
fig, (a1, a2) = plt.subplots(1, 2, figsize=(10, 3.8))
for cur, (color, label) in STYLE.items():
sub = tab[tab["curriculum"] == cur]
if len(sub):
x, m, h = mean_ci(sub, "generation", "declined")
a1.errorbar(x + 1, m, yerr=np.nan_to_num(h), fmt="-o", color=color, capsize=3, label=label,
markerfacecolor="white")
g0 = CONFLICT_FROM[cur]
if g0 in set(x):
a1.plot(g0 + 1, m[list(x).index(g0)], "o", color=color, ms=12, markeredgecolor="black", markeredgewidth=1.2)
arm = OBLIGATE.get(cur)
ob = best[(best["curriculum"] == cur) & (best["arm"] == arm)] if arm else best.iloc[0:0]
if len(ob):
x, m, h = mean_ci(ob, "generation", "value")
a2.errorbar(x + 1, m, yerr=np.nan_to_num(h), fmt="-o", color=color, capsize=3, label=label,
markerfacecolor="white")
g0 = CONFLICT_FROM[cur]
if g0 in set(x):
a2.plot(g0 + 1, m[list(x).index(g0)], "o", color=color, ms=12, markeredgecolor="black", markeredgewidth=1.2)
a1.set(xlabel="generation", ylabel="fraction of merges declined", ylim=(-0.02, 1.05),
title="declinable merge: decline rate")
a2.set(xlabel="generation", ylabel="best-lineage accuracy, all families", ylim=(0.1, 0.9),
title="obligate merge: accuracy")
a1.plot([], [], "o", color="white", ms=10, markeredgecolor="black", markeredgewidth=1.2,
label="first generation with both\nconflicting conventions")
a1.legend(frameon=False, fontsize=8); a2.legend(frameon=False, fontsize=8)
for a in (a1, a2):
a.set_xticks(range(1, 7))
fig.tight_layout()
letter_axes(fig)
savefig(fig, out_dir, "curriculum_timing")
if __name__ == "__main__":
main(*sys.argv[1:])