# Seeing the patterns: three specs

Written 2026-08-17 for generation 5 (#pprog_p8v2_gen5_goal_20260815). MJC's push asked to be able
to see the patterns for B1 and B2 "and patterns generally, nicely visualized", and then: write two
more specs that share no ideas with the first, and build all three. cmpr-src specifies; ../hutter
builds. Nothing here is implemented on this side.

Each spec is deliberately built on a DIFFERENT organizing principle, so that the three disagree
about what a pattern is. Spec A treats the model as an inventory laid out in data space; spec B
treats it as a topology; spec C treats it as something that changes as the sample grows. They share
no encoding, no interaction and no layout.

## Where the data is

All three read only (program text, model file), reconstructed on demand through the query layer --
never a de-optimized dump (#pprog_pattern_query_goal_20260706).

    models      tests/pprog/models/p8v2/enwik9/<64|1000|10000>/wordsv2-<variant>.m
    per-position tests/pprog/gen5-pos/            (and gen1-pos .. gen4-pos for earlier generations)
    table       tests/pprog/gen5.tsv              one row per (variant, sample)
    constants   tests/pprog/axes.json             the "constants" section; never restate a number
    queries     cmpr --run <variant> --ofra tests/pprog/p8v2-words.md --patterns --model <m>
                ... --patterns-from token --model <m>
                ... --explain byte --where <event> --model <m>
                ... --latd <pattern> --model <m>

B1 vs B2 is the variant pair (#wordsv2-v024, #wordsv2-v025) at the same sample. The k=1 strength is
a stated constant, 8, and is in axes.json; the k=2 rules carry their strength in the file.

## Spec A -- the pattern page (inventory in data space)

One static page per (model, sample). The whole k=1 map is a 16x16 grid of source bytes, each cell
printing its argmax successor as the datum itself, with ink weight proportional to the stored
support -- so B1 and B2 render as the SAME page, B1 being what it looks like when the only ink the
file can justify is the bare glyph, and the visual difference between the two pages IS what B1
discards. The k=2 token rules run below as a support-ordered column of small multiples, each one
line -- the token's bytes, an arrow, the consequent, a length-true bar in LSA units -- sharing one
scale with the k=1 cells so strength is comparable across k by eye. Selecting any pattern dims
everything except the positions in the sample where it fired, shown in place in a one-line strip of
the actual text, so one rule and its footprint in the data are a single reading rather than two
charts. No axes, no legend, no colour scale needing a caption to decode: bytes label themselves,
ink is support, grey is absence.

## Spec B -- the transition arc (topology)

One static page per (model, sample), and it answers a question spec A cannot: what SHAPE does the
learned relation have? The 256 byte values sit as unlabelled ticks on a single horizontal baseline
in byte order, and every k=1 rule is a semicircular arc from its source tick to its successor tick,
drawn above the line for a forward step and below for a backward one; support is encoded as ARC
HEIGHT ALONE, never as ink or width, so every arc is the same hairline and the page has exactly one
visual variable. Read that way the structure is immediate and unavailable in any table: the hubs
(ticks that many arcs land on, which are space and e), the short arcs of the alphabet's local
runs, the long arcs that cross the whole range into punctuation and the high bytes, and the cycles,
which are the pairs whose arcs mirror each other above and below the line and which are exactly the
positions where settling can oscillate rather than converge. The k=2 rules are drawn as a second,
fainter baseline beneath it whose ticks are the 65536 contexts in lexicographic order, so the two
orders of the model can be compared as two skylines without either being aggregated into the other.
Nothing is selectable and nothing moves: this is a page to print.

## Spec C -- the learning slopegraph (change across sample sizes)

One page per variant, and its subject is neither an inventory nor a structure but a DIFFERENCE: what
the model learned at e64, at e1k and at e10k, as three columns of a Tufte slopegraph with one line
per source byte joining its argmax successor at each size. Most lines are flat and grey and carry no
information; the page exists for the ones that are not, the argmax FLIPS, and each flip is labelled
with both successors and the counts behind them so the reader sees whether the model corrected
itself or was pushed by LSA's stochastic increment -- the k=1 table naming e after m where the data
has l three times and e twice is one line on this page rather than a paragraph in a report block.
A second panel below plots each rule's support against sample size on a shared log axis, which makes
the generation's central measured fact visible without a sentence: the argmax's share of its context
falls (0.635, 0.515, 0.290) as the sample grows, so a constant stated strength is right at small
samples and the stored B2 matrix is right at large ones. Neither panel has a legend and neither is
interactive; the labels are the data.

## What none of the three do

None aggregate a rate into a single number, none show a per-byte compression rate over a whole model
file (#hutter_metrics forbids it), and none invent a strength the model does not store: under B1 the
k=1 strength is the stated constant from axes.json and must be labelled as stated, not as learned.
