Watch
1
0
Fork
You've already forked SouveraineOS
0

state: charge is a sensor source, and the laptop is moving to viewtop

The r506 build had ChargeEvidence reading sysfs from sessiond's clock with
conclusion() inside the driver type — the rule violated four times in one
object. Recorded here: the ruling (§4), the task reconciliation, and the
bearer audit under the same rule. Also the corrected cutover answer: the
laptop is the test bed, the chooser is phone-shaped, mechanism undecided.
This commit is contained in:
Fimeg 2026-08-15 11:45:28 -04:00
commit 3cdd36ff2f
3 changed files with 91 additions and 12 deletions

View file

@ -18,8 +18,44 @@ stale the same way for the same reason. The packages are now cured
archive, so `pacman -Sl souveraine-aarch64` is the manifest. The surface gap
(a souveraine overlay host for the subconscious views) is still open.
Last updated: 2026-08-09 (the fingerprint TA's command protocol is recovered;
see below and `docs/DUMP-fingerprint-2026-08-09.md`).
Last updated: 2026-08-15 (the charge lane and the machined handoff; see
below).
## 2026-08-15 — charge becomes a sensor source; machined is handed over
Two lanes:
**Laptop → viewtop is real, and recorded.** The earlier "no laptop cutover
scheduled" answer was wrong; Casey corrected it and the plan is now in
STATE as three commits (`a46d9cb`, `6d19ce5`, `b45d776`): the laptop moves
to viewtop as the genuine test bed, via a login-time session choice (viewtop
| hyprland). The chooser must be **phone-shaped** (touch-first, thumb-sized);
mechanism undecided — SDDM session choice is the fallback if nothing
phone-shaped exists, but the search should start phone-shaped, not at SDDM.
**Charge evidence moved into the sensor enum, structurally.** The r506
build had `ChargeEvidence` — a sysfs-reading, conclusion-computing struct
probed by sessiond itself on the clock. The review found it violating the
machine's own rule four times (side door `note_charge`, the authority
probing, the driver interpreting, nothing leaving `tick()`), and its
justifying comment cited `bearer`, another instance of the same divergence.
The correction is committed in r507: `SensorSource::Charge` +
`SensorValue::Charge` on the wire, reported by `souveraine-sensord`
(30-second change-driven poll; the 5-second sysfs probe is gone from
sessiond's clock), entered through `sensor_input` like every other source,
with `EvidenceSeen`/`SourceHealth`/last-seen from the gate for free and
`conclude_charge()` on the machine as its one decision. CI and PKGBUILD now
ship sensord on x86_64 too — the laptop has a battery, and a machine without
the reporter has no charge evidence at all. Ruling and bearer audit:
`docs/DEVICE-STATE-MACHINE.md` §4.
**Machined.** Annie's handoff: machined's packaged unit was fixed
(`/usr/lib` ExecStart on both devices; backup at
`/var/backups/souveraine-machined.service.20260815`; the phone's backup is
gone). Neither device has restarted machined onto the packaged unit yet —
that restart is deliberate here, the signer handoff. `scratchpad/
HANDOFF-open-questions.md` (the "4/6" list) was not found on laptop, phone,
or vanguard; its contents arrived pasted in-message instead.
## 2026-08-09 — fingerprint: the protocol is recovered

View file

@ -372,6 +372,43 @@ authority.
- Serve as a factor in authentication
- Override a manual lock (user pressed power button to lock)
### Charge is evidence, and the reporter never interprets (settled 2026-08-15)
Charging entered the machine as `ChargeEvidence` — a struct that read sysfs
*and* computed `conclusion()`, probed by sessiond itself on the clock
(TASK-33 §2's first build, r506). The review found it against the rule this
machine lives by, four times in one type:
1. **It never became a `SensorSource`.** It entered through `note_charge`, a
side door, so it got none of the gate: no `EvidenceSeen`, no
`SourceHealth`, no last-seen, no `Absent`-vs-`Down`. §10's gate only gates
what routes through it.
2. **The authority probed.** sessiond reached out and read
`/sys/class/power_supply` on a 5-second clock. The decider became a
driver; the afferent nerve has one job, and it is not deciding.
3. **The driver interpreted.** `conclusion()` lived on the type that read
sysfs. Belief's one load-bearing rule — interpretation may consume
evidence but never a driver — was broken inside a single object.
4. **Nothing left `tick()`.** No `Action`, no executor table, just a trail
line and JSON on the wire. §12's shape, absent.
And the comment justified it by citing `bearer` — another instance of the
same divergence, not doctrine. The disease had already propagated once and
was on its way to becoming precedent.
**The ruling:** charge is a sensor source like any other. `SensorSource::Charge`
+ `SensorValue::Charge` on the wire; the reporter reads the supplies and the
machine interprets; source health, freshness, last-seen and `Absent`/`Down`
are free because they are the gate. `conclusion()` lives on the machine, as
the machine's one decision, and the driver type is gone.
**Audit of bearer under the same rule:** bearer is the same shape — a probe
run by the authority on the clock, with `preferred()`/`tunnel_underlay()`
interpretation inside the driver type. Its actions *do* leave `tick()`
(§12's shape is present), which is the one difference from charge. The same
correction applies: the probe moves to the reporter, the interpretation to
the machine. That is a follow-up, not a debate.
---
## 5. Error and audit contract

View file

@ -1,7 +1,9 @@
# TASK 33 — Battery and charging belong to the device state machine
**Status:** open, raised 2026-07-26. **Size:** one session for (1), one for
(2); (3) is a policy decision before it is code.
**Status:** (2) shape landed 2026-08-15 — charge is `SensorSource::Charge`,
reported by `souveraine-sensord`, interpreted by the machine
(`conclude_charge`, one decision). (1) and (3) remain open. **Size:** one
session for (1), one for (2); (3) is a policy decision before it is code.
**Repos:** `~/Projects/souveraine` (`packaging/upower-souveraine`,
`surfaces/quickshell`, `src/sessiond`).
@ -67,14 +69,18 @@ still going straight to the glass.
upstream already defines, finally reporting the truth on this device.
Write path needs a polkit action; the shell is the agent for it.
2. **Charging as evidence, not as a display feed.** `device_state` already
carries sensor evidence and health (`§10`). Charging state belongs
there: plugged/unplugged, charge type, whether the charger is resting or
working, and — the part no surface can currently derive — *what the
machine concludes*, so "Charged", "Charging slowly", and "the cable is in
but nothing is happening and that is now unusual" are one decision made
once rather than three surfaces guessing. `sensors_degraded` (TASK-08 f)
is the precedent for the shape.
2. **Charging as evidence, not as a display feed.** Landed 2026-08-15. The
first build (`ChargeEvidence` reading sysfs from sessiond's clock, with
`conclusion()` inside the driver type) was reviewed out: the decider must
not probe, and a driver must not interpret. Charge is a sensor source like
any other — `SensorSource::Charge` enters through `sensor_input`, gets
`EvidenceSeen`/`SourceHealth`/last-seen from the gate for free, and the
machine's `conclude_charge()` makes the one decision ("Charged",
"Charging slowly", "the cable is in but nothing is happening and that is
now unusual") once. `souveraine-sensord` reports it on a 30-second poll,
change-driven; the 5-second sysfs probe on sessiond's clock is gone.
`DEVICE-STATE-MACHINE.md` §4 carries the full ruling, including the bearer
audit (same shape, same correction owed).
3. **A charge policy, and who is allowed to set it.** Casey's framing: the
agent might one day decide to let the pack run to 30% first, or hold it