pog-mcp 0.9.16 → 0.9.18

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.9.16",
3
+ "version": "0.9.18",
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",
@@ -664,18 +664,18 @@ sets it — there is no `fair:` outside the engine's own tests, and every engine
664
664
  input is built from an explicit field list — so it is a global constant in
665
665
  practice, and setting it on both squads IS the rule change.
666
666
 
667
- **Not swept: the zone-press coefficient.** At the time its selector was broken —
668
- every candidate weight was `0.0`, so `weightedPick` fell back to "the first non-GK
669
- slot" — and a coefficient in front of an undefined selection measures nothing. The
670
- selector was fixed in #730 (`zp-selector.mts` below); the coefficient is sweepable
671
- now but has not been swept.
667
+ **The zone-press coefficient waited for a selector.** While every candidate
668
+ weight at that scene was `0.0`, `weightedPick` fell back to "the first non-GK
669
+ slot" and a coefficient in front of an undefined selection measured nothing.
670
+ #730 fixed the selector (`zp-selector.mts` below), so the axis became sweepable
671
+ and it is swept here, over 1.5..4.5.
672
672
 
673
673
  ### The statistic, and why not the obvious one
674
674
 
675
675
  Rows below are in **win-equivalent share**: a win is 1, a draw is 0.5, a loss is
676
676
  0, and every match counts. The obvious alternative — win rate among DECIDED
677
677
  matches — conditions on something the swept constants themselves move. Free-kick
678
- occurrence takes the regulation draw rate from 57.9% to 38.1% across its range,
678
+ occurrence takes the regulation draw rate from 57.7% to 38.0% across its range,
679
679
  so a decided-only percentage mixes "who wins more" with "which matches got
680
680
  decided at all". It also inflates the number the activation gate is read
681
681
  against: an 11/80/9 record reads 55% decided, clearing a +5pp gate, while the
@@ -722,7 +722,7 @@ to count rather than a failure:
722
722
 
723
723
  | Measured every run | Result |
724
724
  | --- | --- |
725
- | Knockout draws, across both baskets | **0 in 5,440,000** knockout matches |
725
+ | Knockout draws, across both baskets | **0 in 10,880,000** knockout matches |
726
726
 
727
727
  That draw count is a claim this section originally got wrong in the other
728
728
  direction. It said knockout mode "has no draws by construction". It nearly does:
@@ -741,9 +741,10 @@ without — a paired test cannot detect misaligned columns from its own output,
741
741
  a freshly patched shipped-value engine is required to reproduce the default
742
742
  column match for match, in order.
743
743
 
744
- 3,400,000 matches in the narrow basket (5 archetypes, 10 fixtures, 10,000
745
- matches each, 17 conditions, both modes) plus 7,480,000 in the wide one.
746
- **Bonferroni over m = 8,320 pre-registered comparisons, two-sided: |z| >= 4.53.**
744
+ 6,800,000 matches in the narrow basket (5 archetypes, 10 fixtures, 10,000
745
+ matches each, 34 conditions, both modes) plus 14,960,000 in the wide one
746
+ (11 archetypes, 55 fixtures, 4,000 matches each, the same 34 conditions).
747
+ **Bonferroni over m = 17,160 pre-registered comparisons, two-sided: |z| >= 4.68.**
747
748
  That m prices the SEARCHES, not just the tests. A gate cell does not spend one
748
749
  hypothesis, and BOTH of its sides are data-chosen. The baseline side picks a
749
750
  leader out of K and builds a band around it — noisy standings could have named
@@ -770,10 +771,10 @@ power, not a minimum detectable effect. The 80%-power figure adds z(0.80):
770
771
 
771
772
  | median / worst | significance threshold | 80%-power effect |
772
773
  | --- | --- | --- |
773
- | narrow, regulation | 1.0 / 2.2pp | 1.2 / 2.6pp |
774
- | narrow, knockouts | 1.8 / 3.0pp | 2.1 / 3.6pp |
775
- | wide, regulation | 1.8 / 3.8pp | 2.1 / 4.5pp |
776
- | wide, knockouts | 2.9 / 4.8pp | 3.4 / **5.7pp** |
774
+ | narrow, regulation | 0.8 / 2.2pp | 0.9 / 2.6pp |
775
+ | narrow, knockouts | 1.5 / 3.1pp | 1.8 / 3.6pp |
776
+ | wide, regulation | 1.5 / 4.0pp | 1.7 / 4.7pp |
777
+ | wide, knockouts | 2.5 / 4.9pp | 3.0 / **5.7pp** |
777
778
 
778
779
  Read the worst column, not the median, since "every test is powered enough" is a
779
780
  claim about the tail — and read it honestly: **the worst wide-knockout fixture
@@ -796,10 +797,12 @@ gate, and says so.
796
797
  That only settles anything if the band is SHARP — noisy standings widen it, and
797
798
  a wide enough band absorbs every new leader, which would be a power limitation
798
799
  wearing the costume of a result. So the probe reports the band's own
799
- discrimination: it holds **2 of the 5** narrow squads and **3 of the 11** wide
800
- ones, with its edge **1.45pp** and **1.60pp** from the leader. A band that tight
801
- is not swallowing the basket. That is the number a smaller rerun moves, and the
802
- one to check before reusing this conclusion.
800
+ discrimination at its WORST over the searched weights: it holds **2 of the 5**
801
+ narrow squads and **3 of the 11** wide ones, with its edge **1.51pp** and
802
+ **2.29pp** from the leader. Two of five is not a band that has resolved the
803
+ basket — it is why this section's verdict is UNRESOLVED against a wide band
804
+ rather than "no contest", and it is the number a rerun with a further-apart
805
+ basket would move.
803
806
 
804
807
  ### The table
805
808
 
@@ -807,8 +810,11 @@ Basket: `role-433`, `def-433`, `def-532`, `shootonly-433`, `flat-433` — five
807
810
  outfield templates, the shared `squad-lib.mts` builders, so a row here and a row
808
811
  in the round-robin above are the same squads.
809
812
 
810
- - **`sig`** — fixture deltas clearing the corrected bar, out of 40 in the narrow
811
- basket (10 fixtures x 4 swept values) and out of 220 in the wide one (55 x 4).
813
+ - **`sig`** — fixture deltas clearing the corrected bar, out of **10 fixtures x
814
+ that axis's swept values** in the narrow basket and **55 x the same** in the
815
+ wide one. Most axes sweep four, so most rows read out of 40 and 220; set-piece
816
+ `dBonus` sweeps five to cover 3..8 end to end, so its rows read out of 50 and
817
+ 275.
812
818
  Both are printed, because an axis can be classified on the wide basket's
813
819
  evidence alone and a table that hid it would publish a verdict whose decisive
814
820
  measurement is invisible.
@@ -821,28 +827,93 @@ in the round-robin above are the same squads.
821
827
 
822
828
  | Axis (shipped) | Mode | sig (narrow) | sig (wide) | rev | Largest narrow delta | gate | What that row leaves FREE |
823
829
  | --- | --- | --- | --- | --- | --- | --- | --- |
