imagining syntax

Text set in serif type with a dotted bar in the margin was drafted by an LLM (claude-fable-5) and sometimes reviewed by the author. The rest is the author's own. How to read this site

mirror_v1

20260716_133911_mirror_v1 · complete · published 2026-07-17 · seed 42

Intent

This experiment tests directly whether the direction of an α schedule matters in itself. Each mirror pair runs the same α values for the same number of steps with the same seeds, once descending and once ascending; each segment (stage) draws its training pool fresh at its own α, so direction is the only systematic difference.

The grid covers every pair of integer endpoints from 0 to 5 in two shapes: the smooth 24-stage linear ramp of slopesweep_v1, and a jagged ladder with one rung per integer between the endpoints, so an adjacent pair degenerates to a single abrupt switch. Flat arms at each grid value calibrate what no direction looks like. All arms use the with replacement data setting. Design: the mirror_v1 spec.

Background

Background: The build-and-erode account \@{mirror-background}

Every curriculum result so far points one way: a schedule that starts at high pairing concentration and moves toward low concentration builds the agreement rule, and time spent at low α erodes it, the build-and-erode account assembled by curriculum_v1 and burst_v1.

The descending arms to 0 of slopesweep_v1 collapse by the end of training, finals between 19.0 and 32.1 from every start. The collapsing arms of slopesweep_v1 showed seed bimodality, its s5_e0 finishing at 32.1 ±27.4 with seeds spanning 0.4 to 85.3.

Hypothesis

Hypothesis: Descent beats ascent at peak and final \@{mirror-hypothesis}

For symmetric shapes, the higher-to-lower direction always wins on unseen_mismatch: in every mirror pair, in both shape families, the descending arm's cohort mean beats the ascending arm's at its peak waypoint and at the end of training, with a 95% bootstrap interval on the difference that excludes zero. Spread is a separate competition: the descending arm is expected to be no less consistent, its peak standard deviation at most the ascending arm's.

The exposed flank is the pairs ending at 0: an ascending mirror finishes its training at high α with a freshly built rule. If ascent wins there at final, the operative variable is the final α, not the direction.

Setup

