# RESULT — 070 numeric-fidelity: how do NUMBERS survive the SONAR z round-trip?

**Tier: T3-exploratory. DONE + SELF-HARVESTED in-session.** tmux c100_070 launched
07:30:55Z, DONE 07:33:49Z (~3 min wall: smoke ~90 s first — 3 orphan bugs fixed pre-launch,
see Provenance — then full build+encode+decode+bits sharded phys 0/2/3, analyze). Sole
experiment in flight. All 3 GPUs verified free at claim AND exit (35/15/15 MiB); box tmux
server empty both ends; no foreign process touched. Random (non-famous) numbers on a
1–12-digit ladder × {INT, DEC-2dp, YEAR, PHONE, WORD} × context {S~short / M~medium /
K~near-knee}, n=48/cell + 120 FLORES-eng real-number sentences. 069's teacher-forced
per-position I_spec machinery (partner-null = same-template different-number). **All 5 gates
PASS; 3/6 frozen predictions TRUE; mean Brier 0.195** — and the three MISSES are the finding.

## Verdict
★ **In short context there is NO digit cliff: random numbers survive the round-trip
essentially perfectly out to 12 digits (INT-S exact 1.00 through D=5, ≥0.96 at D=12; DEC,
YEAR, PHONE all ≈1.0). The cliff is created ENTIRELY by CONTEXT LOAD, not by magnitude — and
it is a smooth magnitude×load interaction.** A 12-digit number is only ~40 bits, trivially
under the ~460-bit sentence budget (066/068/069), so with nothing competing the decoder stores
it verbatim. Load a near-knee sentence around it and digit survival collapses monotonically
with length: INT near-knee exact 0.90 (D1) → 0.73 (D6) → 0.60 (D8) → 0.50 (D10) → **0.31
(D12)**. **When numbers fail they fail FLUENTLY — magnitude/rounding errors that preserve the
leading digits, or whole-number omission under load — essentially never garbling or
implausible substitution** (ties 022/068 confabulation; here it is length-error-dominated).
**Spelled-out WORDS survive WORSE than digits, not better** (the opposite of P4): the
multi-token form is fragile (drop "hundred" → magnitude error). **I_spec_NUM rises ~linearly
with digit count with no saturation through 12 digits** (12.8→67.2 bits; ~4–5.7 bits/digit),
and a long number does NOT starve the rest of the sentence — the OTHER-span budget is
untouched; the cost of load shows up as number *fidelity* loss, not bit reallocation.

## Digit survival by magnitude × context (exact-number survival; out/results_070_full.json)
| D | INT-S | INT-M | INT-K | DEC-S | DEC-K | | D | INT-S | INT-K |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 1.00 | — | 0.90 | | | | 6 | 0.98 | 0.73 |
| 2 | 1.00 | — | 0.96 | | | | 8 | 0.98 | 0.60 |
| 3 | 1.00 | — | 0.96 | | | | 10 | 1.00 | 0.50 |
| 4 | 1.00 | 0.92 | 0.88 | 1.00 | 0.92 | | 12 | 0.96 | **0.31** |
| 5 | 1.00 | — | 0.75 | | | | | | |
Short-context survival is flat-at-ceiling across the whole ladder (P2 predicted a 50% cliff
in D∈[6,10]; **FALSE — it never crosses 50% in S even at D=12**). The 50% crossing exists
only near the knee, at ~D=10. Medium context is intermediate (D8-M 0.88, D12-M 0.85). Other
types short-context: YEAR-S 1.00, PHONE_d10-S 1.00, DEC_d10-S 0.94 — all near-ceiling.
Near-knee they crater like INT: YEAR-K 0.94 (4-digit, easy), DEC_d10-K 0.48, PHONE_d10-K 0.56.

