Contractual runtime
for AI agents
DEED gives your AI agents pre/post contracts, automatic checkpointing, built-in DEED Credits metering, and policy enforcement — in five lines of code.
pip install deed-runtime
Why DEED?
Every team deploying LLM agents in production hits the same wall: the agent does something unexpected, and you have no idea why. No audit trail, no pre-conditions, no rollback. You're trusting a probabilistic model with deterministic consequences.
DEED treats every agent action as a contract. Before execution: verify conditions. After execution: verify outcomes. In between: charge only what was agreed. If something breaks: replay from the last checkpoint.
DEED is not a new agent framework. It's a contract layer that works with any Python function, any LLM call, any API.
What DEED gives you
Pre/Post Contracts
Declare what must be true before an action runs, and what must be true after. DEED-Kernel enforces both.
Policy Engine
Allow, deny, and cap agent actions based on runtime context. Policy is checked before LLM gets control.
DEED Credits & x402
Charge credits per action. Budget caps enforced by policy. Automatic refund on contract violation. Forward-compatible with the x402 protocol.
Checkpoint & Replay
Every successful deed is checkpointed. On failure: resume from last known good state, zero re-computation.
Installation
Requirements
| Requirement | Version | Notes |
|---|---|---|
| Python | ≥ 3.10 | Uses match statements, union types |
| pip | any |
Install
bash# Install from PyPI pip install deed-runtime # From source git clone https://github.com/Deadly-Reiter/deed cd deed && pip install -e .
Verify installation: python -c "from deed import DeedRuntime; print('deed-runtime ok')"
Quickstart
From zero to a running contractual agent in under 2 minutes.
Install
bashpip install deed-runtime
Describe your agent in .dd
deeddeeds/agents/score_agent.ddagent score_agent capabilities ["score_company"] contract score_contract pre company_name post score_generated policy cap budget_tokens <= 5000 allow score_company if company_name
deeddeeds/pipelines/my_pipeline.ddpipeline my_pipeline stage score agent score_agent -> score_company() checkpoint after on_error retry
jsoninput/state.json{ "company_name": "Acme AI", "budget_tokens": 3000 }
Register and run
pythonrun.pyfrom deed import DeedRuntime def score_company(ctx: dict) -> dict: ctx["score"] = 0.82 ctx["score_generated"] = True return ctx runtime = DeedRuntime(".", initial_credits=100) runtime.register("score_company", score_company) result = runtime.run("my_pipeline", "input/state.json") print(result.get("score")) # 0.82 print(result.get("run_status")) # completed
Pre-condition checked → executor ran → post-condition verified → checkpoint saved. Contract fails → action rejected, no credits charged.
Done. See Use Cases for full multi-stage pipelines, or Reference for the complete .dd syntax.
Core Concepts
The Contract Principle
DEED doesn't trust LLMs to self-regulate. Every deed (atomic action) must satisfy a contract before and after execution. If either check fails, the runtime rejects the action — before it hits your API, database, or wallet.
Execution Lifecycle
Key Primitives
| Primitive | Purpose | Analogy |
|---|---|---|
| agent | Declares agent capabilities and constraints | Class definition |
| deed | Atomic action with retry and idempotency | Atomic transaction |
| pipeline | Ordered sequence of stages | DAG / workflow |
| contract | Pre/post conditions on a deed or agent | Design-by-contract |
| policy | Allow/deny/cap rules enforced before LLM | IAM policy |
Use Case — Sales Intelligence Agent
A three-stage pipeline that enriches a company profile, scores ICP fit, and generates a personalized outreach brief. Each stage runs a dedicated specialist agent with its own contract.
deedpipelines/sales_intelligence.ddpipeline sales_intelligence description "End-to-end sales intelligence workflow" input company_profile stage enrich agent data_agent -> enrich_company() checkpoint after on_error retry stage score agent score_agent -> score_company() checkpoint after on_error retry stage brief agent brief_agent -> generate_brief() -> persist_result() on_error deadletter observe trace true latency warn
deedagents/data_agent.ddagent data_agent description "Enriches company profile with public data" capabilities ["enrich_company"] policy cap budget_tokens <= 5000 deny enrich_company if region == "restricted" contract enrich_contract pre company_name_present post enriched agent score_agent description "Scores ICP fit 0.0 – 1.0" capabilities ["score_company"] policy cap budget_tokens <= 5000 allow score_company if enriched contract score_contract pre enriched post score_generated agent brief_agent description "Generates personalized outreach brief" capabilities ["generate_brief", "persist_result"] policy cap budget_tokens <= 4000 allow generate_brief if scored contract brief_contract pre scored post brief_generated
pythonrun.pyfrom deed import DeedRuntime from executors.sales_ops import enrich_company, score_company, generate_brief, persist_result runtime = DeedRuntime(".", initial_credits=100) (runtime .register("enrich_company", enrich_company, charge=1) .register("score_company", score_company, charge=1) .register("generate_brief", generate_brief, charge=1) .register("persist_result", persist_result, charge=1) ) result = runtime.run("sales_intelligence", "input/company.json") print(f"Score: {result['score']}") print(f"Brief: {result['brief']}") print(f"Credits: {runtime.x402.spent} used")
output[DEED] stage: enrich [DEED] charged: 1 credit | balance: 99 [DEED] checkpoint: enrich::enrich_company [DEED] stage: score [DEED] charged: 1 credit | balance: 98 [DEED] checkpoint: score::score_company [DEED] stage: brief [DEED] charged: 1 credit | balance: 97 [DEED] checkpoint: brief::generate_brief [DEED] checkpoint: brief::persist_result Score: 1.0 Priority: high Brief: Acme AI GmbH is a B2B SaaS company (Series B). ICP score: 1.0 (high priority). Tech stack: Salesforce, HubSpot, Slack. Recommended next action: research decision makers. Credits: 4 used
Use Case — Data Pipeline Agent
An extraction-transformation-load pipeline where each stage has explicit data contracts. If the schema contract fails at any stage, the pipeline halts before bad data propagates downstream.
deedpipelines/data_etl.ddpipeline data_etl description "Schema-safe extraction and transformation" input raw_source stage extract agent extractor_agent -> fetch_records() checkpoint after on_error retry stage validate agent validator_agent -> check_schema() checkpoint after on_error deadletter # halt — don't load bad data stage transform agent transform_agent -> normalize_fields() -> enrich_metadata() checkpoint after on_error retry stage load agent loader_agent -> write_to_warehouse() checkpoint after on_error deadletter
deeddeeds/extract.ddagent extractor_agent capabilities ["fetch_records"] contract extract_contract pre source_url_present post records_fetched policy cap record_count <= 100000 deny fetch_records if source_type == "pii_unmasked" agent validator_agent capabilities ["check_schema"] contract validate_contract pre records_fetched post schema_valid agent loader_agent capabilities ["write_to_warehouse"] deed write_to_warehouse idempotency_key batch_id # safe to retry retry 3 contract load_contract pre schema_valid and records_transformed post data_persisted
pythonrun.pyfrom deed import DeedRuntime from executors.etl_ops import fetch_records, check_schema, normalize_fields, enrich_metadata, write_to_warehouse runtime = DeedRuntime(".", initial_credits=500) (runtime .register("fetch_records", fetch_records, charge=1, retry=3) .register("check_schema", check_schema, charge=1) .register("normalize_fields", normalize_fields, charge=1, retry=2) .register("enrich_metadata", enrich_metadata, charge=1, retry=2) .register("write_to_warehouse", write_to_warehouse, charge=1, idempotency_key="batch_id") ) # First run result = runtime.run("data_etl", "input/source.json") # Failure mid-run? Resume from last checkpoint runtime2 = DeedRuntime(".", replay=True, initial_credits=500) runtime2.register("fetch_records", fetch_records) # ... same registrations ... result = runtime2.run("data_etl", "input/source.json") # → Skips fetch, validate, transform # → Resumes at load — no duplicates
Use Case — API Orchestrator
Coordinates multiple third-party API calls with rate limiting, budget caps per provider, and automatic retry. Useful for agents that fan out to multiple services (search, enrichment, notification).
deedagents/api_orchestrator.ddagent api_orchestrator description "Coordinates external API calls with budget control" capabilities ["search_web", "enrich_linkedin", "send_slack_alert", "write_crm"] policy cap api_calls <= 50 cap budget_tokens <= 5000 deny send_slack_alert if score < 0.6 deny write_crm if not data_validated contract orchestrator_contract pre query_present post result_written or alert_sent observe trace true explain true
deeddeeds/api_calls.dddeed search_web retry 3 idempotency_key query_hash deed enrich_linkedin retry 2 idempotency_key profile_url deed send_slack_alert retry 1 idempotency_key alert_id # blocked by policy if score < 0.6 deed write_crm retry 3 idempotency_key company_id
pythonrun.pyfrom deed import DeedRuntime, ContractViolation, PolicyViolation from executors.api_ops import search_web, enrich_linkedin, send_slack_alert, write_crm runtime = DeedRuntime(".", initial_credits=200) (runtime .register("search_web", search_web, charge=1, retry=3) .register("enrich_linkedin", enrich_linkedin, charge=2, retry=2) .register("send_slack_alert", send_slack_alert, charge=1) .register("write_crm", write_crm, charge=1, retry=3) ) try: result = runtime.run("api_orchestrator", "input/query.json") except PolicyViolation as e: print(f"Blocked by policy: {e}") # e.g. "score 0.4 — send_slack_alert denied" except ContractViolation as e: print(f"Contract failed: {e}") # Checkpoint saved — replay when ready
Syntax Reference — agent
An agent block declares a named agent with its capabilities, policy constraints, and contracts.
deedagent <name> description "..." # optional, human-readable capabilities ["action1", "action2"] # actions this agent can perform policy ... # enforcement rules contract <name> ... # pre/post conditions observe ... # tracing / explain
Fields
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | optional | Human-readable purpose of the agent |
| capabilities | list | required | Action identifiers this agent is permitted to perform |
| policy | block | optional | Allow / deny / cap rules evaluated before execution |
| contract | block | optional | Pre/post conditions verified by DEED-Kernel |
| observe | block | optional | Enables trace logging and explanations |
observe block
deedobserve trace true # emit checkpoint events explain true # LLM explains each decision (verbose) latency warn # warn if stage exceeds threshold
Syntax Reference — pipeline
A pipeline defines an ordered sequence of stages. Each stage maps to a specific agent and a set of actions. DEED-Runtime executes stages in declaration order.
deedpipeline <name> description "..." input <context_key> stage <name> agent <agent_name> -> action1() -> action2() checkpoint after on_error retry | deadletter observe trace true
Stage fields
| Field | Values | Description |
|---|---|---|
| agent | agent name | Which agent handles this stage |
| -> action() | – | Actions to execute in order. Multiple allowed. |
| checkpoint | after | Saves state after stage completes successfully |
| on_error | retry / dead_letter | retry: re-attempts. dead_letter: halts, sends to DLQ. |
Syntax Reference — deed
A deed is the atomic unit of action. It wraps a single operation with retry semantics and idempotency guarantees.
deeddeed <name> retry 3 # attempts before DLQ idempotency_key <context_key> # safe to re-run
Fields
| Field | Type | Required | Description |
|---|---|---|---|
| retry | integer | optional | Max retry attempts on transient failure. Default: 0. |
| idempotency_key | context key | optional | Key from context used to deduplicate calls |
Executor functions are registered in Python via runtime.register("action_name", fn, charge=1). The deed block in .dd files sets retry and idempotency behaviour.
Any deed that writes to an external system (DB, API, wallet) must have an idempotency_key. Without it, retries may cause duplicate writes.
Syntax Reference — contract
Contracts define what must be true before and after a deed or agent execution. DEED-Kernel enforces both. Violations halt execution before any side effects occur.
deedcontract <name> pre <expression> # checked before execution post <expression> # checked after execution
Pre-condition
Evaluated against the current context before the action runs. If false: ContractViolation is raised, no credits are charged, no side effects occur.
Post-condition
Evaluated against the updated context after the action runs. If false: ContractViolation, action is rolled back, credits refunded.
Examples
deed// Named predicate contract c1 pre company_name_present post score_generated # Comparison expression contract c2 pre input.balance > 0 post output.status == "success" # Compound condition contract c3 pre enriched and score_generated post brief_generated or result_persisted
Built-in named predicates
| Predicate | True when |
|---|---|
| company_name_present | context.company_name is non-empty |
| enriched | context.enriched == true |
| scored | context.score is not None |
| score_generated | alias for scored |
| brief_generated | context.brief is non-empty |
| result_persisted | context.persisted == true |
Syntax Reference — policy
Policy rules are evaluated before the LLM receives control. This makes jailbreak and unauthorized tool use structurally impossible — the gate closes before any generation happens.
deedpolicy cap <field> <= | >= | == <value> # resource limit allow <action> if <condition> # allow if condition true deny <action> if <condition> # deny if condition true
Rule types
| Rule | Semantics | On violation |
|---|---|---|
| cap | Context field must satisfy the constraint | PolicyViolation before execution |
| allow | Action is permitted only if condition is true | PolicyViolation if no allow rule matches |
| deny | Action is blocked if condition is true | PolicyViolation immediately |
Evaluation order
cap rules → deny rules → allow rules. An action is allowed if no deny matches and at least one allow matches (or no allow rules are defined for that action).
Examples
deedpolicy # Hard resource caps cap budget_tokens <= 5000 cap api_calls <= 50 # Conditional deny — geography restriction deny enrich_company if region == "restricted" # Conditional allow — require prerequisite allow generate_brief if scored allow write_crm if data_validated and score >= 0.7 # Unconditional deny deny delete_all if true
Syntax Reference — Expressions
Expressions are used in pre:, post:, and if clauses. They are evaluated against the runtime context dictionary.
Comparison operators
| Operator | Example | Notes |
|---|---|---|
| == | output.status == "success" | Equality, works with strings, numbers, bools |
| > | input.balance > 0 | Numeric comparison |
| < | score < 0.6 | |
| >= | score >= 0.7 | |
| <= | budget_tokens <= 5000 |
Logical operators
deed// and — both must be true pre: enriched and company_name_present // or — at least one must be true post: result_persisted or alert_sent // not — negation pre: not data_validated
Context path resolution
Dotted paths like input.region or output.status resolve against the context dict. The input prefix is optional and stripped automatically.
deed// These are equivalent: pre: input.balance > 0 pre: balance > 0
Runtime — Execution Lifecycle
Every deed in DEED passes through a deterministic five-phase cycle. No phase can be skipped.
State machine guarantees
| Guarantee | Mechanism |
|---|---|
| No side effects on pre-condition failure | Validate runs before Execute |
| No charge on contract violation | Credits charged only after pre-condition passes |
| Idempotent replay | Checkpointed steps are skipped on re-run |
| No unbounded resource use | Policy cap enforced before LLM |
Runtime — DEED Credits
DEED treats compute cost as a first-class object. Every deed execution costs 1 DEED Credit by default (configurable via charge in register()). Budget enforcement happens at the policy layer — the agent is stopped before it overspends.
The metering layer uses the X402Client interface, which is designed for forward compatibility with the x402 payment protocol. When x402 matures as an industry standard, DEED will support native on-chain payments without changes to your agent code.
How charging works
Pre-condition passes
Policy cap budget_tokens is checked first. If violated — no charge, no execution.
Credits charged
Credits are deducted from your balance. Current balance available in runtime.x402.credits.
Post-condition fails → refund
If post-condition is violated after charging, credits are refunded automatically.
pythonfrom deed import DeedRuntime runtime = DeedRuntime( project_root=".", initial_credits=1000, # starting balance ) runtime.register("score_company", score_fn, charge=1) runtime.register("send_alert", alert_fn, charge=2) # costs 2 credits result = runtime.run("my_pipeline", "input/state.json") print(runtime.x402.credits) # remaining balance print(runtime.x402.spent) # total spent this run
Runtime — Checkpoint & Replay
Every successful deed writes a checkpoint: the step identifier and full context state. On failure, pass replay=True to resume from the last checkpoint. Completed steps are skipped — no duplicate charges, no duplicate writes.
Checkpoint format
jsonoutput/checkpoint.json{ "completed_steps": [ "enrich::enrich_company", "score::score_company" ], "context": { "company_name": "Acme AI GmbH", "score": 0.82, "score_generated": true, "run_status": "running" } }
Replay
python# Normal run runtime = DeedRuntime(".", initial_credits=100) runtime.register("score_company", score_fn, charge=1) result = runtime.run("my_pipeline", "input/state.json") # Failure at stage 3? Resume: runtime2 = DeedRuntime(".", replay=True, initial_credits=100) runtime2.register("score_company", score_fn, charge=1) result = runtime2.run("my_pipeline", "input/state.json") # → [DEED] replay skip: enrich::enrich_company # → [DEED] replay skip: score::score_company # → [DEED] stage: brief ← continues here
Replay uses the checkpointed context, not the original input. This means enriched data from earlier stages is preserved across replay.
Runtime — Error Handling & DLQ
When a deed fails after exhausting retries, it enters the Dead Letter Queue. DEED-Runtime can either halt execution or continue with subsequent stages depending on the on_error setting.
on_error modes
| Mode | Behaviour | Use when |
|---|---|---|
| retry | Re-attempts up to deed's retry count. On exhaustion: DLQ. | Transient failures (network, rate limits) |
| dead_letter | Immediately halts stage. Writes to deed.dlq. Checkpoint saved. | Data integrity critical (validation, load) |
DLQ entry format
jsonoutput/deed.dlq{ "step": "validate::check_schema", "ts": "2026-05-05T04:22:11Z", "error": "ContractViolation: post: schema_valid not satisfied", "context": { "...": "last known state" }, "retries": 3 }
Recovery flow
Deed fails → DLQ
Entry written to deed.dlq with full context and error. Checkpoint preserved.
Human review or auto-recovery
Runtime emits recovery_intent event. Can be handled by a recovery agent or escalated to human operator.
Replay from checkpoint
Once issue is resolved: runtime.run(context, replay=True) resumes from the failed stage. All prior work is preserved.