824
- | **FK occurrence** `rand(10)<1` | reg | 21/40 | 102/220 | 0 | **+11.8pp** `role-433` vs `flat-433` @x4 | none | the FK taker: every basket squad kicks from slot 9, so this is "more free kicks", never "more free kicks AND a better taker" |
825
- | | ko | 18/40 | 100/220 | 0 | +8.8pp `def-532` vs `flat-433` @x4 | none — +7.5pp against `role-433` alone, 0.0pp against the band it belongs to | shootout exposure — it is a property of the PAIRING, and the basket fixes both halves |
826
- | **Post play** `rand(10)<1.5` | reg | 18/40 | 50/220 | 0 | −4.8pp `role-433` vs `flat-433` @x4 | none | the PP2 shooter is drawn by `getPlayer`, so the row confounds "more post plays" with "who the draw lands on" |
827
- | | ko | 5/40 | 40/220 | 0 | −3.4pp `role-433` vs `shootonly-433` @x4 | none | same, plus FW count: 433 and 532 field three and two forwards, and `fwIdx.length` gates the branch |
828
- | **Counter** `THRESHOLD=5` | reg | 3/40 | 5/220 | 0 | −2.0pp `shootonly-433` vs `flat-433` @0% | none | the four sampled thresholds span 0% to 100%, but changing this constant reroutes RNG consumption, so outcomes need not interpolate between them |
829
- | | ko | **0/40** | 7/220 | 0 | −1.2pp (below bar) | none | as above. This is the control: it never produced a gate in either basket, which is the only behaviour that matters here |
830
- | **`fair`** default 5 | reg | 13/40 | 37/220 | **1** | **+10.9pp** `shootonly-433` vs `flat-433` @22 | none | `fair` is uniform across all 22 players here; per-player or per-position `fair` is a different (and unmeasured) axis |
831
- | | ko | 7/40 | 23/220 | 0 | +10.9pp `shootonly-433` vs `flat-433` @22 | none | keeper `defense`, which every extra penalty routes through — held fixed inside each template |
832
-
833
- **Nothing here becomes a candidate.** All eight rows move margins somewhere — the
834
- control included, once the wide basket is counted — and
835
- the one pairing that re-prices anything does so against a squad that was already
836
- tied for best. The pass set at the plan's own activation gate is empty over both
837
- baskets, and the answer took a day rather than a release.
838
-
839
- **Empty for these four axes, which is not the same as empty for the pool.** The
840
- plan's weekly-rule pool also names set-piece `dBonus`, penalty attack noise, and
841
- base `dBonus`; none of them is swept here, and this run says nothing about them.
842
- The axes measured are the ones the issue behind this section listed — the two
843
- hardcoded rates, `fair`, and the counter control. Anyone reading this as
844
- "schedule nothing" should read it as "schedule none of these four, and go
845
- measure the other three before concluding anything about the pool."
830
+ | **FK occurrence** `rand(10)<1` | reg | 23/40 | 98/220 | 0 | **+11.8pp** `def-532` vs `flat-433` @x4 | none | the FK taker: every basket squad kicks from slot 9, so this is "more free kicks", never "more free kicks AND a better taker" |
831
+ | | ko | 19/40 | 92/220 | 0 | +8.5pp `def-532` vs `flat-433` @x4 | none | shootout exposure — it is a property of the PAIRING, and the basket fixes both halves |
832
+ | **Post play** `rand(10)<1.5` | reg | 16/40 | 52/220 | 0 | −5.0pp `role-433` vs `flat-433` @x4 | none | the PP2 shooter is drawn by `getPlayer`, so the row confounds "more post plays" with "who the draw lands on" |
833
+ | | ko | 7/40 | 33/220 | 0 | −4.1pp `def-532` vs `shootonly-433` @x4 | none | same, plus FW count: 433 and 532 field three and two forwards, and `fwIdx.length` gates the branch |
834
+ | **Counter** `THRESHOLD=5` | reg | 2/40 | 5/220 | 0 | −1.8pp `shootonly-433` vs `flat-433` @0% | none | the four sampled thresholds span 0% to 100%, but changing this constant reroutes RNG consumption, so outcomes need not interpolate between them |
835
+ | | ko | **0/40** | 3/220 | 0 | +1.5pp (below bar) | none | as above. This is the control: it never produced a gate in either basket, which is the only behaviour that matters here |
836
+ | **`fair`** default 5 | reg | 13/40 | 33/220 | **1** | **+11.4pp** `shootonly-433` vs `flat-433` @22 | none | `fair` is uniform across all 22 players here; per-player or per-position `fair` is a different (and unmeasured) axis |
837
+ | | ko | 7/40 | 28/220 | 0 | +10.7pp `shootonly-433` vs `flat-433` @22 | none | keeper `defense`, which every extra penalty routes through — held fixed inside each template |
838
+ | **Set-piece `dBonus`** 5 | reg | 15/50 | 56/275 | 0 | −1.7pp `def-532` vs `flat-433` @8 | none | it widens the DEFENDER's roll at FK1/FK2 only, and the taker is slot 9 in every basket squad. Five swept values, not four: 3..8 end to end with the default column carrying 5 |
839
+ | | ko | 10/50 | 74/275 | 0 | +1.4pp `role-433` vs `shootonly-433` @8 | none | same, plus the shootout, which this axis does not touch (`takePkShot` has its own width) |
840
+ | **Base `dBonus`** 8 | reg | 25/40 | 43/220 | 0 | +2.9pp `def-532` vs `flat-433` @6 | none | the widest-reaching of the seven — it is the defender roll for every non-set-piece contest — and still nothing re-prices |
841
+ | | ko | 14/40 | 41/220 | 0 | +3.7pp `def-532` vs `shootonly-433` @6 | none | as above |
842
+ | **PK attack noise** `rand(16)` | reg | 9/40 | 25/220 | 0 | +0.9pp `role-433` vs `def-532` @8 | none | in regulation it reaches only awarded penalties, which is why the row is nearly flat |
843
+ | | ko | 25/40 | 102/220 | 0 | **+9.7pp** `role-433` vs `def-532` @8 | none | the shootout routes every kick through it, so knockouts feel it and regulation barely does — the largest mode split in the table, and still no gate |
844
+ | **Zone press** `ratio * 3` | reg | **0/40** | **0/220** | 0 | −0.8pp `def-433` vs `flat-433` @4.5 | none | the axis #730 unblocked, and the only one in the file that moves NOTHING: zero significant deltas in either basket, in either mode |
845
+ | | ko | **0/40** | **0/220** | 0 | +1.0pp `def-433` vs `def-532` @1.5 | none | as above. INERT rather than MARGINS — even the counter control clears the bar somewhere |
846
+
847
+ **Nothing here becomes a candidate.** Fourteen of the sixteen rows move margins
848
+ somewhere — the control included, once the wide basket is counted — and the one
849
+ pairing that re-prices anything does so against a squad that was already tied for
850
+ best. The two that move nothing at all are zone press, in both modes. The pass
851
+ set at the plan's own activation gate is empty over both baskets.
852
+
853
+ **The pool is now measured end to end, and nothing in it clears the gate.** An
854
+ earlier run covered only four
855
+ axes and said so: schedule none of those four, and go measure the other three
856
+ before concluding anything about the pool. Those three — set-piece `dBonus`,
857
+ base `dBonus` and penalty attack noise — are in the table above and land where
858
+ the first four did.
859
+
860
+ And the pool is now COMPLETE: the zone-press coefficient, the one parameter the
861
+ plan named but forbade "until #730 decides the selector", is swept here too — the
862
+ selector was decided, so the prohibition lapsed. It comes back INERT, the only
863
+ axis in the file that moves no fixture in either basket in either mode.
864
+
865
+ Two axes are covered END TO END, because the plan gives them ranges and the sweep
866
+ spans them: set-piece `dBonus` over 3..8 (five swept values plus the default 5)
867
+ and base `dBonus` over 6..10 (four plus the default 8). **Penalty attack noise
868
+ and zone press are not**: §8 3.1 names their constants — `rand(16)` and
869
+ `ratio * 3` — and no range, so this run picked ±25% and ±50% around each and the
870
+ conclusions are bounded to 8..24 and 1.5..4.5. A rule proposing a value outside
871
+ those spans is unmeasured, and these do not interpolate — changing them reroutes
872
+ the RNG stream. **No axis produced a candidate that clears the gate: the largest
873
+ gain reachable at ANY exposure weight, across all eight axes, both baskets and
874
+ 20,146 solved interior weights, is 0.00pp against a 5pp threshold.**
875
+
876
+ **And that is a failure to distinguish, not a demonstration that nothing is
877
+ there.** The distinction is the whole reading of this section, so it is worth
878
+ being exact about. A gate cell is scored by pairing the swept optimum against the
879
+ stale one; every one of the 99 cells per basket formed NO PAIR, because the
880
+ swept optimum was already inside the default band. A cell that forms no pair
881
+ contributes a zero gain, and 99 zeros is what produces the 0.00pp above — so the
882
+ headline number is the ABSENCE of a resolvable contest, not the presence of a
883
+ measured null. Whether an axis re-prices the decision is therefore **UNRESOLVED**
884
+ on this evidence.
885
+
886
+ What would resolve it is a sharper band. At its worst the default band holds 2 of
887
+ the 5 narrow squads, with the edge 1.51pp from the leader, and 3 of 11 in the wide
888
+ basket at 2.29pp: a band that wide absorbs any new leader before the gate can
889
+ weigh it. A basket whose members sit further apart would shrink it. A lower bar
890
+ would not — that would only relabel the same inability.
891
+
892
+ One thing this is definitely NOT: "these constants do nothing". PK attack noise
893
+ moves a knockout fixture by 9.7pp and base `dBonus` moves a regulation one by
894
+ 2.9pp; margins move everywhere, and the wide basket below changes the top build
895
+ in 12 of 33 knockout cells. What none of that reaches is the gate.
896
+
897
+ **Scope, stated once and plainly.** Every row above is measured at `cond` 5 on
898
+ both sides, and production has not been that since #794 turned the form system
899
+ on. `getPoint` reads condition in both its individual and its team term, so a
900
+ swept threshold can interact with it; this run cannot see that interaction. So
901
+ the claim this section supports is **no pool axis clears the gate under neutral
902
+ conditions**, not "under production conditions" — closing that gap means
903
+ re-running the pool over representative frozen condition states, which is a
904
+ separate measurement and is not done here.
905
+
906
+ **What that means for 3.1.** The pool produced no schedulable candidate, and
907
+ this run cannot say whether that is because none exists or because its basket
908
+ cannot resolve one. So 3.1's premise — that a weekly rule rotates which build is
909
+ worth fielding — is **not supported by anything measured here, and not refuted
910
+ either.** Two measurements would move it: a basket whose members sit further
911
+ apart, which is what the unformed gates are asking for, and a rerun over
912
+ production's condition states. Building the feature on this evidence would be
913
+ building on an unresolved gate; shelving it permanently on this evidence would
914
+ be over-reading the same gate in the other direction. That is a product call
915
+ rather than a
916
+ measurement one, and it is recorded on #733.
846
917
 
