erdl-landing

ERDL — Guardrails your agents can’t break

中文 English

Last updated: 2026-10-07 — positioned for the multi-agent era

License: MIT npm Vectors A2A Spec Deterministic Kernel Multi-agent

🚀 POC welcome — we encourage you to try this project as a proof of concept in your own environment. For technical support, contact us anytime at support@openoba.com.

Entity-Rule Definition Language · 实体规则定义语言

ERDL is the governance layer for AI agents — deterministic when → then rules, cryptographically verifiable audits, and delegated authority for multi-agent systems. One spec, one canonical tree, one hash — verified across implementations.

Never fails open. Never misses a block — provably, for the expression kernel.

ERDL checks every tool call, every decision, every delegation against rules written in plain YAML — evaluated outside the model, where prompts can’t be jailbroken. Violations are blocked and hashed into an audit trail. The same rule and the same input produce byte-for-byte identical results and hashes on any conforming implementation.

The last blank layer

Agent infrastructure is being built layer by layer — memory, runtime safety, agent management, team orchestration. Every layer that empowers agents already has a breakout open-source project.

Governance is the only blank slot left. ERDL fills it: the rules layer that makes autonomy deployable — and auditable.

What ERDL gives you

Layer What it governs ERDL primitive
Single agent Deterministic when → then behavior rules 34-node expression tree, Simple 30 operators, 13 decisions
Cross-implementation Byte-verifiable audit of every decision Decision Object (DO) + hash chain + 342 conformance vectors
Multi-agent Delegated authority along a delegation chain §6a state blocks (FSM) + §6b delegated-authority invariants (INV-01~05)

Why ERDL?

Problem How ERDL solves it
LLM outputs are probabilistic — prompts are jailbreakable Rules evaluated outside the model; the safety boundary never lives in a prompt
A delegated sub-agent can exceed its authority Delegated-authority invariants (INV-01~05) — authority non-amplification, provenance continuity, narrow-only inheritance, transitive revocation — enforced by event-triggered state machines (§6a), proven by adversarial vectors (AV-01~14)
Rules drift across implementations 342 JCS + SHA-256 vectors enforce byte-for-byte consistency — verified by three independent implementations
Compliance needs audit trails Every evaluation produces a cryptographically verifiable hash
Business users can’t read code Three projection surfaces (Simple / Expression / Decision Table) compile to one semantic tree

30-second guardrail

npm install @openoba/erdl
# refund.erdl.yaml
protocol: "erdl/v2"
version: "2.2.0"
metadata:
  name: "refund-guard"
  decision: ALLOW
  category: coding
rules:
  - name: "SEC-001-refund-limit"
    description: "Refunds over 5000 require human approval"
    priority: 10
    when:
      logic: AND
      conditions:
        - field: "tool.name"
          operator: eq
          value: "issue_refund"
        - field: "tool.args.amount"
          operator: gt
          value: 5000
    then: REQUEST_HUMAN
    message: "Refund amount over 5000, human approval required"
import { loadErdlFile, Evaluator } from '@openoba/erdl'

// 1. Load rules from a YAML file
const { rules, metadata } = loadErdlFile('refund.erdl.yaml')

// 2. Evaluate against a fact object (inject the fallback decision from metadata)
const result = new Evaluator().evaluate(
  rules,
  { tool: { name: 'issue_refund', args: { amount: 8000 } } },
  { fallbackDecision: metadata.decision },
)
console.log(result.decision) // 'REQUEST_HUMAN'

Where it sits

One evaluate() call at your agent’s tool-call boundary — before the tool executes:

import { Evaluator } from '@openoba/erdl'

const result = new Evaluator().evaluate(rules, incomingToolCall, {
  fallbackDecision: 'DENY',
})

if (result.decision !== 'ALLOW') {
  haltForReview(result) // your handler: block the call, keep the audit trail
}

If your agent runs Node, ERDL can guard it. Typical integration points: Claude Code hooks, Codex / Cursor harnesses, MCP servers, A2A agents, custom executors.

