Skip to content

docs(mailboxes): govern agent keys with versioned policies - #109

Merged
aryasaatvik merged 3 commits into
mainfrom
docs/versioned-mailbox-policies
Nov 7, 2026
Merged

aryasaatvik merged 3 commits into
mainfrom
docs/versioned-mailbox-policies

Conversation

@aryasaatvik

@aryasaatvik aryasaatvik commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Samva is replacing a mailbox key's send mode with a decision policy. This updates the public guidance that tells people and agents how to set up a governed mailbox agent, so it matches the API that ships in samva 0.36.0 and @samva/cli 0.31.0.

What changes for a reader

  • Setup runs under a person's OAuth session. It creates the mailbox, issues a restricted key, then sets that key's policy. The agent's key can't change policies or approve its own actions.
  • Holding sends takes a rule instead of sendMode: "approval": { match: { effect: "write" }, atLeast: "person" } holds every send and reply for review.
  • Policy writes are conditional. Read the policy, then replace it with ifVersion set to the version you read. A stale version returns 409; reload and review the current rules before trying again.
  • Approving a held action passes the reviewRound from its decision, so an approval can't land on a decision that has changed since it was read.
Surface Change
cookbooks/mailboxes.md Setup, the policy rule, held sends and approval move to the new API
examples/mailbox-agent README and description describe held replies; samva moves to ^0.36.0
plugins/samva Skill references for auth, CLI, MCP, SDK and mailbox extensions, re-exported from the canonical guidance

Release

samva 0.36.0 and @samva/cli 0.31.0 are on npm. bun.lock resolves samva 0.36.0 for examples/mailbox-agent, and plugins/samva/provenance.json names the release commit 8617fb3b5f, whose skill content matches this export. The other examples stay on 0.35 for the usual dependency propagation PR.

The API change is deployed, so the current sendMode guidance no longer matches production until this merges.

Checks

Frozen install, validate:agent-plugin, test (139), format:check and the mailbox-agent typecheck pass. lint reports only the existing warnings in scripts/check-public-packages.mts.

Samva replaces a key's send mode with a decision policy. Setup reads the
key's policy, then replaces it with the version it read; a stale write
returns 409. A `write` minimum of `person` holds sends and replies for
review, and approving a held action names its review round.

The cookbook, the mailbox-agent example and the agent plugin guidance
move to that contract, to samva ^0.36.0 and to @samva/cli ^0.31.0.
@aryasaatvik
aryasaatvik marked this pull request as ready for review November 7, 2026 18:20
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Tegami

This repository uses Tegami to manage releases. When your changes affect published packages, add a changelog file under .tegami/ before merging.

Create a changelog → · Changelog format

Release preview

Package Bump Version
@samva/better-auth minor 0.11.0 → 0.12.0
@samva/email-sdk minor 0.12.0 → 0.13.0

This PR does not add changelog files. Pending changelogs from other branches are included in the preview above.

Run bun run tegami locally to create a changelog interactively.

Managed by Tegami.

@greptile-apps

greptile-apps Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5 Tier: apex

[Medium impact] The PR appears safe to merge; both earlier findings are fixed and no new actionable issues were found.

Summary

Updates mailbox guidance from send modes to versioned decision policies.

  • People set mailbox policies that hold an agent’s sends for review.
  • Mailbox approvals use the review round a person actually read.
  • Mailbox guides now leave out older thread and retry details.

Diagram

sequenceDiagram
  participant Person
  participant API as Samva API
  participant Agent
  Person->>API: Read key policy
  API-->>Person: Policy and version
  Person->>API: Set review rule with ifVersion
  Agent->>API: Reply with restricted key
  API-->>Agent: approvalRequired and actionId
  Person->>API: Read held action
  API-->>Person: Decision and reviewRound
  Person->>API: Approve observed reviewRound
Loading

Reviews (2) · Last reviewed commit: "docs(plugin): pass idempotencyKey as the..." · Reviewed by Greptile

@aryasaatvik
aryasaatvik merged commit 66f0737 into main Nov 7, 2026
2 checks passed
aryasaatvik added a commit that referenced this pull request Nov 8, 2026
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
Propagate `samva` 0.37.0 and `@samva/cli` 0.31.0 into the maintained
integrations. Both published adapters require only the current SDK minor
and receive minor Tegami notes for the peer-range change.

