distribution: add ViewTop to the laptop body
Record update delivery as a per-body offer and local candidate activation after a live shell push killed an active conversation.
This commit is contained in:
parent
74e3bc5233
commit
d8820da557
4 changed files with 49 additions and 5 deletions
|
|
@ -12,6 +12,10 @@ its release lands. Those decisions live here, once.
|
|||
|
||||
- `manifest.toml` is the canonical body, package, producer, and installer
|
||||
profile graph.
|
||||
- A package normally names one `producer`; when architecture-specific release
|
||||
paths live in different repositories it names `producers` explicitly. This
|
||||
records one package identity without pretending one workflow built both
|
||||
bodies.
|
||||
- The signed `edge` archive is one multi-producer archive. Its implementation
|
||||
currently lives in `souveraine/packaging/arch/publish-edge.sh`; this manifest
|
||||
names it so consumers do not grow their own publisher.
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ repository = "Fimeg/Pixel3Arch"
|
|||
workflow = ".gitea/workflows/packages.yml"
|
||||
architectures = ["aarch64"]
|
||||
|
||||
[producers.souveraine-viewtop]
|
||||
repository = "Fimeg/souveraine-viewtop"
|
||||
workflow = ".gitea/workflows/ci.yml"
|
||||
architectures = ["x86_64"]
|
||||
|
||||
# Current packages. `managed` means a producer and shared archive path exist;
|
||||
# it does not assert that the newest run is green. `blocked` and `planned` are
|
||||
# intentionally visible to the installer gate.
|
||||
|
|
@ -32,7 +37,7 @@ architectures = ["aarch64"]
|
|||
souveraine = { producer = "souveraine", architectures = ["x86_64", "aarch64"], state = "managed" }
|
||||
upower-souveraine = { producer = "souveraine", architectures = ["x86_64", "aarch64"], state = "managed" }
|
||||
souveraine-updater = { producer = "souveraine-updater", architectures = ["x86_64", "aarch64"], state = "managed" }
|
||||
souveraine-viewtop = { producer = "pixel3arch", architectures = ["aarch64"], state = "managed" }
|
||||
souveraine-viewtop = { producers = ["pixel3arch", "souveraine-viewtop"], architectures = ["aarch64", "x86_64"], state = "managed" }
|
||||
linux-blueline = { producer = "pixel3arch", architectures = ["aarch64"], state = "blocked", blocker = "kernel.yml does not publish into the shared archive" }
|
||||
souveraine-callaudio = { producer = "pixel3arch", architectures = ["aarch64"], state = "managed" }
|
||||
souveraine-callaudiod = { producer = "pixel3arch", architectures = ["aarch64"], state = "managed" }
|
||||
|
|
@ -68,8 +73,8 @@ blockers = ["linux-blueline is not published to the shared archive", "rootfs ove
|
|||
[profiles.x86-laptop]
|
||||
status = "blocked"
|
||||
architectures = ["x86_64"]
|
||||
packages = ["souveraine", "upower-souveraine", "souveraine-updater"]
|
||||
blockers = ["laptop installer and hardware profile are not implemented"]
|
||||
packages = ["souveraine", "upower-souveraine", "souveraine-updater", "souveraine-viewtop"]
|
||||
blockers = ["package-owned shell and ViewTop session are not implemented", "laptop installer and hardware profile are not implemented"]
|
||||
|
||||
[profiles.d10]
|
||||
status = "blocked"
|
||||
|
|
|
|||
|
|
@ -158,6 +158,34 @@ live sysfs + D-Bus backend, so a battery/charge page can be honest today.
|
|||
So: package the surfaces → expose what already actuates (charge, existing
|
||||
pages) → add state-machine controls as TASK-15/08 wire them up.
|
||||
|
||||
### 2026-08-11 — an update is offered to a body, not pushed through its glass
|
||||
|
||||
Observed on the Pixel daily driver: `deploy.sh --phone` passed its lock check,
|
||||
snapshotted the tree, and still replaced the live QuickShell composition while
|
||||
Casey was using it. The reload killed an active Souveraine conversation. A
|
||||
rollback makes the files recoverable; it does not make destroying live session
|
||||
state an acceptable delivery protocol.
|
||||
|
||||
Casey's required development shape is now explicit:
|
||||
|
||||
1. CI publishes a signed, immutable surface candidate. The laptop never rsyncs
|
||||
that candidate directly over a live body's active tree.
|
||||
2. A connected-device channel may announce that a development update is
|
||||
available and safe to evaluate. USB Signaller is a possible transport for
|
||||
that offer; it is not the update authority and attachment is not consent.
|
||||
3. Each body answers independently. Its local updater acquires the durable
|
||||
maintenance lease, verifies the package and target profile, stages beside
|
||||
the running candidate, and reports what would change.
|
||||
4. Activation is an explicit local transition with conversation/session state
|
||||
preserved or deliberately quiesced, a health check, and an automatic return
|
||||
to the last working candidate. One connected device accepting must not make
|
||||
every connected device switch.
|
||||
|
||||
`deploy.sh --phone` remains a recovery/developer instrument for an explicitly
|
||||
quiesced target. It is no longer the ordinary update path. TASK-08 owns the
|
||||
lease and state projection; the updater owns retrieval and candidate
|
||||
activation; USB Signaller can carry presence and offers only.
|
||||
|
||||
## The actual inventory (measured 2026-07-25)
|
||||
|
||||
379,153 files under `/usr /etc /opt /boot`; **5,624 owned by nothing**. The
|
||||
|
|
|
|||
|
|
@ -40,8 +40,15 @@ def main() -> int:
|
|||
for name, package in packages.items():
|
||||
if package.get("state") not in PACKAGE_STATES:
|
||||
error(f"package {name}: invalid state {package.get('state')!r}")
|
||||
if package.get("producer") not in producers and package.get("state") != "planned":
|
||||
error(f"package {name}: unknown producer {package.get('producer')!r}")
|
||||
package_producers = package.get("producers")
|
||||
if package_producers is None:
|
||||
package_producers = [package.get("producer")]
|
||||
if not package_producers:
|
||||
error(f"package {name}: no producer declared")
|
||||
elif package.get("state") != "planned":
|
||||
for producer in package_producers:
|
||||
if producer not in producers:
|
||||
error(f"package {name}: unknown producer {producer!r}")
|
||||
if not package.get("architectures"):
|
||||
error(f"package {name}: no architecture declared")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue