← RFC

Result — Coordinator-Discovery Latency: Blind Grid Scan vs. Beacon-Guided Roam (#65)

Status: Stage-2 sim result. Quantifies the cost of the firmware's blind (channel × SF) grid scan and the latency win of the #65 guided-roam reframe (the coordinator announces a neighbour-channel plan so a roaming client retunes directly instead of blind-sweeping). Date: 2026-06-22. Experiment: sim/experiments/discovery_latency.py (cd sim && PYTHONPATH=. python3 -m experiments.discovery_latency). Figure: docs/figures/discovery_latency.png. Design source: frequency-agility-multisector-note.md (frequency = the fourth INFRA authority; beacon carries the cell's freq, a grant can direct a client to another freq).


1. The mechanism being modelled

The firmware discovers a coordinator that may sit on a non-default frequency/SF by sweeping a grid of G = N_channels × N_SFs cells, dwelling SCAN_DWELL_MS = 12 000 ms on each, and adopting the PHY announced by the first beacon it hears. The bench-observed symptom that motivated this work: a client took ~45 s to acquire a cell, catching the beacon on its 2nd dwell of the right channel — i.e. the grid was swept more than once before a (channel, SF) cell that actually carried a beacon lined up with a dwell.

The #65 reframe: the coordinator's beacon announces a neighbour-channel plan (target (ch, SF) and its beacon-phase offset), so a roaming client retunes directlyO(1) acquisition — instead of blind-scanning the whole grid.

Pinned timing (reused from the airtime law, not re-derived)

Quantity Value Source
Beacon period B (one idle frame) 2.117 s BEACON 525 + GUARD 3 + 3·TELEM 280 + ADVERT 751 ms, FLEET SF9/BW125 (membership.py)
Dwell D 12.0 s firmware SCAN_DWELL_MS
Arrivals per dwell D/B ~5.67 a dwell on the right cell almost always contains a beacon
p_detect (per-arrival detect prob) 0.95 (swept) shadowing/SNR-margin knob; flagged for validation

Because D ≫ B, the first dwell on the exact right (ch, SF) cell catches a beacon with probability ≈ 1 (P(catch | right-cell dwell) = 1.00000 at p_detect = 0.95). The cost is therefore not "miss the beacon on the right cell" — it is reaching the right cell in a G-cell sweep, and the bench's "2nd dwell of the right channel" is the right channel being revisited across its several SFs before the right (ch, SF) pair lined up.


2. Model (analytic) and confirmation (Monte-Carlo)

Blind scan. The client sweeps G cells round-robin, D per cell; the coordinator's cell is uniform-random in the sweep (the client has no prior — that is what "blind" means). Mean cells visited before the right one is (G−1)/2. On the right cell it catches a beacon with probability p_catch at conditional time e_t ≈ 1.17 s into the dwell; a miss (only possible if fades knock out every arrival in the dwell) costs a full extra sweep G·D.

E[L_blind] = (G−1)/2 · D  +  ((1/p_catch) − 1) · G · D  +  e_t
           ≈ (G−1)/2 · D                                   (since p_catch ≈ 1 for D ≫ B)

Guided roam. Retune to the named (ch, SF); acquire on the next detected beacon. With a uniform start phase and per-arrival fades:

E[L_guided] = B/2 + ((1/p_detect) − 1) · B   ≈ B/2 ≈ 1.06 s

The Monte-Carlo sim (40 000 trials/grid, full sweep-vs-beacon-phase geometry incl. fades) confirms the analytic mean to within MC error (e.g. 3×3: MC 49.20 s vs analytic 49.17 s; 4×6: MC 138.85 s vs analytic 139.17 s) and supplies the p95 tail the closed form does not.


3. Headline result — latency vs. grid size G

p_detect = 0.95, D = 12 s, B = 2.117 s. Mean and p95 are acquisition latency (s).

Grid (ch×SF) G Blind mean Blind p95 Guided mean Guided p95 Speed-up (mean)
1×1 (fixed, no agility) 1 1.2 s 2.1 s 1.2 s 2.1 s 1.0×
2×1 2 7.2 s 14.0 s 1.2 s 2.1 s 6.2×
2×2 4 19.2 s 37.8 s 1.2 s 2.2 s 16.3×
3×3 9 49.2 s 97.2 s 1.2 s 2.1 s 42×
3×4 12 67.1 s 132.9 s 1.2 s 2.1 s 57×
4×6 (full ISM × SF7–12) 24 138.9 s 265.7 s 1.2 s 2.1 s 118×

