Multi-step & Multi-agent Workflows
Without bundling, workflows produce logs. With bundling, they produce verifiable execution evidence.
Single CER is still a first-class path
When to use a Project Bundle
Use when
- Multi-step workflows (Step 1 → Step 2 → Step 3)
- Multi-agent handoffs (Agent A → Agent B → Agent C)
- Tool-using agents where each call should be auditable
- Branching or parallel graphs that share a final state
Skip when
- A single LLM call, tool call, or deterministic run
- Independent decisions with no shared workflow identity
- Internal logs that never need workflow-level verification
The mental model
- Step - one meaningful unit of execution (one LLM call, one tool call, one agent turn).
- Step CER - a
cer.ai.execution.v1record for that step. - Project Bundle - a
cer.project.bundle.v1artifact grouping the step CERs of one workflow. - projectHash - canonical identity of the bundle.
- Node registration - what makes the bundle publicly verifiable.
Linear multi-step example
Three agents collaborate. Each agent's output becomes a step CER. The three CERs are grouped into one Project Bundle and registered on the node.
Agent A ──▶ stepA CER (certificateHash: sha256:aaa...)
Agent B ──▶ stepB CER (certificateHash: sha256:bbb...)
Agent C ──▶ stepC CER (certificateHash: sha256:ccc...)
└─▶ Project Bundle (projectHash: sha256:zzz...)
│
▼
POST /v1/project-bundle/register
│
▼
verify.nexart.io/p/{projectHash}import {
certifyDecision,
createProjectBundle,
verifyProjectBundle,
registerProjectBundle,
} from "@nexart/ai-execution";
const stepA = await certifyDecision({ /* Agent A inputs */ });
const stepB = await certifyDecision({ /* Agent B inputs, sees Agent A output */ });
const stepC = await certifyDecision({ /* Agent C inputs, sees Agent B output */ });
const bundle = await createProjectBundle({
projectId: "agent-trio-2026-04-21",
steps: [stepA.cer, stepB.cer, stepC.cer],
});
const local = await verifyProjectBundle(bundle);
if (!local.ok) throw new Error("Bundle integrity failed");
const { projectHash } = await registerProjectBundle(bundle, {
apiKey: process.env.NEXART_API_KEY!,
});
console.log(`https://verify.nexart.io/p/${projectHash}`);Tool-using agents
When an agent calls tools, each tool call MAY be a step CER. This gives auditors per-tool-call provenance without requiring you to certify the orchestration loop itself.
- Tool boundary in, tool boundary out: one step CER per call.
- Tool inputs and outputs are hashed into the step CER's
inputHashandoutputHash. - The bundle records the order of calls; the projectHash binds the sequence.
Non-linear handoffs
Branching and parallel execution graphs are supported by the same model. Each branch's step CERs are included in the bundle. The projectHash binds the full set; the bundle's internal step ordering is canonical.
- Parallel branches: include each branch's step CERs in the bundle.
- Conditional branches: only the executed branch's step CERs need to be present.
- Retries: each retry MAY be its own step CER, preserving the audit trail.
Agent Kit
For linear workflows, @nexart/agent-kit wraps the per-step certifyDecision + createProjectBundle pattern behind startWorkflow / step / finish. It is the recommended entry point for linear pipelines. For non-linear graphs, use @nexart/ai-execution directly.
Common pitfalls
- Treating one workflow as one CER. Use one CER per step, then group.
- Skipping registration. Local verification does not make the bundle publicly verifiable.
- Looking up steps by
executionId. Always usecertificateHash.