Watch
1
0
Fork
You've already forked souveraine
0

delivery: separate phone and laptop surface profiles

This commit is contained in:
Fimeg 2026-07-13 13:11:31 -04:00
commit 620c6778ce
4 changed files with 115 additions and 54 deletions

View file

@ -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. |

View file

@ -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.

View file

@ -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 <target>` 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 <target>` 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.

View file

@ -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."