中文 English Last updated: 2026-10-07 — positioned for the multi-agent era
🚀 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 → thenrules, 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.
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.
| 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) |
| 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 |
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'
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.
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.
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 |
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.
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 }
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):
INV-01 ~ INV-05) bound effective authority across a delegation chain —
authority non-amplification, provenance continuity, narrow-only constraint inheritance,
transitive revocation, and capability-boundary non-amplification.AV-01 ~ AV-14) prove the invariants hold under attack —
direct/transitive/aggregation amplification, privilege laundering, revoked-ancestor,
sequence replay, and stale revocation.state/transitions
express the authorization state and its event-triggered, audit-anchored transitions.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 }
| 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 |
“Deterministic” is a claim; here is the construction:
.
├── 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
concordia-python-expression), a spec-and-contract-only Python implementation that byte-verified all 240 V-ENGINE expression-layer vectors; its RESULTS.md recorded 16 spec ambiguities (A1–A16), four of which exposed real gaps now fixed.within/rate). His review of the evaluator surfaced the temporal_state evidence gap on state mutation and the total_evaluated count drift — each now fixed and covered by conformance vectors. The delegated-authority security invariants (INV-01–INV-05) and associated adversarial conformance vectors (AV-01–AV-14) were proposed by him and subsequently refined and developed through technical review and collaboration with OpenOBA, now underpinning OpenOBA’s multi-agent governance direction. He also contributed an independent Python runner (ravindra-annam-python-independent, a Python 3 stdlib spec-only expression-tree evaluator) for the delegated-authority conformance set, verifying AV-01~AV-14 (14/14). He also authored the first independent §7.1 resolution runner (PR #5): 13 neutral V-RESOLVE vectors (R01–R13) + a spec-only runner, whose derivation surfaced and resolved the tightening-direction boundary (R08/R13), now made explicit in §7.1 item 5.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.