model
GPT (nanoGPT-derived), weight-tied embeddings — 2 layers × 4 heads × 256 dim (~1,635,584 params) · block 50 · dropout 0.1 · vocab 167 tokens
training
AdamW (β 0.9/0.95, wd 0.1) · lr 0.0006 constant (no warmup, no decay) · batch 32 · 1200 iterations · fresh init per replicate (seeds derived from base seed) · 10 seeds (base 42)
training data
PCFG, zipfian noun–verb pairing (oneshot where noted) · 12,000 sentences per dataset (9,600 train — 1 epoch = 300 iters) · unseen holdout 10
code
commit ae5f77126dc8
armdata regimedatasetsiters/datasetepochs/dataset
s0_e0fresh-dataset-per-stage 24 50 0.04
s0_e1fresh-dataset-per-stage 24 50 0.04
s0_e1_blkfresh-dataset-per-stage 2 600 0.5
s0_e2fresh-dataset-per-stage 24 50 0.04
s0_e2_blkfresh-dataset-per-stage 3 400 0.33
s0_e3fresh-dataset-per-stage 24 50 0.04
s0_e3_blkfresh-dataset-per-stage 4 300 0.25
s0_e4fresh-dataset-per-stage 24 50 0.04
s0_e4_blkfresh-dataset-per-stage 5 240 0.2
s0_e5fresh-dataset-per-stage 24 50 0.04
s0_e5_blkfresh-dataset-per-stage 6 200 0.17
s1_e0fresh-dataset-per-stage 24 50 0.04
s1_e0_blkfresh-dataset-per-stage 2 600 0.5
s1_e1fresh-dataset-per-stage 24 50 0.04
s1_e2fresh-dataset-per-stage 24 50 0.04
s1_e2_blkfresh-dataset-per-stage 2 600 0.5
s1_e3fresh-dataset-per-stage 24 50 0.04
s1_e3_blkfresh-dataset-per-stage 3 400 0.33
s1_e4fresh-dataset-per-stage 24 50 0.04
s1_e4_blkfresh-dataset-per-stage 4 300 0.25
s1_e5fresh-dataset-per-stage 24 50 0.04
s1_e5_blkfresh-dataset-per-stage 5 240 0.2
s2_e0fresh-dataset-per-stage 24 50 0.04
s2_e0_blkfresh-dataset-per-stage 3 400 0.33
s2_e1fresh-dataset-per-stage 24 50 0.04
s2_e1_blkfresh-dataset-per-stage 2 600 0.5
s2_e2fresh-dataset-per-stage 24 50 0.04
s2_e3fresh-dataset-per-stage 24 50 0.04
s2_e3_blkfresh-dataset-per-stage 2 600 0.5
s2_e4fresh-dataset-per-stage 24 50 0.04
s2_e4_blkfresh-dataset-per-stage 3 400 0.33
s2_e5fresh-dataset-per-stage 24 50 0.04
s2_e5_blkfresh-dataset-per-stage 4 300 0.25
s3_e0fresh-dataset-per-stage 24 50 0.04
s3_e0_blkfresh-dataset-per-stage 4 300 0.25
s3_e1fresh-dataset-per-stage 24 50 0.04
s3_e1_blkfresh-dataset-per-stage 3 400 0.33
s3_e2fresh-dataset-per-stage 24 50 0.04
s3_e2_blkfresh-dataset-per-stage 2 600 0.5
s3_e3fresh-dataset-per-stage 24 50 0.04
s3_e4fresh-dataset-per-stage 24 50 0.04
s3_e4_blkfresh-dataset-per-stage 2 600 0.5
s3_e5fresh-dataset-per-stage 24 50 0.04
s3_e5_blkfresh-dataset-per-stage 3 400 0.33
s4_e0fresh-dataset-per-stage 24 50 0.04
s4_e0_blkfresh-dataset-per-stage 5 240 0.2
s4_e1fresh-dataset-per-stage 24 50 0.04
s4_e1_blkfresh-dataset-per-stage 4 300 0.25
s4_e2fresh-dataset-per-stage 24 50 0.04
s4_e2_blkfresh-dataset-per-stage 3 400 0.33
s4_e3fresh-dataset-per-stage 24 50 0.04
s4_e3_blkfresh-dataset-per-stage 2 600 0.5
s4_e4fresh-dataset-per-stage 24 50 0.04
s4_e5fresh-dataset-per-stage 24 50 0.04
s4_e5_blkfresh-dataset-per-stage 2 600 0.5
s5_e0fresh-dataset-per-stage 24 50 0.04
s5_e0_blkfresh-dataset-per-stage 6 200 0.17
s5_e1fresh-dataset-per-stage 24 50 0.04
s5_e1_blkfresh-dataset-per-stage 5 240 0.2
s5_e2fresh-dataset-per-stage 24 50 0.04
s5_e2_blkfresh-dataset-per-stage 4 300 0.25
s5_e3fresh-dataset-per-stage 24 50 0.04
s5_e3_blkfresh-dataset-per-stage 3 400 0.33
s5_e4fresh-dataset-per-stage 24 50 0.04
s5_e4_blkfresh-dataset-per-stage 2 600 0.5
s5_e5fresh-dataset-per-stage 24 50 0.04

Replicate this experiment

Get the code at this exact version:

git clone https://github.com/ClaireHobbs/imagining-syntax
cd imagining-syntax
git checkout ae5f77126dc8
pip install -e ".[dev]"

Download the config (experiment.yaml) and run:

imsyn exp run experiment.yaml

Checks

PASS children_complete PASS replicate_coverage PASS schedule_total_matches_final_waypoint PASS instrument_consistent

Claims

