--- a/src/bin/souveraine-web.rs
+++ b/src/bin/souveraine-web.rs
@@ -35,8 +35,8 @@
 use tao::event::{Event, StartCause, WindowEvent};
 use tao::event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy};
 use tao::window::WindowBuilder;
-use wry::WebViewBuilder;
 use wry::http::Response;
+use wry::WebViewBuilder;
 
 /// What the shell can tell the face to do, and what it says back.
 ///
--- a/src/sessiond/device_state.rs
+++ b/src/sessiond/device_state.rs
@@ -1454,11 +1454,10 @@
     idle_since: Option<Instant>,
     /// The power verb already in flight, if any.
     ///
-    /// Held from admission until the mechanism returns. A second request is
-    /// refused rather than executed so that "poweroff, then reboot" cannot
-    /// leave the machine having asked for both. The latch is not sleep state:
-    /// a zero exit only says logind accepted the command, never that the
-    /// physical transition was observed.
+    /// Held because the machine cannot observe the outcome: the successful
+    /// case is the process ending. A second request is refused rather than
+    /// executed so that "poweroff, then reboot" cannot leave the machine
+    /// having asked for both.
     power_requested: Option<PowerVerb>,
     /// Per-source freshness, for the staleness rule.
     evidence_seen: EvidenceSeen,
@@ -2552,20 +2551,17 @@
         Ok(vec![Action::Power(verb)])
     }
 
-    /// Release the in-flight latch after the mechanism returned.
+    /// Release the in-flight latch after a power verb failed to happen.
     ///
-    /// This is deliberately symmetric across success and failure. `systemctl
-    /// suspend` and `hibernate` return to the same daemon after resume, while a
-    /// poweroff/reboot command can return zero before shutdown finishes or is
-    /// later cancelled. Leaving the latch set on any return would turn an
-    /// accepted request into a permanent refusal for the rest of the uptime.
-    /// A stale completion cannot clear a newer request for a different verb.
-    pub fn power_request_finished(&mut self, verb: PowerVerb) -> bool {
+    /// Only the failure path calls this. Success is the machine going down, so
+    /// there is nothing to clear and nobody left to clear it — but a refused
+    /// suspend (lid policy, a blocking inhibitor) returns to a running system,
+    /// and a latch left set there would refuse every later attempt for the rest
+    /// of the uptime.
+    pub fn power_request_failed(&mut self, verb: PowerVerb) {
         if self.power_requested == Some(verb) {
             self.power_requested = None;
-            return true;
         }
-        false
     }
 
     /// The executor reports the panel's real state. Turning on counts as
@@ -3240,10 +3236,6 @@
             "idle_secs": self.idle_secs(),
             "dimmed": self.dimmed,
             "blank_requested": self.blank_requested,
-            // Command admission, not physical state. Actual sleep/shutdown
-            // state is learned from logind events rather than inferred from a
-            // request or a successful systemctl exit.
-            "power_requested": self.power_requested.map(PowerVerb::as_str),
             // Freshness means "reported within the TTL", not "has ever been
             // heard from". The `is_some()` version read as fresh for the whole
             // life of the daemon, because `expire_stale_evidence` only clears
@@ -3536,42 +3528,6 @@
     }
 
     #[test]
-    fn a_power_request_is_latched_reported_and_refuses_a_second_verb() {
-        let mut sm = DeviceStateMachine::new();
-
-        assert_eq!(
-            sm.request_power(PowerVerb::Suspend, "test request")
-                .unwrap(),
-            vec![Action::Power(PowerVerb::Suspend)]
-        );
-        assert_eq!(sm.to_ipc_json()["power_requested"], "suspend");
-
-        let refusal = sm
-            .request_power(PowerVerb::Reboot, "racing request")
-            .unwrap_err();
-        assert_eq!(refusal, "suspend is already in flight");
-        assert_eq!(sm.to_ipc_json()["power_requested"], "suspend");
-    }
-
-    #[test]
-    fn only_the_matching_terminal_outcome_releases_a_power_request() {
-        let mut sm = DeviceStateMachine::new();
-        sm.request_power(PowerVerb::Hibernate, "test request")
-            .unwrap();
-
-        assert!(!sm.power_request_finished(PowerVerb::Poweroff));
-        assert_eq!(sm.to_ipc_json()["power_requested"], "hibernate");
-
-        assert!(sm.power_request_finished(PowerVerb::Hibernate));
-        assert_eq!(sm.to_ipc_json()["power_requested"], serde_json::Value::Null);
-        assert_eq!(
-            sm.request_power(PowerVerb::Poweroff, "retry after return")
-                .unwrap(),
-            vec![Action::Power(PowerVerb::Poweroff)]
-        );
-    }
-
-    #[test]
     fn a_three_finger_tap_on_the_wallpaper_raises_nothing() {
         // The no-window case, decided rather than discovered on device: a tap
         // with no subject is inert. The alternative is a sheet with nothing to
--- a/src/sessiond/protocol.rs
+++ b/src/sessiond/protocol.rs
@@ -64,9 +64,9 @@
     /// it. This is the one a chain most often wants: it means *not now*, and
     /// the state that forbade it is worth reading before deciding what next.
     RefusedByState,
-    /// The caller may not do this. Power policy issues it when login1 answers
-    /// `no`; capability tokens will eventually make it caller-specific across
-    /// the rest of the surface too.
+    /// The caller may not do this. Reserved — nothing issues it yet, because
+    /// caller identity is uid 1000 for everything (audit P3). It exists so
+    /// that when capability tokens land, callers already branch on it.
     NotPermitted,
     /// A dependency this op needs is absent — no compositor, no PAM stack, no
     /// sensor. Not the caller's fault and possibly transient.
@@ -259,11 +259,7 @@
         op: "power",
         mutates: true,
         summary: "power the machine off, restart it, or put it to sleep",
-        refuses: &[
-            RefusalCode::RefusedByState,
-            RefusalCode::NotPermitted,
-            RefusalCode::Unavailable,
-        ],
+        refuses: &[RefusalCode::RefusedByState, RefusalCode::Unavailable],
         example: r#"{"op":"power","verb":"poweroff"}"#,
     },
 ];
