Ablation report · 2026-08-08

The gait selector answers to incentives, not exploration

Two single-variable arms from the walking base, run back to back. Arm 1 changed only how the gait bit explores; arm 2 changed only what ignoring it costs. One of them woke the selector up.

Base p(bound)0.004 the selector never leaves trot
Arm 1 · entropy0.010 zero entropy on the logit, init std √2 — nothing
Arm 2 · gd −150.568 the paper's weight — alive, ψ̄ ≈ 0.5 as designed
Blackouts0 −15 + clip coexist when started from a base that walks

What each arm was

Both start from MotionLibWalk — the one configuration measured to walk (0.537 m/s at 98% tracking) — and change exactly one thing, per the discipline rule that six unattributable runs bought us.

Arm 1 (exploration). The gait logit's entropy bonus was paying the policy to keep the bit noisy at ~50/50 forever; the hypothesis was that this jitter prevented any committed gait sequence from ever being sampled long enough to show its value. Entropy on that dim zeroed, initial noise raised to √2: explore hard early, then commit. Verdict: p(bound) 0.010. Exploration was not the bottleneck.

Arm 2 (incentives). At the base's weight of −1, committing to pure trot costs 0.005/step against 0.042/step of earnable positives — pocket change, rationally ignored. At the paper's −15 (annealing to zero over the run, the schedule Table S3 specifies), ignoring the term forfeits more than everything else combined. Verdict: p(bound) 0.568. The selector works; it was just never worth using.

Arm 1 (entropy), iteration 1499, MotionLibWalk-Play-v0, commands 0.3–0.8 m/s. Walks like the base — and its footfall is measurably more trot-like (diagonal sync now dominates lateral, 0.45/0.57 vs 0.34/0.19), the one real effect of removing the bit jitter.
Arm 2 (gd −15), iteration 1499, same play config. The selector mixes gaits (bound 57% of steps) at visible cost: tracking drops to 80%, and one rear leg nearly drags (duty RL 0.18 / RR 0.88) — it partly satisfies diversity by limping.

The numbers side by side

basearm 1 · entropyarm 2 · gd −15
p(bound)0.0040.0100.568
tracking (train)98%~99%80%
terrain (train)1.9261.931.92
envs moving (probe)46/6457/6439/64
diagonal sync.33 / .47.45 / .57.43 / .06
lateral sync.34 / .41.34 / .19.28 / .62
foot duty FL/FR/RL/RR.44/.63/.60/.58.60/.52/.61/.44.50/.63/.18/.88

Sync numbers are Jaccard overlap of stance intervals per leg pair. A clean library trot would read diagonal ≈ 1.0, lateral ≈ 0. Nobody is there yet — but arm 1 is the first policy where diagonal clearly wins.


Why this isn't the final word

These are 1,500-iteration runs, and Table S3's own schedule anneals the gait terms over 50,000 epochs — every number above describes the first 3% of the curve, where the pressure has barely released. The budget run (MotionLibWalkLong: same −15, same anneal stretched to 15,000 iterations, commands widened to 0.0–1.5 m/s so bound can actually pay) has been running on server-gpu since tonight. The question it answers: does arm 2's limp heal as the anneal fades, the way the paper's design intends?

If WalkLong converges clean, the recipe is: arm 1's runner (clean trot imprint) + arm 2's weight (live selector) + budget. That combination is the candidate teacher for distillation.