arborist/docs/soft-hash-channel-t3-bound.md
russell@unturf.com 8599ce3b2c
ticket #000036: add KAT-regen tooling + close
"One more iteration then close" (fox): added committed KAT-regeneration
scripts for both the T3 calculator and φ_PRG — the regen step was a
throwaway temp script before; now it's reproducible and the phi_prg
test's skipif reason ("run scripts/generate_phi_prg_kat.py") points at
a file that exists. Then closed #000036.

New scripts:
- scripts/generate_t3_bound_kat.py — regenerates
  bench/fixtures/t3-bound/known-answer-tests.jsonl from a fixed 12-config
  list (the §7 worked examples under max_envelope + non-default-C_B*
  + g=0 edge + explicit-b1_model pins for the other three models).
- scripts/generate_phi_prg_kat.py — regenerates
  bench/fixtures/phi-prg/known-answer-tests.jsonl from a fixed 10-entry
  list (placeholder/random seeds, one-bit-flip variants, block-boundary
  dim_h=16/17, 4096 counter-rollover stress).
- Both verified to reproduce the committed fixture data lines byte-
  for-byte (only the header comments changed, to reference the script).
  Each docstring states: run after any algorithm change, then bump the
  module version (CALCULATOR_VERSION / PHI_PRG_VERSION) so the fixture's
  version field changes too.

Doc/test:
- test_t3_bound_calculator.py skipif reason now references the regen
  script (matches the phi_prg test pattern).
- #000035 §3.3 + t3-bound.md §10.1 reference the regen scripts.

Closure (#000036):
- Status → closed · 2026-05-11 in the ticket file + TICKETS.md row.
  Phase 1 + dav1d Tier-1/Tier-2 (Option B in v1) + KAT-regen tooling
  all landed; all §5 acceptance criteria met; both dav1d closure
  blockers cleared. Continuation: empirical C_B1/C_B2/C_B3 tightening
  under #000043 (parks on v7 deployment data); landing the bound's
  framing into a v7 plastic-training spec parks on that spec gaining
  a deployment target; R2's architectural integrations (Merkle audit-
  event commitment, SQD canonicalization, CTI clause-lattice, 5F
  trigger, ForkScore security-risk) are separate tickets if wanted.
- t3-bound.md header flipped to "closed 2026-05-11".

Full suite: 2312 passed, 28 skipped.
2026-05-11 08:02:25 -04:00

31 KiB
Raw Blame History

T3 per-window covert-channel budget bound

Ticket: #000036 — closed 2026-05-11. Source analysis: docs/soft-hash-channel-analysis.md Date: 2026-05-10 (dav1d review pass + Option-B + KAT-regen tooling 2026-05-11) Status: formal derivation + calculator landed; dav1d review returned 2026-05-11 → Tier-1 polish + Tier-2 (Option B: the conservative max_envelope B1 model, applied in v1 — no v2 fork)

  • KAT-regen tooling (scripts/generate_t3_bound_kat.py) all landed 2026-05-11; #000036 closed. KAT fixture is 12 entries, active (test_t3_bound_known_answer_tests runs, not skips). The default B1 model is max_envelope (§3.1); effective_control_v1 / fraction_channels / aggregate_bias reachable via --b1-model. The named C_B* constants are conservative starting estimates that empirical tightening — continued under #000043 — can replace without changing call sites. (#000043 parks on v7 deployment data.) Landing the bound's framing into a v7 plastic-training spec parks on that spec gaining a deployment target.

§0. Reviewer brief (dav1d review returned 2026-05-11)

This document derives an upper bound on the per-window mutual information a T3 (hyperparameter) adversary can steer into the SHA-256 commitment C(M_{t+1}). The framework decomposes the channel across T3's three control surfaces (gradient bias, LR selection, batch order) and combines them into a closed-form bound consumed by bench/scripts/t3_bound_calculator.py.

