Skip to content

Signal Quality: Time-based expiry for uncorrectable error penalization after one-time spikes #141

Description

@neofabrics

Problem or Use Case

The health score calculates uncorrectable error severity using cumulative modem counters (which only reset on reboot):

uncorr_pct = uncorrectable / (correctable + uncorrectable)

A single one-time spike event can permanently inflate this percentage — even if the connection has been fully stable since. The "self-healing" property of the percentage metric only works if large numbers of new correctable errors continuously dilute the denominator, which does not happen on an otherwise healthy line.

Real example: On 2026-02-27, a one-time event caused ~1M uncorrectable errors. Since then, virtually no new uncorrectable errors have occurred (~155k correctable total):

Image

The system nonetheless continues to show Poor health:

Image

This happens because:

  • uncorr_pct = 1,000,000 / (155,000 + 1,000,000) ≈ 86.6% — far above the critical threshold of 3%
  • To drop below the 1% warning threshold, ~99 million new correctable errors would need to accumulate
  • On a stable, low-noise line this could take years or never happen at all

This means a one-time historical event — a brief signal outage, a transient noise burst, a firmware glitch — causes a permanent "Poor" rating that no longer reflects the actual current state of the connection. A modem reboot is the only current remedy, which requires the user to understand DOCSIS internals.

Proposed Solution

event_detector.py already tracks uncorrectable error spikes via delta comparison between consecutive snapshots (delta > UNCORR_SPIKE_THRESHOLD). This infrastructure could be extended with a spike-timestamp-based expiry:

  1. When an error_spike event is detected, persist the timestamp of the last spike
  2. In the health analyzer: if the time elapsed since the last spike exceeds a configurable window (e.g. 48h) and no new spike has occurred in that period, suppress the uncorrectable error penalization in the health score
  3. If a new spike occurs, reset the timer

This would reflect actual signal behavior: a recurring problem stays penalized, a one-time historical event expires gracefully.

Suggested configuration (e.g. in thresholds.json):

"errors": {
  "uncorrectable_pct": { "warning": 1.0, "critical": 3.0, "min_codewords": 1000 },
  "spike_expiry_hours": 48
}

Alternatives Considered

No response

Priority

Would be very helpful

Contribution

  • I can help with testing
  • I can contribute code (PR)
  • I can help with documentation

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew behavior, UX improvement, or feature expansion

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions