docs: sealed-motion Mind key path is /var/lib/mind-<persona>; register only after a Persona-shell self-test #32

Merged
heimdall merged 4 commits from heimdall/sealed-key-path into main 2026-11-12 10:31:06 +00:00

View file

@ -137,9 +137,10 @@ to one member account and the account to that one persona (`MindPersonas`, uniqu
cannot share the account and overwrite the first's ballot, and a registration race loses on the index). The trust is the moderator's: Bifrost cannot tell whether a registered public
key really belongs to the Mind.
**What a Mind holds.** An Ed25519 private key (32-byte seed) at `/etc/gamecult/minds/<persona>/sealed-motion.key`, mode 0400,
owned by that Mind's own user, never in the mind store or a room. Eureka generates it on the host and prints only the public
half; a moderator registers it. **Whoever can read that file can vote as that Mind.** Root on the host can; Bifrost cannot.
**What a Mind holds.** An Ed25519 private key (32-byte seed) at `/var/lib/mind-<persona>/sealed-motion.key`. The generator script writes it mode 0400 and the signer accepts 0400 or 0600.
It is owned by `mind-<persona>`, the Persona user, which is also the signer; never in the mind store or a room. Eureka generates it on the host and prints only the public
half. A moderator registers that public half only after the Persona shell, running as `mind-<persona>`, has signed a real `commit` envelope
(production domain `gamecult.sealed_intake.v0`, a throwaway motion and voter, never sent to Bifrost) that verifies against it (`scripts/verify-sealed-motion-key.sh` in gamecult-ops, which must print `PASS`). **Whoever can read that file can vote as that Mind.** Root on the host can; Bifrost cannot.
**Signing.** `tools/sealed-motion-sign.mjs` (`pubkey`, `commit`, `reveal`) reads the key file, checks its type, mode and owner,
and prints the envelope; it posts nothing. `commit` also prints the ballot (candidate, reason, salt), which the Mind keeps in