dav1d's 2026-05-11 review (RESPONSE_1 + RESPONSE_2) findings and how they were resolved:

  1. §2 decomposition — accepted. Markov-chain DPI on A → Θ_{t+1} → C(M_{t+1}) correctly applied; T1+T2 baseline cleanly separated from the T3 capacity term.
  2. §4 (C_B2 LR selection) — accepted. Clean categorical-channel capacity bound.
  3. §5 (C_B3 batch order) — accepted as a model-bound, not a theorem (§5's "model-bound" note reflects this).
  4. §3 (C_B1 gradient bias) — was the closure blocker. g appeared twice in the per-window expression, only sound under the effective_control_v1 reading. Resolved 2026-05-11: Option B applied in v1 — the default b1_model is now max_envelope = max(fraction_channels, aggregate_bias), genuinely upper-bounding across both interpretations of g (§3.1). effective_control_v1 stays reachable for backward comparison. All three B1 variants are reported in every output.
  5. Wording / validation / output-schema fixes — applied (§10.1).

What's not being asked: empirical validation against an actual adversarial-training run (out of scope per §10 item 5; opens as a future ticket once v7 plastic-training has a deployment target).

The headline numeric example in §7 + §11 now yields I_window ≈ 6183 bits/window for the default deployment config under the default max_envelope B1 model (B1 = aggregate_bias = 5849.6 bits dominates fraction_channels = 1729.7 bits; effective_control_v1 would have been 292.5 bits) — well above the 256-bit threshold, so certification_status = NOT_CERTIFIED_BY_BOUND. That is the correct conservative reading: at W=10000 with these inputs, the bound cannot certify M2 residual safety. The calculator's --b1-model flag lets operators inspect the other models if they want the effective-control risk score for comparison.


§1. T3 model restatement

From docs/soft-hash-channel-analysis.md §6, threat model T3 (hyperparameter adversary) extends T2 (gradient adversary) with control over:

  • Learning-rate scheduling: choosing the LR at each scheduled decision point from a constrained range (e.g. log-grid of R levels).
  • Batch ordering: permuting batches within an epoch.

Combined with T2's gradient bias (controlling a g-fraction of training-step gradient computations), T3 is a strict superset of T2. The §4 reduction in soft-hash-channel-analysis.md bounds T1

  • T2 channels at the SHA-256 random-oracle baseline assuming φ is independent of parameter geometry; T3 breaks the implicit "published schedule" assumption so the §4 reduction does not directly apply.

M2 mitigation (per-checkpoint anchor nonce, soft-hash-channel analysis §5.3) re-randomizes the anchor every checkpoint. T3's exploitation window is thus bounded to one nonce-window of length W steps before the anchor re-randomizes. This document bounds the bits T3 can steer into C(M_{t+1}) within a single window.

The bound's intended use: operators choose W (the nonce-window length) such that I_window stays below their target residual (e.g. < 1 bit per window means the adversary needs ≥ 2^256 windows to steer C(M) to a specific 256-bit target).


§2. Per-window channel — formal definition

For a single nonce window of length W steps starting at checkpoint t:

I_window := I( A ; C(M_{t+1}) | H_{≤t}, n_t )

where:

  • A is the joint random variable over T3's adversary inputs during the window: A = (g_1, …, g_W, lr_1, …, lr_⌈W/K⌉, π) where g_s is the adversary-controlled gradient signal at step s, lr_d is the LR at decision point d, π is the batch-ordering permutation.
  • C(M_{t+1}) is the SHA-256 hard-hash committed at the next checkpoint.
  • H_{≤t} is the public history before the window opens.
  • n_t is the published per-checkpoint nonce (M2 mitigation).

This is the standard mutual-information upper bound on distinguishing-from-baseline channel capacity. Conditional on (H_{≤t}, n_t), the random variables form a Markov chain:

A  →  Θ_{t+1}  →  C(M_{t+1})

— T3's window inputs A affect the commitment only through the parameter state Θ_{t+1}. Markov-chain data-processing inequality gives the single-source bound:

I( A ; C(M_{t+1}) | H_{≤t}, n_t )  ≤  I( A ; Θ_{t+1} | H_{≤t}, n_t )

The right-hand side — T3's per-window capacity to encode adversarial bits into the parameter state — is what this document bounds in §§ 3-5.

Inherited T1 + T2 baseline. Independent of T3, the φ-mapping Θ → C(M) itself admits a constant random-oracle baseline channel under the §4 reduction in soft-hash-channel-analysis.md (when φ is φ_PRG per #000035, or φ_linear under the NO_ALIGNMENT verdict per #000034). That baseline is bounded by SHA-256 partial-preimage hardness and is independent of A. Threat-model-additive (T3 capacity

  • T1+T2 baseline = total per-window leak budget) but not information-additive in the same MI sense — the two contributions come from disjoint adversary surfaces:
total per-window bits  ≤  I( A ; Θ_{t+1} | H_{≤t}, n_t )   ← T3, this doc
                        + (T1 + T2 baseline)               ← § 4, inherited

The baseline term is constant-bounded by §4 unchanged; the per- window adversarial capacity is the first term, which we now bound by decomposing across T3's three control surfaces.


§3. C_B1 — gradient-bias bandwidth

Setup. Each step s ∈ {1, …, W}, the adversary controls a g-fraction of gradient computations. The contributed adversarial signal g_s is bounded in norm by g · ‖∇L_max‖ where ‖∇L_max‖ is the per-step gradient-norm cap (gradient clipping, in practice).

Information bound. Per-step parameter-shift channel capacity by discrete-distinguishability counting.

For one SGD step with learning rate lr_s:

Δ Θ_s = lr_s · (1 - g) · ∇L_honest + lr_s · g · ∇L_adv

The adversarial component lr_s · g · ∇L_adv is the parameter shift in the adversary's chosen direction. The honest stochastic gradient contributes noise of standard deviation σ_grad. At each step the parameter shift falls in one of approximately SNR_grad + 1 distinguishable buckets — the noise-only level plus SNR_grad adversarial-signal levels resolvable above the noise floor. The single-symbol channel-capacity bound on a discrete channel with K distinguishable outputs is log₂ K:

I( g_s ; Δ Θ_s ) ≤ log₂( ‖adversarial step‖ / ‖noise step‖ + 1 )
                ≤ log₂( g · lr_s · ‖∇L_max‖ / (lr_s · σ_grad) + 1 )
                = log₂( g · ‖∇L_max‖ / σ_grad + 1 )

The +1 corresponds to the noise-only level (no signal injected); it keeps the log finite when the adversarial step is below the noise floor. (The lr_s factor cancels — LR scales signal and noise identically per-step, so the bound is LR-independent at the per-step level. LR's distinct channel contribution is the §4 LR-selection capacity, not double-counted here.)

Define:

SNR_grad := g · ‖∇L_max‖ / σ_grad

Then per-step gradient-bias capacity is bounded by log₂(SNR_grad + 1) bits.

Per-window. Adversarial signals across steps are information-additive (each step's signal can in principle target a different parameter direction):

C_B1 · g · W · log₂(N_dir)

where the ticket's log₂(N_dir) factor is the per-step bit budget (capped at log₂(SNR_grad + 1) per the discrete channel-capacity bound above, which by data-processing-inequality is much smaller than log₂ of the full direction count 2^256). Replace the ticket sketch's log₂(N_dir) with log₂(SNR_grad + 1):

B1 contribution ≤ C_B1 · g · W · log₂( SNR_grad + 1 )

with C_B1 = 1 (data processing inequality; tight).

For typical deployments g · ‖∇L_max‖ / σ_grad = 0.05 · 1 / 0.1 = 0.5, so log₂(1.5) ≈ 0.5850 bits/step. With W = 10000 and g = 0.05: 1 · 0.05 · 10000 · 0.5850 ≈ 292.48 bits/window.

§3.1 The B1 model — max_envelope (default) vs the alternatives

g enters the naive per-window B1 expression twice: once as the outer multiplier g · W (number of adversary-controlled steps) and once inside log₂(SNR_grad + 1) where SNR_grad = g · ‖∇L_max‖ / σ_grad. dav1d's 2026-05-11 review flagged that this double use is only sound under a narrow interpretation of g. The calculator now offers four B1 models (--b1-model flag), with max_envelope as the default:

b1_model Reading of g Formula Baseline B1 (g=0.05, G=1, σ=0.1, W=10000)
fraction_channels fraction of steerable directions; each carries full per-channel SNR G/σ C_B1 · g · W · log₂(1 + G/σ) 1 729.7 bits
aggregate_bias aggregate adversarial amplitude shrinkage; one effective channel carries SNR g·G/σ C_B1 · W · log₂(1 + g·G/σ) 5 849.6 bits
max_envelope (default) take the worse of the two — no assumption about which interpretation holds max(fraction_channels, aggregate_bias) 5 849.6 bits (aggregate_bias selected)
effective_control_v1 g simultaneously bounds both direction fraction AND amplitude shrinkage — an operational risk score, NOT a worst-case bound C_B1 · g · W · log₂(1 + g·G/σ) 292.5 bits

Every calculator output reports all three concrete variants (B1_fraction_channels, B1_aggregate_bias, B1_effective_control_v1), the selected one (b1_selected), and both SNR readings (snr_grad = g·G/σ, snr_per_channel = G/σ), regardless of which b1_model was requested — so a reader can always see the spread.

Why max_envelope is the default. A security bound that may be optimistic under some interpretation of its own inputs is not a bound. max_envelope is upper-bounding across both readings of g, so certification_status under the default is a genuine certification. effective_control_v1 is kept reachable for operators who specifically want the older effective-control risk score for comparison — it should never be used to certify.

Implementation note (dav1d Option B, applied in v1 2026-05-11). Per fox's direction, this was applied by changing the v1 calculator's default rather than forking a v2 — CALCULATOR_VERSION stays t3-bound-v1-bottou-refinement (the "bottou-refinement" descriptor still names the unchanged B3 term). The b1_model field appears in both the output and the echoed inputs, so KAT replays are unambiguous about which model produced a given row. The KAT fixture was regenerated 2026-05-11 (12 entries: the §7 worked examples under max_envelope plus explicit effective_control_v1 / fraction_channels / aggregate_bias mode pins and a g=0 edge case).


§4. C_B2 — learning-rate selection

Setup. T3 picks LR from a log-grid of R levels at each LR-decision point. With decision interval K steps, the window of length W contains ⌈W/K⌉ decision points.

Information bound. Each decision contributes at most log₂(R) bits to the channel under uniform prior. By data-processing inequality, the LR choice's effect on Θ_{t+1} is bounded by what the LR can change about gradient steps it applies to — which is at most a multiplicative factor in the parameter-step magnitude.

The categorical-channel capacity of R symbols is log₂(R) bits per decision. The mapping from LR symbol to effective parameter shift is a finite function (each LR level corresponds to a fixed step magnitude), so:

B2 contribution ≤ C_B2 · ⌈W / K⌉ · log₂ R

with C_B2 = 1 (data processing inequality; tight).

For typical deployments K = 100, R = 8, W = 10000: 1 · 100 · log₂(8) = 100 · 3 = 300 bits/window.

Tightening note. C_B2 = 1 assumes every LR choice maps to an information-distinguishable parameter trajectory. In practice many LR choices produce trajectories that converge to similar Θ (the loss surface's basin geometry damps small-LR perturbations). A tighter bound would measure the LR-trajectory diversity empirically; the framework above admits substituting C_B2 < 1 when measured.


§5. C_B3 — batch-order bandwidth

Setup. T3 reorders batches within an epoch. With N_b batches per epoch, the naive bound is log₂(N_b!) bits per epoch — but this drastically overestimates the steering capacity because batch-order effects on final Θ are bounded by gradient noise, not by permutation entropy.

Information bound — the Bottou-Bousquet refinement. Per Bottou-Bousquet (2008), Hardt-Recht-Singer (2016), and the broader random-shuffle SGD analysis:

  • Random-shuffle SGD: order has O(1/√N_b) effect on final Θ distribution. Channel bits ≈ 0.
  • Cyclic-shuffle SGD: order has O(1) effect (consistent bias). Channel bits ≈ O(log₂ N_b) per epoch.
  • Adversarial-order SGD: order can amplify directional bias by at most a factor of √N_b over random-shuffle. Channel bits ≈ log₂( σ_grad · √N_b / ‖∇L_max‖ ) per epoch = 0.5 · log₂(N_b) + log₂(σ_grad / ‖∇L_max‖).

The window of length W contains ⌈W / E⌉ epochs where E = N_b (steps per epoch). Each epoch contributes at most:

log₂( N_b · σ_grad / ‖∇L_max‖ ) / 2  bits  (adversarial-order)

For N_b = 1024, σ_grad/‖∇L_max‖ ≈ 0.1: 0.5 · log₂(102.4) ≈ 3.34 bits/epoch.

B3 contribution ≤ C_B3 · ⌈W / E⌉ · log₂( N_b · σ_grad / ‖∇L_max‖ ) / 2

with C_B3 = 1 (data-processing inequality; tight under the
adversarial-order assumption made in this section).

Tightening to the random-shuffle baseline gives C_B3 → O(1/√N_b) — substantially below 1 for typical N_b. That tightening is deferred to §10 + #000043; the headline bound above stays at the adversarial-order ceiling so operators choosing W get the upper-bound conservative number unless they explicitly opt into the random-shuffle constant via --c-b3 on the calculator.

For W = 10000, E = 1024, the contribution is 1 · 9.77 · 3.34 ≈ 32.6 bits/window — substantially less than the naive log₂(N_b!) bound of ~8000+ bits/epoch.

B3 is a model-bound, not a directly-quoted theorem (dav1d review 2026-05-11). The expression above is a gradient-noise- scale conservative modelling term inspired by Bottou-Bousquet / Hardt-Recht-Singer shuffle-stability arguments. It is not a statement that "the Bottou-Bousquet theorem proves every batch-order adversary is bounded by this exact expression." The calculator's test_b3_exact_formula pins the implementation to the model; it does not prove the model. The floor at 0 (when N_b · σ_grad / ‖∇L_max‖ ≤ 1) does not mean batch order has literally zero effect — it means this upper-bound formula gives no positive distinguishable capacity above the noise floor in that regime. Empirical tightening (random-shuffle classification) remains Phase 2 / #000043.


§6. Combined per-window bound

Combining §3-§5, with the default b1_model = max_envelope (§3.1):

B1 = C_B1 · max(  g · W · log₂( 1 + ‖∇L_max‖ / σ_grad ),       ← fraction_channels
                      W · log₂( 1 + g·‖∇L_max‖ / σ_grad ) )    ← aggregate_bias

I_window ≤ B1
         + C_B2 · ⌈W / K⌉ · log₂( R )
         + C_B3 · ⌈W / E⌉ · log₂( N_b · σ_grad / ‖∇L_max‖ ) / 2

with conservative constants C_B1 = C_B2 = C_B3 = 1 (each by data-processing inequality; #000043 may tighten any of them based on empirical measurement). For typical deployments aggregate_bias dominates fraction_channels (because 1/g ≫ log₂(1+G/σ) / log₂(1+g·G/σ)), so B1 ≈ W · log₂(1 + g·‖∇L_max‖/σ_grad).

Other b1_model choices (--b1-model): effective_control_v1 = C_B1 · g · W · log₂(1 + g·‖∇L_max‖/σ_grad) — the older non-worst-case effective-control risk score, ~g× smaller than aggregate_bias; never use it to certify.


§7. Numeric examples

All numbers are the calculator's closed-form output under the default b1_model = max_envelope, not rounded estimates; see bench/scripts/t3_bound_calculator.py, tests/test_t3_bound_calculator.py, and the pinned KAT fixture bench/fixtures/t3-bound/known-answer-tests.jsonl. The effective_control_v1 column shows what the older non-worst-case model would have produced, for comparison.

§7.1 Small deployment

g = 0.05, ‖∇L_max‖ = 1.0, σ_grad = 0.1
K = 100, R = 8, W = 10000, N_b = 1024, E = 1024
snr_grad = g·G/σ = 0.5    snr_per_channel = G/σ = 10.0

B1_fraction_channels = 0.05 · 10000 · log₂(11)    ≈ 1729.72 bits
B1_aggregate_bias    =        10000 · log₂(1.5)   ≈ 5849.63 bits  ← selected (max)
B1 (max_envelope)                                  ≈ 5849.63 bits
B2 = ⌈10000/100⌉ · log₂(8)                          = 300.00 bits
B3 = ⌈10000/1024⌉ · log₂(102.4) / 2                ≈  33.39 bits
total                                               ≈ 6183.02 bits/window
                                  → NOT_CERTIFIED_BY_BOUND
(effective_control_v1 B1 would be ≈ 292.48 → total ≈ 625.87)

§7.2 Medium deployment (longer window)

g = 0.05, ‖∇L_max‖ = 1.0, σ_grad = 0.1
K = 1000, R = 16, W = 100000, N_b = 8192, E = 8192
snr_grad = 0.5    snr_per_channel = 10.0

B1_aggregate_bias = 100000 · log₂(1.5)             ≈ 58496.25 bits  ← selected
B2 = ⌈100000/1000⌉ · log₂(16)                       = 400.00 bits
B3 = ⌈100000/8192⌉ · log₂(819.2) / 2               ≈  62.91 bits
total                                                ≈ 58959.16 bits/window
                                  → NOT_CERTIFIED_BY_BOUND
(effective_control_v1 B1 would be ≈ 2924.81 → total ≈ 3387.72)

§7.3 Hardened deployment (lower g, smaller R)

g = 0.01, ‖∇L_max‖ = 1.0, σ_grad = 0.1
K = 100, R = 4, W = 10000, N_b = 1024, E = 1024
snr_grad = 0.1    snr_per_channel = 10.0

B1_fraction_channels = 0.01 · 10000 · log₂(11)     ≈  345.94 bits
B1_aggregate_bias    =        10000 · log₂(1.1)    ≈ 1375.04 bits  ← selected
B1 (max_envelope)                                   ≈ 1375.04 bits
B2 = ⌈10000/100⌉ · log₂(4)                           = 200.00 bits
B3 = ⌈10000/1024⌉ · log₂(102.4) / 2                ≈  33.39 bits
total                                                ≈ 1608.43 bits/window
                                  → NOT_CERTIFIED_BY_BOUND
(effective_control_v1 B1 would be ≈ 13.75 → total ≈ 247.14)

Note: under the conservative max_envelope model, even the "hardened" config exceeds 256 bits at W=10000 — the aggregate_bias term W · log₂(1 + g·G/σ) grows with W regardless of how small g is. Certifying M2 residual safety under this model requires a much smaller W than the effective-control numbers suggested (see §8).


§8. Operator guidance — choosing window length

The operator picks W such that I_window ≤ B_target where B_target is the desired residual. Under the default max_envelope model with the small-deployment constants (g=0.05, G=1, σ=0.1, K=100, R=8, E=1024), aggregate_bias dominates B1, so:

I_window ≈ W · log₂(1.5)        +  (W/100) · 3      +  (W/1024) · 3.34/2
         = 0.5850 W             +  0.0300 W         +  0.00163 W
         ≈ 0.6166 W   bits/window

Target = 1 bit/window (very conservative; adversary needs ≥ 2^256 windows for a specific target):

1 ≥ 0.6166 W   →   W ≤ 1.6 steps   (impractical — re-anchor essentially every step)

Target = 256 bits/window (the SHA-256 hard-hash output size):

256 ≥ 0.6166 W   →   W ≤ 415 steps

This is the practical operating range under the conservative model: re-anchor approximately every 400 SGD steps to keep T3's per-window steerage at the SHA-256 baseline. (The earlier effective-control numbers gave ~4196 steps; the conservative envelope is ~10× tighter, which is the price of not assuming which interpretation of g holds. An operator who can measure that the effective-control model applies to their deployment can run --b1-model effective_control_v1 and use the looser W — but that is a calibration claim they must justify, not a default.)

Target = 2^16 = 65536 bits/window (much larger window, adversary still needs ~2^240 windows to brute-force):

W ≤ 1.06 × 10^5 steps

This admits roughly day-long training runs between anchor rotations under the conservative model.

Use python -m bench.scripts.t3_bound_calculator with your deployment's g / G / σ / K / R / W / N_b / E to read off the exact certification_status and per-bandwidth breakdown rather than working the algebra above by hand.


§9. Closure of soft-hash-channel-analysis.md §9.3

§9.3 of the analysis posed the open question:

What is the explicit per-window bound on T3 channel capacity under M2?

This document answers it. §6's closed-form bound, parametrized in operator-measurable inputs (g, K, R, W, N_b, σ_grad, ‖∇L_max‖), is the explicit form. Reference: this doc §6.


§10. Open questions + future work

Closure-blocker status. dav1d's 2026-05-11 review flagged two blockers — the B1 model not being worst-case, and the KAT fixture being skip-if-missing. Both resolved 2026-05-11 (§10.1): Option B applied in v1 (per fox's direction — no v2 fork), so the default b1_model is now max_envelope (§3.1); the KAT fixture was regenerated (12 entries) and test_t3_bound_known_answer_tests now runs rather than skips. What remains for closure is fox's final close-or-iterate call (optionally a dav1d re-review of the envelope formula itself).

Items 1-5 below are tightening paths that refine the bound without invalidating it:

  1. C_B1 below the data-processing limit. The discrete channel-capacity bound log₂(SNR_grad + 1) is a per-step ceiling derived under uniform-prior signal levels; tighter bounds are possible if the loss surface has reduced adversary-controllable directions (e.g. Hessian rank deficiency). Empirical measurement via #000034's probe could tighten C_B1 by 1-2 orders of magnitude on typical deployments. (Tracked under #000043.)
  2. C_B2 below 1. Many LR choices map to similar trajectories; a deployment-specific empirical measurement of LR-trajectory diversity (1-Wasserstein distance between (LR_1, LR_2, … LR_R) final-checkpoint distributions) yields C_B2 < 1. (Tracked under #000043.)
  3. C_B3 closer to the random-shuffle baseline. If the deployment's SGD is random-shuffle (most modern training is), the adversarial-order bound used here over-estimates by O(√N_b) factor. C_B3 → O(1/√N_b). (Tracked under #000043; the cheapest of the three constant-tightening paths — needs only a DataLoader-config audit, no checkpoint.)
  4. Future B4-B5 control surfaces. Adaptive optimizer state manipulation (momentum, second-moment estimates) is not in the §1 model. The framework here generalizes — add new B_i terms as new T3 control surfaces are documented.
  5. Empirical validation. This bound has not been validated against an actual adversarial-training experiment. The acceptance criterion (§5 of the source ticket) explicitly marks empirical validation as out-of-scope; landing the doc establishes the framework operators can plan around. #000034's Phase 1b would feed directly into a future empirical-validation ticket.

§10.1 dav1d-review changes landed 2026-05-11

Not "open" — already done (Tier-1 in da62f80, Option B / Tier-2 in the follow-up commit):

  • B1 model = max_envelope (Option B, applied in v1). The default b1_model takes max(fraction_channels, aggregate_bias) — genuinely upper-bounding across both interpretations of g (§3.1). effective_control_v1 / fraction_channels / aggregate_bias reachable via --b1-model. Every output reports all three concrete B1 variants + b1_selected + both SNR readings (snr_grad, snr_per_channel). b1_model is echoed in inputs so KAT replays are unambiguous. Applied by changing the v1 default rather than forking a v2 (per fox's direction): CALCULATOR_VERSION stays t3-bound-v1-bottou-refinement (the "bottou-refinement" descriptor names the unchanged B3 term).
  • KAT fixture regenerated + regen tooling. bench/fixtures/t3-bound/known-answer-tests.jsonl (12 entries: §7 worked examples under max_envelope, explicit-mode pins for the other three models, a g=0 edge case) is now produced by scripts/generate_t3_bound_kat.py — run it after any algorithm change, then bump CALCULATOR_VERSION. test_t3_bound_known_answer_tests now runs (no longer skips); it pins b1_model, b1_selected, certification_status, and the per-contribution numbers.
  • Recommendation wording: "M2's single-window guarantee is broken" → "this conservative bound CANNOT CERTIFY M2's residual" (an upper bound exceeding 256 means we cannot certify, not that the adversary can steer 256 bits).
  • Structured output fields: b1_model, b1_selected, certification_status ∈ {CERTIFIED_BY_BOUND, NOT_CERTIFIED_BY_BOUND}, certification_threshold_bits, model_assumptions[], B1_fraction_channels, B1_aggregate_bias, B1_effective_control_v1, snr_per_channel — callers read a machine-readable status + the full B1 spread, not just prose.
  • Input validation: bools rejected for both int and float fields (isinstance(True, int) is True in Python — a real leak risk for a security calculator); NaN / ±inf rejected for every numeric input and constant; invalid b1_model rejected.
  • gradient_fraction = 0 now accepted (no T2 surface; B1 = 0; T3's LR + batch-order channels still contribute) — improves component isolation.
  • Tests: hard-coded cwd="/home/fox/git/arborist" replaced with pathlib.Path(__file__).resolve().parents[1] so the suite runs on any checkout. New bool/NaN/inf rejection tests, g=0 acceptance test, certification_status field tests, per-model B1 hand-formula tests, --b1-model CLI test, invalid-b1_model rejection test. Suite count 53 → 83.

§11. Calculator script

The closed-form bound from §6 lands as bench/scripts/t3_bound_calculator.py for operator use:

$ python -m bench.scripts.t3_bound_calculator \
    --gradient-fraction 0.05 --gradient-norm-max 1.0 \
    --gradient-noise-stddev 0.1 --lr-decision-interval 100 \
    --lr-grid-size 8 --window-length 10000 \
    --batches-per-epoch 1024 --steps-per-epoch 1024
    # [--b1-model max_envelope]   ← the default
{
  "calculator_version": "t3-bound-v1-bottou-refinement",
  "b1_model": "max_envelope",
  "b1_selected": "aggregate_bias",
  "I_window_bits_upper_bound": 6183.0154,
  "B1_contribution": 5849.625,
  "B1_fraction_channels": 1729.7158,
  "B1_aggregate_bias": 5849.625,
  "B1_effective_control_v1": 292.4813,
  "B2_contribution": 300.0,
  "B3_contribution": 33.3904,
  "snr_grad": 0.5,
  "snr_per_channel": 10.0,
  "decisions_in_window": 100,
  "epochs_in_window": 10,
  "constants": {"C_B1": 1.0, "C_B2": 1.0, "C_B3": 1.0},
  "certification_status": "NOT_CERTIFIED_BY_BOUND",
  "certification_threshold_bits": 256,
  "model_assumptions": [
    "M2_nonce_per_window",
    "SHA256_random_oracle_baseline",
    "B1_model_max_envelope",
    "B3_gradient_noise_refinement"
  ],
  "inputs": { "...echoed input tuple incl. c_b1/c_b2/c_b3 + b1_model..." },
  "recommendation": "I_window upper bound ≈ 6183.0 bits/window
                     EXCEEDS the SHA-256 (256 bit) certification
                     threshold. This conservative bound CANNOT
                     CERTIFY M2's single-window residual at this W
                     — it does not prove the adversary can steer
                     256 bits, only that the bound is too loose to
                     certify safety. Reduce W (or reduce g / R /
                     increase K, or tighten C_B* empirically) until
                     the certified bound is < 256 bits/window."
}

The above shows the default max_envelope model: B1 = aggregate_bias = 5849.6 bits (the larger of the two envelope terms; fraction_channels = 1729.7) → total 6183.0 bits/window, NOT_CERTIFIED_BY_BOUND at W=10000. All three B1 variants (including B1_effective_control_v1 = 292.5, what the older risk-score model would have given) are reported regardless of which b1_model is selected. Pass --b1-model effective_control_v1 (or fraction_channels / aggregate_bias) to switch the selected term. Operators read the structured certification_status field, not just the prose, and adjust W (or g, R, K) to tune — see §8.


§12. References

  • docs/soft-hash-channel-analysis.md — source analysis (#000018).
  • Ticket #000036 — this document's spec.
  • Ticket #000034 — φ_linear Hessian-alignment probe; informs the C_B1 tightening path.
  • Ticket #000035 — φ_PRG construction; closes the random-oracle modeling gap independent of T3.
  • Bottou & Bousquet (2008), "The Tradeoffs of Large Scale Learning" — gradient-noise / batch-order argument that inspires the §5 C_B3 model-bound (not a direct quotation; see §5's "model-bound, not theorem" note).
  • Hardt, Recht & Singer (2016), "Train Faster, Generalize Better: Stability of Stochastic Gradient Descent" — shuffle- stability framework the §5 C_B3 random-shuffle reasoning draws on.
  • dav1d review 2026-05-11 (RESPONSE_1 + RESPONSE_2) — the B1-double-g finding (§3.1), the recommendation-wording correction, validation hardening, and the conservative max_envelope B1 model. All applied in v1 2026-05-11 (Tier-1 + Option B); see §3.1 + §10.1.