System Architecture

Agent Data Model & Ontology

Status: Research (RFC) · Updated: 2026-07-05 · Tracks: AURA-744

This page defines a canonical data model and ontology for coding AI agents — the entities, relationships, states, and events that describe how an agentic coding system represents work, conversation, tools, sub-agents, artifacts, and deployment. It is the reference vocabulary the System Architecture runtime contract (§1.1), the control-plane job/agent store, and the management plane are designed against.

It is synthesized from three battle-tested reference models, each studied for what it models best:

  • Claude Agent SDK (self-hosted loop) — the richest turn/tool/sub-agent/session model.
  • Cloudflare vibesdk (agents-as-infrastructure) — agent-as-Durable-Object, code artifacts, sandbox preview, deploy lifecycle, tenancy.
  • Claude Managed Agents (CMA) (hosted loop) — versioned agent config, an append-only event log as the source of truth, and a brain / hands / session decomposition.

Auraison's central-runtime harness is a CMA; its edge harness is Pi (see System Architecture §1.2 / §1.1). This ontology therefore doubles as the reconciliation between those two runtimes.

1. One axis separates the three models: who owns the loop state

Every coding-agent platform runs the same inner agent loop — prompt, model turn, tool calls, tool results, repeat until done. The three reference models differ on essentially one architectural question: where the loop/conversation state lives, and therefore who is the source of truth for resume and audit.

Claude Agent SDKCloudflare vibesdkClaude Managed Agents
What it isLibrary that runs the loop as a subprocess/in-processVibe-coding platform; agent is a Durable ObjectHosted, managed agent surface (beta managed-agents-2026-04-01)
Who runs the loopThe caller's processThe Durable Object (Cloudflare edge)Anthropic orchestration layer ("harness"), stateless
Loop-state owner (source of truth)Caller — a per-session .jsonl transcript replayed on resumeThe Durable Object — setState() + per-DO SQLiteThe platform — an append-only event log external to the harness
Conversation representationMessage stream, persisted to JSONLfull_conversations / compact_conversations SQLite tablesEvent log (sevt_…), the atomic unit of the model
Resumeresume=<id> replays the transcriptDO rehydrates from AgentState after hibernationwake(session) reboots a fresh harness, replays the log; sandbox restored from an idle checkpoint
Config modelAgentDefinition / Options per callapps row + DO AgentStatePersisted, versioned Agent object; sessions pin a version
Where tools executeCaller infra (or Anthropic server-tools)Sandbox / Container per appPer-session Container (or caller infra if self_hosted)

This is the same gradient the System Architecture doc calls the locality model (§1.3). The edge runtime (Pi) is caller-owned loop state, close to hardware; the central runtime (CMA) is platform-owned loop state, durable and global. The canonical ontology below is deliberately loop-state-owner-agnostic so an entity means the same thing whether it is realized at the edge or centrally.

2. Source ontologies (condensed)

2.1 Claude Agent SDK

A single query() call is one agent loop yielding a stream of Messages until a terminal ResultMessage.

  • Session — persisted conversation (not the filesystem), one .jsonl per session_id under ~/.claude/projects/<encoded-cwd>/. Supports resume (specific), continue (most recent), and fork_session (copy history into a new session_id; file edits are real and shared).
  • Message / turn — union UserMessage, AssistantMessage (model, usage, message_id), SystemMessage (subtype = init / compact_boundary / …), ResultMessage. A turn is one model round-trip that may include tool calls; max_turns counts tool-use turns.
  • ContentBlockTextBlock, ThinkingBlock, ToolUseBlock (id, name, input), ToolResultBlock (tool_use_id, content, is_error). The ToolUseBlock.id to ToolResultBlock.tool_use_id link is the call to result join.
  • Tool — built-in, MCP (mcp__<server>__<tool>), or custom in-process (@tool, input_schema / handler). ToolAnnotations (readOnlyHint, destructiveHint, …) gate parallel execution.
  • Sub-agentAgentDefinition (description drives auto-delegation, prompt, tools, model, skills, permissionMode, background, …) or a markdown file in .claude/agents/. Invoked via the Agent tool; runs in its own fresh context; only its final message returns; child messages carry parent_tool_use_id; a resumable agentId trailer is returned; nesting up to 5 levels.
  • Hook — callbacks at lifecycle points (PreToolUse, PostToolUse, SubagentStart/Stop, PreCompact, …) that can allow / deny / modify.
  • Skill.claude/skills/<name>/SKILL.md, loaded on demand.
  • MemoryCLAUDE.md, re-injected every request (survives compaction).
  • ResultResultMessage (subtype success / error_max_turns / …, total_cost_usd, usage, num_turns, session_id, model_usage, permission_denials).

