Approvals
Read the second half of this page before you rely on the first. The record-keeping and routing side of approvals is built, and the side that carries an answer back to an agent mid-action has been exercised on a staging box. None of it is available to you today: production has no customer bot configured, so a box there cannot send you an approval prompt and you cannot answer one.
The shape of an approval
An approval is a row, created when a box asks for one and closed when an answer is recorded against it. Four things move it:
- The request. A box posts to the approval-request endpoint, carrying the tool it wants to use and a one-line summary of what it would do. The endpoint authenticates the box the same way its heartbeat does — a bearer whose hash is compared against the one stored for that box, in constant time.
- The prompt. The request is sent to the Telegram chat linked to that box, on the customer bot, with an Approve and a Deny control. The admin bot is never used for this.
- The answer. A tap is accepted only when it carries the row's own single-use nonce and arrives from the chat id recorded on that box. A tap that satisfies one and not the other is not an answer.
- The read-back. The box polls the approval-resolve endpoint for the outcome of its request.
The rules built into it
- Only the tap writes an approval. The function that records a decision is called from the Telegram webhook and from nowhere else. The endpoint a box calls can move a row in the deny direction only: a pending row past its expiry becomes expired. A box holding its own credential has no path to approve itself.
- Anything that is not an approval is a denial. A missing row, a denial, an expiry and a database error all resolve the same way. There is no outcome that means “carry on because we could not tell”.
- Requests expire. A request that is not answered runs out. Five minutes is the default life of one, and an hour is the longest a box may ask for.
- Deny is not the smaller control. Approve and Deny are the two buttons of one keyboard row on the prompt, side by side, neither of them the default.
What you can see today
A System's page under Systems lists the approval requests raised for that System on your box, with each row's state — pending, approved, denied or expired — and re-reads them while the page is open, so an answer given elsewhere appears without a reload.
Not shipped yet — read this before relying on approvals
The parts below are not available to you. They are listed so that nothing above is read as covering them.
- You cannot be sent a prompt today. Production carries no customer bot configuration, so nothing can reach your chat and you have no way to answer a request. Do not arrange your work around a stop you can approve or deny.
- The chain has never run in one pass. Delivery of a request to a linked chat, and a box acting on the answer, have each been exercised on a staging box — in separate runs, each standing in for the other half. One run carrying a request from a box to a chat and the answer back has not happened.
- The first-run step that ends “deny it once” is not a customer step yet. A denial has been answered on a staging box and the command it covered did not run. The walkthrough you would follow has not been run by anyone outside this team.
- No message is sent to you about a request you did not answer. A request that runs out is recorded as expired, and nothing goes out about it. One notice is wired to a different case — a prompt that could not be delivered to your chat, for a request that was already recorded — and it is held back while another request for the same box is pending. No prompt is attempted on your box today, so that case does not arise for you.
Until those close, treat an approval row as a record of an intention rather than as a control you hold over what a box does.
Copy status and the documents it was written against: About this copy.