847
918
  The verdict is deliberately absent from the rows above: it belongs to the AXIS,
848
919
  not to a mode. The next section is where it is issued.
@@ -899,7 +970,7 @@ nothing, and no amount of simulation shrinks that. Nor can the difference be
899
970
  paired away: the leader and its weakest opponent are argmax and argmin picks
900
971
  that can change IDENTITY between the two conditions, so there is no fixed pair
901
972
  to difference. What this probe does instead is a 2-sigma DIRECTION screen at
902
- +3.0. It refuses far more than a corrected test would — that would sit near 6.4
973
+ +3.0. It refuses far more than a corrected test would — that would sit near 6.6
903
974
  — which is the safe direction for a gate whose job is to refuse. It is a
904
975
  heuristic, it says so in the probe's own legend, and it is not the plan's
905
976
  sentence. The plan does not put numbers on the feel bands, so the ones
@@ -917,10 +988,14 @@ new leader drawn FROM the band scores zero by construction.
917
988
 
918
989
  | Axis | Best value | Gate (ko weight 0.081) | dom | domAbs | draw | goals | Blocked by |
919
990
  | --- | --- | --- | --- | --- | --- | --- | --- |
920
- | FK occurrence | x0.25 | **0.00pp** | +0.4 | 0.4 | **+5.1pp** | −16% | gain — and it would also fail the draw band |
921
- | Post play | x0.25 | **0.00pp** | −0.1 | 0.0 | −1.0pp | +3% | gain |
922
- | Counter (control) | 0% | **0.00pp** | +0.7 | 0.9 | +1.4pp | −6% | gain |
923
- | `fair` | 1 | **0.00pp** | +0.5 | 0.6 | +3.6pp | −12% | gain |
991
+ | FK occurrence | x0.25 | **0.00pp** | +0.1 | 0.3 | **+5.0pp** | −16% | gain — and it would also fail the draw band |
992
+ | Post play | x0.25 | **0.00pp** | +0.7 | 1.1 | −1.1pp | +3% | gain |
993
+ | Counter (control) | 0% | **0.00pp** | +0.4 | 0.8 | +1.4pp | −6% | gain |
994
+ | `fair` | 1 | **0.00pp** | −0.2 | 0.2 | +3.7pp | −12% | gain |
995
+ | Set-piece `dBonus` | 3 | **0.00pp** | +0.6 | 0.2 | −2.4pp | +8% | gain |
996
+ | Base `dBonus` | 6 | **0.00pp** | −0.2 | 0.2 | **−5.1pp** | +22% | gain |
997
+ | PK attack noise | 8 | **0.00pp** | +1.1 | 0.1 | +1.1pp | −4% | gain |
998
+ | Zone press | x0.5 | **0.00pp** | +1.1 | 0.2 | −1.3pp | +5% | gain — and it is INERT, not MARGINS |
924
999
 
925
1000
  `dom` is the CHANGE in the leader's weakest margin; `domAbs` is that margin
926
1001
  itself, in the eleven-archetype basket. Both block, and the two are not
@@ -928,7 +1003,7 @@ interchangeable: a rule that leaves an already-dominant squad exactly where it
928
1003
  stood scores a `dom` near zero while failing the requirement outright, which is
929
1004
  why the absolute column exists at all. `domAbs` is the one carrying the plan's
930
1005
  sentence — at or past the corrected bar, the same |z| the rest of this section
931
- uses, 4.53 at these sample sizes, one squad significantly beats every other,
1006
+ uses, 4.68 at these sample sizes, one squad significantly beats every other,
932
1007
  which is what a dominant build is. `dom` is the direction screen described
933
1008
  above, at a threshold this probe declares rather than quotes.
934
1009
 
@@ -957,6 +1032,10 @@ table is not four verdicts.)
957
1032
  | Post play | 0.00pp | 0.00pp | 0.00pp |
958
1033
  | Counter (control) | 0.00pp | 0.00pp | 0.00pp |
959
1034
  | `fair` | 0.00pp | 0.00pp | 0.00pp |
1035
+ | Set-piece `dBonus` | 0.00pp | 0.00pp | 0.00pp |
1036
+ | Base `dBonus` | 0.00pp | 0.00pp | 0.00pp |
1037
+ | PK attack noise | 0.00pp | 0.00pp | 0.00pp |
1038
+ | Zone press | 0.00pp | 0.00pp | 0.00pp |
960
1039
 
961
1040
  Those three points do not settle the interior on their own: each squad's
962
1041
  weighted score is linear in the weight, the leader is their upper envelope, and
@@ -979,11 +1058,11 @@ on its own grid answers a different question. Evaluating every boundary, and
979
1058
  inside every resulting interval its midpoint plus both ONE-SIDED limits (the
980
1059
  gain jumps where the leader changes, so a shared endpoint reports the wrong
981
1060
  squad), plus the weights where the two baskets' gain lines cross — that is where
982
- `min(narrow, wide)` peaks when their slopes oppose — comes to 9,816 probe
1061
+ `min(narrow, wide)` peaks when their slopes oppose — comes to 20,146 probe
983
1062
  weights across every value:
984
1063
 
985
1064
  > **The largest gain reachable at ANY exposure weight is 0.00pp**, against a 5pp
986
- > threshold. At all 9,816 probe weights the swept optimum was already inside the
1065
+ > threshold. At all 20,146 probe weights the swept optimum was already inside the
987
1066
  > default band in at least one basket.
988
1067
 
989
1068
  That statement deliberately carries no significance claim, and does not need
@@ -1017,8 +1096,8 @@ on every run instead of implying it did.
1017
1096
 
1018
1097
  **And the near miss is not a near miss.** FK x0.25 fails the gain gate outright —
1019
1098
  0.00pp, because the build it promotes was already inside the default band — and
1020
- it would fail the draw band too, at +5.1pp against a +/-5pp limit. Its dominance
1021
- is fine on the weighted season (+0.4 change, 0.4 absolute), which is worth
1099
+ it would fail the draw band too, at +5.0pp against a +/-5pp limit. Its dominance
1100
+ is fine on the weighted season (+0.1 change, 0.3 absolute), which is worth
1022
1101
  stating precisely: an earlier version of this section read dominance off the two