@@ -451,11 +447,11 @@
     /// blind actor on the one transition that cannot be undone or observed
     /// after the fact — no Action, no executor, no trail entry.
     ///
-    /// logind keeps what it already owns. It answers `CanPowerOff` and carries
-    /// out the verb; doctrine §4 says suspend goes through logind and never
-    /// `/sys/power/state`, and that is unchanged. What moves is the decision to
-    /// ask and the record of its outcome. Actual sleep state remains logind
-    /// evidence; this request does not claim that a transition happened.
+    /// logind keeps what it already owns. It answers `CanPowerOff` and it
+    /// carries out the verb; doctrine §4 says suspend goes through logind and
+    /// never `/sys/power/state`, and that is unchanged. What moves is the
+    /// decision to ask, so the machine that holds `Suspending` and `Asleep` is
+    /// the thing that says when to enter them.
     Power { verb: PowerVerb },
 }
 
@@ -735,47 +731,14 @@
 
         // And the other direction: every variant must be advertised. Bump this
         // deliberately when a verb is added, having added its VerbDoc.
-        // 20 since device power became a session-authority verb (2026-08-09).
+        // 19 since USB posture became a read plus a request (2026-08-07).
         assert_eq!(
             VERBS.len(),
-            20,
+            19,
             "a Request variant was added without a VerbDoc"
         );
     }
 
-    #[test]
-    fn every_power_verb_survives_the_wire_and_maps_to_its_mechanism() {
-        let cases = [
-            ("poweroff", PowerVerb::Poweroff, "CanPowerOff"),
-            ("reboot", PowerVerb::Reboot, "CanReboot"),
-            ("suspend", PowerVerb::Suspend, "CanSuspend"),
-            ("hibernate", PowerVerb::Hibernate, "CanHibernate"),
-        ];
-
-        for (wire, expected, capability) in cases {
-            let raw = format!(r#"{{"op":"power","verb":"{wire}"}}"#);
-            let request: Request = serde_json::from_str(&raw).unwrap();
-            assert!(matches!(&request, Request::Power { verb } if *verb == expected));
-            assert_eq!(expected.as_str(), wire);
-            assert_eq!(expected.as_systemctl(), wire);
-            assert_eq!(expected.logind_capability(), capability);
-            assert_eq!(serde_json::to_string(&request).unwrap(), raw);
-        }
-    }
-
-    #[test]
-    fn power_advertises_every_refusal_its_policy_can_make() {
-        let power = VERBS.iter().find(|verb| verb.op == "power").unwrap();
-        assert_eq!(
-            power.refuses,
-            &[
-                RefusalCode::RefusedByState,
-                RefusalCode::NotPermitted,
-                RefusalCode::Unavailable,
-            ]
-        );
-    }
-
     #[test]
     fn the_envelope_is_backward_compatible() {
         // Every line written before intent existed must still parse, or the
--- a/src/sessiond/server.rs
+++ b/src/sessiond/server.rs
@@ -25,8 +25,8 @@
 use crate::sessiond::lock::{self, LockController, Msg, SessionOutcome};
 use crate::sessiond::lockhint;
 use crate::sessiond::protocol::{
-    Envelope, InputTrigger, Phase, PowerVerb, RefusalCode, Request, SensorSource, SensorValue,
-    UsbMode, LOCKED_ACK_TIMEOUT_SECS, MAX_REQUEST_BYTES, VERBS,
+    Envelope, InputTrigger, Phase, RefusalCode, Request, SensorSource, SensorValue, UsbMode,
+    LOCKED_ACK_TIMEOUT_SECS, MAX_REQUEST_BYTES, VERBS,
 };
 
 /// How often the machine's clock runs. One second is fine: the shortest
@@ -294,6 +294,40 @@
         return;
     }
 
+    // Power is not a table row because success has no return path: the command
+    // that works takes the machine with it. Only the failure branch runs on a
+    // live system, and it has to clear the in-flight latch or a refused suspend
+    // would deafen the verb until the next boot.
+    if let Action::Power(verb) = action {
+        let label = match verb {
+            PowerVerb::Poweroff => "power-off",
+            PowerVerb::Reboot => "power-reboot",
+            PowerVerb::Suspend => "power-suspend",
+            PowerVerb::Hibernate => "power-hibernate",
+        };
+        match std::process::Command::new("systemctl")
+            .arg(verb.as_systemctl())
+            .status()
+        {
+            Ok(status) if status.success() => {}
+            Ok(status) => {
+                let code = status.code().unwrap_or(-1).to_string();
+                warn!("systemctl {} exited {code}", verb.as_systemctl());
+                let mut d = shared.lock();
+                d.device_state.record_error("device-state", label, &code);
+                d.device_state.power_request_failed(verb);
+            }
+            Err(e) => {
+                warn!("could not run systemctl {}: {e}", verb.as_systemctl());
+                let mut d = shared.lock();
+                d.device_state
+                    .record_error("device-state", label, &e.to_string());
+                d.device_state.power_request_failed(verb);
+            }
+        }
+        return;
+    }
+
     // Dim and restore carry a number, so they are not table entries. The
     // machine remembers the exact brightness the panel was at; the executor
     // reads the hardware and sets it back. Neither `brightnessctl -s/-r` nor
@@ -361,10 +395,7 @@
         // sessiond guarantees this runs once per dim, which is what the old
         // hypridle `-s`/`-r` listener could not: a second save while already
         // dim is what pinned brightness at 10/255.
-        // Percent, not an absolute. `set 10` is 10/255 on blueline and 10/2047
-        // on the iPhone 7's Apple DWI backlight, where it reads as fully off —
-        // measured 2026-08-09, brightness=1 with the panel still powered.
-        Action::Dim => ("brightnessctl", vec!["set", "4%"], "panel-dim"),
+        Action::Dim => ("brightnessctl", vec!["set", "10"], "panel-dim"),
         Action::Restore => unreachable!("handled above; the restore carries a value"),
         // The other direction, through the same executor.
         //
@@ -419,7 +450,7 @@
             "power-menu-open",
         ),
         Action::UsbMode(_) => unreachable!("handled above; expressed through usb-signaller"),