2.2 Cloudflare vibesdk

Two persistence layers that must not be conflated: a global D1 relational catalog and per-agent Durable Object state.

  • apps (D1) — the generated app/project: originalPrompt, finalPrompt, framework, userId, visibility, status (generating / completed), deploymentId, version, parentAppId (fork/version lineage), screenshotUrl, lastDeployedAt.
  • users, cloudflareAccounts, aiGateways — tenant identity, the CF account deployments land in, and a per-account gateway with a credit budget.
  • userModelConfigs — per-user, per-agent-action model routing (agentActionName, modelName, temperature, reasoningEffort, fallbackModel, providerOverride).
  • CodeGeneratorAgent extends Agent<Env, AgentState> (Durable Object) — one per app. State is a discriminated union AgentState = PhasicState or AgenticState or ThinkState over BaseProjectState (query, sessionId, blueprint, generatedFilesMap, sandboxInstanceId, commandsHistory, …).
  • Blueprint — the plan: title, description, views, userFlow, dataFlow, architecture, frameworks, implementationRoadmap, initialPhase, pitfalls.
  • FileState (artifact) — filePath, fileContents, filePurpose, lastDiff.
  • PhaseStatename, description, files, completed.
  • CurrentDevState (live status machine) — IDLE, PHASE_GENERATING, PHASE_IMPLEMENTING, REVIEWING, FINALIZING (up to MAX_PHASES = 10).
  • Conversation — per-DO SQLite full_conversations / compact_conversations, deduped by conversationId-role-tool_call_id.
  • Sub-agents are not separate DOs — they are behaviors / objectives inside the one DO.
  • Deployment — packaged into a Workers for Platforms dispatch namespace (isolated Worker per app, unique URL, per-app D1 / KV / R2 bindings).

2.3 Claude Managed Agents