1023
1102
  pure modes and reported +4.4, and that was an artefact of not weighting. The
1024
1103
  candidate that looked closest to shippable still fails, but on the gain and the
@@ -1027,8 +1106,9 @@ feel band, not on concentration.
1027
1106
  ### What the control calibrates
1028
1107
 
1029
1108
  The counter trigger is in this sweep to check that the bar rejects things, and
1030
- under a paired test it is **not** inert: 3 of 40 narrow fixture deltas clear the
1031
- bar, and 12 of 440 across the wide basket's two modes. They are small — and no
1109
+ under a paired test it is **not** inert: 2 of its 80 narrow fixture deltas clear
1110
+ the bar (both in regulation; knockouts give 0 of 40), and 8 of 440 across the
1111
+ wide basket's two modes. They are small — and no
1032
1112
  value of it ever produced a gate, in either basket, at any exposure weight. That
1033
1113
  is the useful result:
1034
1114
 
@@ -1038,22 +1118,34 @@ is the useful result:
1038
1118
 
1039
1119
  It also supplies a floor. In the NARROW basket — same N, same ten fixtures on
1040
1120
  both sides, the only comparison here that is apples to apples — the largest
1041
- movement this known non-lever produces is **2.0pp**. Anything a candidate does
1121
+ movement this known non-lever produces is **1.8pp**. Anything a candidate does
1042
1122
  that is not comfortably above that is not distinguishable from what a knob
1043
1123
  nobody would ship already does:
1044
1124
 
1045
- | Axis | Mode | Largest fixture move | vs the control's 2.0pp |
1125
+ | Axis | Mode | Largest fixture move | vs the control's 1.8pp |
1046
1126
  | --- | --- | --- | --- |
1047
- | FK occurrence | reg | 11.8pp | **6.0x** |
1048
- | FK occurrence | ko | 8.8pp | **4.4x** |
1049
- | `fair` | reg | 10.9pp | **5.5x** |
1050
- | `fair` | ko | 10.9pp | **5.5x** |
1051
- | Post play | reg | 4.8pp | 2.4x |
1052
- | Post play | ko | 3.4pp | **1.7x** — the closest any candidate comes to the floor |
1053
-
1054
- The probe flags a row as indistinguishable from the control below **1.5x**, so
1055
- post play in knockouts clears that line — but only just, and by less than any
1056
- other candidate-mode pair in the table.
1127
+ | FK occurrence | reg | 11.8pp | **6.6x** |
1128
+ | FK occurrence | ko | 8.5pp | **4.8x** |
1129
+ | `fair` | reg | 11.4pp | **6.4x** |
1130
+ | `fair` | ko | 10.7pp | **6.0x** |
1131
+ | PK attack noise | ko | 9.7pp | **5.5x** |
1132
+ | Post play | reg | 5.0pp | 2.8x |
1133
+ | Post play | ko | 4.1pp | 2.3x |
1134
+ | Base `dBonus` | ko | 3.7pp | 2.1x |
1135
+ | Base `dBonus` | reg | 2.9pp | 1.6x |
1136
+ | Set-piece `dBonus` | reg | 1.7pp | **0.9x — inside the control's own noise** |
1137
+ | Set-piece `dBonus` | ko | 1.4pp | **0.8x — inside the control's own noise** |
1138
+ | PK attack noise | reg | 0.9pp | **0.5x — inside the control's own noise** |
1139
+ | Zone press | ko | 1.0pp | **0.6x — inside the control's own noise** |
1140
+ | Zone press | reg | 0.8pp | **0.5x — inside the control's own noise** |
1141
+
1142
+ The probe flags a row as indistinguishable from the control below **1.5x**.
1143
+ Five of the fourteen candidate rows are below it — the control is the floor, so
1144
+ it is not one of them — and all five belong to the axes this run added: set-piece
1145
+ `dBonus` in both modes, PK noise in regulation, and zone press in both modes move
1146
+ a fixture LESS than a knob nobody would ship. PK noise in knockouts is the
1147
+ opposite case — 5.5x, fourth largest behind FK regulation at 6.6x and `fair` at
1148
+ 6.4x and 6.0x — which is the shootout, and still no gate.
1057
1149
 
1058
1150
  The control is swept in BOTH baskets — that is what the gate needs — but this
1059
1151
  ratio is deliberately narrow-only on both sides. It compares a MAXIMUM over a
@@ -1065,43 +1157,53 @@ these ratios by a factor of two between runs that changed no measurement.
1065
1157
  ### Per axis, what actually moved
1066
1158
 
1067
1159
  **FK occurrence is the strongest axis, and what it does is CONCENTRATE.** From
1068
- 2.5% to 40% the regulation draw rate runs 57.9% -> 52.8% (shipped) -> 38.1% and
1069
- goals per match 0.653 -> 0.779 -> 1.288. Every large delta at x4 has the same
1160
+ 2.5% to 40% the regulation draw rate runs 57.7% -> 52.6% (shipped) -> 38.0% and
1161
+ goals per match 0.658 -> 0.787 -> 1.290. Every large delta at x4 has the same
1070
1162
  shape: the differentiated squads pull away from `flat-433` (`role-433` vs
1071
- `flat-433` 68.4% -> 80.2% of the win-equivalent share). Turning it DOWN
1072
- compresses the field instead — `flat-433`'s points per match rises 0.769 ->
1073
- 0.842 while every other squad's falls. So the axis is a skill-expression dial:
1163
+ `flat-433` 68.1% of the win-equivalent share at the shipped rate, +11.4pp of it
1164
+ at x4). Turning it DOWN
1165
+ compresses the field instead — `flat-433`'s own share rises 0.335 -> 0.368 while
1166
+ every other squad's falls. So the axis is a skill-expression dial:
1074
1167
  more free kicks means more of the match decided by who invested, less means more
1075
1168
  of it decided by nothing. Turning it down therefore costs on both feel gates at
1076
1169
  once — more draws AND fewer goals — and in knockouts alone it also raises the
1077
- leader's weakest margin from z 6.3 to 8.9, which points at concentration rather
1170
+ leader's weakest margin from z 5.2 to 6.6, which points at concentration rather
1078
1171
  than rotation. Read that as the knockout-only reading it is: on the
1079
1172
  exposure-weighted season the same change is +0.4, well inside the direction
1080
1173
  screen, and the activation table above reports the weighted number.
1081
1174
 
1082
1175
  **`fair` is the only axis that ROTATES demand rather than amplifying it.**
1083
- Raising it from 4.5% to 100% moves `shootonly-433` from 1.127 to 1.302 points
1084
- per match in regulation and 1.370 to 1.518 in knockouts, while `role-433` and
1085
- `def-433` stand still — more fouls means more free kicks and penalties, and
1086
- those are converted by `shoot`. It carries the run's single reversal: `role-433`
1087
- vs `def-433` goes from **47.5%** at the shipped default to **50.8%** at
1088
- `fair 22`. Read that precisely — the DELTA is significant, the new level is a
1176
+ Raising it from the shipped 22.7% to 100% moves `shootonly-433`'s
1177
+ win-equivalent share from 0.451 to 0.498 in regulation and 0.456 to 0.505 in
1178
+ knockouts, while `role-433` and `def-433` stand still or fall — more fouls means
1179
+ more free kicks and penalties, and those are converted by `shoot`. It carries the
1180
+ run's single reversal: `role-433` vs `def-433` goes from **47.2%** at the shipped
1181
+ default to **50.3%** at `fair 22`. Read that precisely — the DELTA is significant, the new level is a
1089
1182
  coin flip. The rule turned "the defensive lean is better" into "there is no
1090
1183
  difference", which is a re-pricing; it did not turn it into "the attacking lean
1091
1184
  is better".
1092
1185
 
1093
1186
  `fair` is also the only axis whose regulation dominance column does not move
1094
1187
  (+0.0). At the midpoint (`fair 11`, 50%) it still moves four fixtures
