Policy Language

Bundles and rules

A bundle is a header plus an unordered set of rules. A rule is a guard, an effect, and reviewable metadata.

The bundle header pins the policy identity, the version, the schema the bundle is type-checked against, and the semantic mode. Everything after the header is rules. Because rule order is meaningless, a bundle diff is a set diff: rules added, rules removed, rules changed. Review tools, the analyzer, and governance all operate on that set structure.

Rules carry signed artifact metadata: a stable rule identifier, a title, an optional control reference into the institution's control framework, an owner, and a review-by date. Audit answers such as “which rules implement control CTRL-PAY-004 and when were they last reviewed” are computed from the artifact itself.

Rule anatomy

Three kinds. forbid denies, permit admits, require attaches obligations while preserving the verdict.

A complete rule
dpl
permit rule treasury-large-transfers
  title    "Treasury: large transfers under dual control"
  control  "CTRL-PAY-004"
  owner    treasury.desk-head
  review-by 2027-01-31

  when operation == Sign
   and payload is PlainTransfer
   and asset == USDC
   and amount > USDC 10_000
   and destination in set treasury_counterparties

  require approval 2 of group treasury_officers within 4h
          where approver != requester
  require approval 1 of group risk_office within 4h
  require meter tenant_daily_notional
          add notional_usd(amount) limit USD 5_000_000 per 24h

Clause discipline

The verifier enforces which clauses each rule kind may carry.

  • forbid: when, optional unless, mandatory reason; produces a reasoned DENY.
  • permit: when, optional unless, optional require block; admits matching operations and attaches permit-local obligations.
  • require: when, optional unless, mandatory require block; attaches obligations under property P4.

Authoring frontends

The canonical artifact is the typed AST. The .dpl text form and the console rule builder are two frontends producing the same AST; compiling either yields the same package root. Text serves review workflows and version control; the builder serves operators. Both feed the same compiler path.