CMA virtualizes an agent into brain (Claude + harness loop, on Anthropic's orchestration layer), hands (a per-session sandbox container), and session (the append-only log). Design invariant: the brain shouldn't assume where the hands run, the hands shouldn't hold credentials, and the session shouldn't live inside the harness — so the harness is disposable.

  • Agent (agent_…) — persisted, versioned config: name, model, system, tools, mcp_servers, skills, multiagent. Each update mints a new immutable version; sessions pin {id, version}; archive is permanent.
  • Environment (env_…) — reusable container template: config (cloud or self_hosted, networking, packages).
  • Session (sesn_…) — a stateful running instance = one task/run. status = rescheduling to running (which alternates with) idle to terminated. Holds agent (resolved snapshot), resources, vault_ids, usage, outcome_evaluations.
  • Event (sevt_…) — the atomic unit; the append-only log is the conversation state. Typed with a dotted {domain}.{action} namespace: inbound user.message, user.interrupt, user.tool_confirmation, user.custom_tool_result, user.define_outcome; outbound agent.message, agent.thinking, agent.tool_use, agent.tool_result, session.status_running/_idle/_terminated, span.model_request_start/_end (carries model_usage). Communication is explicitly event-based.
  • Container — per-session sandbox where tools execute; the loop does not run here. Checkpointed on idle so a session resumes cleanly.
  • Vault / Credential (vlt_…) — secrets Anthropic injects at egress; never enter the sandbox (mcp_oauth, static_bearer, environment_variable).
  • Memory Store (memstore_…) / Memory (mem_…) / Memory Version (memver_…) — workspace-scoped documents that survive session death (durable cross-session state), with per-mutation actor attribution.
  • Skill (skill_…), Thread (per-subagent isolated event stream, parent_thread_id), Deployment (depl_…, cron-scheduled autonomous sessions), Outcome (a define_outcome
    • grader loop scoring iterations against a rubric).

3. Canonical Auraison agent ontology

The union of the three, normalized to loop-state-owner-agnostic entities. An Auraison agent is a configured identity (Agent) that, under a Role, executes Sessions; each Session is an append-only stream of Events (its source of truth) that projects into Turns, ToolCalls, Artifacts, and Usage.

3.1 Entity mapping

Canonical entityClaude Agent SDKCloudflare vibesdkClaude Managed Agents
Agent (versioned config: LM(s), system prompt, tool grants, skills, sub-agent roster)AgentDefinition / Optionsapps config + CodeGeneratorAgent classAgent (agent_…, versioned)
Role (deploy-time identity + permissions/credentials over resources)permission mode + rulesuserId / cloudflareAccounts bindingvault_ids + tools/permissions on the session
Session (Run) (one stateful execution against a task)Session (.jsonl)apps row + DO instanceSession (sesn_…)
Event (append-only record of everything)Message stream (JSONL lines)full_/compact_conversationsEvent (sevt_…)
Turn / Message (one model round-trip; a projection over Events)AssistantMessage / UserMessageconversation rowsagent.message / user.message
ContentBlock (text, thinking, tool_use, tool_result, image)TextBlock / ThinkingBlock / ToolUseBlock / ToolResultBlockmessage partscontent blocks (identical shape)
Tool (capability grant with I/O schema)built-in / MCP / customagent tools/agent tools / mcp_servers
ToolCall / ToolResult (tool_use paired to its result)ToolUseBlock.id to ToolResultBlock.tool_use_idtool-call rowsagent.tool_use to agent.tool_result
SubAgent / Thread (child execution, isolated context, linked to parent)sub-agent + parent_tool_use_id, agentIdin-DO behaviors/objectivesThread + parent_thread_id
Artifact (produced file/output)file edits (checkpointed)FileState (filePath, fileContents, filePurpose, lastDiff)File output (scope_id)
Environment / Sandbox (compute tools run in; template + instance)sandbox optionSandbox / ContainerEnvironment (env_…) + Container
Plan / Blueprint / Outcome (declared objective + acceptance rubric)Plan agentBlueprintOutcome (define_outcome + grader)
Memory (durable cross-session state)CLAUDE.md(none durable)Memory Store (memstore_…)
Vault / Credential (managed secrets, egress-injected)env / settingssecret store / provider secretsVault (vlt_…)
Deployment (publish produced app to a runtime)(n/a)Workers for Platforms dispatchDeployment (depl_…)
Usage (tokens, cost, turns, duration)usage / model_usage / total_cost_usdAI Gateway metrics + InferenceMetadataSession.usage + span.model_request_end.model_usage

Two entities have no clean equivalent in one source and are worth calling out: Memory as a first-class durable store exists only in CMA (the SDK approximates it with CLAUDE.md; vibesdk has none) — Auraison should adopt the CMA model. Deployment is central to vibesdk and CMA but absent from the SDK — it belongs in the ontology because Auraison's user plane deploys workloads.

3.2 Entity–relationship view

3.3 Entity definitions

  • Agent — a versioned configuration: which LM(s) it may use (large or small — see the System Architecture LM definition), system prompt, the set of Tools and Skills it may call, its sub-agent roster, and default permission posture. Versioning is immutable and append-only (CMA's model); a Session pins the exact version it ran, which is a hard requirement for reproducibility.
  • Role — the deployment-time binding of an Agent to an identity and a permission/credential set over resources (the user's framing in System Architecture §intro). A general-purpose CMA and a domain-specific fine-tuned agent may run the same task under different Roles. Role governs Vault access, tool allow/deny, and tenancy.
  • Session (Run) — one stateful execution of an Agent, under a Role, against a task. It owns a status lifecycle (§4), an Event log, produced Artifacts, and accrued Usage. Whether its loop state is caller-owned (edge/Pi), DO-owned, or platform-owned (central/CMA) is a deployment choice, not an ontological one.
  • Event — the atomic, append-only, timestamped record of everything that happened in a Session: user inputs, model messages, thinking, tool calls and results, sub-agent lifecycle, status transitions, model-request spans (with usage), permission decisions, and deploys. The Event log is the source of truth; Turns, ToolCalls, and Memory are projections over it. Events carry a dotted {domain}.{action} type (adopting CMA's taxonomy) and a processed_at marker.
  • Turn / Message — a projection: one model round-trip. Useful for display and max_turns budgeting; not itself the source of truth.
  • ContentBlocktext, thinking, tool_use, tool_result, image. Identical across the SDK and CMA; adopt verbatim.
  • Tool / ToolCall / ToolResult — a Tool is a capability grant with an input/output schema (built-in, MCP-served, custom in-process, or platform server-tool). A ToolCall (tool_use) is joined to exactly one ToolResult by id. This pairing is universal across all three sources and is the backbone of provenance.
  • SubAgent / Thread — a child Agent execution with its own isolated context, linked to the parent by parent_tool_use_id (SDK) or parent_thread_id (CMA). Only its final result crosses back to the parent; its internal Events stay in its own stream. Auraison models this as a child Session/Thread so the same Event/Artifact machinery applies recursively.
  • Artifact — a produced file or output: path, contents (or a URI to bytes), purpose, diff, and a version. Auraison versions Artifacts immutably in R2 via the data-plane versioning helper (lakehouse.versioning.version_dataset / version_checkpoint) so a produced artifact is a reproducible vN.
  • Environment / Sandbox — the compute the Tools execute in, as a reusable template plus a per-Session instance. Checkpointed on idle for clean resume (CMA's model).
  • Plan / Blueprint / Outcome — the declared objective and, optionally, an acceptance rubric that a grader scores each iteration against. Unifies vibesdk's Blueprint, CMA's Outcome, and the SDK's Plan agent.
  • Memory — durable, cross-session, workspace-scoped state that survives Session death, with per-mutation actor attribution and immutable version history (CMA's Memory Store). In the four-plane model this is the durable backing of the Memory domain, rebuilt as a projection of the Event log.
  • Vault / Credential — managed secrets injected at egress and never exposed to Agent-authored code (CMA's model). A management-plane concern.
  • Deployment — publishing a produced Artifact/app to a runtime (Workers for Platforms, a KubeRay workload, an edge device), with its own identity and lifecycle.
  • Usage — tokens (input, output, cache_creation, cache_read), cost estimate, turns, and durations, recorded per model-request span and aggregated per Session. The unit of cost attribution for the management plane.

4. Lifecycle & state machine

The canonical Session lifecycle, with each source's states mapped onto it.

Canonical stateClaude Agent SDKCloudflare vibesdk (CurrentDevState)Claude Managed Agents (Session.status)
ProvisioningSystemMessage(init)initialize()rescheduling
PlanningPlan modePHASE_GENERATING (blueprint)first running (plan)
Runningassistant to tool to user loopPHASE_IMPLEMENTINGrunning
Idle(streaming input waits)IDLEidle (requires_action)
Reviewing(re-prompt)REVIEWINGoutcome-eval loop
Deploying(n/a)FINALIZING + deployDeployment run
TerminatedResultMessageapps.status = completedterminated

The persisted event set (minimum, for replay / audit / resume — the AgentEvent schema of the runtime contract): user.message / intent, agent.message, agent.thinking, agent.tool_use, agent.tool_result, subagent.started / subagent.stopped, artifact.written, span.model_request_end (usage), session.status_* transitions, permission.decided, deployment.*. Recording exactly this set makes a Session fully reconstructable and lets a stateless harness be rebooted (wake then replay), which is what lets the central runtime survive harness crashes.

5. Four-plane placement

Every entity lands in one of the four planes (see System Architecture). This is the bridge from ontology to where each entity is stored and served.

PlaneEntitiesRationale
User planeSession/Run and Artifacts of the reference-app (edge) agents, near hardwareLatency-sensitive, domain-specific work close to the robot/app
Control planeAgent registry, Role, Session/Run store, Event log, Tool/Skill registry, Plan, orchestration & permission policyThe "solve-once" coordination core; this is where the in-memory _jobs dict is replaced (§6)
Data planeArtifact bytes, Memory stores/projections, Event history, datasetsDuckDB + DuckLake over RustFS/R2; Memory is a derived projection of the Event log
Management plane (v2)Vault/Credential, Usage/cost attribution, quotas, tenancy on Role, Deployment governanceBilling, tenancy, and secrets — the CMA "never in the sandbox" model

6. Reconciliation with the runtime contract

System Architecture §1.1 defines six typed primitives. The canonical ontology is a superset that grounds them in concrete, documented shapes from the three sources:

Runtime primitive (§1.1)Canonical entityConcrete shape to adopt
Intentinbound EventCMA user.message / user.define_outcome; SDK query prompt
SkillSkillSDK / CMA Skill (SKILL.md + version)
ToolCallToolCall / ToolResulttool_use to tool_result id linkage (identical in all three)
RunStateSession (Run)CMA Session.status machine (§4) over the Event log
AgentEventEventCMA Event (sevt_…, dotted {domain}.{action}, append-only, processed_at)
ProjectionEventMemory / Artifact / Turn projectionsderived read models rebuilt from the Event log

This resolves the open design item in System Architecture §1.2 ("the CMA agent loop is event-based … reconcile it with the platform's AgentEvent / ProjectionEvent contract"). The recommendation: adopt CMA's Event taxonomy as the concrete AgentEvent schema, have the edge (Pi Session-Tree events) map onto the same shape, and define ProjectionEvent as the derived Memory-domain read models. One event model then spans edge and central runtimes, which is exactly the property the dual-runtime design needs.

7. Path to a control-plane persistence schema

The control-plane job store is currently an in-memory _jobs dict (api/jobs.py). The ontology gives a direct target schema. The Event log is the source of truth; Jobs, Turns, and status are projections over it.

TableKey columnsNotes
agentsid, name, version, model, system, tools (jsonb), skills (jsonb), archived_atImmutable versions; append-only history
rolesid, agent_id, identity, permissions (jsonb), vault_refs (jsonb), tenant_idDeploy-time binding
sessionsid, agent_id, agent_version, role_id, environment_id, status, created_at, updated_at, usage (jsonb)The Run; status per §4
eventsid, session_id, seq, thread_id, type, payload (jsonb), processed_atAppend-only, source of truth; replaces _jobs semantics
artifactsid, session_id, path, purpose, version, uri, sha256, created_atBytes in R2 (immutable vN); row is the pointer
deploymentsid, artifact_id / session_id, target, identity, status, deployed_atWorkers for Platforms / KubeRay / edge

A "Job" (the current API surface) becomes a thin projection over sessions + events, so the existing POST /api/v1/jobs contract can be preserved while the store gains full provenance, resume, and audit for free. usage rolls up from events (span.model_request_end) for management-plane cost attribution.

8. Open questions

  • Edge event mapping. What is the exact transform from Pi Session-Tree events to the AgentEvent (CMA-shaped) schema? This is the concrete deliverable that unblocks a single event model across runtimes.
  • Artifact vs Memory boundary. vibesdk keeps generated files in agent state; CMA separates Files (session-scoped) from Memory (cross-session). Auraison should draw the line at reproducibility: reproducible outputs are Artifacts (immutable vN in R2); evolving working state is Memory (a projection of the Event log).
  • Multiagent topology. CMA models sub-agents as Threads (own event stream); the SDK as isolated sub-agent contexts; vibesdk as in-DO behaviors. Confirm the recursive Session/Thread model holds for the Deep Evidence Agent's Planner / Researcher / Critic / Synthesizer roster.
  • Fork/version lineage. Adopt vibesdk's parentAppId + version for Session/Artifact lineage, or CMA's immutable Agent versioning, or both at different levels?

References

On this page