Concord blog · Part 2 of 3

Contract, not runtime

Concord is not DBOS. Not LangGraph. Not OPA. The hard part of explaining it is saying what it's not — and then drawing the line cleanly enough that what's left is obvious.

Read ~9 min Series 2 / 3 Previous ← Why agents need a contract

The most common misread

Almost every time I describe Concord, someone replies with one of:

None of those are quite right, but they're all in the right neighborhood. The burden is on me to draw the line — and the cleanest way to do that is to walk through the actual layer stack of an app that runs on Concord.

Hover the layers below.

Interactive · 1 of 3 Layer stack — what each part owns

The boundary in one paragraph

The agent harness runs the reasoning loop. Concord defines what an action means and what governance applies. DBOS executes the action durably. A policy engine evaluates the rules (or Concord's own policy bundles do). Postgres stores the truth. OTel observes the execution. Every consequential thing in the system is a command in Concord's vocabulary; everything else is a layer doing its job underneath.

Concord owns meaning and authority. DBOS owns durable execution. Postgres owns truth. Everything else is plumbing.

This is the line that took me longest to find. The first version of Concord tried to be a workflow engine. The second tried to be an agent framework. The third — the current one — tries to be neither. It's the contract that lets the runtime, the harness, the policy engine, and the storage layer talk to each other in one shape.

Not all actions deserve the full contract

The other thing I get wrong when explaining this is implying that every action gets the full ceremony. They don't. Concord defines five audit tiers, and an action's tier decides what records get written and what governance fires.

Tier 0 is ephemeral — log it to stdout and move on. Tier 4 is high-risk, regulated, and gets the full contract: command, policy decision, approval packet, artifact snapshot, idempotency, compensation, durable audit. Most actions live in the middle.

Try a few in the picker below.

Interactive · 2 of 3 Audit tier picker — what does this action need?
4
High-risk

Booking a hotel commits a customer to a payment, a date, and a third-party contract. It needs the full chain: a command row, a policy decision, an approval packet, an artifact snapshot, an idempotency key, and a compensation path.

The capability graph

Once you accept that not every action is the same, the next question is: how does the system know what an action is? Concord's answer is the Domain Registry — a capability graph that compiles at app startup from declarations spread across the codebase.

The graph starts at an agent role and walks down through skills, tools, command types, and the policies, approvals, artifacts, and connector operations each command is tied to. Clicking a node below shows you what kind of declaration produces it.

Interactive · 3 of 3 Capability graph — hotel_booking_agent
AgentRole hotel_booking_agent Skill hotel_booking_skill@1.4.2 Tool book_hotel CommandType book_hotel PolicyBundle hotel_booking_policy ArtifactSchema reservation_confirmation ConnectorOp hotel_booking.book_hotel ConnectorContract idempotency · retry · compensate
Click a node
Domain Registry

The Domain Registry is the compiled graph of an app's governed capabilities. It's not a database — it's a build artifact, validated at startup. Click any node in the graph to see what kind of declaration produced it.

Three counterarguments I take seriously

"If DBOS owns durability and OPA owns policy, what does Concord actually own?"

Meaning and authority. The capability graph above is the answer in concrete form. Without Concord, those relationships exist but they're implicit — a tool's authorization rule lives in the function body, an artifact's schema lives in the API client, a compensation lives in a try/except somewhere. Concord makes them declared, compiled, and queryable. The result is that a question like "which skills can call this connector operation?" becomes a single graph traversal instead of a codebase search.

That's a small thing on a small app. It's the kind of small thing that compounds.

"Wouldn't it be simpler to extend an agent framework?"

For a pure-agent app, yes. Take LangGraph, give it a richer audit table, attach a policy hook, you'd get something close. The problem is that most production systems aren't pure-agent. They have a deterministic checkout flow, a scheduled vendor sync, a webhook handler, and an agentic recommender — all in the same codebase, all doing real work, all needing the same governance shape.

Agent framework boundaries don't reach into the deterministic code paths. Concord does. The contract has to span both or it's not the contract.

"Why not Temporal?"

Temporal is excellent at what it does and is the named future runtime adapter for Concord — specifically because Temporal supports two capabilities that DBOS doesn't yet: native saga compensation and workflow versioning. Concord's spec is runtime-agnostic. Each adapter declares its capabilities (a frozen set), and the registration-time validator refuses to start an app whose catalog requires capabilities the active runtime doesn't have.

So the answer to "why not Temporal" is: maybe Temporal, eventually. The point of the contract layer is that the choice is yours.

Where I might be wrong

The abstraction might be too thick

The hardest argument against a contract layer is that it's another box in the architecture diagram. Every box has a maintenance cost and a learning curve. If Concord's abstractions aren't earning their keep on a particular team's workflow, the right move is to delete it and put policy hooks directly in DBOS workflows. Concord should not be religion.

Capability declaration is a bet on standardization

The Domain Registry only pays off if teams actually declare their command types, policies, and artifacts in Concord's shape. If teams route around the registry, the graph is incomplete, and an incomplete graph is worse than no graph — it lies. The mitigation is the boundary checker (a CI lint that catches direct runtime imports outside the adapter), but that catches structure, not intent.

I'm betting against ORM-style frameworks

The dominant pattern for "structured app data" is still an ORM with a god-object that mutates over a request lifecycle. Concord is closer to event sourcing — immutable rows, append-only events, derived projections. That's a less familiar shape for many teams. I might be underestimating the cost of that unfamiliarity.

Coming up in Part 3

A day in the life. We'll walk a hotel booking through the contract end-to-end, with an animated step-through and a toggle that strips Concord away so you can see what the alternative looks like.