plan(kez-chat): handles are tudisco@kez.lat, not @tudisco@kez.lat

Fix the doc: a kez-chat handle looks like an email address —
local@server — with NO leading @. The leading @ is mention syntax
in chat ("hey @tudisco look at this"), the same convention Slack /
Twitter / Discord use. It's not part of the handle.

Three forms now spelled out in §3.1:

  Storage / wire    tudisco@kez.lat        (always fully qualified)
  Display (UI)      tudisco                (when default server; full when cross-server)
  Mention (chat)    @tudisco               (in-message convention; UI resolves)

Specifically updated:
- §1 opener mentions the email-style form + note about mention syntax
- §3.1 fully qualified form, no leading @, with the three-forms table
- §5.1 account creation heading and step 12 now use tudisco@kez.lat
- §5.2 local cache key is "chris@kez.lat" not "@chris@kez.lat"
- §12 summary updated

ActivityPub identifiers in SPEC.md (ap:@jason@mastodon.social) are
unchanged — that's the ActivityPub convention for a different
addressing system.

In-text narrative mentions like "@tudisco shares a file with @chris"
and CLI examples like `kez-chat add @chris` are intentionally
preserved — those use the mention syntax, which the CLI resolves
to the full handle.
This commit is contained in:
Tudisco 2026-05-24 22:55:08 -06:00
parent 6dfd5a6938
commit 055040423e

View File

@ -11,7 +11,9 @@ identity stack, with NATS for messaging and Iroh for file transfer.
A real-time chat + file-sharing application with verified identities. A real-time chat + file-sharing application with verified identities.
- Users get human-friendly handles like `@tudisco@kez.lat`. - Users get human-friendly handles like `tudisco@kez.lat`
(email-style — no leading `@`; that's mention syntax in chat, not
part of the handle itself, see §3.1).
- The handle is bound to a KEZ ed25519 primary key; the same key - The handle is bound to a KEZ ed25519 primary key; the same key
authenticates to the chat infrastructure. authenticates to the chat infrastructure.
- Conversations are end-to-end encrypted; the broker is dumb. - Conversations are end-to-end encrypted; the broker is dumb.
@ -66,14 +68,28 @@ a verifier "this user's broker is X, their Iroh nodes are Y₁ and Y₂."
### 3.1 Handles ### 3.1 Handles
Handles look like email and Mastodon addresses: Handles look like email addresses`local@server`, no leading `@`:
``` ```
@tudisco@kez.lat tudisco@kez.lat
@chris@kez.lat chris@kez.lat
@alice@chris.com ← custom domain, opted out of default (future) alice@chris.com ← custom domain, opted out of default (future)
``` ```
**The leading `@` is mention syntax, not part of the handle.**
When a user writes "hey @tudisco, check this" in a chat message,
that's exactly like @-mentions in Slack/Twitter/Discord — the `@` is
a UI convention that says "this token is a person reference." The
underlying handle being referenced is `tudisco@kez.lat`.
Three forms in the system:
| Form | Where | Example |
|---|---|---|
| Storage / wire | Database, sigchain, registry lookups | `tudisco@kez.lat` (always fully qualified) |
| Display | UI, profile pages | `tudisco` when the server is the app's default; full `tudisco@kez.lat` when cross-server |
| Mention | Inside chat messages | `@tudisco` (chat-app convention; UI resolves to the full handle in context) |
`kez.lat` is the placeholder default home server domain. We'll lock in `kez.lat` is the placeholder default home server domain. We'll lock in
the real production domain before launch. the real production domain before launch.
@ -83,8 +99,8 @@ namespaces) is deliberately not in v0, but the design must not preclude
it. See §3.5. it. See §3.5.
In the UI, since there's only one home server in v0, handles are In the UI, since there's only one home server in v0, handles are
displayed bare (`@tudisco`). The `@kez.lat` suffix is implied and stored displayed bare (`tudisco`). The `@kez.lat` suffix is implied. Storage
internally. and the wire always use the fully-qualified form.
### 3.2 Key generation tied to username ### 3.2 Key generation tied to username
@ -103,7 +119,7 @@ When a user creates an account:
4. App **uploads the sigchain** to the deployed `kez-sig-server`. 4. App **uploads the sigchain** to the deployed `kez-sig-server`.
After this flow the user has a fully working KEZ identity: After this flow the user has a fully working KEZ identity:
- `@tudisco@kez.lat` resolves via the handle registry to their primary key. - `tudisco@kez.lat` resolves via the handle registry to their primary key.
- That key's sigchain (on `kez-sig-server`) advertises their NATS broker and Iroh nodes. - That key's sigchain (on `kez-sig-server`) advertises their NATS broker and Iroh nodes.
- Other users can verify them and reach them. - Other users can verify them and reach them.
@ -322,7 +338,7 @@ Sigchain endpoints are **not** on this server — clients talk directly to
## 5. End-to-end flows ## 5. End-to-end flows
### 5.1 Account creation — `@tudisco@kez.lat` ### 5.1 Account creation — `tudisco@kez.lat`
``` ```
1. User opens chat app, clicks "Create account" 1. User opens chat app, clicks "Create account"
@ -345,7 +361,7 @@ Sigchain endpoints are **not** on this server — clients talk directly to
nats-server invokes chat-server's auth callout, gets back yes/no nats-server invokes chat-server's auth callout, gets back yes/no
+ allowed subjects) + allowed subjects)
11. App: subscribes to JetStream durable consumer on its inbox subject 11. App: subscribes to JetStream durable consumer on its inbox subject
12. Done — @tudisco@kez.lat is live and reachable 12. Done — `tudisco@kez.lat` is live and reachable
``` ```
### 5.2 Adding a contact ### 5.2 Adding a contact
@ -359,7 +375,7 @@ Sigchain endpoints are **not** on this server — clients talk directly to
- NATS broker URL + inbox subject (from add_endpoint nats) - NATS broker URL + inbox subject (from add_endpoint nats)
- Iroh node IDs (from add_endpoint iroh) - Iroh node IDs (from add_endpoint iroh)
- Other identity claims (github:chris, dns:chris.com, etc. — for display) - Other identity claims (github:chris, dns:chris.com, etc. — for display)
5. App caches LOCALLY: { "@chris@kez.lat" => ed25519:abc..., endpoints: {...} } 5. App caches LOCALLY: { "chris@kez.lat" => ed25519:abc..., endpoints: {...} }
(TOFU — trust on first use) (TOFU — trust on first use)
``` ```
@ -741,8 +757,9 @@ When we start building:
## 12. One-paragraph summary ## 12. One-paragraph summary
`kez-chat` is a Keybase-class chat and file-sharing app built on the `kez-chat` is a Keybase-class chat and file-sharing app built on the
KEZ identity stack. Users get `@username@kez.lat` handles backed by an KEZ identity stack. Users get `username@kez.lat` handles
ed25519 primary key. The same key authenticates to a NATS broker (email-style; the leading `@` is mention syntax in chat, not part of
the handle) backed by an ed25519 primary key. The same key authenticates to a NATS broker
(chat, presence, file tickets — broker is dumb, clients do E2E with (chat, presence, file tickets — broker is dumb, clients do E2E with
ChaCha20-Poly1305 over X25519-derived keys) and identifies an Iroh ChaCha20-Poly1305 over X25519-derived keys) and identifies an Iroh
node (P2P bulk transfer, content-addressed blobs, on-demand fetch). node (P2P bulk transfer, content-addressed blobs, on-demand fetch).