Task: a billing reminder email
step 1 of 5
Grant and handles
Your side opens the task and issues a grant: which records, which tools, what limits, when it expires. The vault mints handles for the records in scope.
grant tools=send_email records=<CUST:a81z> expires with the task vault <CUST:a81z> <INV:q7m2> <EMAIL:k3f9q>step 2 of 5
The prompt leaves, over handles
The runtime builds the prompt from handles and plain attributes. The egress gateway checks it, then forwards it.
customer <CUST:a81z> plan=pro invoice <INV:q7m2> status=overdue days_overdue=14 recipient options: <EMAIL:k3f9q> (billing contact on file) templates: invoice_reminder_v3, receipt_v2, address_change_confirm_v1step 3 of 5
The model proposes
The model returns a proposed tool call. It can pick a template and a recipient handle. It can’t type an address, so an injection can’t redirect the mail.
{"tool": "send_email", "to": "<EMAIL:k3f9q>", "template": "invoice_reminder_v3", "slots": {"invoice": "<INV:q7m2>"}}step 4 of 5
The tool gateway checks
Recipient binding: the address is a contact on file for this customer. Record binding: the invoice belongs to the same customer. Templated mail within rate limits needs no review; free-form text, refunds, and new addresses would.
schema ok recipient binding ok record binding ok tier: autostep 5 of 5
The executor acts
A local renderer fills the amount, the date, and the payment link from billing. The model never writes a number. Your own mail service sends it with DKIM, and only a result by handle comes back.
sent to=<EMAIL:k3f9q> template=invoice_reminder_v3 logged by handle




