Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
541b7f6
test(regression): pin pre-change values for campaign depth + PV margi…
JasperSeehofer Jul 3, 2026
b52ff8d
[PHYSICS] deepen campaign population to z = 1.5 (fix #20)
JasperSeehofer Jul 3, 2026
8568d9f
[PHYSICS] marginalize residual host peculiar velocity into the host-z…
JasperSeehofer Jul 3, 2026
cbf4ddb
docs: CHANGELOG entries for #20/#16 physics changes + catalogue prove…
JasperSeehofer Jul 3, 2026
3273fa5
[PHYSICS] campaign readiness guards: stale-pool gates, M_z edge clamp…
JasperSeehofer Jul 3, 2026
97b1571
ops(cluster): campaign-shape job templates — walltimes, private CWDs,…
JasperSeehofer Jul 3, 2026
f2a073c
results(G4b): P-P coverage at order-unity sigma_z/z — volume kernel v…
JasperSeehofer Jul 3, 2026
0249363
ops(cluster): thread PRESCREEN_AUDIT env toggle into simulate.sbatch
JasperSeehofer Jul 3, 2026
0cfb6bf
docs(campaign): pre-register the 'bias resolved' criterion before sub…
JasperSeehofer Jul 3, 2026
7b30797
fix: injection provenance columns actually reach the CSV + git commit…
JasperSeehofer Jul 3, 2026
da88c50
results(#16): PV-uncorrected catalogue variant — GLADE+ dipole conven…
JasperSeehofer Jul 3, 2026
b6bf57d
[PHYSICS] disable the quick-SNR pre-screen — smoke audit measured 0.5…
JasperSeehofer Jul 3, 2026
b233375
docs(data): register depth15_campaign pool + Phase-2 campaign submiss…
JasperSeehofer Jul 3, 2026
7257dee
ops(cluster): login-node campaign orchestrator — submission chain ind…
JasperSeehofer Jul 3, 2026
1f3b686
ops(cluster): PROJECT_ROOT env override for the orchestrator (workspa…
JasperSeehofer Jul 3, 2026
b354a2f
ops(cluster): orchestrator resilience against $HOME Lustre EIO
JasperSeehofer Jul 3, 2026
1294022
ops: weekend unattended-operation layer — retrieval watcher + runbook…
JasperSeehofer Jul 3, 2026
8c59cce
fix: thread the shallow-pool escape through the combine path
JasperSeehofer Jul 3, 2026
247f035
docs(handoff): weekend deep code-review session — 12-dimension Workfl…
JasperSeehofer Jul 3, 2026
393666b
docs: reconcile Known Bugs and Pipeline-A drift
JasperSeehofer Jul 4, 2026
562918e
ops(cluster): trivial robustness fixes from code review (Monday deploy)
JasperSeehofer Jul 4, 2026
26ce5d4
docs(pv-test): §7b isolated PV value-correction bound + reproducibili…
JasperSeehofer Jul 4, 2026
7a41603
fix: harden simulation loops + complete run-metadata provenance
JasperSeehofer Jul 4, 2026
3e7f034
test: end-to-end GLADE+ catalogue writer/reader contract (TQ-01)
JasperSeehofer Jul 4, 2026
8c789a6
fix: guard analytic distance against silent wCDM misuse (PHY-01/02, #4)
JasperSeehofer Jul 4, 2026
90bd40e
refactor: remove Pipeline-A dead code (DED-04/05/06)
JasperSeehofer Jul 4, 2026
a712a02
fix: minor safety + stale-comment cleanup (PHY-07/09, HPC-06)
JasperSeehofer Jul 4, 2026
a1e151f
fix(plotting): truth-h from constants, un-clip h-axis, stale-comment …
JasperSeehofer Jul 4, 2026
5a6b6c2
docs(review): add CODE-REVIEW-20260704 report
JasperSeehofer Jul 4, 2026
2809054
docs: CHANGELOG + TODO consistency for the 2026-07-04 code review
JasperSeehofer Jul 4, 2026
ab58242
docs: drop dangling galaxy.py autodoc + stale refs (PR #28 deletion)
JasperSeehofer Jul 7, 2026
afc59e9
[PHYSICS] physical_relations: spline-table luminosity distance + inverse
JasperSeehofer Jul 8, 2026
e49f869
test: kernel + pipeline parity gates for the eval refactor
JasperSeehofer Jul 8, 2026
713fbd1
[PHYSICS] bayesian_statistics: exact semi-analytic with-BH-mass denom…
JasperSeehofer Jul 8, 2026
60752dd
perf: host-batched likelihood kernel, bit-identical (gated)
JasperSeehofer Jul 10, 2026
51caf4d
perf: opt-in fused h-grid evaluation (--h_values), exactly equal per h
JasperSeehofer Jul 10, 2026
fc45d1f
docs: precise value-preservation claim for the batch kernel
JasperSeehofer Jul 10, 2026
ed46390
test: pin the legacy zero-host silent-skip behavior (issue #29 regres…
JasperSeehofer Jul 10, 2026
8db6c6e
[PHYSICS] zero-host events contribute the pure-completion likelihood …
JasperSeehofer Jul 10, 2026
f29a5e7
[PHYSICS] cap the selection integrals at max_redshift (#30 groundwork)
JasperSeehofer Jul 10, 2026
e19fcb2
docs: register the seed1000 rail + #29/#30 fixes + seed600 Omega_m er…
JasperSeehofer Jul 10, 2026
fa50ad5
docs(260710-sjm): pre-dispatch plan for pp_coverage catalogue-support…
JasperSeehofer Jul 10, 2026
a9733bb
test(260710-sjm): pin z_support=None golden behaviour before truncate…
JasperSeehofer Jul 10, 2026
e0eddd3
feat(260710-sjm): add z_support catalogue-support-truncated mode to p…
JasperSeehofer Jul 10, 2026
a8100f1
docs(260710-sjm): author the pp_coverage deep-venue sweep RUNBOOK
JasperSeehofer Jul 10, 2026
cfce571
chore: merge quick task worktree (260710-sjm pp_coverage deep-venue m…
JasperSeehofer Jul 10, 2026
616aeed
results(260710-sjm): pp_coverage deep-venue sweep — fallback estimato…
JasperSeehofer Jul 10, 2026
e0c429e
docs(quick-260710-sjm): pp_coverage catalogue-support-truncated mode …
JasperSeehofer Jul 10, 2026
e520f3b
results(L-B): seed600 A/B — 1D drift gate PASS exact; 2D shift = docu…
JasperSeehofer Jul 10, 2026
711c1b7
docs: correct A/B analysis date stamps (all runs completed 2026-07-10…
JasperSeehofer Jul 10, 2026
0f6f914
feat(260711-07n): add Gray-mixture + conditioned estimator branches a…
JasperSeehofer Jul 10, 2026
995e781
results(260711-07n): EXP-41 gray-mixture 8-cell sweep + conditioned c…
JasperSeehofer Jul 10, 2026
32323ac
docs(quick-260711-07n): EXP-41 gray-mixture quick task — plan, summar…
JasperSeehofer Jul 10, 2026
6a3c8ab
feat(260711-117): exact membership-truncated-kernel mode + --n-z-quad…
JasperSeehofer Jul 10, 2026
b794fa4
results(260711-117): pp_coverage exact-mode 24-cell sweep + N-2c/N-2d…
JasperSeehofer Jul 10, 2026
22797ee
docs(quick-260711-117): exact-kernel quick task — plan, summary, state
JasperSeehofer Jul 10, 2026
e5b8383
feat(260711-1ps): inference-side w_pop prior-tilt knob (gamma) + --h-…
JasperSeehofer Jul 10, 2026
c78c2f5
results(260711-1ps): pre-register prior-tilt ladder + floor-discrimin…
JasperSeehofer Jul 10, 2026
724fc29
results(260711-1ps): prior-tilt ladder + floor discriminator — lever …
JasperSeehofer Jul 10, 2026
f494762
docs(quick-260711-1ps): N-3 prior-tilt quick task — plan, summary, state
JasperSeehofer Jul 10, 2026
0d08992
feat(260711-27m): pdet-in-numerator latent-detection exact-inverse fl…
JasperSeehofer Jul 11, 2026
52be115
results(260711-27m): p_det-in-numerator probe — hypothesis REFUTED, f…
JasperSeehofer Jul 11, 2026
b89d3b7
docs(quick-260711-27m): session wrap — 27m plan/summary, state, [L7] …
JasperSeehofer Jul 11, 2026
66ff434
docs: next-session kickoff prompt — floor noise-model probe, N-4 shal…
JasperSeehofer Jul 11, 2026
77ee9d1
feat(260711-hx1): model-distance sigma in GW likelihood (floor noise-…
JasperSeehofer Jul 11, 2026
03438d8
results(260711-hx1): noise-model floor probe — H_sigma CONFIRMED as t…
JasperSeehofer Jul 11, 2026
ec182d7
docs(quick-260711-hx1): floor noise-model probe — plan, state, [L7] l…
JasperSeehofer Jul 11, 2026
baeaa1c
feat(260711-iic): tunable detection horizon (d50_gpc/w_pdet_gpc) for …
JasperSeehofer Jul 11, 2026
4f603af
results(260711-iic): N-4 shallow-venue probe — shallow 1D offset is e…
JasperSeehofer Jul 11, 2026
038bf82
docs(quick-260711-iic): N-4 shallow-venue probe — plan, state, [L8] l…
JasperSeehofer Jul 11, 2026
78e18a0
docs: next-session kickoff prompt — bias story CLOSED (deep floor + s…
JasperSeehofer Jul 11, 2026
d966156
results(260712): N-4 shallow attribution CLOSED — seed600 low-z hosts…
JasperSeehofer Jul 11, 2026
45398f4
docs(scoping): production host-z kernel correction — /physics-change …
JasperSeehofer Jul 11, 2026
7a3f318
results(260712 N-5): 2D subsample well-behaved post-D_g-fix; Eddingto…
JasperSeehofer Jul 11, 2026
6581d45
docs: next-session handoff — all LOCAL bias work exhausted (N-4 close…
JasperSeehofer Jul 11, 2026
8a6f015
docs(decisions): user calls on D1-D5 + production kernel fix (impleme…
JasperSeehofer Jul 12, 2026
bb9edf2
docs(scoping): Part-1 volume_trunc implementation spec (approved, rea…
JasperSeehofer Jul 12, 2026
821cc30
docs: volume_trunc execution kickoff (Option B — fresh focused session)
JasperSeehofer Jul 12, 2026
2784ed2
docs(planning): sim/eval convention coverage + advisory tracer verdic…
JasperSeehofer Jul 12, 2026
c4a1c7d
[PHYSICS] volume_trunc host-z kernel (Part 1) — implemented, empirica…
JasperSeehofer Jul 12, 2026
320a115
docs(planning): record Part 1 volume_trunc FALSIFIED at seed600 gate …
JasperSeehofer Jul 12, 2026
793786c
docs: CHANGELOG entry for the experimental/falsified volume_trunc mode
JasperSeehofer Jul 12, 2026
5d82f21
results: host-mass kernel truncation biases the 2D H0 channel HIGH (H…
JasperSeehofer Jul 13, 2026
87d7dc0
results: H1 shallow bias is the z>=0 photo-z CLAMP, not the volume co…
JasperSeehofer Jul 13, 2026
79e1370
results(h1): catalogue photo-z is smooth/unclamped near 0 -> harness …
JasperSeehofer Jul 13, 2026
171ab95
results(mass): firm up mass-kernel bias into the real loose-photo-z r…
JasperSeehofer Jul 13, 2026
70bee1f
[PHYSICS] mass_trunc host-mass kernel (EXP-45) — implemented, exonera…
JasperSeehofer Jul 13, 2026
01af724
docs(bias): scope the mass_trunc/volume_trunc exonerations to their s…
JasperSeehofer Jul 14, 2026
cd8ae9e
merge: pick up main's deps bump into consolidation branch
JasperSeehofer Jul 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/rules/hpc-gpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _get_xp(use_gpu: bool) -> types.ModuleType:

### Rules

- **GPU imports must always be guarded.** Never place `import cupy as cp` at module top level unconditionally. Known issues in `decorators.py`, `memory_management.py`, `LISA_configuration.py`, `parameter_estimation.py` — fix when touched.
- **GPU imports must always be guarded.** Never place `import cupy as cp` at module top level unconditionally. All source modules are compliant as of commit `4894648` (`decorators.py`, `memory_management.py`, `LISA_configuration.py`, `parameter_estimation.py` all use the guarded `try/except ImportError` + `_CUPY_AVAILABLE` pattern) — keep new modules compliant.
- **Vectorize array operations.** Never iterate over array elements in a hot path. Use vectorized `xp.*` operations (e.g., `xp.trapz(integrant / psd, x=fs)` instead of a Python loop).
- **Avoid GPU-to-CPU transfers in hot paths.** Do not call `cp.asnumpy()` or `.get()` inside functions called thousands of times. Keep data on GPU until a single scalar result.
- **GPU memory management.** Free GPU memory after each full simulation step (`cp.get_default_memory_pool().free_all_blocks()`). Do not call inside inner loops — the CuPy allocator reuses blocks.
Expand Down
218 changes: 218 additions & 0 deletions .planning/BIAS-INVESTIGATION-20260710.md

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions .planning/CAMPAIGN-PREP-PHASE2.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,54 @@ railed baseline. After combine `5698618` completes and results are retrieved+ver
- ☐ **Smoke test first**: `--tasks 2 --steps 10` (cluster skill golden rule) + the §1
pre-screen measurements, THEN full submission.

## 4b. PRE-REGISTERED "bias resolved" criterion (fixed 2026-07-03, BEFORE submission)

Defined before any campaign data exists, per the referee's asserted-decisiveness
critique (report either outcome):

1. **Multi-seed accuracy (primary)**: over the 4 seeds at h_true = 0.73, the
per-seed volume_deconv 1D MAP sample must satisfy
|mean(MAP) − 0.73| < 2·SEM (SEM = std(MAP)/√4). Same check for posterior means.
2. **Closure**: each closure run (0.67, 0.77) recovers its truth inside its own
68% HPD interval (both channels).
3. **Calibration**: per-seed `pp_coverage` (G4b, volume kernel) at the campaign's
photometric width stays near-nominal — cov68 within ±0.10 of 0.68 at n=250
realizations (binomial σ≈0.03; the 2026-07-03 σ_z/z scan bounds validity at
σ_z/z ≲ 0.8).
4. **Verdict language**: all three pass → "bias resolved at the campaign's
statistical precision"; any fail → report the measured residual with its
multi-seed uncertainty — no stronger claim.

## 4c. Unattended weekend operation (2026-07-03 → Monday 07-07)

Three self-driving layers (no live SSH dependency — every connection is per-poll):

1. **Cluster login node**: `$WS/campaign_orchestrator.sh` (pid in
`$WS/campaign_orchestrator.log`) submits seeds 2000/3000/4000 @ 0.73 +
5000 @ 0.67 + 6000 @ 0.77 (`--tasks 100 --steps 40`, pool
`$WS/injection_pool_depth15_50k`) whenever queue depth < 150; retries the
same seed through the ongoing $HOME Lustre EIO flakiness (read-probe +
5-min backoff); idempotent on restart.
2. **Dev box**: `results/campaign_phase2_runs/watch_and_retrieve.sh`
(detached) rsyncs every run dir + orchestrator logs back every 30 min →
`results/campaign_phase2_runs/{status.log,rsync.log,run_*/}`. The §7b PV
test queue (`results/pv_correction_test_20260703/run_queue.log`) finishes
Thursday evening.
3. **Claude session watchers** (if the session survives): smoke-chain combine,
pipeline-1 sim array.

**Monday checklist** (if anything stalled):
- `tail $WS/campaign_orchestrator.log` + `pgrep -f "campaign_orchestrator[.]sh"`
— restart with: `cd $WS && PROJECT_ROOT=$HOME/MasterThesisCode setsid --fork
bash campaign_orchestrator.sh` (idempotent).
- Cluster repo is PINNED at `b233375` (= tag code-wise): $HOME EIO blocks git
pulls (`unpack-objects failed`); commits after it are docs/ops-only. Re-sync
when the filesystem heals; report persistent EIO to the bwHPC hotline.
- Straggler arrays: `bash cluster/resubmit_failed.sh <SIM_JOBID> <RUN_DIR>
<BASE_SEED> <STEPS>` (TIMEOUT excluded by default — expected on
gpu_h100_short).
- `results/campaign_phase2_runs/status.log` is the weekend flight recorder.

## 5. Paper hooks

- Paper A (`paper_a/`, drafting in flight): consumes the seed600 confirmation (§0) into
Expand Down
68 changes: 68 additions & 0 deletions .planning/CONVENTIONS-MANIFEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# CONVENTIONS-MANIFEST — MasterThesisCode (SKELETON)

> **STATUS: SKELETON — NOT the full manifest.** This is the 4-incident-derived seed
> (+ HOST_DRAW_Z_MAX row + 2 verifiable bonus rows) mandated by
> [[orbiter-upgrade-design]] Part 4, C.6, as the standing floor for the sim/eval
> convention-consistency task-area. It enumerates only the convention-bearing
> quantities that have *already caused a dated incident* or are *flagged live*.
> **The full manifest — every convention-bearing quantity across the sim↔eval
> boundary — is domain archaeology estimated at 2–3 days of MTC/GPD-session
> context and is a separate named task (owner: Jasper / MTC sessions).** A class
> absent from this table is invisible to the tracer that consumes it; that
> incompleteness is declared in every tracer verdict.

- **Schema**: `conventions-manifest/skeleton-v0`
- **Seeded**: 2026-07-12 (advisory tracer run, pre-Phase-2-submission)
- **Boundary modelled**: INJECTION (sim: `main.injection_campaign`, `dark_siren_injection`, FEW/CRB) → STORAGE (injection CSV, GLADE+ reduced catalogue, CRB CSV) → P_DET GRID (`simulation_detection_probability`) → INFERENCE (`bayesian_statistics`, `posterior_combination`)
- **Convention on how to read the table**: each cell records the convention *as the code actually implements it at that stage*, with a `file:line` anchor where read from source, or `UNKNOWN — needs domain confirmation` where it could not be verified by reading code in one pass.
- **Paired-test column**: the invariant test that *should* guard this row per the C.6 floor (astropy round-trip · "a fix must produce different values" · every-output invariant · schema/provenance gate). `NONE FOUND` means no such guard was located — a manifest-upkeep action, not necessarily a bug.

---

## Table 1 — Convention-bearing quantities (incident-seeded)

| # | Quantity | Incident origin | AT INJECTION | AT STORAGE | AT P_DET GRID | AT INFERENCE | Paired invariant test | Verified? |
|---|----------|-----------------|--------------|------------|---------------|--------------|-----------------------|-----------|
| M1 | Sky-angle frame `qS`/`phiS` (θ,φ) | Coordinate-frame bug 2026-04-21 (0.0% apparent bias / 6 milestones) | ecliptic `BarycentricTrueEcliptic(J2000)`; host angles → `parameter_space.qS/phiS`; `ResponseWrapper(is_ecliptic_latitude=False)` (`waveform_generator.py:64`) | CRB CSV `qS/phiS` ecliptic rad; catalogue on disk is **equatorial ICRS deg** (raw cols 8/9), rotated **in place** to ecliptic at load (`handler._rotate_equatorial_to_ecliptic`, COORD-03/Phase 36, `handler.py:251`) | (sky enters via equal-\|sin β\| ecliptic-latitude bands; `bayesian_statistics.py:339`) | ecliptic; `Detection.phi/theta`; `get_possible_hosts_from_ball_tree` ecliptic (`bayesian_statistics.py:1175`) | astropy `SkyCoord.transform_to` round-trip at ingestion (COORD-03); FRAME-AUDIT.md 4/4 claims CONFIRMED | **YES — CONSISTENT** |
| M2 | BH mass frame `M` (source `M` vs redshifted `M_z=M(1+z)`) | Redshifted-mass bug 2026-06-20 (passed 568 tests, W-CONF-13) | **`M_z = M·(1+z)` lifted once at injection** (`main.py:899`); FEW sees `M_z`; source-frame `sample.M` NOT stored | injection CSV `"M"` column = **`M_z`** observer-frame (`main.py:980-983`); `Detection.M` documented `M_z` (`detection.py:60,85`); catalogue `host.M` = **source-frame** `M_g` (`handler.py:105`, `_rate_weight` note) | grid mass axis = **observer-frame `M_z`** (`_M_arr = pooled_df["M"]` = injection `M_z`; `simulation_detection_probability.py:139,272`) | numerator rate-weight uses source-frame `host.M` (matches draw); selection query **lifts** `M_z_g = M_g·(1+z_g)` to match grid axis (`bayesian_statistics.py:768`) | "a fix must produce different values" (M_z ≠ M); every-output invariant across CRB CSV **and** injection CSV (W-PRE-12 lesson); `test_parameter_space_h` guards CRB path | **YES — CONSISTENT (post-Design-B + H3 fix)** |
| M3 | In-catalogue likelihood `L_cat` form | `L_cat` mean-of-ratios bug, commit `816f904` | n/a (generative) | n/a | n/a | **ratio-of-sums** `(Σ_g w·N_g)/(Σ_g w·D_g)` — Gray (2020) Eq. A.9/A.10; `weighted_ratio_of_sums` (`bayesian_statistics.py:212-260`); constant-weight limit = plain ratio of sums | equivalence test that the ratio-of-sums (not mean-of-ratios) is canonical; `--catalog_only` ablation sign-test | **YES — CONSISTENT (post-816f904)** |
| M4 | `p_det` placement in the per-event ratio | p_det-in-numerator / incomplete-fix, commit `341ca62`, W-PRE-12 | detection = deterministic SNR≥threshold at injection | injection CSV stores `SNR`,`d_L` (raw, ungated; `PRE_SCREEN_SNR_FACTOR=0.0`, `constants.py:63`) | p_det = detection-horizon **survival** `P(d_hor≥d_L)`, `d_hor=SNR·d_L/thr` (`simulation_detection_probability.py:334`) | `p_det` appears **only in denominator** `D(h)=β_G+β_Ḡ` (`precompute_completion_denominator:389`); numerator `single_host_likelihood` has **no** `p_det`; `p_i=(β_G·L_cat + B_num)/D(h)` | integrand re-derivation invariant ("p_det in denominator only"); `--catalog_only` ablation | **YES — CONSISTENT (post-341ca62)** |
| M5 | Host-draw population depth `HOST_DRAW_Z_MAX` | **LIVE item** flagged 2026-07-02 (`CAMPAIGN-PREP-PHASE2.md`): "`0.5` horizon-stale" | `z_cut = HOST_DRAW_Z_MAX` (`main.py:825`); injections drawn to this depth | `constants.HOST_DRAW_Z_MAX = 1.5`; `GALAXY_CATALOG_REDSHIFT_UPPER_LIMIT = 1.55`; injection CSV carries `z_cut` provenance column | `expected_z_max=HOST_DRAW_Z_MAX` passed at construction; **hard `raise ValueError`** on shallow (`pool_z_max < 0.9·1.5`) or mixed-`z_cut` pool (`simulation_detection_probability.py:290-322`) | `cosmological_model.max_redshift = 1.5` asserts `HOST_DRAW_Z_MAX ≤ max_redshift` (`cosmological_model.py:189`); D(h) integrals capped at `max_redshift` (`f29a5e7`, #30) | provenance/schema gate: `z_cut` uniqueness + `code_rev` check + shallow-pool `ValueError` | **RESOLVED → 1.5 (fix #20, `b52ff8d`, 2026-07-03); CONSISTENT if campaign pool regenerated (hard-gated)** |

## Table 2 — Verifiable bonus rows (read from code this pass; not incident-seeded)

| # | Quantity | AT INJECTION | AT STORAGE | AT INFERENCE | Verified? |
|---|----------|--------------|------------|--------------|-----------|
| B1 | Redshift frame (heliocentric vs CMB vs cosmological) | population z is cosmological (synthetic, frame-neutral) | catalogue **`z_cmb`** (GLADE+ col 28, PV-corrected; migrated from `z_helio` col 27) fed to `d_L(z,h)` & `M_z=M(1+z)` (`handler.py:153-158`) | residual host peculiar velocity marginalized into host-z kernel `σ_z_pv=(1+z)·200km/s/c` (issue #16, `constants.py:71-83`) | **CONSISTENT in-code; RECENT migration — see WATCH (verify campaign catalogue is the z_cmb rebuild)** |
| B2 | SNR detection threshold | `SNR_THRESHOLD=20` (`main.py:1308,1409`) | injection CSV `SNR` ungated | horizon `d_hor=SNR·d_L/20` (`snr_threshold=SNR_THRESHOLD`, `posterior_combination.py:583`); CRB filter `SNR≥20` (`bayesian_statistics.py:1027`) | **CONSISTENT (uniform 20)** |
| B3 | Distance unit `d_L` | Gpc | injection CSV Gpc; CRB CSV Gpc | `dist()`/`dist_vectorized()` return Gpc (`physical_relations.py:141,235`); `d_hor` Gpc | **CONSISTENT (Gpc uniform)** |

---

## Declared incompleteness (mandatory)

This skeleton covers **8 rows** across a boundary that certainly carries more
convention-bearing quantities. Known gaps NOT modelled here (candidates for the
full-manifest archaeology task):

- Fisher/CRB covariance conventions (which parameters are `log`-scaled; units of
`delta_*_delta_*` covariance entries; correlation sign conventions).
- Prior/population weight conventions (`w_pop ∝ dV_c/dz/(1+z)`; the Eddington-shift
`eddington_shifted_host_mass`; the volume-deconvolution `normalization_mode`).
- Completeness `f(z)`/`m_th` HEALPix conventions (magnitude system, NSIDE, apparent
vs absolute threshold).
- Photo-z vs spec-z error-model conventions (`σ_z` floors, the σ_z/z shallow-venue
regime flagged in SCV 2026-07-11).
- `pp_coverage` validation-harness population ceiling (`Z_MAX_POP=0.95`) vs the
production campaign depth (`1.5`) — see tracer verdict Q7 (UNKNOWN).

**An `UNKNOWN` or a flagged row in this manifest is a valid, valuable output. A
false "all covered" is the exact W-CONF-13 failure mode this artifact exists to
prevent.**

## Upkeep contract (C.6 floor)

Per the layered-ownership recommendation: any `/physics-change` (or equivalent)
edit touching a convention-bearing quantity above **updates its manifest row and
its paired invariant test in the same change**. Manifest staleness is the tracer's
input — an unmaintained manifest produces false assurance.
Loading