Loop Engine

Core Concepts

Actor Model

Why actors matter

Every transition is attributed to an actor in the transition record and emitted events.
Nothing executes anonymously.

Actor types

human

Use when a person executes a transition.

1const actor = { type: 'human', id: actorId('drew@acme.com'), sessionId: 'sess_abc' }

automation

Use for jobs, integrations, and rule engines.

1const actor = { type: 'automation', id: actorId('system:po-router'), serviceId: 'po-service' }

ai-agent

Use for model-driven recommendations or execution.

1const actor = {
2 type: 'ai-agent',
3 id: actorId('agent:forecaster'),
4 agentId: 'claude-3-5-sonnet',
5 gatewaySessionId: 'gw_123'
6}

webhook

Use for externally triggered actions.

1const actor = { type: 'webhook', id: actorId('webhook:shopify'), source: 'shopify' }

system

Use for internal runtime/platform initiated actions.

1const actor = { type: 'system', id: actorId('system:loop-engine') }

Actor evidence

Use buildActorEvidence(actor, baseEvidence) to normalize actor-attributed evidence.

For all actors, the helper adds:

  • actor_type
  • actor_id

For ai-agent, it also adds:

  • ai_agent_id
  • optional ai_confidence and ai_reasoning (when present in base evidence)

Authorization checks

canActorExecuteTransition(actor, transition, constraints?) returns:

1{ authorized: boolean; requiresApproval: boolean; reason?: string }
1import { canActorExecuteTransition } from '@loop-engine/actors'
2 
3const auth = canActorExecuteTransition(actor, transition)
4if (!auth.authorized) {
5 console.log(auth.reason)
6}