## Context load is the whole story (P3 TRUE, drop 0.375 ≥ 0.15)
At D=8, exact survival S→K falls **0.98 → 0.60 = 37.5 points**. The knee is certified real:
K-cell round-trip chrF ≈ 72 (068's knee sits ~70–73 chrF), M-cell ≈ 86–88 (below knee). So
the same number is stored perfectly alone and lossily once the vector is near its ~460-bit
capacity — digits, being the max-entropy (~3.3 bit) tokens, are the first casualty of
capacity pressure, exactly as 068 saw for acronyms/rare terms.

## How numbers fail — frozen taxonomy (P6 TRUE: fluent 45 vs dropped 4, ≈11×)
Near-knee INT non-exact items are dominated by **magnitude** (wrong digit count) and
**rounded** (leading digits correct, tail wrong); omission is rare and garbled/substitution
≈0:
| cell | exact | rounded | magnitude | subst | omission | garbled |
|---|---|---|---|---|---|---|
| INT_d8_K | 29 | 6 | 13 | 0 | 0 | 0 |
| INT_d10_K | 24 | 11 | 12 | 0 | 1 | 0 |
| INT_d12_K | 15 | 15 | 17 | 0 | 1 | 0 |
Sample INT_d12_K failures: `660428362565 → 66042836255` (one digit dropped, leading 6604283625
preserved); `481181123810 → 4811111238108` (mid-run corruption + length off); and whole
number-sentence **omission** under load (the number-bearing clause vanishes, filler survives).
The decoder preserves HIGH-order structure and corrupts the LOW-order digits / length — it
never swaps to an unrelated same-length number (substitution ≈0). This is on-manifold numeric
confabulation: the output always *looks like* a plausible number.

## Format: digits beat words (P4 FALSE — predicted the reverse, −29 pts)
WORD value-survival is BELOW matched digit format at D∈{3,4} (mean S+K): e.g. WORD_d3-S 0.73
vs INT_d3 1.00; WORD_d4-K 0.52 vs INT_d4-K 0.88. Word failures are mostly **magnitude** errors
(WORD_d3-S: 12/13 non-exact are magnitude) — the spelled multi-token form ("three hundred
forty-seven") loses a scale word and mis-scales. Words also cost MORE bits than digits
(I_spec_NUM D4: WORD 35.4 vs INT 32.9) and ~3× the tokens, so under load they crater harder.
Digits are the more robust numeric channel. (wordout_frac: the decoder echoes the word format,
WORD_d4-S 0.92 — failures are genuine mis-parses, not format flips.)

## Bits: linear, non-saturating, and NOT starving the sentence (P5 FALSE)
I_spec_NUM (INT, S) by digit: 12.8 / 21.3 / 27.1 / 32.9 / 38.5 / 41.3 / 50.6 / 59.4 / **67.2**
(D=1…12). Slopes: early(D1–6) **5.69**, late(D8–12) **4.13** — barely sublinear, nowhere near
the ≥50% saturation P5 required (P5 wanted early∈[2,4.5] & late<0.5·early). Numbers keep
costing bits ~linearly and the decoder keeps paying, right through 12 digits — the direct
mechanistic correlate of "no cliff in short context." (vs the grand-mean null I_mu_NUM is
lower, 9.1→53.0 ≈ 4 bits/digit, closer to the 3.3-bit theoretical max; the partner-null
I_spec is larger because the null is a *specific wrong number*, not a uniform digit prior.)
**A long number does not starve other spans:** OTHER-span I_spec is untouched by number length
(INT_d8 OTH = 0.7 / 139 / 251 bits at S/M/K — grows with added filler exactly as expected) and
NUM only dips slightly under load (50.6 / 50.6 / 47.1). Load degrades number *fidelity* without
reallocating the vector's bit budget away from the number — the failure is lossy storage of the
number itself, not eviction by the rest of the sentence.

## Real-world numbers (FLORES, as-is): exact 0.88
By run length: 2-digit 0.94 (n=35), 3-digit 0.61 (n=28), 4-digit 0.97 (n=57, mostly years).
Real numeric text survives well because it is short and often year-like/round; the 3-digit dip
is small-n and a quantity/year mix (reported, not modeled — REAL is news-register).

## Gates (all PASS)
- **G1 positive control:** INT_d1-S, d2-S exact = 1.00 ≥ 0.90 — cliff claims valid (lesson 5).
- **G2 token/knee:** ≥90% M/K cells within ±20% of target; K-cell INT chrF = 72.5 ≥ 45 —
  K certified near- (not past-) knee.
- **G3 bits instrument:** pad-gate 3.0e-5 nats ≪ 0.01; I_spec_NUM(D4,S) = 32.9 ≥ 3 bits.
  align 48/48 on every cell (perfect spm span alignment — cleaner than 069's 95.7%).
- **G4 norm profile:** max/min mean-‖z‖ = 1.73 < 5 (lesson 3).
- **G5 randomness:** leading-digit histogram flat (max 0.123 ≈ uniform 0.111, ≤ 2×); 0
  famous/round numbers accepted (by construction). No Benford skew — random numbers confirmed.

## Predictions → Brier (frozen in PREREG_LITE)
| pred | P | outcome | Brier |
|---|---|---|---|
| P1 D1–2 S exact ≥ 0.95 (pos ctrl) | 0.85 | **TRUE** (1.00) | 0.0225 |
| P2 short-ctx 50% cliff at D*∈[6,10] | 0.60 | **FALSE** (no cliff in S; ≥0.96 at D=12) | 0.3600 |
| P3 D=8 S→K drop ≥ 15 pts | 0.65 | **TRUE** (37.5 pts) | 0.1225 |
| P4 WORD value-survival > digit by ≥5 pts | 0.45 | **FALSE** (−29 pts; digits win) | 0.2025 |
| P5 I_spec/digit slope 2–4.5, saturates | 0.55 | **FALSE** (5.69→4.13, linear) | 0.3025 |
| P6 D≥6 fluent ≥ 2× dropped | 0.60 | **TRUE** (45 vs 4, ≈11×) | 0.1600 |

**Mean Brier = 0.195.** The three misses cohere into one revision of the prior: digits are
NOT intrinsically fragile — they survive to 12 digits (P2), bits stay linear (P5) — because a
random number is small vs the ~460-bit budget; fragility is purely a capacity-pressure
phenomenon and, when it bites, produces length/rounding confabulation (P6) rather than the
substitution the prior half-expected. P4's reversal (words fragile, not friendly) is the
cleanest single surprise.

## Limitations / what did NOT run
- Greedy (beam=1) decode only; single SONAR encoder/decoder; English only; templated frames
  (8/type) — template idiosyncrasy is partially controlled by the same-template partner null.
- I_spec is decoder-extractable bits vs a same-template different-number null (a conservative
  lower bound); partner-null I_spec exceeds the ~3.3-bit/digit ceiling because the null is a
  specific wrong number — the grand-mean I_mu (~4 bits/digit) is the more comparable figure.
- Codex ambiguity-judge NOT run: the rule taxonomy was decisive (garbled/substitution ≈ 0,
  align 48/48), so the ≤100-item neutral-framing judge was unnecessary; failures partition
  cleanly into magnitude/rounded/omission by rule. Noted as a skipped exploratory adjunct.
- K "near-knee" is one token target (~58); a length dose-response through the knee (like 069's
  capacity-gated position effect) would trace the survival collapse as a continuous curve.
- REAL is FLORES news (year/quantity-heavy); random-ladder cells are the controlled measure.
- P2/P5 as frozen assumed digit fragility; had the ladder been pushed past 12 digits AND paired
  with near-knee load the S-context cliff might yet appear — untested beyond D=12.

## Follow-up worth funding? **Y (narrow).**
1. **Length dose-response through the knee** at fixed D: sweep context 32→144 tok and watch the
   D=8/12 survival curve collapse — locate the number-fidelity knee vs the chrF knee (ties
   068/069 capacity-gating; is digit loss the *first* thing to go as bits run out?).
2. **Digit-position error profile:** the leading-digit-preserving / tail-corrupting pattern
   suggests a positional fidelity gradient inside the number — measure per-digit-position exact
   rate (are units-place digits lost first?). Directly probes how the decoder allocates
   precision within a high-entropy span.
3. **Why words are fragile:** is it token count, sub-word segmentation of number-words, or
   scale-word ("hundred/thousand") dropping? A words-vs-digits-vs-grouped ablation at matched
   token length would isolate it.

## Provenance / hygiene
Repo: PREREG_LITE.md (design + preds frozen; adopted from prior manager with audit note),
src/{run_070.py, run_070.sh}, out/{results, bits×3, decodes×3, items, run.log}. Box dir
`/workspace/HOME/guest/campaign100/070-numeric-fidelity` (z npz box-only). **Three orphan-code
bugs found and fixed pre-launch (the prior manager was killed before ever smoke-testing):**
(1) hard-unique number dedup hung the build on D=1 cells (8 valid values vs n=48) → best-effort
dedup with attempt cap; (2) cyclic same-template partner-null self-assert crashed on singleton
template groups (smoke n=6 < 8 frames) → robust same-template-different-number partner with
fallback; (3) `cfg.only` returned a Python `set` → `json.dumps` TypeError in build → changed to
list. Smoke then passed first try; all gates passed at full n. GPUs free at claim + exit
(35/15/15 MiB); tmux self-ended (kill-session on c100_070 only); no foreign process touched.
Single experiment in flight throughout. NOT left RUNNING. Local commit, no push. T3.
