{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://pcp-protocol.github.io/pcp/schemas/0.3/export.context.schema.json",
  "title": "PCP context descriptor",
  "description": "context.json in a PCP archive (SPEC §8.2): the context's kind and controller, its principals, its partitions and their access lists. A personal context has one human principal, the default partition and an empty access list. Grants, tokens and credentials are never part of it.",
  "type": "object",
  "additionalProperties": false,
  "required": ["pcp_version", "kind", "controller", "principals", "partitions"],
  "properties": {
    "pcp_version": { "enum": ["0.3"] },
    "kind": { "enum": ["personal", "work", "team"] },
    "controller": { "$ref": "memory.page.schema.json#/$defs/principal" },
    "features": {
      "type": "array",
      "uniqueItems": true,
      "items": { "enum": ["partitions", "review", "delegation"] }
    },
    "principals": {
      "type": "array",
      "description": "Every principal of the context, and every former principal that any exported page, revision, audit entry or receipt names (status removed), so references resolve.",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "status"],
        "properties": {
          "id": { "$ref": "memory.page.schema.json#/$defs/principal" },
          "display_name": { "type": "string", "maxLength": 200 },
          "roles": {
            "type": "array",
            "description": "Server-defined role names (SPEC §1.3 rule 4), informative. Effective rights are in the partition access lists.",
            "uniqueItems": true,
            "items": { "type": "string", "pattern": "^[a-z][a-z0-9_-]{0,63}$" }
          },
          "status": { "enum": ["active", "suspended", "removed"] },
          "acts_for": {
            "type": "array",
            "description": "For agents with the delegation feature: the humans this agent may act for (SPEC §7.4).",
            "uniqueItems": true,
            "items": { "$ref": "memory.page.schema.json#/$defs/principal" }
          }
        }
      }
    },
    "partitions": {
      "type": "array",
      "description": "Every partition (SPEC §5.3), including default.",
      "minItems": 1,
      "contains": {
        "type": "object",
        "properties": { "name": { "const": "default" } },
        "required": ["name"]
      },
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "access"],
        "properties": {
          "name": { "$ref": "memory.page.schema.json#/$defs/partition_name" },
          "description": { "type": "string", "maxLength": 500 },
          "access": {
            "type": "array",
            "description": "The access list (SPEC §7.3). Empty in a context without the partitions feature, where every principal has read, propose and write on default.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["principal", "rights"],
              "properties": {
                "principal": { "$ref": "memory.page.schema.json#/$defs/principal" },
                "rights": {
                  "type": "array",
                  "minItems": 1,
                  "uniqueItems": true,
                  "items": { "enum": ["read", "propose", "write", "review"] }
                }
              }
            }
          }
        }
      }
    }
  },
  "patternProperties": {
    "^x[_-][A-Za-z0-9_-]+$": {
      "description": "Implementation keys, preserved on restore."
    }
  },
  "allOf": [
    {
      "description": "A personal context is controlled by the person and has no org principal (SPEC §9.2.1).",
      "if": { "properties": { "kind": { "const": "personal" } } },
      "then": {
        "properties": {
          "controller": { "pattern": "^human:" },
          "principals": { "items": { "properties": { "id": { "not": { "pattern": "^org:" } } } } }
        }
      }
    }
  ]
}
