Watch
1
0
Fork
You've already forked SouveraineOS
0

device-state: §9.5 prescribed the wrong debounce; the trail said so

This commit is contained in:
Fimeg 2026-07-26 12:52:03 -04:00
commit 6aa10d38cd

View file

@ -52,13 +52,11 @@ for a lock first because one was "already held". This is doctrine §4 verbatim:
"never a hand-tracked bool. A shadow copy can disagree with logind." Fixed by
`lockhint.rs` — logind is read, not mirrored.
**OPEN — proximity has no debounce, and it thrashes.** 69 transitions and 68
sensor inputs in 40 minutes, `Locked → Observed → Locked` flapping on a
sensor with no hysteresis. §9.5 of this document already specifies the fix and
it was never built: Android's `DisplayPowerProximityStateController` uses 0 ms
positive debounce and **250 ms negative** — near suppresses immediately, far
waits before being believed. Every flap writes a forensic entry, so this is
also most of the log volume below.
**FIXED 2026-07-26 — proximity is debounced, and not the way §9.5 said.** 69
transitions in 40 minutes, `Locked → Observed → Locked` on a sensor with no
hysteresis. The fix was specified here on 07-24 as Android's 0 ms positive /
250 ms negative and was never built. When it came time to build it, the trail
said the specification was wrong — see §9.5.
**FIXED 2026-07-26 — the trail was on tmpfs, unbounded, and chained to
nothing.** `$XDG_RUNTIME_DIR/souveraine/forensic.jsonl` was RAM on a 3.5 GB
@ -639,11 +637,34 @@ drop detection as a power state machine input.
layer. Our design separates the unified device state from the shell
projections (IdleCoordinator, GlobalStates). Same shape, better coverage.
5. **Proximity debounce matters.** Android's DisplayPowerProximityStateController
uses 0ms positive debounce (immediate) and 250ms negative debounce (wait
before declaring "far"). Our design should adopt this — proximity-near
should suppress DPMS immediately, but proximity-far should wait 250ms
before re-enabling it (prevents flicker when the sensor is noisy).
5. **Proximity debounce matters — and the direction is ours, not Android's.**
`DisplayPowerProximityStateController` uses 0 ms positive and 250 ms
negative: believe `near` at once, make `far` wait. This section told us to
copy that. **Measured on the trail 2026-07-26, it would have done nothing.**
44 near-episodes over 2.4 hours: median dwell **1 second**, 15 of them
sub-second, median 115 s of quiet between them. Not a sensor bouncing around
a threshold — isolated one-second blips. A negative debounce delays believing
`far`, so each 1 s blip would have become a 1.25 s blip and all 88
transitions would have stayed.
The mirror image is what this data asks for: debounce the **positive** edge.
Android debounces the negative one because there `near` means *screen off at
the ear, now*, and a positive delay is felt. That constraint left the moment
proximity stopped actuating (§4) — it now only vetoes tap-to-wake, where
waiting is imperceptible and a false veto is the worse failure.
Built as `PROXIMITY_NEAR_DEBOUNCE` 700 ms / `PROXIMITY_FAR_DEBOUNCE` 0, both
policy fields. Nine of the 44 episodes ran ≥5 s (max 173 s) — pocket, ear,
deliberate cover — and pass through untouched. Resolution happens on the
reading *and* on the tick, so a reporter that heartbeats every 30 s cannot
delay a real `near` by half a minute. The edge that wins is written to the
trail with how long it held; the blips that lose are not written at all,
which is most of the log volume §0 was complaining about.
**The lesson is the method, not the number.** The prior art was read
correctly and applied to a device whose constraints had changed underneath
it. Measure the thing before adopting the answer.
---