# Landscape (/docs/landscape)



Most of what an agent runtime can do, some other tool already does.
This page says which is which — honestly, in both directions. We
ran the field (Helicone, Langfuse, LangSmith, Portkey, LiteLLM,
OpenMeter, MLflow, Logfire, Braintrust, Datadog, Arize Phoenix,
LangGraph, Temporal, Inngest, CrewAI, the OpenTelemetry GenAI
conventions) against twenty capabilities Pleach claims, and graded
each one.

Three tiers, ordered by how much of the capability is structural
to `@pleach/core` versus available elsewhere:

* **Structural** — the shape is the audit row, and we didn't find
  it shipping as a first-class concept in the tools above. Reach
  for Pleach *for these*.
* **Assembled here** — the pieces exist across two or three
  separate products; Pleach is the one place they're one primitive.
  The wedge is the combination, not the invention.
* **Table stakes** — commodity. Everyone ships it. Don't switch
  runtimes for these; if you already have one of the tools below,
  you already have the capability.

A note on the verdicts: where a tier says "we didn't find it," that
is absence of evidence across the public docs we read, not a proof
that nothing exists. Each row names the mechanism, so you can check
it against your own stack rather than take the grade on faith.

## Tier 1 — Structural to the audit row [#tier-1--structural-to-the-audit-row]

The capabilities where the substrate's row shape is the
differentiator. Each row: what's different here, and where the rest
of the field lands.

| # | Capability                                     | Where the field lands                                                                                                                                                                                                                                                         | What's different in Pleach                                                                                                                                                                                                                |
| - | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | **Tamper-evident hash chain over the LLM log** | No LLM-observability or gateway tool we read ships a hash chain over the call log. The mechanism is proven elsewhere — AWS CloudTrail digest chaining, `immudb`, Sigstore Rekor — but none are LLM-call-shaped.                                                               | Every event-log row carries `prev_hash` + `row_hash`. A backfill or a removed row breaks the chain at the verifier pass (`verifyChainForChat`, `generateProof` in `@pleach/core/eventLog`). See [hash chain](/docs/hash-chain).           |
| 2 | **Deterministic replay of the agent path**     | Three things get called "replay." Durable-execution platforms (Temporal, Inngest) journal the model output as an opaque step result. LangGraph's own docs say replay re-fires LLM calls and "may return different results." Eval tools re-generate and score.                 | A recorded turn replays byte-identical against the same version + fingerprint, or strict mode throws `ReplayDivergenceError` naming the first diverging event. See [determinism](/docs/determinism).                                      |
| 3 | **Family-lock as a replay-integrity guard**    | No framework names "this replay is only valid against the same model family" as an enforced constraint. The adjacent idea — Temporal's non-determinism guard, eval-tool `seed` pinning — is about code version or sampling, not provider family.                              | At session start the lock freezes tokenizer, prompt-cache key, tool-call dialect, and refusal pattern; the cascade walks the same family and never silently widens. See [family-lock](/docs/family-lock).                                 |
| 4 | **Subagent cost rolled up to the parent turn** | Observability tools capture child-span tokens, then reconstruct cost by walking the trace tree at query time. The gap is documented in agent runtimes' own trackers, where a parent turn can under-report child spend.                                                        | Each subagent's `AuditableCall` rows carry the parent `turnId`, so child-session token spend rolls up as a stored field — per-customer billing is one `GROUP BY`, not a tree walk. See [subagents](/docs/subagents).                      |
| 5 | **One typed row per provider call**            | The market emits span *trees* into an analytical store, with sampling expected. MLflow is the closest neighbor — one row per trace — but it's per-trace, not per-decision, and not framed to join billing.                                                                    | Every model invocation writes exactly one `AuditableCall` row, no sampling, keyed `(sessionId, turnId, stageId, seqWithinTurn)`. See [the AuditableCall row](/docs/auditable-call-row).                                                   |
| 6 | **Event-granular session fork**                | LangGraph forks at the super-step / node boundary — the finest grain in the field. Mastra suspends and resumes at a step id. Nobody forks mid-step at an arbitrary event.                                                                                                     | `fork(opts)` splices the original event stream at `forkAtSequenceNumber`, an event-keyed row, not a node boundary. See [time-travel](/docs/time-travel).                                                                                  |
| 7 | **Same primitives, two adoption paths**        | The brownfield hook (wrap an existing loop) and the greenfield runtime both exist — but as different products with different value shapes. Inngest's `step.ai.wrap` adds durability; LangSmith adds tracing; neither writes the *same* audit primitive the full runtime does. | The hook over an existing loop and the full runtime write the same `AuditableCall` row, so the hook is an on-ramp into the runtime, not a separate tool. See [adoption paths](/docs/adoption-paths).                                      |
| 8 | **Trust posture as a stated contract**         | Telemetry-on-by-default is the norm in agent frameworks. No framework we read packages the four promises into one named commitment.                                                                                                                                           | No telemetry phone-home, no remote license check, no account to run, no retroactive paywall via the license clock — stated, and scoped to the runtime package. See [ownership](/docs/ownership).                                          |
| 9 | **Language-agnostic wire contract**            | Multi-language tooling means either N parallel SDKs over an inter-agent protocol (Google ADK + A2A) or N clients of one central server (Temporal). Neither is two reference implementations holding one contract honest.                                                      | The contract pins HTTP+SSE shapes, fingerprint canonicalization, and row layout; a Go implementation round-trips the same recorded turns as the TypeScript reference. See [language-agnostic contract](/docs/language-agnostic-contract). |