The package exposes the document loader (loadErdlFile / parseErdlDocument), the evaluation engine, the 34-node expression-tree kernel, rule validation, YAML serialization, and the template engine. See the specification for the format, and API.md for the full API reference.

We attack ourselves

The multi-agent security model is proven under attack by fourteen adversarial vectors (AV-01 ~ AV-14, SPEC §6b):

Attack Vector class
Sub-agent grants itself more authority than its delegator Direct / transitive / aggregation amplification
Privileges laundered through chains of delegation Privilege laundering
Acting on a grant that was already revoked Revoked-ancestor, stale revocation
Replaying an earlier authorization Sequence replay

All 14 blocked. Every invariant held.

Verified Conformance

ERDL’s semantics are pinned by a cross-implementation vector set (see erdl-vectors). Independent, spec-only runners recompute every vector with self-built JCS — no reference code, no answer file.

Layer Vectors Status
Decision Hash (DO v1.5) 78 ✅ Node.js (reference) · ✅ Go (norviq-go) · ✅ Python (concordia-python)
Expression Projection (V-ENGINE) 240 ✅ Node.js (reference) · ✅ Python (concordia-python-expression)
Resolution (V-RESOLVE) 13 ✅ Node.js (reference) · ✅ Ravindra Annam (spec-only runner)
Signature (V-SIGN) 5 generated (reference self-verified)
Time-anchoring (TSA) 3 generated (reference self-verified)
decision_divergence 3 re-derivation

Formal Verification

Vectors prove the cases you sampled. erdl-formal proves the rest — it compiles the ERDL expression kernel into SMT (Z3) and verifies, over all inputs, that a rule never errors, never fails open, never misses a block. Full 34-node / E1–E12 coverage, with counterexamples you can replay against this reference engine.

Stateful rules (§6a state blocks & transitions)

Beyond stateless when → then rules, ERDL supports a single-instance finite state machine (§6a): two optional top-level fields — state (the state space) and transitions (the deterministic, event-triggered transition function). State is held by the engine outside the expression-tree kernel and read read-only via the state.<name> namespace; transition guards read state.* + event.* only. Each committed transition is appended to a serially-anchored audit chain (genesis → transition / transition_error), and evaluation records an on-demand state_snapshot ({ values, state_version, transitions_head }) into the result. This is the primitive that the organization layer builds multi-agent delegated-authority governance on (SPEC §6b, INV-01~05).

state:
  - name: authorization
    values: [authorized, revoked]
    initial: revoked
transitions:
  - on: authorize
    audit_as: DELEGATE
    set: { authorization: authorized }
  - on: revoke
    audit_as: DELEGATE
    set: { authorization: revoked }
import { StateMachine, Evaluator } from '@openoba/erdl'

const sm = new StateMachine(stateDecls, transitions, docTreeHash)
sm.injectEvent({ event_id: 'e1', on: 'authorize', actor: 'root-P' })

const result = new Evaluator().evaluate(rules, fact, { stateMachine: sm })
result.stateSnapshot // { values: { authorization: 'authorized' }, state_version: 1, transitions_head }

Multi-agent governance (delegated authority)

Single-agent guardrails stop at “this agent, this decision.” Multi-agent systems add a harder question: when Agent A delegates to Agent B, whose authority chain led to B’s action, and where did it violate policy? ERDL answers it with the delegated-authority security model (SPEC §6b):

The delegated-authority security invariants (INV-01–INV-05) and associated adversarial conformance vectors (AV-01–AV-14) were proposed by Ravindra Annam and subsequently refined and developed through technical review and collaboration with OpenOBA. They live in the rulsynor-multi-agent repository — the organization layer that consumes ERDL primitives. ERDL supplies the deterministic expression decision + the state-machine primitive; the organization layer derives effective authority across hops; the expression layer remains the sole decision authority (SPEC §6b, DESIGN §8a).

# One instance of the authorization FSM per delegation relationship (SPEC §6a.1 layering)
state:
  - name: authorization
    values: [authorized, revoked]
    initial: revoked
