TASK-32: record that --phone rsyncs --delete with no snapshot
Folds in the 2026-07-29 finding instead of a new task file; TASK-32 already owns how these surfaces ship.
This commit is contained in:
parent
00d2449acc
commit
39c9a022b4
3 changed files with 16 additions and 94 deletions
|
|
@ -66,6 +66,22 @@ owns the fix.
|
|||
- Both ship by a mechanism that survives an update, or the gap is named with
|
||||
the task that owns it.
|
||||
|
||||
## The shipping mechanism destroys on-device edits (found 2026-07-29)
|
||||
|
||||
Neither surface has a package; the whole quickshell tree reaches the phone only
|
||||
via `deploy.sh --phone`, which is `rsync -a --delete` from the laptop checkout
|
||||
into the phone's tree with **no snapshot** (`deploy.sh:246`). The local compose
|
||||
snapshots to `.ii-previous`/`.souveraine-previous` first; the phone path does
|
||||
not. So an on-device edit is destroyed with no record — which is how four
|
||||
pkgrels of stevia came to exist only on the phone, and why Casey is "loosing my
|
||||
filesystem on my daily driver".
|
||||
|
||||
Root cause is the install target, not the tool: `deploy.sh` writes into `$HOME`,
|
||||
so it cannot tell the user's files from its own. A pacman package cannot do that
|
||||
— payload to `/usr/share`, `$HOME` keeps only overrides, and pacman refuses to
|
||||
clobber unowned files (`.pacnew` for owned ones). Cheap interim fix: give the
|
||||
`--phone` rsync the same `snapshot_tree` the local compose already has.
|
||||
|
||||
## Do not
|
||||
|
||||
- Patch another keyboard symptom without a reference layout in hand.
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
# TASK 49 — the shell surface is not a package, and it eats on-device edits
|
||||
|
||||
**Status:** open, diagnosed 2026-07-29. **Repo:** `~/Projects/souveraine`
|
||||
(`surfaces/quickshell/deploy.sh`, `packaging/arch/`), `Pixel3Arch`.
|
||||
|
||||
Casey, 2026-07-29: *"I often enough make custom changes on that end as well — so
|
||||
this bothers me. I clearly want a better way and to stop loosing my filesystem on
|
||||
my daily driver device."*
|
||||
|
||||
This is not a papercut. The phone is the daily driver and the deploy path is
|
||||
destructive by construction.
|
||||
|
||||
## What is actually true today
|
||||
|
||||
`souveraine`'s CI packages the Rust binaries (`souveraine`, `souveraine-secrets`,
|
||||
`souveraine-machined`, `souveraine-sessiond`) and the UPower fork, and CLAUDE.md
|
||||
states the rule plainly: *"Everything this repo produces ships as a package... If
|
||||
a binary needs to reach a device, it goes through the package."*
|
||||
|
||||
**The quickshell surface is the exception, and nothing says so.** Every mention of
|
||||
quickshell under `packaging/` is an incidental comment. There is no
|
||||
`souveraine-shell` package. The entire shell — every QML file, the ii base pin,
|
||||
the phone overlay — reaches the phone only via `deploy.sh --phone`.
|
||||
|
||||
## The two exposures, precisely
|
||||
|
||||
| Path | Operation | Snapshot? |
|
||||
|---|---|---|
|
||||
| `$PHONE_DEST` (phone's copy of the surface source) | `deploy.sh:246` `rsync -a --delete` from the laptop checkout | **none** |
|
||||
| `$II`, `$SV` (composed dirs under `~/.config/quickshell`) | `deploy.sh:388,391` `rsync -a --delete-delay` | yes — `.ii-previous` / `.souveraine-previous`, one generation |
|
||||
|
||||
So the composed trees are recoverable one deep. **The phone's source tree is
|
||||
not.** `--delete` with no snapshot means an on-device edit or a new file in that
|
||||
directory is destroyed with no record it existed. That is the mechanism behind
|
||||
"losing my filesystem", and it is the `--phone` path specifically — the local
|
||||
compose is comparatively careful.
|
||||
|
||||
`deploy.sh` is *not* careless otherwise: it stages into `.ii-next.$$` /
|
||||
`.souveraine-next.$$`, uses `--delay-updates`, refuses to clear an unexpected
|
||||
rollback path, and traps for cleanup. The problem is not hygiene. It is the
|
||||
target.
|
||||
|
||||
## The root cause is the install target, not the tool
|
||||
|
||||
`deploy.sh` installs **into `$HOME`**. That is why it cannot distinguish the
|
||||
user's files from its own: everything lives in one tree that one rsync owns.
|
||||
No amount of flag-tuning fixes that, because the tool has no ownership model.
|
||||
|
||||
A pacman package cannot install into `$HOME`, and that constraint is the fix:
|
||||
|
||||
- **Payload to `/usr/share/souveraine/quickshell/`** — package-owned, read-only,
|
||||
replaced wholesale on upgrade with no ambiguity about who owns what.
|
||||
- **`$HOME` holds only overrides.** An upgrade physically cannot touch a file the
|
||||
package does not own, because it never writes there.
|
||||
- **pacman refuses to clobber unowned files** rather than deleting them, and
|
||||
emits `.pacnew` for package-owned files the user modified — the edit survives
|
||||
*and* the new version arrives beside it.
|
||||
- **`pacman -Qkk souveraine-shell`** answers "what did I change?", which nothing
|
||||
can answer today.
|
||||
- **`backup=()`** in the PKGBUILD marks the genuinely user-editable files
|
||||
explicitly, making the contract legible instead of conventional.
|
||||
|
||||
This also lands the surface on the `souveraine-updater` path the rest of the
|
||||
system already uses, which is what Casey asked for — but note the upgradeability
|
||||
is the *secondary* benefit. The primary one is that clobbering becomes
|
||||
structurally impossible.
|
||||
|
||||
## What this needs
|
||||
|
||||
1. **A resolution order in the shell.** `$HOME` override → package payload →
|
||||
ii pin. `deploy.sh`'s manifest already encodes exactly this three-way
|
||||
composition (override / borrow-whole-dir / compose-file-by-file), so the logic
|
||||
exists and moves rather than gets invented.
|
||||
2. **`souveraine-shell` PKGBUILD** carrying `surfaces/quickshell/` (including
|
||||
`ii-base/` at its pin and the `ii-phone/` overlay, arch-gated as
|
||||
`deploy.sh` already gates on `TARGET_ARCH`).
|
||||
3. **A CI job**, matching the existing binaries' shape, publishing to the
|
||||
`souveraine-{arch}` db on `edge`. Note the CLAUDE.md trap: only `public`
|
||||
publishes, and a skipped job does not make a run red — check the jobs, not
|
||||
the run.
|
||||
4. **Keep `deploy.sh` for the laptop dev loop**, where fast iteration matters and
|
||||
the tree is not a daily driver. It should stop being the phone's path.
|
||||
5. **Interim mitigation, cheap and worth doing first:** give the `--phone` rsync
|
||||
the same `snapshot_tree` treatment the local compose already has, so a
|
||||
mistaken deploy is recoverable while the package work happens.
|
||||
|
||||
## Connects to
|
||||
|
||||
- [[29-souveraine-updater]] — the pipeline this rides.
|
||||
- `souveraine/CLAUDE.md` — the "everything ships as a package" rule this is the
|
||||
standing exception to.
|
||||
- TASK-18 (selection menu) surfaced it: new shell files currently have no route
|
||||
to the phone other than the destructive one.
|
||||
|
|
@ -58,7 +58,6 @@ Four that are cheap relative to what they unblock:
|
|||
|
||||
| # | Task | What's left |
|
||||
|---|------|-------------|
|
||||
| 49 | [The shell surface is not a package, and it eats on-device edits](49-shell-surface-is-not-a-package.md) | `deploy.sh --phone` rsyncs `--delete` into the phone's tree with **no snapshot** — on-device edits are destroyed with no record. Root cause is installing into `$HOME`, which has no ownership model. Payload belongs in `/usr/share`, `$HOME` keeps only overrides. |
|
||||
| 48 | [Shell dies on any reload that owes a lock](48-lock-surface-reload-fatal.md) | Fully diagnosed 07-29, 11 crashes since 07-17. A reload re-requests ext-session-lock while the outgoing instance still holds it → `FATAL: Tried to show lockscreen surfaces without active lock`. **Sync with TASK-43 before touching the lock path.** |
|
||||
| 47 | [Auto-brightness: anchors, none of it built](47-auto-brightness-anchors.md) | §12 reads as settled and has **zero** code behind its actuation half — no brightness `Action`, no anchors, `grep anchor src/` is empty. The evidence half (lux in, health tracked) is live. |
|
||||
| 46 | [Camera: **the front camera works**](46-camera-imx363.md) | **First frame captured 2026-07-29** on the running kernel — no reboot, no DT change. Both front IMX355 were already bound; nobody had tried streaming. Recipe + the stride/packing gotchas are in the task. Next: exposure controls, then libcamera. Rear IMX363 DT (`c7784b716`) still unbuilt but no longer the blocker. |
|
||||
|
|
|
|||
Loading…
Reference in a new issue