# Reproducing the `sor-consent` study A step-by-step checklist for reproducing the linkability / anonymity-set / churn-resilience measurements reported in `docs/stage-07-paper-draft.md` and `docs/stage-07-companion-methods.md`. This instrument is built for **defensive measurement** of a trust model's exposure. It moves only **self-generated fixture traffic** on **our own lab grid**, and every forwarder runs **inside an isolated engine** (docker / multipass) — never on the host (`assert engine != local` or the code refuses). Reproduce it in the same spirit: no external targets, no third-party traffic. **Self-contained.** Everything needed to reproduce is committed in this repo — no `sci-method` checkout is required. The reproduction deposits are: | Deposit | Path | Purpose | |---|---|---| | Frozen pre-registration | `docs/prereg/sor-consent-prereg.md` (+ `.sha256`) | the hashed, frozen design; the launcher SHA-checks it | | Bibliography | `docs/sor-consent-bibliography.md` | full 36-source reference list for the paper | | Analysis + instrument | `cmd_chat/sor/` | every DV measure and analysis pass lives here | | Analysis results + integrity manifest | `output/sor-confirmatory//` — `analysis/stage06-results.json`, `SHA256SUMS.txt`, `INTEGRITY-REPORT.md`, `provenance.json` | the committed, verifiable outputs of the frozen run | > **Raw data is *not* committed.** The per-run pcaps + event logs > (`output/sor-confirmatory//confirmatory-data/`, ~1.2 GB: 9,000 `events.jsonl` + > 27,000 pcaps) are `.gitignore`d for size. What *is* committed is their `SHA256SUMS.txt` > manifest and the analysis results. To re-run the analysis from raw pcaps you must either obtain > that archive out-of-band or re-collect it via §5; a clean clone can still **verify** the > committed results and the integrity manifest. --- ## 0. Where does the code run? (the common confusion) | Component | Runs where | How | |---|---|---| | Clone, venv, orchestration, analysis | **On the host** (your laptop) | you drive everything from the repo checkout | | Circuit **forwarders / hops** | **Inside an isolated engine** (docker container or multipass VM) | spawned automatically by the code via the isolation prefix (`cmd_chat/agent/bridge.py:517-530`); the host never forwards | You **clone once, on the host.** You do **not** clone inside the VM. When a run starts, each hop is launched into its own container/VM for you. There is a hard containment check: if the engine resolves to `local`, the forwarder refuses to run. --- ## 1. Get the code ```bash git clone https://git.churchofmalware.org/trilltechnician/hack-house.git cd hack-house git checkout feat/sor-consent-relay # the branch this study lives on ``` ## 2. Set up the environment (host) ```bash hh/scripts/bootstrap.sh # Python venv + server deps + Rust client build # (or: python3 -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt) ``` Requires **Python 3.10+** and a Rust toolchain (bootstrap builds the client). Install **at least one isolated engine** — forwarders will not run without one: ```bash hh/scripts/ensure-docker.sh # docker (the default engine, --engine docker) hh/scripts/ensure-multipass.sh # multipass (full-VM isolation), optional ``` ## 3. Verify the instrument (no grid, no confirmatory data) ```bash pytest tests/ # Python acceptance checks (R1–R7) cd hh && cargo test && cd .. # Rust `_sor` consent-parser proptests # Safe start-line preflight — runs the §5 gate, grid inventory, cell plan, # a 2-run deterministic dry provenance pass, and the assembler dry check. # Collects NO confirmatory data; prints a GO/NO-GO summary. python -m cmd_chat.sor.confirmatory_run ``` A green preflight means the six instrument-validation gate items pass: 3-hop end-to-end delivery with per-hop pcap + checksum, seeded reproducibility, correlator calibration (linked AUC≈1 / unlinked≈0.5), entropy calibration (H=log₂N), isolated-engine-only forwarders, and append-only provenance whose `events.jsonl` SHA-256 matches the manifest. ## 4. Reproduce the reported analysis Every number in the paper is deterministically regenerable from the frozen raw data and the single base seed **S0 = 20260719** — same seed → identical output. **Two things a clean clone can always do (no grid, no raw data):** re-hash the committed results and verify the raw-data integrity manifest: ```bash cd output/sor-confirmatory/20260720T060132Z && sha256sum -c SHA256SUMS.txt # needs raw data present # and inspect the committed frozen outputs directly: cat output/sor-confirmatory/20260720T060132Z/analysis/stage06-results.json ``` **To regenerate the numbers from raw pcaps** you need the ~1.2 GB `confirmatory-data/` archive present (obtain out-of-band, or re-collect via §5). With it in place: ```bash # Lead paper — RQ1-P1, RQ1-P2, RQ2-P1, RQ2-P3 (Holm family_size=7, report 4) python -m cmd_chat.sor.analysis.stage06_run \ output/sor-confirmatory/20260720T060132Z/confirmatory-data \ --out output/sor-confirmatory/20260720T060132Z/analysis/stage06-results.json # Companion — RQ2-P3′ mechanism study and RQ3 python -m cmd_chat.sor.analysis.rq2p3_confirm # shared-pool anonymity-set mechanism python -m cmd_chat.sor.analysis.rq3_confirm # churn-resilience selector ``` Same seed → identical output (10,000 BCa bootstrap resamples, α = 0.05). Verify integrity by re-hashing each run's `events.jsonl` against its `manifest.json`, and confirming the frozen prereg still hashes to `f22331a72e0d0ccf38b787e63acabbe9d666456ec76076787a6d545c3193425b`. ## 5. Re-run the full confirmatory battery (human-gated — needs the lab grid) The immutable data run (**R = 30 runs × C = 50 circuits = 9,000 live circuits**) is deliberately **human-gated**. It is triple-locked and refuses to launch unless all four hold: 1. **Operator token** — `SOR_CONFIRMATORY_GO=1` in the environment. 2. **Frozen prereg** — the on-disk prereg hashes to `f22331a7…` (see §6 caveat). 3. **Isolation** — `--engine docker` (or `multipass`); never `local`. 4. **Full grid** — every device reachable (the launcher refuses a degraded grid rather than fabricate cells). ```bash SOR_CONFIRMATORY_GO=1 python -m cmd_chat.sor.confirmatory_run --operator-go --engine docker python -m cmd_chat.sor.rq3_confirmatory_run --engine docker # companion RQ3 battery ``` Then re-run the §4 analysis over the freshly collected `confirmatory-data/`. --- ## Seeds & determinism - **Base seed:** `S0 = 20260719` (fixed pre-data). - **Per-cell seed:** `SHA256(S0 ‖ cell_id ‖ run_index)` — drives every stochastic element (path selection, churn schedule, padding jitter) so two runs with the same seed produce an identical circuit-build sequence. - Seed + git SHA + node-role→device mapping are echoed into each run's immutable `manifest.json`. ## Outputs (treat as immutable once written) ``` output/sor-runs// manifest.json · events.jsonl · pcap/hop.pcap · metrics.json output/sor-confirmatory// preflight artifacts · confirmatory-data/ · analysis/ ``` ## Honest reproduction caveats - **The frozen prereg is vendored.** The confirmatory launcher (§5) hard-refuses unless the pre-registration is present and hashes to `f22331a7…`. The frozen prereg is committed in-repo at `docs/prereg/sor-consent-prereg.md` (with `.sha256`), so this checkout is self-contained — no `sci-method` access is needed. The launcher prefers the in-repo copy and falls back to the operator's canonical `sci-method` checkout; the SHA-256 pin (not the path) is the integrity guarantee. Verify it yourself: `cd docs/prereg && sha256sum -c sor-consent-prereg.sha256`. - **The physical grid is lab-specific.** The reported run distributes hops across our own 2 phones + laptop + hack-house VM churn fabric. An external reproducer instead uses the **containerised-hop fallback** (all hops as isolated docker containers) — this reproduces the instrument and the analysis, but not the exact physical device distribution. - **Agent arm (RQ3).** Local open-weight (Ollama, temp 0) is **not** bit-identical across machines (quantization / GPU logit drift). The agent arm reproduces via the **committed decision-log + `(seed, state-hash)` cache replay**, not via independent cross-hardware model re-execution. See `CLAUDE.md` for the containment law and `docs/stage-07-paper-draft.md` §4 for the frozen method.