Wire the RQ3 churn-resilience companion (severable follow-on; RQ3 frozen in its
own prereg) as SYNTHETIC/OFFLINE build + calibration only — no confirmatory
battery run.
- battery: enumerate_rq3_cells()/rq3_schedule() add selector in {static(control),
random, agent} at 1house/bridge-off under pinned churn kp=30/steps=20, kept
SEPARATE so the frozen 6-cell lead lattice stays byte-identical.
- executor: run_rq3_cell_run collects offline selector DVs (throughput-retention,
drops/rebuilds, rebuild-interval gaps); added-latency is live-only (offline path
records None, never fabricated); run_rq3_battery(live=False) hard-raises.
- analysis/rq3_calibration: DRY offline gate. Churn-bites (1589 drops/1576
rebuilds) + rebuild-classifier calibration green with real teeth — churned(kp30)
vs baseline(kp5) AUC 0.926 separable, baseline-vs-baseline null 0.518 blind.
Classifier scored on the PER-RUN mean inter-rebuild gap (the confirmatory
grouping unit); the frozen instrument (rebuild_interval_gaps,
rebuild_classifier_auc) is untouched, no fit to confirmatory data.
HARD HOLD: no RQ3 confirmatory battery (live added-latency is operator+grid-gated).
Lead prereg SHA f22331a72e… untouched; containment intact (synthetic/offline, $0
local Ollama, frontier arm inert); worktree-only.
Tests: tests/test_sor_rq3_wiring.py 9 passed; full SOR suite 194 passed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Operator ruling (Andre, 2026-07-21): the STOP was correct and the diagnosis
right — §7 items 1-2 did not fail because the instrument is broken, but because
they were worded under the naive-funnel prior. Under the ratified posterior the
pool is a MIX (shared bridge → shared exit_signature → larger anonymity set →
higher H). Corrected pre-freeze, logged transparently (no HARKing).
- rq2p3-mechanism-prereg.md §7: item 1 re-anchored on the FROZEN bridge-federated
branch (injective fresh-bridge → m_i=1 → H≈0, constant c=1/C — a pool draws with
replacement so it cannot reproduce the zero-variance degeneracy); item 2 B=1 →
c=1.0 AND high H (maximal mix, "low H" refuted by construction); added a §7 scope
note (the gate validates the INSTRUMENT and must NOT pre-assert the H-vs-c sign —
that stays the two-sided confirmatory question H1/H2). Confirmatory hypotheses
unchanged.
- docs/stage-05-rq2p3-gate-clarification.md: dated deviation-rationale log (cites
the dry-pass output, no number invented; records the two-sided direction-agnostic
pre-commitment is untouched; the mix ρ 0→+0.838 is an exploratory finding that
strengthens note-unique-bridge-artifact.md).
- rq2p3_calibration.py: item-1 teeth moved to frozen_branch_regression() on the
untouched bridge-federated branch; item-2 now asserts c=1.0 AND high H; added
all_pass aggregate. confirm.py/stats.py/confirm_load_rq2.py untouched.
Re-run: all four gate items PASS with real teeth (all_pass=True). Synthetic/DRY
only, no confirmatory record read. FREEZE STAYS A HUMAN GATE: §10 empty, no
confirmatory RQ2-P3 cell until operator records the SHA-256 + signs off. Lead
prereg SHA f22331a72e... untouched; worktree-only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build the funnelling-mechanism instrument for the RQ2-P3 follow-up: a new
`bridge-federated-pool` topology drawing each circuit's bridge from a finite
willing-bridge pool (size B) under Zipf willingness skew (alpha), so bridge
concentration genuinely varies as a manipulated IV. Defensive measurement only:
synthetic seeds, no engine, no traffic, no confirmatory record read.
- assembler.py: add `bridge-federated-pool` branch + zipf_weights/weighted_draw
helpers; existing lead `bridge-federated` branch left untouched and
bit-reproducible (fresh bridge per seed).
- battery.py: enumerate_rq2p3_cells() = B{2,4,8} x alpha{0,1,2} + anchor B=50,
alpha=0 (separate fn; frozen 6-cell lead lattice unmutated).
- analysis/rq2p3_calibration.py: DRY synthetic-only §7 calibration gate; no
confirmatory data read. confirm_load_rq2.py/confirm.py/stats.py unchanged.
- tests/test_sor_rq2p3_pool.py: 9 synthetic tests (helpers + pool reuse/variance
+ lead branch reproducibility).
Calibration gate RAN: items 3 (monotonicity) & 4 (entropy) PASS; items 1 & 2 do
NOT match their naive-funnel wording because the ratified posterior yields a MIX
(rho>0 across the whole sweep incl anchor rho=+0.838; B=1 -> H=2.54 bits HIGH) --
the note-unique-bridge-artifact.md prediction, surfaced early. HARD HOLD: no
confirmatory battery, no prereg freeze; NEEDS-OPERATOR banner raised for the §7
item-1/2 re-word decision. Lead prereg SHA f22331a72e... untouched; worktree-only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
One auditable, deterministic run of the four lead-paper §6 tests on the
frozen raw battery. Calibration gate PASS (linked AUC 1.0000, unlinked
0.5036 on §5 fixtures) → AUCs reportable.
- RQ1-P1 (bridge leak): AUC 0.4660 CI[0.4523,0.4798] = anomaly-below-chance.
NO measurable leak; Holm-sig but in the WRONG direction (not evidence of
linkability).
- RQ2-P1 (federation): ΔH −0.9587 bits CI[−1.056,−0.864] = SHRINK. Holm-sig
HONEST-NEGATIVE — federation reduces the anonymity set (opposite of RQ2's
motivation); reported with equal prominence per §6 two-sided framing.
- RQ1-P2 (padding): ΔAUC +0.0113 CI[−0.0025,+0.0234] padding-ineffective
(raw p 0.091, Holm adj-p 0.456, not rejected).
- RQ2-P3 (funnelling): Spearman ρ=0, zero-variance concentration =
as-instrumented degeneracy flagged in advance; inconclusive.
Holm family=7 report-4 (multipliers 7,6,5,4); only RQ1-P1 + RQ2-P1 survive.
Ran ONLY the pre-registered tests — no re-slicing, no post-hoc subgroups.
Method faithfulness: RQ1-P1/P2 CIs use a bit-faithful fast numpy bootstrap
(frozen O(n²)-per-fold jackknife intractable at n=75000); stage06_run.py
--verify proves both == frozen stats.bootstrap_ci bit-for-bit (point/lo/hi/
method within 1e-12, incl the average-rank tie path). RQ2-P1/P3 stay on the
frozen confirm.* paths (tractable). Frozen prereg SHA INTACT.
Artifacts: docs/stage-06-analysis.md (methods-faithful narrative, Holm table,
CONFIRMATORY/EXPLORATORY labels, nulls reported honestly) + force-added
output/…/analysis/stage06-results.json (regenerable via stage06_run).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pairing ruling (docs/stage-05-rq1p2-pairing-clarification.md, RATIFIED-by-
derivation, made while BLIND): the frozen §6 L197-198 "paired" bootstrap pairs
the bridge-on (no-pad) and bridge-on+padding arms BY RUN INDEX — the only
balanced pairing the R=30 (§4 L111) interleaved (§3 L97) design supports; the
§4 L108 RQ1 unit is AUC over the (entry,exit) pair set, so the pairable unit is
the run, not the circuit. Prereg SHA untouched (f22331a72e…).
confirm_load.collect_rq1_p2_paired feeds one confirm.PairedCircuit per shared
run_index into the FROZEN confirm.rq1_p2_padding (§6 arm-level ΔAUC preserved);
per_run_delta_aucs exposes the auditable per-run ΔAUC_i; missing-arm indices are
unpaired (frozen R not redefined). Unit-tested on SYNTHETIC pcaps only
(prereg §2 blinding — unblocks CODE not RESULTS); full SOR suite 176 passed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flip docs/stage-05-rq2-posterior-clarification.md PROPOSED->RATIFIED (operator
Andre, 2026-07-20, ratified while BLIND to RQ2 data — honest prereg-completion of
a gap the freeze left, not HARKing). Substance of the construction unchanged.
Add cmd_chat/sor/analysis/confirm_load_rq2.py: reconstructs each circuit's spec
OFFLINE from the persisted per_circuit_seeds via deterministic assemble(), derives
the observation-consistent anonymity set A_i (uniform / max-entropy -> [1]*m_i),
per-circuit Miller-Madow H_i, and the willing-bridge concentration series — the
exact inputs confirm.rq2_p1_delta_h (ΔH, two-sided) and rq2_p3_funnel (Spearman ρ)
consume. Grounded only in the ratified rule ([Serjantov2002]/[Diaz2002]).
BLINDING preserved (prereg §2): ratification unblocks CODE, not results. The
collect_* real-data entrypoints are BLIND-GATED and NOT run; the reconstruction is
unit-tested on SYNTHETIC specs/seeds only (test_sor_confirm_load_rq2.py, 6 passed;
full SOR suite 172 passed). Frozen prereg untouched; no RQ2 statistic computed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
confirm_load.py reconstructs the RQ1 (entry,exit) circuit-pair set from
the REAL per-hop pcaps (bin_pcap_bytes -> score_matrix; diagonal=linked,
off-diagonal=unlinked) so confirm.rq1_p1_leak scores measured data — the
frozen §4 unit. classify_run reads persisted metrics.json;
collect_rq1_p1_pairs selects only bridge=on no-pad runs.
Plumbing unit-tested on SYNTHETIC pcaps only (prereg §2 blinding — no
inspecting intermediate confirmatory results before the battery
completes). RQ1-P2 nopad/pad pairing + all RQ2 held for the operator
ruling (NEEDS-OPERATOR: RQ2 per-circuit posterior underspecified).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Encodes the four lead-paper confirmatory tests exactly per the frozen prereg §6,
calibrated on synthetic ground truth only (never re-fit to cell data):
- RQ1-P1 leak: correlation AUC + BCa CI; gate = CI excludes 0.5 (D2); 0.60 CI
lower bound = separate materiality label (material / weak-but-real), not the gate.
- RQ1-P2 padding: paired ΔAUC = AUC(no-pad) − AUC(pad) over circuits; effective
iff CI > 0.
- RQ2-P1 anonymity set: ΔH = H(federated) − H(single, matched N) with Miller-Madow
per-circuit entropy; two-sided grow / honest-shrink / inconclusive by CI sign.
- RQ2-P3 mechanism: Spearman ρ(top-3 bridge concentration, per-circuit H) + CI.
apply_holm corrects the reported RQ1/RQ2 subset against the full frozen family of
7 (family_size default 7) — never re-optimised to the 4 reported. Bootstrap
p-values order the Holm step-down only; every decision is a CI gate, never a bare p.
stats.py: bootstrap CIs can now return their resample distribution so the Holm
ordering p-value comes from the same resamples as the CI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Turnkey implementation of the frozen prereg §6 analysis plan, written before any
confirmatory data exists (analysis-precedes-data, rigor-standards §Statistics).
Pure stdlib, no I/O, no engine, no traffic — calibrated on synthetic ground truth only:
- bootstrap_ci / two_sample_diff_ci: BCa 95% CIs (10k resamples default) with a
percentile fallback when bias/acceleration terms are degenerate; seeded and
reproducible (CIResult carries method+seed for the §6 three-seed spot-check).
- miller_madow_entropy_bits: plug-in Shannon entropy + Miller-Madow bias
correction (§3 estimator).
- spearman: rank correlation for RQ2-P3.
- holm_bonferroni: step-down multiplicity correction with explicit family_size so
a lead paper reporting a subset of the frozen 7-test family still corrects
against the full family (never re-optimised to the reported subset).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
churn.py emits a seed-deterministic kill/spawn schedule (pure data — no real VM
spin/kill; the live fabric half stays gated by the containment law). selector.py
consumes the schedule and rebuilds a circuit whenever a kill drops one of its
hops, across static | random | agent strategies; the paid frontier-model agent
arm (GOAL envelope (c)) is human-gated and NOT wired — the agent strategy here is
a local stability heuristic that spends nothing. analysis/metrics.py aggregates
the four DV families (RQ1 correlation AUC, RQ2 entropy bits, RQ3 throughput
retention + rebuild-classifier AUC) into a schema-valid, write-once metrics.json.
Acceptance check green: under a fixed churn seed the selector rebuilds every
dropped circuit (every_drop_rebuilt, all strategies) and metrics.json is
produced. Python R7 selector suite 11 passed; full SOR suite 92 passed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Land only the offline-validatable half of R7 (instrument-validation gate items
3 and 4): the detectors the gate calibrates on synthetic fixtures, never on
confirmatory-cell data. Pure stdlib functions over in-memory series — no pcaps,
no engine, no traffic, no VM fabric.
- analysis/detectors.py: shannon_entropy_bits (RQ2 anonymity-set entropy),
pearson/score_matrix/auc/linkage_auc, bridge_correlation_auc (RQ1
linkability scorer), and synthetic_bridge_fixture (seed-deterministic
known-linked / known-unlinked ground truth via the R1 SorRng).
Calibration green: entropy returns exactly log2(N) for N equiprobable senders
(gate item 4); a known-linked control pair scores AUC=1.0 and the unlinked
estimator is unbiased at chance (ensemble mean over 40 seeds = 0.498 ~ 0.5,
gate item 3). Detectors are calibrated on synthetic fixtures only — no fitting.
The traffic-moving R7 pieces (churn.py VM spin/kill, live selector rebuild loop,
metrics.json emission) are HELD for R4/R6 + a live grid and are absent here.
Python SOR suite 66 passed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>