Bench cross-check: the observed ~45 s acquisition sits between the model's 3×3 mean (49.2 s) and is well inside its p95 (97.2 s) — consistent with the "2nd dwell of the right channel" report at a ~3×3-class grid.

Scaling law

Blind grid scan:   E[L] ≈ (G−1)/2 · D        →  LINEAR in G   (≈ 6 s of latency per grid cell at D=12 s)
                   p95   ≈ (G−1)   · D        →  full-sweep worst case
Guided roam:       E[L] ≈ B/2 ≈ 1.06 s        →  CONSTANT in G (independent of grid size)

Blind scan pays D/2 ≈ 6 s of expected latency for every cell added to the grid; guided roam pays nothing. So the discovery cost is exactly what makes frequency/SF agility look expensive — and exactly what the beacon-announced plan removes. The speed-up grows with agility: ~6× at the smallest 2-cell grid, ~42× at 3×3, ~118× at the full 4×6.

Sensitivity to shadowing margin (full 4×6 grid, G=24)

p_detect Blind mean P(catch/dwell) Guided mean Speed-up
0.99 139.1 s 1.000 1.08 s 129×
0.95 139.2 s 1.000 1.17 s 119×
0.80 139.6 s 1.000 1.59 s 88×
0.60 142.2 s 0.994 2.47 s 58×

Blind scan is insensitive to p_detect (because D ≫ B so the right-cell dwell almost always still catches a beacon even under heavy fading); the guided path degrades gently (extra beacon periods to ride out fades) but stays one-to-two beacon periods. The blind cost is dominated by sweep geometry, not link quality.


4. Roaming hand-off — scan-while-camped data gap (Section 3 of the task)

A camped client periodically hops away to look for a better cell. Each probe takes it off its home channel, so it misses its home telemetry/downlink windows for the probe duration.

Data gap, expressed as missed home frames (gap / B):

Grid candidates Blind gap Guided gap Blind missed frames Guided missed frames
2×1 1 12.0 s 2.1 s 5.7 1.0
2×2 3 36.0 s 6.4 s 17.0 3.0
3×3 8 96.0 s 16.9 s 45.3 8.0
3×4 11 132.0 s 23.3 s 62.3 11.0
4×6 23 276.0 s 48.7 s 130.4 23.0

A blind scan-while-camped survey of a 3×3 grid blacks the client out of home service for ~45 frames (~96 s); the guided pre-tune costs ~8 frames (~17 s) — a D/B ≈ 5.7× reduction per probed cell. This is the same D/B factor that drives the acquisition speed-up, re-expressed as a hand-off cost: guided roaming replaces a full dwell with a single beacon period at every cell touched.


5. Model assumptions (all flagged for bench validation)

  1. Beacon recurrence = one idle frame (B ≈ 2.117 s), evenly spaced, one beacon/frame. If the real beacon cadence is sparser than once-per-frame, B rises and both paths slow, but the D/2-per-cell blind law and the constant-B guided law are unchanged in form.
  2. Uniform-random coordinator cell and uniform sweep start phase — the client has no prior on where the coordinator is (the definition of blind scan).
  3. D ≫ B (here 5.67×), so a right-cell dwell catches a beacon w.p. ≈ 1; the blind cost is sweep geometry, not beacon-phase misses. If D were cut below B the model gains a second per-cell miss term — not our regime, but the experiment's dwell_catch_stats computes it exactly for that case.
  4. No discovery-time collisions / no false positives. Bring-up traffic is tiny and the cell is lightly loaded; shadowing is folded into p_detect, swept above.
  5. Negligible PLL/retune settle vs. B for the guided path (PLL settle ≪ 2 s).
  6. Guided pre-tune knows the neighbour's beacon phase (carried in the plan). Without the phase, guided degrades to "tune to the named cell, wait ≤ one full B" — still O(1) and still ~B mean; the phase just tightens the tail.

6. Takeaway for #65

Cross-references: frequency-agility-multisector-note.md (the beacon-freq / grant-freq contract this builds on), jammer-freq-agility-result.md (the agility-escapes-jammer companion), mode-and-handoff-note.md (hand-off hysteresis), data-window-latency / membership.py (the frame-period B this reuses).