Skip to content

Deadlines, escalation and stale decisions ​

Every action that needs a person has two separate deadlines: one to receive a verified decision, and one for the agent to resume after approval. Neither can outlive the request's own validity or the grant.

How the deadlines are set ​

DeadlineSet whenValue
not_afterSubmitThe agent's not_after, or 24 hours after submit.
decision_deadlineSubmit, when approval is neededThe earliest of not_after, the grant's expires_at, and now + the shortest decision_ttl_seconds of the required approvals.
resume_deadlineWhen the last approval arrivesThe earliest of not_after, the grant's expires_at, and now + the shortest resume_ttl_seconds of the requirements.
resume_deadlineSubmit, allowed within a grantThe earliest of not_after, the grant's expiry, and now + 1 hour (only relevant if the action was submitted without immediate execution).

The status document shows both (decision_deadline, resume_deadline) and expires_at, which is the deadline that matters in the current state. The approval page and the email show the decision deadline.

What happens when a deadline passes ​

  • A pending_approval action past its decision deadline (or not_after) becomes expired with reason_code: approval_expired; its pending approvals become expired.
  • An approved action past its resume deadline (or not_after) becomes expired with reason_code: resume_expired: the approval stood, but the original agent did not come back in time. A grant that expires or is revoked before the agent resumes is reported by the resume recheck instead (see the table below).
  • Expiry is applied both by the periodic sweep (every 5 minutes; Cron Trigger on Cloudflare, Cloud Scheduler on GCP) and immediately whenever the action is read or resumed, so nobody sees an overdue action as still open.
  • An approver opening an overdue request sees "the decision deadline has passed" and cannot decide.

Late and repeated decisions ​

Every state change is conditional on the current state. A decision that arrives after expiry, denial, cancellation or revocation (a late ServiceNow readback, a replayed webhook, a restored backup) is ignored: it cannot revive a closed record. An expired request needs a new request and a fresh approval.

Progress while pending ​

While an action is pending_approval, progress tells the agent and the admin where it is stuck:

progressMeaning
delivery_pendingAxiom has not yet delivered the request to the approval system (or is retrying).
waiting_on_personDelivered; waiting for an approver.
decision_readback_unavailableThe approval system could not be read back; Axiom retries every 60 seconds.
awaiting_agent_resume(state approved) A decision is in; nothing happens until the original agent resumes.
reconciling(state outcome_unknown) Axiom is asking the provider for the outcome by operation key.

approvals[].next_party names who must act next: approval delivery before delivery, then for example finance_approver in axiom or finance_approver in servicenow.

Escalation and alternate approvers ​

In this release:

  • Alternate approvers are every person who holds the required role in the tenant, directly or through an org-level role. All of them are notified, and any eligible one can decide. To add an alternate, give a second person the role.
  • There are no escalation chains or multi-stage approvals yet. A request nobody decides simply expires at its deadline, visibly, with approval_expired. Multi-stage approval and customer-defined escalation are proposed future workflows.
  • Delivery failures are retried with exponential backoff (up to 8 attempts, at most 15 minutes apart); after that the approval shows delivery failed in the action timeline.

Stale decisions on resume ​

An approval is evidence of a decision at a point in time, not permanent authority. When the agent resumes, Axiom rechecks everything before claiming execution:

What changed since the approvalResult
The agent was suspended or retiredrevoked (agent_suspended)
The credential was revokedrevoked (credential_revoked)
The grant was revoked or expiredrevoked (grant_revoked), or denied (grant_expired)
An emergency deny now appliesrevoked (emergency_deny)
Policy now denies (for example a new ceiling)denied with the rule's reason code
Policy now needs more approvalsdenied (policy_stale)
An approver no longer holds the roledenied (approver_ineligible)
The agent changed a material fieldRefused with 409 conflict (material_change); the action stays approved

Choosing values ​

  • Make decision_ttl_seconds long enough for your approvers' working pattern (the sample uses 4 hours) but shorter than the grant.
  • Keep resume_ttl_seconds short (the sample uses 1 hour): it is the window in which an approved but unexecuted request is live.
  • Remember the agent's own not_after caps both.

Developer preview. Contract version 2026-11-14.