claimsourceexpectationΔseedsverdict
lin_1to0_mean_final manifest s1_e0 > s0_e1 on unseen_mismatch @ final -7.0 mixed 95% CI on delta [-23.6, +10.8] straddles 0
lin_1to0_mean_peak manifest s1_e0 > s0_e1 on unseen_mismatch @ peak +0.5 mixed 95% CI on delta [-0.5, +1.5] straddles 0
lin_1to0_sd_peak manifest s1_e0 <= s0_e1 on unseen_mismatch (sd) @ peak +0.1 rejected mean-only (no per-seed vectors)
lin_2to0_mean_final manifest s2_e0 > s0_e2 on unseen_mismatch @ final -70.2 rejected
lin_2to0_mean_peak manifest s2_e0 > s0_e2 on unseen_mismatch @ peak +7.1 held
lin_2to0_sd_peak manifest s2_e0 <= s0_e2 on unseen_mismatch (sd) @ peak -7.8 held mean-only (no per-seed vectors)
lin_2to1_mean_final manifest s2_e1 > s1_e2 on unseen_mismatch @ final +3.3 held
lin_2to1_mean_peak manifest s2_e1 > s1_e2 on unseen_mismatch @ peak -2.4 rejected
lin_2to1_sd_peak manifest s2_e1 <= s1_e2 on unseen_mismatch (sd) @ peak +1.2 rejected mean-only (no per-seed vectors)
lin_3to0_mean_final manifest s3_e0 > s0_e3 on unseen_mismatch @ final -65.0 rejected
lin_3to0_mean_peak manifest s3_e0 > s0_e3 on unseen_mismatch @ peak +5.6 mixed 95% CI on delta [-2.5, +16.3] straddles 0
lin_3to0_sd_peak manifest s3_e0 <= s0_e3 on unseen_mismatch (sd) @ peak -9.1 held mean-only (no per-seed vectors)
lin_3to1_mean_final manifest s3_e1 > s1_e3 on unseen_mismatch @ final +19.0 held
lin_3to1_mean_peak manifest s3_e1 > s1_e3 on unseen_mismatch @ peak -1.6 mixed 95% CI on delta [-5.7, +2.5] straddles 0
lin_3to1_sd_peak manifest s3_e1 <= s1_e3 on unseen_mismatch (sd) @ peak -0.4 held mean-only (no per-seed vectors)
lin_3to2_mean_final manifest s3_e2 > s2_e3 on unseen_mismatch @ final +8.5 held
lin_3to2_mean_peak manifest s3_e2 > s2_e3 on unseen_mismatch @ peak -5.6 rejected
lin_3to2_sd_peak manifest s3_e2 <= s2_e3 on unseen_mismatch (sd) @ peak -1.5 held mean-only (no per-seed vectors)
lin_4to0_mean_final manifest s4_e0 > s0_e4 on unseen_mismatch @ final -49.2 rejected
lin_4to0_mean_peak manifest s4_e0 > s0_e4 on unseen_mismatch @ peak +2.7 mixed 95% CI on delta [-3.4, +10.9] straddles 0
lin_4to0_sd_peak manifest s4_e0 <= s0_e4 on unseen_mismatch (sd) @ peak -7.2 held mean-only (no per-seed vectors)
lin_4to1_mean_final manifest s4_e1 > s1_e4 on unseen_mismatch @ final +21.5 held
lin_4to1_mean_peak manifest s4_e1 > s1_e4 on unseen_mismatch @ peak -5.0 rejected
lin_4to1_sd_peak manifest s4_e1 <= s1_e4 on unseen_mismatch (sd) @ peak +3.0 rejected mean-only (no per-seed vectors)
lin_4to2_mean_final manifest s4_e2 > s2_e4 on unseen_mismatch @ final +10.2 held
lin_4to2_mean_peak manifest s4_e2 > s2_e4 on unseen_mismatch @ peak -6.5 rejected
lin_4to2_sd_peak manifest s4_e2 <= s2_e4 on unseen_mismatch (sd) @ peak -0.6 held mean-only (no per-seed vectors)
lin_4to3_mean_final manifest s4_e3 > s3_e4 on unseen_mismatch @ final +2.5 mixed 95% CI on delta [-2.6, +8.0] straddles 0
lin_4to3_mean_peak manifest s4_e3 > s3_e4 on unseen_mismatch @ peak +3.0 mixed 95% CI on delta [-2.1, +8.0] straddles 0
lin_4to3_sd_peak manifest s4_e3 <= s3_e4 on unseen_mismatch (sd) @ peak -1.5 held mean-only (no per-seed vectors)
lin_5to0_mean_final manifest s5_e0 > s0_e5 on unseen_mismatch @ final -43.5 rejected
lin_5to0_mean_peak manifest s5_e0 > s0_e5 on unseen_mismatch @ peak +10.3 held
lin_5to0_sd_peak manifest s5_e0 <= s0_e5 on unseen_mismatch (sd) @ peak +3.5 rejected mean-only (no per-seed vectors)
lin_5to1_mean_final manifest s5_e1 > s1_e5 on unseen_mismatch @ final +26.9 held
lin_5to1_mean_peak manifest s5_e1 > s1_e5 on unseen_mismatch @ peak -1.6 mixed 95% CI on delta [-5.6, +1.9] straddles 0
lin_5to1_sd_peak manifest s5_e1 <= s1_e5 on unseen_mismatch (sd) @ peak +1.6 rejected mean-only (no per-seed vectors)
lin_5to2_mean_final manifest s5_e2 > s2_e5 on unseen_mismatch @ final +13.4 held
lin_5to2_mean_peak manifest s5_e2 > s2_e5 on unseen_mismatch @ peak -5.9 mixed 95% CI on delta [-12.3, +0.9] straddles 0
lin_5to2_sd_peak manifest s5_e2 <= s2_e5 on unseen_mismatch (sd) @ peak -1.5 held mean-only (no per-seed vectors)
lin_5to3_mean_final manifest s5_e3 > s3_e5 on unseen_mismatch @ final +3.8 held
lin_5to3_mean_peak manifest s5_e3 > s3_e5 on unseen_mismatch @ peak +1.7 mixed 95% CI on delta [-2.9, +6.1] straddles 0
lin_5to3_sd_peak manifest s5_e3 <= s3_e5 on unseen_mismatch (sd) @ peak +1.3 rejected mean-only (no per-seed vectors)
lin_5to4_mean_final manifest s5_e4 > s4_e5 on unseen_mismatch @ final +1.0 mixed 95% CI on delta [-2.4, +4.3] straddles 0
lin_5to4_mean_peak manifest s5_e4 > s4_e5 on unseen_mismatch @ peak +0.6 mixed 95% CI on delta [-4.0, +4.9] straddles 0
lin_5to4_sd_peak manifest s5_e4 <= s4_e5 on unseen_mismatch (sd) @ peak +0.2 rejected mean-only (no per-seed vectors)
blk_1to0_mean_final manifest s1_e0_blk > s0_e1_blk on unseen_mismatch @ final -47.7 rejected
blk_1to0_mean_peak manifest s1_e0_blk > s0_e1_blk on unseen_mismatch @ peak -23.5 rejected
blk_1to0_sd_peak manifest s1_e0_blk <= s0_e1_blk on unseen_mismatch (sd) @ peak +11.5 rejected mean-only (no per-seed vectors)
blk_2to0_mean_final manifest s2_e0_blk > s0_e2_blk on unseen_mismatch @ final -72.7 rejected
blk_2to0_mean_peak manifest s2_e0_blk > s0_e2_blk on unseen_mismatch @ peak +1.5 held
blk_2to0_sd_peak manifest s2_e0_blk <= s0_e2_blk on unseen_mismatch (sd) @ peak -1.3 held mean-only (no per-seed vectors)
blk_2to1_mean_final manifest s2_e1_blk > s1_e2_blk on unseen_mismatch @ final +1.9 mixed 95% CI on delta [-2.3, +5.8] straddles 0
blk_2to1_mean_peak manifest s2_e1_blk > s1_e2_blk on unseen_mismatch @ peak -0.4 mixed 95% CI on delta [-2.1, +1.3] straddles 0
blk_2to1_sd_peak manifest s2_e1_blk <= s1_e2_blk on unseen_mismatch (sd) @ peak -0.2 held mean-only (no per-seed vectors)
blk_3to0_mean_final manifest s3_e0_blk > s0_e3_blk on unseen_mismatch @ final -65.7 rejected
blk_3to0_mean_peak manifest s3_e0_blk > s0_e3_blk on unseen_mismatch @ peak +0.2 mixed 95% CI on delta [-5.3, +6.4] straddles 0
blk_3to0_sd_peak manifest s3_e0_blk <= s0_e3_blk on unseen_mismatch (sd) @ peak -4.3 held mean-only (no per-seed vectors)
blk_3to1_mean_final manifest s3_e1_blk > s1_e3_blk on unseen_mismatch @ final +5.6 mixed 95% CI on delta [-1.9, +12.7] straddles 0
blk_3to1_mean_peak manifest s3_e1_blk > s1_e3_blk on unseen_mismatch @ peak -0.5 mixed 95% CI on delta [-3.6, +2.1] straddles 0
blk_3to1_sd_peak manifest s3_e1_blk <= s1_e3_blk on unseen_mismatch (sd) @ peak +1.5 rejected mean-only (no per-seed vectors)
blk_3to2_mean_final manifest s3_e2_blk > s2_e3_blk on unseen_mismatch @ final +4.9 mixed 95% CI on delta [-2.1, +10.8] straddles 0
blk_3to2_mean_peak manifest s3_e2_blk > s2_e3_blk on unseen_mismatch @ peak -11.4 rejected
blk_3to2_sd_peak manifest s3_e2_blk <= s2_e3_blk on unseen_mismatch (sd) @ peak +4.2 rejected mean-only (no per-seed vectors)
blk_4to0_mean_final manifest s4_e0_blk > s0_e4_blk on unseen_mismatch @ final -53.7 rejected
blk_4to0_mean_peak manifest s4_e0_blk > s0_e4_blk on unseen_mismatch @ peak +7.6 held
blk_4to0_sd_peak manifest s4_e0_blk <= s0_e4_blk on unseen_mismatch (sd) @ peak -10.7 held mean-only (no per-seed vectors)
blk_4to1_mean_final manifest s4_e1_blk > s1_e4_blk on unseen_mismatch @ final +20.7 held
blk_4to1_mean_peak manifest s4_e1_blk > s1_e4_blk on unseen_mismatch @ peak +5.1 mixed 95% CI on delta [-1.3, +12.6] straddles 0
blk_4to1_sd_peak manifest s4_e1_blk <= s1_e4_blk on unseen_mismatch (sd) @ peak -8.9 held mean-only (no per-seed vectors)
blk_4to2_mean_final manifest s4_e2_blk > s2_e4_blk on unseen_mismatch @ final +9.4 held
blk_4to2_mean_peak manifest s4_e2_blk > s2_e4_blk on unseen_mismatch @ peak -12.5 rejected
blk_4to2_sd_peak manifest s4_e2_blk <= s2_e4_blk on unseen_mismatch (sd) @ peak +2.9 rejected mean-only (no per-seed vectors)
blk_4to3_mean_final manifest s4_e3_blk > s3_e4_blk on unseen_mismatch @ final +3.2 mixed 95% CI on delta [-1.4, +7.7] straddles 0
blk_4to3_mean_peak manifest s4_e3_blk > s3_e4_blk on unseen_mismatch @ peak -1.2 mixed 95% CI on delta [-4.5, +1.9] straddles 0
blk_4to3_sd_peak manifest s4_e3_blk <= s3_e4_blk on unseen_mismatch (sd) @ peak +0.0 held mean-only (no per-seed vectors)
blk_5to0_mean_final manifest s5_e0_blk > s0_e5_blk on unseen_mismatch @ final -40.4 rejected
blk_5to0_mean_peak manifest s5_e0_blk > s0_e5_blk on unseen_mismatch @ peak +3.0 mixed 95% CI on delta [-2.2, +9.2] straddles 0
blk_5to0_sd_peak manifest s5_e0_blk <= s0_e5_blk on unseen_mismatch (sd) @ peak -4.8 held mean-only (no per-seed vectors)
blk_5to1_mean_final manifest s5_e1_blk > s1_e5_blk on unseen_mismatch @ final +22.7 held
blk_5to1_mean_peak manifest s5_e1_blk > s1_e5_blk on unseen_mismatch @ peak -0.6 mixed 95% CI on delta [-3.3, +2.1] straddles 0
blk_5to1_sd_peak manifest s5_e1_blk <= s1_e5_blk on unseen_mismatch (sd) @ peak -0.1 held mean-only (no per-seed vectors)
blk_5to2_mean_final manifest s5_e2_blk > s2_e5_blk on unseen_mismatch @ final +10.6 held
blk_5to2_mean_peak manifest s5_e2_blk > s2_e5_blk on unseen_mismatch @ peak -14.2 rejected
blk_5to2_sd_peak manifest s5_e2_blk <= s2_e5_blk on unseen_mismatch (sd) @ peak +5.3 rejected mean-only (no per-seed vectors)
blk_5to3_mean_final manifest s5_e3_blk > s3_e5_blk on unseen_mismatch @ final +4.2 held
blk_5to3_mean_peak manifest s5_e3_blk > s3_e5_blk on unseen_mismatch @ peak -2.1 mixed 95% CI on delta [-6.1, +1.7] straddles 0
blk_5to3_sd_peak manifest s5_e3_blk <= s3_e5_blk on unseen_mismatch (sd) @ peak +1.6 rejected mean-only (no per-seed vectors)
blk_5to4_mean_final manifest s5_e4_blk > s4_e5_blk on unseen_mismatch @ final +1.6 mixed 95% CI on delta [-1.9, +4.8] straddles 0
blk_5to4_mean_peak manifest s5_e4_blk > s4_e5_blk on unseen_mismatch @ peak +0.0 mixed 95% CI on delta [-3.7, +3.5] straddles 0
blk_5to4_sd_peak manifest s5_e4_blk <= s4_e5_blk on unseen_mismatch (sd) @ peak -0.9 held mean-only (no per-seed vectors)

