From 620c6778cedcf766a17138223738597d51b49018 Mon Sep 17 00:00:00 2001 From: Fimeg Date: Mon, 13 Jul 2026 13:11:31 -0400 Subject: [PATCH] delivery: separate phone and laptop surface profiles --- docs/tasks/INDEX.md | 1 + .../device-specific-quickshell-profiles.md | 67 +++++++++++++++++++ docs/tasks/quickshell-surface-package.md | 60 ++++++++++------- scripts/install-quickshell-surface.sh | 41 +++--------- 4 files changed, 115 insertions(+), 54 deletions(-) create mode 100644 docs/tasks/device-specific-quickshell-profiles.md diff --git a/docs/tasks/INDEX.md b/docs/tasks/INDEX.md index 8d03204..4d7a175 100644 --- a/docs/tasks/INDEX.md +++ b/docs/tasks/INDEX.md @@ -98,6 +98,7 @@ | `subconscious-surfacing-threshold.md` | 3.0 | pending | Fix surfacing filter — events appear every turn instead of only when important. Three-tier visibility: streaming one-liner, expandable transcript, cockpit surfaced messages. | | `souveraine-subconscious-naming.md` | 2 | pending | Clarify naming: Ani's subconscious = Aster, Souveraine agents' subconscious = Souveraine-subconscious. | | `quickshell-surface-package.md` | delivery | **in progress** | Split core from QuickShell surface package; safe preview/adopt installer, no automatic ii overwrite. | +| `device-specific-quickshell-profiles.md` | delivery | scoped | Phone and laptop share the agent channel but have distinct QuickShell bodies, manifests, and packages. | | `footer-cleanup.md` | 3.0 | **landed** | Removed S-Ret indicator, scroll hint, posture label. Footer: Esc menu · Tab · tool hint · conv ID · ctx%. | | `ui-styling-cleanup.md` | 3.0 | pending | UI styling polish for cockpit/subconscious/thinking boxes — sentences run together, needs formatting and visual cleanup. | | `resume-timestamp-indicator.md` | 3.0 | pending | Show "User resumed conversation at HH:MM" when returning after hours of absence. Also show duration ("4 hours, 12 minutes later"). Ambient sense rendered as separate timestamp marker, not inline. | diff --git a/docs/tasks/device-specific-quickshell-profiles.md b/docs/tasks/device-specific-quickshell-profiles.md new file mode 100644 index 0000000..2d09da0 --- /dev/null +++ b/docs/tasks/device-specific-quickshell-profiles.md @@ -0,0 +1,67 @@ +--- +task_id: souveraine-surface-002 +title: Device-specific QuickShell profiles — shared agent channel, distinct bodies +status: scoped +priority: high +phase: delivery +created: 2026-07-13 +references: docs/tasks/quickshell-surface-package.md, surfaces/quickshell/ +--- + +# Device-Specific QuickShell Profiles + +## Decision + +Phone and laptop are not interchangeable shells. They are separate sensorium +surfaces of the same Souveraine service. + +The shared layer is small and semantic: + +- `Souveraine.qml`: server connection, agent catalog, selection, conversation + creation/resume, streaming and backchannel operations. +- `Ai.qml`: message projection and `/agent`/`/resume` semantics. +- shared agent identity, API tokens, transcript, and subconscious events. + +The body is profile-owned: + +| Profile | Interaction contract | Visual contract | +|---|---|---| +| Phone | thumb-first, short-lived attention, rotation/dock/handset states | compact custom bar and pill; intentionally limited visible bulk | +| Laptop | keyboard/mouse, wider attention and many concurrent controls | richer bar, more icons, sidebars and desktop-oriented dock/overview | + +No profile imports or replaces the other profile's bar, dock, or layout. + +## Work breakdown + +1. **Inventory current overlay files.** Mark each as common, phone, laptop, or + genuinely unresolved. The existing mixed `deploy.sh` remains a developer + tool only until this classification is complete. +2. **Create manifests.** `manifests/common`, `manifests/phone`, and + `manifests/laptop` list only their own target paths. Each profile installer + consumes its manifest, never the aggregate. +3. **Extract shared QML carefully.** Shared services must not read phone-only + geometry, rotation state, or laptop-only sidebar assumptions. Pass profile + capabilities/config explicitly where necessary. +4. **Package separately.** Build `common`, `phone`, and `laptop` surface + packages as architecture-independent assets. Pacman installation writes + `/usr/share` only; an explicit per-profile adoption command changes user + QuickShell config after preview and consent. +5. **Test against two fixtures.** A disposable phone ii tree and laptop ii + tree must demonstrate that each profile changes only its own files, can be + declined without side effects, and preserves every adopted conflict. + +## Immediate laptop path + +The laptop needs the shared channel now, not a phone bar. The minimal targeted +deployment is `AiChat.qml` plus the already linked `Ai.qml` and +`Souveraine.qml`; it exposes `/agent` and `/resume` against the local server +without changing the laptop dock or bar. This remains the only approved live +adoption until the laptop manifest exists. + +## Acceptance + +- A phone package cannot place a pill or compact phone bar in laptop ii. +- A laptop package cannot add desktop density to the phone shell. +- Both profiles enumerate and switch the same server-provided agent catalog. +- Profile selection is explicit in installer output, package names, and task + documentation; no hostname guessing is used. diff --git a/docs/tasks/quickshell-surface-package.md b/docs/tasks/quickshell-surface-package.md index 7988320..0c23c43 100644 --- a/docs/tasks/quickshell-surface-package.md +++ b/docs/tasks/quickshell-surface-package.md @@ -13,9 +13,9 @@ references: docs/tasks/souveraine-cicd-pipeline.md, surfaces/quickshell/deploy.s ## Outcome `souveraine` remains the non-visual substrate package: server binary, user -unit, and no ownership of `~/.souveraine` or `~/.config`. A separate -architecture-independent `souveraine-surface-quickshell` package ships the -QuickShell assets and an explicit adoption command. Installing/upgrading a +unit, and no ownership of `~/.souveraine` or `~/.config`. The QuickShell body +splits by device profile: laptop and phone share Souveraine's channel protocol, +not a top bar, dock, layout, or interaction density. Installing/upgrading a package never silently replaces a person's ii shell, top bar, dock, or local QuickShell changes. @@ -23,7 +23,10 @@ QuickShell changes. - The running laptop package ships only `/usr/bin/souveraine`, its user unit, and license files. It correctly updates with pacman, but contains no QML. -- `surfaces/quickshell/` is the canonical source for Souveraine's ii overlay. +- `surfaces/quickshell/` is the canonical source for shared channel code and a + currently mixed development overlay. It is **not** a universal surface + manifest: `pill/shell.qml` and the compact rotating phone bar do not belong + on a laptop, whose bar intentionally has more visible controls. - `deploy.sh` is the development deployment path; it manages symlinks and retains one `.upstream` copy for ordinary upstream files. - The laptop had an older `AiChat.qml`; its `/agent` and `/resume` commands @@ -34,42 +37,51 @@ QuickShell changes. 1. Pacman places only package-owned assets under `/usr/share/souveraine/` and an adoption tool under `/usr/bin/` or `/usr/libexec/`. -2. The adoption tool defaults to a dry run: it names every managed, new, and +2. The package name and manifest are profile-specific: at minimum + `souveraine-surface-laptop` and `souveraine-surface-phone`; shared QML lives + in a common asset layer. A laptop installer never considers phone files, + and vice versa. +3. The adoption tool defaults to a dry run: it names every managed, new, and replacement target. -3. A normal `--apply` succeeds only when targets are new or already managed by +4. A normal `--apply` succeeds only when targets are new or already managed by Souveraine. -4. Replacements require `--adopt`; each conflicting file or symlink is copied +5. Replacements require `--adopt`; each conflicting file or symlink is copied to a timestamped `*.pre-souveraine-*` backup before the overlay changes it. -5. `--uninstall` restores the original `.upstream` files where available and +6. `--uninstall` restores the original `.upstream` files where available and otherwise removes only Souveraine-managed symlinks. It never removes user data, agent memory, or unrelated ii files. -6. Package upgrades do not run adoption automatically. They update the assets; +7. Package upgrades do not run adoption automatically. They update the assets; the user reviews and applies their desktop changes explicitly. ## First cut — in progress - [x] Expose `deploy.sh --manifest` so package tooling and the developer path share a single authoritative list of managed files. -- [x] Add `scripts/install-quickshell-surface.sh`, an explicit dry-run/apply/ - adopt wrapper around that manifest. -- [ ] Exercise its dry-run, clean apply, conflict refusal, adoption backup, and - uninstall behaviour in a disposable QuickShell config. -- [ ] Add a targeted `--only ` mode so a small repair such as `AiChat` - can be adopted without touching the dock or bar. +- [x] Add `scripts/install-quickshell-surface.sh` as a safe inventory tool. + Its apply/adopt mode is deliberately disabled until profiles exist; it cannot + make the mixed overlay look universally safe. +- [ ] Split the current development manifest into `common`, `laptop`, and + `phone` manifests. Classify every file by actual layout and interaction + contract; do not infer a laptop layout from phone work or vice versa. +- [ ] Re-enable safe apply/adopt only against a selected profile. Exercise its + dry-run, clean apply, conflict refusal, adoption backup, and uninstall + behaviour in disposable configs for both devices. +- [ ] Add a targeted `--only ` mode within the chosen profile so a + small repair such as `AiChat` can be adopted without touching a bar or dock. ## Package design — next cut -1. Add `packaging/arch/PKGBUILD.surface` (`arch=('any')`) that installs the - canonical QML tree under `/usr/share/souveraine/quickshell/` and the safe - adoption command. +1. Add `packaging/arch/PKGBUILD.surface-common`, `.surface-laptop`, and + `.surface-phone` (`arch=('any')`). The common package supplies the channel + code; each profile supplies only its own QML/assets and adoption manifest. 2. Make the command resolve packaged assets first, with a checked-out repo retained as an explicit developer override. 3. Extend the CI release job to build/sign/publish the surface package once per edge release alongside both binary packages. 4. Add a narrow integration test using a temporary `$XDG_CONFIG_HOME`; verify no automatic overwrite and that `--adopt` preserves every conflict. -5. On phone and laptop, install the surface package with pacman, run the - preview, then choose adoption deliberately. The phone's existing live +5. On phone and laptop, install the appropriate profile package with pacman, + run the profile preview, then choose adoption deliberately. The phone's existing live symlink development loop remains valid until this proves itself. ## Later: desktop profile @@ -82,9 +94,11 @@ machine one clear install target without sacrificing ownership of its shell. ## Acceptance - `pacman -S souveraine` never changes a QuickShell file. -- `pacman -S souveraine-surface-quickshell` never changes a QuickShell file. +- `pacman -S souveraine-surface-laptop` and + `pacman -S souveraine-surface-phone` never change a QuickShell file. - The adoption command clearly reports its plan and refuses unapproved replacements. -- A deliberate adoption makes `/agent`, `/resume`, agent selection, and the - Souveraine panel available against the locally running package service. +- A deliberate profile adoption makes `/agent`, `/resume`, agent selection, + and the Souveraine panel available against the locally running package + service without importing another device's bar or dock. - An upgrade and uninstall preserve user settings and agent state. diff --git a/scripts/install-quickshell-surface.sh b/scripts/install-quickshell-surface.sh index aaf509b..263789a 100755 --- a/scripts/install-quickshell-surface.sh +++ b/scripts/install-quickshell-surface.sh @@ -7,25 +7,24 @@ set -euo pipefail usage() { cat <<'EOF' -Usage: install-quickshell-surface.sh [--dry-run | --apply | --adopt] +Usage: install-quickshell-surface.sh [--dry-run] - --dry-run Show every file the Souveraine surface would manage (default). - --apply Install when every target is new or already Souveraine-managed. - --adopt Permit replacing existing ii files after preserving a timestamped - copy beside each conflict. Implies --apply. + --dry-run Show every file in the current development overlay (default). -Pacman should install surface assets only. This command is the explicit, -user-owned step that changes ~/.config/quickshell/ii. +The present development overlay mixes phone and laptop assumptions. It is not +safe to adopt wholesale on either device. Profile-specific manifests must land +before an apply/adopt mode is enabled. Pacman should install assets only. EOF } mode=dry-run -adopt=false while (($#)); do case "$1" in --dry-run) mode=dry-run ;; - --apply) mode=apply ;; - --adopt) mode=apply; adopt=true ;; + --apply|--adopt) + echo "Surface adoption is disabled until laptop and phone manifests are split." >&2 + exit 2 + ;; -h|--help) usage; exit 0 ;; *) echo "unknown option: $1" >&2; usage >&2; exit 2 ;; esac @@ -68,24 +67,4 @@ done < <("$DEPLOY" --manifest) printf '\n%d managed, %d new, %d replacement(s).\n' \ "$managed_count" "$new_count" "${#conflicts[@]}" -if [[ "$mode" == dry-run ]]; then - echo "Dry run only; use --apply when there are no replacements, or --adopt to preserve and replace them." - exit 0 -fi - -if ((${#conflicts[@]}) > 0) && [[ "$adopt" != true ]]; then - echo "Refusing to replace existing ii files without --adopt. No files changed." >&2 - exit 2 -fi - -if ((${#conflicts[@]}) > 0); then - stamp="$(date +%Y%m%d-%H%M%S)" - for target in "${conflicts[@]}"; do - dst="$QS/$target" - backup="${dst}.pre-souveraine-${stamp}" - cp -a -- "$dst" "$backup" - echo "preserved $target -> ${backup#$QS/}" - done -fi - -exec "$DEPLOY" +echo "Dry run only. Profile-specific laptop/phone manifests are required before adoption can be enabled."