Behavior Engine
The seventh of ArcFlow's eight layers. Owns declarative behaviors — programs and triggers that fire in response to graph events, execute inside the engine, and write their results back through the same Cypher surface.
A behavior is a piece of work the engine performs on the graph's behalf whenever the graph changes in a way the behavior cares about. Behaviors are how an agent encodes "when X happens, do Y" without writing an external poll loop, a webhook listener, or a sidecar worker.
What the Behavior Engine provides#
| Capability | What it does |
|---|---|
| Programs | Declarative units of work registered against the engine; named, versioned, composable. |
| Triggers | Conditions that fire a program — node created, property changed, edge added, live-view delta. |
| Skills | Reusable behavior fragments invoked by name; the building blocks of larger programs. |
| Behavior graphs | Compose programs + skills into directed graphs of work; the engine schedules execution. |
| Write-back | Results land in the graph through the same CREATE / SET / MERGE surface a user would write. |
Why behaviors live in the engine#
A behavior could be an external service that subscribes to the Event Bus and posts mutations through the client SDK. That works, but it loses three properties:
- Transactional grounding. A behavior running inside the engine sees the same mutation that triggered it, in the same transaction. The result it writes commits atomically with the input that caused it.
- No round-trip. No network hop, no serialisation, no reconnect logic.
- One identity story. The program is registered against the workspace; it carries the same provenance as any other authored fact.
Behaviors are the engine's answer to "stored procedure" — typed, declarative, graph-aware.
Why this is its own layer#
The Behavior Engine is downstream of every other layer:
- It consumes deltas from the Live Surface — that is how triggers fire.
- It emits results through the Query Engine — the same Cypher surface a user writes against.
- It publishes intents through the Event Bus — other behaviors and external consumers can subscribe.
- It can invoke the Algorithm Library —
CALL algo.*andCALL arcflow.*procedures.
Keeping behaviors separate from the layers they consume keeps each layer's responsibilities clean. A behavior is a composition of the lower layers' guarantees.
Why this matters for agents#
For agents, the Behavior Engine is what turns the database from a record-keeper into a participant. Examples:
- A perception arrives; a program normalises it, runs entity resolution, and writes a typed entity reference.
- A new edge appears in the call graph; a trigger fires a code-intelligence skill that updates the symbol table.
- A live view's delta indicates a fraud-ring threshold crossing; a behavior emits an intent the responder consumes.
The agent does not poll. The agent does not glue services together. The agent declares the behavior once; the engine fires it whenever the graph changes in a matching way.
LLM-tier skills (the LLM Node)#
A skill declared with TIER LLM and an optional MODEL '<catalog-row>' clause routes its execution to a language model instead of an inline prompt evaluator or compiled program:
CREATE SKILL coach_summary
FROM PROMPT 'Analyze {{name}}'
ALLOWED ON [Player]
TIER LLM
MODEL 'cli/claude-code'LLM calls do not run inside the engine process. They route through an arcflow-llm sidecar process supervised by the runtime — provider state isolated, sidecar crash restarted by the supervisor without taking down the engine, failures sandboxed.
Provider key management. Keys live in the OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) and are never written to disk:
arcflow keys add openai # interactive entry, piped, or --key
arcflow keys list # masked
arcflow keys set-daily-cap openai 25.00 # USD per provider per dayBudgetMeter. Every LLM call is intercepted before dispatch; calls that would exceed the daily cap fail with a typed error. Inspect with arcflow keys list (shows daily_cap_usd and spent_today_usd per provider).
Provider catalogs:
| Prefix | Provider | Notes |
|---|---|---|
openai/* | OpenAI-compatible HTTPS | Works for any vendor that exposes the same API shape — OpenAI, Together, Groq, Anyscale |
cli/* | SubprocessCli | Routes to a locally-installed CLI agent (cli/claude-code, cli/codex, cli/gemini); zero network egress from the engine; the local CLI authenticates with its own provider |
oz/* | OZ first-party | Hosted catalog at llm.oz.com; default oz/deepseek-v3 |
Models are discovered through the active provider's own catalog — oz/* from llm.oz.com, openai/* from /models on the configured base URL, cli/* from the local CLI tool's --list-models (where supported).
Per-skill MODEL routing means an agent can declare which model handles a given skill — and change it later without rewriting the prompt. Combined with the CLI provider family, this lets a workflow run entirely on locally-installed LLM CLIs (no network) for one skill, and on a hosted endpoint for another.
See also#
- Behavior Graphs — the canonical surface reference + worked examples.
- Skills — the reusable building blocks.
- Programs — the program manifest format.
- Triggers — the extension reference.
- Relationship Skills — edge-aware skill patterns.