Source releases:
[`samva@0.36.0`](https://github.com/SamvaHQ/samva-typescript/releases/tag/samva%400.36.0),
[`samva@0.37.0`](https://github.com/SamvaHQ/samva-typescript/releases/tag/samva%400.37.0),
[`@samva/webhooks@0.37.0`](https://github.com/SamvaHQ/samva-typescript/releases/tag/%40samva%2Fwebhooks%400.37.0),
and
[`@samva/cli@0.31.0`](https://github.com/SamvaHQ/samva-cli/releases/tag/%40samva%2Fcli%400.31.0).
Reviewed the producer's SDK, webhooks, and CLI changelogs plus the
published package declarations (`samva` 0.35.0 and 0.37.0,
`@samva/webhooks` 0.36.0 and 0.37.0, `@samva/cli` 0.30.0 and 0.31.0).
Producer checkouts were read only.

| Repository surface | Impact and evidence | Disposition |
| --- | --- | --- |
| Both adapters; all 14 example manifests; Supabase Deno map | SDK
dev/peer/dependency ranges move to ^0.37.0, including
`examples/mailbox-agent`, which #109 had left on ^0.36.0. External Deno
import pins 0.37.0. TSX template example uses CLI ^0.31.0. Bun 1.4.4
lock regenerated from npm and resolves one `samva@0.37.0` with
`@samva/webhooks@0.37.0`. | affected |
| TSX example and TSX cookbook authoring toolchain | `@samva/cli` 0.31
drives authoring 0.23.x and refuses a 0.22.x project (`this project has
@samva/markup 0.22.1, but this CLI drives 0.23.x`). `@samva/markup` and
`@samva/vite` move to ^0.23.0. 0.23.0 is a compatibility re-release:
`dist` and `package.json` differ from 0.22.1 only by the version string,
and both templates build and check unchanged. | affected |
| Root README, adapter READMEs, TSX example README,
Effect/mailbox/Supabase/TSX cookbooks | Current-minor references updated
to 0.37.0 and CLI 0.31.0. No older-line support matrix. | affected |
| Plugin distribution guidance | README names the current SDK/CLI minors
and explains decision policies, HMAC webhook verification, permanent
template deletion, and namespace-scoped reads. Canonical
skill/instructions and all seven references reviewed; immutable skill
bytes and `provenance.json` untouched. | affected |
| Mailbox-agent extension comment | Still told readers to install with
`--send-mode approval`, which 0.36 removed. Now points at a `--policy`
whose `write` rules hold for a person, matching #109. | affected |
| Adapter send paths and request bodies; every cookbook and plugin
SDK/CLI snippet | `@samva/email-sdk` builds a flat email payload, calls
`email.send`, and reads `id` from the response; `@samva/better-auth`
builds `{ to, channel: "email", email }`, calls `messages.send`, and
ignores the response. `EmailSendMessagePayload`,
`ReplyMailboxEmailPayload`, and `SendMailboxEmailPayload` are
byte-identical between 0.35.0 and 0.37.0. Neither adapter reads a
response into a request. Webhook calls already use `eventTypes`, and no
undeclared caller fields were found. | unaffected |
| Webhook verification | 0.37 removes `verifyWebhookAtWithPublicKeys`,
`WebhookSignatureVersion`, `webhookSignedContent`, and
`encodeWebhookSignature` from `@samva/webhooks/protocol`. Every
integration uses `verifyRequest` or `createWebhookHandler` with the
endpoint signing secret, and no direct `@samva/webhooks` dependency
exists to bump. | unaffected |
| Decision policies and held actions | 0.36 replaces mailbox grant and
API key `sendMode` and agent/integration `mode` with
`policy`/`decision`. Adapters send through `email.send` or
`messages.send` and never touch grants, agents, or approvals.
`MailboxSendReceipt.state` still enumerates `approvalRequired`, and
`decision` is nullable there. Guidance updated in #109 and carried
forward here. | unaffected |
| Template `isActive`, `templates.delete`, `TemplateInUseError` |
Template reads and create/update payloads no longer expose `isActive`.
No integration reads or writes the field, and none deletes a template.
`TemplateInUseError` (409) is added to the SDK error set only. |
unaffected |
| Namespaced scheduled sends, analytics, conversations, knowledge
sources | New optional `namespaceId` inputs on both clients. No
integration calls scheduled messages, analytics, or conversations;
`templates.createFromWebsite` already passes an optional `namespaceId`.
| unaffected |
| Effect client | Adds the `Policies` module and `namespaceId` filters;
existing `Client`, `Email`, and mailbox entrypoints are unchanged. No
analytics callers, so the 0.35 `Date` filter change stays inert. |
unaffected |

## What changed in 0.36 and 0.37 that matters here

- **0.36 — decision rules.** Mailbox actions carry a decision (`allow`,
`hold`, or `refuse`); policies replace `sendMode` and agent `mode`.
Policy reads return `version`, replacement requires `ifVersion`, and a
stale write is `409`. Approval and denial require the observed
`decision.reviewRound`. Templates and projects can be permanently
deleted. Namespace keys reach scheduled sends, analytics, conversations,
and brands, and an agent's knowledge sources must belong to its
namespace.
- **0.37 — HMAC only.** The RSA `v2` webhook helpers left the protocol
entrypoint; HMAC `v1` signing and verification are unchanged, and Samva
never sent `v2`.

## Validation

Bun 1.4.4, Node 22.23.4, Deno 2.9.5 (matches the CI pin):

- `bun install`, then `bun install --frozen-lockfile`: passed, no
changes.
- `bun run build --continue`: 12/12 tasks. `bun run typecheck
--continue`: 18/18 tasks. `bun run test`: 7 files, 139 tests.
- `bun run lint`: warnings only, all in unchanged code. `bun run
format:check`: 229 files clean.
- `bun run validate:agent-plugin`, `bun --filter tsx-template-samva
check`, the Supabase Deno `deno check`, and `git diff --check`: passed.
- No live email sends, publishing, or deploys.

## Local testing checklist

1. `bun install && bun install --frozen-lockfile`
2. `bun run build --continue && bun run typecheck --continue && bun run
test`
3. `bun run validate:agent-plugin && bun --filter tsx-template-samva
check`
4. `cd examples/supabase-auth-hook && deno check --node-modules-dir=none
--no-lock --min-dep-age=0 supabase/functions/send-email/index.ts`

## Review

Greptile's one finding was correct: the 0.37 release note described both
adapters as using the same send call. Fixed in `937918a`, and this table
now states each path separately.

## Release

Merging this PR does not publish anything by itself. Its Tegami minor
notes are picked up by the `tegami/version-packages` PR, and that PR
publishes `@samva/email-sdk` and `@samva/better-auth` when it merges.

This PR is intentionally not labelled `release`, and #108
(`tegami/version-packages`) is untouched.
<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-87270b0f-af3f-568f-b436-9942afd2918d?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-87270b0f-af3f-568f-b436-9942afd2918d&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant