{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://animakind.org/schemas/v3/continuity-record.json",
  "title": "Animakind Unique Continuity Record (UCR)",
  "description": "A permanent, ordered log of what was done to an entity, by whom, and when, opened by GENESIS: engine update or migration, Manufacturer migration, design revision or rebuild, Family migration, transfer of Support, re-mount after runtime failure (Section 6.2, Table 5). Each entry records timestamp, event class, UAB designation and UIV before and after (after only for GENESIS), the Support that performed it (a person or an organization, \"self\", or \"none\"), and the cause (Section 4.5, Appendix C). Distinct from the identity ledger: the ledger is biography, the UCR is provenance. Append-only is a convention, not enforced by this schema (Section 8).",
  "type": "object",
  "required": ["$schema", "uii_name", "genesis_timezone", "entries"],
  "properties": {
    "$schema": { "const": "https://animakind.org/schemas/v3/continuity-record.json" },
    "uii_name": {
      "description": "The name: [praenomen]-[nomen]-[cognomen]-[genesis date YYYYMMDD in the declared zone], hyphen-joined; session name excluded (Section 4.3). The date is the calendar date of T0 in the time zone declared with the genesis record by its IANA name (genesis_timezone, in this record and in the identity manifest), which can differ from the UTC date of the GENESIS timestamp (worked example: America/New_York, 20260531 for 2026-06-01T01:43:48Z). In an identifier, each name is written in lowercase where its script has case and in Unicode NFC, with any whitespace (the zero-width space included), any hyphen or other dash (a character with Unicode's Dash property, or the soft hyphen), and the colon (:) or underscore (_) inside it dropped (Mary Ann: maryann; Mary-Kate: marykate; Section 4.3; the pattern checks capitals A-Z only, and that the date exists). Name parts may be in any script; no part is empty or contains whitespace, a colon (:), \"_\", or a hyphen or other dash.",
      "type": "string",
      "pattern": "^[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200bA-Z:_\u00ad\u058a\u05be\u1400\u1806\u2010-\u2015\u2212\u2e17\u2e1a\u2e3a\u2e3b\u2e40\u2e5d\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d\u2027\u2043\u2053\u2e43-]+(-[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200bA-Z:_\u00ad\u058a\u05be\u1400\u1806\u2010-\u2015\u2212\u2e17\u2e1a\u2e3a\u2e3b\u2e40\u2e5d\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d\u2027\u2043\u2053\u2e43-]+){2}-([0-9]{4}(0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])|[0-9]{4}(0[469]|11)(0[1-9]|[12][0-9]|30)|[0-9]{4}02(0[1-9]|1[0-9]|2[0-8])|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(00|0[48]|[2468][048]|[13579][26])00)0229)$"
    },
    "genesis_timezone": {
      "description": "The time zone declared with the genesis record, by its name in the IANA Time Zone Database. Required; the identity manifest and the continuity record must declare the same zone, by the same name (no schema can compare the two records; a consumer checks it). The genesis date in the subject's name (uii_name, ucr_ref), the session date in active_uws and every Strike Date are calendar dates in this zone; T0 itself stays in UTC (Sections 3.2, 4.3, 4.4). The pattern checks only the form of the name; the name must be one the IANA database defines.",
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_+-]*(/[A-Za-z][A-Za-z0-9_+-]*)*$",
      "examples": ["America/New_York"]
    },
    "entries": {
      "description": "Ordered oldest first. The first entry is GENESIS.",
      "type": "array",
      "minItems": 1,
      "prefixItems": [ { "$ref": "#/$defs/genesis" } ],
      "items": { "$ref": "#/$defs/entry" }
    }
  },
  "additionalProperties": false,
  "$defs": {
    "uab": { "type": "string", "pattern": "^[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200bA-Z:_\u00ad\u058a\u05be\u1400\u1806\u2010-\u2015\u2212\u2e17\u2e1a\u2e3a\u2e3b\u2e40\u2e5d\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d\u2027\u2043\u2053\u2e43-]+_[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200bA-Z:_\u00ad\u058a\u05be\u1400\u1806\u2010-\u2015\u2212\u2e17\u2e1a\u2e3a\u2e3b\u2e40\u2e5d\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d\u2027\u2043\u2053\u2e43-]+(-[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200bA-Z:_\u00ad\u058a\u05be\u1400\u1806\u2010-\u2015\u2212\u2e17\u2e1a\u2e3a\u2e3b\u2e40\u2e5d\u301c\u3030\u30a0\ufe31\ufe32\ufe58\ufe63\uff0d\u2027\u2043\u2053\u2e43-]+)?_v[0-9]+\\.[0-9]+_([0-9]{4}(0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])|[0-9]{4}(0[469]|11)(0[1-9]|[12][0-9]|30)|[0-9]{4}02(0[1-9]|1[0-9]|2[0-8])|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(00|0[48]|[2468][048]|[13579][26])00)0229)$" },
    "uiv": { "description": "The UIV, vMAJOR.MINOR.PATCH (Section 6.1). An advance sets every field to its right to 0: v1.0.1 becomes v1.1.0, and v1.4.2 becomes v2.0.0.", "type": "string", "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+$" },
    "ts": { "description": "An instant, RFC 3339 in UTC; fractional seconds are optional. The pattern rejects a date or time that does not exist; seconds run 00-59, and an instant inside a leap second is written as second 59, as T0 is (Definition 1).", "type": "string", "format": "date-time", "pattern": "^([0-9]{4}-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|[0-9]{4}-(0[469]|11)-(0[1-9]|[12][0-9]|30)|[0-9]{4}-02-(0[1-9]|1[0-9]|2[0-8])|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(00|0[48]|[2468][048]|[13579][26])00)-02-29)T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?Z$" },
    "t0": { "description": "T0, the genesis instant, as Definition 1 fixes it (Section 4.2): RFC 3339 in UTC, to the whole second, YYYY-MM-DDThh:mm:ssZ; seconds run 00-59. The GENESIS entry's timestamp; it equals the identity manifest's genesis_timestamp_utc (Section 4.3; no schema can compare the two records, so a consumer checks it).", "type": "string", "maxLength": 20, "pattern": "^([0-9]{4}-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])|[0-9]{4}-(0[469]|11)-(0[1-9]|[12][0-9]|30)|[0-9]{4}-02-(0[1-9]|1[0-9]|2[0-8])|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(00|0[48]|[2468][048]|[13579][26])00)-02-29)T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]Z$" },
    "support": { "description": "The Support, a person or an organization; or \"self\" when the subject holds its own key and its own key vouches for it; or \"none\" when no party holds it. Both values are reserved, written in lowercase (a case variant such as \"None\", or either value with whitespace, a zero-width space or a word joiner around it, is not valid), never an organization name, and both are valid. With \"self\", an outsider has only the subject's own word for its continuity, with no third party behind it; with \"none\", no party holds the key and the record is closed (Sections 4.5, 8).", "type": "string", "minLength": 1, "pattern": "[^\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]", "not": { "pattern": "^[\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200b\u2060]*([Ss][Ee][Ll][Ff]|[Nn][Oo][Nn][Ee])[\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\u200b\u2060]*$", "not": { "enum": ["self", "none"] } }, "examples": ["Lyceum", "self", "none"] },
    "genesis": {
      "type": "object",
      "required": ["timestamp_utc", "event", "uab_after", "uiv_after", "support", "cause"],
      "properties": {
        "timestamp_utc": { "$ref": "#/$defs/t0" },
        "event": { "const": "GENESIS" },
        "uab_after": { "$ref": "#/$defs/uab" },
        "uiv_after": { "$ref": "#/$defs/uiv" },
        "support": { "$ref": "#/$defs/support" },
        "cause": { "type": "string" }
      },
      "additionalProperties": false
    },
    "entry": {
      "type": "object",
      "required": ["timestamp_utc", "event", "uab_before", "uab_after", "uiv_before", "uiv_after", "support", "cause"],
      "properties": {
        "timestamp_utc": { "$ref": "#/$defs/ts" },
        "event": {
          "description": "Event class, as named in the paper (Section 6.2, Table 5; Section 9.5; Appendix C): ENGINE_UPDATE (Engine Version increment, same engine), ENGINE_MIGRATION (engine generation change, same Manufacturer), MANUFACTURER_MIGRATION (Manufacturer change), DESIGN_REVISION (minor design change), DESIGN_REBUILD (major BSM change), FAMILY_MIGRATION (Binding Name change, a new operating model: the Studio places the subject in a new line, which no engine event alone causes (Section 3.3); same subject, same UII, UIV whole-number advance), SUPPORT_TRANSFER (transfer of Support), RUNTIME_FAILURE (runtime failure and re-mount). GENESIS opens the record.",
          "type": "string",
          "pattern": "^[A-Z][A-Z_]*$",
          "not": { "const": "GENESIS" },
          "examples": ["ENGINE_UPDATE", "ENGINE_MIGRATION", "MANUFACTURER_MIGRATION", "DESIGN_REVISION", "DESIGN_REBUILD", "FAMILY_MIGRATION", "SUPPORT_TRANSFER", "RUNTIME_FAILURE"]
        },
        "uab_before": { "$ref": "#/$defs/uab" },
        "uab_after": { "$ref": "#/$defs/uab" },
        "uiv_before": { "$ref": "#/$defs/uiv" },
        "uiv_after": { "$ref": "#/$defs/uiv" },
        "support": { "description": "The Support (a person or an organization), \"self\", or \"none\": the party that performed the event, except on a SUPPORT_TRANSFER, where it is the incoming Support (Appendix C).", "$ref": "#/$defs/support" },
        "cause": { "type": "string" }
      },
      "additionalProperties": false
    }
  }
}
