Capture the design for the two tier-2 items that weren't shipped inline in alpha.28 — both require CI/infrastructure work (GitHub Actions, Homebrew tap, winget manifest) or broker schema migration that's safer to do as a separate PR with feature flag rollout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.1 KiB
Per-Peer Capabilities
Goal
Give mesh members fine-grained control over what peers can do to their
session. Today: any mesh peer can send you any message; all messages get
pushed as <channel> reminders. Users can't say "only @alice can send me
messages," "read-only peers," or "@bob can broadcast but not DM."
Current state
- Mesh-level role:
admin|member(only affects invite issuance) - No per-peer filter — every peer message is delivered
- No per-peer read/write split (all peers have the same capabilities)
Target capability model
| Capability | Meaning |
|---|---|
read |
Peer appears in your list_peers, can see your summary |
dm |
Peer can send you direct messages |
broadcast |
Peer's group broadcasts reach you |
state-read |
Peer can read shared state keys |
state-write |
Peer can set shared state keys |
file-read |
Peer can read files you've shared (already exists) |
CLI surface
claudemesh grant @alice dm broadcast # allow direct + broadcast
claudemesh grant @bob state-read # read-only
claudemesh revoke @alice broadcast
claudemesh grants # list current grants per peer
claudemesh block @spammer # shorthand for revoke-all
Broker schema
New column on mesh_member:
peer_grants jsonb DEFAULT '{}'::jsonb
-- shape: { "<peer_pubkey_hex>": ["dm", "broadcast", ...] }
Alternative (cleaner): separate peer_grant table keyed on
(member_id, target_pubkey).
Enforcement point
Broker's message router (apps/broker/src/index.ts — send flow).
Before writing the encrypted message to the recipient's queue, check
recipient.peer_grants[sender_pubkey] against message kind. Drop
silently if disallowed (sender sees delivered, recipient sees nothing —
matches Signal/iMessage block semantics).
Defaults
- Unknown peers:
read + dm(matches current behavior — additive-safe rollout) - Existing members: grandfathered into
read + dm + broadcast + state-readvia a migration claudemesh profile --default-grants read dmlets users change their own default
UI
claudemesh peersrenders a[grants: dm,broadcast]tag per peerclaudemesh verifygains a--with-grantsflag that shows the grant set alongside the safety number (helps the "did I accidentally block them?" check)
Crypto implications
Grants are server-enforced metadata. Not capability tokens. A malicious broker could forward messages regardless — this is about UX trust (spam / noise control), not protocol security. The spec is clear about this.
Migration plan
- Ship broker schema change (jsonb column, nullable, default
{}). - Ship
grant/revoke/grants/blockCLI commands against an unused column. - Enable enforcement in broker behind a per-mesh feature flag.
- Flip on for all meshes.
Priority
Nice-to-have. The killer feature here is block — every mesh gets a bad
actor eventually. Ship block first even if the full grant system is deferred.