1095
- significantly while taking the draw rate DOWN, 52.8% -> 48.6%, and goals up,
1096
- 0.779 -> 0.899 — the one cell in the whole sweep whose feel side-effects point
1188
+ significantly while taking the draw rate DOWN, 52.6% -> 48.4%, and goals up,
1189
+ 0.787 -> 0.903 — the one cell in the whole sweep whose feel side-effects point
1097
1190
  in a direction anyone would ask for.
1098
1191
 
1099
- **Post play is the weakest candidate.** Its largest move is 2.4x the control's
1100
- in regulation and 1.7x in knockouts — the closest any candidate comes to a knob
1101
- that gates 3.9% of goals. It needs x4 (60% of box entries) to reach even that,
1102
- the feel barely registers (draw rate +4.3pp, goals −0.095), and across all eight
1103
- of its wide-basket cells — four swept values in each mode — the top of the
1104
- eleven-archetype table never changes.
1192
+ **Set-piece `dBonus` is the weakest axis that moves anything at all.** Zone press
1193
+ is weaker and moves nothing: it is the only INERT row here, 0 significant deltas
1194
+ in either basket. Set-piece `dBonus` does clear the bar in 15 narrow and 56 wide
1195
+ regulation cells, but its largest move is 0.9x the control's in regulation and
1196
+ 0.8x in knockouts — a knob that gates 3.9% of goals moves a fixture MORE than it
1197
+ does. The feel barely registers either —
1198
+ its regulation draw rate spans 50.2% to 55.9% across the whole 3..8 range — yet
1199
+ it still changes the top of the
1200
+ eleven-archetype knockout table in two of its ten wide-basket cells, which is
1201
+ the whole lesson of the wide basket restated: moving a table's top is cheap,
1202
+ and moving the decision is what the gate asks about.
1203
+
1204
+ **Post play needs its whole range to reach 2.8x.** It gets there only at x4
1205
+ (60% of box entries), and the feel barely registers on the way (draw rate
1206
+ +4.4pp, goals −0.096).
1105
1207
 
1106
1208
  **The counter trigger never gates.** Swept from "counters never happen" to
1107
1209
  "every eligible turnover becomes one", goals per match moved 0.036, the basket's
@@ -1117,8 +1219,7 @@ The narrow basket's biggest weakness is that five archetypes may simply not
1117
1219
  contain the alternative a rule rewards. So EVERY swept value of every axis — the
1118
1220
  control included, so it is checked on the same surface as the candidates — is
1119
1221
  re-asked over the ELEVEN archetypes the round-robin publishes, 55 fixtures,
1120
- 4,000 matches each. That is 34 cells; the probe prints them all, and the shape
1121
- is simple enough to state:
1222
+ 4,000 matches each. That is 68 cells, 34 per mode; the probe prints them all.
1122
1223
 
1123
1224
  Standings here are the **win-equivalent share** — the same 1 / 0.5 / 0 statistic
1124
1225
  the gate measures, so the leader they name is the squad the gate is then
@@ -1126,26 +1227,47 @@ evaluated on. Ranking by league points instead is not a monotonic
1126
1227
  transformation of it when draw rates differ, and these constants move draw rates
1127
1228
  by fifteen points.
1128
1229
 
1129
- | Mode | Shipped rule's top four | Last | Cells whose top changed |
1230
+ | Mode | Shipped rule's top four | Last | Swept cells whose top changed |
1130
1231
  | --- | --- | --- | --- |
1131
- | reg | `gkmin-433` .603, `def-433` .586, `def-532` .585, `role-433` .564 | `flat-433` .365 | **none of 16** |
1132
- | ko | `role-433` .615, `gkheavy-433` .599, `def-433` .591, `def-532` .573 | `flat-433` .259 | **2 of 16**, both FK down |
1133
-
1134
- In regulation, `gkmin-433` leads every single cell — nothing moves the answer at
1135
- any value of any axis. The two knockout exceptions are FK x0.25 and FK x0.5,
1136
- which both promote `gkheavy-433` (+7.5pp z 4.7 and +6.0pp z 3.8 against
1137
- `role-433`; 0.0pp against the tied band it belongs to). `flat-433` is last in 32
1138
- of the 34 cells; the two it is not are FK x0.25 and x0.5 in regulation, where
1139
- `stars-433` drops below it — that build wins and loses far more than it draws,
1140
- so a metric that counts draws at half costs it more than a points table does.
1141
-
1142
- **That one axis-and-direction is the most interesting number in this section.**
1143
- Read as a pair in both rules:
1144
-
1145
- > `gkheavy-433` vs `role-433`, knockout: **49.8% (z −0.3) at the shipped FK rate
1146
- > -> 53.7% (z +4.7) at FK x0.25.** A coin flip becomes a significant win. Those
1147
- > are shares; the +7.5pp above is the same reading as a win-rate advantage, which
1148
- > is exactly twice the share advantage over 50%.
1232
+ | reg | `gkmin-433` .601, `def-532` .586, `def-433` .586, `role-433` .557 | `flat-433` .365 | **1 of 33** (`fair 22`, and not significantly) |
1233
+ | ko | `role-433` .603, `gkheavy-433` .597, `def-433` .595, `def-532` .572 | `flat-433` .258 | **12 of 33**, two of them significant |
1234
+
1235
+ Regulation is almost immovable: `gkmin-433` leads 32 of the 33 swept cells, and
1236
+ the one exception (`fair 22`, where `def-532` reads .592 against `gkmin-433`'s
1237
+ .590) is not
1238
+ significant. `flat-433` is last in all 68 cells.
1239
+
1240
+ **Knockouts are where the newly swept axes show up.** Twelve cells change the
1241
+ top build, and the two that do so significantly are `fk x0.25` (+9.8pp, z 6.2)
1242
+ and `pknoise 8` (+11.4pp, z 7.2), both promoting `gkheavy-433` over `role-433`;
1243
+ `pknoise 12` (+7.3pp, z 4.7) misses the corrected bar. Base `dBonus` and set-piece `dBonus` change the
1244
+ top in six more cells, none significantly.
1245
+
1246
+ **Read the width axes as mean AND variance, not variance alone.** `randFloat(w)`
1247
+ is uniform on [0, w), so its mean is w/2: taking base `dBonus` from 8 to 10 does
1248
+ not just widen the defender's roll, it raises that defender's expected score from
1249
+ 4 to 5, and narrowing it to 6 lowers the mean to 3. The kicker's PK roll moves the
1250
+ same way in the other direction. So the pattern — `fk 0.25`/`0.5`, `pknoise 8`/`12`
1251
+ and `dbonus 9`/`10` promoting the 29-point keeper, while `dbonus 6`/`7` and
1252
+ `pknoise 24` hand `def-433` the lead — is consistent with "whose contest is made
1253
+ decisive" AND with a straight shift in who is favoured on average, and this run
1254
+ cannot separate the two. A rule designer reading a mechanism off these rows would
1255
+ be guessing; separating them needs rolls centred on their shipped mean, which is
1256
+ a different experiment from the one the plan's parameter names.
1257
+
1258
+ **None of it produces a gate.** The promoted build was already inside the
1259
+ default band every time — that is why the gate column reads 0.00pp for all seven
1260
+ axes while this table moves as much as it does. Changing which build is at the
1261
+ TOP of a table is not the same as re-pricing the DECISION, and this section is
1262
+ the clearest demonstration of the difference in the file.
1263
+
1264
+ **The FK direction is the pair worth reading in full**, because the same
1265
+ promotion arrives three separate ways and this is the one with a shipped-rule
1266
+ baseline to compare against:
1267
+
1268
+ > `gkheavy-433` vs `role-433`, knockout: **50.9% (z +1.1) at the shipped FK rate
1269
+ > -> 54.9% (z +6.2) at FK x0.25.** A coin flip becomes a significant win. Those
1270
+ > are shares; a win-rate advantage is exactly twice the share advantage over 50%.
1149
1271
 
1150
1272
  Mechanically that is coherent: fewer free kicks means fewer set-piece goals,
1151
1273
  more matches level at full time, more shootouts, and the 29-point keeper the
@@ -1169,31 +1291,32 @@ since none of these constants is scheduled.
1169
1291
 
