tasks: log 07-21 findings (culver A/B/D/E, mic wedge, overview, keyboard); add 19-23
Records what the 2026-07-21/22 sessions actually found and shipped, so the ledger matches reality: - TASK-16: A, B, D landed; C (contact card) implemented, phone acceptance pending; new unit E (history-fill boot amnesia) done. - TASK-08: shell-side state projection exists; add the maintenance- lease requirement so a deploy can never race the idle lock again (root cause of the 19:29 auto-lock-during-deploy crash). - TASK-09: stale-lock incident — panel/IRQ alive, session-lock routing stale; capture both in the resume test. - TASK-14: expand to the Auxo-style running-app surface and an unconditional Home tap; folds in the GLES OpacityMask and workspace-ratchet findings. - TASK-17: pin the iOS-like keyboard target and the Hyprland key-safety hammer test. - Mic trace path corrected to its new home. New: TASK-19 (settings control center), TASK-20 (player video + agent control), TASK-21 (reboot-to-Android confirmation), TASK-22 (settings/fullscreen tweaks), TASK-23 (culver locked-notification nudge).
This commit is contained in:
parent
931e794701
commit
adce4441cc
12 changed files with 406 additions and 19 deletions
|
|
@ -84,7 +84,7 @@ No -110/NACK storm in dmesg across repeated open/close.
|
|||
The bus-wedge diagnosis that got us here: every TX-path setup write
|
||||
succeeded; the bus died on the first *read* after arming TX7/TX8
|
||||
(`0x801` poll → 1.046 s timeout → NGD `TX_NACKED_2` forever). Full
|
||||
trace: `linux-blueline-mic-order/MIC-WEDGE-TRACE-20260717.md`. Dead
|
||||
trace: `linux-blueline-current/notes/MIC-WEDGE-TRACE-20260717.md`. Dead
|
||||
ends already falsified — do not re-derive: 0x0c96 was innocent; codec
|
||||
regs match Android ground truth bit-for-bit; q6afe cdc_codec_config
|
||||
already fires (ret=0); AFE_SLIMBUS_SLAVE_PORT_CONFIG is SLIMBUS_5_TX
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# TASK 08 — Device state manager / power profiles
|
||||
|
||||
**Status:** open. The "session state manager we dance around." Largest
|
||||
**Status:** in progress. The shell-side state projection and reason-tracked
|
||||
inhibitors exist; the durable manager and device tiers remain open. Largest
|
||||
of the tasks; sub-divide before starting.
|
||||
|
||||
## Goal
|
||||
|
|
@ -29,6 +30,11 @@ Wants (from handoff doc item 12):
|
|||
toggle to fork — build fresh.
|
||||
- **(d) Wifi handoff gating.** Radio transitions belong to the same
|
||||
state model, not ad-hoc.
|
||||
- **(e) Bounded maintenance/update leases.** A deploy or system update may
|
||||
inhibit *automatic* idle lock while it mutates live session components,
|
||||
but never bypass an existing lock or disable manual lock. The lease has an
|
||||
owner/reason/deadline, survives a shell reload, expires on deploy failure,
|
||||
disconnect or timeout, and restores the exact prior idle state.
|
||||
|
||||
## Context
|
||||
|
||||
|
|
@ -38,6 +44,16 @@ Wants (from handoff doc item 12):
|
|||
(inhibit checked INSIDE handlers, monitor objects never destroyed).
|
||||
- hypridle is the redundant fallback (300s lock, 600s screen-off, suspend
|
||||
DISABLED per TASK-09 interim).
|
||||
- `Session.qml` already implements `state()`, reason-tracked `inhibit()` /
|
||||
`uninhibit()`, and the `Idle.inhibit` projection. A 2026-07-21 audit found
|
||||
that no `IpcHandler` actually exposed those methods despite comments saying
|
||||
it did; a worktree fix adds the missing local `session` IPC seam.
|
||||
- **Measured maintenance failure (2026-07-21 19:29):** the phone auto-locked
|
||||
during a live shell deploy. Quickshell reloaded while the compositor lock
|
||||
was secure, hit `FATAL: Tried to show lockscreen surfaces without active
|
||||
lock`, crashed, and sessiond correctly fail-closed. Repeated shell owners
|
||||
then contended for notifications/polkit until cleanup. A deploy must never
|
||||
race the idle lock again.
|
||||
- The conclusions want to land in `power-profiles-daemon` as the hint layer.
|
||||
|
||||
## Sub-tasks (do separately)
|
||||
|
|
@ -46,6 +62,10 @@ Wants (from handoff doc item 12):
|
|||
2. Charge-aware profile (needs the PMIC investigation first).
|
||||
3. USB role UI toggle.
|
||||
4. Wifi handoff in the state model.
|
||||
5. Maintenance/update lease in the durable manager. Interim `deploy.sh` may
|
||||
use a systemd-timer-backed hypridle lease, but it must first refuse an
|
||||
already locked session and schedule automatic recovery *before* stopping
|
||||
idle handling.
|
||||
|
||||
Start with (1) — it's the spine the others hang off.
|
||||
|
||||
|
|
@ -55,6 +75,10 @@ One daemon owns device power state. `session state` IPC reports the
|
|||
current tier. A plugged-in-at-100% phone doesn't float-charge blindly.
|
||||
USB mode is visible and switchable from the shell.
|
||||
|
||||
An update lease is visible in the same state projection with owner, reason and
|
||||
deadline. Manual lock during a lease wins immediately. Kill the deploy/SSH
|
||||
mid-run: automatic idle handling returns within the bounded timeout.
|
||||
|
||||
## Connects to
|
||||
|
||||
TASK-09 (suspend must be safe before it's a tier), idle coordinator
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ worked once but did NOT hold on a re-wedge.
|
|||
Gadget/ssh survive idle. Suspend is fully off the table until this closes.
|
||||
- The "Android is the reference" rule (`android-is-the-reference-rule`):
|
||||
mimic Android for the pacing; don't invent.
|
||||
- 2026-07-21 stale-lock incident: Hyprland still listed `fts-1`; five harmless
|
||||
taps produced five valid evdev down/up pairs and the FTS IRQ advanced, while
|
||||
the secure lock surface received none. A cold reboot restored native PIN
|
||||
touch immediately. Kernel logs still contained the known Force-calibration
|
||||
warnings. This proves the panel/IRQ can be alive while the compositor →
|
||||
session-lock routing is stale; capture both evdev and secure-surface delivery
|
||||
in the resume test, not merely `hyprctl devices`.
|
||||
|
||||
## Acceptance
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
# TASK 14 — Overview pane → phone app grid
|
||||
|
||||
**Status:** open. Scoped 2026-07-20 from Casey's ask: make the overview
|
||||
actually useful on a phone, appgrid-shaped.
|
||||
**Status:** in progress. Scoped 2026-07-20 from Casey's ask: make the overview
|
||||
actually useful on a phone, appgrid-shaped; expanded 2026-07-21 to include
|
||||
Auxo-like running-app cards and an unconditional Home path.
|
||||
|
||||
## Goal
|
||||
|
||||
|
|
@ -11,7 +12,20 @@ for OSK behavior. On a 5.5" phone the workspace grid is dead weight. Replace
|
|||
the pane's body with a paged app grid (the thing a phone home key opens):
|
||||
icon grid from the desktop-entry list, alphabetical, paged horizontally,
|
||||
long-press for app actions later. Search stays exactly as-is on top — it
|
||||
already works and the OSK dance is already solved there.
|
||||
already works on the laptop and the OSK dance is already solved there. The
|
||||
phone regression still needs device acceptance.
|
||||
|
||||
The pill's second-stage swipe currently sets
|
||||
`GlobalStates.missionControlOpen`, but **no surface consumes that state**.
|
||||
Build the missing Auxo-like multitasking surface: horizontally swiped live app
|
||||
cards from the foreign-toplevel list, tap to focus, close affordance, and a
|
||||
Home card. This is separate from the app grid/search page.
|
||||
|
||||
Single-tapping the pill is Home after the existing 350ms double-tap window:
|
||||
close overview/mission-control/OSK and focus workspace 1. Double-tap keeps its
|
||||
fullscreen toggle. This is also the escape from Hyprland's internal special
|
||||
workspace (`2147483646`, surfaced to Casey as workspace 48/50) after a failed
|
||||
standalone window.
|
||||
|
||||
## Prior art
|
||||
|
||||
|
|
@ -37,12 +51,35 @@ already works and the OSK dance is already solved there.
|
|||
- Keep the diff-against-upstream-ii discipline: new grid lives in its own
|
||||
QML file(s); Overview.qml only swaps the body widget, so ii updates stay
|
||||
mergeable.
|
||||
- Desktop evidence 2026-07-21: `DesktopEntries=53`, `AppSearch=53`, a typed
|
||||
query returned eight results and rendered them. Do not rewrite the search
|
||||
backend to fix a phone-only/stale-shell symptom.
|
||||
- Phone evidence 2026-07-21 after reboot: the live backend returned seven
|
||||
results for `settings`, and `ScriptModel` instantiated all seven, but the
|
||||
dynamic `Qt5Compat.GraphicalEffects.OpacityMask` layer around the results
|
||||
column did not present them on the Adreno/GLES path. The mask was removed;
|
||||
the containing rectangle already clips the list. After the controlled shell
|
||||
restart the live list measured `count=7`, `height=368`, `contentHeight=348`
|
||||
with one Quickshell process. Visual/touch confirmation remains the last
|
||||
device acceptance step. Casey confirmed the search list renders on device.
|
||||
- Related field finding 2026-07-21 ("overview page 100"): not an overview bug —
|
||||
the overview shows the workspace *group* of the active Hyprland workspace,
|
||||
and hyprgrass 1-finger swipe with the default
|
||||
`gestures:workspace_swipe_create_new=true` had ratcheted the active
|
||||
workspace id to 100 over days (each rightward swipe mints the next empty
|
||||
workspace; empties behind evaporate, so no gesture leads home). Fixed on the
|
||||
phone: `workspace_swipe_create_new = false` in `~/.config/hypr/hyprland.lua`
|
||||
(gestures block, applied live via `hyprctl eval`); swipe now only moves
|
||||
between existing workspaces. Recovery dispatch syntax on the phone's
|
||||
Lua-eval hyprctl: `hyprctl dispatch "hl.dsp.focus({ workspace = 1 })"`.
|
||||
|
||||
## Acceptance
|
||||
|
||||
Overview open → app grid visible, correct icons, tap launches, search still
|
||||
works with OSK, close behaves (Escape / toggle / launch). No regression in
|
||||
the OSK-open dismissal behavior.
|
||||
works with OSK, close behaves (Escape / toggle / launch). Second-stage pill
|
||||
swipe → running-app cards; card focus/close works. Single pill tap always lands
|
||||
on workspace 1; double tap still toggles fullscreen. No regression in the
|
||||
OSK-open dismissal behavior.
|
||||
|
||||
## Connects to
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
# TASK 16 — culver: usable messenger + contacts as the Personal-class store
|
||||
|
||||
**Status:** open. Rooms sync today; the app is not yet usable and the
|
||||
contacts store does not yet meet the security bar. Unblocks TASK-01.
|
||||
**Status:** in progress. A, B and D landed 2026-07-21; C is implemented in the
|
||||
local Culver worktree and passes the focused archdev build, with phone
|
||||
acceptance/deploy still pending. Unblocks TASK-01.
|
||||
**Size:** not single-session — four distinct work units (A–D), each
|
||||
session-sized. Do them in order; A is the smallest and most load-bearing.
|
||||
**Repo:** `~/Projects/culver` (Gitea `Fimeg/culver`, CI on `primary`).
|
||||
|
|
@ -20,9 +21,9 @@ session-sized. Do them in order; A is the smallest and most load-bearing.
|
|||
export, number/MXID/email → identity resolver. The runtime already
|
||||
uses it for name resolution via the `resolve_display` hook.
|
||||
|
||||
## The four problems (observed on device + read in tree)
|
||||
## The four work units
|
||||
|
||||
### A. Tap a room → no messages render *(highest leverage)*
|
||||
### A. Tap a room → no messages render — **landed `669f13a`**
|
||||
|
||||
The QML and the `ChatModel` bridge were written to **two different
|
||||
contracts** and never reconciled. Same failure *class* as the
|
||||
|
|
@ -52,7 +53,7 @@ tapping a room shows content with no backend change.
|
|||
**Acceptance:** tap any synced room → its messages render; scroll up
|
||||
paginates history; header shows title + protocol glyph.
|
||||
|
||||
### B. Contacts as the Personal-class store *(the security bar)*
|
||||
### B. Contacts as the Personal-class store — **landed `57740b1`**
|
||||
|
||||
The store works but is **plaintext today** — `Connection::open(path)`,
|
||||
`PRAGMA journal_mode = WAL`, names/numbers/MXIDs/emails/inline photo
|
||||
|
|
@ -83,7 +84,7 @@ without the machine identity (verify: move the file to a bare box → no
|
|||
plaintext). A vCard export attempt raises stepUp and does nothing
|
||||
without it. Round-trip still green for a legitimately-authorized share.
|
||||
|
||||
### C. Contact card UI *(built ON TOP of B, not before)*
|
||||
### C. Contact card UI — **implemented locally; device acceptance pending**
|
||||
|
||||
The cards at the top of the inbox can't open because there is **no
|
||||
contact-card bridge or view** — `crates/contacts` has no UI surface
|
||||
|
|
@ -96,7 +97,44 @@ we are moving away from.
|
|||
**Acceptance:** tapping a contact chip/avatar opens a card (name,
|
||||
numbers, MXIDs, photo); "share" on the card triggers stepUp.
|
||||
|
||||
### D. Notifications: culver → NotifyEvents *(small)*
|
||||
Implementation note (2026-07-21): `ContactModel` now projects the keyed store,
|
||||
the chat-header avatar resolves SMS/Matrix participants into `ContactCard`, and
|
||||
share verifies through `org.souveraine.Secrets.Manage.VerifyPassphrase` before
|
||||
the runtime can mint `EgressAuth` and return a vCard. `cargo check -p culver`
|
||||
passed on archdev and the touched QML passes `qmllint`; phone interaction is
|
||||
not yet claimed.
|
||||
|
||||
Late 2026-07-21 additions (same worktree, single deploy with E):
|
||||
`qml/Contacts.qml` — a contacts *list* page reached from a 👤 button in the
|
||||
inbox title bar (narrow: StackView push; wide: modal popup like Accounts);
|
||||
rows come from the existing `ContactModel`, tap → `selectContact` → the
|
||||
shared `ContactCard`. Registered in `build.rs` views.
|
||||
|
||||
### E. History persistence: boot amnesia — **implemented 2026-07-21**
|
||||
|
||||
Casey's field report: every boot Culver "drops its message history and has
|
||||
to regain it." Probe of the phone's keyed store (busctl plain-session key
|
||||
fetch + `culver-core` example on archdev) showed the store persists fine —
|
||||
75 conversations — but most rooms had **0 messages**: `LoadTimeline` only
|
||||
ever read the local store and nothing ever asked a backend to fill gaps, so
|
||||
what looked like "regaining" was sliding-sync re-delivery on every boot.
|
||||
|
||||
Fix: `CoreEvent::HistoryFetched { conversation, messages, before, limit }`
|
||||
(core) + `spawn_history_fill` (runtime). A store page shorter than the
|
||||
request spawns an async backend `messages()` fetch off the event loop;
|
||||
the fetched page is persisted (idempotent upserts) and the open view
|
||||
re-rendered from the store. Short *pagination* pages are WITHHELD until
|
||||
the fill answers, because `ChatPrepend` has no dedup — the fill's event is
|
||||
the single prepend for that request (falls back to exactly the withheld
|
||||
page on backend failure). Telephony's `messages()` reads the same store,
|
||||
so the fill is a harmless no-op there. Once fetched, history is on disk
|
||||
(SQLCipher) and later boots serve it without the network.
|
||||
|
||||
Known-latent, NOT touched: ChatView's ListView is `BottomToTop` while
|
||||
ChatModel rows are chronological — verify message order visually on device
|
||||
before changing either side.
|
||||
|
||||
### D. Notifications: culver → NotifyEvents — **landed `d33d837`**
|
||||
|
||||
Notifications on the phone already work — the **shell owns the surface**
|
||||
(`org.freedesktop.Notifications` is quickshell's; TASK archive/04 built
|
||||
|
|
@ -122,6 +160,12 @@ filter/toggle later. Rail ordered by last-contacted, later honouring a
|
|||
pinned state. New component, not a fix — do it after A lands so there
|
||||
is content to open.
|
||||
|
||||
Full-app completion after C: wire the currently guarded/inert inbox mute and
|
||||
delete actions, contact create/edit/import, attachment send progress, search,
|
||||
delivery/read state, and account error/recovery surfaces. Treat each as a
|
||||
separate acceptance-backed unit; “the backend has a method” is not a shipped
|
||||
user feature until the QML bridge and phone path exercise it.
|
||||
|
||||
## Build / deploy
|
||||
|
||||
Per tree conventions: build on archdev, never the laptop. culver builds
|
||||
|
|
|
|||
|
|
@ -47,6 +47,15 @@ one session. What shipped works; the follow-ons are UX/layout polish.
|
|||
layout format (`src/layouts/*.json` in the stevia tree). Porting the
|
||||
iOS layout to stevia is open design work — start from the squeekboard
|
||||
header notes in `SouveraineOS/blueline/squeekboard/`.
|
||||
The target is now explicit: iOS-like letter geometry, a permanent number
|
||||
row, Hunspell completion retained, working language/layout switcher, mic
|
||||
retained, and compact arrows available outside the terminal-only layout.
|
||||
The parked `surfaces/quickshell/assets/keyboard/us.json` number-row draft
|
||||
is input, not acceptance.
|
||||
5. **Hyprland key safety**: Pixel3Arch `a5fdbf6` ships stevia 0.56.0-5 with
|
||||
high virtual eventcodes plus zeroed fallback modifiers. Keep the
|
||||
compositor-collision hammer test (bound letters/digits must never dispatch
|
||||
Hyprland actions or shutdown) in every later layout patch.
|
||||
4. **TTS**: Config.options.speech.tts + the Settings field exist but the
|
||||
endpoint is empty — no TTS server on the VPN yet (VibeVoice runs on
|
||||
10.10.20.19 but isn't wired to a REST route the shell can call). When
|
||||
|
|
@ -68,8 +77,9 @@ one session. What shipped works; the follow-ons are UX/layout polish.
|
|||
|
||||
Keyboard usable in every app; mic key dictates real speech into the
|
||||
focused field (verified 2026-07-21: "Hello, can you hear me?" end-to-end);
|
||||
pill dismisses without eating key taps; a recording indicator makes the
|
||||
mic key's state obvious.
|
||||
pill dismisses without eating key taps; number row, layout switcher, Hunspell
|
||||
suggestions and compact arrows work in the daily layout; a recording indicator
|
||||
makes the mic key's state obvious.
|
||||
|
||||
## Connects to
|
||||
|
||||
|
|
|
|||
50
docs/tasks/19-settings-control-center.md
Normal file
50
docs/tasks/19-settings-control-center.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# TASK 19 — First-party Settings control center
|
||||
|
||||
**Status:** in progress (worktree, device acceptance blocked while phone is
|
||||
locked). **Repo:** `~/Projects/souveraine`.
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the removed ii settings application with one Souveraine-owned control
|
||||
center for phone and desktop. One page model, responsive chrome: stack
|
||||
navigation on phone, side rail on desktop. Every control is a view over the
|
||||
owning Config/service/daemon; no success-shaped switches.
|
||||
|
||||
## Current surface
|
||||
|
||||
Owned pages: Device, Lock, Wallpaper, Dock, Navigation, Idle, Keyboard,
|
||||
Speech. Worktree adds Network & internet (Network/Cellular/Bluetooth), Display
|
||||
(real Brightness), and Sound & microphone (PipeWire defaults).
|
||||
|
||||
Still required: app permissions/health, storage, accounts, updates, battery/
|
||||
power profile, and explicit unavailable/error states.
|
||||
|
||||
## Launch/fullscreen failure found 2026-07-21
|
||||
|
||||
- Qt `Window.FullScreen` did not match the pill's compositor-owned fullscreen
|
||||
path and could hide the navigation rail. Start windowed, then target the
|
||||
Settings PID with the same Hyprland Lua fullscreen dispatcher the pill uses.
|
||||
- The launcher allowed duplicate `qs -p` instances. Repeated taps coincided
|
||||
with repeated full-shell run IDs, notification/polkit contention, lost
|
||||
sessiond heartbeat, and fail-closed locks. Launcher must resolve the
|
||||
standalone QML realpath and use `qs --no-duplicate -p <file>`.
|
||||
- Until a controlled launch proves the log says `Launching config: .../
|
||||
settings.qml`, the phone desktop entry stays hidden. Never accept another
|
||||
`shell.qml` run ID from the Settings button.
|
||||
|
||||
## Acceptance
|
||||
|
||||
1. Hammer Settings icon ten times: exactly one standalone PID/window, zero new
|
||||
`shell.qml` run IDs, one notification owner, one polkit agent, sessiond
|
||||
heartbeat continuous.
|
||||
2. Settings log identifies `settings.qml`; close exits the process.
|
||||
3. Phone opens using the pill's fullscreen state; pill remains usable and its
|
||||
double tap returns the app to windowed.
|
||||
4. Every page parses and scrolls at 540×1080; controls change the real service
|
||||
and reflect failure/unavailability.
|
||||
5. Desktop uses the same page components in a normal resizable window.
|
||||
|
||||
## Connects to
|
||||
|
||||
TASK-08 (power/update state), TASK-17 (keyboard/speech), TASK-07 (microphone),
|
||||
TASK-15 (idle), deploy maintenance lease in TASK-08.
|
||||
62
docs/tasks/20-player-video-agent.md
Normal file
62
docs/tasks/20-player-video-agent.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# TASK 20 — Souveraine Player: video + first-class agent control
|
||||
|
||||
**Status:** open. **Repo:** `~/Projects/souveraine-player`.
|
||||
|
||||
## Goal
|
||||
|
||||
Grow the existing music/Navidrome player into a VLC-class local/network media
|
||||
app without regressing its library, queue, downloads, MPRIS, equalizer or
|
||||
session history. The same first-class app surface must let the agent read live
|
||||
progress, issue guarded controls, and capture the exact decoded frame as an
|
||||
explicit artifact.
|
||||
|
||||
## What exists
|
||||
|
||||
- GStreamer `playbin`, audio sink/filter chain, play/pause/seek/volume and a
|
||||
250ms position/duration poll.
|
||||
- QML now-playing bridge, queue/library/server browsing and MPRIS.
|
||||
- `src/manifest.rs` maintains a useful in-process `ManifestState` with guarded
|
||||
commands, but `main.rs` only constructs an `Arc`; it is **not published over
|
||||
IPC or D-Bus**, so it is substrate, not an agent surface.
|
||||
- No video sink/view, subtitles, chapters, stream selection or snapshots.
|
||||
|
||||
## Work units
|
||||
|
||||
### A. Video pipeline and QML surface
|
||||
|
||||
Give playbin a video sink integrated with Qt/Wayland, prefer hardware decode
|
||||
when available, and keep one source model for local files and authenticated
|
||||
HTTP streams. Handle orientation, aspect fit/fill, fullscreen and audio-only
|
||||
background behavior.
|
||||
|
||||
### B. Media UX
|
||||
|
||||
Timeline/scrub preview, subtitle enable/track/file, audio-track selection,
|
||||
chapters, playback speed, resume position, files/URLs/playlists, rotation and
|
||||
picture modes. Surface buffering/errors instead of leaving the spinner alive.
|
||||
|
||||
### C. Real app/agent manifest
|
||||
|
||||
Publish the existing manifest through the ecosystem's explicit IPC/D-Bus seam.
|
||||
Report current media, play state, position/duration, buffering, selected
|
||||
audio/subtitle/chapter, capabilities and last command result. Commands are
|
||||
guarded and auditable; an in-process `Arc` alone does not satisfy this unit.
|
||||
|
||||
### D. Exact frame snapshot
|
||||
|
||||
Use an appsink/tee or equivalent decoded-frame path, not screen scraping.
|
||||
Snapshot records media identity, playback timestamp and output artifact path;
|
||||
conversion/encoding must not stall playback. A locked session refuses personal
|
||||
content egress, and agent-triggered capture follows step-up/consent policy.
|
||||
|
||||
### E. Acceptance matrix
|
||||
|
||||
Local + HTTP H.264/H.265 and device-supported codecs, audio-only, subtitle
|
||||
file/embedded tracks, audio switching, chapter/seek, rotation/fullscreen,
|
||||
resume and snapshot timestamp correctness. Verify live manifest cadence and
|
||||
locked/refused behavior on the Pixel 3 as well as desktop.
|
||||
|
||||
## Connects to
|
||||
|
||||
`docs/FIRST_CLASS_APPS.md`, lock content policy/step-up, TASK-15 network fetcher
|
||||
and idle behavior, Souveraine shell media card.
|
||||
44
docs/tasks/21-reboot-android-confirmation.md
Normal file
44
docs/tasks/21-reboot-android-confirmation.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# TASK 21 — reboot-to-Android confirmation applet
|
||||
|
||||
**Status:** 2026-07-22 — scoped, not started.
|
||||
**Size:** single-session.
|
||||
|
||||
## Why (it went off)
|
||||
|
||||
`/usr/share/applications/blueline-reboot-android.desktop` on the phone execs
|
||||
`blueline-reboot-android` (slot switch to B + warm reboot) with ZERO
|
||||
confirmation. On 2026-07-22 the overview OSK preedit bug made typed search
|
||||
silently empty, Casey tapped blind, hit this entry, and the phone slot-
|
||||
switched to Android mid-session. Recovery needed fastboot
|
||||
(`fastboot set_active a; fastboot reboot`). A one-tap irreversible slot flip
|
||||
must not sit bare in app search.
|
||||
|
||||
Also relevant: the warm reboot it performs is the cold-boot-doctrine
|
||||
violation (TZ/remoteproc poison) — the applet should warn about that, or the
|
||||
script should do the cleanest shutdown it can before switching.
|
||||
|
||||
## Do
|
||||
|
||||
1. Short term (one line): set `NoDisplay=true` in the .desktop so it leaves
|
||||
app search; keep the script callable by hand.
|
||||
2. Real fix: a confirmation surface in the shell —
|
||||
- Dialog in souveraine style (the stepUp-card / sessionScreen pattern):
|
||||
"Switch to Android? The phone reboots into slot B; getting back needs
|
||||
Reboot-to-Linux from Android or fastboot."
|
||||
- Confirm → run existing `blueline-reboot-android`; cancel → no-op.
|
||||
- Point the .desktop `Exec` at the applet, e.g.
|
||||
`qs -c souveraine ipc call session rebootAndroid` with the handler in
|
||||
sessionScreen, which already owns power actions.
|
||||
3. Verify the Android side has a symmetric "reboot to Linux" path so the
|
||||
round trip never needs fastboot; name it in the applet text.
|
||||
|
||||
## Acceptance
|
||||
|
||||
Tapping the search result shows the confirmation; cancel is a no-op; confirm
|
||||
lands in Android; slot a boots back to Linux afterward without fastboot.
|
||||
|
||||
## Connects to
|
||||
|
||||
TASK-14 (the search bug that pulled the pin), blueline-mark-boot-successful
|
||||
(already guards retry exhaustion — this failure was a deliberate slot
|
||||
switch, not retry burn), session authority / sessionScreen power actions.
|
||||
45
docs/tasks/22-settings-fullscreen-tweaks.md
Normal file
45
docs/tasks/22-settings-fullscreen-tweaks.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# TASK 22 — souveraine-settings polish + fullscreen-app behavior sweep
|
||||
|
||||
**Status:** 2026-07-22 — scoped by Casey ("smaller individual tweaks to the
|
||||
souveraine-settings app and fullscreen apps in general"), specifics to be
|
||||
enumerated with Casey at session start. **Size:** a batch of small bounded
|
||||
items, not one feature.
|
||||
**Repo:** `~/Projects/souveraine` (settings), shell trees for fullscreen.
|
||||
|
||||
## Shape
|
||||
|
||||
Two lanes, each item independently landable:
|
||||
|
||||
### A. souveraine-settings tweaks
|
||||
|
||||
Individual paper cuts in the TASK-19 control center — visual, behavioral,
|
||||
missing small controls. Enumerate with Casey; candidates already known from
|
||||
TASK-19's "still required" list (unavailable/error states, battery/power
|
||||
profile stub, etc.) but this task is for the SMALL items, not new pages.
|
||||
|
||||
### B. Fullscreen apps in general
|
||||
|
||||
Known context, all from TASK-19's launch/fullscreen findings and
|
||||
fix-dock-fullscreen-detection.md (superseded doc, patch snippet still valid):
|
||||
|
||||
- Qt `Window.FullScreen` vs the pill's compositor-owned fullscreen path
|
||||
diverge; apps should start windowed and be fullscreened via the same
|
||||
Hyprland Lua dispatcher the pill uses (per-PID).
|
||||
- Dock/ScreenCorners fullscreen detection needed the QML fallback for
|
||||
`qs -p` windows — applied hot on both devices but stranded per-device
|
||||
until the tree unification (`unify-shell-trees-laptop-phone.md`).
|
||||
- Whatever additional fullscreen misbehavior Casey has been seeing across
|
||||
apps (status bar overlap? corner/dock reveal while fullscreen? OSK over
|
||||
fullscreen surfaces?) — capture concrete symptoms first, one item each.
|
||||
|
||||
## Ground rules
|
||||
|
||||
- Each tweak = its own small diff with its own device check; no batching
|
||||
unrelated changes into one deploy.
|
||||
- Anything touching the ii-base layer gets promoted to the laptop repo the
|
||||
same session (divergence doctrine).
|
||||
|
||||
## Connects to
|
||||
|
||||
TASK-19 (the settings app itself), unify-shell-trees-laptop-phone.md (deploy
|
||||
durability), TASK-14 (overview/pill interaction with fullscreen).
|
||||
62
docs/tasks/23-culver-locked-notification-nudge.md
Normal file
62
docs/tasks/23-culver-locked-notification-nudge.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# TASK-23 — Culver locked-notification nudge (the push analogue)
|
||||
|
||||
Status: designed 2026-07-22, not started. Depends on culver's activity
|
||||
orchestrator (landed 2026-07-22) and the shell's LockedHint write-back
|
||||
(landed same day, souveraine Session.qml).
|
||||
|
||||
## Problem
|
||||
|
||||
Culver now stops its Matrix sliding sync while the session is locked
|
||||
(battery: locked = zero network/CPU — verified on device). The trade: no
|
||||
Matrix messages arrive while locked, so no lock-screen banners. SMS is
|
||||
unaffected (the modem is the platform's real push channel and telephony is
|
||||
exempt from `set_active`).
|
||||
|
||||
Android solves this with FCM push waking a brief sync
|
||||
(`isSyncingNotificationEvent` in Element X's SyncOrchestrator). SouveraineOS
|
||||
has no Google push — but it has something better positioned: the shell is
|
||||
always awake, owns the lock surface, and already talks to culver's
|
||||
notification pipe.
|
||||
|
||||
## Design
|
||||
|
||||
A periodic, shell-driven sync nudge while locked:
|
||||
|
||||
1. Culver exposes a D-Bus method on the session bus:
|
||||
`net.wiuf.Culver1.SyncBurst()` — runs ONE sliding-sync round-trip
|
||||
(SyncService start → first room-list response → stop, bounded ~10s
|
||||
hard timeout) even while inactive, emitting notifications for anything
|
||||
inbound. Idempotent; a burst during active sync is a no-op.
|
||||
2. The shell's IdleCoordinator schedules the nudge while locked, riding the
|
||||
idle stages it already manages:
|
||||
- stage 0–1 (recently locked): every 2 min
|
||||
- deeper stages: every 10–15 min, aligned with any existing wake
|
||||
(the point is coalescing with wakeups that happen anyway, not adding
|
||||
timers)
|
||||
- suspend pending/inhibited: no nudges (system asleep = truly quiet)
|
||||
3. Notification path is unchanged: culver's inbound fold already posts
|
||||
org.freedesktop.Notifications, which the shell renders as the lock card.
|
||||
|
||||
## Security notes (same doctrine as timeline-architecture.md §activity)
|
||||
|
||||
- SyncBurst grants nothing: it can only cause culver to do work it is
|
||||
already authorized to do. Any same-user process could equally start the
|
||||
app; the method is a battery lever, not an authority boundary.
|
||||
- The nudge cadence is shell policy, not culver policy — the component
|
||||
that owns idle/battery state owns the schedule. Culver stays policy-free.
|
||||
- No content crosses the nudge interface — notifications flow through the
|
||||
existing pipe with its existing redaction behavior on the lock card.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Real push (ntfy/UnifiedPush relay) — a later, separate task; this design
|
||||
is forward-compatible (a push arrival would call the same SyncBurst).
|
||||
- Per-room priority — the sliding-sync round already orders by recency.
|
||||
|
||||
## Acceptance
|
||||
|
||||
Lock the phone, have someone send a Matrix message, wait ≤2 min: the lock
|
||||
card shows the banner while `journalctl --user -u culver-app` shows exactly
|
||||
one burst (start → response → stop), then silence resumes. Battery
|
||||
regression check: overnight locked drain within noise of the pre-nudge
|
||||
build.
|
||||
|
|
@ -16,15 +16,17 @@ plus open threads from the 2026-07-17 session.
|
|||
| 2 | [Lockscreen-as-Rust-system: glance + swipe](02-lockscreen-rust-system.md) | in progress | stopgap shipped 2026-07-17 |
|
||||
| 3 | [Boot timing: fade splash → lock, no extra fixes](03-boot-timing-splash-to-lock.md) | diagnosed | EBUSY handoff race is the last timing bug; splash text killed, holder added |
|
||||
| 7 | [WCD9340 mic: functional-pinned; unpin + fidelity](07-mic-wcd9340-slim-tx.md) | functional 07-20 | defect: power pin; kernel `mic-race-fix` |
|
||||
| 8 | [Device state manager / power profiles](08-device-state-manager.md) | open | blocked-by TASK-09 suspend item |
|
||||
| 8 | [Device state manager / power profiles](08-device-state-manager.md) | in progress | blocked-by TASK-09 suspend item; adds maintenance leases |
|
||||
| 9 | [Suspend-resume FTS calibration race](09-suspend-resume-fts.md) | interim-fix | kernel-side; cold-boot only |
|
||||
| 12 | [Face auth as a capability factor (Gaze reference)](12-gaze-reference-face-auth.md) | open | per-target: phone needs front-cam bring-up |
|
||||
| 13 | [Active Edge (squeeze) as a sensor input](13-active-edge-squeeze.md) | open | substrate up; bring-up unit not drafted |
|
||||
| 14 | [Overview pane → phone app grid](14-overview-appgrid.md) | open | shell-side; appgrid prior art linked in-file |
|
||||
| 14 | [Overview/app grid + Auxo multitasking](14-overview-appgrid.md) | in progress | shell-side; Home path + app cards |
|
||||
| 15 | [Idle coordinator: freeze, doze, scheduled wakeups](15-idle-coordinator.md) | open | design; blocked-by 09 for suspend tier; eats half of 08 |
|
||||
| 16 | [culver: usable messenger + contacts as Personal-class store](16-culver-messenger-contacts.md) | open | unblocks TASK-01; uses TASK-11 (keying) + archive/04 (NotifyEvents) |
|
||||
| 16 | [culver: usable messenger + contacts as Personal-class store](16-culver-messenger-contacts.md) | in progress | A/B/D landed; C contact card next; unblocks TASK-01 |
|
||||
| 17 | [Keyboard (stevia) + dictation polish](17-keyboard-stevia-dictation.md) | shipped-partial | OSK + mic key + STT live 07-21; layout/UX follow-ons |
|
||||
| 18 | [Selection/highlight action menu](18-selection-menu.md) | open | design captured 07-21; component-first, Read Aloud gated on TTS server |
|
||||
| 19 | [First-party Settings control center](19-settings-control-center.md) | in progress | guarded standalone launch + owned pages |
|
||||
| 20 | [Souveraine Player video + agent control](20-player-video-agent.md) | open | video/snapshot/manifest; preserve music |
|
||||
|
||||
Archived (see `archive/`): 05 crash reporter — done 2026-07-21,
|
||||
CrashReporter.qml in-shell watcher, kill-test verified on device;
|
||||
|
|
|
|||
Loading…
Reference in a new issue