Approvals
Approvals in TraceMem exist to capture human judgment as durable decision evidence, not to orchestrate workflows or replace existing tools.
They answer one question:
"Who explicitly allowed this exception, under what context, and why?"
What Approvals Are (and Are Not)
An approval is:
- A first-class decision event
- A resolution of an exception
- A recorded judgment, not a side effect
- A durable, queryable artifact
An approval is not:
- A task in a workflow system
- A Slack bot command
- A UI state
- A mutable permission
Approvals exist to be remembered, not just acted upon.
When Approvals Are Required
An approval is required when policy evaluation cannot automatically allow an action.
Typical triggers:
- Policy returns
requires_exception - Automation mode mandates human approval (
propose,approve) - Data Product write requires approval by definition
- Restriction escalation (e.g., sensitive data access)
Approvals are never optional once required.
Approval Lifecycle
Once resolved, an approval is final and immutable.
Approval Request Semantics
1. Approval is Always Tied to a Decision Envelope
- Every approval references exactly one
decision_id - An approval cannot exist outside a decision context
2. Approval Requests Are Explicit
An approval request includes:
decision_id- Reason for approval (derived from policy rationale)
- Summary of proposed action
- Relevant context (safe, non-sensitive)
- Expiration (optional but recommended)
This ensures approvers understand what they are approving.
3. Approval Requests Are Recorded Immediately
When an approval is requested:
- An
approval_requesteddecision event is appended - The envelope enters
needs_approvalstate - No further writes are allowed
Even if delivery fails, the request is recorded.
Approval Resolution Semantics
Approved
When approved:
- An
approval_resolvedevent is appended - Approver identity is recorded
- Rationale (if provided) is stored
- Envelope transitions to
approved - Writes are now allowed
Rejected
When rejected:
- An
approval_resolvedevent is appended - Rejector identity is recorded
- Rationale (if provided) is stored
- Envelope transitions to
rejected - Decision must abort
Expired
When expired:
- An
approval_resolvedevent is appended - Outcome is
expired - Envelope transitions to
aborted - Decision cannot proceed
Approval Delivery
Approvals are delivered through a three-layer architecture:
- Policies - Define when approvals are needed (business logic layer)
- Approval Routes - Define where to send and what requirements apply (logical layer)
- Integrations - Handle the technical delivery (transport layer)
When a policy returns requires_exception, it references an Approval Route, which in turn uses an Integration to deliver the approval request.
For more details, see:
- Approval Routes - The logical routing layer
- Integrations - The transport delivery layer
How Agents Request Approvals
Agents request approvals via Agent MCP:
# Policy evaluation returns requires_exception
policy_result = agent.evaluate_policy(
decision_id=decision.id,
policy_id="discount_cap_v1",
inputs={"proposed_discount": 0.25}
)
if policy_result["outcome"] == "requires_exception":
# Request approval
approval = agent.request_approval(
decision_id=decision.id,
title="25% Discount Approval",
message="Customer requesting 25% discount on $10k order...",
require_rationale=True,
expires_in_seconds=3600
)
# Poll for approval status
while True:
decision_status = agent.get_decision(decision.id)
if decision_status["status"] == "approved":
break
elif decision_status["status"] == "rejected":
agent.close_decision(decision.id, action="rollback")
break
time.sleep(2)
Approval Delivery Process
Approval requests are delivered asynchronously by the Background Worker:
- Agent requests approval
- Approval request queued
- Worker picks up request
- Worker uses Approval Route to identify Integration
- Integration delivers request to human
- Human responds via Integration
- Response recorded in TraceMem
- Decision state updated
The delivery mechanism is abstracted from agents—they only know that an approval is needed, not how it's delivered.
Best Practices
- Always include context - Help approvers understand what they're approving
- Set expiration times - Don't let approvals hang indefinitely
- Require rationale - Capture why approvals were granted/rejected
- Use appropriate channels - Route to the right team/channel
- Handle timeouts - Poll for status and handle expiration
Relationship to Other Concepts
- Policies - Policies trigger approvals when they return
requires_exception - Approval Routes - Routes define where approvals are sent and what requirements apply
- Integrations - Integrations handle the technical delivery of approval requests
- Decision Envelopes - Approvals are tied to specific decisions
- Decision Traces - Approval events are part of the trace