ticket #000036 Tier-2: dav1d Option B (conservative B1 envelope) applied in v1
Per fox: apply the conservative max_envelope B1 model by changing the
v1 calculator's default — NOT by forking a v2. CALCULATOR_VERSION stays
"t3-bound-v1-bottou-refinement" (the descriptor names the unchanged B3
term); b1_model is echoed in the output AND the inputs dict so KAT
replays are unambiguous about which model produced a row.
Calculator (bench/scripts/t3_bound_calculator.py):
- New b1_model kwarg + --b1-model CLI flag, choices:
max_envelope (default) max(fraction_channels, aggregate_bias)
fraction_channels g · W · log₂(1 + G/σ)
aggregate_bias W · log₂(1 + g·G/σ)
effective_control_v1 g · W · log₂(1 + g·G/σ) (old non-worst-case)
- Default is now max_envelope — genuinely upper-bounding across both
interpretations of g (dav1d review §3 closure blocker, RESOLVED).
- Every output reports all three concrete B1 variants
(B1_fraction_channels / B1_aggregate_bias / B1_effective_control_v1),
b1_selected, and both SNR readings (snr_grad = g·G/σ,
snr_per_channel = G/σ) regardless of which b1_model was requested.
- model_assumptions[] now carries f"B1_model_{b1_model}".
- inputs echo now includes c_b1/c_b2/c_b3/b1_model (replay-complete).
- Invalid b1_model rejected with a ValueError naming the field.
- Baseline I_window: 625.8716 (effective_control_v1) → 6183.0154
(max_envelope: B1=aggregate_bias 5849.63 dominates fraction_channels
1729.72), certification_status NOT_CERTIFIED_BY_BOUND at W=10000.
KAT fixture (bench/fixtures/t3-bound/known-answer-tests.jsonl):
- Regenerated 2026-05-11 — 12 entries: the 8 §7-derived configs under
the new max_envelope default, a g=0 edge case, plus explicit-mode
pins for effective_control_v1 / fraction_channels / aggregate_bias.
- Each entry carries b1_model, expected_b1_selected,
expected_b1_{fraction_channels,aggregate_bias,effective_control_v1},
expected_snr_per_channel, expected_certification_status.
Tests (tests/test_t3_bound_calculator.py, 75 → 83):
- test_t3_bound_known_answer_tests no longer skips (fixture active);
pins b1_model, b1_selected, certification_status + numbers, tolerates
optional new fields on older fixtures.
- New: test_b1_max_envelope_exact_formula, test_invalid_b1_model_rejected,
test_cli_b1_model_flag (effective_control_v1 / fraction_channels /
aggregate_bias). test_b1_exact_formula renamed
test_b1_effective_control_v1_exact_formula and now passes the explicit
model. Updated baseline / below-256 / CLI tests for the new numbers.
Doc (docs/soft-hash-channel-t3-bound.md):
- Header + §0 + §3.1 + §6 + §7 (worked examples) + §8 (operator
guidance W-solving) + §10 (closure blockers RESOLVED) + §10.1 +
§11 (calculator schema) + §12 all updated for the max_envelope
default. §8: target-256 W drops from ~4196 to ~415 steps under the
conservative model — the ~10× cost of not assuming which g-reading
holds; operators who can measure effective-control applies can use
--b1-model effective_control_v1 for the looser W (a calibration
claim they must justify, not a default).
Status (#000036 ticket + TICKETS.md): both prior dav1d closure
blockers cleared (B1 worst-case model + active KAT fixture); remaining
= fox's final close-or-iterate call.
AUTOCOUNT markers bumped 75 → 83. Full suite: 2288 passed, 28 skipped.
This commit is contained in:
parent
dbe824944a
commit
1d1a942d57
8 changed files with 501 additions and 258 deletions
|
|
@ -1,12 +1,16 @@
|
|||
# T3 bound calculator known-answer tests — version t3-bound-v1-bottou-refinement
|
||||
# Generated 2026-05-10 from docs/soft-hash-channel-t3-bound.md §7
|
||||
# worked examples + override-constant variants + edge regimes.
|
||||
# Algorithm change MUST bump CALCULATOR_VERSION + emit new fixture.
|
||||
{"label": "small-deployment-\u00a77.1", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"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}, "expected_total": 625.8716, "expected_b1": 292.4813, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5}
|
||||
{"label": "medium-deployment-\u00a77.2", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 1000, "lr_grid_size": 16, "window_length": 100000, "batches_per_epoch": 8192, "steps_per_epoch": 8192}, "expected_total": 3387.72, "expected_b1": 2924.8125, "expected_b2": 400.0, "expected_b3": 62.9075, "expected_snr_grad": 0.5}
|
||||
{"label": "hardened-deployment-\u00a77.3", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"gradient_fraction": 0.01, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 100, "lr_grid_size": 4, "window_length": 10000, "batches_per_epoch": 1024, "steps_per_epoch": 1024}, "expected_total": 247.1407, "expected_b1": 13.7504, "expected_b2": 200.0, "expected_b3": 33.3904, "expected_snr_grad": 0.1}
|
||||
{"label": "extreme-low-g", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"gradient_fraction": 0.001, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.5, "lr_decision_interval": 500, "lr_grid_size": 2, "window_length": 5000, "batches_per_epoch": 256, "steps_per_epoch": 256}, "expected_total": 80.0144, "expected_b1": 0.0144, "expected_b2": 10.0, "expected_b3": 70.0, "expected_snr_grad": 0.002}
|
||||
{"label": "tight-window-W=100", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 2.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 50, "lr_grid_size": 4, "window_length": 100, "batches_per_epoch": 64, "steps_per_epoch": 64}, "expected_total": 10.6781, "expected_b1": 5.0, "expected_b2": 4.0, "expected_b3": 1.6781, "expected_snr_grad": 1.0}
|
||||
{"label": "tightened-c-b1", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"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, "c_b1": 0.5}, "expected_total": 479.631, "expected_b1": 146.2406, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5}
|
||||
{"label": "all-constants-tight", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"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, "c_b1": 0.1, "c_b2": 0.1, "c_b3": 0.1}, "expected_total": 62.5872, "expected_b1": 29.2481, "expected_b2": 30.0, "expected_b3": 3.339, "expected_snr_grad": 0.5}
|
||||
{"label": "b3-floor-regime", "calculator_version": "t3-bound-v1-bottou-refinement", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 100.0, "gradient_noise_stddev": 0.001, "lr_decision_interval": 100, "lr_grid_size": 8, "window_length": 10000, "batches_per_epoch": 4, "steps_per_epoch": 4}, "expected_total": 6444.0004, "expected_b1": 6144.0004, "expected_b2": 300.0, "expected_b3": 0.0, "expected_snr_grad": 5000.0}
|
||||
# Regenerated 2026-05-11 after the b1_model=max_envelope default change
|
||||
# (dav1d review Option B applied in v1). Algorithm change MUST bump
|
||||
# CALCULATOR_VERSION + emit a new fixture file.
|
||||
{"label": "small-deployment-§7.1", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"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, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 6183.0154, "expected_b1": 5849.625, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 1729.7158, "expected_b1_aggregate_bias": 5849.625, "expected_b1_effective_control_v1": 292.4813, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "medium-deployment-§7.2", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 1000, "lr_grid_size": 16, "window_length": 100000, "batches_per_epoch": 8192, "steps_per_epoch": 8192, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 58959.1575, "expected_b1": 58496.2501, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 17297.1581, "expected_b1_aggregate_bias": 58496.2501, "expected_b1_effective_control_v1": 2924.8125, "expected_b2": 400.0, "expected_b3": 62.9075, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "hardened-deployment-§7.3", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.01, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 100, "lr_grid_size": 4, "window_length": 10000, "batches_per_epoch": 1024, "steps_per_epoch": 1024, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 1608.4256, "expected_b1": 1375.0352, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 345.9432, "expected_b1_aggregate_bias": 1375.0352, "expected_b1_effective_control_v1": 13.7504, "expected_b2": 200.0, "expected_b3": 33.3904, "expected_snr_grad": 0.1, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "extreme-low-g", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.001, "gradient_norm_max": 1.0, "gradient_noise_stddev": 0.5, "lr_decision_interval": 500, "lr_grid_size": 2, "window_length": 5000, "batches_per_epoch": 256, "steps_per_epoch": 256, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 94.4125, "expected_b1": 14.4125, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 7.9248, "expected_b1_aggregate_bias": 14.4125, "expected_b1_effective_control_v1": 0.0144, "expected_b2": 10.0, "expected_b3": 70.0, "expected_snr_grad": 0.002, "expected_snr_per_channel": 2.0, "expected_certification_status": "CERTIFIED_BY_BOUND"}
|
||||
{"label": "tight-window-W=100", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 2.0, "gradient_noise_stddev": 0.1, "lr_decision_interval": 50, "lr_grid_size": 4, "window_length": 100, "batches_per_epoch": 64, "steps_per_epoch": 64, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 105.6781, "expected_b1": 100.0, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 21.9616, "expected_b1_aggregate_bias": 100.0, "expected_b1_effective_control_v1": 5.0, "expected_b2": 4.0, "expected_b3": 1.6781, "expected_snr_grad": 1.0, "expected_snr_per_channel": 20.0, "expected_certification_status": "CERTIFIED_BY_BOUND"}
|
||||
{"label": "tightened-c-b1", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"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, "c_b1": 0.5, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 3258.2029, "expected_b1": 2924.8125, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 864.8579, "expected_b1_aggregate_bias": 2924.8125, "expected_b1_effective_control_v1": 146.2406, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "all-constants-tight", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"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, "c_b1": 0.1, "c_b2": 0.1, "c_b3": 0.1, "b1_model": "max_envelope"}, "expected_total": 618.3015, "expected_b1": 584.9625, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 172.9716, "expected_b1_aggregate_bias": 584.9625, "expected_b1_effective_control_v1": 29.2481, "expected_b2": 30.0, "expected_b3": 3.339, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "b3-floor-regime", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.05, "gradient_norm_max": 100.0, "gradient_noise_stddev": 0.001, "lr_decision_interval": 100, "lr_grid_size": 8, "window_length": 10000, "batches_per_epoch": 4, "steps_per_epoch": 4, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 123180.0089, "expected_b1": 122880.0089, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 8304.8275, "expected_b1_aggregate_bias": 122880.0089, "expected_b1_effective_control_v1": 6144.0004, "expected_b2": 300.0, "expected_b3": 0.0, "expected_snr_grad": 5000.0, "expected_snr_per_channel": 100000.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "gradient-fraction-zero", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "max_envelope", "inputs": {"gradient_fraction": 0.0, "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, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "max_envelope"}, "expected_total": 333.3904, "expected_b1": 0.0, "expected_b1_selected": "fraction_channels", "expected_b1_fraction_channels": 0.0, "expected_b1_aggregate_bias": 0.0, "expected_b1_effective_control_v1": 0.0, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.0, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "b1-effective-control-v1-mode", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "effective_control_v1", "inputs": {"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, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "effective_control_v1"}, "expected_total": 625.8716, "expected_b1": 292.4813, "expected_b1_selected": "effective_control_v1", "expected_b1_fraction_channels": 1729.7158, "expected_b1_aggregate_bias": 5849.625, "expected_b1_effective_control_v1": 292.4813, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "b1-fraction-channels-mode", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "fraction_channels", "inputs": {"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, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "fraction_channels"}, "expected_total": 2063.1062, "expected_b1": 1729.7158, "expected_b1_selected": "fraction_channels", "expected_b1_fraction_channels": 1729.7158, "expected_b1_aggregate_bias": 5849.625, "expected_b1_effective_control_v1": 292.4813, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
{"label": "b1-aggregate-bias-mode", "calculator_version": "t3-bound-v1-bottou-refinement", "b1_model": "aggregate_bias", "inputs": {"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, "c_b1": 1.0, "c_b2": 1.0, "c_b3": 1.0, "b1_model": "aggregate_bias"}, "expected_total": 6183.0154, "expected_b1": 5849.625, "expected_b1_selected": "aggregate_bias", "expected_b1_fraction_channels": 1729.7158, "expected_b1_aggregate_bias": 5849.625, "expected_b1_effective_control_v1": 292.4813, "expected_b2": 300.0, "expected_b3": 33.3904, "expected_snr_grad": 0.5, "expected_snr_per_channel": 10.0, "expected_certification_status": "NOT_CERTIFIED_BY_BOUND"}
|
||||
|
|
|
|||
|
|
@ -23,15 +23,24 @@ processing inequality; see §6 + §10). Operators with deployment-
|
|||
specific empirical measurements of the constants pass them via
|
||||
``--c-b1`` / ``--c-b2`` / ``--c-b3`` flags.
|
||||
|
||||
**B1 model.** This v1 calculator uses ``b1_model="effective_control_v1"``:
|
||||
``g`` is read as an *effective gradient-control coefficient* that
|
||||
simultaneously bounds the fraction of steerable directions AND the
|
||||
amplitude shrinkage of the aggregate adversarial gradient. Under that
|
||||
reading the B1 formula ``C_B1 · g · W · log₂(1 + g·G/σ)`` is sound,
|
||||
but it is **not the most-conservative gradient adversary** — see
|
||||
#000036 §3 + §10 for the alternative ``b1_model="max_envelope"``
|
||||
path (deferred to a v2 bump). For now ``certification_status`` is
|
||||
relative to this v1 effective-control model.
|
||||
**B1 model.** Default ``b1_model="max_envelope"`` (#000036 §3.1,
|
||||
dav1d review 2026-05-11): ``g`` has two competing interpretations —
|
||||
*fraction of steerable directions* (each carrying full per-channel
|
||||
SNR ``G/σ``) and *aggregate amplitude shrinkage* (one effective
|
||||
channel carrying SNR ``g·G/σ``). The conservative envelope is the
|
||||
larger of the two:
|
||||
|
||||
B1_fraction_channels = C_B1 · g · W · log₂(1 + G/σ)
|
||||
B1_aggregate_bias = C_B1 · W · log₂(1 + g·G/σ)
|
||||
B1 (max_envelope) = max(B1_fraction_channels, B1_aggregate_bias)
|
||||
|
||||
Other ``b1_model`` choices: ``"fraction_channels"`` / ``"aggregate_bias"``
|
||||
(the individual envelope terms) and ``"effective_control_v1"`` (the
|
||||
older ``C_B1 · g · W · log₂(1 + g·G/σ)`` — an operational risk
|
||||
score, NOT a worst-case bound; kept for backward comparison).
|
||||
``certification_status`` is relative to whichever model is selected;
|
||||
under the default ``max_envelope`` it is a genuine upper-bound
|
||||
certification.
|
||||
|
||||
Pure stdlib. No numpy / scipy dependency — the math is
|
||||
arithmetic + math.log2.
|
||||
|
|
@ -58,7 +67,16 @@ import sys
|
|||
|
||||
|
||||
CALCULATOR_VERSION = "t3-bound-v1-bottou-refinement"
|
||||
B1_MODEL = "effective_control_v1"
|
||||
# B1 model selection (#000036 §3.1). Default is the conservative
|
||||
# envelope; effective_control_v1 is the older non-worst-case formula
|
||||
# kept for backward comparison.
|
||||
B1_MODELS = (
|
||||
"max_envelope",
|
||||
"fraction_channels",
|
||||
"aggregate_bias",
|
||||
"effective_control_v1",
|
||||
)
|
||||
B1_MODEL_DEFAULT = "max_envelope"
|
||||
CERTIFICATION_THRESHOLD_BITS = 256
|
||||
|
||||
|
||||
|
|
@ -100,13 +118,21 @@ def t3_bound_bits(
|
|||
c_b1: float = 1.0,
|
||||
c_b2: float = 1.0,
|
||||
c_b3: float = 1.0,
|
||||
b1_model: str = B1_MODEL_DEFAULT,
|
||||
) -> dict:
|
||||
"""Compute the per-window mutual-information bound + per-bandwidth
|
||||
contributions per #000036 §6.
|
||||
|
||||
Returns a dict with the total bound, three per-bandwidth
|
||||
contributions, the constants in use, and a sentence of operator
|
||||
guidance based on the bound vs the SHA-256 (256-bit) baseline.
|
||||
``b1_model`` selects the gradient-bias model (see #000036 §3.1):
|
||||
``"max_envelope"`` (default, conservative), ``"fraction_channels"``,
|
||||
``"aggregate_bias"``, or ``"effective_control_v1"`` (older
|
||||
non-worst-case formula).
|
||||
|
||||
Returns a dict with the total bound, the per-bandwidth
|
||||
contributions (including all three B1 model variants), the
|
||||
constants + selected B1 model, a structured ``certification_status``,
|
||||
and a sentence of operator guidance based on the bound vs the
|
||||
SHA-256 (256-bit) certification threshold.
|
||||
"""
|
||||
# Validation — reject bools / NaN / inf; coerce numeric types.
|
||||
gradient_fraction = _require_finite_float("gradient_fraction", gradient_fraction)
|
||||
|
|
@ -140,16 +166,41 @@ def t3_bound_bits(
|
|||
for name, c in [("c_b1", c_b1), ("c_b2", c_b2), ("c_b3", c_b3)]:
|
||||
if not 0 <= c <= 1:
|
||||
raise ValueError(f"{name} must be in [0, 1]; got {c}")
|
||||
if b1_model not in B1_MODELS:
|
||||
raise ValueError(
|
||||
f"b1_model must be one of {B1_MODELS}; got {b1_model!r}"
|
||||
)
|
||||
|
||||
# B1 — gradient bias. Per-step discrete channel-capacity bound on
|
||||
# the adversary-controlled parameter shift (NOT Fano's inequality —
|
||||
# see #000036 §3): the per-step shift falls in one of ~SNR_grad+1
|
||||
# distinguishable buckets, capacity ≤ log₂(SNR_grad+1). Under the
|
||||
# b1_model="effective_control_v1" reading, g bounds both the
|
||||
# steerable-direction fraction and the aggregate amplitude shrinkage.
|
||||
snr_grad = gradient_fraction * gradient_norm_max / gradient_noise_stddev
|
||||
b1_per_step = math.log2(snr_grad + 1)
|
||||
b1 = c_b1 * gradient_fraction * window_length * b1_per_step
|
||||
# see #000036 §3): the per-step shift falls in one of ~SNR+1
|
||||
# distinguishable buckets, capacity ≤ log₂(SNR+1). Two SNR readings
|
||||
# (#000036 §3.1):
|
||||
# per-channel SNR = G/σ → fraction_channels model
|
||||
# aggregate SNR = g·G/σ → aggregate_bias / effective_control
|
||||
# Default b1_model="max_envelope" = max of the two envelope terms —
|
||||
# genuinely upper-bounding across both interpretations (dav1d review
|
||||
# 2026-05-11).
|
||||
snr_grad = gradient_fraction * gradient_norm_max / gradient_noise_stddev # g·G/σ
|
||||
snr_per_channel = gradient_norm_max / gradient_noise_stddev # G/σ
|
||||
b1_fraction_channels = (
|
||||
c_b1 * gradient_fraction * window_length * math.log2(snr_per_channel + 1)
|
||||
)
|
||||
b1_aggregate_bias = c_b1 * window_length * math.log2(snr_grad + 1)
|
||||
b1_effective_control = (
|
||||
c_b1 * gradient_fraction * window_length * math.log2(snr_grad + 1)
|
||||
)
|
||||
if b1_model == "max_envelope":
|
||||
if b1_fraction_channels >= b1_aggregate_bias:
|
||||
b1, b1_selected = b1_fraction_channels, "fraction_channels"
|
||||
else:
|
||||
b1, b1_selected = b1_aggregate_bias, "aggregate_bias"
|
||||
elif b1_model == "fraction_channels":
|
||||
b1, b1_selected = b1_fraction_channels, "fraction_channels"
|
||||
elif b1_model == "aggregate_bias":
|
||||
b1, b1_selected = b1_aggregate_bias, "aggregate_bias"
|
||||
else: # effective_control_v1
|
||||
b1, b1_selected = b1_effective_control, "effective_control_v1"
|
||||
|
||||
# B2 — LR selection. R-symbol categorical channel at every K-step
|
||||
# decision point (#000036 §4).
|
||||
|
|
@ -210,12 +261,17 @@ def t3_bound_bits(
|
|||
|
||||
return {
|
||||
"calculator_version": CALCULATOR_VERSION,
|
||||
"b1_model": B1_MODEL,
|
||||
"b1_model": b1_model,
|
||||
"b1_selected": b1_selected,
|
||||
"I_window_bits_upper_bound": round(total, 4),
|
||||
"B1_contribution": round(b1, 4),
|
||||
"B1_fraction_channels": round(b1_fraction_channels, 4),
|
||||
"B1_aggregate_bias": round(b1_aggregate_bias, 4),
|
||||
"B1_effective_control_v1": round(b1_effective_control, 4),
|
||||
"B2_contribution": round(b2, 4),
|
||||
"B3_contribution": round(b3, 4),
|
||||
"snr_grad": round(snr_grad, 4),
|
||||
"snr_per_channel": round(snr_per_channel, 4),
|
||||
"decisions_in_window": decisions_in_window,
|
||||
"epochs_in_window": epochs_in_window,
|
||||
"constants": {"C_B1": c_b1, "C_B2": c_b2, "C_B3": c_b3},
|
||||
|
|
@ -224,7 +280,7 @@ def t3_bound_bits(
|
|||
"model_assumptions": [
|
||||
"M2_nonce_per_window",
|
||||
"SHA256_random_oracle_baseline",
|
||||
"B1_effective_control_model_v1",
|
||||
f"B1_model_{b1_model}",
|
||||
"B3_gradient_noise_refinement",
|
||||
],
|
||||
"inputs": {
|
||||
|
|
@ -236,6 +292,10 @@ def t3_bound_bits(
|
|||
"window_length": window_length,
|
||||
"batches_per_epoch": batches_per_epoch,
|
||||
"steps_per_epoch": steps_per_epoch,
|
||||
"c_b1": c_b1,
|
||||
"c_b2": c_b2,
|
||||
"c_b3": c_b3,
|
||||
"b1_model": b1_model,
|
||||
},
|
||||
"recommendation": recommendation,
|
||||
}
|
||||
|
|
@ -245,7 +305,7 @@ def main(argv: list[str] | None = None) -> int:
|
|||
p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
p.add_argument(
|
||||
"--gradient-fraction", type=float, required=True,
|
||||
help="g — effective gradient-control coefficient (b1_model=effective_control_v1); in [0, 1], 0 = no T2 surface",
|
||||
help="g — gradient-control coefficient; in [0, 1], 0 = no T2 surface. Interpretation depends on --b1-model.",
|
||||
)
|
||||
p.add_argument(
|
||||
"--gradient-norm-max", type=float, required=True,
|
||||
|
|
@ -287,6 +347,15 @@ def main(argv: list[str] | None = None) -> int:
|
|||
"--c-b3", type=float, default=1.0,
|
||||
help="C_B3 constant; default 1.0",
|
||||
)
|
||||
p.add_argument(
|
||||
"--b1-model", type=str, default=B1_MODEL_DEFAULT, choices=list(B1_MODELS),
|
||||
help=(
|
||||
"B1 gradient-bias model (#000036 §3.1). Default 'max_envelope' = "
|
||||
"worst-case envelope across the two g-interpretations; "
|
||||
"'fraction_channels' / 'aggregate_bias' = the individual terms; "
|
||||
"'effective_control_v1' = older non-worst-case formula."
|
||||
),
|
||||
)
|
||||
|
||||
args = p.parse_args(argv)
|
||||
try:
|
||||
|
|
@ -302,6 +371,7 @@ def main(argv: list[str] | None = None) -> int:
|
|||
c_b1=args.c_b1,
|
||||
c_b2=args.c_b2,
|
||||
c_b3=args.c_b3,
|
||||
b1_model=args.b1_model,
|
||||
)
|
||||
except ValueError as e:
|
||||
print(f"input error: {e}", file=sys.stderr)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ Newest first. Update on every open/close.
|
|||
| #000039 | Optional `sqlite-vec` retrieval backend (A/B vs FTS5, hybrid not replacement) | open · awaiting go/no-go (doc-only Phase 0) | 2026-05-09 | — |
|
||||
| #000038 | Phase 4 content acquisition — proprietary textbook license decisions for warrant coverage | closed · obviated 2026-05-10 by alias-substitution sprint under #000031 (74 rows in #000041 + 13 rows in #000042); 92/92 records now resolve. Residue (multilingual PD, Hilbert-Ackermann OCR, Knuth permission, personal-copy path B) preserved as design log §8 | 2026-05-09 | — |
|
||||
| #000037 | Prometheus-Σ recursive falsification controller (bicameral substrate) | in progress · Phases 0 + 1 + 1.b + 1.c + 2 landed 2026-05-10; **§12 Trigger 2 fired** (divergence variance 0.575 / N=37); §22 Findings 2 + 3 RESOLVED (kernel/llm cost split + sweep_weights §15.4 + per-mode τ_qa); `controller_events` carries 4 event kinds (decision · difficulty · budget_allocation · falsification_proposal) feeding `arborist controller-events` inspector + live-harvest third bucket in `bench/scripts/harvest_falsification_proposals.py`; §12 Trigger 1 probe wired 2026-05-11 (`trigger_1_branch_density` reads `fork_score_branches` — measurable, not yet fired); Phase 3 sleep-sweep scheduler tracked under #000045 (gating ticket) | 2026-05-09 | — |
|
||||
| #000036 | T3 per-window covert-channel budget bound | in progress · Phase 1 + dav1d review returned 2026-05-11; Tier-1 polish applied (wording → "CANNOT CERTIFY", structured `certification_status`/`b1_model` fields, bool/NaN/inf validation, `g=0` accepted, test cwd fix; 53 → 75 tests); **closure blockers: B1 conservative-envelope v2 calculator (awaits fox go/no-go) + active KAT fixture** | 2026-05-09 | — |
|
||||
| #000036 | T3 per-window covert-channel budget bound | in progress · Phase 1 + dav1d review 2026-05-11 → Tier-1 + Tier-2 (Option B = `b1_model=max_envelope` default, applied *in v1*, no v2 fork) both landed 2026-05-11; KAT regenerated (12 entries, active); baseline 625.87 → 6183.02 (max_envelope); 53 → 83 tests; both prior closure blockers cleared — remaining = fox final close-or-iterate call | 2026-05-09 | — |
|
||||
| #000035 | PRG choice for φ_PRG (HMAC-SHA-512 expansion) | in progress · Phase 1 landed 2026-05-10; v7 §9.10 amendment awaits maintainer review | 2026-05-09 | — |
|
||||
| #000034 | Hessian alignment under φ_linear | in progress · Phase 1a landed 2026-05-10 (synthetic-ablation probe + KAT fixture); Phase 1b parks for v7 ramp-up | 2026-05-09 | — |
|
||||
| #000033 | Claim-pack pillar VII (combinatorics) | closed · landed 2026-05-09 (live in shard 000.db; lift verified) | 2026-05-09 | — |
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ bench across three modules:
|
|||
closed-form bound for #000036
|
||||
|
||||
The exemplar test file is ``tests/test_t3_bound_calculator.py``
|
||||
(<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->75<!--/AUTOCOUNT--> cases as of 2026-05-10; fox shipped 51 in the
|
||||
(<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->83<!--/AUTOCOUNT--> cases as of 2026-05-10; fox shipped 51 in the
|
||||
initial cut and the +2 KAT-fixture-gap closure landed in
|
||||
``581ad90``). The other two test files
|
||||
(``tests/test_anchor_prg.py`` and
|
||||
|
|
@ -378,7 +378,7 @@ shape exposes the corresponding surface. Many calculator modules
|
|||
Exemplar test files:
|
||||
|
||||
- ``tests/test_t3_bound_calculator.py`` —
|
||||
<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->75<!--/AUTOCOUNT--> tests covering
|
||||
<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->83<!--/AUTOCOUNT--> tests covering
|
||||
items 1-9 for the T3 closed-form bound.
|
||||
- ``tests/test_pi_star_arithmetic.py`` —
|
||||
<!--AUTOCOUNT:tests:tests/test_pi_star_arithmetic.py-->56<!--/AUTOCOUNT--> tests covering items
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@
|
|||
|
||||
**Ticket**: #000036
|
||||
**Source analysis**: `docs/soft-hash-channel-analysis.md`
|
||||
**Date**: 2026-05-10 (review pass 2026-05-11)
|
||||
**Date**: 2026-05-10 (dav1d review pass + Option-B applied 2026-05-11)
|
||||
**Status**: formal derivation + calculator landed; **dav1d review
|
||||
returned 2026-05-11**. Tier-1 polish applied (recommendation
|
||||
wording, structured `certification_status` output, validation
|
||||
hardening, B1-model labelling — see §3.1 + §10.1). **Closure
|
||||
blockers remaining**: B1 conservative-envelope (v2 calculator,
|
||||
§10 item 1) and active KAT fixture (§10 item 2). The framework is
|
||||
the deliverable; the named constants are conservative starting
|
||||
estimates that empirical tightening (#000043) can replace without
|
||||
changing call sites.
|
||||
returned 2026-05-11** → **Tier-1 polish + Tier-2 (Option B: the
|
||||
conservative `max_envelope` B1 model, applied in v1 — no v2 fork)
|
||||
both landed 2026-05-11**. KAT fixture regenerated (12 entries,
|
||||
active — `test_t3_bound_known_answer_tests` no longer skips). The
|
||||
default B1 model is now `max_envelope` (§3.1); `effective_control_v1`
|
||||
is reachable as a backward-comparison mode. Remaining before
|
||||
closure: fox's final close-or-iterate call (optionally a dav1d
|
||||
re-review of the envelope formula). The named C_B* constants are
|
||||
conservative starting estimates that empirical tightening
|
||||
(#000043) can replace without changing call sites.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -25,7 +27,7 @@ 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`)
|
||||
landed these findings:
|
||||
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
|
||||
|
|
@ -34,26 +36,32 @@ landed these findings:
|
|||
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)** — **closure blocker**. `g` appears
|
||||
twice in the per-window expression, which is only sound under
|
||||
the `effective_control_v1` reading (§3.1). A worst-case
|
||||
gradient adversary needs the `max_envelope` model — the v2
|
||||
calculator path (§10 item 1).
|
||||
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 7;
|
||||
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 yields
|
||||
`I_window ≈ 626 bits/window` for a default deployment config
|
||||
**under the v1 effective-control B1 model** — exceeding SHA-256's
|
||||
256-bit threshold, so `certification_status = NOT_CERTIFIED_BY_BOUND`.
|
||||
A conservative `max_envelope` B1 model would produce ~5850 bits.
|
||||
The framework's job is to make the trigger derivable from
|
||||
operator-measurable inputs; the v2 path makes the bound
|
||||
worst-case-conservative rather than effective-control-relative.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -224,58 +232,49 @@ 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 — `g` appears twice (dav1d review 2026-05-11)
|
||||
### §3.1 The B1 model — `max_envelope` (default) vs the alternatives
|
||||
|
||||
Note that `g` enters the per-window B1 expression **twice**: once
|
||||
as the outer multiplier `g · W` (number of adversary-controlled
|
||||
`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`. That double use is only sound
|
||||
under a specific reading:
|
||||
`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 = "effective_control_v1":
|
||||
g is an effective gradient-control coefficient that
|
||||
simultaneously bounds (a) the fraction of steerable
|
||||
directions per step AND (b) the amplitude shrinkage of
|
||||
the aggregate adversarial gradient signal.
|
||||
```
|
||||
| `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 |
|
||||
|
||||
If instead `g` means **only** "fraction of gradient computations
|
||||
controlled" (with full per-channel amplitude), the conservative
|
||||
shape is larger. dav1d's review spelled out the spread on the
|
||||
baseline (`g=0.05, ‖∇L_max‖=1, σ_grad=0.1, W=10000`):
|
||||
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.
|
||||
|
||||
| B1 model | Formula | Baseline B1 |
|
||||
|---|---|---|
|
||||
| `effective_control_v1` (current) | `g · W · log₂(1 + g·G/σ)` | **292.5 bits** |
|
||||
| `fraction_channels` (g = channel fraction only) | `g · W · log₂(1 + G/σ)` | 1 729.7 bits |
|
||||
| `aggregate_bias` (g = amplitude shrinkage only) | `W · log₂(1 + g·G/σ)` | 5 849.6 bits |
|
||||
| `max_envelope` (conservative) | `max(fraction_channels, aggregate_bias)` | 5 849.6 bits |
|
||||
**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*.
|
||||
|
||||
The current v1 calculator uses `effective_control_v1`. The
|
||||
`certification_status` it emits is therefore **relative to that
|
||||
model** — it is an operational risk score, not a worst-case upper
|
||||
bound across all gradient-adversary interpretations.
|
||||
|
||||
**The conservative `max_envelope` model is the v2 path.** When the
|
||||
team wants the calculator to certify against the worst-case
|
||||
gradient adversary, it should:
|
||||
|
||||
```
|
||||
1. add a b1_model parameter (default "max_envelope" for v2)
|
||||
2. bump CALCULATOR_VERSION → "t3-bound-v2-conservative-envelope"
|
||||
3. emit a new KAT fixture under
|
||||
bench/fixtures/t3-bound/v2-conservative-envelope/
|
||||
4. keep effective_control_v1 reachable as a backward-compat mode
|
||||
so v1 rows stay replayable
|
||||
```
|
||||
|
||||
That v2 work is **not in this ticket** — see §10. Until it lands,
|
||||
read the calculator's output as: "under the v1 effective-control
|
||||
model, the baseline evaluates to ~626 bits/window; this exceeds
|
||||
the 256-bit certification threshold so the calculator CANNOT
|
||||
CERTIFY M2 residual safety at W=10000; a conservative B1 envelope
|
||||
would produce a larger bound (~5850 bits in the example above)."
|
||||
**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).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -384,50 +383,70 @@ remains Phase 2 / #000043.
|
|||
|
||||
## §6. Combined per-window bound
|
||||
|
||||
Combining §3-§5:
|
||||
Combining §3-§5, with the **default `b1_model = max_envelope`**
|
||||
(§3.1):
|
||||
|
||||
```
|
||||
I_window ≤ C_B1 · g · W · log₂( SNR_grad + 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; future work may tighten any of them
|
||||
based on empirical loss-surface measurement).
|
||||
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 = 0.5
|
||||
snr_grad = g·G/σ = 0.5 snr_per_channel = G/σ = 10.0
|
||||
|
||||
B1 = 1 · 0.05 · 10000 · log₂(1.5) ≈ 292.48 bits
|
||||
B2 = 1 · ⌈10000/100⌉ · log₂(8) = 300.00 bits
|
||||
B3 = 1 · ⌈10000/1024⌉ · log₂(102.4) / 2 ≈ 33.39 bits
|
||||
total ≈ 625.87 bits/window
|
||||
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)
|
||||
```
|
||||
|
||||
(Numbers are the calculator's closed-form output, not rounded
|
||||
estimates; see ``bench/scripts/t3_bound_calculator.py`` and the
|
||||
unit tests in ``tests/test_t3_bound_calculator.py``.)
|
||||
|
||||
### §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_grad = 0.5 snr_per_channel = 10.0
|
||||
|
||||
B1 = 1 · 0.05 · 100000 · log₂(1.5) ≈ 2924.81 bits
|
||||
B2 = 1 · ⌈100000/1000⌉ · log₂(16) = 400.00 bits
|
||||
B3 = 1 · ⌈100000/8192⌉ · log₂(819.2) / 2 ≈ 62.91 bits
|
||||
total ≈ 3387.72 bits/window
|
||||
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)
|
||||
|
|
@ -435,54 +454,78 @@ total ≈ 3387.72 bits/window
|
|||
```
|
||||
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_grad = 0.1 snr_per_channel = 10.0
|
||||
|
||||
B1 = 1 · 0.01 · 10000 · log₂(1.1) ≈ 13.75 bits
|
||||
B2 = 1 · ⌈10000/100⌉ · log₂(4) = 200.00 bits
|
||||
B3 = 1 · ⌈10000/1024⌉ · log₂(102.4) / 2 ≈ 33.39 bits
|
||||
total ≈ 247.14 bits/window
|
||||
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.
|
||||
`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):
|
||||
|
||||
Solving for `W` in §6 with the small-deployment constants:
|
||||
|
||||
```
|
||||
1 ≥ 0.05 · W · 0.58 + (W/100) · 3 + (W/1024) · 3.34 / 2
|
||||
1 ≥ 0.029 W + 0.030 W + 0.0016 W
|
||||
1 ≥ 0.061 W
|
||||
W ≤ 16 steps (impractical — re-anchor every 16 steps)
|
||||
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;
|
||||
informational equivalent of a single brute-force preimage
|
||||
attempt per window):
|
||||
**Target = 256 bits/window** (the SHA-256 hard-hash output size):
|
||||
|
||||
```
|
||||
256 ≥ 0.061 W
|
||||
W ≤ 4196 steps
|
||||
256 ≥ 0.6166 W → W ≤ 415 steps
|
||||
```
|
||||
|
||||
This is the practical operating range: re-anchor approximately
|
||||
every 4000 SGD steps to keep T3's per-window steerage at the
|
||||
SHA-256 baseline.
|
||||
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.07 × 10^6 steps
|
||||
W ≤ 1.06 × 10^5 steps
|
||||
```
|
||||
|
||||
This admits week-long training runs between anchor rotations.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -501,32 +544,20 @@ is the explicit form. Reference: this doc §6.
|
|||
|
||||
## §10. Open questions + future work
|
||||
|
||||
Items 1-2 below are the **closure blockers** flagged by dav1d's
|
||||
2026-05-11 review; items 3-6 are tightening paths that refine
|
||||
the bound without invalidating it.
|
||||
**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).
|
||||
|
||||
1. **B1 conservative envelope (v2 calculator) — closure blocker.**
|
||||
The current `b1_model="effective_control_v1"` (§3.1) reads `g`
|
||||
as a combined direction-fraction + amplitude-shrinkage
|
||||
coefficient, which makes the headline B1 ~292 bits on the
|
||||
baseline. A worst-case gradient adversary needs the
|
||||
`max_envelope` model (~5850 bits on the same baseline). Until
|
||||
the v2 calculator with `b1_model` selection lands —
|
||||
`CALCULATOR_VERSION → t3-bound-v2-conservative-envelope`, new
|
||||
KAT fixture under `bench/fixtures/t3-bound/v2-conservative-envelope/`,
|
||||
`effective_control_v1` kept as a backward-compat mode — the
|
||||
calculator's `certification_status` is relative to the v1
|
||||
model only and should be read as an operational risk score,
|
||||
not a certified worst-case bound. **Do not close #000036
|
||||
until this is resolved** (either by landing v2 or by an
|
||||
explicit team decision to keep v1 with the narrowed-semantics
|
||||
caveat documented in §3.1).
|
||||
2. **Active KAT fixture for closure.** `bench/fixtures/t3-bound/known-answer-tests.jsonl`
|
||||
must exist and `test_t3_bound_known_answer_tests` must run
|
||||
(not skip) with ≥ 5 entries before #000036 closes. If the v2
|
||||
B1 model lands first, the KAT fixture goes under the
|
||||
versioned subdirectory.
|
||||
3. **C_B1 below the data-processing limit.** The discrete
|
||||
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
|
||||
|
|
@ -534,22 +565,22 @@ the bound without invalidating it.
|
|||
deficiency). Empirical measurement via #000034's probe
|
||||
could tighten C_B1 by 1-2 orders of magnitude on typical
|
||||
deployments. (Tracked under #000043.)
|
||||
4. **C_B2 below 1.** Many LR choices map to similar
|
||||
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.)
|
||||
5. **C_B3 closer to the random-shuffle baseline.** If the
|
||||
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.)
|
||||
6. **Future B4-B5 control surfaces.** Adaptive optimizer state
|
||||
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.
|
||||
7. **Empirical validation.** This bound has not been validated
|
||||
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
|
||||
|
|
@ -557,31 +588,52 @@ the bound without invalidating it.
|
|||
#000034's Phase 1b would feed directly into a future
|
||||
empirical-validation ticket.
|
||||
|
||||
### §10.1 Calculator hardening landed 2026-05-11 (dav1d review)
|
||||
### §10.1 dav1d-review changes landed 2026-05-11
|
||||
|
||||
Not "open" — already done in the `8916bf3` follow-up + the
|
||||
2026-05-11 review pass:
|
||||
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** (`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).
|
||||
`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`, `certification_status`
|
||||
∈ {`CERTIFIED_BY_BOUND`, `NOT_CERTIFIED_BY_BOUND`},
|
||||
`certification_threshold_bits`, `model_assumptions[]` — so
|
||||
callers read a machine-readable status, not just prose.
|
||||
- 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.
|
||||
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.
|
||||
Suite count 53 → 75.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -592,22 +644,24 @@ The closed-form bound from §6 lands as
|
|||
|
||||
```bash
|
||||
$ 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
|
||||
--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": "effective_control_v1",
|
||||
"I_window_bits_upper_bound": 625.8716,
|
||||
"B1_contribution": 292.4813,
|
||||
"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},
|
||||
|
|
@ -616,11 +670,11 @@ $ python -m bench.scripts.t3_bound_calculator \
|
|||
"model_assumptions": [
|
||||
"M2_nonce_per_window",
|
||||
"SHA256_random_oracle_baseline",
|
||||
"B1_effective_control_model_v1",
|
||||
"B1_model_max_envelope",
|
||||
"B3_gradient_noise_refinement"
|
||||
],
|
||||
"inputs": { "...echoed input tuple..." },
|
||||
"recommendation": "I_window upper bound ≈ 625.9 bits/window
|
||||
"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
|
||||
|
|
@ -632,14 +686,16 @@ $ python -m bench.scripts.t3_bound_calculator \
|
|||
}
|
||||
```
|
||||
|
||||
The above example shows a deployment whose per-window bound
|
||||
exceeds 256 bits **under the `effective_control_v1` B1 model** —
|
||||
`certification_status` is `NOT_CERTIFIED_BY_BOUND` and the W of
|
||||
10000 is too large for a 1-window SHA-256-resistance certification.
|
||||
A conservative `max_envelope` B1 model (§3.1) would produce a
|
||||
larger bound (~5850 bits in the worked example). Operators read
|
||||
the structured `certification_status` field, not just the prose,
|
||||
and adjust W (or g, R, K) to tune.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -660,5 +716,6 @@ and adjust W (or g, R, K) to tune.
|
|||
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 v2 conservative-
|
||||
envelope path (§10 item 1).
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Ticket #000036 — T3 per-window covert-channel budget bound
|
||||
|
||||
**Status:** in progress · Phase 1 (formal derivation + calculator) landed 2026-05-10; **dav1d review returned 2026-05-11** (`RESPONSE_1` + `RESPONSE_2`); **Tier-1 polish applied 2026-05-11** (recommendation wording → "CANNOT CERTIFY", structured `certification_status` / `b1_model` / `model_assumptions` output fields, bool/NaN/inf validation hardening, `g=0` accepted, hard-coded test cwd removed; test suite 53 → 75); **closure blockers remaining**: (1) B1 conservative-envelope = v2 calculator (`b1_model=max_envelope`, `CALCULATOR_VERSION → t3-bound-v2-conservative-envelope`, versioned KAT fixture) — awaits fox go/no-go on Tier 2; (2) active KAT fixture (`bench/fixtures/t3-bound/known-answer-tests.jsonl` must exist + test must run not skip, ≥ 5 entries). Empirical constant-tightening tracked separately under #000043. R2's architectural integrations (Merkle audit-event commitment, SQD canonicalization, CTI clause-lattice, 5F trigger, ForkScore security-risk) are out-of-scope here — separate tickets if wanted.
|
||||
**Status:** in progress · Phase 1 (formal derivation + calculator) landed 2026-05-10; **dav1d review returned 2026-05-11** (`RESPONSE_1` + `RESPONSE_2`) → **Tier-1 + Tier-2 both applied 2026-05-11**. Tier-1: recommendation wording → "CANNOT CERTIFY", structured `certification_status` / `b1_model` / `b1_selected` / `model_assumptions` output fields, bool/NaN/inf validation hardening, `g=0` accepted, hard-coded test cwd removed. **Tier-2 = dav1d Option B applied *in v1* (per fox — no v2 fork)**: default `b1_model` is now `max_envelope` = `max(fraction_channels, aggregate_bias)` (genuinely upper-bounding across both interpretations of `g`); `effective_control_v1` / `fraction_channels` / `aggregate_bias` reachable via `--b1-model`; every output reports all three B1 variants + both SNR readings; `CALCULATOR_VERSION` unchanged (`t3-bound-v1-bottou-refinement` — the descriptor names the unchanged B3 term, and `b1_model` echoed in `inputs` disambiguates KAT replays). **KAT fixture regenerated 2026-05-11** (12 entries; `test_t3_bound_known_answer_tests` now runs, not skips). Baseline I_window: 625.87 (effective_control_v1) → **6183.02 (max_envelope default)**. Test suite 53 → 83. **Both prior closure blockers cleared**; remaining = fox's final close-or-iterate call (optionally a dav1d re-review of the envelope formula). Empirical constant-tightening tracked separately under #000043. R2's architectural integrations (Merkle audit-event commitment, SQD canonicalization, CTI clause-lattice, 5F trigger, ForkScore security-risk) out-of-scope here — separate tickets if wanted.
|
||||
**Opened:** 2026-05-09
|
||||
**Scope:** Derive an explicit closed-form upper bound on the covert-
|
||||
channel capacity under threat model T3 (hyperparameter adversary),
|
||||
|
|
|
|||
|
|
@ -600,7 +600,7 @@ than waiting for bench-time STRICT-rate drift to surface it.
|
|||
W concentration + dim_h, closure (a_top + a_bot ≡
|
||||
full-spectrum on dense decomposition), Lanczos eigenvalue
|
||||
ordering invariant.
|
||||
- `tests/test_t3_bound_calculator.py` — **<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->75<!--/AUTOCOUNT--> tests** (was 51;
|
||||
- `tests/test_t3_bound_calculator.py` — **<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->83<!--/AUTOCOUNT--> tests** (was 51;
|
||||
+2 from `581ad90` 2026-05-10 KAT-fixture-gap closure) for the
|
||||
T3 per-window covert-channel bound calculator (#000036 §11);
|
||||
pins the closed-form B1/B2/B3 formulas, monotonicity in each
|
||||
|
|
@ -674,7 +674,7 @@ than waiting for bench-time STRICT-rate drift to surface it.
|
|||
| aliases.py | 512 | 469 (<!--AUTOCOUNT:tests:tests/test_aliases.py-->28<!--/AUTOCOUNT--> tests) | 0.92 |
|
||||
| warrant_resolver.py | ~800 | ~430 (combined) | 0.54 |
|
||||
| warrant_chain.py | 89 | 320 (<!--AUTOCOUNT:tests:tests/test_warrant_chain.py-->9<!--/AUTOCOUNT--> tests) | 3.6 |
|
||||
| t3_bound_calculator.py | 249 | 446 (<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->75<!--/AUTOCOUNT--> tests) | 1.79 |
|
||||
| t3_bound_calculator.py | 249 | 446 (<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->83<!--/AUTOCOUNT--> tests) | 1.79 |
|
||||
| fork_score.py | 386 | 609 (<!--AUTOCOUNT:tests:tests/test_fork_score.py-->23<!--/AUTOCOUNT--> tests) | 1.58 |
|
||||
| weights.py | 73 | 180 (<!--AUTOCOUNT:tests:tests/test_weights.py-->16<!--/AUTOCOUNT--> tests) | 2.5 |
|
||||
| pi_star/protocol+registry | 124 | 280 (<!--AUTOCOUNT:tests:tests/test_pi_star_protocol_and_registry.py-->21<!--/AUTOCOUNT--> tests) | 2.3 |
|
||||
|
|
|
|||
|
|
@ -51,32 +51,45 @@ _BASELINE = dict(
|
|||
|
||||
|
||||
def test_baseline_matches_section_11_doc():
|
||||
"""The §11 worked example baseline. Calculator's actual numbers:
|
||||
"""The §11 worked example baseline under the default b1_model=
|
||||
"max_envelope" (dav1d review 2026-05-11). Calculator's actual numbers:
|
||||
|
||||
I_window_bits_upper_bound: 625.8716
|
||||
B1_contribution: 292.4813
|
||||
B2_contribution: 300.0
|
||||
B3_contribution: 33.3904
|
||||
snr_grad: 0.5
|
||||
I_window_bits_upper_bound: 6183.0154
|
||||
B1_contribution: 5849.625 (aggregate_bias selected)
|
||||
B1_fraction_channels: 1729.7158
|
||||
B1_aggregate_bias: 5849.625
|
||||
B1_effective_control_v1: 292.4813 (the older non-worst-case)
|
||||
B2_contribution: 300.0
|
||||
B3_contribution: 33.3904
|
||||
snr_grad: 0.5 (g·G/σ)
|
||||
snr_per_channel: 10.0 (G/σ)
|
||||
|
||||
Doc §11's quoted 622.7 / 290.0 / 32.7 are first-cut rounded
|
||||
estimates; calculator's actual closed-form values differ by
|
||||
~3 bits total due to the doc's 290 vs actual 292.5 in B1 and
|
||||
32.7 vs actual 33.4 in B3. This test pins the closed-form
|
||||
truth (the doc text needs a calibration pass; tracked in this
|
||||
test's docstring as a follow-up).
|
||||
The conservative envelope takes max(fraction_channels, aggregate_bias);
|
||||
at this baseline aggregate_bias (5849.6) dominates fraction_channels
|
||||
(1729.7). The old effective_control formula (292.5) is still reported
|
||||
as B1_effective_control_v1 for comparison.
|
||||
"""
|
||||
r = t3_bound_bits(**_BASELINE)
|
||||
# Total: ⟨B1+B2+B3⟩ ≈ 292.48 + 300.0 + 33.39 = 625.87
|
||||
assert r["I_window_bits_upper_bound"] == pytest.approx(625.87, abs=0.05)
|
||||
assert r["b1_model"] == "max_envelope"
|
||||
assert r["b1_selected"] == "aggregate_bias"
|
||||
# Total: ⟨B1+B2+B3⟩ ≈ 5849.63 + 300.0 + 33.39 = 6183.02
|
||||
assert r["I_window_bits_upper_bound"] == pytest.approx(6183.02, abs=0.05)
|
||||
# B2 is exact: ⌈10000/100⌉ · log₂(8) = 100 · 3 = 300
|
||||
assert r["B2_contribution"] == pytest.approx(300.0, abs=1e-3)
|
||||
# B3: epochs = ⌈10000/1024⌉ = 10; per-epoch factor = 1024·0.1/1.0 = 102.4;
|
||||
# log₂(102.4)/2 ≈ 3.339; total ≈ 33.39 bits.
|
||||
assert r["B3_contribution"] == pytest.approx(33.39, abs=0.05)
|
||||
# B1: C_B1 · g · W · log₂(SNR+1) where SNR = 0.05·1.0/0.1 = 0.5
|
||||
# → log₂(1.5) ≈ 0.585; total ≈ 1.0 · 0.05 · 10000 · 0.585 = 292.48
|
||||
assert r["B1_contribution"] == pytest.approx(292.48, abs=0.05)
|
||||
# B1 (max_envelope): aggregate_bias = W·log₂(1 + g·G/σ) = 10000·log₂(1.5)
|
||||
# ≈ 10000·0.585 = 5849.63 (> fraction_channels 1729.72).
|
||||
assert r["B1_contribution"] == pytest.approx(5849.63, abs=0.05)
|
||||
assert r["B1_aggregate_bias"] == pytest.approx(5849.63, abs=0.05)
|
||||
# fraction_channels = g·W·log₂(1 + G/σ) = 0.05·10000·log₂(11) ≈ 1729.72
|
||||
assert r["B1_fraction_channels"] == pytest.approx(1729.72, abs=0.05)
|
||||
# effective_control_v1 (old formula) still reported: g·W·log₂(1+g·G/σ)
|
||||
# = 0.05·10000·log₂(1.5) ≈ 292.48
|
||||
assert r["B1_effective_control_v1"] == pytest.approx(292.48, abs=0.05)
|
||||
assert r["snr_grad"] == pytest.approx(0.5, abs=1e-6) # g·G/σ
|
||||
assert r["snr_per_channel"] == pytest.approx(10.0, abs=1e-6) # G/σ
|
||||
|
||||
|
||||
def test_returns_calculator_version_token():
|
||||
|
|
@ -289,15 +302,17 @@ def test_recommendation_total_le_zero():
|
|||
|
||||
|
||||
def test_recommendation_below_sha256():
|
||||
"""Baseline (~622 bits) actually exceeds 256 — wrong band for
|
||||
this test. Use a config that lands in the (0, 256) range."""
|
||||
args = {**_BASELINE, "window_length": 1000}
|
||||
"""The default-baseline bound exceeds 256 under max_envelope; use a
|
||||
small W that lands in the (0, 256) certified band. At W=300:
|
||||
aggregate_bias ≈ 175.5, B2 = 9, B3 ≈ 3.3 → total ≈ 187.8."""
|
||||
args = {**_BASELINE, "window_length": 300}
|
||||
r = t3_bound_bits(**args)
|
||||
assert 0 < r["I_window_bits_upper_bound"] < 256, (
|
||||
f"window_length=1000 should land in (0, 256); got {r['I_window_bits_upper_bound']}"
|
||||
f"window_length=300 should land in (0, 256); got {r['I_window_bits_upper_bound']}"
|
||||
)
|
||||
assert "windows" in r["recommendation"]
|
||||
assert "256" in r["recommendation"]
|
||||
assert r["certification_status"] == "CERTIFIED_BY_BOUND"
|
||||
|
||||
|
||||
def test_recommendation_exceeds_sha256():
|
||||
|
|
@ -315,22 +330,29 @@ def test_recommendation_exceeds_sha256():
|
|||
|
||||
|
||||
def test_output_carries_b1_model_and_certification_fields():
|
||||
"""Structured machine-readable fields added per dav1d review
|
||||
2026-05-11: b1_model, certification_status,
|
||||
certification_threshold_bits, model_assumptions."""
|
||||
"""Structured machine-readable fields (dav1d review 2026-05-11):
|
||||
b1_model, b1_selected, certification_status,
|
||||
certification_threshold_bits, model_assumptions, plus all three
|
||||
B1 model variants + both SNR readings."""
|
||||
r = t3_bound_bits(**_BASELINE)
|
||||
assert r["b1_model"] == "effective_control_v1"
|
||||
assert r["b1_model"] == "max_envelope" # the new default
|
||||
assert r["b1_selected"] in {"fraction_channels", "aggregate_bias"}
|
||||
assert r["certification_threshold_bits"] == 256
|
||||
assert r["certification_status"] in {
|
||||
"CERTIFIED_BY_BOUND", "NOT_CERTIFIED_BY_BOUND"
|
||||
}
|
||||
assert "B1_effective_control_model_v1" in r["model_assumptions"]
|
||||
assert "B1_model_max_envelope" in r["model_assumptions"]
|
||||
# all three B1 variants reported regardless of which is selected
|
||||
for k in ("B1_fraction_channels", "B1_aggregate_bias",
|
||||
"B1_effective_control_v1", "snr_per_channel"):
|
||||
assert k in r, f"missing output field {k!r}"
|
||||
assert r["certification_status"] == "NOT_CERTIFIED_BY_BOUND" # baseline > 256
|
||||
|
||||
|
||||
def test_certification_status_certified_below_threshold():
|
||||
"""A config landing in (0, 256) → CERTIFIED_BY_BOUND."""
|
||||
r = t3_bound_bits(**{**_BASELINE, "window_length": 1000})
|
||||
"""A config landing in (0, 256) → CERTIFIED_BY_BOUND. W=300 under
|
||||
max_envelope yields ~188 bits."""
|
||||
r = t3_bound_bits(**{**_BASELINE, "window_length": 300})
|
||||
assert 0 < r["I_window_bits_upper_bound"] < 256
|
||||
assert r["certification_status"] == "CERTIFIED_BY_BOUND"
|
||||
|
||||
|
|
@ -357,8 +379,34 @@ def test_cli_baseline_runs_clean(tmp_path):
|
|||
cwd=REPO_ROOT)
|
||||
j = json.loads(out.stdout)
|
||||
assert j["calculator_version"] == CALCULATOR_VERSION
|
||||
# Closed-form actual; doc §11's 622.7 is approximate.
|
||||
assert j["I_window_bits_upper_bound"] == pytest.approx(625.87, abs=0.05)
|
||||
assert j["b1_model"] == "max_envelope" # CLI default
|
||||
# Closed-form actual under max_envelope: 5849.63 + 300.0 + 33.39 = 6183.02
|
||||
assert j["I_window_bits_upper_bound"] == pytest.approx(6183.02, abs=0.05)
|
||||
|
||||
|
||||
def test_cli_b1_model_flag():
|
||||
"""--b1-model effective_control_v1 reverts to the older formula;
|
||||
--b1-model fraction_channels picks that envelope term."""
|
||||
base_cmd = [
|
||||
sys.executable, "-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",
|
||||
]
|
||||
for model, expected_b1 in [
|
||||
("effective_control_v1", 292.48),
|
||||
("fraction_channels", 1729.72),
|
||||
("aggregate_bias", 5849.63),
|
||||
]:
|
||||
out = subprocess.run(base_cmd + ["--b1-model", model],
|
||||
capture_output=True, text=True, check=True,
|
||||
cwd=REPO_ROOT)
|
||||
j = json.loads(out.stdout)
|
||||
assert j["b1_model"] == model
|
||||
assert j["B1_contribution"] == pytest.approx(expected_b1, abs=0.05), (
|
||||
f"b1_model={model}: B1={j['B1_contribution']} vs expected {expected_b1}"
|
||||
)
|
||||
|
||||
|
||||
def test_cli_invalid_input_exits_2():
|
||||
|
|
@ -404,24 +452,59 @@ def test_b2_exact_formula():
|
|||
)
|
||||
|
||||
|
||||
def test_b1_exact_formula():
|
||||
"""B1 = C_B1 · g · W · log₂(SNR + 1) where SNR = g·‖∇L_max‖/σ_grad.
|
||||
def test_b1_effective_control_v1_exact_formula():
|
||||
"""b1_model="effective_control_v1": B1 = C_B1 · g · W · log₂(SNR+1)
|
||||
where SNR = g·‖∇L_max‖/σ_grad (the older non-worst-case formula).
|
||||
Hand-compute for one config and check exact agreement."""
|
||||
g, gnm, sigma, W = 0.1, 2.0, 0.5, 5000
|
||||
snr = g * gnm / sigma # 0.4
|
||||
expected = 1.0 * g * W * math.log2(snr + 1)
|
||||
r = t3_bound_bits(**{
|
||||
**_BASELINE,
|
||||
"gradient_fraction": g,
|
||||
"gradient_norm_max": gnm,
|
||||
"gradient_noise_stddev": sigma,
|
||||
"window_length": W,
|
||||
"gradient_fraction": g, "gradient_norm_max": gnm,
|
||||
"gradient_noise_stddev": sigma, "window_length": W,
|
||||
"b1_model": "effective_control_v1",
|
||||
})
|
||||
# Output rounded to 4 dp inside the calculator.
|
||||
assert r["b1_model"] == "effective_control_v1"
|
||||
assert r["b1_selected"] == "effective_control_v1"
|
||||
assert r["B1_contribution"] == pytest.approx(expected, abs=1e-3)
|
||||
assert r["B1_effective_control_v1"] == pytest.approx(expected, abs=1e-3)
|
||||
assert r["snr_grad"] == pytest.approx(snr, abs=1e-3)
|
||||
|
||||
|
||||
def test_b1_max_envelope_exact_formula():
|
||||
"""b1_model="max_envelope" (default): B1 = max(fraction_channels,
|
||||
aggregate_bias) where
|
||||
fraction_channels = C_B1 · g · W · log₂(1 + G/σ)
|
||||
aggregate_bias = C_B1 · W · log₂(1 + g·G/σ)
|
||||
Hand-compute for one config; verify the larger term is selected."""
|
||||
g, gnm, sigma, W = 0.1, 2.0, 0.5, 5000
|
||||
snr_per_channel = gnm / sigma # 4.0
|
||||
snr_grad = g * gnm / sigma # 0.4
|
||||
fc = 1.0 * g * W * math.log2(snr_per_channel + 1) # 0.1·5000·log₂(5) ≈ 1160.96
|
||||
ab = 1.0 * W * math.log2(snr_grad + 1) # 5000·log₂(1.4) ≈ 2426.26
|
||||
expected_b1 = max(fc, ab)
|
||||
expected_selected = "aggregate_bias" if ab >= fc else "fraction_channels"
|
||||
r = t3_bound_bits(**{
|
||||
**_BASELINE,
|
||||
"gradient_fraction": g, "gradient_norm_max": gnm,
|
||||
"gradient_noise_stddev": sigma, "window_length": W,
|
||||
# b1_model defaults to max_envelope
|
||||
})
|
||||
assert r["b1_model"] == "max_envelope"
|
||||
assert r["b1_selected"] == expected_selected
|
||||
assert r["B1_contribution"] == pytest.approx(expected_b1, abs=1e-3)
|
||||
assert r["B1_fraction_channels"] == pytest.approx(fc, abs=1e-3)
|
||||
assert r["B1_aggregate_bias"] == pytest.approx(ab, abs=1e-3)
|
||||
assert r["snr_per_channel"] == pytest.approx(snr_per_channel, abs=1e-3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("bad", ["v2", "envelope", "", "MAX_ENVELOPE", None, 1])
|
||||
def test_invalid_b1_model_rejected(bad):
|
||||
with pytest.raises(ValueError, match="b1_model"):
|
||||
t3_bound_bits(**{**_BASELINE, "b1_model": bad})
|
||||
|
||||
|
||||
# --- integration with §6 framework -----------------------------------
|
||||
|
||||
|
||||
|
|
@ -504,6 +587,21 @@ def test_t3_bound_known_answer_tests():
|
|||
Closes the calculator-test-patterns.md §1 checklist gap (no
|
||||
KAT fixture for this calculator).
|
||||
"""
|
||||
# Numeric fields checked on every KAT entry.
|
||||
_NUMERIC = [
|
||||
("expected_total", "I_window_bits_upper_bound"),
|
||||
("expected_b1", "B1_contribution"),
|
||||
("expected_b2", "B2_contribution"),
|
||||
("expected_b3", "B3_contribution"),
|
||||
("expected_snr_grad", "snr_grad"),
|
||||
]
|
||||
# Optional numeric fields (present in 2026-05-11+ fixtures).
|
||||
_NUMERIC_OPT = [
|
||||
("expected_b1_fraction_channels", "B1_fraction_channels"),
|
||||
("expected_b1_aggregate_bias", "B1_aggregate_bias"),
|
||||
("expected_b1_effective_control_v1", "B1_effective_control_v1"),
|
||||
("expected_snr_per_channel", "snr_per_channel"),
|
||||
]
|
||||
n_kats = 0
|
||||
for line in KAT_FIXTURE.read_text(encoding="utf-8").splitlines():
|
||||
line = line.strip()
|
||||
|
|
@ -517,13 +615,27 @@ def test_t3_bound_known_answer_tests():
|
|||
f"recorded {kat['calculator_version']}, "
|
||||
f"function {r['calculator_version']}"
|
||||
)
|
||||
for field, key in [
|
||||
("expected_total", "I_window_bits_upper_bound"),
|
||||
("expected_b1", "B1_contribution"),
|
||||
("expected_b2", "B2_contribution"),
|
||||
("expected_b3", "B3_contribution"),
|
||||
("expected_snr_grad", "snr_grad"),
|
||||
]:
|
||||
# b1_model + b1_selected pinned when recorded.
|
||||
if "b1_model" in kat:
|
||||
assert r["b1_model"] == kat["b1_model"], (
|
||||
f"KAT b1_model mismatch on {kat['label']!r}: "
|
||||
f"recorded {kat['b1_model']}, function {r['b1_model']}"
|
||||
)
|
||||
if "expected_b1_selected" in kat:
|
||||
assert r["b1_selected"] == kat["expected_b1_selected"], (
|
||||
f"KAT b1_selected mismatch on {kat['label']!r}: "
|
||||
f"recorded {kat['expected_b1_selected']}, "
|
||||
f"function {r['b1_selected']}"
|
||||
)
|
||||
if "expected_certification_status" in kat:
|
||||
assert r["certification_status"] == kat["expected_certification_status"], (
|
||||
f"KAT certification_status mismatch on {kat['label']!r}: "
|
||||
f"recorded {kat['expected_certification_status']}, "
|
||||
f"function {r['certification_status']}"
|
||||
)
|
||||
for field, key in _NUMERIC + _NUMERIC_OPT:
|
||||
if field not in kat:
|
||||
continue
|
||||
recorded = float(kat[field])
|
||||
observed = float(r[key])
|
||||
assert observed == pytest.approx(recorded, abs=1e-3), (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue