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.

Gem Version License: MIT


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 ─────────────────────────────────
    permission :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.0fosm-rails integration: 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