Approvals
The concept page covers fingerprints, quorum and single-use grants. This page is the loop as you actually run it.
What the agent gets
An agent handed require_approval receives an approvalId and the reason. It
does not receive an error, a refused action and a paused action are different
things, and an agent that cannot tell them apart will retry the wrong one.
{
"effect": "require_approval",
"approvalId": "a_7f31c2",
"reason": "Auth and session code changes need a second pair of eyes.",
"approvers": ["security-team"]
}What the human does
memnox approvals # what is waiting, with the id for each
memnox approve <id> --by dana # --by defaults to $USER
memnox deny <id>
memnox approvals status <id> # pending · granted 1/2 (dana) · approvedThe <id> is printed by memnox approvals; it is never something you construct.
--by is the name the audit trail keeps, so it should be a person rather than a
shared account.
From the console it is the Approvals screen; from chat, a Slack-compatible
webhook announces new requests (--approval-webhook).
Console → Approvals, one request selected showing action, target, environment, agent and quorum progress
screenshot slot, save as public/screens/…png and set src
What the agent does next
It retries the same action. That is the entire client-side protocol.
The gateway claims the grant by fingerprint, so the agent does not have to
carry the approval id back, which is what makes this work from an editor hook
that has nowhere to put one. A caller that does have the id may still send it as
approvalId on the check.
While it waits, an agent may poll its own approval:
curl http://127.0.0.1:7466/v1/approvals/a_7f31c2 \
-H "Authorization: Bearer $MEMNOX_AGENT_TOKEN"This is the only route an agent token may read beyond the decision endpoints. It returns the approval that agent raised, and answers 403 on anyone else's.
Timing
An approval that nobody answers should not hold an agent forever, and a grant that nobody uses should not sit around indefinitely. Both are bounded by TTL, and a grant is spent the moment it authorizes an action regardless.
What a grant never overrides
- an agent's declared capabilities;
- a suspended agent;
- a non-overridable taint block (
project.delete,database.drop).
Each refuses the action and leaves the grant unspent, so the approval is still there afterwards, and the audit shows it was not the approval that failed.
Break-glass
memnox approvals override <id> --reason "incident 4471, on-call escalation"The reason is required. The override is audited as critical and opens a
break_glass_override incident. Irreversible actions refuse it with a 403 and
audit the attempt.
Break-glass is not a faster approval. It is an event somebody will read.
Approval health
memnox approvals healthReports how long requests are waiting and how many are still unanswered. Rising latency here is the earliest sign that a rule is routed to the wrong group. The rule is not wrong; the audience is.
Check it weekly. A rule nobody answers is a rule somebody will eventually delete instead of fixing, and the deletion is much harder to notice.

