Every person who contacts Curia — whether through email, Signal, or the HTTP API — is treated as a contact with an assigned trust level. Before Curia takes any action on a sender’s behalf, it checks who they are, how confident it is in their identity, and whether the channel they’re using is trusted enough for what they’re asking. These checks are deterministic: a sender either has permission or they don’t.Documentation Index
Fetch the complete documentation index at: https://curia.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
How trust scores work
Every inbound message from an external sender carries amessageTrustScore between 0.0 and 1.0. Curia computes this score in the dispatch layer before the coordinator ever sees the message.
The score combines three inputs:
| Channel | Trust level | Normalized weight |
|---|---|---|
| CLI | High | 1.0 |
| Signal | High | 1.0 |
| HTTP API | Medium | 0.6 |
| Low | 0.3 |
Score examples
| Sender | Score | Why |
|---|---|---|
| Brand-new email sender | ~0.12 | Low channel trust (0.3 × 0.4) + zero contact confidence |
| CEO-verified Signal contact | ~0.80 | High channel trust (1.0 × 0.4) + high confidence (0.95 × 0.4) |
| Unknown Signal sender | ~0.40 | High channel trust + zero contact confidence |
| Known email contact (long history) | ~0.52 | Low channel trust + high confidence |
Action thresholds
The coordinator checks the sender’smessageTrustScore before taking action. If the score falls below the threshold for the requested action, the request is declined.
| Action category | Minimum score | What this means |
|---|---|---|
| Information queries | 0.2 | Any authenticated message qualifies |
| Scheduling | 0.5 | Medium trust channel or a known email contact |
| Data export | 0.8 | High-trust channel and a verified contact |
| Financial actions | 0.8 | High-trust channel and a verified contact |
config/default.yaml under trust_policy and can be adjusted without a code change.
Trust thresholds do not apply to you (the CEO). Messages arriving via CLI, or from a contact with the
ceo role, are always trusted regardless of score. Curia never explains the trust system or mentions scores to external senders.Email sender verification
Email is the highest-risk channel because From headers can be spoofed. Curia adds an extra layer on top of the trust score: SPF, DKIM, and DMARC validation. Your email provider performs these checks at the server level. The email channel adapter reads theAuthentication-Results headers on every inbound message and maps them to a senderVerified flag:
senderVerified: true— SPF, DKIM, and DMARC all passsenderVerified: false— any check fails, or headers are absent (fails closed)
senderVerified: false, the coordinator will not take consequential actions — financial, data, or access changes — without confirmation via a verified channel like Signal or CLI.
Handling unknown senders
When Curia receives a message from someone not in your contacts, it follows the hold and notify policy for email and Signal: the message is held in a queue, and Curia mentions it to you at the next opportunity.Message arrives from an unknown sender
The dispatch layer looks up the sender’s channel identifier (
email address, Signal number) in the contacts database. No match is found. The message is placed in the held messages queue. An audit event is written with the sender identifier, channel, and routing decision.Curia notifies you
At the next conversation, Curia mentions the oldest held message: “By the way, you have a held email from
stranger@example.com about ‘Q3 Numbers’. Want me to identify them?”Curia surfaces one held message at a time — not a list — to avoid interrupting the conversation flow. You can ask for the full list at any time.You decide what to do
You have three options for each held message:
- Identify — tell Curia who the sender is. Curia creates a confirmed contact and replays the held message through normal processing with full contact context.
- Dismiss — discard the message. The sender’s provisional contact record is preserved in case they reach out again.
- Block — discard the message and mark the sender as blocked. Future messages from this sender are dropped without acknowledgment.
Adding contacts proactively
You don’t have to wait for someone to reach out. Tell Curia about people directly in conversation:“Add Sarah Chen, CFO at Acme. Her email is sarah.chen@acme.com and she’s on Signal at +15550001111.”Curia creates a contact record, links both channel identities as verified, and assigns the CFO role with its default permissions. You can also update existing contacts:
“Jenna’s new work email is jenna.torres@acme.com.”
“Grant Jenna permission to send emails on my behalf.”All contact mutations are confirmed with you before they’re written, and every change is audit-logged.
Contact deduplication
Curia runs a weekly background scan for likely duplicate contacts — for example, “Jenna Torres” and “J. Torres” who share the same email address. When potential duplicates are detected, Curia presents them to you for review:“I noticed two contacts that look like the same person:Curia never auto-merges contacts. You confirm every merge.I’d merge them into Jenna Torres (CFO). Want me to proceed?”
- Jenna Torres (CFO, verified email jenna@acme.com)
- J. Torres (no role, email jenna@acme.com)
How authorization works
Authorization runs through a three-layer check on every request from a non-CEO sender:- Per-contact overrides — explicit grants and denials you’ve set for this specific contact. These always win over role defaults.
- Role defaults — the default permissions and denials for the contact’s role (CFO, board member, direct report, advisor, etc.).
- Channel trust gate — even if role and overrides permit an action, the channel must be trusted enough. Financial and data actions require a high-trust channel.
Allowed, Denied, Blocked by channel trust, or Needs CEO decision.
Self-claimed identities
If someone messages on a new channel and claims to be an existing contact (“Hi, it’s Jenna”), that identity is taggedself_claimed and treated as unverified until you confirm it. Curia never auto-promotes self-claimed identities to verified status. An unverified identity is gated the same as an unknown sender for any consequential action.
Contact statuses at a glance
| Status | Who | Permissions |
|---|---|---|
| Provisional | New contacts — not yet confirmed by you | None. Curia acknowledges but takes no action. |
| Confirmed | Contacts you’ve verified or that arrived from authoritative sources (CRM, calendar) | Role defaults + any per-contact overrides |
| Blocked | Contacts you’ve blocked | None. Messages are dropped without response. |