In the Mountains · Movement · 2026-07-03

The point man waits

A squad shouldn't string out across a draw because one man snagged on a wall while the lead kept marching. Fixing that meant first proving what the men actually snag on — and the obvious answer was wrong.

tsc ✓build ✓ smoke ✓ (determinism + serialize) balance ✓ (0 stranded) window gate: unchanged held-out: 0 new strandings

The report

“(1) The point man should slow down and stop when the squad isn’t together. Right now he just keeps going — the worst part — and it makes him unrealistically far forward. (2) Squad members, especially later in the file, are getting stuck on buildings in the villages, and the squad spreads out because the point man does not wait. Unless you find a real solution, we can just make the buildings visual-only.”

Two asks, and a causal theory tying them together: men snag → the lead doesn’t wait → the file spreads. The house rule here is no fix without a number, so before touching a line I built a probe that attributes every stalled tick to the exact cell that blocked the man, and ran it on 21 near-village patrols — the ones a player actually watches.

Finding #1 — “buildings in villages” is the wrong suspect

Blocked-seconds per patrol, by the land type that actually stopped the man.

0.6s
Village qalat walls. Almost nothing. The thing the report named is the least of it.
11.6s
COP b-huts. The men grind the outpost’s own buildings on the way out — “later in the file,” exactly as reported.
38.6s
Terrain & the HESCO wire. Cliffs, the river, and sliding along the perimeter berm on egress dominate.
The premise was testable, and it failed. I did implement “make qalat walls passable-but-still-cover” (it’s combat-safe — cover and line-of-sight are baked independently of passability, and sight is blocked by elevation and vegetation, never by walls). It moved the aggregate from 20.2s → 19.9s. Walls were never the cause, so I reverted it rather than ship a change that softens the village maze for no measured gain.

Finding #2 — the real defect, and two dead metrics

Whatever a man snags on — a wall, a b-hut, the wire, a cliff — the point man barely reacts. While a follower is genuinely stuck he runs at 0.51 m/s (full march) and is fully halted just 1% of the time. He marches on; the file opens to 94 m ahead of centroid, and stretches to 355 m on the worst seed. That is the “unrealistically far forward.”

Two guards that were supposed to catch this turned out to be dead code — both keyed on blockedTimer > 6, but the stall watchdog resets blockedTimer at 2 seconds, so it can never exceed ~2. One was a mis-aimed exclusion in the pace governor; the other was the follower-strand harness’s maxWedge column, which had read 0.0s on every seed — the very “nobody is stuck” reassurance a prior investigation had leaned on. Both fixed.

The fix — a bounded halt, gated on being stuck, not slow

The point man now takes a knee — a genuine stop — when a follower is blocked and trailing, or when the rearmost man’s along-wake lag exceeds a file-length. It’s clock-latched and, critically, capped at 45 seconds of halt per leg.

Why this doesn’t re-break the tactical window. A prior effort (issue 031) proved you can’t slow the lead for a tired straggler on a climb — a chronic sub-floor creep over hundreds of seconds makes far villages arrive too late. This is a different animal: a discrete, budgeted stop (45s is a rounding error against the 1500s window), gated on a follower actually being blocked — which a merely-slow climber never is. So it fires in villages and on the wire, and stays silent on the long climb where the hustle already owns the problem.

See it — delta-4, worst march moment

Every dot is a soldier at the instant the point man is furthest ahead of the element centroid (×). Same seed, same route — only the wait differs.

point man the other eight element centroid — — — the “forward” span
BASELINE — he does not wait delta-4 · point man 52 m ahead of centroid point
52 m strung. The point man has run well clear of the pack.
FIX — he holds for the file delta-4 · point man 40 m ahead of centroid point
40 m. He’s reined in toward the element — the file is tighter.

The numbers

A/B on identical code (a runtime switch disables the halt), near villages, march phase only.

1%38%
Point man halted while a follower is wedged. He now actually waits.
0.510.32
m/s — his speed while a man is stuck. Cut by a third.
129
of 21 seeds with the point man >40 m forward at his worst. Peaks reined in.

Held-out — survey-40…55, sixteen seeds I never tuned on

metricbaselinefixread
halt % while a man is wedged0%26%waits
nav speed while wedged (m/s)0.580.45slower
seeds with peak forward > 40 m9 / 165 / 16tighter
new strandings introduced0none

Tactical-window gate (squad-arrival) — the issue-031 arbiter

metricbaselinefixread
point man arrived25 / 2725 / 27identical
…within tactical window (≤1500 s)15 / 2715 / 27identical
squad cohesion @ objective99%98%noise
elements stranded mid-route (balance)00none

Byte-for-byte the same arrival profile — the 45s/leg budget makes the halt provably window-neutral. Combat is untouched (the halt only runs during the patrol move; contact resets it): KIA 0.83 / WIA 8.75 / civilian casualties 0, within the noise floor.

What I did not fix — named, on purpose

Reproduce. npx tsx scripts/squad-wedge.ts (cause attribution + halt %; ITM_NOWAIT=1 for the baseline) · npx tsx scripts/squad-arrival.ts (the window gate) · held-out A/B on survey-40…55. Full evidence, verbatim baselines, and per-seed tables in docs/progress/2026-07-03-squad-village-cohesion/; the mechanism and residuals in docs/issues/036.

Code: lib/sim/world/formation.ts (the wedge/cohesion halt), tasks.ts (per-leg budget reset), types.ts (task latch fields), scripts/squad-wedge.ts (the probe), scripts/follower-strand.ts (dead-metric fix).