{
  "version": 1,
  "note": "Field definitions for every record type in the register. Drives validation, referential integrity, the facets in the UI, and what the templates render. Adding a field here is all that is needed to surface it — do not hardcode a field list anywhere else.",

  "enums": {
    "confidence": {
      "confirmed": {
        "label": "Confirmed",
        "rank": 1,
        "note": "Stated by a primary source — the party's own filing, site, or an official designation."
      },
      "strong": {
        "label": "Strong",
        "rank": 2,
        "note": "Multiple independent technical or documentary indicators agree, with no contrary evidence."
      },
      "suggestive": {
        "label": "Suggestive",
        "rank": 3,
        "note": "Consistent with the hypothesis but explainable other ways. Do not rely on it."
      },
      "struck": {
        "label": "Struck",
        "rank": 4,
        "note": "Investigated and disproven. Kept on the record so the dead end is not walked twice."
      }
    },

    "entity_type": {
      "person": { "label": "Person" },
      "holding": { "label": "Holding group" },
      "company": { "label": "Operating company" },
      "vehicle": { "label": "Offshore vehicle" },
      "vendor": { "label": "Service vendor" },
      "association": { "label": "Industry council / association" }
    },

    "sanctions": {
      "designated": { "label": "Designated" },
      "named_in_designation": { "label": "Named in a designation" },
      "not_designated": { "label": "Not designated" },
      "unknown": { "label": "Unknown" }
    },

    "jurisdiction": {
      "SY": { "label": "Syria" },
      "AE": { "label": "United Arab Emirates" },
      "LB": { "label": "Lebanon" },
      "EG": { "label": "Egypt" },
      "PA": { "label": "Panama" },
      "XX": { "label": "Unknown" }
    },

    "category": {
      "union": { "label": "Union estate" },
      "hamsho": { "label": "Hamsho-named" },
      "offshore": { "label": "Offshore" },
      "sama": { "label": "Sama holding" },
      "industry": { "label": "Industry" },
      "consumer": { "label": "Consumer" },
      "finance": { "label": "Finance" },
      "gaia": { "label": "Gaia infrastructure" },
      "third_party": { "label": "Third-party client" }
    },

    "source_kind": {
      "primary": { "label": "Primary — the party's own material" },
      "sanctions": { "label": "Sanctions record" },
      "press": { "label": "Reporting" },
      "technical": { "label": "Technical observation" },
      "directory": { "label": "Business directory" }
    },

    "status": {
      "live": { "label": "Live" },
      "dormant": { "label": "Dormant" },
      "suspended": { "label": "Suspended" },
      "unresolved": { "label": "Not resolving" },
      "mail_only": { "label": "Mail only" }
    },

    "relation_kind": {
      "spouse": { "label": "Spouse" },
      "parent": { "label": "Parent" },
      "child": { "label": "Child" },
      "sibling": { "label": "Sibling" },
      "cousin": { "label": "Cousin" }
    }
  },

  "records": {
    "entities": {
      "label": "Entity",
      "collection": "entities",
      "note": "People and companies. `controlled_by` and `parent` are the ownership graph; the site derives the reverse edges (subsidiaries, controls) at build time, so record each relationship once, on the child.",
      "fields": [
        { "key": "id",                 "label": "ID",                             "type": "id",            "required": true },
        { "key": "name",               "label": "Name",                           "type": "string",        "required": true, "max": 140, "translatable": true },
        { "key": "aka",                "label": "Also known as",                  "type": "list",          "translatable": true },
        { "key": "hover_alt",          "label": "Hover alt (decorative)",         "type": "string",        "max": 60 },
        { "key": "type",               "label": "Type",                           "type": "enum",          "enum": "entity_type", "required": true, "facet": true },
        { "key": "jurisdiction",       "label": "Jurisdiction",                   "type": "enum",          "enum": "jurisdiction", "required": true, "facet": true },
        { "key": "sanctions",          "label": "Sanctions",                      "type": "enum",          "enum": "sanctions", "required": true, "facet": true },
        { "key": "confidence",         "label": "Confidence",                     "type": "enum",          "enum": "confidence", "required": true, "facet": true },
        { "key": "sector",             "label": "Sector",                         "type": "string",        "max": 160, "translatable": true },
        { "key": "summary",            "label": "Summary",                        "type": "text",          "required": true, "max": 900, "translatable": true },
        { "key": "established",        "label": "Established",                    "type": "string",        "max": 80, "translatable": true },
        { "key": "address",            "label": "Address",                        "type": "string",        "max": 240, "translatable": true },
        { "key": "contact",            "label": "Contact",                        "type": "list",          "translatable": true },
        { "key": "passport",           "label": "Passport",                       "type": "string",        "max": 40 },
        { "key": "positions",          "label": "Positions held",                 "type": "list",          "translatable": true },
        { "key": "external_ids",       "label": "External identifiers",           "type": "list" },
        { "key": "priorities",         "label": "Stated priorities",              "type": "list" },
        { "key": "logo",               "label": "Logo(s)",                        "type": "list" },
        { "key": "photo",              "label": "Photo",                          "type": "string",        "max": 200 },
        { "key": "registry_id",        "label": "Registry ID (CBLS)",             "type": "string",        "max": 40 },
        { "key": "registry_number",    "label": "Registry number",                "type": "string",        "max": 40 },
        { "key": "registry_status",    "label": "Registry status",                "type": "string",        "max": 40 },
        { "key": "emirate",            "label": "Emirate / sub-jurisdiction",     "type": "string",        "max": 60 },
        { "key": "incorporation_date", "label": "Incorporation date",             "type": "date" },
        { "key": "legal_form",         "label": "Legal form",                     "type": "string",        "max": 80, "translatable": true },
        { "key": "paid_capital",       "label": "Paid share capital",             "type": "string",        "max": 60, "translatable": true },
        { "key": "authorized_capital", "label": "Authorized capital",             "type": "string",        "max": 60 },
        { "key": "activity_codes",     "label": "Registered activities",          "type": "list" },
        { "key": "note",               "label": "Note",                           "type": "text",          "max": 500, "translatable": true },
        { "key": "parent",             "label": "Parent",                         "type": "ref",           "ref": "entities" },
        { "key": "controlled_by",      "label": "Controlled by",                  "type": "ref",           "ref": "entities", "multi": true },
        { "key": "family_relations",   "label": "Family relations (not control)", "type": "relation_list", "ref": "entities", "kindEnum": "relation_kind" },
        { "key": "sources",            "label": "Sources",                        "type": "ref",           "ref": "sources", "multi": true }
      ]
    },

    "findings": {
      "label": "Finding",
      "collection": "findings",
      "note": "Each finding is a claim plus its confidence and its sources. `order` controls the sequence on the front page. Attach long-form writing to a finding by adding its id to an article's `findings:` list — see site/articles/.",
      "fields": [
        { "key": "id",         "label": "ID",              "type": "id",     "required": true },
        { "key": "title",      "label": "Title",           "type": "string", "required": true, "max": 140, "translatable": true },
        { "key": "confidence", "label": "Confidence",      "type": "enum",   "enum": "confidence", "required": true, "facet": true },
        { "key": "order",      "label": "Order",           "type": "number", "required": true },
        { "key": "summary",    "label": "Summary",         "type": "text",   "required": true, "max": 700, "translatable": true },
        { "key": "detail",     "label": "Detail",          "type": "list",   "translatable": true },
        { "key": "quote",      "label": "Quote",           "type": "object" },
        { "key": "images",     "label": "Document images", "type": "list" },
        { "key": "entities",   "label": "Entities",        "type": "ref",    "ref": "entities", "multi": true },
        { "key": "sources",    "label": "Sources",         "type": "ref",    "ref": "sources", "multi": true }
      ]
    },

    "domains": {
      "label": "Domain",
      "collection": "domains",
      "note": "The domain register. `server` must match an id in data/servers/ and `entity` an id in data/entities/ — scripts/validate.mjs enforces both. `created` and `registrar` are from Verisign RDAP where retrieved; leave them out rather than guessing.",
      "fields": [
        { "key": "id",        "label": "Domain",                   "type": "id",     "required": true },
        { "key": "purpose",   "label": "Purpose",                  "type": "string", "required": true, "max": 200, "translatable": true },
        { "key": "category",  "label": "Category",                 "type": "enum",   "enum": "category", "required": true, "facet": true },
        { "key": "server",    "label": "Server",                   "type": "ref",    "ref": "servers", "required": true, "facet": true },
        { "key": "status",    "label": "Status",                   "type": "enum",   "enum": "status", "facet": true },
        { "key": "entity",    "label": "Entity",                   "type": "ref",    "ref": "entities" },
        { "key": "created",   "label": "Created",                  "type": "date" },
        { "key": "registrar", "label": "Registrar",                "type": "string", "max": 80 },
        { "key": "note",      "label": "Note",                     "type": "string", "max": 240, "translatable": true },
        { "key": "research",  "label": "Online research snapshot", "type": "object" }
      ]
    },

    "servers": {
      "label": "Server",
      "collection": "servers",
      "note": "Hosts the estate sits on. Every domain record names one of these; the id is what data/domains/ references. The estate has run on two IT operators, not one: Gaia (Server A, Server B) is the current one, and a predecessor, BOC (Server C), authorised mail for domains registered 2002–2017 before the handover.",
      "fields": [
        { "key": "id",          "label": "ID",          "type": "id",     "required": true },
        { "key": "ip",          "label": "IP",          "type": "string", "required": true },
        { "key": "label",       "label": "Label",       "type": "string", "required": true },
        { "key": "provider",    "label": "Provider",    "type": "string", "required": true },
        { "key": "role",        "label": "Role",        "type": "string", "required": true, "translatable": true },
        { "key": "reverse_dns", "label": "Reverse DNS", "type": "string" },
        { "key": "nameservers", "label": "Nameservers", "type": "list" },
        { "key": "notes",       "label": "Notes",       "type": "list",   "translatable": true }
      ]
    },

    "events": {
      "label": "Event",
      "collection": "events",
      "note": "Registration and corporate timeline. `sort` is the key the site orders by — use the ISO date of the first event in the cluster so ranges sort correctly. `date` is the human label.",
      "fields": [
        { "key": "id",       "label": "ID",       "type": "id",     "required": true },
        { "key": "date",     "label": "Date",     "type": "string", "required": true },
        { "key": "sort",     "label": "Sort key", "type": "string", "required": true },
        { "key": "title",    "label": "Title",    "type": "string", "required": true, "max": 140, "translatable": true },
        { "key": "flag",     "label": "Flag",     "type": "string", "max": 60, "translatable": true },
        { "key": "body",     "label": "Body",     "type": "text",   "max": 700, "translatable": true },
        { "key": "domains",  "label": "Domains",  "type": "ref",    "ref": "domains", "multi": true },
        { "key": "entities", "label": "Entities", "type": "ref",    "ref": "entities", "multi": true },
        { "key": "findings", "label": "Findings", "type": "ref",    "ref": "findings", "multi": true },
        { "key": "sources",  "label": "Sources",  "type": "ref",    "ref": "sources", "multi": true }
      ]
    },

    "sources": {
      "label": "Source",
      "collection": "sources",
      "note": "Bibliography. Every claim in the register cites source ids from here; scripts/validate.mjs fails the build on a reference to an id that does not exist.",
      "fields": [
        { "key": "id",        "label": "ID",                    "type": "id",     "required": true },
        { "key": "title",     "label": "Title",                 "type": "string", "required": true, "max": 220, "translatable": true },
        { "key": "url",       "label": "URL",                   "type": "url",    "required": true },
        { "key": "kind",      "label": "Kind",                  "type": "enum",   "enum": "source_kind", "required": true, "facet": true },
        { "key": "publisher", "label": "Publisher",             "type": "string", "max": 120 },
        { "key": "retrieved", "label": "Retrieved",             "type": "date" },
        { "key": "note",      "label": "Note",                  "type": "string", "max": 600, "translatable": true },
        { "key": "quote_ar",  "label": "Verbatim Arabic quote", "type": "text",   "max": 900 }
      ]
    }
  }
}
