{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://pcp-protocol.github.io/pcp/schemas/0.3/memory.page.schema.json",
  "title": "PCP memory page frontmatter",
  "description": "The YAML frontmatter of a memory page (SPEC §5.2), validated as the JSON data model of YAML 1.2's core schema (timestamps are strings). Keys marked server-stamped are set by the server on write and kept as they are on import (SPEC §5.2.3).",
  "allOf": [
    {
      "$ref": "#/$defs/page_keys"
    }
  ],
  "required": [
    "title",
    "updated"
  ],
  "$defs": {
    "page_keys": {
      "type": "object",
      "description": "Every frontmatter key, with none required. Tool inputs reuse this (SPEC §6.2).",
      "properties": {
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "updated": {
          "$ref": "#/$defs/utc_datetime",
          "description": "Server-stamped. When the page last changed. Kept as is on import."
        },
        "id": {
          "type": "string",
          "description": "Server-stamped, optional. An opaque id, unique in the context and stable when the page is moved.",
          "pattern": "^[A-Za-z0-9._:-]{1,128}$"
        },
        "type": {
          "enum": [
            "episodic",
            "semantic",
            "procedural"
          ]
        },
        "tags": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        "sensitivity": {
          "description": "Authoritative. Absent means normal, except under style/ where the server stores sensitive unless the write says normal (SPEC §5.7).",
          "enum": [
            "normal",
            "sensitive"
          ]
        },
        "lifecycle": {
          "enum": [
            "active",
            "validated",
            "stale",
            "archived"
          ]
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "How sure the context is that the content is true."
        },
        "importance": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "Salience for retrieval and retention. Not confidence."
        },
        "valid_from": {
          "$ref": "#/$defs/date_or_datetime"
        },
        "valid_until": {
          "$ref": "#/$defs/date_or_datetime"
        },
        "recorded_at": {
          "$ref": "#/$defs/utc_datetime",
          "description": "Server-stamped. Transaction time: when the context first recorded this page. Never changes afterwards; kept on import."
        },
        "expires": {
          "$ref": "#/$defs/utc_datetime",
          "description": "Retention. After this instant the page is not returned and SHOULD be deleted. Distinct from valid_until."
        },
        "partition": {
          "$ref": "#/$defs/partition_name",
          "description": "The partition holding the page. Absent means \"default\"."
        },
        "source": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "origin": {
              "enum": [
                "chat",
                "agent",
                "connector",
                "import",
                "user",
                "consolidation"
              ]
            },
            "basis": {
              "description": "provided: the person or team stated it. observed: recorded from activity. inferred: derived by a model or rule.",
              "enum": [
                "provided",
                "observed",
                "inferred"
              ]
            },
            "principal": {
              "$ref": "#/$defs/principal",
              "description": "Server-stamped. The principal whose token created the page."
            },
            "on_behalf_of": {
              "$ref": "#/$defs/principal",
              "description": "Server-stamped. The human principal an agent acted for, when delegated (SPEC §7.4)."
            },
            "client": {
              "type": "string",
              "maxLength": 512,
              "description": "Server-stamped. The client that wrote the page (OAuth client_id or client name)."
            },
            "session": {
              "type": "string",
              "maxLength": 256
            },
            "at": {
              "$ref": "#/$defs/date_or_datetime"
            }
          }
        },
        "derived_from": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/path"
          }
        },
        "relations": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "rel",
              "target"
            ],
            "additionalProperties": false,
            "properties": {
              "rel": {
                "description": "A core relation, or a namespaced one (<prefix>:<name>) kept for lossless imports.",
                "anyOf": [
                  {
                    "enum": [
                      "supersedes",
                      "contradicts",
                      "refines",
                      "about"
                    ]
                  },
                  {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9-]*:[a-z][a-z0-9_-]*$"
                  }
                ]
              },
              "target": {
                "$ref": "#/$defs/path"
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            }
          }
        },
        "review": {
          "type": "object",
          "description": "Review state (SPEC §5.4). Absent means approved.",
          "required": [
            "state"
          ],
          "additionalProperties": false,
          "properties": {
            "state": {
              "enum": [
                "proposed",
                "approved",
                "rejected"
              ]
            },
            "generated": {
              "$ref": "#/$defs/actor_at",
              "description": "Server-stamped. Who produced the content under review, and when (OKF generated)."
            },
            "verified": {
              "type": "array",
              "description": "Server-stamped. Each approval (OKF verified).",
              "items": {
                "$ref": "#/$defs/actor_at"
              }
            },
            "rejected": {
              "$ref": "#/$defs/actor_at",
              "description": "Server-stamped. The rejection, when state is rejected."
            }
          },
          "allOf": [
            {
              "if": {
                "properties": {
                  "state": {
                    "const": "rejected"
                  }
                }
              },
              "then": {
                "required": [
                  "rejected"
                ]
              }
            }
          ]
        },
        "x_import": {
          "type": "object",
          "description": "Set by an importer in import mode (SPEC §8.7.3). Records where the page came from and keeps, once, every source value PCP has no key for. Restore never adds it. Kept on later exports and imports.",
          "additionalProperties": false,
          "required": [
            "format",
            "at"
          ],
          "properties": {
            "format": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9-]{0,49}$",
              "description": "pcp, or a foreign format named in docs/interop.md (agent-brain, basic-memory, mem0, supermemory, omp, remnic, dti-conversation)."
            },
            "at": {
              "$ref": "#/$defs/utc_datetime",
              "description": "When the import ran."
            },
            "exporter": {
              "type": "string",
              "maxLength": 100,
              "description": "exporter.name from the archive manifest, or the source tool."
            },
            "context": {
              "type": "string",
              "maxLength": 512,
              "description": "The source context: its discovery URL or handle, when known."
            },
            "id": {
              "type": "string",
              "maxLength": 256,
              "description": "The item's id in the source."
            },
            "path": {
              "$ref": "#/$defs/path",
              "description": "The page's path in the source, when the import renamed it or mapped it from another scheme."
            },
            "sha256": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$",
              "description": "SHA-256 of the source file or record as received. With the path, the idempotency key (SPEC §8.7.3)."
            },
            "recorded_at": {
              "$ref": "#/$defs/utc_datetime",
              "description": "recorded_at in the source, which import replaces with the import instant."
            },
            "source": {
              "type": "object",
              "description": "The source object as it was in the source context, with principal ids as they were there."
            },
            "review": {
              "type": "object",
              "description": "The review object as it was in the source context, when import reset it."
            },
            "partition": {
              "type": "string",
              "maxLength": 64,
              "description": "The partition in the source context, when import mapped it to another."
            },
            "fields": {
              "type": "object",
              "description": "Source values with no PCP key, under their source names. Values that only restate a mapped key, and derived values (hashes, scores, embeddings), are not kept."
            }
          }
        }
      },
      "patternProperties": {
        "^x[_-][A-Za-z0-9_-]+$": {
          "description": "Implementation or import keys. Preserved on round trip; never interpreted by other servers."
        }
      },
      "additionalProperties": false
    },
    "utc_datetime": {
      "type": "string",
      "description": "RFC 3339 date-time in UTC, with a Z offset.",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?Z$"
    },
    "date_or_datetime": {
      "type": "string",
      "description": "RFC 3339 full-date or date-time with an offset.",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2}))?$"
    },
    "path": {
      "type": "string",
      "description": "A page path (SPEC §5.1): segments of [A-Za-z0-9._-] separated by /, no segment starting with a dot, 255 characters at most.",
      "maxLength": 255,
      "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]{0,63}(/[A-Za-z0-9_][A-Za-z0-9._-]{0,63})*$"
    },
    "partition_name": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
    },
    "principal": {
      "type": "string",
      "description": "A typed principal id (SPEC §1.3): human:, agent:, org: or service:, then a local id.",
      "pattern": "^(human|agent|org|service):[A-Za-z0-9._@+/-]{1,128}$"
    },
    "actor_at": {
      "type": "object",
      "required": [
        "by",
        "at"
      ],
      "additionalProperties": false,
      "properties": {
        "by": {
          "$ref": "#/$defs/principal"
        },
        "at": {
          "$ref": "#/$defs/utc_datetime"
        }
      }
    }
  }
}
