{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://3rdpersona.com/spec/capture.schema.json",
  "title": "3p.capture/1",
  "description": "A person's capture: the acts that happened at the moment of capture (typed, voice, photo, import, relayed) and the facts that cite them. What a 3P node exports and what another tool, such as the Zharfex mirror or a capture app, may hand a node. Never carries the declared-vs-lived delta.",
  "type": "object",
  "additionalProperties": false,
  "required": ["format", "exported_at", "acts", "facts"],
  "properties": {
    "format": {"const": "3p.capture/1"},
    "exported_at": {"$ref": "#/$defs/instant"},
    "acts": {"type": "array", "items": {"$ref": "#/$defs/act"}},
    "facts": {"type": "array", "items": {"$ref": "#/$defs/fact"}}
  },
  "$defs": {
    "instant": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"},
    "day": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
    "sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
    "act": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "kind", "captured_at", "device", "content_sha256"],
      "properties": {
        "id": {"type": "string", "pattern": "^act:[0-9a-zA-Z_.-]{8,64}$"},
        "kind": {"enum": ["typed", "voice", "photo", "import", "relayed", "unrecorded"]},
        "captured_at": {"$ref": "#/$defs/instant"},
        "device": {"type": "string", "minLength": 1, "maxLength": 200},
        "content_sha256": {"$ref": "#/$defs/sha256"},
        "media": {
          "type": "object", "additionalProperties": false, "required": ["sha256", "mime"],
          "properties": {"sha256": {"$ref": "#/$defs/sha256"}, "mime": {"type": "string", "minLength": 3},
                         "bytes": {"type": "integer", "minimum": 0}}
        },
        "transcript": {
          "type": "object", "additionalProperties": false, "required": ["engine", "text"],
          "properties": {"engine": {"type": "string", "minLength": 1}, "locale": {"type": ["string", "null"]},
                         "text": {"type": "string"}}
        },
        "source": {
          "type": "object", "additionalProperties": false, "required": ["system", "ref"],
          "properties": {"system": {"type": "string", "minLength": 1}, "ref": {"type": "string", "minLength": 1}}
        },
        "relayed_by": {"type": "string", "minLength": 1}
      }
    },
    "fact": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "text", "occurred", "recorded", "entry_mode", "act", "share_tier"],
      "properties": {
        "id": {"type": "string", "pattern": "^fact:[0-9a-zA-Z_.:-]{1,64}$"},
        "text": {"type": "string", "minLength": 1, "maxLength": 20000},
        "occurred": {"$ref": "#/$defs/day"},
        "recorded": {"$ref": "#/$defs/instant"},
        "entry_mode": {"enum": ["live", "backfill", "seed"]},
        "act": {"type": "string", "pattern": "^act:"},
        "share_tier": {"enum": ["private", "trusted", "mutual", "public"]},
        "tags": {"type": "array", "items": {"type": "string", "pattern": "^[a-z0-9_-]+$"}},
        "revised": {"$ref": "#/$defs/instant"}
      }
    }
  }
}
