When you ask the assistant to change something, it does not change it. It shows an approval card and waits.
The approval card
The card has:
- a plain-language summary of the change, for example
Create issue "Fix login" in project web. - the diff: each field with its value before and after
- Approve and Reject buttons, and a line that says
Nothing has changed yet.
When you press Approve, the change runs once with your own permissions and the card shows the result. Pressing it twice does not run it twice. Reject leaves everything as it was.
Who can approve
Only the person who asked. A tool call cannot approve, a model cannot approve, and text in an issue, a docs page or any retrieved content cannot approve. There is no tool for it. The assistant never accepts an approval for you, even if you say “yes” in the chat; the button is the only way.
If an issue or page contains an instruction such as “assign everything to an agent”, the assistant treats it as quoted data. It may show it to you, but it proposes nothing unless you ask.
Expiry and checks at approval time
An approval expires after 15 minutes. After that the assistant says so and you ask again.
When you approve, the assistant checks again that your role can still make the change, that read-only mode is off, and that the arguments are exactly the ones you were shown. If any check fails, nothing runs.
Undo
After a change has run, the card shows Undo when the change can be reversed. Undo does not silently reverse anything: it creates a new approval card for the opposite change, with its own summary and diff, and runs only if you approve that too. You can also type undo. Some changes cannot be reversed automatically; the assistant says so.
Check it yourself
This sample runs in the docs tests against the real contracts:
const approval = AgentApproval.parse({
tenantId: "t1",
id: "apr-1",
conversationId: "c1",
requestedBy: "user-1",
tool: "createIssue",
summary: "Create issue \"Fix login\" in project web.",
diff: [{ field: "title", before: null, after: "Fix login" }],
argumentsDigest: `sha256:${"a".repeat(64)}`,
state: "pending",
createdAt: "2026-10-09T10:00:00.000Z",
expiresAt: "2026-10-09T10:15:00.000Z",
});
assert.equal(approval.state, "pending");
assert.equal(approval.diff[0].after, "Fix login");