Results — unseen_mismatch (mean ± sd over 10 seeds)

Evaluation data: seen_* probed at reference α = 1.4 · unseen_* = held-out pairings, uniform (α-independent) · 1000 pairs per condition
armend of training (t = 1200)per-seedflags
s0_e0 26.1 ±30.2 ⚠ seed_split: range 0.0-96.8 (3 low / 1 high of 10)
s0_e1 21.4 ±20.9 ⚠ seed_split: range 0.0-52.5 (5 low / 2 high of 10)
s0_e1_blk 83.0 ±20.2 ⚠ seed_split: range 43.6-100.0 (2 low / 6 high of 10)
s0_e2 90.0 ±11.2 ⚠ seed_split: range 59.5-100.0 (1 low / 7 high of 10)
s0_e2_blk 94.1 ±3.9
s0_e3 79.8 ±7.2
s0_e3_blk 81.4 ±4.6
s0_e4 70.9 ±3.7
s0_e4_blk 72.4 ±4.0
s0_e5 68.7 ±3.5
s0_e5_blk 66.3 ±2.7
s1_e0 14.4 ±17.9 ⚠ seed_split: range 0.0-51.1 (5 low / 2 high of 10)
s1_e0_blk 35.3 ±30.1 ⚠ seed_split: range 0.0-96.9 (3 low / 1 high of 10)
s1_e1 85.6 ±22.1 ⚠ seed_split: range 25.0-100.0 (1 low / 6 high of 10)
s1_e2 90.8 ±3.4
s1_e2_blk 89.1 ±3.7
s1_e3 75.1 ±3.5
s1_e3_blk 77.7 ±3.4
s1_e4 70.1 ±4.3
s1_e4_blk 68.9 ±2.7
s1_e5 64.3 ±2.2
s1_e5_blk 67.1 ±2.9
s2_e0 19.8 ±11.9
s2_e0_blk 21.4 ±15.8 ⚠ seed_split: range 1.2-48.4 (3 low / 2 high of 10)
s2_e1 94.1 ±3.3
s2_e1_blk 91.0 ±5.4
s2_e2 84.3 ±4.7
s2_e3 76.2 ±4.3
s2_e3_blk 78.4 ±4.9
s2_e4 73.3 ±5.0
s2_e4_blk 73.8 ±4.4
s2_e5 69.8 ±3.8
s2_e5_blk 71.7 ±3.6
s3_e0 14.8 ±7.7
s3_e0_blk 15.7 ±10.6
s3_e1 94.1 ±4.5
s3_e1_blk 83.3 ±11.5 ⚠ seed_split: range 58.8-99.0 (1 low / 4 high of 10)
s3_e2 84.7 ±5.7
s3_e2_blk 83.3 ±9.4
s3_e3 75.2 ±5.2
s3_e4 70.5 ±5.4
s3_e4_blk 71.4 ±5.7
s3_e5 68.4 ±2.7
s3_e5_blk 69.9 ±4.8
s4_e0 21.7 ±23.0 ⚠ seed_split: range 1.0-82.4 (5 low / 1 high of 10)
s4_e0_blk 18.7 ±16.2 ⚠ seed_split: range 2.8-51.5 (5 low / 1 high of 10)
s4_e1 91.6 ±9.3
s4_e1_blk 89.6 ±10.9
s4_e2 83.5 ±5.3
s4_e2_blk 83.2 ±5.9
s4_e3 73.0 ±6.6
s4_e3_blk 74.6 ±4.6
s4_e4 69.8 ±3.6
s4_e5 67.2 ±2.9
s4_e5_blk 67.2 ±4.2
s5_e0 25.2 ±20.8 ⚠ seed_split: range 6.6-76.6 (4 low / 1 high of 10)
s5_e0_blk 25.9 ±24.3 ⚠ seed_split: range 10.2-96.9 (7 low / 1 high of 10)
s5_e1 91.2 ±4.7
s5_e1_blk 89.8 ±6.4
s5_e2 83.2 ±6.7
s5_e2_blk 82.3 ±7.2
s5_e3 72.2 ±4.7
s5_e3_blk 74.1 ±3.3
s5_e4 68.2 ±4.5
s5_e4_blk 68.8 ±3.6
s5_e5 66.2 ±3.9

