Pact

Pact Specification

Version: 0.1.0-draft


Overview

A pact is a data structure representing a commitment between parties, with defined terms, stakes, and a designated resolution mechanism.

This document defines the minimal required schema and optional extensions.


Schema

Core Structure

{
  "pact": {
    "version": "0.1",
    "id": "string",

    "parties": [
      {
        "id": "string",
        "role": "string"
      }
    ],

    "terms": {
      "description": "string",
      "acceptance_criteria": [
        "string"
      ],
      "context": "string",
      "attachments": [
        {
          "hash": "string",
          "uri": "string",
          "type": "string"
        }
      ],
      "deadline": "timestamp"
    },

    "stakes": {
      "type": "string",
      "details": {}
    },

    "resolver": {
      "type": "string",
      "endpoint": "string",
      "config": {}
    },

    "state": "proposed | active | disputed | resolved",

    "evidence": [
      {
        "party": "string",
        "hash": "string",
        "uri": "string",
        "submitted_at": "timestamp"
      }
    ],

    "resolution": {
      "outcome": "fulfilled | breached | partial | void",
      "reasoning": "string",
      "resolved_by": "string",
      "resolved_at": "timestamp"
    },

    "metadata": {
      "created_at": "timestamp",
      "updated_at": "timestamp",
      "chain": "string",
      "contract_address": "string"
    }
  }
}

Terms

The terms object is the heart of a pact. It must balance human readability with machine evaluability.

Acceptance Criteria

Inspired by software acceptance criteria, these are discrete conditions a resolver checks. They should be:

Good criteria:

{
  "acceptance_criteria": [
    "Delivers 3 distinct logo concepts in PNG format",
    "Source files provided (AI, PSD, or Figma)",
    "Final delivery within 7 days of project start"
  ]
}

Bad criteria:

{
  "acceptance_criteria": [
    "Does good work",
    "Client is happy",
    "Professional quality"
  ]
}

Context

Freeform information that helps interpret the criteria but isn't directly evaluated. This is where background, preferences, and nuance live.

{
  "context": "This is for a climate tech podcast called \"Carbon Copy.\" Style preference: minimal, geometric, modern. Primary colors: greens and blues. See attached mood board for reference."
}

Attachments

References to external materials. Store hashes for integrity verification.

{
  "attachments": [
    {
      "hash": "sha256:a1b2c3...",
      "uri": "ipfs://Qm...",
      "type": "image"
    }
  ]
}

Stakes

What's at risk if the pact is breached or fulfilled.

Escrow

{
  "stakes": {
    "type": "escrow",
    "details": {
      "amount": "500",
      "currency": "USDC",
      "contract": "0x...",
      "release_on": "fulfilled",
      "return_on": "breached"
    }
  }
}

Reputation

{
  "stakes": {
    "type": "reputation",
    "details": {
      "system": "pact-reputation-v1",
      "weight": 1.0
    }
  }
}

Access

{
  "stakes": {
    "type": "access",
    "details": {
      "resource": "premium-content-xyz",
      "grant_on": "fulfilled",
      "revoke_on": "breached"
    }
  }
}

Composite

Stakes can be combined:

{
  "stakes": {
    "type": "composite",
    "details": [
      {
        "type": "escrow",
        "details": { "amount": "500", "currency": "USDC" }
      },
      {
        "type": "reputation",
        "details": { "system": "pact-reputation-v1", "weight": 1.0 }
      }
    ]
  }
}

Resolvers

A resolver is any mechanism that can evaluate a pact and return an outcome.

Resolver Interface

Resolvers must accept a pact and evidence, and return a resolution:

resolve(pact, evidence) → resolution

Where resolution contains:

Resolver Types

AI Resolver

{
  "resolver": {
    "type": "ai",
    "endpoint": "https://resolver.example.com/evaluate",
    "config": {
      "model": "claude-3",
      "temperature": 0
    }
  }
}

Human Resolver

{
  "resolver": {
    "type": "human",
    "endpoint": "https://arbitration.example.com/cases",
    "config": {
      "arbitrators": 3,
      "majority_required": true
    }
  }
}

DAO Resolver

{
  "resolver": {
    "type": "dao",
    "config": {
      "contract": "0x...",
      "quorum": 0.1,
      "voting_period": "72h"
    }
  }
}

State Machine

proposed → active → resolved
              ↓
          disputed → resolved

On-Chain Considerations

For on-chain implementations:

  1. Commit hash on-chain — Store a hash of the full pact terms, keeping full content off-chain or encrypted
  2. Minimal on-chain state — Only id, parties, stakes, resolver, state, resolution
  3. Events — Emit events for state transitions
  4. Resolver integration — Resolver can be a contract address with a standard interface

Example Solidity interface:

interface IPact {
    function propose(bytes32 termsHash, address[] parties, address resolver) external returns (uint256 pactId);
    function activate(uint256 pactId) external;
    function dispute(uint256 pactId, bytes evidence) external;
    function resolve(uint256 pactId, Outcome outcome, string reasoning) external; // resolver only
}

enum Outcome { Fulfilled, Breached, Partial, Void }

Extensions

The core schema is intentionally minimal. Extensions can add:


Versioning

Pact specs follow semantic versioning. Breaking changes increment the major version.

Current: 0.1.0-draft