Skip to main content

Runtime API Deep Dive

The ActraRuntime is the primary execution layer for JavaScript applications.

It transforms a compiled Policy artifact into deterministic runtime enforcement before your functions execute.


Creating a Runtime​

Create a runtime from a compiled Policy.

import { Actra, ActraRuntime } from "@getactra/actra"

const policy = await Actra.fromDirectory("./policy")
const runtime = new ActraRuntime(policy)

The runtime instance is reusable across requests, workers, and job executions.


Resolver APIs​

Resolvers dynamically provide runtime context.

Actor Resolver​

runtime.setActorResolver((ctx) => ({
role: ctx.user.role,
tenant: ctx.user.tenant,
}))

Use this for:

  • JWT claims
  • request identity
  • service-to-service auth
  • AI agent identity
  • queue worker ownership

Snapshot Resolver​

runtime.setSnapshotResolver((ctx) => ({
is_locked: ctx.account.locked,
balance: ctx.account.balance,
}))

Use this for:

  • DB lookups
  • Redis flags
  • fraud systems
  • deployment state
  • approval workflows

Decision Observer​

runtime.setDecisionObserver((event) => {
console.log(event.decision.effect)
})

Observers receive:

  • action
  • decision
  • resolved actor
  • resolved snapshot
  • timestamp
  • durationMs

Observer failures never break execution.


Decision Helper APIs​

These methods are ideal for lightweight checks.

allow()​

const ok = runtime.allow("refund", {
amount: 100,
})

Returns true if decision effect is allow.


block()​

const denied = runtime.block("delete_user", {
target: "user_123",
})

Returns true if decision effect is block.


requiresApproval()​

const approval = runtime.requiresApproval("deploy", {
environment: "production",
})

Returns true for require_approval decisions.


check()​

const decision = runtime.check("refund", {
amount: 1000,
})

Returns the full Decision object.


Function Protection APIs​

These are the most commonly used production APIs.


admit()​

Protect a function before execution.

async function refund(orderId: string) {
return { ok: true }
}

const guardedRefund = runtime.admit("refund", refund)

When called:

  1. action payload is built
  2. actor resolver runs
  3. snapshot resolver runs
  4. policy evaluates
  5. function executes only if allowed

Failure Behavior​

  • block → throws ActraPolicyError
  • require_approval → throws ActraPolicyError
  • allow → executes function

The error includes decision metadata including matched_rule.


audit()​

Non-blocking shadow mode.

const auditedRefund = runtime.audit("refund", refund)

Always executes the function while still evaluating policy.

Ideal for:

  • migrations
  • shadow rollout
  • policy tuning
  • observability-only mode

Argument Mapping Model​

The runtime supports multiple action payload construction strategies.

Object-first Mapping​

runtime.check("refund", {
amount: 100,
currency: "USD",
})

Single object args are highest priority.


Explicit Field Mapping​

const guarded = runtime.admit("refund", refund, {
fields: ["amount", "currency"],
})

Maps positional args to explicit field names.


Schema-driven Mapping​

If fields are omitted, runtime falls back to schema-defined action fields.

This makes function protection ergonomic for existing codebases.


Action Builder APIs​

buildAction()​

Build an action payload manually.

const action = runtime.buildAction("refund", {
amount: 1000,
})

Supports:

  • field filtering
  • schema filtering
  • custom builder override

action()​

Ergonomic helper using runtime schema.

const action = runtime.action("refund", {
amount: 1000,
})

Best for:

  • middleware
  • queues
  • workers
  • agent tools
  • MCP

Custom Action Builders​

Override default payload generation.

const guarded = runtime.admit("refund", refund, {
builder: (actionType, kwargs, ctx) => ({
...kwargs,
tenant: ctx.user.tenant,
}),
})

This is extremely useful for framework integrations.

Builder failures throw ActraError.


Explain APIs​

explain()​

Explain a concrete action.

runtime.explain({
type: "refund",
amount: 1000,
})

Prints:

  • action
  • actor
  • snapshot
  • final decision

explainCall()​

Explain an upcoming function call.

runtime.explainCall(refund, {
args: ["order_123"],
actionName: "refund",
})

This uses schema-driven argument normalization.


Error Semantics​

Resolver Failures​

Actor or snapshot resolver failures throw:

ActraError

Policy Failures​

Evaluation failures throw:

ActraPolicyError

Builder Failures​

Custom builder failures throw:

ActraError

Production Mental Model​

Function Call
-> Build Action
-> Resolve Actor
-> Resolve Snapshot
-> Evaluate Policy
-> Execute or Throw

This is the core runtime execution pipeline.


Next Steps​

  • Explore Policy Artifact API
  • Learn Compiler API
  • Build Actor Resolvers
  • Build Snapshot Resolvers
  • Add Observability & Audit
  • Use Explain & Debugging