Context
v0.5.1 landed G-7 — dashboard tiles render explanatory N/A with hover
tooltip when a sensor is structurally absent on the host platform
(Intel iGPU has no discrete temp/power; RAPL CVE-locked; no fan tool;
etc). Reasons currently live in the frontend as a hardcoded naReasons
dict, duplicated between live-telemetry-tile.js and sparkline-tile.js.
See docs/aur-publishing.md § G-7 for the case study.
What's needed
Move reason ownership to the collector layer. Each SignalDescriptor
should optionally expose its current availability + reason at probe
time, e.g.:
@dataclass
class SignalDescriptor:
name: str
unit: str
dtype: str
...
unavailable_reason: str | None = None # ← new
Then /api/discoveries already surfaces the manifest; frontend tiles
consume unavailable_reason directly instead of mapping from signal
name. Net effect: when a new platform gap is discovered, only the
collector changes — no frontend edit needed.
Acceptance
Why this matters
Today, when an enterprise user finds a new structurally-missing signal,
the fix is split across backend (emit null) and frontend (add the reason
to the dict). Centralising in the collector turns it into a single
edit + automatic CI coverage via the platform fixtures.
Difficulty: medium. Scope: schema + 5 collectors + 2 tiles + 1 fixture
test. Estimated ~150 LOC.
Context
v0.5.1 landed G-7 — dashboard tiles render explanatory
N/Awith hovertooltip when a sensor is structurally absent on the host platform
(Intel iGPU has no discrete temp/power; RAPL CVE-locked; no fan tool;
etc). Reasons currently live in the frontend as a hardcoded
naReasonsdict, duplicated between
live-telemetry-tile.jsandsparkline-tile.js.See
docs/aur-publishing.md§ G-7 for the case study.What's needed
Move reason ownership to the collector layer. Each
SignalDescriptorshould optionally expose its current availability + reason at probe
time, e.g.:
Then
/api/discoveriesalready surfaces the manifest; frontend tilesconsume
unavailable_reasondirectly instead of mapping from signalname. Net effect: when a new platform gap is discovered, only the
collector changes — no frontend edit needed.
Acceptance
SignalDescriptor.unavailable_reasonfield added with backward-compat defaultlive-telemetry-tile.js+sparkline-tile.jsread from/api/discoveriesinstead of frontend dictWhy this matters
Today, when an enterprise user finds a new structurally-missing signal,
the fix is split across backend (emit null) and frontend (add the reason
to the dict). Centralising in the collector turns it into a single
edit + automatic CI coverage via the platform fixtures.
Difficulty: medium. Scope: schema + 5 collectors + 2 tiles + 1 fixture
test. Estimated ~150 LOC.