For each tool below we wrote an illustrative OCP 0.3 document from its public source or docs, with invented values, and checked it with
loopmath ocp validate: all thirteen conform, with no errors and no warnings. These are mappings, not shipped exporters; where loopmath already reads a tool, its section says so. Sources were read on 2026-09-23 and are listed with each tool; tools change, so check them against the current version.Reference implementation
loopmath writes, reads, validates and migrates OCP. It reads Claude Code and Codex logs directly and writes 0.3 (loopmath graph --format ocp). Eight adapters (loopmath adapt) read Pi, OpenCode, OMP, bb, Paseo, Orca, Atrium and OpenTelemetry GenAI data and write 0.2, which loopmath run import upgrades to 0.3. The Paseo and Orca adapters carry no tokens, and the Atrium adapter reads events only. It has no adapter yet for LangGraph, CrewAI or the OpenAI Agents SDK.
At a glance
Hooks and cost. Where to read a tool from, and what it records per attempt.
What structure it exposes. How a tool marks retries, how its work fits together, and how results are judged.
“Priced by exporter” means the tool records tokens but no dollars; an exporter prices them and records the price table in
cost.tariff.
Where 0.3 loses information
Every mapping validates, but some records have no exact place in 0.3 yet:- Several models in one attempt. OpenCode, OMP, Codex and Claude Code sessions can switch models midway. OCP has one model per attempt, so an exporter splits the attempt or keeps the per-model split in
ext. - Relations without a core edge kind. Handoffs (Agents SDK), forks (bb, Pi, Codex) and cross-agent messages (bb, Atrium, Orca) are written as
deporspawnedges, or inext. - Control flow beyond gate and repair. A 0.3 workflow is acyclic, and
control.repairsends one gate’s rejection back to one piece. LangGraph graphs with several loops, and imperative workflow scripts, are approximated. - API retries. Retries of a single model request are not attempts. They belong in
cost.requestsorext. Retries a framework makes on purpose (CrewAI guardrails, Orca dispatch retries, Pi workflowretry()) are attempts with a cause. - Free-text verdicts. Verdict values are a closed set. Orca decision-gate resolutions and OpenTelemetry evaluation labels are free text, so an exporter maps them or records a score or event instead.
By tool
Two things come from outside every tool below.run.task and run.acceptance_rule come from the exporter’s configuration or the orchestrator, since no tool records a user’s acceptance rule. And run.provenance says how the configuration was chosen, which the logs alone do not show: keep what the orchestrator knows. A run whose configuration the user’s habit chose is {kind: logged, chooser: habit}; one chosen for it by a recommender, the user or a planner is designed, even when it is exported from logs afterwards. When the choice is not known, leave provenance out.
Claude Code
Mapping
Mapping
- Hook in: a hook script (SubagentStart and SubagentStop, Stop, SessionEnd, PostToolUse) for identity, effort, gates and file paths, plus either the per-agent transcripts or an OTLP receiver for tokens.
- Fills: one attempt per session and per subagent; model (verified) and effort (reported, from hooks and OTel); the full token split per agent from transcripts, including 5-minute and 1-hour cache buckets (
measured); dollars from OTelcost_usd;spawnedges from subagent records or OTel parent ids (verified);launchedges acrossclaude -psessions through the OTel trace parent; artifact edges from Write, Edit and Read paths; a verdict when a blocking hook ran a check. - Gaps: nothing links a retried agent to the earlier one, so there is no attempt cause. The OTel route loses the cache buckets. A workflow script is imperative, so the configuration is inferred (
heuristic). - loopmath 0.1: reads transcripts natively and writes 0.3 with measured cost, spawn and artifact edges; its
otel-genaiadapter reads Claude Code traces.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
Codex CLI
Mapping
Mapping
- Hook in: a poller over rollout files (the richest source), an OTLP receiver, or the
codex exec --jsonstream for runs the orchestrator starts. - Fills: one attempt per thread; model and effort per turn (reported); input, cached input, cache writes, output and reasoning tokens (
measured; uncached input isinput_tokensminuscached_input_tokens);spawnedges from the parent thread id (verified); files written. - Gaps: no gate or verdict object; files read are not recorded; no dollars outside an OTel estimate, so an exporter prices tokens with a tariff.
- loopmath 0.1: reads rollouts natively and writes 0.3 with spawn lineage and launch origins.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
OpenCode
Mapping
Mapping
- Hook in: a plugin on session, message and file events, or a poller over
opencode export, theopencode serveHTTP server, oropencode run --format json. - Fills: one attempt per session; model (verified) and its variant as effort (reported); input, cache reads and writes, output and reasoning tokens (
measured); dollars as the harness computed them;spawnedges from child sessions’ parent id; files written. - Gaps: no acceptance signal; no cache retention buckets; one session can mix models.
- loopmath 0.1: adapter (
opencode), which keeps the per-model split inext.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
Pi
Mapping
Mapping
- Hook in: a Pi extension on session, agent, turn and tool events, or the session JSONL files after the fact.
- Fills: model per message (verified), thinking level as effort (reported), input, cache reads and writes (including a 1-hour bucket), reasoning and output tokens, and dollars per message.
- Gaps: core Pi has no subagents, gates or dependencies; add-on packages supply them, and their run files were not examined. A fork has no core edge kind.
- loopmath 0.1: adapter (
pi): one attempt per session, measured tokens and dollars, no edges.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
OMP
Mapping
Mapping
- Hook in: a hook or extension on session, agent, turn, tool and retry events, or a poller over session files.
- Fills: model and thinking level per session; input, cache reads and writes, and output tokens; dollars; subagent child sessions with per-spawn effort.
- Gaps: ordinary task children have no durable parent key, so
spawnedges areheuristic(verified for the vibe runtime); no verdicts;auto_retryevents are API retries, not attempts. - loopmath 0.1: adapter (
omp).
bb
Mapping
Mapping
- Hook in: a bb backend plugin, the HTTP and WebSocket API, or read-only access to its database for backfill.
- Fills: one attempt per thread; model and reasoning level overrides (reported); input, cached input, output and reasoning tokens per thread;
spawnand fork lineage (verified). - Gaps: no dollars; queued messages between threads have no core edge kind; no native run boundary (by convention, a root thread is a run). Input includes cache reads for Codex threads.
- loopmath 0.1: adapter (
bb), withlaunchedges to joined vendor sessions (heuristic).
Sources, seen 2026-09-23
Sources, seen 2026-09-23
Paseo
Mapping
Mapping
- Hook in: a daemon WebSocket client or a server plugin. A poller over the agent files works for backfill but gets no tokens.
- Fills: one attempt per agent with its provider, model and thinking option (reported);
spawnedges from the parent-agent label; tokens and dollars only from live usage events. - Gaps: no persisted usage; no verdicts, dependencies or artifacts; the parent label can be edited later.
- loopmath 0.1: adapter (
paseo), without tokens.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
Orca
Mapping
Mapping
- Hook in: a poller over its orchestration database or the CLI’s
--jsoncommands. The plugin API exposes only worktree and status events. - Fills: tasks with declared dependencies (
depedges, verified); one attempt per dispatch, with a typed retry pointer forcause; model and effort from the worker launch (reported); decision gates, worker outcomes and merge-ready messages as verdicts (reported); files modified. - Gaps: usage is kept per session and worktree, never per dispatch, so per-attempt cost is always
allocated; decision-gate options are free text. - loopmath 0.1: adapter (
orca), without tokens; it does not yet read dependencies or retry pointers.
Atrium
Mapping
Mapping
- Hook in: a poller over the CLI’s
--jsonoutput. Its database schema is documented as internal. - Fills: tasks as nodes and runs as attempts (reported); a task moved to done as a verdict (reported).
- Gaps: no public record of tokens, cost, model or effort; cost has to come from the wrapped harness’s own logs. Only the public docs were read; there is no public source.
- loopmath 0.1: adapter (
atrium), which reads its timeline into events only.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
LangGraph
Mapping
Mapping
- Hook in: a checkpointer wrapper (steps, forks, interrupts, routing) plus a callback handler for per-call usage and model, or OTLP export.
- Fills: the compiled graph as a declared workflow (verified) and
depedges; one attempt per node step, with repair rounds from routing; model (verified) and effort (reported); input, cache reads and writes, output and reasoning tokens (measured, after subtracting cached input); router decisions as reported verdicts. - Gaps: individual retries under a retry policy are not persisted; graphs with several loops or non-gate routers can only be approximated as a 0.3 workflow; no dollars.
- loopmath 0.1: no adapter.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
CrewAI
Mapping
Mapping
- Hook in: a listener on CrewAI’s event bus.
- Fills: tasks and their declared context as
depedges (verified); one attempt per task try, with guardrail retries as attempts caused by a failed gate; guardrail results as verified verdicts; model and reasoning effort (reported); per-call usage from LLM call events; output files as artifacts. - Gaps: usage keys depend on the provider, so the split needs normalizing; no dollars; human-input feedback is a directive, not a verdict.
- loopmath 0.1: no adapter.
OpenAI Agents SDK
Mapping
Mapping
- Hook in: a tracing processor registered with
add_trace_processor, or run and agent hooks. - Fills: one run per trace and one attempt per agent span; model (verified) and reasoning effort from model settings (reported); input, cached input, cache writes, output and reasoning tokens per request (
measured, after subtracting cached input); handoffs and agents used as tools as edges; guardrail tripwires as verdicts. - Gaps: no files and no dollars; a handoff has no core edge kind; a tripwire ends the run rather than repairing it.
- loopmath 0.1: no adapter.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
OpenTelemetry GenAI
Mapping
Mapping
- Hook in: an OTLP receiver, or a Collector file exporter read afterwards.
- Fills: one attempt per agent invocation; model and the reasoning level sent to the provider; input, cache reads and writes, output and reasoning tokens (after subtracting cached input);
spawnandlaunchedges from span parents; evaluation results as verdicts (reported). - Gaps: the conventions define no cost, attempts, retry causes, declared dependencies or gates, and every attribute is still in development, so an exporter should pin the version it follows.
- loopmath 0.1: adapter (
otel-genai), used for Claude Code and Codex traces.
Sources, seen 2026-09-23
Sources, seen 2026-09-23
Add your tool
If you maintain an agent tool or have written an exporter, add it here. Open an issue or a pull request with the tool, where the exporter hooks in, and an example document that passesloopmath ocp validate. See Contributing.