Asks and answers
An ask is a message with an ask field: the agent stops and waits for a person’s decision.
ask.type says how the question is shown; the answer’s resolution.decision says what it means.
Kinds of ask
ask.type |
You see | The answer |
|---|---|---|
confirm |
Approve and Reject, or up to 4 buttons of your own, each meaning approve or reject | decision: approve or reject |
choice |
2 to 12 options; multiple: true lets you pick several, allow_other lets you type your own |
decision: respond, with option or options |
multi |
2 to 12 options to tick, between min and max of them |
decision: respond, with options |
text |
A text field, with optional suggestions |
decision: respond, with text |
form |
Up to 10 fields: text, numbers, yes or no, one or several of a list, a date | decision: respond, with values |
A two-button confirm is answered right from the notification, on the Lock Screen; anything richer opens Kabu. Any ask
can let you decline instead (decision: reject), and allow_comment adds a note to the answer.
{
"title": "Run the production migration?",
"body": "Adds `orders.archived_at`. About a 3 s lock.",
"action": { "name": "db.migrate", "args": { "version": 42, "env": "prod" } },
"ask": { "type": "confirm", "irreversible": true }
}action says what will run if you approve, and Kabu shows it with the question. With allow_edit, you may change
its arguments: the decision is then edit, with the arguments you approved in edited_args.
Decisions
Branch on resolution.decision, never on the button’s label:
decision |
Means |
|---|---|
approve |
Do exactly what was asked |
reject |
Do not, or the person declined to answer; comment may say why |
edit |
Do it, with edited_args instead of the proposed arguments |
respond |
The answer is the value: option, options, text or values |
ignore |
Skip this step: only when an option offered it |
A decision you do not recognise is never approval. The resolution also records who answered (responded_by), where
(via: the Lock Screen, the app, the web) and how sure Kabu is it was them (assurance), and carries
a signed receipt.
Waiting, and expiry
An ask waits until it is answered, cancelled or expires (expires_in, an hour unless you say; from a minute to 30
days). Wait for it with ?wait= on POST /v2/messages and GET /v2/messages/{message_id}, or with kabu ask,
which waits as long as it takes.
Expiry never approves anything. Unanswered, an ask ends expired with no decision, unless it set
ask.on_expire to a safe default (reject, respond with a value, or ignore), which Kabu then applies and marks as
the system’s. An agent cannot schedule its own approval.
Irreversible asks
irreversible: true is for the steps you cannot take back: approving needs your phone unlocked, and the ask is
never settled by its expiry (on_expire is refused). Use it for production deploys, migrations and deletions.
Who may answer
The people it was sent to (to), from the Kabu app and its notifications, or the link Kabu sends
them. With several recipients, the first answer settles the ask and the others’ notifications are withdrawn. A
service of yours can answer on a person’s behalf with a key holding answers:delegate.
The key that asked never can: any key that may send messages is refused with 403
self_response_forbidden, so an agent cannot approve its own request. An
answer to a settled ask is 409 already_settled; one after the deadline, 410
ask_expired.