-        Action::Power(_) => unreachable!("power requests use the result-bearing power executor"),
+        Action::Power(_) => unreachable!("handled above; only its failure returns"),
         Action::Blank => {
             // The invariant, enforced where it cannot be reasoned around: the
             // panel does not go dark unless logind says this session is
@@ -928,221 +959,47 @@
     }
 }
 
-/// Every answer login1 documents for its `Can*` power methods.
+/// What logind says about a power verb: `yes`, `no`, `challenge`, or `na`.
 ///
-/// These are deliberately not flattened to a bool. `no` is a permission
-/// refusal, `na` is missing mechanism, and an inhibitor is current machine
-/// state; callers composing verbs need those to remain different answers.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum PowerCapability {
-    Yes,
-    No,
-    Challenge,
-    NotAvailable,
-    Inhibited,
-    InhibitorBlocked,
-    ChallengeInhibitorBlocked,
-}
-
-impl PowerCapability {
-    fn parse_busctl(text: &str) -> Result<Self> {
-        // busctl prints `s "challenge"`. Take the second field and strip the
-        // quotes here rather than in the shell — an earlier version parsed it
-        // behind two escaping layers, matched a backslash-quote busctl never
-        // emits, and left every capability reading "unknown" on the phone.
-        let answer = text
-            .split_whitespace()
-            .nth(1)
-            .unwrap_or_default()
-            .trim_matches('"');
-        match answer {
-            "yes" => Ok(Self::Yes),
-            "no" => Ok(Self::No),
-            "challenge" => Ok(Self::Challenge),
-            "na" => Ok(Self::NotAvailable),
-            "inhibited" => Ok(Self::Inhibited),
-            "inhibitor-blocked" => Ok(Self::InhibitorBlocked),
-            "challenge-inhibitor-blocked" => Ok(Self::ChallengeInhibitorBlocked),
-            _ => anyhow::bail!("unrecognised login1 power capability {answer:?}"),
-        }
-    }
-
-    fn as_str(self) -> &'static str {
-        match self {
-            Self::Yes => "yes",
-            Self::No => "no",
-            Self::Challenge => "challenge",
-            Self::NotAvailable => "na",
-            Self::Inhibited => "inhibited",
-            Self::InhibitorBlocked => "inhibitor-blocked",
-            Self::ChallengeInhibitorBlocked => "challenge-inhibitor-blocked",
-        }
-    }
-
-    fn refusal_code(self) -> Option<RefusalCode> {
-        match self {
-            Self::Yes | Self::Challenge => None,
-            Self::No => Some(RefusalCode::NotPermitted),
-            Self::NotAvailable => Some(RefusalCode::Unavailable),
-            Self::Inhibited | Self::InhibitorBlocked | Self::ChallengeInhibitorBlocked => {
-                Some(RefusalCode::RefusedByState)
-            }
-        }
-    }
-}
-
-/// Injectable boundary around the two process calls a power request needs.
-/// Unit tests use a fake implementation, so no test can invoke a real power
-/// mechanism even if it runs on a developer's live session.
-trait PowerBackend {
-    fn capability(&self, verb: PowerVerb) -> Result<PowerCapability>;
-    fn execute(&self, verb: PowerVerb) -> Result<()>;
-}
-
-struct SystemPowerBackend;
-
-impl PowerBackend for SystemPowerBackend {
-    fn capability(&self, verb: PowerVerb) -> Result<PowerCapability> {
-        let capability = verb.logind_capability();
-        let output = std::process::Command::new("busctl")
-            .args([
-                "--system",
-                "call",
-                "org.freedesktop.login1",
-                "/org/freedesktop/login1",
-                "org.freedesktop.login1.Manager",
-                capability,
-            ])
-            .output()
-            .with_context(|| format!("running busctl {capability}"))?;
-        if !output.status.success() {
-            anyhow::bail!(
-                "busctl {capability} exited {}",
-                output.status.code().unwrap_or(-1)
-            );
-        }
-        PowerCapability::parse_busctl(&String::from_utf8_lossy(&output.stdout))
-    }
-
-    fn execute(&self, verb: PowerVerb) -> Result<()> {
-        let status = std::process::Command::new("systemctl")
-            .arg(verb.as_systemctl())
-            .status()
-            .with_context(|| format!("running systemctl {}", verb.as_systemctl()))?;
-        if !status.success() {
-            anyhow::bail!(
-                "systemctl {} exited {}",
-                verb.as_systemctl(),
-                status.code().unwrap_or(-1)
-            );
-        }
-        Ok(())
+/// Asked live rather than probed once at startup. The answer moves with the
+/// machine — hibernate depends on swap that can be configured after boot, and
+/// `CanPowerOff` reflects inhibitors that come and go — so a cached value would
+/// be exactly the shadow copy doctrine §4 forbids.
+fn logind_can(capability: &str) -> Result<String> {
+    let output = std::process::Command::new("busctl")
+        .args([
+            "--system",
+            "call",
+            "org.freedesktop.login1",
+            "/org/freedesktop/login1",
+            "org.freedesktop.login1.Manager",
+            capability,
+        ])
+        .output()
+        .with_context(|| format!("running busctl {capability}"))?;
+    if !output.status.success() {
+        anyhow::bail!(
+            "busctl {capability} exited {}",
+            output.status.code().unwrap_or(-1)
+        );
     }
+    // busctl prints `s "challenge"`. Take the second field and strip the quotes
+    // here rather than in the shell — an earlier version of this parse lived in
+    // `sh` behind two escaping layers, matched a literal backslash-quote busctl
+    // never emits, and left every capability reading "unknown" on the phone.
+    let text = String::from_utf8_lossy(&output.stdout);
+    Ok(text
+        .split_whitespace()
+        .nth(1)
+        .unwrap_or_default()
+        .trim_matches('"')
+        .to_string())
 }
 
 fn refuse(code: RefusalCode, reason: &str) -> serde_json::Value {
     serde_json::json!({ "ok": false, "code": code.as_str(), "reason": reason })
 }
 
-fn power_label(verb: PowerVerb) -> &'static str {
-    match verb {
-        PowerVerb::Poweroff => "power-off",
-        PowerVerb::Reboot => "power-reboot",
-        PowerVerb::Suspend => "power-suspend",
-        PowerVerb::Hibernate => "power-hibernate",
-    }
-}
-
-/// Admit, gate, execute, and finish one power request.
-///
-/// The latch is taken before the live capability probe, so two callers cannot
-/// both pass policy and race different terminal actions. Every path after
-/// admission releases it. A zero exit is reported as `accepted`: it proves the
-/// mechanism returned success, not that shutdown or sleep was observed.
-fn handle_power_request<B: PowerBackend + ?Sized>(
-    shared: &Arc<Shared>,
-    verb: PowerVerb,
-    backend: &B,
-) -> serde_json::Value {
-    let actions = {
-        let mut d = shared.lock();
-        d.device_state
-            .request_power(verb, "power requested through the session authority")
-    };
-    let action_verb = match actions {
-        Ok(actions) if actions == vec![Action::Power(verb)] => verb,
-        Ok(actions) => {
-            let reason = format!("power admission returned unexpected actions: {actions:?}");
-            let mut d = shared.lock();
-            d.device_state.power_request_finished(verb);
-            d.device_state
-                .record_error("device-state", power_label(verb), &reason);
-            return refuse(RefusalCode::Unavailable, &reason);
-        }
-        Err(reason) => return refuse(RefusalCode::RefusedByState, &reason),
-    };
-
-    let capability = match backend.capability(action_verb) {
-        Ok(capability) => capability,
-        Err(error) => {
-            let reason = format!(
-                "could not ask logind about {}: {error:#}",
-                action_verb.as_str()
-            );
-            let mut d = shared.lock();
-            d.device_state.power_request_finished(action_verb);
-            d.device_state
-                .record_error("device-state", "power-capability", &reason);
-            return refuse(RefusalCode::Unavailable, &reason);
-        }
-    };
-
-    if let Some(code) = capability.refusal_code() {
-        let reason = format!(
-            "logind says {}: {}",
-            action_verb.logind_capability(),
-            capability.as_str()
-        );
-        let mut d = shared.lock();
-        d.device_state.power_request_finished(action_verb);
-        d.device_state.record_decision(
-            "power-request-refused",
-            serde_json::json!({
-                "verb": action_verb.as_str(),
-                "capability": capability.as_str(),
-            }),
-            &reason,
-        );
-        return refuse(code, &reason);
-    }
-
-    match backend.execute(action_verb) {
-        Ok(()) => {
-            let mut d = shared.lock();
-            d.device_state.power_request_finished(action_verb);
-            d.device_state.record_decision(
-                "power-command-accepted",
-                serde_json::json!({ "verb": action_verb.as_str() }),
-                "the power mechanism returned success; physical state is not inferred",
-            );
-            serde_json::json!({
-                "ok": true,
-                "verb": action_verb.as_str(),
-                "status": "accepted",
-            })
-        }
-        Err(error) => {
-            let reason = error.to_string();
-            warn!("power command {} failed: {reason}", action_verb.as_str());
-            let mut d = shared.lock();
-            d.device_state.power_request_finished(action_verb);
-            d.device_state
-                .record_error("device-state", power_label(action_verb), &reason);
-            refuse(RefusalCode::Unavailable, &reason)
-        }
-    }
-}
-
 fn respond(writer: &mut UnixStream, value: serde_json::Value) -> std::io::Result<()> {
     writer.write_all(value.to_string().as_bytes())?;
     writer.write_all(b"\n")?;
@@ -1697,7 +1554,50 @@
                 ),
             }
         }
