Skip to content

Establish single source of truth for all quantitative thresholds (RSSI / rate / health / diagnostics / color) #1173

Description

@AustinChangLinksys

Problem

Quantitative thresholds that map raw values (RSSI dBm, data rate Mbps, packet-loss %, CPU %, latency/jitter, uptime) into graded states (excellent / good / fair / poor / critical, scores, colors, animations) are defined independently in many places across the 2.x codebase. There is no single source of truth. The same concept ("weak signal", "high CPU", "poor link") is re-decided with different numbers in different files, and none of these numbers has a documented spec backing — they were set ad-hoc during implementation.

This causes:

  • Conflicting thresholds for the same quantity (e.g. RSSI warning at −75 vs central −78/−71; CPU high at 80 vs scoring line 85).
  • Multiple normalization coordinate systems that disagree (level judged on −65−78 but progress bar on −100−30 → a bar can show "2/3" yet be labeled Excellent).
  • ≥5 color-semantic systems and inconsistent animations for the same state.
  • Silent mis-mapping risk (enum declared in non-monotonic order, resolved by 3 - index arithmetic).

Full inventory below (scanned against dev-2.7.0, ~/dev/PrivacyGUI-2x, 2026-07-27). Line numbers are snapshot-based; re-verify before editing.

Goal

Establish a single source of truth for every quantitative threshold, and make all subsystems reference it. Add a lint/guard to prevent downstream code from redefining thresholds again (mechanism over reminder).

Ratification note

  • Items marked dedup-only are genuine duplicates of the same value → safe to consolidate with no behavior change.
  • Items marked needs-ratify have conflicting values with no spec backing → consolidating them forces picking a winner, which is a real domain decision. A candidate value is proposed, but must be confirmed by the owner (🌐 network expert for quantitative thresholds; 🎨 design system for state→color/animation) before the value is changed. Do not silently rubber-stamp an ad-hoc number as authoritative.

Owner legend: 🌐 network expert (are the numbers correct) · 🎨 design system (state → color / animation) · 🔧 engineering (pure structural dedup, no external decision needed)


1. RSSI signal grading — ≥4 enums + 5 numeric variants

Judgement Value Location Owner Spec Status
Central source excellent/good/fair −65 / −71 / −78 dBm wifi.dart:10-12 🌐 none needs-ratify (authority candidate)
Diagnostics WiFi warning < −75 unified_diagnostics notifier:1255 🌐 none needs-ratify (4th number, conflict)
Mesh backhaul poor (borrows fair) < −78 service.dart:705-735 🌐 partial needs-ratify
ui_kit topology fallback −50 / −70 ui_kit 🌐 none needs-ratify (separate set)
device_score RSSI→score ≥−65→100, ≥−71→80, ≥−78→60, else 40 device_score.dart:64-68 🌐 partial dedup-only (uses central)

Duplicated grading enums (same semantics, separate declarations): NodeSignalLevel (wifi.dart:52), SignalTier (wifi.dart:102), DeviceSignalLevel (device_filter_state.dart:8), HealthTier (network_health_helpers.dart:14) — at least 4.

  • Ratify authoritative RSSI thresholds (🌐); resolve the −75 conflict
  • Collapse the 4 grading enums to one shared definition

2. RSSI normalization (0~1) — coordinates disagree with grading

Use Formula Implied range Location Owner Status
Performance-card progress bar (rssi+100)/70 −100~−30 performance_card.dart:156 🌐 needs-ratify
SNR normalization snr/50 0~50 wifi.dart:117 🌐 needs-ratify
Missing-value fallback ?? -100 −100 = worst performance_card.dart:58 🔧 dedup-only
Node viz level ≥−50→0.9, ≥−60→0.65, ≥−70→0.4, else 0.1 −50/−60/−70 topology builder 🌐 needs-ratify (3rd breakpoint set)
Link distance factor clamp(−75,−45) −75~−45 topology builder:527 🌐 needs-ratify (4th breakpoint set)
  • Unify RSSI→[0,1] normalization onto one coordinate system consistent with the grading thresholds (🌐)

3. Data rate (Mbps) grading — ≥3 sets

Use Thresholds Location Owner Spec Status
dataRate score ≥100→100, ≥50→80, ≥20→60, ≥10→40, else 20 device_score.dart:72-79 🌐 none needs-ratify
dataRate label ≥100 Fast, ≥50 Good, ≥20 Moderate, ≥10 Slow, else Very Slow device_score.dart:95-99 🌐 none dedup-only (same breakpoints, not shared const)
hasLowDataRate < 20 Mbps device_score.dart:60 🌐 none dedup-only
Mesh backhaul PHY healthy ≥ 400, weak 100–400, poor < 100 unified_diagnostics_service.dart:717-727 🌐 none needs-ratify
Mesh backhaul downlink poor < 50 Mbps same:724 🌐 none needs-ratify
  • Ratify data-rate tier thresholds and backhaul PHY thresholds (🌐)
  • Share one constant set between score/label/hasLowDataRate

4. Health-score models — ≥3 unrelated

