Skip to content
Back to Blog

Approval-Mode Tiers: A Compatibility Taxonomy You Can Actually Ship

Published Updated Editorial policy & corrections

Share:XBSMRedditHNEmail
Approval-Mode Tiers: A Compatibility Taxonomy You Can Actually Ship illustration

A team I work with shipped an AI assistant for their support org last summer. The pilot went well. The second team adopted it in October. By December the slack channel was an anthropology project: someone needed an approval step before the agent emailed customers, someone else needed one before refunds, a third before file uploads, a fourth before contract changes — but only above a threshold, and only outside business hours, and only for VIP accounts.

By March they had thirty named approval gates. Pull requests to add the thirty-first were the team’s most-disliked Jira ticket. Audit reports took a week. Every new use case made the problem worse, not better.

This is not only a tooling problem. It is a classification problem. The team was binding approvals to workflows when it needed stable operational labels plus a native description of each action’s effect, authority, reversibility, interaction boundary, and data scope.

2026 update: tiers are the v1 projection, not the native risk model

The five approval modes remain required in v1 schemas, adapter manifests, compiled tool surfaces, critic verdicts, gateway envelopes, approval events, and Decision Records. But they are a compatibility projection and safety ceiling—not ContextOS’s complete risk model. network describes an effect boundary, delegated describes authority, and destructive describes reversibility; treating them as one universal order hides important combinations.

New implementations declare native ActionRisk across five independent dimensions and derive a conservative v1 mode when an older consumer requires one. A label that exists only in policy prose will drift. A vector and projection emitted into the contract can be enforced, queried, replayed, and reviewed.

The five v1 compatibility tiers

ContextOS v1 uses exactly five approval-mode values. Every adapter capability declares the highest compatibility mode it can produce; policy can select a lower effective mode within its priority but cannot exceed that ceiling. Native policy still evaluates every ActionRisk dimension independently.

ModeExamplesConditions to evaluate, not automatic permission
read_onlylookups, search, retrievalcurrent read authority, eligible data use and any required approval
local_writetenant-scoped notes, drafts, memorycurrent write scope, governed memory/retention and owned effects
networkoutbound calls, webhooks, third-party readsactual recipient/processor, egress, credentials and shared capacity
delegatedbooking, message send, calendar writecurrent scoped mandate and all ancestor restrictions; exact approval when required
destructivepayment capture, account deletion, data exportnative risk and policy conditions, exact stored approval when required, honest recovery limits

Five wire-compatible labels, not fifty workflow-specific gates. The constraint makes v1 operations comparable; the native vector preserves the risk information the ladder cannot express.

Where the tier is enforced

The tier is not just metadata for the UI. It is checked at each place where risk can change shape.

Runtime pointWhat it checksArtifact emitted
Adapter registrationCapability declares native ActionRisk, its maximum v1 approval_mode, and constraintsVersioned manifest entry; signing is an optional provenance profile
Context compileCompiler surfaces only tools allowed by pack, policy, and RunContext.safety_modeCompiledContext.tool_manifest
Critic verifyProposed plan stays within surfaced tools, argument bounds, and effective modecritic_verdict
Tool GatewayExecute-time policy re-check, credential scope, idempotency, and egresstoolCall / toolResult
Approval gateHuman or delegated authorization binds to frozen evidenceapproval_event
Decision RecordFinal action records declared mode, effective mode, policy rule, and approverDecisionRecord.approvals[]

This table is an architectural mapping, not a claim that compilation or a receipt performs every check. The execution contract assigns current verification, credential/data/boundary enforcement and protected atomic stores to their implementation owners. Missing required support or evidence blocks dependent work.

Why workflow-named gates rot

When you name gates after workflows, three things happen. They are obvious in retrospect; they are very hard to see in the moment.

First, the taxonomy explodes. Every new use case wants a name, every name acquires a special case, and within a year you have GATE_REFUND_FRAUD_VIP_TIER2_HOLIDAY_OVERRIDE. Auditors do not query that schema; they archaeologize it.

Second, the same business action carries different risk in different contexts, and a single gate name flattens that risk. A 50-rupee refund and a 5-million-rupee refund are not the same risk event. The team that named GATE_REFUND_APPROVAL had to either accept that ergonomic mistake or invent yet another gate to fix it. They invented one.

Third, cross-workflow comparison is impossible. “Show me every destructive action this quarter, by approver, ranked by override rate” is one line of SQL against a tier taxonomy. It is a research project against a workflow-name taxonomy. The compliance org rapidly learns to stop asking.

A stable compatibility taxonomy improves all three because gate names are runtime artifacts that bind to a mode. You can still keep gate names for routing—GATE_FINANCE_APPROVAL is fine as a runtime artifact—but the audit story queries both the native vector and the projected mode.

The downgrade-only invariant

The single most important v1 rule is that policy bundles can select a lower effective approval mode but cannot exceed the wire-time ceiling. This rule never permits policy to weaken a native ActionRisk constraint.

The ceiling prevents a compatibility projection from advertising more capability than its registration. It does not make under-protection safe: removing an approval or data constraint can still cause an incident. Keep native risk, current authority, exact approval, independent guardrails, active boundary/data controls and budget as conjunctive requirements.

