build_corpus: lossless slot-mode identifier encoding#675
Merged
Conversation
Frequency mode promotes the top-N identifiers by count and drops every other identifier onto ONE fallback token. On the 2026-07 ecosystem corpus at top_n=256 that is 45.7% of all identifier occurrences. The consequence is not a quality loss, it is an expressiveness loss: a correct program cannot be represented. `total is total + items[i]` encodes as `<ident> is <ident> + <ident>[<ident>]`, so "assign the variable I just read" -- the property separating well-formed output from correct output -- is not statable, and no amount of training can recover it. Measured identifier structure of the corpus (379,321 occurrences): builtin/stdlib names (MUST be exact) 26,904 7.1% 219 distinct local/arbitrary names 352,417 92.9% 25,355 distinct 93% of identifier references are locals, where any consistent renaming yields an equally correct program -- only IDENTITY matters, never the name. The budget was being spent memorising 25,355 arbitrary names while the 219 that must be exact (you cannot call `pront`) were a rounding error. Slot mode gives every builtin an exact token -- asking the RUNTIME'S OWN registry, so the list cannot drift as builtins are added -- and encodes each local as one of N reusable LRU slots. A name keeps its slot until evicted, so every occurrence inside a window is the SAME token. Slot count is measured, not guessed. Distinct locals per real 32-token window: median 5, p99 10, max 17. So 20 slots cover 100% of windows, and no eviction can occur inside a window (all of a window's locals are more recently used than anything it would evict). Full corpus, both modes: FREQUENCY vocab 341 fallback <ident> = 91,161 (45.7% of ident tokens) SLOT vocab 362 fallback <ident> = 0 ( 0.0%) Zero identifier information lost for 21 extra vocabulary tokens, with slot usage uniform across all 20 (5.1-5.4% each) rather than piling onto one slot -- which is what stops a slot becoming the new frequency attractor. HONEST SCOPE -- this does NOT raise the grade ceiling. Measured on 300 real corpus units, both encodings give an identical distribution (incomplete=58 g0=14 g1=223 g2=5). Grade 2 requires the extracted unit to RUN, and a 60-token window of real code almost never defines everything it references, so `v1 is v1 + v2[v3]` is coherent but still errors on undefined names. The ceiling is bounded by unit self-containment, not by identifier encoding. The claim here is only that a correct program is now REPRESENTABLE; whether a model reaches that is a separate question that needs a training run. Opt-in via an optional 6th argument, so frequency mode and every recorded number from it are unchanged, and the two encodings can be A/B'd. Suite: 3107/3107, with [43a2b] pinning zero-fallback, in-range slot ids, and identity preservation (a repeated local keeps one slot). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Counts how many ternary codes actually change per requantise. Under QAT a gradient update smaller than the alpha*0.5 threshold leaves the code unchanged and is therefore erased as far as the forward pass is concerned -- the master weight moves, the model does not. Distinguishing "learning" from "accumulating sub-threshold noise" needs the flip rate, and nothing was measuring it. Used to kill a live hypothesis: the trainer requantises on EVERY step, which is the worst protocol in the commit-scheduling literature, so Zeno-style freezing was plausible. Measured instead: untrained 0.0275% of codes flip per step epoch 1 0.1552% epoch 4 0.2540% The rate RISES 9x over training rather than collapsing, so ~187 of 73,728 codes change every step and each code flips roughly 475 times per epoch. Nothing is being frozen out; the hypothesis is dead. Gated behind the env var and a no-op when unset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Slot mode partitioned identifiers by looking the name up in the live global env and accepting VAL_BUILTIN or VAL_FN. By the time build_corpus runs, the driver script's own top-level functions are bound in that same env and are indistinguishable from stdlib entries by Value type -- so they were promoted to exact tokens. Measured on the shipped vocabulary: collect_eigs, _skip_dir, _skip_repo and _has_pathological_repetition, four helpers from iLambdaAi's build_corpus_v3.eigs, sat in the identifier vocabulary beside print and len. Wrong twice over. Those names are not part of the language, and it makes the vocabulary a function of whichever script built the corpus: add a helper to the driver and every token id shifts, silently invalidating comparison against any model trained on an earlier build. The block comment claimed asking the runtime's own registry made the list drift-proof; it introduced a new drift source in the one place it promised safety. Capture the binding count at the end of register_builtins and answer from that. Allocation-free -- a process-lifetime name snapshot would land in the leak tally the suite gates on. SL05 pins it: the driver defines a function whose name also occurs in the corpus, and it must not reach the exact-token vocab. Verified red before the fix, green after. SL03 tightened from >= 1 to == 2; the fixture makes the number exact, and the loose form passed with identity half-broken. Also correct the vocab-size figure in the block comment, which stated a predicted number as a measured one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
Frequency mode promotes the top-N identifiers and drops every other identifier onto one fallback token. At
top_n=256on the current ecosystem corpus that is 45.7% of all identifier occurrences.The consequence isn't a quality loss, it's an expressiveness loss.
total is total + items[i]encodes as:"Assign the variable I just read" — the property separating well-formed output from correct output — is not statable. No amount of training recovers it.
Measured identifier structure
379,321 identifier occurrences across the corpus:
93% are locals, where any consistent renaming is an equally correct program — only identity matters. The vocabulary was being spent memorising 25,355 arbitrary names while the 219 that must be exact were a rounding error.
The encoding
Builtins get exact tokens, decided by the runtime's own registry (
env_get+VAL_BUILTIN), so the list cannot drift as builtins are added. Every other identifier becomes one of N reusable LRU slots — a name keeps its slot until evicted, so every occurrence in a window is the same token.Slot count is measured, not guessed. Distinct locals per real 32-token window: median 5, p99 10, max 17 → 20 slots cover 100% of windows, and no eviction can occur inside a window.
Result
Zero identifier loss for 21 extra vocabulary tokens. Slot usage is uniform across all 20 (5.1–5.4% each) rather than concentrating — which prevents a slot becoming the new frequency attractor.
Honest scope — this does NOT raise the grade ceiling
Measured on 300 real corpus units, both encodings give an identical distribution:
Grade 2 requires the unit to run, and a 60-token window of real code almost never defines everything it references — so
v1 is v1 + v2[v3]is coherent but still errors on undefined names. The ceiling is bounded by unit self-containment, not by identifier encoding.The claim is only that a correct program is now representable. Whether a model reaches that is a separate question requiring a training run.
Compatibility
Opt-in via an optional 6th argument. Frequency mode and every number recorded from it are unchanged, so the two encodings can be A/B'd.
Testing
Suite 3107/3107. New
[43a2b]pins zero-fallback, in-range slot ids, identity preservation (a repeated local keeps one slot), and that frequency mode is untouched.Second commit adds
EIGS_TERNARY_FLIPS, a gated QAT code-churn diagnostic that killed a Zeno-freezing hypothesis (flip rate rises 9× over training rather than collapsing).🤖 Generated with Claude Code