System Algorithm Location Owner Spec Status
Device overallScore (signal+dataRate)/2; hasIssue<50; color <50/<70 device_score.dart:50,53 + step_result_tile:455 🌐+🎨 none needs-ratify (50/50 weighting unjustified)
Network HealthTier (F-022) loss%→score: ≤0→100, <0.01→95, <0.1→85, <1→70, <5→45, else 20 network_health_helpers.dart:32-39 🌐 none needs-ratify
↳ score→tier ≥95 exc, ≥80 good, ≥60 fair, ≥40 poor, else critical same:42-47 🌐 none needs-ratify
HealthDimension (mascot) excellent 90 / good 70 / fair 50 / poor 30 health_dimension.dart:123-126 🌐 none needs-ratify (3rd score-breakpoint set)
  • Ratify a single health-scoring rubric and tier breakpoints (🌐)

5. Diagnostic thresholds — scattered, no central definition

Judgement Threshold Location Owner Spec Status
hasHighJitter > 50 ms unified_diagnostics_service.dart:554 🌐 none needs-ratify
recentReboot uptime < 300 s same:556 🌐 none needs-ratify
stale node no contact > 10 min same:691 _staleThresholdMinutes (noted "no TR-181 standard") 🌐 none needs-ratify
"advanced" device traffic downlink>50Mbps OR uplink>10Mbps same:253 🌐 none needs-ratify
  • Ratify diagnostic thresholds (jitter / reboot window / stale window / traffic) (🌐)

6. CPU / memory — scoring vs copy disagree

Use Threshold Location Owner Spec Status
Health-dimension scoring 50 / 70 / 85 / 95 mascot_config.dart:23-29 (excellent=50, ≥95→20) 🌐 none needs-ratify
CPU/mem usage grading good 0.8 / fair 0.5 mascot_config.dart:34-36 🌐 none needs-ratify
Mascot copy "CPU high" > 80 mascot_message_templates.dart:144 🌐 none needs-ratify (conflicts with scoring 85)
  • Ratify CPU/mem thresholds; resolve 85-vs-80 conflict (🌐)

7. Color semantics — ≥5 coexisting systems

System excellent/good/fair/poor/critical Location Status
NodeSignalLevelExt green/green/red/red wifi_ui.dart:57-68 needs-ratify
SignalTierExt primary/tertiary/orange/error wifi_ui.dart:84-89 needs-ratify
HealthTier tierColor primary/tertiary/amber/orange/error network_health_helpers.dart:51-57 needs-ratify
topology poor grey unknown (reversed vs scale) builder:268 needs-ratify
mascot LED blue/green/orange (emotion, not signal) linksys_mascot_renderer.dart:96-101 needs-ratify
legend colors (3 places) tertiary vs lightGreen×2 wifi_ui / statistics / dashboard needs-ratify
  • Define one authoritative state→color mapping; all subsystems reference it (🎨)

8. Animation mapping

Dimension Rule Location Status
Link type → line wired solid pulse / wireless dashed flow link_renderer.dart:184-190 dedup-only (has branching)
Signal level → node rings 0.9/0.65/0.4/0.1 usp_topology_builder.dart needs-ratify (ignores wired/wireless, asymmetric with lines)
poor downgrade grey unknown (reversed) builder:268 needs-ratify
  • Define state→animation mapping consistent with the color mapping (🎨)

9. Enum ordering decoupled from semantics (pure risk)

Item Current Risk Location Status
NodeSignalLevel declaration order poor, good, fair, excellent (non-monotonic), resolved via 3 - index reordering silently mis-maps wifi.dart:52-58 dedup-only (add guard test)
  • Decouple ordering from arithmetic; add a guard test (🔧)

10. Dead / half-wired code

  • Mascot walk action: defined but no trigger fires it (mascot_trigger_provider.dart)

  • cpuHigh / memoryHigh triggers: factory defined, no caller (trigger_definitions.dart:45,57) → System dimension computes CPU/mem score but never pops the mascot

  • 9 triggers defined, only 5 have a fire site

  • Wire or remove dead triggers / walk action (🔧)


Suggested execution order

  1. Structural dedup (behavior-preserving, 🔧) — extract one threshold registry; consolidate only dedup-only rows; leave needs-ratify rows at their current values as placeholders. Zero behavior change.
  2. Ratification — owners confirm the needs-ratify values (🌐 quantitative thresholds; 🎨 color/animation). Confirmed values fill the registry.
  3. Mechanism — add a lint/guard forbidding downstream redefinition of thresholds.

Statistics

Domain Threshold sets needs-ratify dedup-only
RSSI grading ≥4 enums + 5 numeric variants 4 1
RSSI normalization 4 breakpoint sets 3 1
Data rate Mbps ≥3 (+ backhaul 400/100/50) 3 2
Health score ≥3 (device / network / dimension) 4 0
Diagnostics 4 (jitter / reboot / stale / traffic) 4 0
CPU / memory 3 (scoring / usage / copy 85-vs-80) 3 0
Color semantics ≥5 systems 6 0
Animation 3 2 1
enum / dead code structural

Metadata

Metadata

Labels

2.xLabeled for 2.x versionrefactorBehavior-preserving cleanup / tech-debt (Sweeper mode)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions