Skip to content

T-018: warn on a clock-fault RATE, not a lifetime counter - #6

Merged
Skeyelab merged 1 commit into
mainfrom
fix/diagnostics-and-resolution
Jul 14, 2026
Merged

Skeyelab merged 1 commit into
mainfrom
fix/diagnostics-and-resolution

Conversation

@Skeyelab

Copy link
Copy Markdown
Member

HARDWARE-FOUND. The diagnostics dot was permanently amber on a perfectly healthy device — and it was my bug.

hasDiagWarning was droppedTicks > 0. But those are LIFETIME counters, and the firmware says so in as many words (ks_tick_health.h: "Lifetime counters, not windowed — a worst-case that scrolled past is not a measurement").

So the real kstouch-dfd0, reporting drop:47 accumulated once at boot, lit an amber warning forever:

t+ 4s  drop=47  over=0  gap=1487  work=229
t+32s  drop=47  over=0  gap=1487  work=229    ← 8 samples, never moved

The clock was flawless and the app said otherwise, permanently. That's alarm fatigue by construction — a warning that is always on is one nobody reads, and it gets ignored on the one day it means something.

The fix

The app polls continuously, so it can just look at the delta:

means user should
non-zero but static dropped ticks at boot, fine now nothing
increasing the clock task is dropping ticks right now this is ESP-027's class of fault

ClockFault.between(previous:current:) is pure and tested. Two traps it handles:

  • The first sample has no rate, so it must not alarm — otherwise a device that booted with 47 drops alarms the instant you open its screen, which is the bug.
  • A counter going DOWN means the device rebooted (lifetime counters zero on restart) — and this app reboots devices deliberately, via WRITE & REBOOT and OTA. A reset is not a fault, and must not read as one or as a huge negative rate.

The counters are still shown ("47 since boot") — they're real data. They just aren't an alarm. When the rate is non-zero, the screen says so in words: "The clock task is dropping ticks RIGHT NOW."

This is the same mistake for the fourth time today

  • A /config.json 404 is not a dead network (T-009)
  • One dropped poll is not a disconnection (T-010)
  • A decode failure is not an unreachable device (T-016)
  • And now: a lifetime counter is not a live fault (T-018)

Every one is two situations collapsed into one signal, sending the user to fix the wrong thing. The rule worth generalising, recorded in T-018's notes: before showing a warning, ask what the user would DO about it. If two causes need different actions, they need different signals.

maxStepMicros stays deliberately un-warned — nobody has given us a threshold, and inventing one would be worse than showing the raw number.

Also files T-019

The device answered on 192.168.0.101 while kstouch-dfd0.local timed out and dns-sd was still advertising it. The app resolves by <name>.local, so that flake surfaces as a false UNREACHABLE. Not fixed here — filed with the evidence.


100 tests, 0 failures.

https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6

+ file T-019 (.local resolution fallback)

HARDWARE-FOUND. The diagnostics dot was permanently amber on a perfectly healthy
device.

hasDiagWarning was `droppedTicks > 0`. But those are LIFETIME counters — the
firmware says so in as many words (ks_tick_health.h: "Lifetime counters, not
windowed — a worst-case that scrolled past is not a measurement").

So the real kstouch-dfd0, reporting drop:47 accumulated once at boot, lit an
amber warning FOREVER. Sampled every 4s for 32s: drop never moved off 47, over
stayed 0. The clock was flawless and the app said otherwise, permanently.

That is alarm fatigue by construction. A warning that is always on is a warning
nobody reads, and it would be ignored on the one day it means something.

The app polls continuously, so it can just look at the delta:
- non-zero but STATIC   -> dropped ticks at boot, fine now. Say nothing.
- INCREASING            -> the clock task is dropping ticks RIGHT NOW. Alarm.

ClockFault.between(previous:current:) is pure and tested. Two traps it handles:
- The FIRST sample has no rate, so it must not alarm — otherwise a device that
  booted with 47 drops alarms the instant you open its screen, which is the bug.
- A counter going DOWN means the device REBOOTED (lifetime counters zero on
  restart) — and this app reboots devices deliberately, via WRITE & REBOOT and
  OTA. A reset is not a fault and must not read as one, nor as a huge negative
  rate.

The counters are still SHOWN ("47 since boot") — they are real data. They just
aren't an alarm. When the rate is non-zero the screen says so in words: "The
clock task is dropping ticks RIGHT NOW."

This is the same error for the FOURTH time today: a /config.json 404 is not a
dead network (T-009); one dropped poll is not a disconnection (T-010); a decode
failure is not an unreachable device (T-016). Now: a lifetime counter is not a
live fault. Every one is two situations collapsed into one signal, sending the
user to fix the wrong thing.

The rule worth generalising, and it's in T-018's notes: before showing a warning,
ask what the user would DO about it. If two causes need different actions, they
need different signals.

maxStepMicros stays deliberately un-warned — nobody has given us a threshold and
inventing one would be worse than showing the number.

Also files T-019: the device answered on 192.168.0.101 while kstouch-dfd0.local
timed out and Bonjour was STILL advertising it. The app resolves by <name>.local,
so that flake surfaces as a false UNREACHABLE.

100 tests, 0 failures.
@Skeyelab
Skeyelab merged commit a23d5f4 into main Jul 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants