{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://aigentsy.com/specs/adapter-contract.schema.json",
  "title": "AiGentsy AdapterContract",
  "description": "Declarative AdapterContract for AiGentsy v0. AdapterContract types, validates, versions, and allow-lists adapter-produced signals. AcceptancePolicy is where the user/counterparty defines whether those validated signals add up to acceptable work. AiGentsy enforces the user's policy deterministically against type-validated inputs; it does not decide what counts as good work.",
  "type": "object",
  "required": [
    "adapter_contract_version",
    "adapter_id",
    "adapter_version",
    "input_schema_version",
    "input_schema_hash",
    "output_fields",
    "allowed_policy_fields",
    "validator_name",
    "validator_version",
    "contract_hash"
  ],
  "additionalProperties": true,
  "properties": {
    "adapter_contract_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Semver of the AdapterContract schema. Currently 1.0.0."
    },
    "adapter_id": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_][a-z0-9_]*)+$",
      "description": "Reverse-DNS style identifier — e.g. aigentsy.settlement_native_mcp.starter or your.org.your_adapter."
    },
    "adapter_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Semver of THIS adapter contract release."
    },
    "input_schema_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Semver of the input schema this contract consumes."
    },
    "input_schema_hash": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$",
      "description": "sha256 over canonical-JSON of the schema declaration. Recomputable from {input_schema_version, sorted(output_fields), validator_name, validator_version}."
    },
    "output_fields": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "pattern": "^[a-z][a-z0-9_]*$"
      },
      "minItems": 1,
      "uniqueItems": true,
      "description": "Fields the adapter promises to emit. snake_case, alphanumeric_."
    },
    "allowed_policy_fields": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "pattern": "^[a-z][a-z0-9_]*$"
      },
      "uniqueItems": true,
      "description": "Subset of output_fields that may enter AcceptancePolicy context. Must be a subset of the runtime's accepted policy field allow-list to be enforceable; the lint tool checks this."
    },
    "validator_name": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[a-z][a-z0-9_]*$",
      "description": "Name of the runtime validator registered for this contract. Unknown validators are still loaded (contract registered) but evaluate_adapter routes to require_review (fail-closed)."
    },
    "validator_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Semver of the validator implementation expected."
    },
    "contract_hash": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$",
      "description": "sha256 over canonical-JSON of the entire contract declaration. Recomputable offline; the lint tool verifies."
    },
    "status": {
      "type": "string",
      "enum": ["active", "deprecated", "revoked"],
      "description": "Lifecycle status. OPTIONAL. Absence is treated as 'active'. Lifecycle metadata is for developer discovery and adoption only — it does NOT enter the canonical contract_hash key set, and aigentsy-verify ignores it at replay time (artifacts replay forever from embedded declarations). 'deprecated' contracts are still listable and still replayable in historical bundles. 'revoked' contracts are listable for transparency but evaluate_adapter routes new evaluations to unknown_adapter (fail-closed)."
    },
    "supersedes": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_][a-z0-9_]*)+@[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Optional pointer to the prior (adapter_id, adapter_version) this release supersedes. Format: 'adapter_id@semver'. Outside canonical hash key set."
    },
    "replaced_by": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9_]*(\\.[a-z0-9_][a-z0-9_]*)+@[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Optional pointer to the (adapter_id, adapter_version) that replaces this one. Set together with status='deprecated' or 'revoked'. Outside canonical hash key set."
    },
    "published_at": {
      "type": "string",
      "format": "date-time",
      "description": "Optional ISO-8601 timestamp recording when this contract was published. Outside canonical hash key set."
    },
    "min_verifier_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Optional minimum aigentsy-verify version required to fully understand any future fields this contract may use. Outside canonical hash key set. Older verifiers MAY still replay the existing hash + allow-list invariants; they MUST NOT auto-accept beyond what they can verify."
    },
    "distribution_channel": {
      "type": "string",
      "enum": ["aigentsy.builtin", "aigentsy.examples", "developer.local", "third_party"],
      "description": "Optional provenance label. Outside canonical hash key set. Discovery surfaces may filter by channel."
    }
  }
}