-        Request::Power { verb } => handle_power_request(shared, verb, &SystemPowerBackend),
+        Request::Power { verb } => {
+            // logind owns the policy and always has (doctrine §4). Ask it, and
+            // refuse honestly rather than firing a verb the machine cannot
+            // honor — a hibernate with no swap that silently does nothing is
+            // the worst outcome, because the caller believes it worked.
+            // "challenge" is a yes that may prompt polkit.
+            match logind_can(verb.logind_capability()) {
+                Ok(answer) if answer == "yes" || answer == "challenge" => {}
+                Ok(answer) => {
+                    return refuse(
+                        RefusalCode::Unavailable,
+                        &format!("logind says {}: {answer}", verb.logind_capability()),
+                    );
+                }
+                Err(error) => {
+                    return refuse(
+                        RefusalCode::Unavailable,
+                        &format!("could not ask logind about {}: {error:#}", verb.as_str()),
+                    );
+                }
+            }
+            let actions = {
+                let mut d = shared.lock();
+                d.device_state
+                    .request_power(verb, "power requested through the session authority")
+            };
+            match actions {
+                Ok(actions) => {
+                    for action in actions {
+                        execute(shared, action);
+                    }
+                    // Reached only if the verb did not take the machine down.
+                    // Saying "started" here would be the report claiming an
+                    // outcome the executor just recorded as a failure.
+                    let d = shared.lock();
+                    serde_json::json!({
+                        "ok": true,
+                        "verb": verb.as_str(),
+                        "state": d.device_state.state().as_str(),
+                    })
+                }
+                Err(reason) => refuse(RefusalCode::RefusedByState, &reason),
+            }
+        }
         Request::Bearer => {
             let d = shared.lock();
             let b = &d.device_state.bearer;
@@ -1884,7 +1784,6 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use std::cell::Cell;
 
     fn idle_shared() -> Arc<Shared> {
         Arc::new(Shared {
@@ -1903,160 +1802,6 @@
         })
     }
 
-    struct FakePowerBackend {
-        capability: std::result::Result<PowerCapability, &'static str>,
-        execution: std::result::Result<(), &'static str>,
-        capability_calls: Cell<usize>,
-        execution_calls: Cell<usize>,
-        inspect_latch: Option<(Arc<Shared>, PowerVerb)>,
-        saw_latch_before_probe: Cell<bool>,
-    }
-
-    impl FakePowerBackend {
-        fn new(
-            capability: std::result::Result<PowerCapability, &'static str>,
-            execution: std::result::Result<(), &'static str>,
-        ) -> Self {
-            Self {
-                capability,
-                execution,
-                capability_calls: Cell::new(0),
-                execution_calls: Cell::new(0),
-                inspect_latch: None,
-                saw_latch_before_probe: Cell::new(false),
-            }
-        }
-
-        fn inspecting(mut self, shared: &Arc<Shared>, verb: PowerVerb) -> Self {
-            self.inspect_latch = Some((Arc::clone(shared), verb));
-            self
-        }
-    }
-
-    impl PowerBackend for FakePowerBackend {
-        fn capability(&self, _verb: PowerVerb) -> Result<PowerCapability> {
-            self.capability_calls.set(self.capability_calls.get() + 1);
-            if let Some((shared, expected)) = &self.inspect_latch {
-                let value = shared.lock().device_state.to_ipc_json()["power_requested"].clone();
-                self.saw_latch_before_probe
-                    .set(value == serde_json::json!(expected.as_str()));
-            }
-            self.capability.map_err(|reason| anyhow::anyhow!(reason))
-        }
-
-        fn execute(&self, _verb: PowerVerb) -> Result<()> {
-            self.execution_calls.set(self.execution_calls.get() + 1);
-            self.execution.map_err(|reason| anyhow::anyhow!(reason))
-        }
-    }
-
-    #[test]
-    fn login1_power_capability_parser_names_every_documented_answer() {
-        let cases = [
-            ("yes", PowerCapability::Yes),
-            ("no", PowerCapability::No),
-            ("challenge", PowerCapability::Challenge),
-            ("na", PowerCapability::NotAvailable),
-            ("inhibited", PowerCapability::Inhibited),
-            ("inhibitor-blocked", PowerCapability::InhibitorBlocked),
-            (
-                "challenge-inhibitor-blocked",
-                PowerCapability::ChallengeInhibitorBlocked,
-            ),
-        ];
-
-        for (wire, expected) in cases {
-            assert_eq!(
-                PowerCapability::parse_busctl(&format!("s \"{wire}\"\n")).unwrap(),
-                expected
-            );
-            assert_eq!(expected.as_str(), wire);
-        }
-        assert!(PowerCapability::parse_busctl("").is_err());
-        assert!(PowerCapability::parse_busctl("s \"future-answer\"").is_err());
-    }
-
-    #[test]
-    fn yes_and_challenge_execute_after_the_latch_is_taken() {
-        for capability in [PowerCapability::Yes, PowerCapability::Challenge] {
-            let shared = idle_shared();
-            let backend = FakePowerBackend::new(Ok(capability), Ok(()))
-                .inspecting(&shared, PowerVerb::Suspend);
-
-            let reply = handle_power_request(&shared, PowerVerb::Suspend, &backend);
-
-            assert_eq!(reply["ok"], true);
-            assert_eq!(reply["status"], "accepted");
-            assert_eq!(reply["verb"], "suspend");
-            assert!(
-                reply.get("state").is_none(),
-                "request must not claim sleep state"
-            );
-            assert!(backend.saw_latch_before_probe.get());
-            assert_eq!(backend.capability_calls.get(), 1);
-            assert_eq!(backend.execution_calls.get(), 1);
-            assert_eq!(
-                shared.lock().device_state.to_ipc_json()["power_requested"],
-                serde_json::Value::Null
-            );
-        }
-    }
-
-    #[test]
-    fn capability_refusals_keep_permission_state_and_availability_distinct() {
-        let cases = [
-            (PowerCapability::No, "not_permitted"),
-            (PowerCapability::NotAvailable, "unavailable"),
-            (PowerCapability::Inhibited, "refused_by_state"),
-            (PowerCapability::InhibitorBlocked, "refused_by_state"),
-            (
-                PowerCapability::ChallengeInhibitorBlocked,
-                "refused_by_state",
-            ),
-        ];
-
-        for (capability, expected_code) in cases {
-            let shared = idle_shared();
-            let backend = FakePowerBackend::new(Ok(capability), Ok(()));
-
-            let reply = handle_power_request(&shared, PowerVerb::Poweroff, &backend);
-
-            assert_eq!(reply["ok"], false);
-            assert_eq!(reply["code"], expected_code);
-            assert_eq!(backend.capability_calls.get(), 1);
-            assert_eq!(backend.execution_calls.get(), 0);
-            assert_eq!(
-                shared.lock().device_state.to_ipc_json()["power_requested"],
-                serde_json::Value::Null
-            );
-        }
-    }
-
-    #[test]
-    fn probe_and_command_errors_are_honest_and_release_the_latch_for_retry() {
-        let shared = idle_shared();
-        let probe_failure = FakePowerBackend::new(Err("busctl unavailable"), Ok(()));
-        let reply = handle_power_request(&shared, PowerVerb::Reboot, &probe_failure);
-        assert_eq!(reply["ok"], false);
-        assert_eq!(reply["code"], "unavailable");
-        assert_eq!(probe_failure.execution_calls.get(), 0);
-
-        let command_failure =
-            FakePowerBackend::new(Ok(PowerCapability::Yes), Err("systemctl reboot exited 1"));
-        let reply = handle_power_request(&shared, PowerVerb::Reboot, &command_failure);
-        assert_eq!(reply["ok"], false);
-        assert_eq!(reply["code"], "unavailable");
-        assert_eq!(command_failure.execution_calls.get(), 1);
-
-        let retry = FakePowerBackend::new(Ok(PowerCapability::Yes), Ok(()));
-        let reply = handle_power_request(&shared, PowerVerb::Reboot, &retry);
-        assert_eq!(
-            reply["ok"], true,
-            "both terminal errors must release admission"
-        );
-        assert_eq!(reply["status"], "accepted");
-    }
-
     #[test]
     fn second_shell_ready_cannot_steal_authority_lease() {
         let shared = idle_shared();
--- a/surfaces/quickshell/deploy.sh
+++ b/surfaces/quickshell/deploy.sh
@@ -25,8 +25,6 @@
 set -euo pipefail
 
 SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-REPO_ROOT="$(cd "$SRC/../.." && pwd)"
-FACE_SRC="$REPO_ROOT/assets/face"
 QS="${HOME}/.config/quickshell"
 II="${QS}/ii"
 SV="${QS}/souveraine"
@@ -63,8 +61,6 @@
 modules/souveraine/windowSheet/PowerOptionRow.qml souveraine/modules/souveraine/windowSheet/PowerOptionRow.qml
 modules/souveraine/windowSheet/qmldir  souveraine/modules/souveraine/windowSheet/qmldir
 services/Face.qml            souveraine/services/Face.qml
-services/Lens.qml            souveraine/services/Lens.qml
-services/FingerprintPreview.qml souveraine/services/FingerprintPreview.qml
 services/ViewtopControl.qml  souveraine/services/ViewtopControl.qml
 services/ZoneTransition.qml  souveraine/services/ZoneTransition.qml
 services/Hyprsunset.qml      souveraine/services/Hyprsunset.qml
@@ -94,8 +90,6 @@
 modules/ii/sidebarRight/SidebarRight.qml  souveraine/modules/ii/sidebarRight/SidebarRight.qml
 modules/ii/sidebarRight/SidebarRightContent.qml souveraine/modules/ii/sidebarRight/SidebarRightContent.qml
 modules/ii/sidebarRight/QuickSliders.qml  souveraine/modules/ii/sidebarRight/QuickSliders.qml
-modules/ii/sidebarRight/CenterWidgetGroup.qml souveraine/modules/ii/sidebarRight/CenterWidgetGroup.qml
-modules/ii/sidebarRight/lens/LensWidget.qml souveraine/modules/ii/sidebarRight/lens/LensWidget.qml
 modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml souveraine/modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml
 modules/ii/bar/UtilButtons.qml souveraine/modules/ii/bar/UtilButtons.qml
 modules/common/Config.qml    souveraine/modules/common/Config.qml
@@ -118,7 +112,6 @@
 modules/settings/IdleConfig.qml     souveraine/modules/settings/IdleConfig.qml
 modules/settings/SpeechConfig.qml   souveraine/modules/settings/SpeechConfig.qml
 modules/ii/polkit/Polkit.qml       souveraine/modules/ii/polkit/Polkit.qml
-modules/ii/polkit/PolkitContent.qml souveraine/modules/ii/polkit/PolkitContent.qml
 modules/ii/dock/Dock.qml           souveraine/modules/ii/dock/Dock.qml
 modules/ii/dock/DockManifest.qml   souveraine/modules/ii/dock/DockManifest.qml
 modules/ii/dock/DockApps.qml       souveraine/modules/ii/dock/DockApps.qml
@@ -309,20 +302,6 @@
         echo "  → if any of that is work you want, copy it back into the repo now." >&2
     fi
 
-    # The face host reads its page and rig from ~/.souveraine/face, outside
-    # the composed QML tree. Stage that tracked limb before the QML switch so
-    # a newly-added control cannot arrive without the page that implements it.
-    # Preserve the prior phone copy first; this is the daily driver and the
-    # destination has no git history of its own.
-    [[ -f "$FACE_SRC/index.html" && -d "$FACE_SRC/live2d" ]] || {
-        echo "ERROR: tracked face assets are incomplete at $FACE_SRC" >&2
-        exit 1
-    }
-    "${ssh_i[@]}" "$PHONE_USB" \
-        "mkdir -p ~/.souveraine/.face-previous ~/.souveraine/face; rsync -a --delete ~/.souveraine/face/ ~/.souveraine/.face-previous/"
-    rsync -ac -e "ssh -F /dev/null -i $HOME/.ssh/ani" \
-        "$FACE_SRC/" "$PHONE_USB:.souveraine/face/"
-
     # Checksum, not timestamp. Plain -a reports files that differ only in mtime
     # from earlier hand copies, which lies about what is actually changing.
     rsync -ac -e "ssh -F /dev/null -i $HOME/.ssh/ani" "$SRC/" "$PHONE_USB:$PHONE_DEST/"
@@ -539,6 +518,4 @@
 if grep -q 'qsConfig", "ii"' "$HOME/.config/hypr/hyprland/variables.lua" 2>/dev/null; then
     echo "NOTE: hyprland qsConfig is still 'ii' — flip variables.lua to 'souveraine' to switch."
 fi
-"$REPO_ROOT/tools/stage-face.sh" >/dev/null
-echo "face assets staged at $HOME/.souveraine/face"
 echo "Run with: qs -c souveraine   (restart: pkill -f 'qs -c souveraine')"
--- a/surfaces/quickshell/services/Face.qml
+++ b/surfaces/quickshell/services/Face.qml
@@ -136,17 +136,8 @@
                     return;
                 }
                 // Anything the page wants to say goes through the one transport.
-                if (msg.event === "said" && msg.text) {
-                    const result = Souveraine.send(msg.text);
-                    const accepted = result === true;
-                    const reason = result === "step-up"
-                        ? "Authentication is required before sending"
-                        : accepted ? "" : "The agent is unavailable or already answering";
-                    root._eval(`window.hands && window.hands.agentResult(${JSON.stringify({
-                        accepted: accepted,
-                        reason: reason
-                    })})`);
-                }
+                if (msg.event === "said" && msg.text)
+                    Souveraine.send(msg.text);
                 else if (msg.event === "tapped")
                     root.tapped(msg.area ?? "body");
                 else if (msg.event === "talk")
@@ -185,14 +176,9 @@
         case "key":
             HidController.key(message.key ?? "", message.modifiers ?? "");
             break;
-        case "type": {
-            const accepted = HidController.sendText(message.text ?? "");
-            root._eval(`window.hands && window.hands.hostResult(${JSON.stringify({
-                accepted: accepted,
-                reason: accepted ? "" : HidController.lastError
-            })})`);
+        case "type":
+            HidController.sendText(message.text ?? "");
             break;
-        }
         case "arm":
             HidController.arm();
             break;
@@ -357,6 +343,10 @@
             root.join();
         }
 
