Keep assistant, reasoning, tool-call, and tool-return frames structured through the sidebar delegate. Tool cards bind returns by wire id and fold their output by default.
Reasoned from the SSE contract and existing TUI renderer. Diff check passed. Untested against a running shell: Casey applies and reloads staged patches.
exclusionMode was ExclusionMode.Ignore, which tells the compositor to
disregard the exclusive zone outright — so the expression below it computed
a height that was thrown away and every window laid out underneath the bar.
The bar is not app space while it is visible.
Auto-hide still yields 0, so a bar configured to hide gives its space back;
the mode only says "honour what I claim".
Not deployed: the phone locked itself on session start, which is
lock-on-startup firing for the first time under viewtop (80cb4b2), and
deploy.sh refuses a live deploy into a locked session.
Two things that worked under Hyprland and stopped when viewtop took the
session, both for the same reason: the binding lived in hyprland.lua and
the daemon was never in the path.
dt2w: note_input recorded the wake and returned Restore, which is
brightness. So a double tap reported to the machine and the screen stayed
dark. It now returns Unblank first — the brightness a panel comes back at
means nothing until the panel is back. Only for the deliberate wakes
(DoubleTapToWake, Squeeze) and only when the panel is actually dark. The
power button is excluded on purpose: apply_gesture already wakes on its
resolved tap, and emitting a second unblank here is precisely how the
wake loop happened in the compositor this afternoon.
Volume: Action::Volume through the executor table, per §12 — a small
daemon reading a signal and calling wpctl is the eighth blind actor. It
fires on the DOWN edge rather than from a recognised gesture, because
BUTTON_MULTI_TAP_WINDOW is 300ms and a volume key that lags a third of a
second behind the press feels broken. The recogniser still sees the
edges, so a future binding table gets volume hold-to-ramp without this
changing.
Shell: HyprlandData did a bare JSON.parse on hyprctl output, which throws
on every refresh when there is no hyprctl — six exceptions a pass, and
every consumer of monitorData.scale got undefined. That is why the region
selector rendered as a sliver: the geometry was not wrong, it was NaN.
Absence is now a latched state, and RegionSelection/OverviewWidget fall
back to screen.devicePixelRatio. Hyprland stays preferred where it exists.
105 tests.
It read "On" for an hour through a dead tunnel — NM said activated while wg had
368 B received against 5.3 KiB sent. Now off/connecting/limited/online, decided
by a 2s probe of the far-side resolver rather than by the interface being up.
Sailfish models the same distinction (Online/Limited/Connecting); Android won't
let an unvalidated network win at all.
GroupButton called it unguarded while releaseAction two lines up was guarded.
altAction is null for every toggle without a menu, so a long-press threw. Only
showed once the toggles that had been filtered out of the panel started
rendering.
The hand-written allowlist in AndroidQuickPanel had drifted from it, so the
phone rendered 12 of its 17 configured toggles and said nothing about the rest.
Adds the missing fullScreenshot and waydroidTerminate, and a deploy guard so
the phone chooser can't fall behind the base one again.
The old wiuf profile shared its address and private key with the laptop, so
WireGuard could only hold one of them, and the key is no longer listed
server-side — it sent and never received. wiufph is 10.8.0.6, port 51822,
keepalive 25. Proven off-LAN: handshake 8s, gitea 200 in 0.126s.
Deliberate, never automatic. The autonomous gate it replaces recycled the
tunnel 652 times in 90 minutes and could not be switched off, because
'nmcli connection down' fired the dispatcher that brought it back up.
Reads NM for state rather than tracking a bool. No privilege needed: polkit
already lets the seat user activate a system connection. Registered in the
ii-phone chooser as well as ii-base, or the phone overlay wins and the
delegate never appears.
The subconscious three-tier surface (SubconsciousTicker + SubconsciousEventPanel)
is Souveraine-original, not upstream ii. It lived under ii-base/modules/ii only
because it had never been re-homed, so the ii -> souveraine shell migration
silently stranded it: the files survived, but the running shell (qs -c souveraine)
never loaded them, and the feature dropped off the device.
Relocated into modules/souveraine/subconscious/, decoupled from the ii overlay
system it was riveted to:
- SubconsciousTicker: was clean of ii imports but opened the panel through the
ii OverlayContext singleton. Now emits requestOpenPanel(); a host connects it.
- SubconsciousEventPanel: was a StyledOverlayWidget (qs.modules.ii.overlay). Now
plain content a host instantiates; the pin/close/drag affordances were the
overlay host's job, not the content's.
The model (services/Ai.qml) was already substrate-neutral and never moved; only
the views were stranded. GAP NAMED: no souveraine overlay host mounts these yet,
so they do not reach the glass until one exists — the ii overlay host was
intentionally not ported. The dangling ii references (AiChat, OverlayContext,
OverlayWidgetDelegateChooser) are removed.
~/souveraine-surfaces/quickshell on the phone is not a git repo and was the
only copy of five files. Brought back verbatim:
- Gestures.qml, SystemGestureRail.qml: TASK-38 osk-swap detent (DUMP §5, §6)
- OnScreenKeyboard.qml: showOsk asks the bus instead of pgrep+sleep 1
- DockAppButton.qml, DockStack.qml: suffix-tolerant AppSearch.resolveEntry
resolveEntry itself had been added to the phone's live ~/.config/quickshell/ii
tree, which deploy.sh rsyncs from ii-base — the next deploy would have deleted
it and left the two dock callers referring to nothing. It lands in ii-base here.
Speech: prefetch() now sets synthProc._prefetch=true before voiceLookup
so the background synth doesn't auto-play. speak() skips voiceLookup
when the endpoint+voice are already resolved (faster repeat taps).
Ai: addMessage defaults model to Souveraine.currentAgentId so restored
messages (/resume, new conversations) show the agent icon/name instead
of a generic placeholder.
Session: create_with_messages_and_timestamps preserves persisted
created_at/updated_at through load_persisted so /resume sorts by
actual activity time, not server restart time.
TTS: ttsClean strips unclosed think blocks, fixes regex dotAll flag
for older Qt/V8 (phone), adds pronunciation map.
SubconsciousTicker: tap psychology icon to expand inline mini-log,
long-press to open the event panel overlay.
New: workspace-selector.sh + .desktop — wofi dmenu grid for quick
workspace 1-10 jump from the app drawer. Installed to phone via
deploy.sh symlink.