Question
Are crowd-induced CSI dynamics approximately linear between occupancy-change events and forced at them — does the HAVOK residual forcing coordinate |v_r| spike time-locked to entries and exits — when the test finally runs on a simulated corpus built to be able to answer it?
This is claim A of the PUB-4 pre-registration (math-methods-publication-roadmap;
brunton2017_c9fc ↗). The claim, kill line,
and every analysis choice were declared on 2026-08-07 in
monad_knowledge/notebooks/python/csi_havok_forcing.py and sealed in
obsidian/monad-knowledge/_attachments/havok-forcing/results.json — before this campaign
existed, so the corpus is being built to the test, never the test to the corpus.
Hypothesis, and why
We expect the forcing to be event-locked (per-run z > 0, permutation p ≤ 0.05), because the mechanism already fired exactly as predicted on the scripted synthetic stream that encodes it: a Rician tapped-delay channel with AR(1) diffuse dynamics (linear between events) and a tap-kick at each entry/exit produced z = 3.45, p = 0.004 (26 usable events), while the decoupled null — same event schedule, channel independent of occupancy — correctly did NOT fire (p = 0.78). The test has demonstrated sensitivity and specificity; what it has never had is mechanism-relevant ray-traced data. If instead the forcing is NOT event-locked on the coupled JuPedSim→Sionna corpus, the intermittently-forced-linear reading of crowd CSI is wrong for ray-traced physics and PUB-4's last live claim dies — a clean, publishable negative either way.
The framing gate is not at risk: HAVOK reconstruction R² (v1) was 0.998+ on both existing real runs (gate is ≥ 0.3), so the linear-between-events skeleton fits; the open question is purely whether the residual forcing concentrates at events.
Why every existing corpus is structurally unusable (the blocking audit)
The 2026-08-07 data audit (recorded in results.json before any model fit) found:
- c-csi-crowd-temporal (the parent,
seek_and_occupy): every occupancy-change event falls in the first ~9 s ingress transient — agents walk in and park, and the persistent walkers never change rooms or cross a link LOS. Runsn8_f2.4e9_s0andn6_f2.4e9_s1had 9 and 7 events, 0 usable inside the valid forcing axis; the notebook's guard (< 5 usable events → BLOCKED, no p reported) fired on both, because a single-burst event design cannot separate event-locking from nonstationarity. The occluder count was constant over ~95% of each stream. - c-multifloor-fsm-observatory (the FSM behaviour machinery this campaign borrows): the crowds DO produce distributed entries/exits, but the coarse temporal stride left only 26–40 CSI frames per run — an order of magnitude short of the q = 60 delay embedding (30 s at 0.5 s/frame) plus a meaningful forcing axis.
So the two ingredients exist in the fleet but never together: the parent has the frames without the events; the FSM observatory has the events without the frames. This campaign is the conjunction.
Design — every number from the audit
| Knob | Value | Justification (from results.json / the notebook) |
|---|---|---|
dt |
0.05 s | Parent chain constant (walker + RT share it). |
trajectory_frame_stride |
10 | CSI frame every 0.5 s — the frame rate the pre-registered choices assume (q = 60 frames = 30 s; window ±4 frames = ±2 s). The multifloor chain's coarse stride is what starved it to 26–40 frames. |
duration_units |
6000 (300 s) | 600 CSI frames per run — 2× the ≥300-frame floor, and a forcing axis of m = 600 − 60 + 1 = 541 frames so events between ~17 s and ~283 s are usable. |
| Events per run | ~48 designed, ≥30 usable required | 32 entry/exit events (16 agents in + 16 out, staggered over 20–260 s) + ~16 FSM room crossings. The synthetic leg reached z = 3.45 with 26 usable events; the blocked real runs had 0. Mean event spacing ~6 s ≳ the ±2 s window, so event windows rarely overlap. |
| Event distribution | staggered by construction | Three visitor cohorts arrive in windows [20–80 s], [90–160 s], [170–240 s] and leave at dwell-end; circulators cross rooms every 45–60 s and depart after 260 s. No ingress-only burst is possible; the corpus gate additionally requires no 30 s window to hold > 25% of events. |
| Seeds | 5 (scenario.seed 0–4, per floor) |
With pilot effect z ≈ 3.45 and pilot_sigma ≈ 1.2 (the q-sensitivity spread), n = 10 runs powers the mean-z t CI to exclude 0 even if the ray-traced effect is half the scripted one. Seed drives the walker cast realization (arrival jitter, spawn, seat choice), as in the parent's seed-replication sweep. |
| Geometries | 2 floors via replications: |
resplan-12439-floor-0 (the parent's floor + csi-link-resplan-12439-multiroom layout — direct comparability with the blocked runs) and resplan-16157-floor-0 (+ csi-link-resplan-16157), the best-coupled small floor of the FSM observatory (occ↔|H| ρ = −0.91). Two geometries guard the verdict against a single-floor artifact at ~2× cost. |
| Band | 2.4 GHz only | Both blocked runs were 2.4 GHz — the band was never the blocker — and the parent showed the temporal feature is band-insensitive (ρ = +1.00 at both bands). Adding 5 GHz doubles RT cost without serving the event test. |
| Runs | 2 × 5 = 10 | 10 runs × 600 RT frames = 6000 frames ≈ 0.55× the parent's 30 × 360 = 10,800 frames at cpu_hours: 10 — hence cpu_hours: 6.0, s3_bytes: 5 GB (parent: 8 GB for 10,800 frames). |
The scenario: block in sim_params is the validated 12439 cast: it passed
sim_scenario_validate (strict Pydantic schema, kind: agendas + fsms:) AND the
floor-inventory cross-ref against the cached gis export-floor bundle for
resplan-12439-floor-0 (2 room refs, both present among the floor's 13 rooms). Room names are
floor-specific: for the resplan-16157 replication the supervisor MUST re-target the cast from
the staged bundle (largest room → the living-0 role, kitchen/second room → the kitchen-0
role, per the c-multifloor-fsm-observatory template) and re-run sim_scenario_validate
with that floor's bundle before launching.
What the supervisor does
- Launch the 10 coupled runs (
exp-csi-crowd: walk-notebookfrom_floor,kind: agendas→ sionna-csi-runner) over the tworeplications:rows × seeds {0–4} at 2.4 GHz. CPU-only RT; keep the per-run frame budget as designed — do not coarsen the stride to save wall-clock, that is the exact failure being repaired. - Artefact contract (hard gate): each run must ship
csi.hdf5(H [frame, link, 1, 1, subcarrier]), a frame-indexedlinks.parquetwith per-frame per-linkn_occluders, the carried-throughtrajectory.parquet, andfloor_geometry.json— the notebook derives the secondary room-crossing event stream from trajectory × room polygons, so the bundle must be carried into the run artefacts. No NaN/Inf. - Check the corpus gate first (frames, usable events, distribution) on one early run per floor before spending the rest of the budget; if the cast under-produces events on a floor, fix the cast (more visitors / shorter dwells), not the test.
- Feed the runs to
csi_havok_forcing.py(configruns:list, one entry per run dir) with the pre-registered choices untouched: q = 60, window ±4, n_perm = 2000, Gavish–Donoho rank (floor 3, cap 12), one-sided spike. Primary events =n_occluderstransitions; room crossings and q ∈ {40, 80} are sensitivity. - Aggregate at the run level: per-run z and permutation p, cross-run mean z with 95% t CI (n = 10), per-floor subtotals. Then synthesis per the expected interpretations below.
How to read the result
One number per run: z = how many null standard deviations the event-triggered mean |v_r|
(the HAVOK forcing amplitude averaged in a ±2 s window around each event) sits above what
2000 random circular shifts of the same event times produce. z > 0 with small p = the forcing
concentrates at entries/exits; z ≈ 0 = the forcing is indifferent to events. The campaign-level
figure is the run-level forest: ten z values, their mean, and the 95% t CI — the claim is
positive only if that CI clears 0 (CI-clears-line, never point-above-line). The event-triggered
average vs the permutation band (the perm_null-style panel) shows where in the ±2 s window
the spike sits; the decoupled-null shape from the pre-registration is the reference for what
"no mechanism" looks like.
What it means
- Locked (CI > 0, most runs p ≤ 0.05) — crowd-induced CSI dynamics are intermittently forced linear systems on ray-traced physics: occupancy changes act as impulsive inputs to an otherwise linear latent flow. PUB-4's claim A stands on mechanism-relevant sim data (still in-silico — the honest scope line stays), and event-triggered CSI features become a principled entry/exit detector candidate for the thesis' sensing chain.
- Not locked (CI includes 0 / p > 0.05) — the kill line fires at a powered design: HAVOK forcing is negative, and since the DMDc leg is already dead (below), PUB-4 dies entirely; this note records the negative and the roadmap entry is closed, not resurrected on a new corpus.
- Corpus gate fails — a platform finding on the agenda-driven coupled chain (cast or stride regression), to be fixed and re-run; no inference is reported from a gated corpus, exactly as the notebook's BLOCKED guard behaves.
Out of scope
- The DMDc leg (claim B) is dead — do not re-run it as a verdict. With the affine-baseline
amendment (disclosed in
results.json), DMDc with the occupancy count as control (proctor2016_2407 ↗) failed its kill line everywhere: synthetic coupled h1 −0.6% [−1.1, −0.15]%, h10 −7.7% [−12.0, −3.6]%; both real runs negative at h10 as well. The notebook still emits the DMDc numbers as descriptive output; they are explicitly NOT part of this campaign's claims or multiplicity family. - Real-hardware capture (IP-106 / EXP-C1 territory), BLE coupling, cross-geometry transfer claims, 5 GHz replication, and any tuning of the pre-registered analysis constants.
Figure render request
perm_null— the event-triggered |v_r| average vs the permutation 95% band, one panel per floor (the mechanism picture).seed_trace— per-run z across seeds, grouped by floor, with the cross-run mean ± 95% t CI (the forest / honesty picture).
Provenance
Pre-registration, blocking audit, window/permutation parameters, and the synthetic pilot all
live in obsidian/monad-knowledge/_attachments/havok-forcing/results.json (built by
monad_knowledge/notebooks/python/csi_havok_forcing.py, 2026-08-07). Parent campaign:
c-csi-crowd-temporal (blocked runs 01KVWZY4AAYJRW8SHBD0GR3S43, 01KVWZQ9K7K8HQ5NT7K70M1GF3,
session 01KVWYPHMHZVGRYQBW5Z9ZYEQ7). Behaviour machinery: c-multifloor-fsm-observatory +
IP-107 (kind: agendas, fsms: guards). Methods:
brunton2017_c9fc ↗ (HAVOK),
williams2015_6b7c ↗
(Koopman framing), Gavish–Donoho rank threshold (10.1109/TIT.2014.2323359, no vault note — cited
by DOI).