Preferred path: friend installs LastDB + Org β shows a public key β you seal the org key to that key β they join. The sealed package may travel on any clear channel (email/Slack/Signal). Friend does not need an Exemem account.
Only optional cloud/admin features need an Exemem account later. Invite identity
is just a public key (orgpk1:β¦).
| Need | How |
|---|---|
| macOS Apple Silicon | β |
| Bun | https://bun.sh |
| LastDB Mini running | brew install edgevector/lastdb/lastdb + brew services start lastdb |
| LastSecrets | https://github.com/EdgeVector/lastsecrets β bun link + lastsecrets init |
| Org | https://github.com/EdgeVector/org β bun link + org init |
Recommended one-shot (installs org + lastsecrets + other apps):
export PATH="$HOME/.bun/bin:$HOME/.local/bin:$PATH"
git clone https://github.com/EdgeVector/last-stack ~/.last-stack
~/.last-stack/setup
~/.last-stack/bin/last-stack-install-apps
brew services start lastdb
lastsecrets init
org initHealth check (path is /health, not /api/health):
curl -s --unix-socket ~/.lastdb/data/folddb.sock http://localhost/health
# expect: {"status":"ok"}Install LastDB + apps (includes org):
https://thelastdb.com/llms.txt
or: last-stack-install-apps from https://github.com/EdgeVector/last-stack
No Exemem account needed.
export PATH="$HOME/.bun/bin:$HOME/.local/bin:$PATH"
lastsecrets init # once per machine
org init # once per machine
org receiveFriend copies the orgpk1:β¦ line (and optional fingerprint) back to you.
Safe on any channel.
export PATH="$HOME/.bun/bin:$HOME/.local/bin:$PATH"
# once:
# lastsecrets init && org init
# org create friends --name "Friends"
org invite friends --to 'orgpk1:PASTE_THEIR_KEY' --agentCopy the printed orgseal1:β¦ package (and agent instructions if helpful)
to the friend over any channel. Clear-channel safe β encrypted to their key.
org join --sealed 'orgseal1:PASTE_PACKAGE' [--member-name "Your Name"]
# or: org receive --sealed 'orgseal1:β¦'
org show friendsMust use the same machine that ran org receive (same local private key
under ~/.org/).
Invites expire (default 72h; admin sets --expires-in 30m|72h|14d). An
expired invite is rejected at join with nothing stored β ask for a fresh one.
org join prints a line starting with acceptance=orgaccept1:β¦. Send that
full token back to the admin over any channel β it contains no secrets (it is
encrypted with the org key and self-signed by your member identity).
org member add friends --accept 'orgaccept1:PASTE_TOKEN' [--role member]
org member list friendsMembership lands only as an owner-signed epoch in the org's registry chain β there is no mutable member row. Each acceptance is one-time: a replayed token is rejected and no epoch is minted. To remove someone from the registry later:
org kick friends <member_id> # revocation epoch (non-retroactive)
org member revoke friends <hash> # separate lever: stop their live cloud syncWhen you cannot do the pubkey handshake (AirGap USB, etc.):
org invite friends --out ~/Desktop/friends.invite.json --agent
# hand the file OOB β it contains the raw e2e key
# friend:
org join --from ~/Downloads/friends.invite.jsonNever paste invite JSON into email/chat. Delete the file after join.
org invite --to mailto:β¦ still issues a portable token (AES envelope with
embedded key). Treat that token like a password. Prefer orgpk1: sealing.
| On the wire | OK? |
|---|---|
| Install link | Yes |
Friend orgpk1:β¦ public key |
Yes |
orgseal1:β¦ package |
Yes (encrypted to friend) |
| Raw org E2E key / invite JSON | No |
- Kick someone: rotate the org E2E key and re-invite remaining pubkeys (shared-secret model β deleting a name does nothing if they still have the key).
- Names/People mapping is out of band (or a future People app), not required here.
- Continuous multi-device data sync is separate: membership hands out keys;
Mini cloud sync (
cloud_sync.json/lastdb connect) is what converges encrypted org logs across machines.
| Symptom | Fix |
|---|---|
command not found: org |
export PATH="$HOME/.bun/bin:$HOME/.local/bin:$PATH"; re-run install / bun link in the org checkout |
App schema not loaded / missing schema |
Re-run org init on a current Mini (brew upgrade lastdb / Last Stack install) |
join --sealed fails after receive on another laptop |
Sealed packages bind to the receive keypair; re-run org receive on the join machine and re-invite |
org show works but friend never sees your writes |
Cloud sync not enabled on both nodes β membership alone is local; see Mini cloud sync docs |
| Health check fails | brew services start lastdb; socket ~/.lastdb/data/folddb.sock |
Boots two throwaway Mini homes and proves the preferred public-key path:
friend org receive β admin org invite --to orgpk1:β¦ --agent β friend
org join --sealed β org show.
# from an org checkout
LS_CLI=~/lastdb-apps/lastsecrets/src/cli.ts \
# or: LS_CLI=~/.host-track/apps/lastsecrets/current/src/cli.ts
scripts/invite-e2e-dogfood.sh
# expect: VERDICT: GREENNever points either home at the primary ~/.lastdb brain.