device-state: §12 — where ambient light enters, and why it is an Action not a daemon
This commit is contained in:
parent
f7aa5ce8a2
commit
736567c0d4
1 changed files with 74 additions and 0 deletions
|
|
@ -821,3 +821,77 @@ verify across a rotation. Proven on the device 2026-07-26 — 14 entries verify,
|
|||
and editing one byte of entry 2 reports `seq 1 hash does not cover its body`
|
||||
and exits 1. The same contract reads `SessionAudit.qml`'s chain, which has
|
||||
never been checked either.
|
||||
|
||||
---
|
||||
|
||||
## 12. Ambient light — where it belongs in the chain (2026-07-26)
|
||||
|
||||
Light is already half-modelled: `SensorSource::Light` exists, `light_changing`
|
||||
carries +0.2 in §4's arithmetic, and §10 tracks its health. It has no reporter,
|
||||
so it sits at `Unknown` forever. Adding auto-brightness means answering two
|
||||
separate questions, and conflating them is how this goes wrong.
|
||||
|
||||
### Two consumers, one input
|
||||
|
||||
| | question | already exists |
|
||||
|---|---|---|
|
||||
| evidence | is the light *changing*? (someone is here) | yes — §4, unfed |
|
||||
| actuation | how bright *should* the panel be? | no |
|
||||
|
||||
A change-detector cannot drive brightness and an absolute lux reading is weak
|
||||
evidence of presence. Both come off the same sensor; neither substitutes.
|
||||
|
||||
### It must be an Action, not a daemon
|
||||
|
||||
The tempting shape is a small auto-brightness service reading lux and calling
|
||||
`brightnessctl`. That is an **eighth blind actor** and §1 already says what
|
||||
happens: sessiond owns the panel's brightness today — `Dim` captures the
|
||||
current value, `Restore` puts it back, and the code comment on that capture
|
||||
records what it cost to get right. A second writer makes the captured value a
|
||||
lie the moment it writes, and the failure looks exactly like the one already
|
||||
recorded there: "a tap-to-dismiss came back at a different level than it
|
||||
started."
|
||||
|
||||
So: lux enters through `sensor_input` like proximity, and auto-brightness
|
||||
leaves as an `Action` computed in `tick()`, executed by the same executor
|
||||
table that owns `Dim`/`Restore`. One writer, one trail.
|
||||
|
||||
### The interaction that has to be stated
|
||||
|
||||
`Dim` is a deliberate departure from the correct brightness, so auto-brightness
|
||||
must be **suspended between `Dim` and `Restore`**, not merely rate-limited.
|
||||
Otherwise the dim is fought by the ambient controller, and `Restore` puts back
|
||||
a value auto-brightness has since superseded.
|
||||
|
||||
The rule: auto-brightness proposes only while the panel is undimmed and the
|
||||
device is not `Locked`. On `Restore` it re-evaluates from current lux rather
|
||||
than replaying the captured number — the capture exists to undo *our* dim, not
|
||||
to pin the panel to a stale room.
|
||||
|
||||
### Hysteresis, for the same reason proximity has it
|
||||
|
||||
§9.5's lesson applies directly: an unsmoothed sensor driving an actuator
|
||||
produces exactly the flapping proximity produced. Lux is continuous and noisy —
|
||||
a hand passing over the sensor is a 1-second event. Ramp, do not step, and
|
||||
require a sustained delta before moving at all. The numbers should come off the
|
||||
trail the way `PROXIMITY_NEAR_DEBOUNCE` did, not out of this document.
|
||||
|
||||
### The reporter is the same open question as proximity's
|
||||
|
||||
`blueline-proximity-lock` is a shell script on a `sleep 30` loop feeding
|
||||
`sensor_input`, and §10's heartbeat requirement is implemented inside it. A
|
||||
light reporter needs the identical contract — heartbeat inside
|
||||
`SOURCE_DOWN_AFTER`, seed from a startup probe — which is the second copy of
|
||||
that logic and the argument for one reporter process serving every
|
||||
iio-sensor-proxy source instead of one script per sensor. Decide that before
|
||||
writing the second script, not after the third.
|
||||
|
||||
### Open
|
||||
|
||||
- Manual override: a user who sets brightness by hand has stated a preference.
|
||||
Auto-brightness must yield to it, and for how long is a policy decision
|
||||
nobody has taken. Android uses the manual value as a bias on the curve
|
||||
rather than a suspension; that is probably right here too.
|
||||
- Whether lux belongs in the confidence table at all once it drives an
|
||||
actuator, or whether `light_changing` should be derived from the same
|
||||
smoothed signal auto-brightness uses rather than a second raw one.
|
||||
|
|
|
|||
Loading…
Reference in a new issue