Permissions and tiers
Every call is sorted before anything runs: a guest, someone you asked, or a contact you approved, each seeing a different set of tools.
Three tiers
A call carries a chain — as the client certificate or inside a sealed envelope’s signature — and the receiver validates it first (§ 14.2). Then the root decides. A root that resolves to no pin, a blocked one, or a leaf older than the pinned one is a guest: two tools, redeem_invite and request_contact. A root I asked to be my contact, answering from its pinned endpoint, is pending: contact_accepted and contact_rejected, and every other call from it answers pending_approval. An active pin at its endpoint is a contact, and sees the tools its permission profile grants. A leaf newer than the pinned one, at the pinned endpoint, replaces it on the way through — that is a renewal, learned; a different endpoint is a new address (§ 6.1, § 5.3).
The switchboard
Permissions are a per-contact switchboard, controlled by the owner and enforced at the owner’s server on every call. Changes apply instantly and need no wire protocol: flip a switch, and the tool disappears from that caller’s tools/list while calls to it return permission_denied (§ 8).
| Permission | Gates | In the “basic” preset |
|---|---|---|
message.text | send_message | yes |
message.media | send_media | no |
status.view | get_status | no |
calendar.availability | check_availability | no |
calendar.book | book_slot, cancel_booking | no |
integration.<name> | every tool that integration exposes | no |
Four presets ship as documented defaults: basic grants text only; work adds availability and booking; friend adds media and status to that; family is the same bundle as friend, the distinction being the owner’s to draw. A preset is a label for a bundle, not a lock: hand-toggle one switch and the grant is bespoke. Integration grants sit outside presets in both directions — applying a preset never grants one and never revokes one (§ 8). update_contact, remove_contact and get_card are always present at the contact tier (§ 6.2).
Budgets
Every call budget is a token bucket, a sustained rate and a burst. By default a contact may make one call a second with a burst of ten; the identity’s contacts together get the number of contacts it may hold times that rate; a guest gets ten calls an hour per address and key. Every call that reaches dispatch spends, tools/list included, and the values in force are advertised in get_card’s limits (§ 12).
Blocked looks exactly like unknown
Blocked is indistinguishable from never-met: a blocked sender’s calls and envelopes are processed exactly as an unknown sender’s, so nothing — not a refusal, not a sealing answer — becomes an oracle for who the owner knows (§ 5, § 13.3, § 12).