pog-mcp 0.8.8 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pog-mcp",
3
- "version": "0.8.8",
3
+ "version": "0.8.10",
4
4
  "type": "module",
5
5
  "description": "MCP server that lets an AI agent play Proof of Goal — wallet, sign-in, squad building, and matches as typed tools.",
6
6
  "license": "MIT",
@@ -39,8 +39,8 @@
39
39
  "scripts": {
40
40
  "build": "tsc",
41
41
  "dev": "tsc --watch",
42
- "type-check": "tsc --noEmit",
43
- "lint": "tsc --noEmit",
42
+ "type-check": "tsc --noEmit -p tsconfig.typecheck.json",
43
+ "lint": "pnpm run type-check",
44
44
  "start": "node dist/index.js",
45
45
  "test": "vitest run",
46
46
  "test:watch": "vitest",
package/skill/SKILL.md CHANGED
@@ -361,9 +361,22 @@ the tables are in `reference/measurements.md`. These describe the engine as it
361
361
  currently stands and could change if it is rebalanced.
362
362
 
363
363
  **Give every player a shape.** A squad with all four attributes equal on every
364
- player is the worst thing you can build — it lost to every differentiated squad
365
- tested, most by 3:1. Defenders want defense, forwards want shoot. This is the
366
- single largest effect measured, and it is what a naive even split gets wrong.
364
+ player is the worst thing you can build — last of eleven in the round-robin, and
365
+ beaten by nine of the ten differentiated squads tested. In the worst of those
366
+ pairings it wins 9% of matches and loses 53%, over 20,000 matches. Defenders
367
+ want defense, forwards want shoot. This is the single largest effect measured,
368
+ and it is what a naive even split gets wrong.
369
+
370
+ **The tenth pairing is worth knowing, and it is not a reprieve.** The flat squad
371
+ edges `stars-433` — the build that pours its budget into a few 26–29 players —
372
+ winning 39.5% of 20,000 regulation matches to 34.6% lost, the rest drawn (the
373
+ two are level in knockouts). Piling a budget onto a handful of players is the
374
+ one mistake that costs more than not shaping at all, because that squad concedes
375
+ 1.30 goals a match, roughly four times what the leaders concede. Spread the
376
+ points across eleven, *then* shape them. (Corrected 2026-08-22: this passage used
377
+ to say the flat squad lost to every differentiated squad. It never did — the
378
+ probe seeder was too weak to show the exception. See
379
+ `reference/measurements.md`.)
367
380
 
368
381
  **The goalkeeper slot reads exactly one attribute when defending.** Every save
369
382
  a keeper ever makes scores `defense + cond/2 + total/3`, at three sites: the 1v1
@@ -461,8 +474,14 @@ total / 3`, `isPkKicker` by `(pass + shoot) / 2 + total / 3`. One player may
461
474
  hold both roles if he wins both criteria. (Neither nomination applies to a shootout — that order is computed
462
475
  from `shoot + pass` across the whole squad.)
463
476
 
464
- **There is no home advantage.** Identical squads win equally often from either
465
- side. Never explain a result by which side you were on.
477
+ **Home and away are not measurably different.** Identical squads win 25.1%
478
+ against 24.9% over 200,000 matches, on each of three squad shapes — which bounds
479
+ any edge to under 0.6 of a percentage point. Do not explain a result by which
480
+ side you were on: an effect that small cannot show up in the number of matches
481
+ you will ever play. (The engine is not literally symmetric — one attacking
482
+ branch reads a different player's total at home — so a squad deliberately built
483
+ around it is worth measuring rather than assuming. Nothing measured so far
484
+ moves.)
466
485
 
467
486
  ## Measuring a change — `simulate_batch`, not thirty friendlies
468
487
 
@@ -50,9 +50,27 @@ measured) — the cycle probe additionally applies a Bonferroni-corrected
50
50
  threshold, and its re-run is recorded in "Strategy round-robin in BOTH modes"
51
51
  below. `sample-size.mts` was re-validated the same day (SHA-256; both tables below
52
52
  updated — shape unchanged, rows a touch weaker; its identical-squads section is
53
- its own true-zero control). Still queued: `strategy-probe.mts`,
54
- `skill-value.mts`, `gk-sweep.mts`, and any published verdict resting on
55
- |z| < 10 from the old seeder.
53
+ its own true-zero control).
54
+
55
+ **2026-08-22: the last three were re-seeded and re-run** — `strategy-probe.mts`,
56
+ `skill-value.mts` and `gk-sweep.mts`, each now on SHA-256 with a standing mirror
57
+ cell, at the sample sizes their published tables used. Every table they feed is
58
+ updated below, changed values marked. **No probe in this directory uses the old
59
+ seeder any more.**
60
+
61
+ That re-run also produced the sharpest demonstration yet of why it was needed.
62
+ Take the round-robin's `flat-433` vs `stars-433` fixture, put the SAME squad on
63
+ both sides — a cell whose true value is zero by construction — and seed it from
64
+ the tag pair those two labels generate. Over 20,000 matches the SHA-256 mirror
65
+ reads **z −0.41**; the FNV mirror reads **z −4.17**. On the real fixture the old
66
+ seeder then scored the pairing 50.3% (z 1.03 — a coin flip) where SHA-256 scores
67
+ it 52.5% (z 8.11). So the old seeder does not only invent effects on empty
68
+ cells; it also buries real ones. A sentence in `SKILL.md` had been resting on
69
+ the buried half — see the round-robin correction below.
70
+
71
+ `strategy-probe.mts` section ⑤ prints that four-cell comparison on every run. It
72
+ is the one place the retired seeder still exists in this directory, kept as the
73
+ control that justifies its retirement.
56
74
 
57
75
  **A probe that scores by comparing `homeScore` to `awayScore` is wrong under
58
76
  `gameFlg: 1`** and silently reports decided matches as draws. `MatchResult` has
@@ -95,27 +113,92 @@ matches than a per-call cap allows and they carry their mirror controls.
95
113
 
96
114
  ## Round-robin: 11 strategies × home/away × 300 seeds = 33,000 matches
97
115
 
98
- Ordered by points per match (3 for a win, 1 for a draw).
116
+ Re-measured 2026-08-22 with SHA-256 seeding (mirror control z −0.43). Ordered by
117
+ points per match (3 for a win, 1 for a draw).
99
118
 
100
119
  | Strategy | Win % | Draw % | Goals for /match | Goals against /match |
101
120
  | --- | --- | --- | --- | --- |
102
- | `gkmin-433` — minimum keeper, spread outfield | 37.2 | 47.2 | 0.68 | 0.33 |
103
- | `def-433` — defense-leaning roles | 32.4 | 52.6 | 0.52 | 0.27 |
104
- | `role-433` — attack-leaning roles | 32.9 | 48.1 | 0.58 | 0.36 |
105
- | `def-532` — five at the back | 27.4 | 62.8 | 0.39 | 0.16 |
106
- | `bal-442` | 25.3 | 52.4 | 0.46 | 0.40 |
107
- | `shootonly-433` — shoot on everyone | 26.6 | 41.9 | 0.57 | 0.63 |
108
- | `gkheavy-433` — 29-point keeper | 22.9 | 50.4 | 0.43 | 0.47 |
109
- | `atk-352` | 22.9 | 48.4 | 0.46 | 0.52 |
110
- | `passonly-433` — pass on everyone | 22.1 | 46.9 | 0.47 | 0.57 |
111
- | `stars-433` — a few 26–29 players | 25.8 | 26.0 | 0.88 | **1.30** |
112
- | `flat-433` — all four attributes equal | **15.3** | 41.9 | 0.35 | 0.76 |
121
+ | `gkmin-433` — minimum keeper, spread outfield | 37.1 | 46.7 | 0.67 | 0.33 |
122
+ | `def-433` — defense-leaning roles | 31.7 | 52.6 | 0.51 | 0.28 |
123
+ | `def-532` — five at the back | 28.0 | 62.5 | 0.40 | 0.15 |
124
+ | `role-433` — attack-leaning roles | 31.5 | 48.8 | 0.57 | 0.39 |
125
+ | `bal-442` | 25.9 | 51.3 | 0.46 | 0.40 |
126
+ | `gkheavy-433` — 29-point keeper | 24.7 | 49.7 | 0.45 | 0.45 |
127
+ | `shootonly-433` — shoot on everyone | 25.4 | 42.3 | 0.57 | 0.66 |
128
+ | `passonly-433` — pass on everyone | 23.2 | 47.3 | 0.48 | 0.53 |
129
+ | `atk-352` | 21.9 | 48.6 | 0.44 | 0.53 |
130
+ | `stars-433` — a few 26–29 players | 25.4 | 26.9 | 0.85 | **1.30** |
131
+ | `flat-433` — all four attributes equal | **15.3** | 42.9 | 0.36 | 0.74 |
132
+
133
+ **What the re-seed changed here: three adjacent swaps, no movement at either
134
+ end.** `def-532` now finishes above `role-433`, `gkheavy-433` above
135
+ `shootonly-433`, and `passonly-433` above `atk-352`.
136
+
137
+ The first has independent corroboration, **but only for the direct matchup**.
138
+ `cycle-probe.mts` plays that pair at 4,000 matches with a Bonferroni-corrected
139
+ threshold and has `def-532` beating `role-433` 60.2% of decided matches,
140
+ significant. That establishes the two are genuinely separated *head to head*.
141
+ It does not settle which belongs higher in this table, because these rows rank
142
+ by points aggregated over ten opponents, and a head-to-head result is blind to
143
+ the other nine — a squad can win a pairing and still finish below its opponent
144
+ on aggregate. So: the direct matchup is decided, the aggregate ordering is not.
145
+
146
+ The other two swaps have no corroboration at all. They separate rows 0.05 and
147
+ 0.03 points-per-match apart; a 6,000-match row here carries a standard error
148
+ near 0.014, so those gaps sit at roughly 2.6 and 1.3 standard errors
149
+ uncorrected — and this table makes 55 pairwise comparisons, for which
150
+ `cycle-probe`'s bar would be |z| ≈ 3.3. Neither clears it.
151
+
152
+ So read the eleven rows as bands, not as a ranking: `gkmin-433` clear at the
153
+ top, then a top group, a middle group, then `stars-433` and `flat-433`. The top
154
+ and bottom of the table did not move at all. **No aggregate ordering inside a
155
+ band is decidable at 300 seeds, before or after the re-seed** — that is what
156
+ `cycle-probe.mts` exists to do, and it does it pairing by pairing.
113
157
 
114
158
  Two things stand out. `flat-433` — the squad a naive even split produces — is
115
159
  last by a wide margin, which is why "give every player a shape" is the first
116
160
  piece of advice. And `stars-433` scores the most goals of any squad and still
117
161
  finishes near the bottom, because it concedes 1.30 per match.
118
162
 
163
+ ### Correction: `flat-433` does NOT lose to everything
164
+
165
+ `SKILL.md` said the flat squad "lost to every differentiated squad tested". It
166
+ does not, and it did not under the old seeder either — the claim was never true
167
+ of the data, and the weak seeder is why nobody could see it. Head to head over
168
+ 20,000 regulation matches (`strategy-probe.mts` section ④, which runs by default
169
+ so this correction reproduces from a checkout rather than citing a scratch run):
170
+
171
+ | `flat-433` vs | Points share % | W % | D % | L % | z |
172
+ | --- | --- | --- | --- | --- | --- |
173
+ | `gkmin-433` | 28.2 | 9.2 | 38.0 | 52.8 | −78.2 |
174
+ | `def-433` | 30.7 | 6.1 | 49.2 | 44.7 | −76.5 |
175
+ | `def-532` | 32.6 | 3.6 | 58.1 | 38.3 | −75.9 |
176
+ | `role-433` | 31.5 | 10.5 | 42.1 | 47.4 | −68.7 |
177
+ | `bal-442` | 34.8 | 11.8 | 46.0 | 42.2 | −58.4 |
178
+ | `gkheavy-433` | 37.5 | 13.7 | 47.7 | 38.6 | −48.7 |
179
+ | `shootonly-433` | 38.5 | 19.8 | 37.3 | 42.9 | −41.2 |
180
+ | `passonly-433` | 39.5 | 17.8 | 43.4 | 38.8 | −39.5 |
181
+ | `atk-352` | 38.4 | 16.6 | 43.7 | 39.7 | −43.7 |
182
+ | `stars-433` | **52.5** | **39.5** | 25.9 | 34.6 | **+8.1** |
183
+
184
+ **The points column counts a draw as half a win; it is not a win rate.** Half of
185
+ all regulation matches end level, so the two columns sit far apart — `flat-433`
186
+ takes 32.6% of the points against `def-532` while winning 3.6% of the matches.
187
+ Quote the wrong one and the table says something it does not say (Codex P2,
188
+ #736). The W/D/L columns are printed by the probe for exactly that reason.
189
+
190
+ Nine crushing losses and one real win. `cycle-probe.mts` — already on SHA-256,
191
+ already published — had the same cell at 54.3% of decided matches, significant
192
+ under its Bonferroni bar; the fact was in this repository and unread. In
193
+ knockouts the pairing is level (52.5% of decided matches, not significant), so
194
+ the win is a regulation-only result.
195
+
196
+ This is not a defence of the flat split, and the reason matters more than the
197
+ row: **pouring a budget into a few 26–29 players is the one mistake that costs
198
+ more than not shaping at all.** `stars-433` concedes 1.30 goals a match, roughly
199
+ four times what the top squads concede. Being beaten by the second-worst build
200
+ in the table is not evidence for the worst one.
201
+
119
202
  Note the draw column: with regulation-only scoring, roughly half of all matches
120
203
  end level. That is the single most important fact for anyone trying to read a
121
204
  short run of friendlies.
@@ -124,24 +207,32 @@ short run of friendlies.
124
207
 
125
208
  Only the goalkeeper's total changes; the remaining points are spread evenly over
126
209
  the ten outfield players. Every squad plays the same fixed opponent (a keeper of
127
- 20, spread outfield), home and away, 3,000 matches per row.
210
+ 20, spread outfield), home and away, 3,000 matches per row. Re-measured
211
+ 2026-08-22 with SHA-256 seeding (mirror control z 0.28).
128
212
 
129
213
  | GK total | Points per match | Goals against /match |
130
214
  | --- | --- | --- |
131
- | 10 | 1.406 | 0.38 |
132
- | 13 | 1.363 | 0.40 |
133
- | 17 | 1.333 | 0.39 |
134
- | 19 | 1.314 | 0.39 |
135
- | 23 | 1.144 | 0.47 |
136
- | 29 | 0.991 | 0.51 |
137
-
138
- The trend falls across the whole range, but **adjacent totals do not separate**.
139
- Re-running the sweep, the order reverses at five of the twenty values — 13, 15,
140
- 17, 19 and 28 each score above the total directly below them. Three thousand
215
+ | 10 | 1.365 | 0.38 |
216
+ | 13 | 1.284 | 0.40 |
217
+ | 17 | 1.324 | 0.38 |
218
+ | 19 | 1.235 | 0.41 |
219
+ | 23 | 1.142 | 0.49 |
220
+ | 29 | 1.037 | 0.53 |
221
+
222
+ The trend falls across the whole range, but **adjacent totals do not separate**,
223
+ and the re-seed made that more obvious rather than less. Over the full
224
+ twenty-value sweep the order now reverses at **eight** values 14, 15, 17, 18,
225
+ 20, 22, 26 and 28 each score above the total directly below them, where the old
226
+ seeder showed five (13, 15, 17, 19, 28). Neither list is a finding; the fact
227
+ that the list changes wholesale between seeders is the finding. Three thousand
141
228
  matches cannot split a one-point difference in keeper budget. What it does split
142
- is the range: the ~0.4 pt/match gap between the low teens and the high twenties
143
- is far larger than any reversal. Read this table as "the low end beats the high
144
- end", never as "19 beats 20".
229
+ is the range: the ~0.33 pt/match gap between total 10 and total 29 is far larger
230
+ than any reversal. Read this table as "the low end beats the high end", never as
231
+ "19 beats 20".
232
+
233
+ Note also that the effect is smaller than published: 1.406 → 1.365 at the cheap
234
+ end and 0.991 → 1.037 at the expensive end, so the spread narrowed from ~0.42 to
235
+ ~0.33. The direction and the mechanism are unchanged.
145
236
 
146
237
  Note the second column: a *better* keeper concedes *more*, because the points
147
238
  came out of the ten players in front of it.
@@ -307,7 +398,9 @@ dominance or cycle verdict.
307
398
  | 3-cycles (A>B>C>A) | **0** | **0** |
308
399
  | Dominant strategy | none | **`role-433`** beats all seven |
309
400
 
310
- Mode reversals that survived this re-measurement:
401
+ Mode reversals that survived this re-measurement. **Every percentage in these
402
+ three bullets is a share of DECIDED matches** — draws dropped, not counted as
403
+ half — which is the metric that probe's matrix prints:
311
404
 
312
405
  - **Attack vs defense lean** (same formation, same budgets): `def-433` beats
313
406
  `role-433` 56.5% in regulation; the SAME pairing flips to 53.6% for the
@@ -323,27 +416,93 @@ Mode reversals that survived this re-measurement:
323
416
  Monotone in both modes, still: role differentiation (`flat-433` last
324
417
  everywhere) and spreading over star-concentration (`stars-433` next-to-last).
325
418
 
419
+ **Those are statements about the RANKING, not about every pairing** — and the
420
+ difference is exactly where a `SKILL.md` sentence went wrong. This probe's own
421
+ regulation matrix has `flat-433` beating `stars-433` 54.3% of decided matches,
422
+ significant under the Bonferroni bar above. Last in the table does not mean
423
+ loses to everyone. See "Correction: `flat-433` does NOT lose to everything".
424
+
326
425
  Scope: all squads tenure=0, as everywhere in this file. Production applies
327
426
  `applyMatchGrowth()` before the engine, raising effective totals — these
328
427
  dominance/reversal claims are about zero-buff squads until the buff-0/max
329
428
  control runs (docs/tactics/01, track 0.1).
330
429
 
331
- ## Home advantage: none
430
+ ## Home advantage: none measurable
332
431
 
333
- Identical squads, 3,000 matches: home 24.1%, draw 51.9%, away 24.0%. Symmetric
334
- to within a tenth of a point.
432
+ Identical squads, home side fixed (`gk-sweep.mts` section ②):
433
+
434
+ | Squad · sample | Home | Draw | Away | z |
435
+ | --- | --- | --- | --- | --- |
436
+ | baseline · 3,000 (the published sample) | 26.63% | 49.53% | 23.83% | 2.16 |
437
+ | baseline · 200,000 (the deciding sample) | 25.06% | 50.10% | 24.85% | 1.34 |
438
+ | `stars-433` · 200,000 | 38.87% | 22.25% | 38.87% | −0.01 |
439
+ | `atk-352` · 200,000 | 25.40% | 49.43% | 25.16% | 1.49 |
440
+
441
+ **The verdict holds; the old evidence for it did not.** The previous entry read
442
+ "home 24.1%, draw 51.9%, away 24.0% — symmetric to within a tenth of a point",
443
+ which sounds like a tight measurement and was luck: at 3,000 matches the
444
+ standard error on the home−away gap is about 1.3 points, so a tenth of a point
445
+ is three decimal places past what that sample can see. Re-seeded, the same
446
+ sample size lands 2.8 points apart instead — also luck, in the other direction.
447
+ The section now carries a sample that can actually decide it, and at 200,000
448
+ matches home and away are within 0.2 points.
449
+
450
+ **Worth knowing that this is an empirical result and not a structural one.** The
451
+ engine is *not* symmetric in code: `getPoint` has an `isHome` branch for DMF
452
+ attackers that scores the ball carrier's total (`this.kiten`) instead of the
453
+ acting player's — a faithful port of the original Perl bug, marked as such in
454
+ `engine.ts`. It can only bite when the acting DMF is *not* the carrier, which
455
+ rules out the ordinary pass/dribble/shoot path and leaves free-kick receivers,
456
+ counter-attacks and post-play. That is why the last two rows are there: they are
457
+ the shapes most able to trigger it — `stars-433` spreads its slot totals from 12
458
+ to 29, so "the carrier's total" and "this player's total" are far apart, and
459
+ `atk-352` fields three DMFs. Both come back level.
460
+
461
+ **Be precise about what that establishes.** Inside an affected play the branch
462
+ does change the number: the home side scores it off the carrier's total, the
463
+ away side off the acting DMF's, so this is not an inert code path and the two
464
+ sides are not computing the same thing. What the rows above show is that no
465
+ effect survives to the *match result* for the three squad layouts sampled. The
466
+ legal roster space is far larger than three, and none of the rest is tested
467
+ here — a squad shaped to exploit the branch, or a rebalance that widens DMF
468
+ involvement, has to be measured rather than assumed. The claim is "no aggregate
469
+ effect detected in these squads", not "the asymmetry is harmless".
470
+
471
+ **The practical advice survives that narrowing, for a reason worth separating
472
+ out.** Do not explain a result by which side you were on — not because the
473
+ effect is proven to be exactly zero everywhere, but because of its size. Across
474
+ the three 200,000-match runs the 95% interval on home-minus-away tops out at
475
+ +0.52, +0.39 and +0.55 percentage points of all matches — so even the loosest
476
+ reading leaves under 0.6 of a point on the table, and a 3,000-match sample
477
+ cannot see something that small (it read 2.8 points the wrong way on pure
478
+ noise).
479
+ Anyone reading a handful of friendlies is orders of magnitude further away. So
480
+ side is never the explanation for a result you can actually observe — while a
481
+ squad built to lean on DMF free-kick receivers or counters is untested here, and
482
+ should be measured rather than assumed either way.
335
483
 
336
484
  ## Set-piece takers
337
485
 
338
486
  Same squad, only the kicker slots move. Opponent fixed, 3,000 matches each.
487
+ Re-measured 2026-08-22 with SHA-256 seeding (`gk-sweep.mts` section ③, mirror
488
+ control z 0.28).
339
489
 
340
490
  | FK / PK taker | Win % | Points per match |
341
491
  | --- | --- | --- |
342
- | FW / FW (same player) | 25.5 | 1.271 |
343
- | FW / FW (two players) | 24.1 | 1.221 |
344
- | OMF / FW | 20.4 | 1.145 |
345
- | DF / DF | 20.4 | 1.149 |
346
- | GK / GK | 17.4 | 1.066 |
492
+ | FW / FW (same player, slot 9) | 25.4 | 1.249 |
493
+ | FW / FW (same player, slot 8) | 24.9 | 1.235 |
494
+ | FW / FW (two players) | 24.2 | 1.241 |
495
+ | OMF / FW | 19.5 | 1.115 |
496
+ | DF / DF | 18.9 | 1.112 |
497
+ | GK / GK | 17.6 | 1.075 |
498
+
499
+ The ordering survived: forwards first, the keeper last by a wide margin. Two
500
+ things moved, both inside the noise this sample can resolve. `OMF / FW` and
501
+ `DF / DF` swapped places — they are 0.003 pt/match apart, which is nothing. And
502
+ the slot-8 row is new: it is the same *kind* of arrangement as the slot-9 row
503
+ (one forward taking both kicks), and it scores 0.014 lower. That difference has
504
+ no cause, and it is the honest floor for reading any other gap in this table.
505
+ The old five-row version silently dropped it.
347
506
 
348
507
  Conversion tracks the taker's shooting — for FREE kicks. This table moved both
349
508
  roles together and never crossed the two criteria, so it says nothing about the
@@ -447,7 +606,8 @@ decisive" and "is decisive".
447
606
  ## Does the Skill actually help? — and which part of it
448
607
 
449
608
  Three hand-built squads, each exactly 212 and validator-clean, 8,000 matches per
450
- pairing, home and away balanced (`probes/skill-value.mts`):
609
+ pairing, home and away balanced (`probes/skill-value.mts`). Re-measured
610
+ 2026-08-22 with SHA-256 seeding (mirror control z −0.55):
451
611
 
452
612
  - **naive** — 5/5/5/4 on everyone, the squad the tool descriptions alone produce.
453
613
  - **shaped** — roles differentiated, defense-leaning, both set pieces on the best
@@ -457,15 +617,16 @@ pairing, home and away balanced (`probes/skill-value.mts`):
457
617
 
458
618
  | Matchup | Win % | Draw % | Loss % |
459
619
  | --- | --- | --- | --- |
460
- | shaped + cheap keeper **vs** naive | 52.1 | 40.4 | 7.5 |
461
- | shaped (keeper 20) **vs** naive | 43.6 | 45.9 | 10.6 |
462
- | shaped + cheap keeper **vs** shaped | 25.7 | 55.0 | 19.3 |
620
+ | shaped + cheap keeper **vs** naive | 51.7 | 40.4 | 7.9 |
621
+ | shaped (keeper 20) **vs** naive | 44.0 | 46.3 | 9.7 |
622
+ | shaped + cheap keeper **vs** shaped | 27.3 | 53.4 | 19.3 |
463
623
 
464
- Read the second and third rows together: **role shaping alone accounts for most
465
- of the advantage**, and the keeper budget adds a real but secondary edge on top.
466
- An agent that only differentiates its roles and never touches the keeper beats a
467
- naive squad 43.6% of the time and loses 10.6% a four-to-one record, with the
468
- rest drawn.
624
+ Every row moved by less than a point and a half; this is the table the re-seed
625
+ touched least. Read the second and third rows together: **role shaping alone
626
+ accounts for most of the advantage**, and the keeper budget adds a real but
627
+ secondary edge on top. An agent that only differentiates its roles and never
628
+ touches the keeper beats a naive squad 44.0% of the time and loses 9.7% — better
629
+ than four wins to one loss, with the rest drawn.
469
630
 
470
631
  ---
471
632
 
@@ -495,8 +656,8 @@ So even the two facts do not compose into one recommended shape. What survives
495
656
  is the negative advice: never leave points in the keeper's pass/dribble/shoot,
496
657
  and never scale a balanced keeper down.
497
658
 
498
- Keep it in proportion. Against a naive squad, role shaping alone wins 43.6% and
499
- adding a cheap keeper takes that to 52.1%. Role differentiation still decides
659
+ Keep it in proportion. Against a naive squad, role shaping alone wins 44.0% and
660
+ adding a cheap keeper takes that to 51.7%. Role differentiation still decides
500
661
  more matches than the keeper does.
501
662
 
502
663
  `SKILL.md` states the two facts separately and warns against scaling a balanced