/* #pprog_p8v2_gen3_report_20260810 @pprog_p8v2_gen3_goal_20260810 @p8v2_gen3 @variant_protocol @f-p8 @pp_wordsv2 @hutter_publication_handoff GENERATION 3 IS BUILT AND AWAITS THE PICKS (run --needs) The choices are in #pprog_p8v2_gen3_goal_20260810, seven of them, A through G. NOTE THE TWO LETTERINGS: #p8v2_gen3's choices are yours and are already answered; the goal block's are the ones still open. Every reference below says which. This block is what the runs and the query layer say. Under #variant_protocol the picks are the programmer's; nothing here prunes. Data: tests/pprog/gen3.tsv (measured), tests/pprog/gen3-pos/ (per position), tests/pprog/axes.json (19 alternatives now, and the LSA operations table), and `python3 tests/pprog/gen1-report tests/pprog/gen3.tsv` for the derived view. ../hutter's generation panel renders gen3-pos with no work on their side. RUN IT WITH CMPR=./cmpr/dist/cmpr. tests/pprog/acceptance-p8v2 defaults to the INSTALLED cmpr on PATH, which here was a 2026-08-05 build from before the k=0 removal: it silently produced models 256 bytes too big and failed the size identity. Whether to install the current build is yours. ## What landed before the runs THE FOLD-BACK (#p8v2_gen3's choice F, "all of them"). #f-p8 is now the single normative statement of f, carrying the application rule, W with its non-overlapping tiling, the W time steps, initialisation to 256 zeros, the clamping policy, and the argmax readout with its smallest-index tie-break. Five are marked AXIS CANDIDATE because you asked for them to be driven rather than frozen; the goal block's choice D asks which become axes now. The constant-sum derivation is marked WITHDRAWN in place with your ruling quoted, and its text kept, because it is what generations 1 and 2 measured. THE VOCABULARY. "Message" is gone from p8v2-words.md (27 to 4, and those four quote the retired word as history) and gone from axes.json entirely (44 to 0), which takes it off ../hutter's page at their next rebuild. "Sweep" went with it. Data column names did NOT move -- mean_sweeps is a column, not a term of art -- and no generated block regenerated, so no measured number moved. Verified: v002 is byte-identical in every column across gen1, gen2 and gen3. THE LSA OPERATIONS TABLE (your "no more lsa_ceil_log2"). Seven rows in #f-p8: each operation in ordinary arithmetic, where it saturates, and whether it draws from the entropy stream. Lifted into axes.json the way alternative prose is, and acceptance-p8v2-axes now FAILS if any lsa_* identifier appears anywhere else in that file without a row. It caught one on its first run. ## The runs Four runs at e64/e1k/e10k: the baseline v002 (A2) and the three a5 alternatives. Trace is 5901 at e10k for ALL FOUR -- D1, so axis A cannot reach the rate, exactly as in generation 2. So the axis is read off settling. e10k trace settled_ok mean time steps applications what it does v002 5901 5828 71.87 1819055 the baseline, decay by the constant 2 v021 5901 5725 34.35 1815933 A4, decay by the support deficit v022 5901 5504 5.72 1700599 A5, a firing period per pattern v023 5901 5826 78.01 1811600 A6, decay by the applications that arrived WHAT smax WAS, since A4 and A5 both measure a deficit from it and nothing on this axis is conformance-checkable (they inherit A2's accumulation, and lsa_add draws from the stream). The built reading is "the largest support present in the model": the largest learned weight over the k=1 argmax pairs and over the kept k=2 rules, floored at 1. Measured: smax = 2 at e64, 6 at e1k, 9 at e10k. AND A k=1 PATTERN'S SUPPORT IS THE LEARNED WEIGHT, NOT THE 255 THE SHELL APPLIES IT AT. sup1[x] is c1[x*256 + table[x]], so inside A4 and A5 the same k=1 pattern simultaneously DELIVERS at 255 and has a RATE set by a support of 0, 1 or 2. That is the k=1 strength gap biting inside the new alternatives rather than beside them, and it is another reason the goal block's choice C is not cosmetic. At e64, 229 of the 256 entries of sup1 are 0 -- a byte never seen as a predecessor -- so their deficit is the full smax. CONSEQUENCE FOR A5 THAT IS WORTH SEEING RATHER THAN DERIVING. The period is 2^(smax - s) and W is 128, so at e64 the periods are 1, 2 or 4 and everything fires; at e1k they reach 64 and a support-0 pattern fires twice in a window; at e10k they reach 512 and A SUPPORT-0 PATTERN NEVER FIRES INSIDE A WINDOW AT ALL. The alternative's own block predicted that case as a possibility; at e10k it is what happens, for 169 of the 256 bytes. ## THE FINDING, which is about the shape of the rule and not about which one wins A UNIFORM FALL-OFF CANNOT REORDER AN EVENT SPACE. A2 subtracts the same d from all 256 entries of a position, and lsa_sub is monotone, so the only way a uniform decay changes the settled argmax is by pushing entries onto the 0 floor. A4 and A6 vary d BETWEEN positions but are still uniform WITHIN one, and that is why A6 -- which replaces the constant 2 with the actually-measured count, usually 3 -- lands within 2 positions of the baseline at e10k despite decaying half again as fast. A5 is the only one of the three where the rate differs between the patterns FEEDING ONE POSITION, because a pattern with less support is applied on fewer time steps, and it moved the most: 324 fewer positions settled correctly at e10k. IT IS NOT CHEAPER, AND THE 6 PERCENT DROP IN settle_apps IS NOT THE SCHEDULE. The implementation computes all three vectors and increments settle_apps, and only then decides by the period whether to apply them, so a skipped application costs exactly what a taken one costs. The 1700599 against the baseline's 1819055 is an INDIRECT effect: under a different settling trajectory more positions reach a state whose backward predecessor set is empty, so fewer applications fire at all. A schedule that actually bought energy would decide before computing, and #f-p8's own derivation is explicit that "applying a pattern always costs energy" -- so this is an implementation that does not yet mean what the alternative says. It does not touch the settling numbers, which are what the axis is read on. So if "each pattern fires at a rate set by its own support" is to mean anything at the readout, it has to bite between the patterns feeding a position rather than between positions. That is a statement about where the rule has to live, and it is what the three alternatives were built to find out. ONE CAVEAT ON A5's CONVERGENCE, which will show on the panel. Its mean time steps at e64 is 1.00. It did not converge; conv records the first step at which the argmax sequence stops changing, and under a schedule the low-support patterns have not fired yet at step 1, so a window can look settled because nothing has happened. The conv column measures the wrong thing for a scheduled rule and generation 3 does not fix it -- it is one more thing the fold-back turned up rather than invented. ## WHAT LATD FOUND ON ITS FIRST QUERY --latd is built (#p8v2_gen3's choice E, "probably a new verb, or it can be the explanation of a pattern"; the interface shape you left to Claude, so the goal block's choice F asks you to confirm it). Given a pattern named by its antecedent sentence as --patterns prints it, it answers with the set of INPUT POSITIONS that formed it, presented as SN clusters with the observed successor counts. Parent-side reconstruction from (program text, model file), no run, nothing stored. Documented in --help pprog; gated by tests/pprog/acceptance-p8v2 section 8, which checks against the replayed sample that every position it names really does carry the antecedent byte. Its first query, on the pattern ../hutter had raised independently: "The input byte is m." "The input byte is e." 1. positions: 1 12 29 44 61 observed successors: e 2 l 3 the argmax this pattern names holds 2 of 5 times ; stored LSA weight 1 THE MODEL NAMES THE WRONG SUCCESSOR. In the only data there is, m is followed by l three times and by e twice, and the k=1 table says e. Confirmed from v013's stored matrix, where the same model's learned weights are c1[m][e] = 2 and c1[m][l] = 1: LSA's stochastic increment took a 3-count to 1 and a 2-count to 2. That is not a tie and not a tie-break -- it is the log estimate inverting the order of two small counts, which is exactly the uncorrelated-error property LSA is designed around, seen from the data side for the first time. It bears directly on axis A. a5 sets each pattern's rate from its own support, and at these sample sizes the support is a one- or two-bit quantity whose ORDERING is not reliable. Whatever the formula, it is being fed a noisy input, and LATD is now the surface on which that is visible rather than inferred. ## The k=1 strength gap (the goal block's choice C) Raised by ../hutter, confirmed here. The 256-byte k=1 section carries NO WEIGHT, so both of its readers invent one and they invent opposite ends: the settling shell applies these patterns at 255 ("its pattern weight is the absolute 255") and the query layer reports all 256 at strength 1 (measured histogram at e64: exactly {1: 256}). Two consequences, both in #f-p8: axis B is not isolating the reconstruction it claims to, because the same pattern is ABSOLUTE under B1 and SUPPORT-1 under B2; and it is a prerequisite for a5, because a rate set by a pattern's own support cannot be computed for a pattern whose support is not in the file. The three alternatives are measurable anyway, and it is worth being exact about why: under D1 settling never runs at decode time, so A4 and A5 read support from the learned tables in memory. Combining either with D2 or D3 would need the support serialized. That restriction is recorded in both alternatives' blocks rather than left to be discovered. ## The rest C2 has its PRUNED line, on your ruling. The live question under C -- min ignores the rest of each ES -- is answered by showing the whole source ES against the argmax actually used, which is ../hutter's page and not a new alternative. D is parked pending the viewer, per your answer. A3 has NOT been given a PRUNED line: "was not anything that I wanted" is a rejection of a direction and reads to me as short of a prune, so it says that and the goal block's choice E asks you which it is. ## What this generation did not do No picks, no chart point, no rate quoted for anything (#hutter_publication_handoff). No LATD beyond the k=1 and k=2 families -- the memory chain expands to every position by construction and printing that is a dump, not an expansion. No support serialization, no multi-window settling, and no change to the .pos or TSV formats. Written 2026-08-10. */