The wire-time contract on the adapter pins the v1 ceiling. A capability for issuing refunds projects to destructive in its registration. A recorded rule may select a lower compatibility mode, but cannot bypass the vector’s authority, data, destination, reversibility or evidence constraints. Enforcement belongs outside model-controlled output. Compiler prohibition accumulation also remains distinct from normalized business-rule priority: a winning allow cannot erase an independent denial, escalation or required approval.

A walkthrough

The intent is support.refund. The wire-time facts include a native vector and a conservative destructive compatibility projection:

{
  "permission_id": "perm_payments_refund_capped",
  "adapter_id": "adp_payments",
  "capability": "issue_refund",
  "action_risk": {
    "effect": "external_state",
    "authority": "human_approved",
    "reversibility": "compensatable",
    "interaction": "api",
    "data_scope": "CONFIDENTIAL"
  },
  "approval_mode": "destructive",
  "arg_constraints": {
    "amount_inr": { "min": 1, "max": 50000 },
    "currency": { "enum": ["INR"] },
    "idempotency_key": { "required": true, "pattern": "^ik_[a-z0-9]{16}$" }
  }
}

A legacy policy fragment selects a lower compatibility projection for low amounts while retaining the required human gate:

{
  "rule_id": "R_VIP_INSTANT_REFUND",
  "applies_to": { "intent": "support.refund" },
  "if": {
    "and": [
      { "==": [{ "var": "request.context.user.is_vip" }, true] },
      { "<=": [{ "var": "request.context.refund_amount" }, 200] }
    ]
  },
  "then": { "allow": true, "approval_mode": "delegated", "requires_approval_gate": "GATE_REFUND_APPROVAL" }
}

For a 200-rupee refund to a VIP, this fragment selects delegated, but the action still declares authority: human_approved and retains GATE_REFUND_APPROVAL. The Decision Record records the projection and rule; dispatch still needs the current exact stored approval and every other mandatory condition. The fragment is not a complete authorization input or an executable tutorial.

For a 50,000-rupee refund the rule would not match, the wire-time destructive would stand, and execution would route through propose → approve → execute with a frozen evidence snapshot. Same capability, different effective mode, complete audit either way.

An autonomous small-refund path needs its own correctly classified, narrowly scoped service/user mandate and policy; it cannot be created by clearing a gate on a human-approved action. Bind currency and integer minor-unit business amounts, exact nested arguments, destination, actor, proposal/request and immutable pins into the action digest. Verify current entitled distinct approvers/quorum where required. Redemption is an atomic store transition, not permission for an additional effect; preserve the stable operation through unknown outcomes and provider-specific recovery.

What changes operationally

Once the vector and projection are consistently recorded, the dashboard becomes comparable across workflows. Compliance rate, gate honor rate, latency-to-approval, and override rate can be sliced by native dimension and compatibility mode. “Destructive-mode share by tenant” remains useful, but it should sit beside irreversible-effect, delegated-authority, external-state, restricted-data, and interaction-boundary views.

Two metrics worth watching specifically:

  • Cross-tier downgrade rate. Inspect which projection changed and which mandatory controls remained. A high rate can indicate a conservative registration or misclassification; it cannot justify bypassing an approval or infer safety from the label alone.
  • Approver review time per evidence_snapshot_hash. If the median approver spends three seconds on a frozen snapshot, the gate has become a rubber stamp; either the threshold needs to move down, or the snapshot needs more context.

Reviewer checklist

Before a new capability ships, the reviewer should be able to answer this without reading the prompt:

QuestionBlock if
What is the native action risk and wire-time maximum mode?The adapter registration is missing either the vector or its conservative v1 projection.
Can policy only constrain the capability?A rule can make the call more powerful than its manifest ceiling.
Are arguments bounded?A side-effecting capability lacks schema limits, idempotency, or destination constraints.
Is the evidence snapshot frozen before approval?The approver sees live, mutable data instead of a hash-addressed snapshot.
Can audit query by tier across workflows?The only searchable concept is a workflow-specific gate name.

What people get wrong

The two arguments against this model are both wrong, and they are wrong for the same reason.

The first is: “five tiers are not enough to describe risk.” That is correct, which is why ActionRisk is multidimensional. Five labels are enough for the v1 compatibility surface because workflow-specific gate names remain routing artifacts rather than new modes.

The second is: “every call needs the same human-review latency.” Review requirements depend on current authority, policy, data and native risk, rather than the mode alone. Some read or local-write operations require approval; an already authorized narrow path may proceed without a new prompt when no mandatory gate applies. Measure verification and review latency on the actual workflow.

The operational lesson is that stable labels let engineering ship without inventing and auditing a new mode for every gate. Native dimensions then give security and operations the precision those labels intentionally lack.

A closing thought

Risk taxonomies are unglamorous. They get out-voted by “let’s just add a gate.” Six months later, the team that resisted the taxonomy has the worst audit experience in the company.

If you want governance you can ship, declare ActionRisk for every capability, derive one of the five v1 compatibility modes, and bind workflow gates to policy rather than inventing new modes. Let policy select a lower mode only inside the declared ceiling and never let that projection bypass native constraints. The audit reports and cross-workflow views then have both compatibility and precision.

Found this useful? Share it.

Share:XBSMRedditHNEmail

Continue through the same topic without returning to the index.

View the series