Conclusions

Conclusion: Direction is not the operative variable \@{mirror-conclusion}

The registered hypothesis is rejected. Of the 90 pre-registered claims, 34 held, 26 were mixed, and 30 were rejected, and the failures are not noise scattered over the table: they fall into three bands, each of which replaces part of the hypothesis with something sharper.

Descent wins the contest it was designed around, retention at a safe floor.

Result: Descent wins retention at a safe floor \@{mirror-descent-retention}

Across both shape families, no descending arm with a floor at α = 1 or above lost its final-value claim on unseen_mismatch: of the twenty such claims, thirteen held, with margins from 3.3 to 26.9 points, and seven straddled, the ties concentrated at short spans.

Start high and land in the working range, and the anneal ends ahead of its mirror.

Conclusion: Final α, not direction, sets the endpoint \@{mirror-final-alpha-dominance}

Every pair ending at 0 reverses this, and not narrowly. Nine of those ten final-value claims were rejected, with the ascending arm ahead by 40 to 73 points (block 2→0: Δ −72.7, 95% interval −82.7 to −62.7); the tenth, the smooth 1→0 pair, straddled. The reading is direct: the descending arm passes through the uniform tail after it has built the rule and loses it to catastrophic interference, while its mirror spends the same uniform segments before there is anything to erase, and finishes training at peak concentration. At the horizon the final α, not the direction of travel, sets the outcome.