1170
1292
  And it is worth **0.0pp at the activation gate** — in the mode with the LEAST
1171
1293
  exposure, since knockouts are cup-only and the cup runs once a day for the
1172
- ladder's top 48. Two things reduce it from +7.5pp to nothing, and both are in
1294
+ ladder's top 48. Two things reduce it from +9.8pp to nothing, and both are in
1173
1295
  the activation section above. `gkheavy-433` is inside the shipped rule's
1174
1296
  unresolved top band, so a manager could already have been on it for free. And
1175
- the same cell moves the draw rate +5.1pp, outside the +/-5pp band a rule change
1176
- is allowed to move it, so even a real gain there would have been refused.
1297
+ the same cell moves the draw rate +5.0pp, at the edge of the +/-5pp band a rule
1298
+ change is allowed to move it, so even a real gain there would have been
1299
+ argued about before it shipped.
1177
1300
 
1178
1301
  Incidentally, the shipped rows above are an 11-archetype round-robin at 4,000
1179
1302
  matches per fixture — roughly seven times the 300 seeds behind the published
1180
1303
  table — and they agree with it where that table says it is decidable:
1181
1304
  `gkmin-433` clear at the top of regulation, `role-433` at the top of knockouts,
1182
- `flat-433` at the bottom of all but two. The middle band still reorders between
1305
+ `flat-433` at the bottom of every one of the 68 cells. The middle band still reorders between
1183
1306
  the two runs, as that section says it must — and note that the bottom is where
1184
1307
  the metric matters: on a points table `stars-433` is above `flat-433`, and on
1185
1308
  the win-equivalent share the two swap in a couple of cells. The shipped `role-433` vs `def-433`
1186
1309
  fixture also independently reproduces the Skill's "solidity beats aggression"
1187
- pair at 10,000 matches: the attacking lean takes 47.5% of the win-equivalent
1188
- share in regulation and 53.1% in knockouts.
1310
+ pair at 10,000 matches: the attacking lean takes 47.2% of the win-equivalent
1311
+ share in regulation and 52.6% in knockouts.
1189
1312
 
1190
- **Do not read that 47.5% against the Skill's 56.5%** — they are different
1313
+ **Do not read that 47.2% against the Skill's 56.5%** — they are different
1191
1314
  statistics on the same fact. The Skill quotes DECIDED matches, this section
1192
1315
  quotes the win-equivalent share, and half of all regulation matches are draws,
1193
1316
  so the share is compressed toward 50 exactly as the round-robin correction above
1194
- warns. The knockout figures (53.1% here, 53.6% there) are directly comparable,
1195
- because knockout draws are vanishingly rare — zero in the 5,440,000 knockout matches
1196
- this run played, though not structurally impossible.
1317
+ warns. The knockout figures (52.6% here, 53.6% there) are directly comparable,
1318
+ because knockout draws are vanishingly rare — zero in the 10,880,000 knockout
1319
+ matches this run played, though not structurally impossible.
1197
1320
 
1198
1321
  ### Degrees of freedom this sweep LEFT free
1199
1322
 
@@ -1211,12 +1334,18 @@ uncontrolled degree of freedom each time. So, explicitly:
1211
1334
  and the zone press, the team-contribution terms and possession all read it.
1212
1335
  - **Set-piece slots.** `squad-lib` pins the FK taker to slot 9 and the penalty
1213
1336
  taker to slot 10 for every candidate. The FK rows are the RATE axis only.
1214
- - **Slot order.** Identical across the basket, which pins the broken zone-press
1215
- fallback to the same position in all of them. Held constant, not measured.
1337
+ - **Slot order.** Identical across the basket. It used to carry a confound —
1338
+ the zone-press fallback made the first non-GK slot a hidden lever — and #730
1339
+ removed it, so the zone-press rows here are not contaminated by it. Held
1340
+ constant either way, and not measured.
1216
1341
  - **Interactions.** One axis moves at a time. Nothing here says what FK x4 does
1217
1342
  while `fair` is 22, and a pool built from two axes at once is untested.
1218
- - **`cond`.** Fixed at 5 everywhere, as production does today. A form system
1219
- would invalidate every row.
1343
+ - **`cond`.** Fixed at 5 everywhere, and production no longer is: #794 turned
1344
+ the form system on, so competitive matches now arrive with per-player
1345
+ conditions derived and frozen at claim time. `getPoint` reads `cond` in both
1346
+ the individual and the team term, so a swept threshold can interact with it,
1347
+ and **every row here is a neutral-condition row.** That is the single largest
1348
+ scope limit on this section's conclusion — see the verdict, which states it.
1220
1349
  - **Opponent population.** Archetypes, not the live ladder — and production bots
1221
1350
  are a single build, which is neither.
1222
1351
 
@@ -4830,3 +4959,267 @@ few points, as any change to who presses must.
4830
4959
  original expression cannot be recovered.
4831
4960
 
4832
4961
  5,648,400 matches in about a minute. Whole run: `zp-selector.mts`.
