diff --git a/PROJECT.md b/PROJECT.md
index e8f3d1d..491fe19 100644
--- a/PROJECT.md
+++ b/PROJECT.md
@@ -5585,6 +5585,48 @@ sein, dass durch die geänderte Mechanik alles etwas schwerer geworden ist"*.
- (c) **Widen the early whiff edge only** (a smaller tail), keeping the error race: undoes most of the
"harder" without changing the model.
+### Step 4 (b), Oliver's pick: the follow-through, and a CPU that can WIN a point (2026-10-14, v373)
+Oliver: *"b"* (options above). Two halves, each useless alone (both were measured alone above):
+- **THE FOLLOW-THROUGH** (`TUNE.swingTail` 0.06 s, rally modes, player, bounced balls only). A swing
+ meets a ball arriving up to 60 ms after its window closed at q 0.05. The early whiff edge goes from ~70
+ ms back to ~130 ms (where the volley window had it before step 1); past it, it is still a whiff. The
+ log says `q=0.05 · early 115ms`. Volleys keep their window: a tail on balls in the air raised the
+ back-court volley share.
+- **THE SITTER IS PUNISHED** (`gameplay.punishes`): a player ball under `punishBelow` (0.5) is answered
+ with a put-away at a chance from `punishMin` 0.2 to `punishMax` 0.85 along the Climb's own progress
+ (`matchStep`, so its brisk bottom counts), classic by `DIFFS[].punish` (0.2/0.5/0.8). A put-away is
+ struck at `punishQ` 0.95, skips the style's soft shots, aims at `punishX` 3.5 m (the line; the rung's
+ width dial still bounds it, so the bottom of the ladder punishes without painting lines), and only
+ counts if no cap took it down (a low volley stays a block). The log says `THEM PUT-AWAY of your weak ball`.
+- **...AND HE IS ON HIS HEELS** (`ball.heels`, `punishRead` 0.5 s): the auto-run stands for that long on a
+ put-away of his own sitter. This is the half that makes it work. The auto-run started on the strike's
+ frame with a perfect read, ~7 m/s plus a 1.75 m reach, and covered the whole court: a q 0.95 put-away
+ to the open court won 0 of 21, at the line 0-2 of 20. Read 0.25 s: ~5%; 0.4: ~20%; 0.55: ~70%.
+ **Feel risk:** he visibly stands still for half a second. If that reads as a bug on the phone, the
+ alternatives are a slowed (not frozen) run, or a shorter read with the put-away hit harder.
+- **A step-2 regression it surfaced:** the drop's dig-out cap read `ball.spin < 1`, and the slicer hits
+ EVERY rally ball at spin 0.8, so every low contact against him (both sides) came back at `lowVolleyQ`.
+ Now `ball.soft && spin < 1`. THE SELLER went from 35% to 47-54% and normal rally lengths.
+- **Measured** (Climb, level 26, 8 seeds × 500 s, point win %):
+
+ | rung | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
+ |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+ | σ40 | 95 | 88 | 88 | 87 | 75 | 58 | 52 | 45 | 54 | 48 | 47 | 77 | 42 | 46 | 64 | 40 | 65 | 39 |
+ | σ60 | 95 | 88 | 83 | 78 | 62 | 55 | 53 | 43 | 47 | 46 | 36 | 61 | 30 | 43 | 57 | 28 | 55 | 28 |
+
+ The ladder slopes now, down to the Champion at 28-39%. Classic: easy ~80, medium ~57, hard ~30 (σ60, level 1).
+- **Still open:**
+ - (1) **The net rushers** (Umpire, Club Pro, Director) are 15-25 points easier than their neighbours.
+ They win only ~35-55% of their net points, because the bot ALWAYS passes or lobs a net man, which is
+ their tag's answer played perfectly. The phone decides whether a human does that; if so, the dial is
+ their split-step read (`netReact`) or their put-away from the net.
+ - (2) The bottom three rungs are ~90%. That is easy for level 26, but the Climb is a marathon.
+- Tests (167, nine seeds): the follow-through meets an ~80 ms early tap (and the old edge did not); the
+ put-away share climbs the ladder, goes for the line, never answers a good ball; a low slice drive is not
+ a dug-out drop. The baseline-shape test excludes the answer to a put-away (a man on his heels takes it in
+ the air legitimately), and synthetic returns in the suite now carry `pow: 1` (a stale `pow` from the
+ previous test read as a sitter).
+
# OPEN — leftovers, in rough priority order
Nothing here is broken; these are known gaps and unverified risks.
@@ -5592,9 +5634,10 @@ Nothing here is broken; these are known gaps and unverified risks.
0. **THE RALLY GOES FLAT (2026-10-13), the top item.** Every match converged on serve, both at the net,
reflex volleys, won by a wrong-foot. Step 1 (the court gets its length) SHIPPED v361, awaiting the
phone verdict; the tap timing + leg knee (v362), the soft ball (v363, drop/lob split v364) and the
- opponent styles (v364) followed; the swing-log fixes ran to v371. **Step 4 (v372) is BLOCKED on a
- design decision**: the ladder cannot climb while points are decided by the player's whiffs. See "Step
- 4, measured first" above for options (a)/(b)/(c). Fallback tag `rally-baseline-v360`.
+ opponent styles (v364) followed; the swing-log fixes ran to v371. Step 4: v372 measured why the ladder
+ could not climb (points decided by the player's whiffs); Oliver picked (b), shipped v373 (the follow-
+ through, put-aways, on his heels). Awaiting the phone verdict on v373, especially the half-second
+ flat-footed read and the net rushers. See "Step 4 (b)" above. Fallback tag `rally-baseline-v360`.
1. **`RES` 4 is unverified on a real phone under load.** It nearly doubled the fill rate (810 -> 1080
device px across). Oliver has not reported stutter, but he also has not played a late horde since.
diff --git a/index.html b/index.html
index 6d2cb83..6f7dfa5 100644
--- a/index.html
+++ b/index.html
@@ -1140,6 +1140,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
REC
-
+