Watch
1
0
Fork
You've already forked SouveraineOS
0

Delete TASK-26; record what DEVICE-STATE-MACHINE actually built

TASK-26 duplicated this doc and should not have been written. The doc
already covers the seven-actor scatter, the evidence model, the
proximity-lock/screen-toggle mapping, and names sessiond as the owner.

Corrects the status: b4b30b1 built the enum, the transition guard, the
confidence arithmetic and the forensic log, but nothing drives them - the
daemon never leaves Active, so six of eight states are unreachable outside
tests, and no sensor feeder exists. Notes the two places the code already
diverges from section 4.
This commit is contained in:
Fimeg 2026-07-25 12:17:22 -04:00
commit ab600c2c16
2 changed files with 28 additions and 147 deletions

View file

@ -1,7 +1,34 @@
# Device state machine — unified design
**Status:** design doc, not yet implemented.
**Status:** partly built and entirely inert (verified in code 2026-07-25).
**Created:** 2026-07-24.
`b4b30b1` landed most of this in `souveraine/src/sessiond/device_state.rs`:
the §2 enum (all 8 variants), a 20-pair `LEGAL_TRANSITIONS` guard, §4's
confidence arithmetic with exactly the weights below, and the forensic log.
**None of it runs.** `transition()` has no caller outside `update_sensors`,
which only fires when already `Locked` — and nothing ever puts it there, so
the daemon never leaves `Active` and `Locked`/`Observed`/`DozeLight`/
`DozeDeep`/`Suspending`/`Asleep` are unreachable outside tests. There is no
sensor feeder anywhere (`sensor_input` has no sender), no logind/D-Bus code,
no `PrepareForSleep`, and no DPMS/freeze/inhibitor call. Both confidence
gates are computed, logged, and never branched on. Live IPC:
`observed_confidence: 0.0`, `forensic_log count: 0`.
Two divergences to settle when wiring, code-first per doc precedence:
- The `Locked → Observed` transition keys on **raw `proximity_near`**, not on
the §4 threshold table.
- §4 says proximity-near + accel-moving is hand-held so DPMS wake is NOT
suppressed; the code computes 0.4+0.30.2 = 0.5 ≥ 0.3 and suppresses it
anyway (its own test asserts the suppression).
Not in this doc, and needed before any of it can be trusted: **evidence-source
health is device state.** On 2026-07-25 SLPI took a CHRE fatal, remoteproc
recovered it, `blueline-hexagonrpcd-sdsp` exited "successfully" and was never
restarted — every sensor was dead for hours and nothing noticed, because a
consumer of a dead sensor looks identical to one whose sensor is quiet. See
`Pixel3Arch/PAF/slpi.md`. "No evidence" and "evidence says nothing is
happening" must not be the same state.
**Supersedes:** the scattered state machines in IdleCoordinator.qml (7 states),
sessiond server.rs Phase (4 states), blueline-screen-toggle (2 states), and
blueline-proximity-lock (2 states). Those are projections of this model, not

View file