## Tier 2 — Assembled here [#tier-2--assembled-here]

Each of these exists in the field, split across separate products.
Pleach's claim is that they're one primitive in the audit row, not
that no one else has the pieces.

| #  | Capability                                           | Where the pieces live                                                                                                                                                                                                            | What the combination buys                                                                                                                              |
| -- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 10 | **Cost joinable to a billing schema in your own DB** | LiteLLM owns the spend row in your Postgres; OpenMeter does the billing join and Stripe sync. Neither carries agent-aware shape (turn, subagent depth, tool name).                                                               | One row you own *and* can join — agent-shaped — without a second metering pipeline.                                                                    |
| 11 | **Per-turn cost as a queryable field**               | Per-*request* cost is a first-class inline field (OpenRouter `usage.cost`, Cloudflare, Vercel). A turn that fans out into many calls is a query-time `GROUP BY`, not a column.                                                   | `tokenUsage` rolls to `turnId` on the row, so the turn — not the request — is the indexed unit.                                                        |
| 12 | **Ledger written to your destination**               | "Ship OTLP spans to a trace backend" is commodity (OpenLLMetry, the OTel collector). Writing the audit *ledger* into your existing operational Postgres / Supabase — with Memory as a peer for tests — is not the shipped shape. | BYO-DB adapters write the row where the rest of your business data already lives. See [storage](/docs/storage).                                        |
| 13 | **SQL-queryable ownership**                          | Logfire gives you full SQL — in their cloud. MLflow gives you SQL on your own Postgres. Langfuse / LangSmith / Braintrust self-host means your infra, but a proprietary store, not joinable rows.                                | The row is in your database, queryable with ordinary SQL, joinable to the tables next to it. See [the audit ledger](/docs/audit-ledger).               |
| 14 | **Erasure that coexists with the chain**             | "Delete rows by user id" is common. Erasure that preserves a tamper-evident chain — crypto-shred the subject, keep the hash — is unsolved in the products we read; the tension is real.                                          | `GDPRSoftDelete` is a plug-point designed to erase the subject without breaking the chain verifier. See [GDPR erasure](/docs/compliance/gdpr-erasure). |
| 15 | **Sessions, graph, and channels together**           | Sessions are universal. A graph runtime is common. The three as co-equal, surfaced primitives is essentially only LangGraph today, and there "channels" is an internal compilation detail.                                       | All three are documented developer primitives on one substrate. See [graph](/docs/graph) and [channels](/docs/channels).                               |

## Tier 3 — Table stakes [#tier-3--table-stakes]

Commodity. If you already run one of the tools named, you already
have the capability — these are not a reason to change runtimes.
Pleach ships them because the substrate needs them, not because
they're differentiated.

| #  | Capability                          | Already shipped by                                                                                                                                                                         |
| -- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 16 | **Per-tenant cost allocation**      | Helicone (`Helicone-User-Id`), Portkey metadata, LiteLLM (`x-litellm-customer-id`), Vercel AI Gateway, Cloudflare, Datadog, OpenMeter. A metadata tag and a `GROUP BY`.                    |
| 17 | **Tool-call audit capture**         | The OpenTelemetry GenAI conventions and OpenLLMetry made tool-call spans table stakes. Every tracing tool captures them.                                                                   |
| 18 | **Checkpointing / resumable state** | LangGraph is the reference; Temporal / Inngest / Restate do it as durable execution; Mastra snapshots on suspend.                                                                          |
| 19 | **Regression diff engine**          | Braintrust, LangSmith, Langfuse, Promptfoo, DeepEval all diff scores across runs. (Diffing two *deterministic* runs event-for-event is Tier 1, row 2 — different claim.)                   |
| 20 | **PII redaction at the boundary**   | Microsoft Presidio is the detection engine; Langfuse, LangSmith, LiteLLM, Portkey are hooks that mostly delegate to it. `@pleach/compliance` `Scrubber`s do the same and can delegate too. |

## The short version [#the-short-version]

If you want four sentences to carry to a buyer:

1. Per-tenant cost is table stakes — don't sell it as new.
2. The differentiated shape is the **row**: one typed,
   hash-chained `AuditableCall` per call, in your own database,
   with subagent spend already rolled to the turn.
3. **Deterministic replay** plus **family-lock** is the pair the
   rest of the field admits it doesn't ship — replay you can trust
   because the lock keeps it honest.
4. Everything else here is real, but it's a combination of parts
   you could assemble yourself — Pleach is the assembly, not the
   only source of the parts.

<Cards>
  <Card title="Comparison" href="/docs/comparison" description="The axis-by-axis matrix against the AI SDK, LangChain, LlamaIndex, Mastra, and the observability cohort." />

  <Card title="The AuditableCall row" href="/docs/auditable-call-row" description="The row shape that Tier 1 is built on — what it carries and what you can join it against." />

  <Card title="Ownership" href="/docs/ownership" description="The four trust commitments, and what they are and aren't scoped to." />

  <Card title="When to reach for something else" href="/docs/comparison#when-to-reach-for-something-else" description="The honest case for the AI SDK, a harness, or a durable-execution platform instead." />
</Cards>