+        function joinHands(): void {
+            root.joinHands();
+        }
+
         function leave(): void {
             root.leave();
         }
--- a/surfaces/quickshell/services/HidController.qml
+++ b/surfaces/quickshell/services/HidController.qml
@@ -24,7 +24,6 @@
     property bool active: false
     property bool ready: false
     property string lastError: ""
-    property bool _stopping: false
 
     readonly property bool modeReady: UsbState.mode === "hid" || UsbState.mode === "kvm"
     readonly property bool permitted: root.active && !GlobalStates.screenLockSecure
@@ -61,8 +60,12 @@
     }
 
     function close() {
-        root._stopInjector();
+        if (root.ready) {
+            root._flushPointer();
+            injector.write("release\n");
+        }
         root.active = false;
+        root.ready = false;
         root._pendingX = 0;
         root._pendingY = 0;
         root._pendingWheel = 0;
@@ -71,18 +74,6 @@
         root.controllerChanged();
     }
 
-    function _stopInjector() {
-        if (root.ready) {
-            root._flushPointer();
-            injector.write("release\n");
-        }
-        root.ready = false;
-        if (injector.running) {
-            root._stopping = true;
-            injector.running = false;
-        }
-    }
-
     function arm() {
         if (!root.active) {
             root.lastError = "USB Hands is not joined";
@@ -100,6 +91,13 @@
         return true;
     }
 
+    function retry() {
+        root.lastError = "";
+        if (injector.running)
+            injector.running = false;
+        root._reconcile();
+    }
+
     function _reconcile() {
         const wanted = root.permitted && root.modeReady;
         if (!wanted) {
@@ -134,18 +132,7 @@
     }
 
     function sendText(value): bool {
-        const text = String(value ?? "");
-        // Mirror the helper's boot-keyboard map before accepting the page's
-        // field. The helper still performs the authoritative full preflight,
-        // but this keeps rejected Unicode on the glass instead of clearing a
-        // field whose first report was never written.
-        if (/[^\x09\x0a\x0d\x20-\x7e]/.test(text)) {
-            root.lastError = "Host typing currently accepts ASCII keyboard characters only";
-            root.refused(root.lastError);
-            root.controllerChanged();
-            return false;
-        }
-        const lines = text.replace(/\r\n/g, "\n").split("\n");
+        const lines = String(value ?? "").replace(/\r\n/g, "\n").split("\n");
         if (lines.length === 1 && lines[0].length === 0)
             return false;
         for (let i = 0; i < lines.length; i++) {
@@ -229,8 +216,7 @@
         stdout: SplitParser {
             splitMarker: "\n"
             onRead: line => {
-                const event = line.trim();
-                if (event !== "ready" && event !== "ok")
+                if (line.trim() !== "ready")
                     return;
                 root.ready = true;
                 root.lastError = "";
@@ -249,13 +235,10 @@
             }
         }
 
-        onExited: exitCode => {
+        onExited: (exitCode, exitStatus) => {
             root.ready = false;
-            if (root._stopping) {
-                root._stopping = false;
-            } else if (root.permitted && root.modeReady && root.lastError.length === 0) {
+            if (root.permitted && root.modeReady && root.lastError.length === 0)
                 root.lastError = "HID bridge exited (" + exitCode + ")";
-            }
             root.controllerChanged();
         }
     }
@@ -263,15 +246,6 @@
     Connections {
         target: UsbState
 
-        // setMode() raises busy before it writes to sessiond. Close both HID
-        // endpoint fds on that edge, before usb-signaller tears their configfs
-        // functions down; a failed switch restarts the helper against the
-        // still-live old mode in onChangeFailed below.
-        function onBusyChanged() {
-            if (UsbState.busy)
-                root._stopInjector();
-        }
-
         function onRefreshed() {
             root._reconcile();
             root.controllerChanged();
@@ -279,7 +253,6 @@
 
         function onChangeFailed(reason) {
             root.lastError = reason;
-            root._reconcile();
             root.controllerChanged();
         }
     }
@@ -312,23 +285,23 @@
         }
 
         function sendText(text: string): string {
-            return root.sendText(text) ? "queued" : root._notReadyReason();
+            return root.sendText(text) ? "sent" : root._notReadyReason();
         }
 
         function key(keyName: string, modifiers: string): string {
-            return root.key(keyName, modifiers) ? "queued" : root._notReadyReason();
+            return root.key(keyName, modifiers) ? "sent" : root._notReadyReason();
         }
 
         function tap(keyName: string): string {
-            return root.key(keyName) ? "queued" : root._notReadyReason();
+            return root.key(keyName) ? "sent" : root._notReadyReason();
         }
 
         function click(button: string): string {
-            return root.click(button) ? "queued" : root._notReadyReason();
+            return root.click(button) ? "sent" : root._notReadyReason();
         }
 
         function pointer(x: int, y: int, wheel: int): string {
-            return root.movePointer(x, y, wheel) ? "queued" : root._notReadyReason();
+            return root.movePointer(x, y, wheel) ? "sent" : root._notReadyReason();
         }
     }
 }
--- a/surfaces/quickshell/services/Souveraine.qml
+++ b/surfaces/quickshell/services/Souveraine.qml
@@ -378,7 +378,6 @@
     function send(text) {
         if (!root.serverUp || root.currentAgentId.length === 0) return false;
         if (text.length === 0) return false;
-        if (root.turnActive) return false;
         // Step-up gate: if enabled and no valid send grant exists, block
         // the send and emit a signal so the UI can trigger auth + retry.
         // Break-glass grants bypass normal step-up — they are one-time,
