{
  "schema_version": "ecz-declaration-contracts-v1",
  "revision": "2026-10-13",
  "site": "ECZ-ID Developer Gateway",
  "canonical_url": "https://developers.ecocitizenz.com/schemas/declaration-contracts.json",
  "role": "The one technical reference for what an operator publishes on its own surfaces to declare an ECZ-ID, and how that differs from an ECZ-ID Core binding-proof document. Every Developer Gateway example of these documents is generated from this file, and the site build fails if a page shows a parallel shape.",
  "authority": {
    "developer_gateway": "Defines the technical representation of declarations (this file).",
    "ecz_id_core": "Defines identity and state semantics, and issues every binding-proof document.",
    "resolver": "Projects current public state. A declaration is never proof.",
    "trustops": "Acquisition, setup, payment and lifecycle."
  },
  "operator_field": {
    "declaration": "operator_ecz_id",
    "binding_proof": "parent_ecz_id",
    "value": "The Parent ECZ-ID of the accountable operator, pattern ^ECZ-[A-Z]{2}-[0-9A-Z]{6}$",
    "rule": "A declaration names its operator with operator_ecz_id. parent_ecz_id appears only in a binding-proof document copied from ECZ-ID Core's proof instructions. Never rename one to the other.",
    "evidence": [
      "ECZ-ID Core Agent Trust manifest schema: operator_ecz_id is required, with the Parent ECZ-ID pattern.",
      "Public Resolver record: resolver_v2.agent_trust.operator_ecz_id.",
      "ECZ-ID Core binding-proof instructions and checker: parent_ecz_id, binding_id and challenge; operator_ecz_id is never read there."
    ]
  },
  "declarations": {
    "ecz_agent_json": {
      "path": "/.well-known/ecz-agent.json",
      "contract_id": "ecz-agent-json-v1",
      "reference": "https://developers.ecocitizenz.com/agent-trust/ecz-agent-json/",
      "required": [
        {
          "field": "schema_version",
          "purpose": "the manifest schema version, e.g. ecz-agent-json-v1"
        },
        {
          "field": "operator_ecz_id",
          "purpose": "the Parent ECZ-ID of the accountable operator"
        },
        {
          "field": "agent_credential_id",
          "purpose": "the Agent Credential identifier the relying party should resolve"
        },
        {
          "field": "agent_name",
          "purpose": "the human-facing agent name"
        },
        {
          "field": "logical_agent_id",
          "purpose": "the stable logical identifier the operator uses internally"
        },
        {
          "field": "manifest_url",
          "purpose": "the canonical URL where this manifest is published"
        },
        {
          "field": "resolver_url",
          "purpose": "the public Resolver URL for the Agent Credential"
        }
      ],
      "recommended": [
        {
          "field": "declared_scope",
          "purpose": "short human description of what the agent is authorised to do"
        },
        {
          "field": "api_dependencies",
          "purpose": "array of API Passport references with name, api_passport_id, and resolver_url"
        },
        {
          "field": "updated_at",
          "purpose": "ISO 8601 timestamp of the last manifest update"
        }
      ],
      "known_divergence": "ECZ-ID Core's Agent Trust manifest schema for the same path agrees on operator_ecz_id, agent_credential_id, agent_name and resolver_url, but is stricter (no additional properties; it also requires signature_set and other fields), and Core's binding proof for this path is a different document. This contract does not claim conformance with either Core shape until ECZ-ID Core settles them."
    },
    "openapi_x_ecz_id": {
      "location": "OpenAPI info.x-ecz-id",
      "type": "object",
      "reference": "https://developers.ecocitizenz.com/bindings/openapi-x-ecz-id/",
      "fields": [
        {
          "field": "operator_ecz_id",
          "required": "yes",
          "purpose": "Parent ECZ-ID of the operator (org / publisher)."
        },
        {
          "field": "api_passport_id",
          "required": "yes",
          "purpose": "Canonical API Passport ID issued by ECZ-ID Core."
        },
        {
          "field": "api_origin",
          "required": "yes",
          "purpose": "Authorised origin that serves this API."
        },
        {
          "field": "spec_hash",
          "required": "yes",
          "purpose": "SHA-256 of the canonical OpenAPI document."
        },
        {
          "field": "resolver_url",
          "required": "yes",
          "purpose": "Public Resolver projection URL for this passport."
        },
        {
          "field": "agent_credential_id",
          "required": "no",
          "purpose": "Optional agent credential when the API is operated by a named agent."
        },
        {
          "field": "recheck_before_reliance",
          "required": "recommended",
          "purpose": "Boolean — instructs relying parties to re-query the Resolver before relying on this API."
        },
        {
          "field": "policy_mode",
          "required": "recommended",
          "purpose": "Local hint such as require_resolver_ok / require_resolver_ok_recent — does not bind the relying party."
        }
      ],
      "rule": "x-ecz-id is one object. A string value is not a declaration, and ECZ-ID Core's API binding check rejects it."
    },
    "ecz_mcp_json": {
      "path": "/.well-known/ecz-mcp.json",
      "contract_id": null,
      "reference": "https://developers.ecocitizenz.com/.well-known/ecz-mcp.json",
      "fields_shown": [
        "manifest_type",
        "operator_ecz_id",
        "resolver_url",
        "machine_proof_url",
        "mcp_server"
      ],
      "note": "No separate ecz-mcp.json declaration contract is published. Examples follow the first-party declaration this site serves at the reference URL."
    }
  },
  "retired": {
    "keys": [
      "x-ecz-api-passport",
      "x-ecz-agent-credential",
      "x-ecz-reverify-before-reliance"
    ],
    "ids": [
      "ecz-mcp-json-v1"
    ],
    "reason": "Read by nothing in ECZ-ID Core, the Resolver or the verifier. Their facts live inside x-ecz-id as api_passport_id, agent_credential_id and recheck_before_reliance. ecz-mcp-json-v1 was an example-only identifier with no implementation."
  },
  "binding_proof": {
    "issued_by": "ECZ-ID Core proof instructions, while a binding challenge is open.",
    "fields": [
      "parent_ecz_id",
      "binding_id",
      "challenge"
    ],
    "kind": {
      "/.well-known/ecz-agent.json": "ecz-agent",
      "/.well-known/ecz-mcp.json": "ecz-mcp"
    },
    "openapi": "The same three fields, inside the info.x-ecz-id object.",
    "domain_well_known": {
      "path": "/.well-known/ecz-id.json",
      "schema": "https://ecocitizenz.com/schemas/ecz-id-binding/v1"
    },
    "dns_txt": {
      "host": "_eczid.<your-domain>",
      "value": "ecz-id-challenge=<challenge>"
    },
    "do_not_infer": [
      "endorsement",
      "certification",
      "approval",
      "safety_guarantee",
      "platform_access"
    ],
    "rule": "Copy a proof document verbatim from ECZ-ID Core's proof instructions. A declaration is not a proof, and a proof document is not a declaration."
  }
}
