Overview
An owner decides how far a bot may go on its own:draft, ask, tell or limits. The runtime (allternit-api) checks the policy before every outbound action. The API below is how clients read and change it. See What your bot can do on its own for the owner’s view.
All routes are under /api/v1 and need the owner’s session.
Levels
The action
payment is held at every level except draft, which keeps it a draft.
Scope and precedence
A policy hasbotId, channel and person. Each can be empty, which means “all”. channel is a provider (telegram, slack, email, sms, call, …) or a class: email, sms, call, chat (every other provider). The most specific match wins: person, then bot, then provider, then class, then everything. With no match the default applies: email is ask, sms and call are tell, chat is limits with maxMessagesPerDay: 200.
Endpoints
GET /autonomy/policies?botId=<id>
PUT /autonomy/policies
Creates or replaces the policy for (botId, channel, person).
400 for an unknown level, 404 for a bot that is not the caller’s.
DELETE /autonomy/policies/{id}
{ "ok": true }, or 404. The place goes back to the default.
GET /autonomy/effective?botId=<id>&channel=<channel>&person=<id>
GET /autonomy/usage?botId=<id>
Today’s actions (UTC day) by channel and outcome (sent, held, drafted).
Where the check runs
Email only reads an explicit policy; with none set, the mailbox’s reply mode stays in charge. A policy can tighten any email send and can loosen a bot reply to direct only on a verified domain, under the reply caps.
Inbox cards
Held, drafted and told actions are written toinbox_items with type autonomy.ask, autonomy.draft or autonomy.digest. The id is derived from the correlation id, so a retry never makes a second card. metadata carries channel, to, level, threadId and, for holds, approvalId.
Storage
Runtime migrationV233__autonomy_policies.sql: autonomy_policies (the settings) and autonomy_actions (what was done, used for the daily limits). Both are in the runtime database. There is no cloud-side table.