11 KiB
TASK: Unify the Souveraine shell trees — laptop, phone, SouveraineOS
Status: DONE — verified 2026-07-31. Every goal in this file is met.
Zero stranded files; the drift it was filed against is gone; it blocks nothing.
Ready to move to archive/.
Filed: 2026-07-21
Re-measured 2026-07-31 (md5 of every file, both devices)
| 2026-07-21 (filed) | 2026-07-31 | |
|---|---|---|
| files differing in content | 918 | 7 |
| laptop-only | 30 | 0 |
| phone-only | 13 | 4 (intentional overlay) |
The fix landed without this task being worked: deploy.sh now rsyncs the repo's
ii-base/ → ~/.config/quickshell/ii on both devices ("ii synced from
pin"), then layers ii-phone/ on aarch64. That is option (A) from §1 below
— a pinned base both devices deploy from — and it killed the independent drift.
modules/settings/system/ (the whole Wifi/Bluetooth/Vpn/Monitor suite) and
SettingsHome.qml are now byte-identical across repo, laptop and phone.
The 4 phone-only files are the declared overlay and are correct:
AutoRotateToggle.qml, WallpaperShuffleToggle.qml,
AndroidAutoRotateToggle.qml, AndroidWallpaperShuffleToggle.qml.
Stranded files remaining: ZERO
Every one of the 7 content differences is a declared, version-controlled
phone override. ii-phone/ is exactly 11 files and accounts for all of them:
modules/common/models/quickToggles/AutoRotateToggle.qml
modules/common/models/quickToggles/WallpaperShuffleToggle.qml
modules/ii/bar/BarContent.qml ← carrier + signal, far-left
modules/ii/bar/ClockWidget.qml ← per-instance date format
modules/ii/bar/Resources.qml ← one rotating stat (540px bar)
modules/ii/onScreenKeyboard/layouts.js
modules/ii/sidebarRight/quickToggles/androidStyle/AndroidAutoRotateToggle.qml
modules/ii/sidebarRight/quickToggles/androidStyle/AndroidToggleDelegateChooser.qml
modules/ii/sidebarRight/quickToggles/androidStyle/AndroidWallpaperShuffleToggle.qml
scripts/colors/switchwall.sh ← skip the blocking upscayl prompt
services/Audio.qml
That is §3's "declared home for phone-specific files", built and working.
§2 is done too — the KEEP list was promoted, not lost
The 07-21 record lists services/Cellular.qml, services/Souveraine.qml and
modules/ii/dock/DockStack.qml as untracked phone-only files at risk. All
three are now in the repo, in deploy.sh's manifest, and live on the phone —
promoted to first-class overrides exactly as §2 asked. They are no longer in the
ii tree because they no longer belong there.
(Beware when auditing this: those files live in the souveraine tree, not
ii. Checking ~/.config/quickshell/ii/services/Cellular.qml reports them
missing and is the wrong tree — that mistake was made on 2026-07-31 and briefly
recorded here as data loss. They were never lost.)
One correction that does stand
deploy.sh --phone no longer "only rsyncs surfaces/quickshell/" — it rsyncs
the pinned ii-base with --delete, then layers ii-phone. That
--delete is precisely why an undeclared phone-local edit cannot survive a
deploy, and why the overlay above is the only correct home for one.
Owner rule: builds on archdev only; deploy from laptop. See
souveraine-build-deploy memory + souveraine-work-rules.
The problem (one sentence)
The laptop and the phone are the same platform, but their shell code lives in two independently-maintained trees that have silently diverged by ~900 files, so fixes and features land on one device and never reach the other — and there is no source of truth that spans both.
Why this bit us today
Chasing a dock/ScreenCorners fullscreen bug, work landed in ~/.config/quickshell/ii/
on the laptop — an untracked, borrowed-upstream tree that:
- is not in the
souverainerepo (so it's not source-controlled), and - is not carried by
deploy.sh --phone(onlysurfaces/quickshell/rsyncs),
so the "fix" reached nothing on the phone. The phone had to be hot-patched in
place. That patch now lives ONLY on the phone's disk, untracked, and the next
deploy.sh recompose can revert it. This is unsustainable.
Ground truth (measured 2026-07-21)
Two trees per device under ~/.config/quickshell/:
souveraine/— composed bysurfaces/quickshell/deploy.sh. Our files are repo symlinks (manifest in deploy.sh); everything else is a whole-dir symlink borrowed from the siblingii/tree.ii/— the illogical-impulse / dots-hyprland upstream base. Maintained independently on each device. Not in any repo. Not synced by anything.
Surface tree (surfaces/quickshell/ in the souveraine repo) — GOOD
Laptop repo experimental/session-trust-phase1 vs phone rsync target
(~/souveraine-surfaces/quickshell/): only 2 files differ, both this session's
uncommitted edits:
modules/ii/dock/Dock.qmlmodules/settings/WallpaperConfig.qml
The phone surface is not a git repo — it's a plain rsync target. No history.
ii base tree — BROKEN, this is the whole problem
Laptop ii vs phone ii (rsync dry-run, whole tree):
- 918 files differ in content
- 30 files exist on the laptop but NOT the phone — the phone is behind
- 13 files exist on the phone but NOT the laptop — mix of real + junk
30 phone-missing highlights (laptop is ahead — the phone should get these):
scripts/colors/random/random_wallhaven_wall.sh← the wallhaven script from earlier this session NEVER reached the phone- entire
modules/settings/system/—WifiConfig,WifiAdvancedConfig,WifiKnownConfig,BluetoothConfig,VpnConfig,MonitorConfig,KdeConfig modules/settings/SettingsHome.qmlservices/ClaudeUsage.qml,services/FileSearch.qml,services/NetworkTraffic.qml,services/PhysicalKeyboard.qmlmodules/ii/bar/ClaudeUsageBar.qml, pomodoro widgets, background stat widgetsservices/ai/OpenAiResponsesApiStrategy.qml
13 phone-only files — DO NOT blindly delete these:
- KEEP (real phone-specific):
services/Cellular.qml(phone has a modem, laptop doesn't),modules/common/models/quickToggles/AutoRotateToggle.qml,WallpaperShuffleToggle.qml,modules/ii/sidebarRight/quickToggles/androidStyle/AndroidAutoRotateToggle.qml,AndroidWallpaperShuffleToggle.qml, phone-sideservices/Souveraine.qml,modules/ii/dock/DockStack.qml,modules/ii/sidebarLeft/SidebarLeft.qml(?) - JUNK (stale backups, delete):
*.bak-osk-20260711-*,QuickSliders.qml.pre-audio-null-20260711,switchwall.sh.bak-upscale,services/Idle.qml.bak-20260711-130054,services/Audio.qml.bak-pipewire-20260714-123729
A naive rsync --delete laptop→phone would destroy the phone's cellular
service and rotation toggles. It must be a reviewed merge, not a blind push.
The real fix (design — decide in the session)
Three intertwined decisions:
1. Bring the ii base under version control and sync it
The ii tree is the actual source of drift. Options:
- (A) Vendor a pinned
iisnapshot into a repo (SouveraineOS or a submodule) and have BOTH devices deploy from that pin — kills independent drift dead. - (B) Keep upstream
iias a tracked fork with a known base commit + our patch set on top, re-syncable per device. - Recommendation: (A). We already treat
iias a frozen base we borrow from; pin it so "borrowed" means "borrowed from the same commit everywhere."
2. Everything device-agnostic that we patch must become a repo override
ScreenCorners is the poster child: it's a fix we NEED on the phone but it lived in
the borrowed base. Any file we modify must move into surfaces/quickshell/ + the
deploy.sh manifest so it ships. Audit for other stranded edits in ii on both
devices before pinning (diff each device's ii against the chosen upstream pin;
every local delta is either a patch to promote or upstream drift to drop).
3. Make "phone follows laptop" the default, safely
- Phone surface should become a deploy from the repo, not a bare rsync target (or at least record the deployed commit on the phone so drift is detectable).
- Phone-specific files (Cellular, rotation/wallpaper toggles) need a declared
home — a
platform/phone/overlay in the manifest — so a full sync can't clobber them. Right now they survive only because nothing syncsii.
Concrete steps (draft — refine in session)
- Snapshot both devices'
iifirst (tar both~/.config/quickshell/ii, laptop + phone) so nothing is lost. Store off-device. - Pick the upstream
iipin (likely the laptop's currentii, it's ahead). Diff BOTH devices'iiagainst it; classify every delta: promote-to-override, phone-platform-overlay, or drop-as-upstream-drift. - Promote all device-agnostic patches (ScreenCorners fallback, wallhaven script,
anything else found) into
surfaces/quickshell/+ manifest. - Give phone-only files a real home in a phone overlay in the manifest.
- Commit the two dangling laptop edits (Dock.qml fallback, WallpaperConfig.qml
folder-browsing) — they're currently uncommitted on
experimental/session-trust-phase1. - Rebuild the deploy so
deploy.sh --phonereproduces a phone identical to the laptop's shell plus the phone overlay, from tracked sources only. - Verify on the phone: fullscreen settings hides dock+corners; wallhaven button works; cellular + rotation still present; no QML errors.
- Decide SouveraineOS's role — is it the home for the pinned
iiand the deploy tooling? (It already documents the components; it's the natural owner.)
Interim state (what's live right now, 2026-07-21)
- Laptop repo, uncommitted:
Dock.qml(fullscreen fallback),WallpaperConfig.qml(folder browsing). Onexperimental/session-trust-phase1. - Laptop
ii(untracked): ScreenCorners.qml fallback patch, wallhaven script. - Phone, hot-patched in place (untracked, may be reverted by recompose):
~/souveraine-surfaces/quickshell/modules/ii/dock/Dock.qml— fallback~/.config/quickshell/ii/modules/ii/screenCorners/ScreenCorners.qml— fallback- Shell restarted,
qs -c souveraineactive/running, no QML errors.
- Phone is behind the laptop on ~918
iifiles incl. the wallhaven script and the wholemodules/settings/system/config suite.
The fallback patch itself (for reference / re-application)
Both Dock.qml and ScreenCorners.qml detect fullscreen via
ws.toplevels.values.filter(w => w.wayland?.fullscreen), which uses
ext-foreign-toplevel-list and never sees standalone qs -p windows
(souveraine-settings). The fix adds a fallback to Hyprland's own IPC, already
polled by HyprlandData (qs.services):
// after the existing workspace-scan bool:
|| HyprlandData.activeWindow?.fullscreen === 2 // 2 = real fullscreen
HyprlandData.updateAll() re-polls on every Hyprland raw event, so it reacts when
settings goes fullscreen. Requires import qs.services (both files already have it).
Supersedes docs/tasks/archive/fix-dock-fullscreen-detection.md.