transitions:
  - on: authorize
    audit_as: DELEGATE
    reason: authorize
    set: { authorization: authorized }
  - on: revoke
    audit_as: DELEGATE
    reason: revoke
    set: { authorization: revoked }

Ecosystem

Piece What it is
@openoba/erdl (this repo) Reference engine — loader, evaluator, 34-node kernel, §6a state machine
erdl-vectors 342 conformance vectors, recomputed by independent spec-only runners
erdl-formal SMT (Z3) formal verification of the expression kernel — all inputs, not just samples
rulsynor-multi-agent The organization layer that consumes ERDL primitives for delegated authority
A2A Discussion #2031 ERDL proposed as an Agent Cards extension — behavioral rules for agent discovery

For the skeptics

“Deterministic” is a claim; here is the construction:

Specification

Community

Repository Structure

.
├── README.md                 # English README (this file)
├── README.zh-CN.md           # Chinese README
├── erdl-language-spec-v2.3.md              # 中文规范(权威)
├── erdl-language-spec-v2.3.en.md           # English specification
├── API.md                    # API reference
├── CHANGELOG.md              # release history (Keep a Changelog)
├── CHANGELOG.zh-CN.md        # release history (Keep a Changelog)
├── CONTRIBUTING.md           # contribution guide
├── CODE_OF_CONDUCT.md        # code of conduct
├── SECURITY.md               # security policy
├── DEVELOPMENT.md            # development tooling + roadmap
├── LICENSE                   # MIT
├── NOTICE.md                 # trademark notice
├── package.json / tsconfig.json / vitest.config.ts
└── src/
    ├── index.ts              # public API entry
    ├── erdl-loader.ts        # YAML document loader (parseErdlDocument / loadErdlFile)
    ├── evaluator.ts          # evaluation engine
    ├── erdl-schema.ts        # single source of truth (decisions / operators / categories)
    ├── rule-definition.ts    # core type definitions
    ├── rule-validator.ts     # rule validation
    ├── rule-yaml-serializer.ts  # RuleDefinition → §2.1 YAML
    ├── rule-quality-gate.ts  # load-time quality gates
    ├── template-engine.ts    # template engine
    ├── field-contracts.ts    # field contracts + display_name
    ├── fn-registry.ts        # function delegation registry
    ├── guard-state-manager.ts  # stateful operator (within/rate) state
    ├── state-definition.ts   # §6a state/transitions types + load-time validation
    ├── state-machine.ts      # §6a runtime FSM (event injection / audit chain / state_snapshot)
    ├── evaluation-object.ts  # language-layer evaluation-result DO serialization + hash
    ├── safe-regex.ts         # ReDoS-safe regex
    ├── clock.ts / date-utils.ts  # time + date utilities
    └── expr-tree/            # the 34-node expression-tree kernel
        ├── node-types.ts     # ExprNode + 34 node types
        ├── evaluator.ts      # tree evaluator (E1–E12)
        ├── gloss.ts          # natural-language projection (gloss)
        ├── s-expression.ts   # S-expression serialization
        ├── simple-compiler.ts  # Simple 30-operator compilation
        ├── rule-to-expr.ts   # when → tree compilation
        ├── canonical.ts       # canonical form
        ├── fixed-point.ts     # fixed-point rational arithmetic
        ├── limits.ts          # resource limits (E4)
        ├── normalize.ts       # NFC normalization
        ├── grade.ts           # rule grading (A/B/C)
        ├── decision-table.ts # decision-table compilation
        ├── eval-trace.ts / eval-warning.ts  # evaluation trace + warnings
        └── *.spec.ts         # test suites

Acknowledgments

License

MIT © 2026 深圳市秒镜科技有限公司 (Shenzhen Miaojing Technology Co., Ltd.)

Trademark: ERDL™ is a trademark of 深圳市秒镜科技有限公司. The MIT License covers copyright only and grants no trademark rights. See NOTICE.md.