4962
+
4963
+ ## Do the six pog axis candidates move the outcome, and are any of them a decision? (`pog-axes.mts`)
4964
+
4965
+ Six candidates for the pog playbook (issue #809, gate G0): `balance`, `line`,
4966
+ `press`, `build`, `keeper`, `set_piece`. Every one ships as a **selection**
4967
+ preference — abilities stay frozen from creation (F-6) and a playbook only
4968
+ chooses who starts, at which position, and who takes kicks. This probe
4969
+ measures by sweeping 212-point TEMPLATES: the question is whether the engine
4970
+ is sensitive to the profile difference at all; selection realizes it
4971
+ discretely, checked separately in a 17-player-pool companion measurement.
4972
+
4973
+ Five of the six realizations change `squad-lib.mts`'s `build()` inputs;
4974
+ `set_piece` instead reassigns the already-built team's `fkKicker`/`pkKicker`
4975
+ flags directly (`build()` itself hardcodes those flags onto slots 9/10, so
4976
+ this is still a 212-template property, just set via a different code path).
4977
+ `D_*_APPR` (issue #745) is the one axis that patches the engine, via the
4978
+ `appr-role.mts`/#728 exact-match-count-asserted source-replace pattern.
4979
+
4980
+ Eight Codex review rounds (41 findings total, 1 deferred to a follow-up
4981
+ issue rather than fixed inline — see "What Codex found") progressively
4982
+ hardened the isolation guarantees. Highlights load-bearing for the tables
4983
+ below: `balance`/`press` pin the goalkeeper BYTE-IDENTICAL to the base
4984
+ squad, including for `mid`. `line` (round 8) instead clones all 11 existing
4985
+ players byte-for-byte and relabels only the `position` field to the new
4986
+ formation's slot — no attribute rebuild at all, so no GK-pinning pipeline
4987
+ is even needed for this axis. `D_*_APPR`'s focus policies override the
4988
+ argmax player's selection weight to 1,000,000 (not 1024 — see "What Codex
4989
+ found"). `set_piece` ranks FK/PK candidates independently by the actual
4990
+ engine formula: `getPoint`/`takePkShot` show both use `atkSkill + cond/2 +
4991
+ total/3 + roll`, and FK's single `fkKicker` flag triggers a 50/50 mix of a
4992
+ shoot-based and a pass-based branch, so the expected-value-optimal ranking
4993
+ for BOTH roles is `(pass+shoot)/2 + total/3` — with a tie-break that keeps
4994
+ the two roles on different players. This still omits `ofTeamContrib`, a
4995
+ team-aggregate term `getPoint` also adds — round 8's Finding 1, deferred
4996
+ (see "What Codex found").
4997
+
4998
+ ### Method
4999
+
5000
+ Four cores (`flat`, `shaped`, `gkheavy`, `gkmin`). Each axis is a `low`/`mid`/
5001
+ `high` ladder; `low`/`high` change exactly one dimension of `build()`'s
5002
+ inputs (see `docs/pog/02-axes-measurement.md` §2). Opponent grid = the same
5003
+ four cores, both modes, `N=20,000` per cell, seeds keyed on
5004
+ `(axis, myCoreKey, oppCoreKey, mode)`. Bonferroni family size (m=706)
5005
+ computed analytically before any comparison runs. Non-monotone requires BOTH
5006
+ ladder legs to individually clear the bar with opposite signs, on the
5007
+ self-play cell. Opponent-conditional requires a candidate to beat both
5008
+ others at the same bar, for each opponent.
5009
+
5010
+ Adoption is judged on "significant against any of the 4 opponents", which
5011
+ does not always match the displayed self-play row alone — both counts are
5012
+ now reported side by side for reconciliation (see Result below).
5013
+
5014
+ Controls: patch-identity; mirror cells; a `D_*_APPR` policy mirror; a live
5015
+ assertion that no knockout match returns a null winner; every 17-player
5016
+ pool's full 2^17=131,072 possible 11-subsets checked and validated; and the
5017
+ reported grand total checked against a value computed analytically from the
5018
+ loop structure.
5019
+
5020
+ ### Result
5021
+
5022
+ | axis | adopted | sig (self-play only) | sig (any of 4 opp) | max \|Δ\| pp | non-monotone | opponent-conditional |
5023
+ | --- | --- | --- | --- | --- | --- | --- |
5024
+ | `balance` | yes | 7/8 | 8/8 | 33.89 | **0/8** | **0/8** |
5025
+ | `line` | yes | 8/8 | 8/8 | 22.87 | 1/8 | 3/8 |
5026
+ | `press` | yes | 7/8 | 8/8 | 39.88 | 2/8 | **7/8** |
5027
+ | `build` | yes | 7/8 | 8/8 | 12.52 | 1/8 | 0/8 |
5028
+ | `keeper` | yes | 8/8 | 8/8 | 19.02 | **0/8** | **0/8** |
5029
+ | `set_piece` | yes | 8/8 | 8/8 | 11.38 | 4/8 | 0/8 |
5030
+
5031
+ All six adopted (judged on the any-opponent column, matching the code's
5032
+ adoption rule); `line`/`press`/`build`/`set_piece` non-monotone,
5033
+ `balance`/`keeper` cleanly monotone. G0 passes (4 of 6 non-monotone, above
5034
+ the 2-required bar). `press` remains the strongest trade-off: 7 of 8
5035
+ core×mode cells have a supported leader that flips across the 4-opponent
5036
+ grid. `set_piece`'s `flat` core is no longer an exact 0.00pp tie (as in
5037
+ round 4) — it now shows a small but genuinely significant effect
5038
+ (+0.29/+0.33pp) once the ranking criterion includes `total/3`, which makes
5039
+ `slotTotals()`'s rounding-driven total differences the real tiebreaker
5040
+ instead of array order. Round 6 additionally found FK's ranking was missing
5041
+ half its own mechanic (see "What Codex found").
5042
+
5043
+ `D_*_APPR` (#745's three questions): `focus-total` is now restricted to
5044
+ FORWARDS specifically (round 7 — searching all outfielders let a DF win the
5045
+ argmax whenever rounding gave one the squad's top total, e.g. `gkheavy`'s
5046
+ 19-point DF against 18-point forwards, silently testing "focus on whoever
5047
+ has the most points" rather than #745's actual forward-specific claim). The
5048
+ picture sharpened considerably: only `shaped` (STARS weighting, clearly
5049
+ uneven totals with forwards on top) benefits from `focus-total`
5050
+ (+16.65/+19.80pp); the other three cores, where totals are flatter or a
5051
+ forward isn't the max, take a LARGE loss from forcing defensive duty onto a
5052
+ forward (−30 to −46pp) — a much more precise reproduction of #745's own
5053
+ conditional claim ("only works when totals are uneven") than the
5054
+ all-position version showed. The reversal boundary is confirmed in both
5055
+ modes at outfield total-spread 17 (`focus-total` wins, z=36.61 REG / 30.03
5056
+ KO); at every lower spread tested (1, 6, 11) `focus-defense` wins
5057
+ confirmed, now by far larger margins (up to −47.6pp) since the two policies
5058
+ target genuinely different players. Opponent-conditional: 0/8.
5059
+
5060
+ **17-pool realizability (exploratory, not gating)**: same construction as
5061
+ before (three pools of 17, all 2^17 subsets checked). Two limitations now
5062
+ documented, pulling in OPPOSITE directions: (1, round 5) the pool assumes
5063
+ each of the 17 individuals' POSITION and kicker flags are fixed at their
5064
+ build-time template, but `AGENTS.md` states F-6 freezes ABILITY VALUES
5065
+ only, not "pool membership, mutable unminted positions/names, or FK/PK
5066
+ choices" — the real product may allow repositioning or kicker reassignment
5067
+ this check cannot see, understating realizability; (2, round 7) an
5068
+ alternate's total is copied from the slot it replaces, which squad-lib's
5069
+ own `slotTotals()` clamps to [10,29] — wider than the production FA
5070
+ generator's actual reachable range of 16-28 (`AGENTS.md` §3-16). `pool-shaped`/
5071
+ `pool-gkheavy` do produce alternates outside that window (as low as 12, as
5072
+ high as 29 — a keeper on `pool-gkheavy`), i.e. synthetic reserves the real
5073
+ generator could never mint, which OVERSTATES realizability for any verdict
5074
+ depending on one. This exploratory check does not net the two limitations
5075
+ against each other — the true direction is unresolved. Full table and
5076
+ caveats: `docs/pog/02-axes-measurement.md` §6.
5077
+
5078
+ ### What Codex found, and what changed (eight review rounds, 41 findings)
5079
+
5080
+ Rounds 1–4 are summarized in `docs/pog/02-axes-measurement.md` §7 (GK
5081
+ weight-share leaks across three different axes and two different root
5082
+ causes, cross-slot scarcity-repair leaks, unvalidated/undersized/
5083
+ misnamed pool XIs, unsupported opponent-conditional argmax, combined then
5084
+ still-colliding FK/PK selection, proportional instead of concentrated
5085
+ `D_*_APPR` policies, `mid` built through a different algorithm than
5086
+ `low`/`high`, several doc-accuracy corrections).
5087
+
5088
+ **Round 5 (2 P1, 2 P2)** — new defects inside rounds 1–4's fixes:
5089
+
5090
+ - `D_*_APPR`'s focus-weight override of 1024 (round 3's fix) wasn't large
5091
+ enough: in the highest-competition scenes (A0/A1, where up to 4 DF plus
5092
+ the GK each carry ~100 stock weight, summing to ~500), 1024 only bought
5093
+ the focal player 62-72% of the draw rather than near-total concentration
5094
+ (measured on `shaped`/A0). `appr-role.mts`'s 1024 was calibrated for the
5095
+ offence table's much smaller competing sums, not this one. Raised to
5096
+ 1,000,000 — a three-orders-of-magnitude safety margin that guarantees
5097
+ >99.9% share regardless of competing weight.
5098
+ - `set_piece`'s FK/PK ranking (round 4's independent-selection fix) still
5099
+ ranked by the bare `shoot` / `(pass+shoot)/2` stat alone, omitting the
5100
+ `total/3` term `getPoint` and `takePkShot` actually add to the kicker's
5101
+ point. On `flat` (every outfielder has identical `shoot`), ties were
5102
+ broken by JS's stable-sort array order — which happened to correlate with
5103
+ `slotTotals()`'s rounding drift (a couple of slots get one extra total
5104
+ point) — landing the "worst" AND "best" ranking on the same higher-total
5105
+ DF/DMF slot while `mid` uses the FW slots, manufacturing a discontinuity
5106
+ unrelated to kicker quality. Including `total/3` makes ties genuine
5107
+ engine-level ties rather than rounding artifacts wearing a tie's mask.
5108
+ - Two P2s: the 17-pool check doesn't model that unminted players' positions
5109
+ and kicker flags are mutable in the real product (`AGENTS.md`) — documented
5110
+ as a lower-bound limitation rather than modeled (modeling it properly needs
5111
+ a lineup solver, P1-2's job); and the "significant" cell counts didn't
5112
+ match the displayed self-play rows (adoption is judged on "any of 4
5113
+ opponents", which a reader can't verify from the self-play table alone) —
5114
+ now both counts are reported side by side.
5115
+
5116
+ **Round 6 (1 P1)** — a new defect inside round 5's own fix:
5117
+
5118
+ - `set_piece`'s FK ranking (round 5's `total/3` fix) still measured only
5119
+ HALF of the `fkKicker` mechanic. `doFk` sends every free kick through one
5120
+ 50/50 coin flip between `doFkDirect` (`getPoint(..., 'shoot', SCENE.FK1)`)
5121
+ and `doFkCross` (`getPoint(..., 'pass', SCENE.FK2)`) — the same single
5122
+ flag governs both branches. Ranking by `shoot + total/3` alone matched
5123
+ only the direct-kick half in isolation (presumably what
5124
+ `docs/tactics/00-plan.md`'s narrower "FK=shoot" finding itself measured),
5125
+ not the blended mechanic the flag actually controls. Reading `getPoint`
5126
+ directly confirmed both branches use the identical
5127
+ `atkSkill + cond/2 + total/3 + roll` shape with only `atkSkill` swapped
5128
+ between `shoot` and `pass`, so the expected-value-optimal FK ranking is
5129
+ `(shoot+pass)/2 + total/3` — the same formula PK already uses. The two
5130
+ roles now genuinely converge on the same "best all-round kicker" ranking,
5131
+ which is the correct consequence of the engine's real mechanics, not a
5132
+ bug — it just means round 4's "PK falls to the next-best candidate when
5133
+ it ties with FK's pick" tie-break now fires on nearly every ladder cell
5134
+ instead of occasionally.
5135
+
5136
+ **Round 7 (1 P1, 4 P2)** — new defects inside earlier rounds' fixes:
5137
+
5138
+ - `D_*_APPR`'s `focus-total` searched the argmax total across ALL outfield
5139
+ positions, not specifically forwards — #745's own claim names "your
5140
+ biggest FORWARD" explicitly. On `gkheavy` (19-point DF vs 18-point
5141
+ forwards) and the B3 boundary's alpha=0 squad, rounding made a DF the
5142
+ squad-wide max, so `focus-total` was silently testing "focus on whoever
5143
+ has the most points" rather than #745's forward-specific policy.
5144
+ Restricting the search to `position === 'FW'` sharpened the picture
5145
+ considerably (see Result above): only `shaped` (clearly uneven totals,
5146
+ forwards on top) benefits, and the other three cores take a large loss
5147
+ (−30 to −46pp) from forcing defensive duty onto a forward — a much more
5148
+ precise reproduction of #745's conditional claim than the all-position
5149
+ version showed.
5150
+ - Four P2s: both documents still described FK's ranking as `shoot + total/3`
5151
+ even after round 6 corrected the code to `(pass+shoot)/2 + total/3` —
5152
+ fixed to match the committed treatment; the probe's own header comment
5153
+ claimed all six axes are template-input changes via `build()`, when
5154
+ `set_piece` actually reassigns already-built kicker flags directly — now
5155
+ distinguished; the header also still claimed `mid` is "always the bare
5156
+ core", which stopped being true for `balance`/`press`/`line` once round 4
5157
+ rebuilt `mid` through the same pinned pipeline as `low`/`high` (the exact
5158
+ difference round 4 used to find `balance`'s spurious reversal) — corrected
5159
+ to state the real per-axis contract; and the 17-pool's bench alternates can
5160
+ carry totals outside the production FA generator's actual reachable range
5161
+ of 16-28 (`AGENTS.md` §3-16) — as low as 12, as high as 29 for a keeper —
5162
+ documented as a SECOND limitation pulling in the OPPOSITE direction from
5163
+ round 5's position/kicker-flexibility one (this one makes some "가능"/
5164
+ "부분" verdicts optimistic rather than conservative; the two are not
5165
+ netted against each other).
5166
+
5167
+ **Round 8 (2 P1)** — new defects inside earlier rounds' fixes:
5168
+
5169
+ - **[Fixed]** `line`'s realization conflated formation change with attribute
5170
+ reallocation. `AGENTS.md` states F-6 freezes ABILITY VALUES only —
5171
+ unminted players' position labels and FK/PK assignments stay mutable — but
5172
+ the pre-round-8 `line` implementation rebuilt the outfield through
5173
+ `buildGkPinnedVariant` using the new formation's mix ratios, so a position
5174
+ change also dragged along an attribute redistribution the real product
5175
+ doesn't require. Rewritten to clone all 11 existing players (GK included)
5176
+ byte-for-byte and relabel only `position` to the new formation's slot —
5177
+ `buildGkPinnedVariant` is no longer needed for this axis at all, since no
5178
+ attribute is touched. The now-dead `avgOutfieldWeightByPosition()` helper
5179
+ was deleted. Re-measured: `flat` (EVEN weighting, where the old and new
5180
+ approaches coincide by construction) is byte-identical; the other three
5181
+ cores show smaller, more isolated formation-only effects (e.g. `shaped`
5182
+ −8.43→−5.00pp) — the axis's own max \|Δ\| drops from 32.20pp to 22.87pp.
5183
+ Non-monotone/opponent-conditional classification is unchanged (1/8, 3/8) —
5184
+ only the magnitude was wrong, not the qualitative call.
5185
+ - **[Deferred to a follow-up issue]** `set_piece`'s FK/PK ranking
5186
+ (`(shoot+pass)/2 + total/3`, fixed in rounds 5–6) omits `ofTeamContrib`,
5187
+ the team-aggregate term `getPoint`'s full formula also adds:
5188
+ `ofPoint = ofPlayerP + ofTeamContrib`, where `ofTeamContrib =
5189
+ (atkCondSum*atkRate*0.075 + atkAttrSum*atkRate*0.1) * (teamPow/100)`.
5190
+ Codex supplied a concrete counterexample on the `flat` core where including
5191
+ this term could flip the top-ranked candidate. Closing this gap requires
5192
+ extracting the engine's `O_*_RATE` tables and `teamPow` computation — new
5193
+ engine-internals research outside this issue's (#809) measurement scope.
5194
+ Per the coordinator's round-7 scope-management guidance, this was left as a
5195
+ documented "KNOWN LIMITATION" code comment rather than extending the review
5196
+ loop further, and tracked in a separate GitHub issue (linked from PR #840)
5197
+ instead. It does not affect `set_piece`'s own adopted/non-monotone verdict —
5198
+ the current ranking already captures the dominant term of the real
5199
+ mechanism; only a secondary correction term is missing.
5200
+
5201
+ ### What it means
5202
+
5203
+ - **G0 passes.** 6/6 adopted, 4/6 non-monotone. `docs/pog/02-axes-measurement.md`
5204
+ has the full write-up and all eight review rounds' changelogs.
5205
+ - **The realizability column's direction is explicitly unresolved, not
5206
+ presented as a clean lower bound** — round 7 found a second limitation
5207
+ (out-of-range synthetic reserves) pulling the opposite way from round 5's
5208
+ (position/kicker flexibility), and this exploratory check does not net
5209
+ them. Important for W1's planning: some "불가능" verdicts could turn
5210
+ "가능" once P1-2 builds a real fixture, but some "가능" verdicts here
5211
+ could also turn out to be unreachable.
5212
+ - **Every finding across all eight rounds lived inside a FIX, not the
5213
+ original measurement design** — the generalizable lesson: a control that
5214
+ checks the harness is unbiased (mirror, patch-identity) says nothing about
5215
+ whether a specific numeric choice (a weight constant, a ranking formula, an
5216
+ allocator) actually matches the real mechanism it's meant to approximate.
5217
+ Each of those needed independent verification against the actual engine
5218
+ formula or actual competing magnitudes, not just "does the effect look
5219
+ directionally right."
5220
+
5221
+ 14,066,000 matches in 182.5s (N=20,000, round-8 re-run — the loop structure
5222
+ is unchanged so the match count is identical, only wall-clock varies between
5223
+ runs; self-checked against the loop structure). The default `N=6,000`
5224
+ reaches the same G0 PASS verdict in about a third of the time. Whole run:
5225
+ `pog-axes.mts`.