Watch
1
0
Fork
You've already forked SouveraineOS
0

provisioning-gaps: log every hand-fill from the first federation test

STATE.md: federation test passed — two instance branches, both agents
speaking on glm-5.2, identities split.
This commit is contained in:
Fimeg 2026-07-16 16:11:15 -04:00
commit b563c37d0a
2 changed files with 155 additions and 19 deletions

View file

@ -25,25 +25,42 @@ Branch `experimental/session-trust-phase1` @ `c96f95b`.
(pre-`memory sync`) — superseded.
## NEXT SESSION (Casey's stated order, 2026-07-16 evening)
1. **Souveraine phone-side test** — get phone AND laptop on the fresh
`c96f95b` build, then test agent transfer between them. The phone's
agent memfs is MORE UP TO DATE than the laptop's — phone is source of
truth; never clobber it. Sequence per FEDERATION.md: provision machined
on both (`sudo souveraine machine init --migrate-from
~/.souveraine/seed-id` + enable `packaging/souveraine-machined.service`,
sysusers), provision one bare memfs remote on Gitea for the agent,
`git -C <memfs> remote add origin <url>` on both, `memory sync` both
sides, verify two `instance/*` branches on the remote. Merge policy
(step 3) is NOT built — first test is push/fetch + branch visibility,
not reconciliation.
2. **Auxo tray + Chatty**. Auxo-style multitasking tray under the dock —
design first (talks only so far). Chatty: Casey says "the contacts app
is still needed to land so matrix can stay logged in" — the two open
pieces in that area are the qtpim contacts direction
(docs/qtpim-contacts-handoff.md, three paths, undecided) and
souveraine-secrets as the libsecret backend Chatty/libcmatrix need for
token persistence (committed, never build-verified). Confirm with Casey
which dependency he means before building.
1. **Souveraine phone-side test — DONE, PASSED (2026-07-16 late).** Both
machines on `b4dc39e` (laptop x86_64 + phone aarch64), agents speaking on
glm-5.2. Machine identities split (laptop `6344f24e…` ▽●△△ lineage via
`--migrate-from`; phone `69bf24d7…` ▽■◑★ fresh). `memory sync` ran on both
sides via the agents' own tool: two `instance/*` branches on the Gitea
remote, laptop's fetch surfaced the phone's branch. Phone Souveraine wrote
`system/instances.md` unprompted after reading the briefing. Root cause of
the mute-agent detour: agent-level `provider: claude` + empty key hitting
Anthropic's OpenAI-compat 401 — fixed; plus the silent-turn-death and
`reasoning_content` fixes (`33068d6`/`b4dc39e`). Every manual gap-fill from
the test is recorded in `docs/provisioning-gaps.md` — that file is design
input for the commission ceremony. Merge policy (FEDERATION.md step 3)
remains the next transport build step. Phone hard-reset once mid-chat
(no pstore configured — gap §5); phone memfs remains source of truth.
2. **Auxo tray + Chatty/contacts**. Auxo-style multitasking tray under the
dock — design first (talks only so far). Contacts: RESOLVED 2026-07-16 —
the store is the **user's** address book, user-owned, Annie has a
capability over it (Android runtime-permission model, not Annie's brain).
Design of record: `docs/contacts-design.md` (trust boundary, capability
gate, tier semantics, build order); `docs/qtpim-contacts-handoff.md`
holds qtpim build state + the three backend paths (path 3 = sqlite engine
against upstream dev, chosen). **secrets is NOT a blocker**
souveraine-secrets (`04a8390`) is built; token persistence is solved.
First build move is naming the trust-tier signal boundary with whoever
owns session-trust (the capability gate is greenfield in the substrate;
`src/core/session/mod.rs` is message-types only).
**Chatty RCS — investigated, options in `docs/messaging-rcs.md`.** Carrier
fact: Fido = Jibe (Rogers shipped RCS to Google's cloud in 2016), so there's
no carrier UP server → rust-rcs-client is out for Casey's number. The live
path is a Jibe puppeting transport, **unblocked because Play Integrity is
defeatable at the system layer** (Casey already does this on every LineageOS
install; PIF→PIF-NEXT/keybox injection lineage). Corrected from an earlier
wrong "fixed wall" framing. Real costs: adversarial keybox supply chain,
Google-cloud routing (already true of carrier RCS), Google-protocol client.
Time-boxed posture debt, highest capability tier, P3-visible. Long-arc
default stays Matrix-first + SMS fallback. No code touched.
- Federation memory transport, first two steps landed (`8cfa992`,
`a62379a`): `memfs_commit` presence signal on the bus after every memfs
mutation (replaces the unconsumed `memory_*` events), and `memory sync`

119
docs/provisioning-gaps.md Normal file
View file

@ -0,0 +1,119 @@
# Provisioning gaps — what got hand-filled on 2026-07-16
Every item here is a manual intervention performed during the first live
federation test (laptop + Pixel 3, agent Souveraine). Each one is a gap the
real setup flow — the node commission ceremony FEDERATION.md parks — must
close. This file is the evidence log: if we don't record what we did by hand,
the ceremony gets designed from memory and misses them.
Ordering is by how badly the gap bit, not by build order.
## 1. Agent provider config drift — silent until b4dc39e
**What happened:** Souveraine's `agent.json` carried `provider: claude` with an
empty key while its model said `glm-5.2`. A model sweep updates `model`; nothing
polices `provider`. Every turn 401'd against Anthropic's OpenAI-compat endpoint
and, before the error-event fix, rendered as the agent going mute.
**What the system must do:** a preflight at agent load (or config write):
resolve the agent's provider chain and fail loudly if the key is empty or the
provider unreachable. "Can this agent speak?" is a checkable invariant, not a
runtime surprise.
## 2. Memfs remote naming — `gitea` vs `origin`
**What happened:** `memory sync` requires an `origin` remote. Existing memfs
checkouts carried the same URL under the name `gitea`. Fixed by aliasing on
both machines by hand.
**What the system must do:** commission-time provisioning names the shared
remote `origin`, and/or `sync` accepts a configured remote name. Existing
checkouts need a migration nudge, not a silent error.
## 3. Cloned machine identity — the shared-seed trap
**What happened:** the phone's `~/.souveraine` was cloned from the laptop, so
both machines held the same `seed-id` (6344f24e…) for months. Left alone, both
would have pushed the same `instance/` branch and the federation test would
have proven nothing. Split by hand: laptop `machine init --migrate-from`,
phone `machine init --fresh`.
**What the system must do:** commission ceremony detects a seed that already
exists in the federation (registry or remote branch collision) and forces the
fresh-mint path. A cloned filesystem must not silently become a cloned
identity.
## 4. Agent server is a hand-started process
**What happened:** on both machines `souveraine server` runs as a
`setsid`/nohup user process logging to `/tmp`. The phone hard-reset and the
server simply didn't exist afterward; restart was manual over SSH. Its logs
die with `/tmp`.
**What the system must do:** a user systemd unit (`souveraine-server.service`)
with journal logging and restart policy, installed by packaging, enabled at
commission. The machined precedent already exists — mirror it.
## 5. No crash forensics on the phone
**What happened:** the phone hard-reset mid-`souveraine chat` (14:11). No
shutdown record, no coredumps, journal stops mid-write, `/sys/fs/pstore` is
empty. The reset is unattributable — thermal, watchdog, TZ/remoteproc wedge —
because nothing was configured to remember it.
**What the system must do:** wire ramoops/pstore (Android configures it on
this exact hardware — the reference answer, per the Android-is-the-reference
rule). Belongs in Pixel3Arch kernel/DT work, not the ceremony, but the
ceremony should *verify* pstore is live on phone-class nodes.
## 6. machined socket ACL doesn't survive restart
**What happened:** `usermod -aG souveraine` lands at next login; until then a
manual `setfacl` on `/run/souveraine` is needed after every machined restart.
Done by hand twice today.
**What the system must do:** packaging owns it — tmpfiles.d or group-writable
socket creation in machined itself, so a restart never strands the user
session.
## 7. Instance label ↔ glyph mapping doesn't exist agent-side
**What happened:** sync reports branches as machine-pubkey prefixes
(`instance/69bf24d7b185`). The laptop agent, asked whether the peer branch was
the phone, correctly refused to confirm — it has no stored association between
glyphs (▽●△△ / ▽■◑★) and instance labels, and said recording Casey's
assertion isn't verification. It was right.
**What the system must do:** the `memfs_commit` payload and `sync` output
should carry the glyph alongside the pubkey; the in-memfs `system/instances.md`
(which the phone agent wrote unprompted after reading the briefing) is the
durable half. Commission stamps the mapping; the agent never has to take it on
faith.
## 8. Binary deploys are scp + pkill by hand
**What happened:** deploy = scp from archdev, `sudo install`, then kill and
restart the server — including the recurring pkill-matches-own-ssh-cmdline
footgun, hit twice this session.
**What the system must do:** packaging (PKGBUILD or a deploy script in-repo)
plus the systemd unit from §4 makes deploy = install + `systemctl restart`.
## 9. New system files aren't surfaced to the agent
**What happened:** a briefing file written directly into the phone memfs was
invisible to the primary until the subconscious caught the false "no such
file" claim and corrected it mid-thread ([intrusive] surfacing — the
architecture working as designed, but as a backstop, not a flow).
**What the system must do:** memfs writes that arrive from outside the agent's
own tool path (human edits, sync merges) should generate the same felt signal
as local compaction — this is FEDERATION.md's receive-side doctrine; the local
case (files appearing on disk between turns) needs it too.
---
Resolved during the same session, recorded for completeness: `hosted_agents`
announce read the wrong tree (`server/agents/` vs `agents/`) — fixed with a
regression test in `da410b1`; silent turn-death — fixed end-to-end error
events in `33068d6`/`b4dc39e`.