6.1 KiB
| title | status | priority | created | owner | references |
|---|---|---|---|---|---|
| Souveraine shell ecosystem — layer registry, surface manifests, guarded method abstraction | scoped | medium | 2026-07-13 | next-instance | surfaces/quickshell/SETTINGS-APP-PLAN.md |
Context
qs -c souveraine is live on laptop + phone (2026-07-13): a composed
quickshell config, not an ii overlay. SouveraineFamily.qml is the panel
family, convergence-scoreboard for desktop/phone homogenization. The shell
works, but it's a collection of panels — it has no framework for how
surfaces relate, how their state is exposed, or how the agent acts on them.
This task scopes the framework basics we're presently missing. Reference
studied: ~/Projects/PostMarketOS-Blueline/references/phosh (full source
checkout). We steal Phosh's conceptual model; we do not copy its C.
The three pieces (compose incrementally, no rewrite)
1. Layer registry + ShellState
Today our panels live on whatever layer ii gave them, implicitly. Phosh's
model: every surface declares its layer (BACKGROUND / TOP / OVERLAY) and
stack-order explicitly, and a state bitmask gates visibility —
use_top_layer = !locked is the canonical line. State drives layer
visibility, not the reverse.
GlobalStates.qmlis almost this already — it holds the state bits (barOpen, oskOpen, screenLocked, overviewOpen, etc.) but doesn't own the layer/stack declarations.- Quickshell gives us layer-shell via
PanelWindowanchors + exclusive zones — same wlr protocol as Phosh, QML binding not C. - The stacked-within-a-layer ordering Phosh does via
zphoc_stacked_layer_surface_v1is something quickshell handles through window stacking / PanelWindow order; verify the exact mechanism when we build this. Do not assume.
Artifact: a LayerRegistry (or formalized ShellState) where each
surface's layer + stack-order is declared in one place, gated by state.
Not all panels at once — start with the surfaces the manifest work touches.
2. Live manifest per surface
Each major surface projects its current state as a queryable structure. The dock first: pinned apps, stacks, positions, visibility, mode. This is a service / IPC surface, not UI.
- The dock already holds this state internally (TaskbarApps, DockStack, the reveal/pulse machinery). The manifest is the projection of that state for external consumers — read-only snapshot + guarded mutation.
- Shape (draft, to finalize when built):
dock.manifest→{ pinned: [...], stacks: [...], hidden: bool, mode: "phone"|"desktop", revealState: ... }
3. Method abstraction for the agent — with state checks
Correction carried in this doc so it isn't lost: the agent does NOT get a new toolcall integration. Souveraine is already a fully-fleshed harness with its own integration state; we use THAT. What lives on the dock side is a small method surface the agent calls — not "parse the QML and figure out what's pinned."
Methods (draft): dock.pin(appId), dock.unpin(appId), dock.restack(...),
dock.reveal(), dock.hide().
Critical: state checks baked into every method. The abstraction must be hard to misuse, not easy:
- Validate inputs (appId exists, stackId well-formed).
- Refuse mutation when the dock is in a state that forbids it (screen locked, mid-drag, OSK suppressing the dock, manifest stale).
- Return real results (success / refused-with-reason / not-found), not fire-and-forget.
- Idempotent where it can be (pinning an already-pinned app is a no-op success, not an error).
The agent calls a guarded method. It genuinely can't break the dock through the abstraction. This is the whole point — a method surface with guardrails, not a footgun.
Where the lessons live — Souveraine School
The teaching of these methods — what they are, when to use them, the lessons learned — is NOT inline in the dock or the agent. It lives in the Souveraine School, taught to agent and human in proper time.
- The dock's job: expose the abstraction.
- The School's job: teach it.
- Two separate concerns. Do not conflate. Do not inline lessons into the method surface or the agent prompt.
Build order
- Dock manifest (read-only projection first). The dock is built, working, has internal state. Projecting it into a queryable manifest proves the pattern with the smallest blast radius. No mutation yet.
- Guarded method surface. Add the mutation methods with state checks. Prove the agent can't break it.
- Layer registry + ShellState formalization. Generalize the state-gates-visibility pattern that the dock work will have exercised. Apply to other surfaces as they need it.
- Repeat per surface (pill, lock, osk, overview) — each gets its own manifest + method surface as the need becomes real. Don't speculatively build manifests for surfaces that don't need agent action yet.
Non-goals (explicit)
- Not copying Phosh's C architecture. Conceptual model only.
- Not building a new toolcall integration for the agent. Use Souveraine's existing harness integration state.
- Not inlining lessons / teaching into the method surface. That's the School's job.
- Not speculatively manifesting every surface. Build when the agent (or another consumer) actually needs to act on it.
- Not a shell rewrite. The panels stay; the framework grows around them.
Open questions to resolve when building
- Exact quickshell mechanism for within-layer stacking (PanelWindow order? a separate z property?) — verify, don't assume it mirrors phoc's extension.
- Manifest transport: qs IPC handler (
qs -c souveraine ipc call dock.manifest) is the natural shape; confirm the agent's existing integration can reach it through Souveraine's harness, not by shelling out. - Where state checks live: in the method (QML) or in a thin validation layer the method calls. Lean toward the method owning its own guards — keeps the surface honest and discoverable.
References on disk
- Phosh source:
~/Projects/PostMarketOS-Blueline/references/phosh(read-only). - end4-pC fork:
~/Projects/end4-pC(studied, not copied). - Pure Maps: referenced in
Pixel3Arch/docs/car-and-dock-references.md, not yet pulled as source.