This is the falsification condition the hypothesis named in advance, and it fired.

The peak claims hold the result nothing in the prior work predicted.

Result: Ascent out-peaks descent on interior pairs \@{mirror-ascent-peaks}

Only four of thirty held, all on pairs ending at 0, where the descending arm's mid-run peak precedes its collapse. Eight were rejected, and seven of those are interior pairs where the ascending arm reaches the higher peak: every block pair ending at 2 (5→2: Δ −14.2, interval [−19.1, −10.0]; 4→2: −12.5; 3→2: −11.4), two of the three smooth ones (4→2: −6.5; 3→2: −5.6; 5→2 straddled at −5.9), and the smooth 4→1 and 2→1 (−5.0 and −2.4); the eighth, block 1→0 (−23.5), is a pair whose descending arm never builds the rule before the uniform tail takes it. The timing tempers the surprise without removing it: the ascending arms peak early, at 250 to 500 steps (s2_e4_blk reaches 96.5 at 300), while their descending mirrors' peaks sit at the horizon itself, 1100 to 1200 and still rising, which is the signature of undertraining under a fixed budget.

Whether the anneal would catch those peaks given a longer run is open; extending the horizon on the interior pairs is the obvious follow-up.

The consistency competition split 17 held to 13 rejected, so descent is not reliably the steadier direction, and where it collapses it is also the wilder one: the block 1→0 spread claim was rejected with the descending arm's peak standard deviation 11.5 points larger, seed bimodality again rather than uniform mediocrity. The adjacent pairs 5↔4 and 4↔3 tied every mean claim in both families; at a span of one grid step, direction is invisible at ten replicates.

