ruvnet / ruvnet/RuView

Calibration binds a grid the radios abandon, then hangs in collecting forever

Open
#1,939 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Rust
Stars
94.5k
Forks
12.5k
Avg merge
21h 27m
Merged PRs (30d)
43

Description

Calibration binds a grid the radios abandon, then hangs in collecting forever

Repo: ruvnet/RuView (sensing-server) · Severity: High · Measured: 2026-09-15, 4 ESP32-C6 nodes

Symptom

A capture reaches both minimums and then never finalizes. Observed:

status      collecting          (858 s elapsed, min 600)
frames      10,997              (min 1,000) — frozen, not advancing
bound grid  64sc on node 11 — status: stale, last frame 5+ min ago
nodes       11,12,13,14 all active, fresh 28 ms, all emitting 256sc

No error is surfaced. The user sees a stalled capture and a flickering UI as the client
repeatedly retries finalization against a stale grid.

Root cause

Two policies in the same file disagree.

accept_grid (ADR-110) locks each node onto the densest grid seen and rejects sparser
frames from the feature path — on an ESP32-C6, the ~16% HT 64-bin minority that arrives
alongside HE-SU 256-bin:

/// Returns `true` to accept. Policy: lock onto the densest grid seen.
/// Sparser-grid frames (the ~16% HT minority an ESP32-C6 keeps emitting
/// alongside HE) are rejected from the feature path

select_calibration_grid ordered candidates by max_gap_s first. A sparse trickle at a
metronomic cadence has a smaller worst-case gap than a busy stream with one scheduling
hiccup — so selection kept binding the grid admission is designed to discard. Once the
nodes locked onto 256sc, the bound 64sc grid stopped arriving entirely.

Selection chose 64sc on three separate captures. Both captures that bound 256sc produced a
usable model (5 baseline eigenvalues).

Fix

Order by subcarrier count first so selection agrees with admission, then fall back to the
existing gap/rate/ppdu ordering among equally dense candidates.

Related

Same defect class as PR #1919 ("bind the grid whose frames come from one population"),
measured independently on C6 rather than S3.


Fixed in #1936.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read accept_grid and select_calibration_grid in the shared file, then compare the ordering with ADR-110 and the fix in PR #1936. Done means calibration selects the densest admitted grid first and preserves the existing gap, rate, and PPDU tie-breakers, without binding a grid that admission discards.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
embedded-iot, networking
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.