Tether
DocsGitHub

Guides

Choosing risk levels

Every write already requires a confirmation. risk decides which ones require a second, deliberate gesture on top of it — and that budget is small, because people stop reading warnings they see all day.

The three levels

riskConfirm callAcknowledgement
low (default)requiredno
elevatedrequiredyes
highrequiredyes

elevated and high behave identically at the API — both demand acknowledgeHighRisk: true. The difference is the message your user sees and the weight your UI gives it. Use the distinction for your own interface, not for a behaviour change that is not there.

A decision procedure

Ask three questions about the write, in order.

  1. Can the person who approved it undo it themselves, in under a minute, from the same screen? If yes, it is low. Adding an item to a draft, updating a par level, creating a task.

  2. Does it leave your system — money, a message, a supplier, a customer? If yes, at least elevated. You cannot unsend an SMS or unspend money.

  3. Would a mistake be expensive, public, or unrecoverable? If yes, high. Voiding a live ticket, issuing a refund, deleting records, dispatching an order.

Worked examples

WriteriskReasoning
add_items_to_cartlowA draft. Removing the line undoes it
update_par_levellowA setting. Change it back
create_tasklowDelete it
mark_item_unavailablelowVisible immediately, reversible in one tap
send_purchase_orderelevatedLeaves your system. A supplier now has it
record_wasteelevatedMoves inventory. Correcting it means a reversing entry, not an undo
notify_customerelevatedA person received a message
void_tickethighMoney, a live table, and an audit trail
issue_refundhighMoney leaves. Reversal is a second transaction, not an undo
delete_menu_itemhighDestructive, and it takes history with it
approve_purchase_orderhighCommits spend on someone else's authority

The console's starting point

The onboarding console and the dashboard's import show every operation on one screen with a risk already chosen for each write, labelled Tether suggests. It is a starting point you see and change before you confirm, never a decision: the risk registered is the one on the screen. It reads the verb and the operation's own name and path, never its prose:

DefaultWhen
highA word is refund-, delete- or payment-like (delete, remove, destroy, erase, purge, wipe, void, terminate, refund, reimburse, pay, payment, payout, charge, chargeback, transfer, withdraw, capture, debit), or the verb is DELETE
elevatedOtherwise, a word is update- or cancel-like (update, change, edit, modify, set, replace, adjust, rename, move, reset, cancel, reschedule, revoke, reject, suspend, disable, deactivate, archive, close, unsubscribe), or the verb is PUT or PATCH
lowAnything else: create-like

A word counts in its plural, past and -ing forms (refunds, cancelled). The same words apply in every domain, which is why the procedure above still decides: send_purchase_order starts at low and belongs at elevated.

Do not mark everything high

The same logic applies to your interface. If the risk gate is always "click OK", it is not a gate. Reserve the typed phrase for high and use a plainer confirmation step for elevated.

The value threshold

Independently of risk, an acknowledgement is required when the staged arguments carry a value, amount or total at or above the configured threshold (AI:ActionGuardrails:HighValueThreshold).

Two practical consequences for your schemas:

Name the money field value, amount or total if you want the threshold to apply. A field called cents or grand_total is invisible to this check.

Do not put a value field on a write where it means something else. A value parameter that holds a par level rather than a currency amount will trip the threshold at 1,000 units and confuse everyone.

A read cannot be risky

Declaring risk above low on a tool that is not is_write is rejected at registration.

It looks careful and gates nothing: risk is consulted only on the confirm path, and a read never reaches it. Rather than ignoring the field, Tether refuses the catalog. If a read is dangerous enough to want a gate, the honest answer is usually that it is not a read — see Reads and writes.

Where risk is not the answer

Risk levels are blunt: they are per tool, not per argument, and they do not know who is asking.

  • "Shift leads may void under $50." That is your permission model. Your endpoint sees every write and can refuse.
  • "Only during business hours." Your endpoint.
  • "Not more than three times an hour." Your endpoint.

Tether enforces the tenant boundary, because it is the only party that can. Everything specific to your organization belongs where your organization is modelled.

Changing a level later

Risk is read from the current catalog at confirm time, not from the catalog in force when the action was staged. Raising a level takes effect immediately, including for actions already pending — which is the safe direction. Lowering one takes effect immediately too, so lower deliberately.