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