@ -1,146 +0,0 @@
# TASK 26 — Sensor evidence and reactions belong to the state machine
**Status:** open — carved 2026-07-25 after finding the device state machine
is not "observational", it is **blind**, while a scatter of standalone
`/usr/bin` shell scripts each hold their own sensor claim and act on their
own authority.
**Blocks:** TASK-08(a) idle tiers, TASK-15 idle coordinator. Both are
efferent — they give the machine actuators. Neither supplies it afferents,
and both read as though something already does.
## The finding
`souveraine-sessiond` is running, package-owned, and answering IPC:
{"device_state":"active","display_active":true,"locked":false,
"observed":false,"observed_confidence":0.0,"phase":"released",
"shell_alive":true,"suppress_dpms_wake":false}
forensic_log -> {"count":0,"entries":[]}
`observed_confidence` is **0.0 and structurally cannot move**, and the
forensic buffer **cannot fill**. `src/sessiond/protocol.rs` defines
`Request::SensorInput(SensorInput)` for proximity / accelerometer / light /
touch, and **nothing in any repo ever sends one.** The only match outside
sessiond is `surfaces/quickshell/services/SessionAudit.qml:logSensorInput()`
— a logging helper with no callers. `SessiondBridge.qml` implements only the
lock handoff (`shell_ready` / `locked_ack`), not evidence.
The DUMP's "still observational — it logs, it drives nothing" undersells
this. It logs nothing either. It has no inputs.
## The sensors are not the problem — they were brought up long ago
**SLPI bring-up is SOLVED (2026-07-10) and the sensor set is wide.** The
bounded SUID sweep of 2026-07-13 (`Pixel3Arch/PAF/slpi.md`) found working
SUIDs for:
| sensor | part |
|---|---|
| `accel` / `gyro` | BMI160 |
| `mag` | LIS2MDL |
| `pressure` | BMP380 |
| `ambient_light` / `proximity` | TMD2725 |
| `sensor_temperature` | LIS2MDL |
Only `amd` (activity-motion-detect) lacks a SUID. `iio-sensor-proxy` has run
always-on from boot since 2026-07-20 via `blueline-sensors-enable.service`
(`After=blueline-hexagonrpcd-sdsp.service`), replacing the old on-demand
start/stop. PAF README: *"Proximity (TMD2725) and accelerometer both live."*
So the protocol's four evidence sources are all backed by real hardware that
already works. **There is nothing to bring up here.** The work is entirely
about who owns the evidence and who acts on it.
## The real shape of the problem: it is scattered into scripts
Each consumer is an independent standalone shell script in `/usr/bin`, owned
by no package, holding its own `monitor-sensor` claim and reaching its own
conclusion:
| script | sensor | acts on |
|---|---|---|
| `blueline-proximity-lock` | proximity | blanks panel when locked |
| `blueline-screen-toggle` | proximity | DT2W wake gate |
| `blueline-autorotate` | accelerometer | screen rotation |
These are not merely "unpackaged" (TASK-25) — they are **parallel
authorities over device state**, which is the thing
`SESSION-AUTHORITY-DOCTRINE.md` exists to forbid, and the same collision
called out for `org.freedesktop.secrets` vs gnome-keyring on 2026-07-24.
**They must not become "clients" of the state machine. The state machine
absorbs them.** Proximity-while-locked, the DT2W gate, and rotation are all
*device state reactions* — they are the machine's job by definition. A shell
script that independently decides to blank the panel is a second state
machine with no forensic log, no confidence model, and no coordination with
the first.
This is also why they must land together rather than one at a time: two of
them read the *same* proximity signal and can reach opposite conclusions, and
splitting the work leaves that contradiction in place for longer.
## Why this must precede TASK-08(a) / TASK-15
TASK-19's rule is that every control is a view over the owning service — no
success-shaped switches. A control over `observed_confidence` today would be
a view over a constant. Wiring actuators to a machine with no afferents
manufactures exactly the lie TASK-19 forbids: settings that *look* correct in
the UI and are inert.
**Sensors before actuators.** This is the precondition, not a parallel track.
## The evidence path silently dies — and nothing notices
Live incident, 2026-07-25 06:04:33 (this is not hypothetical):
kernel: qcom_q6v5_pas 5c00000.remoteproc: fatal error received:
err_qdi.c:456:EF:sensor_process:1:fatal_error.cc:22:CHRE
fatal@platform_sensor_manager.cc:158
remoteproc remoteproc2: crash detected in slpi / recovering slpi
remoteproc remoteproc2: remote processor slpi is now up
SLPI recovered. But `blueline-hexagonrpcd-sdsp.service` took
`Could not fetch next FastRPC message: Broken pipe` and
**"Deactivated successfully"** — systemd read a clean exit and never
restarted it. SLPI came back up; its HexagonFS daemon did not. Result:
iio-sensor-proxy: 'registry' sensor unavailable, is hexagonrpcd running?
HasAccelerometer: false HasAmbientLight: false HasProximity: false
**Every sensor on the device was dead for hours** and nothing reported it.
The scripts kept running against a proxy with nothing behind it — a standalone
script consuming a dead sensor looks identical to one whose sensor is simply
quiet.
Two consequences for this task:
1. **`blueline-hexagonrpcd-sdsp.service` needs a restart policy that survives
SLPI crash-recovery** (SLPI recovers itself; its filesystem daemon must
follow). That fix belongs in `Pixel3Arch/rootfs-overlay/`, **never only on
the device** — a fix that lives only on the phone is erased by the next
reprovision, which is the whole reason the pacman pipeline exists.
2. **Evidence-source health is itself device state.** The machine must know
its afferents are gone rather than quietly reporting steady state on
absent input. "No evidence" and "evidence says nothing is happening" are
different, and only one of them is safe to act on.
## Acceptance
- `observed_confidence` moves off 0.0 in response to a real physical event.
- `forensic_log` returns entries with `count > 0` after that event.
- Proximity-while-locked, the DT2W gate, and autorotate are all decided by
the state machine; no standalone script holds a `monitor-sensor` claim.
- `pacman -Qo` names a package for every surviving component.
- Sensor-stack death is visible in device state, not silent.
- No regression: locked-screen proximity blank, DT2W, and rotation all still
work.
## Connects to
TASK-08 (device state manager — this feeds its tiers), TASK-15 (idle
coordinator — same owner question), TASK-19 (why the ordering is not
negotiable), TASK-25 (the scripts are unowned, and the restart fix must live
in the overlay), `Pixel3Arch/PAF/slpi.md` (sensor island, SUID sweep, the
CHRE fatal history), and
`SouveraineOS/docs/SESSION-AUTHORITY-DOCTRINE.md`.