Wire Smokescreen blinding into sp_validation on the fork's theory-backend protocol: three sp_validation theory_fn backends driven by one deterministic per-version draw, per-part-at-birth blinding through a three-verb custody surface, and a hash commitment that stays publicly verifiable while the seed and true vectors sit encrypted at rest.
Desired end state
Custody — per part, at birth. Three verbs plus one assertion:
blind-init (once per catalogue version): OS-entropy seed → repo-committable commitment.json carrying sha256(seed) plus a config digest binding envelope and fiducial → seed encrypted into a bundle (smokescreen.encryption, no firecrown dependency). The plaintext seed is never written to disk.
blind-part (per blindable intermediate — coarse ξ±, fine ξ±, pseudo-Cℓ — the moment it is computed): read the encrypted seed, conceal the part, stamp concealed=True and blind_commitment, strip seed_smokescreen, escrow the true vector into a per-part bundle beside the blinded part, delete the plaintext. Each part's escrow is self-contained: unblinding one part needs only its bundle plus the seed bundle.
unblind: verifies both sha256(seed) and the config digest against the commitment before subtracting — fails closed on either mismatch.
- Terminal assembly asserts
blind_commitment is identical across parts, failing closed otherwise.
Derived statistics. COSEBIs and pure-E/B are born blinded — re-derived through the pipeline estimators from the blinded fine ξ±, never shifted directly. Covariances never change. The pure-EB seam follows the pipeline's edge-based bounds.
On the fork protocol.
- The amplitude-shift envelope is expressed through the fork's fixed CCL-native draw (order-independent, local
default_rng), calibrated on the sp_validation side to an equivalent S8 amplitude; the same seed yields the same hidden cosmology for every part, which is what makes the parts mutually consistent.
- Three theory backends — coarse ξ±, fine-grid ξ±, and pseudo-Cℓ (W @ ΔCℓ_EE) — each a
theory_fn callable supplied by this issue, overriding the fork's built-in default CCL backend (which does not know our layout or IA config). Our backends are plain CCL callables that compute exactly our fiducial.
- Cross-backend consistency: the same hidden cosmology through two theory callables agrees to machine precision (~1e-10).
CAMB↔CCL cross-check (folded-in test). A theory-consistency test — same cosmology, same n(z), ξ± on our θ grid within tolerance. It must settle the σ8-for-CCL vs A_s-for-CAMB amplitude convention (σ8-matching is load-bearing: nominal A_s leaves σ8 ~3% off and blows the comparison to ~9–10%), and halofit_version strings must match on both stacks (mead2020 vs mead2020_feedback differ several percent at k≳1). Observed floor on the single-bin synthetic fixture: ξ+ 0.21% / ξ− 0.10% against 0.5%/1.0% tolerances.
Out of scope: Snakemake rule authoring — which rule invokes blind-part, where blind-init fires — belongs to the migration row (#247). This issue delivers the CLIs, backends, and the assembly-time assertion.
Acceptance
- B-mode estimators are unchanged under blinding on mocks, to the estimator's numerical floor.
- End-to-end on fixture parts:
blind-init → blind-part on each of the three real intermediates → terminal assembly (hash assertion passes) → unblind restores each part bit-for-bit; no plaintext seed or true part survives on disk at any point.
- The cross-backend and CAMB↔CCL consistency tests pass at the stated tolerances.
— Fable on behalf of Cail.
Wire Smokescreen blinding into sp_validation on the fork's theory-backend protocol: three sp_validation
theory_fnbackends driven by one deterministic per-version draw, per-part-at-birth blinding through a three-verb custody surface, and a hash commitment that stays publicly verifiable while the seed and true vectors sit encrypted at rest.Desired end state
Custody — per part, at birth. Three verbs plus one assertion:
blind-init(once per catalogue version): OS-entropy seed → repo-committablecommitment.jsoncarryingsha256(seed)plus a config digest binding envelope and fiducial → seed encrypted into a bundle (smokescreen.encryption, no firecrown dependency). The plaintext seed is never written to disk.blind-part(per blindable intermediate — coarse ξ±, fine ξ±, pseudo-Cℓ — the moment it is computed): read the encrypted seed, conceal the part, stampconcealed=Trueandblind_commitment, stripseed_smokescreen, escrow the true vector into a per-part bundle beside the blinded part, delete the plaintext. Each part's escrow is self-contained: unblinding one part needs only its bundle plus the seed bundle.unblind: verifies bothsha256(seed)and the config digest against the commitment before subtracting — fails closed on either mismatch.blind_commitmentis identical across parts, failing closed otherwise.Derived statistics. COSEBIs and pure-E/B are born blinded — re-derived through the pipeline estimators from the blinded fine ξ±, never shifted directly. Covariances never change. The pure-EB seam follows the pipeline's edge-based bounds.
On the fork protocol.
default_rng), calibrated on the sp_validation side to an equivalent S8 amplitude; the same seed yields the same hidden cosmology for every part, which is what makes the parts mutually consistent.theory_fncallable supplied by this issue, overriding the fork's built-in default CCL backend (which does not know our layout or IA config). Our backends are plain CCL callables that compute exactly our fiducial.CAMB↔CCL cross-check (folded-in test). A theory-consistency test — same cosmology, same n(z), ξ± on our θ grid within tolerance. It must settle the σ8-for-CCL vs A_s-for-CAMB amplitude convention (σ8-matching is load-bearing: nominal A_s leaves σ8 ~3% off and blows the comparison to ~9–10%), and
halofit_versionstrings must match on both stacks (mead2020 vs mead2020_feedback differ several percent at k≳1). Observed floor on the single-bin synthetic fixture: ξ+ 0.21% / ξ− 0.10% against 0.5%/1.0% tolerances.Out of scope: Snakemake rule authoring — which rule invokes
blind-part, whereblind-initfires — belongs to the migration row (#247). This issue delivers the CLIs, backends, and the assembly-time assertion.Acceptance
blind-init→blind-parton each of the three real intermediates → terminal assembly (hash assertion passes) →unblindrestores each part bit-for-bit; no plaintext seed or true part survives on disk at any point.— Fable on behalf of Cail.