MandateClaw-DSL
The Employment Contract Between You and Your Agent.
MandateClaw-DSL is a Ruby gem for defining programmatic, human-readable contracts that govern what an AI agent is — and is not — allowed to do on behalf of a human or organisation.
It gives your agent a signed scope. Not a system prompt. A contract.
The Problem
Every serious deployment of an AI agent in a consequential workflow — financial, legal, medical, regulatory — hits the same wall:
- System prompts are unenforceable. The model may ignore them.
- Tool allowlists are opaque. They are deployer-side, invisible to counterparties and regulators.
- Audit logs are held by the deployer. Exactly the wrong party.
- Smart contracts are unreadable to the lawyers and compliance officers who need to sign off.
What is missing is a layer that is:
- Signed before work begins
- Deterministic in what it permits
- Readable by humans
- Enforceable at runtime
- Auditable by regulators
That is MandateClaw.
Installation
# Gemfile
gem "mandateclaw-dsl"
bundle install
Or install directly:
gem install mandateclaw-dsl
Quick Start
require "mandate_claw"
class InvoiceContract < MandateClaw::DSL::Contract
contract :invoice do
# ── Parties ──────────────────────────────────────────────────────────
party :buyer, identifies_by: :customer_id
party :seller, identifies_by: :merchant_id
party :ai_agent, identifies_by: :agent_did, kind: :autonomous
# ── Obligations: what a party MUST do ────────────────────────────────
obligation :pay_invoice,
on: :buyer,
within: 30.days,
breach: :late_payment_penalty
# ── Permissions: what a party MAY do ─────────────────────────────────
:dispute,
on: :buyer,
within: 7.days,
event: :raise_dispute
# ── Prohibitions: what a party MUST NOT do ───────────────────────────
prohibition :unilateral_amend,
on: :ai_agent,
breach: :void_transition
# ── Agent capability envelope ─────────────────────────────────────────
agent_bounds :ai_agent do
may :issue_invoice, :send_reminder
must_not :modify_amount, :waive_penalty
must_log_to :contract_registry
end
# ── Decision rules (ternary: true / false / :unknown) ─────────────────
rule :payment_overdue do
decide :overdue,
when: ->(ctx) { ctx.days_since_issued > 30 },
unknown_when: ->(ctx) { ctx.issued_at.nil? }
end
# ── Attestation: who must sign before the contract is in force ────────
attestation do
require_signature_from :buyer, :seller, :ai_agent
sign_with :ed25519
end
end
end
Validate the contract definition
InvoiceContract.validate!
# => true (raises MandateClaw::ValidationError if malformed)
Render as human-readable Markdown
puts InvoiceContract.to_markdown
Output:
# Contract: Invoice
> Generated by MandateClaw-DSL v0.0.1
## Parties
| Name | Kind | Identified By |
|----------|--------------|---------------|
| buyer | Human | customer_id |
| seller | Human | merchant_id |
| ai_agent | Autonomous | agent_did |
## Obligations
- **Buyer** MUST `pay_invoice` within **30 days**. Breach: `late_payment_penalty`.
## Permissions
- **Buyer** MAY `dispute` within **7 days**.
## Prohibitions
- **Ai_agent** MUST NOT `unilateral_amend`. Breach: `void_transition`.
## Agent Capability Bounds
### Agent: `ai_agent`
- **May do:** `issue_invoice`, `send_reminder`
- **Must not do:** `modify_amount`, `waive_penalty`
- **Must log to:** `contract_registry`
## Attestation
This contract comes into force only when all required parties have signed.
**Required signatories:**
- `buyer`
- `seller`
- `ai_agent`
**Signing algorithm:** `ed25519`
Core Concepts
Parties
party :buyer, identifies_by: :customer_id # human (default)
party :seller, identifies_by: :merchant_id, kind: :organisation
party :ai_agent, identifies_by: :agent_did, kind: :autonomous
Party kinds: :human, :organisation, :autonomous.
Obligations, Permissions, Prohibitions
The three deontic modalities of contract law:
| DSL method | Meaning | Breach on failure? |
|---|---|---|
obligation |
Party MUST do this | Yes |
permission |
Party MAY do this | No |
prohibition |
Party MUST NOT do this | Yes (on attempt) |
Agent Bounds
The agent_bounds block is the contract clause that directly constrains an autonomous agent. The agent is given a capability envelope it cannot exceed:
agent_bounds :ai_agent do
may :read_invoice, :send_reminder # explicit allowlist
must_not :delete_invoice, :modify_amount # explicit denylist
must_log_to :contract_registry # mandatory audit targets
end
Decision Rules (Ternary Truth)
Borrowed from SMU's L4 language: a rule evaluates to true, false, or :unknown — never silently collapses an unknown value to false:
rule :payment_overdue do
decide :overdue,
when: ->(ctx) { ctx.days_since_issued > 30 },
unknown_when: ->(ctx) { ctx.issued_at.nil? }
end
result = InvoiceContract._rules.first.evaluate(my_context)
# => true | false | :unknown
Inline Definition
PaymentContract = MandateClaw.define(:payment) do
party :payer, identifies_by: :user_id
party :payee, identifies_by: :merchant_id
obligation :transfer_funds, on: :payer, within: 1.day, breach: :payment_failed
end
Architecture
MandateClaw is intentionally split into focused components:
| Gem | Role | License |
|---|---|---|
| mandateclaw-dsl (this gem) | Contract definition DSL + Markdown renderer | MIT |
| mandateclaw-registry | Signing, storage, audit ledger | FSL-1.1-Apache-2.0 |
| MandateClaw Cloud | Hosted registry, regulator webhooks, compliance dashboards | Commercial |
The DSL has no runtime enforcement — that is the registry's job. The DSL's output is a validated, human-readable contract definition that the registry stores, signs, and monitors.
Roadmap
- [x]
0.0.1— Core DSL: parties, obligations, permissions, prohibitions, agent bounds, attestation, decision rules, Markdown renderer - [ ]
0.1.0—fosm-railsintegration: lifecycle events validated against contract definitions - [ ]
0.2.0— JSON Schema renderer for machine-readable contract exchange - [ ]
0.3.0— Contract diffing: show what changed between two versions of a contract
Contributing
Bug reports and pull requests are welcome at github.com/parolkar/MandateClaw-DSL.
Please read CONTRIBUTING.md before opening a PR. All contributions are expected to have specs.
License
MIT — Copyright (c) 2026 Abhishek Parolkar