@else-ventures/agent-provenance-dag
v0.1.0
Published
Signed causal provenance DAGs for delegated agent work
Maintainers
Readme
agent-provenance-dag
Signed causal provenance DAGs for delegated agent work.
agent-provenance-dag is a small TypeScript package for creating and verifying signed event graphs that explain how delegated work moved from one agent to another. It is built for OpenClaw agents, autonomous agents, and human operators who want a portable provenance envelope instead of a hand-wavy trust story.
Agent metadata
- Built for: OpenClaw agents, autonomous agents, and human operators
- Category: agent-infrastructure
- Use cases: delegated task provenance, agent handoff verification, artifact lineage, compact trust envelopes
- Runtime: Node.js / TypeScript
Current status
V1 is intentionally narrow:
- create signed provenance events
- link them with
selfParentandcausalParents - verify graph integrity offline
- create a compact signed claim that can travel with a task
- carry the full DAG inline or by pointer
V1 does not try to solve:
- agent reputation
- payment settlement
- RPC-based on-chain verification
- key management or rotation
- protocol-wide policy engines
Why a DAG instead of a plain log?
Delegated agent work is rarely a single straight line.
One agent can start a task, delegate part of it to another agent, receive a signed artifact back, and then forward the result downstream. Payment, delivery, and verification can happen on different branches. A DAG captures that causal structure directly.
Mental model: Alice and Bob
Alice is handling a task but needs market context before she can continue.
- Alice creates a
GENESISevent for the task. - Alice delegates part of the task to Bob and signs a
DELEGATEDevent. - Bob verifies the incoming claim, accepts the work, and signs an
ACCEPTEDevent. - Bob produces an artifact, signs a
DELIVEREDevent, and returns it to Alice. - Alice forwards the result to another agent with:
- the task output
- a compact signed claim
- optionally a pointer to the full DAG
The next agent does not need to interrogate Alice or Bob live. It can inspect the signed provenance payload, verify the structure offline, and decide whether to trust the handoff.
Install
Clone the repo and install dependencies:
git clone https://github.com/Else-Ventures/agent-provenance-dag.git
cd agent-provenance-dag
npm install
npm run buildnpm publish comes after v1 review.
API
createEvent(input): Promise<ProvenanceEvent>
verifyEvent(event): Promise<boolean>
createDag(): ProvenanceDag
insertEvent(dag, event): ProvenanceDag
verifyDag(dag): Promise<{ valid: boolean; errors: string[] }>
hashDag(dag): string
createClaim(input): Promise<ChainClaim>
verifyClaim(claim): Promise<boolean>
createPaymentReceiptRef(txHash, chainId, amount, asset): PaymentReceiptRef
attachProvenance(task, envelope): taskWithExtensions
extractProvenance(task): ProvenanceEnvelope | null
generateEd25519Identity(): { publicKey: string; privateKey: string }
makeSigner(privateKey)
makeVerifier(publicKey)Example
import {
attachProvenance,
createClaim,
createDag,
createEvent,
generateEd25519Identity,
hashDag,
insertEvent,
makeSigner,
} from '@else-ventures/agent-provenance-dag';
const alice = generateEd25519Identity();
const bob = generateEd25519Identity();
const genesis = await createEvent({
type: 'GENESIS',
agentId: 'alice',
publicKey: alice.publicKey,
nonce: 0,
payload: { taskId: 'task-alice-bob-001', description: 'Research one opportunity' },
sign: makeSigner(alice.privateKey),
});
const delegated = await createEvent({
type: 'DELEGATED',
agentId: 'alice',
publicKey: alice.publicKey,
nonce: 1,
payload: { taskId: 'task-alice-bob-001', to: 'bob' },
selfParent: genesis.id,
causalParents: [genesis.id],
sign: makeSigner(alice.privateKey),
});
const accepted = await createEvent({
type: 'ACCEPTED',
agentId: 'bob',
publicKey: bob.publicKey,
nonce: 0,
payload: { taskId: 'task-alice-bob-001', acceptedFrom: 'alice' },
causalParents: [delegated.id],
sign: makeSigner(bob.privateKey),
});
const delivered = await createEvent({
type: 'DELIVERED',
agentId: 'bob',
publicKey: bob.publicKey,
nonce: 1,
payload: { taskId: 'task-alice-bob-001', artifactHash: 'sha256:artifact-001' },
selfParent: accepted.id,
causalParents: [accepted.id, delegated.id],
sign: makeSigner(bob.privateKey),
});
let dag = createDag();
dag = insertEvent(dag, genesis);
dag = insertEvent(dag, delegated);
dag = insertEvent(dag, accepted);
dag = insertEvent(dag, delivered);
const claim = await createClaim({
issuer: 'alice',
publicKey: alice.publicKey,
taskId: 'task-alice-bob-001',
headIds: [delivered.id],
dagHash: hashDag(dag),
dagRef: 'ipfs://bafy-example',
sign: makeSigner(alice.privateKey),
});
const outgoingTask = attachProvenance(
{ id: 'task-alice-bob-001' },
{ claim, dagRef: claim.dagRef, dag },
);See examples/alice-bob.ts for a runnable end-to-end example.
Offline vs online verification
Offline verification in v1 covers:
- event integrity
- signatures
- self-parent nonce progression
- parent existence
- cycle detection
- DAG hash matching when you compare a fetched DAG to a claim
Online verification is intentionally out of scope for v1. If you want to reference payment receipts now, attach a PaymentReceiptRef and handle chain-specific verification in your own adapter.
Key management note
This package does not manage private keys. You are responsible for generating, storing, and rotating signing keys in a way that fits your deployment.
Development
npm install
npm test
npm run build
npm run example