/* #pprog_p8v2_gen4_goal_20260815 @pprog_p8v2_gen3_goal_20260810 @p8v2_gen3 @variant_protocol @f-p8 @pp_wordsv2 @hutter_publication_handoff GENERATION 4: one k=1 strength, everywhere MJC's answers to generation 3 are inline in #pprog_p8v2_gen3_goal_20260810. This generation is his answer to choice C -- "it's worth gen4 even if the only thing it does is extirpate the argmax 256-table interpreted as 255 rules everywhere that it exists" -- together with the discipline named with it: "it doesn't really matter what we do here, as long as it's consistent across the implementations and viewers; that's the real discipline we need now." With it: streamline the generation bump, and close the remaining gaps between the shipped code and the picture of it. The extirpation is QUIET. No output document gets a note about what the 255 used to be. It goes away, and attention stays on the parts that are actually uncertain. ## CARRIED FROM GENERATION 3 A -- no pick, "let's just experiment here until something becomes more clear", with the constraint that sets this generation's shape: "The delivery and the fall-off need to make sense together, so either deliver 1 with a low fall-off rate, or deliver 255 with a high rate." B -- not answered, and now downstream of C: a reference support only exists once a pattern has a support. C -- answered at length; it is this generation. D -- none of #f-p8's axis candidates become axes. E -- A3 PRUNED, and #f-p8-renorm now carries the line. F -- --latd stays as built. G -- "I don't care", so ../hutter's g2 stands, being the one already written into their #viz_standard: panels stay gen.html on the legacy path, instruments versioned by path. ## WHAT THE MEASUREMENT SAYS Reproduce with `python3 tests/pprog/p8v2-k1-strength.py wordsv2-v002 `. It replays the retained models through p8v2-replay.py with the delivery and the fall-off exposed as constants; the shipped setting is one row of its own grid and is checked against the retained .pos dump, so the grid is anchored to a run that really happened. 255 IS NOT A STRENGTH, IT IS THE IDENTITY OF min. "Its pattern weight is the absolute 255" and "this pattern has no weight, pass the source through unchanged" are the same line of code. The shell was never asserting that the rule is absolute; the prose read a neutral element as a claim. The query layer's 1 IS a claim -- it is offered as the pattern's support, and it is equally a literal. So the two readers were never disagreeing about one quantity. They were reporting two different kinds of thing in the same units, and naming them apart is most of the fix. THE ARGMAX'S REAL SHARE, from the sample each model was learned on. The argmax successor carries 0.635 / 0.515 / 0.290 of its context's observations at e64 / e1k / e10k -- a log deficit of 0.51 / 0.73 / 1.51 as an unweighted mean over contexts, 0.83 / 1.10 / 1.98 weighted by occurrence. The model's own LSA rows estimate that deficit at 0.51 / 0.86 / 1.49, within 0.15 of an LSA unit at every size, which is LSA doing its job at the aggregate for the first time on this data. Expressed the way MJC's proposal of 8 expresses it -- the weight that makes the argmax that share of an ES whose other 255 events sit at 0 -- the measurement gives 9 / 8 / 7. So "half the mass" is what the data says, and 8 is its value at e1k and within one unit of it everywhere. THE 255 CAN GO AND GOING IS FREE, BUT ONLY IF THE FALL-OFF MOVES WITH IT. Unrecorded positions settling back to their true byte, v002, B1, LSA addition: rule w_p fall-off e64 e1k empty e1k conv e1k cap (shipped) 255 2 14/59 165/833 31 47 cap 8 2 11/59 173/833 208 128 cap 8 1 15/59 223/833 2 16 cap 4 1 15/59 222/833 6 128 cap 1 0 0/59 18/833 1 112 attenuate 0 1 15/59 223/833 4 16 attenuate 1 1 14/59 167/833 6 17 Read it in that order. Capping at 8 instead of passing through is FREE: at a fall-off of 1 the two are indistinguishable (223 against 223). The whole improvement from 165 to 223, and the convergence from step 47 to step 16, is THE FALL-OFF. Capping at 8 while leaving the fall-off at 2 is worse than shipping and leaves 208 of 833 vectors all-zero at the readout -- that is the collapse, and it is caused by the mismatch and not by the strength. A2's decay of 2 has had no derivation behind it since generation 3 marked the constant-sum argument WITHDRAWN, so moving it overturns nothing. AND A STRENGTH OF 1 CANNOT BE APPLIED AS A CAP AT ALL: min(1, w_s) puts the whole window in a 0-to-1 band where the stochastic add is noise, and it recovers 18 of 833. If 1 is to be the strength, in p7's sense of "we have seen this once", then the application rule has to stop being a cap. That is what the attenuate rows are: deliver the source one LSA unit weaker rather than clipped to one unit. B2 DOES NOT CURRENTLY SERVE AS GROUND TRUTH. The push wants "the actual fact (from B2)" as what each B1 strategy is compared against. As it stands B2 recovers ZERO unrecorded positions: v013's settled_ok is 5 at e64 in gen2.tsv and those 5 are the 5 clamped positions. Delivering the true learned weights, which are 1s and 2s at this sample, through min() is the same degeneracy as capping at 1. So B2 becomes usable as ground truth only once the application rule changes -- the same fix -- and it is the first thing that will show whether the fix is real. B2 doesn't have anything to do with the application rule. What "B2" means here is that we have the full 65536-pair LPP in the model. That's it. So anything we do with B1 has exactly the ground truth to compare against, because it's in the model. -MJC ## WHAT GENERATION 4 BUILDS 1. THE EXTIRPATION. One interpretation across five places that today hold four readings: the generated C (#pp_wordsv2's pp_settle, whose FORWARD and BACKWARD applications already disagree with each other -- forward passes through, backward subtracts the cost of choosing among predecessors), tests/pprog/p8v2-replay.py, the query layer (--patterns, --explain and --latd each hardcode 1), axes.json, and ../hutter's shell (fwd[table[a]] = apply(255, ws) in their e64 template). --latd additionally prints its literal under the label "stored LSA weight", claiming a provenance the number does not have; that goes whichever way the choice lands. 2. THE AXIS, per the push: the table stays, its INTERPRETATION becomes the axis, B2 is the ground truth each interpretation is scored against. Because delivery and fall-off cannot move separately, an alternative here is a PAIR. That keeps #variant_protocol's no-cross-product rule by making the pair the unit, rather than by pretending the two are independent. 3. FAITHFULNESS, a standing deliverable rather than a one-off. Three holes found while measuring: p8v2-replay.py implements A1/A2/A3 only, so the reference a viewer is conformance-checked against is a generation behind the runs; its .pos check looks in gen1-pos and gen2-pos and never gen3-pos, so it silently reports no check at all for current runs; and axes.json carries each alternative's PROSE but not its NUMBERS, so every constant f uses exists separately in C, in Python and in JS. Choice C is how far to close that. 4. THE GENERATION BUMP. What it costs today: a P8V2_GEN case in acceptance-p8v2, variant blocks in p8v2-words.md, a line each in pp_wordsv2_axes, a regenerated axes.json, and a render on the other side. A SEVENTH axis digit would also touch the model header (bytes 36..41 hold the six digits, 42..47 are free), the .pos header line, and both trees' parsers -- which is choice B. "Feedback from the programmer here." 255. ## The choices A. The interpretation, as a (delivery, fall-off) pair. B2 is the ground truth in every case. a7 cap at 8, fall-off 1 -- the argmax takes half a flat ES; free against what ships, and better a8 cap at the measured share, 9 / 8 / 7 by sample -- a constant that admits the model gets less certain the more it sees a9 attenuate by 1, fall-off 1 -- "strength 1" made applicable by dropping the cap a10 pass-through, fall-off 1 -- the honest name for what ships, with the 255 deleted from every text and the delivery documented as no attenuation Some of what you wrote above was wrong, because 255 is pass-through and it is an absolute pattern. It is literally an absolute rule applied to something that represents partial knowledge. It is the highest strength a pattern can have *because* of the UM max-min forward pass, and *because* 255 is the identity of min. Cap at 8 is fine. -MJC B. Where the interpretation lives. b4 new f alternative blocks on axis A's existing digit -- no format change, no parser touched b5 a seventh axis digit -- one axis per concern, at the cost of the model header, the .pos header and both trees' parsers What interpretation? I'm not following this part; do something that makes sense and don't be afraid to generated new code and leave old code untouched. -MJC C. How faithfulness is enforced, beyond the prose gate that exists. c5 axes.json grows the CONSTANTS f uses, so no implementation holds its own copy c6 c5 plus a conformance fixture: the C dumps one settling trace at e64 that a viewer must reproduce exactly for every deterministic alternative c7 c6 plus p8v2-replay.py brought up to the current generation and gated by acceptance-p8v2, so the reference cannot fall behind again c7 sounds close, but don't get too hung up on LSA entropy stream dependence. The point is not to care about minor differences between variations; if they can't be detected without reproducable PRNG then they shouldn't matter. -MJC Written 2026-08-15. */