Decouple the signing identity from the network identity. This phase
ships the plumbing only — every device still has exactly one posting
identity, copied from the network key on first 0.6.3 launch so all
existing signed content keeps verifying. Phase 5 builds the
multi-persona UX on top.
Types:
- New PostingIdentity struct: { node_id, secret_seed, display_name,
created_at }
Storage:
- New posting_identities(node_id, secret_seed, display_name,
created_at) table
- Methods: upsert / get / list / delete posting identities;
get/set default posting id (stored in settings)
- seed_posting_identity_from_network: idempotent migration inserts
the network key as the single posting identity and sets it default
on first 0.6.3 launch
Node:
- default_posting_id + default_posting_secret fields populated on
startup via the migration
- All content signing / encryption / key wrapping now uses
default_posting_secret; the old Node.secret_seed field is gone
(iroh holds the network secret internally)
- author field on all locally-created content is now
default_posting_id (equal to node_id for upgraders until Phase 5
introduces separate personas)
- Auto-follow-self covers both network_id and default_posting_id
(same in 0.6.3, may diverge in 0.6.4+)
Export/import:
- Bundle now includes posting_identities.json in
IdentityOnly / PostsWithIdentity / Everything scopes
- restore_posting_identities(zip, storage) reads and upserts on
import
Smoke-tested:
- Fresh 0.6.3 install: posting_identities seeded from network key;
default set; new post's author = default_posting_id = network_id
- Two-node pull sync: B pulls A's post, signature verifies across
the wire
- 111 core tests pass
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>