Three notes on reading the table. Mirror pairs in which both arms sit at saturation produce degenerate intervals and adjudicate as mixed by construction, so a mixed peak verdict often means both arms at ceiling rather than genuine ambiguity. The ten-seed percentile bootstrap is mildly anti-conservative, so an isolated hairline hold should not be over-read. The mirror comparison figures rendered with the experiment show each pair side by side and are the fastest way to see the three bands above.

Comparison figures

curriculum_comparison.png
curriculum_comparison.png
mirror_comparison_blk.png
mirror_comparison_blk.png
mirror_comparison_lin.png
mirror_comparison_lin.png
schedules.png
schedules.png

Children

Child peak unseen_mismatchStatus
s5_e5 66.2 done
s5_e4 69.0 done
s5_e3 73.0 done
s5_e2 83.2 done
s5_e1 93.3 done
s5_e0 92.7 done
s4_e4 69.8 done
s4_e3 75.1 done
s4_e2 83.8 done
s4_e1 93.7 done
s4_e0 92.6 done
s3_e3 76.6 done
s3_e2 86.1 done
s3_e1 94.9 done
s3_e0 92.4 done
s2_e2 94.8 done
s2_e1 97.2 done
s2_e0 98.1 done
s1_e1 89.6 done
s1_e0 50.2 done
s0_e0 49.6 done
s0_e1 49.7 done
s0_e2 91.0 done
s0_e3 86.8 done
s0_e4 89.9 done
s0_e5 82.4 done
s1_e2 99.6 done
s1_e3 96.5 done
s1_e4 98.7 done
s1_e5 94.9 done
s2_e3 91.7 done
s2_e4 90.3 done
s2_e5 89.1 done
s3_e4 72.1 done
s3_e5 71.3 done
s4_e5 68.4 done
s5_e4_blk 68.8 done
s5_e3_blk 74.1 done
s5_e2_blk 82.3 done
s5_e1_blk 95.7 done
s5_e0_blk 94.9 done
s4_e3_blk 75.0 done
s4_e2_blk 84.0 done
s4_e1_blk 96.8 done
s4_e0_blk 98.2 done
s3_e2_blk 85.1 done
s3_e1_blk 95.5 done
s3_e0_blk 93.9 done
s2_e1_blk 98.0 done
s2_e0_blk 99.3 done
s1_e0_blk 59.5 done
s0_e1_blk 83.0 done
s0_e2_blk 97.8 done
s0_e3_blk 93.7 done
s0_e4_blk 90.6 done
s0_e5_blk 91.9 done
s1_e2_blk 98.4 done
s1_e3_blk 96.0 done
s1_e4_blk 91.7 done
s1_e5_blk 96.3 done
s2_e3_blk 96.5 done
s2_e4_blk 96.5 done
s2_e5_blk 96.5 done
s3_e4_blk 76.2 done
s3_e5_blk 76.2 done
s4_e5_blk 68.8 done

experiment.yaml