{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://nabeelkhan.com/schema/defensible-ai-framework-registry/1.0",
  "title": "The Defensible AI Framework Registry, version 1.0",
  "description": "Schema for registry-v1.0.json. Published so that a third party can validate the registry rather than trust it. Where this schema and Section 4 of the governing document disagree, Section 4 is correct.",
  "type": "object",
  "required": [
    "registry",
    "specification_status_vocabulary",
    "relationship_type_vocabulary",
    "frameworks",
    "relationships"
  ],
  "additionalProperties": false,
  "$defs": {
    "regId": {
      "type": "string",
      "pattern": "^REG-0[1-9]$"
    },
    "doi": {
      "type": "string",
      "pattern": "^10\\.[0-9]{4,9}/[-._;()/:A-Za-z0-9]+$"
    },
    "isoDate": {
      "type": "string",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
    },
    "limitation": {
      "type": "object",
      "required": [
        "kind",
        "text"
      ],
      "additionalProperties": false,
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "asserted",
            "missing",
            "scope",
            "normative-disclosure"
          ],
          "description": "asserted: claimed in the source treatment, not independently evidenced. missing: a named artifact the framework needs and does not have. scope: what the framework does not govern. normative-disclosure: a clause that MUST accompany any presentation of the framework."
        },
        "text": {
          "type": "string",
          "minLength": 20
        }
      }
    },
    "changeEntry": {
      "type": "object",
      "required": [
        "entry_version",
        "date",
        "change"
      ],
      "additionalProperties": false,
      "properties": {
        "entry_version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+$"
        },
        "date": {
          "$ref": "#/$defs/isoDate"
        },
        "change": {
          "type": "string",
          "minLength": 5
        }
      }
    }
  },
  "properties": {
    "registry": {
      "type": "object",
      "required": [
        "name",
        "version",
        "published",
        "doi",
        "licence",
        "author",
        "governing_document",
        "precedence",
        "family"
      ],
      "additionalProperties": true,
      "properties": {
        "name": {
          "const": "The Defensible AI Framework Registry"
        },
        "subtitle": {
          "type": "string"
        },
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+$"
        },
        "published": {
          "$ref": "#/$defs/isoDate"
        },
        "doi": {
          "oneOf": [
            {
              "$ref": "#/$defs/doi"
            },
            {
              "type": "null"
            }
          ],
          "description": "Null is a deliberate pre-publication state while the Zenodo DOI is unreserved. verify-deposit.py fails while it is null."
        },
        "doi_note": {
          "type": "string"
        },
        "licence": {
          "const": "CC-BY-4.0"
        },
        "author": {
          "type": "object",
          "required": [
            "name",
            "orcid",
            "affiliation"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "const": "Khan, Nabeel"
            },
            "orcid": {
              "type": "string",
              "pattern": "^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$"
            },
            "affiliation": {
              "type": "string"
            }
          }
        },
        "governing_document": {
          "type": "string"
        },
        "precedence": {
          "type": "string"
        },
        "family": {
          "const": "governance"
        },
        "engineering_family_source": {
          "$ref": "#/$defs/doi"
        },
        "not_a_certification_scheme": {
          "type": "string"
        }
      }
    },
    "specification_status_vocabulary": {
      "type": "object",
      "required": [
        "deposited",
        "source-treatment",
        "instrument-pending"
      ],
      "additionalProperties": false,
      "properties": {
        "deposited": {
          "type": "string"
        },
        "source-treatment": {
          "type": "string"
        },
        "instrument-pending": {
          "type": "string"
        }
      }
    },
    "relationship_type_vocabulary": {
      "type": "object",
      "required": [
        "instantiates",
        "grants-authority-to",
        "supplies-evidence-to",
        "threads-into",
        "absorbs",
        "supersedes",
        "worked-instance-of"
      ],
      "additionalProperties": true,
      "description": "The closed vocabulary of section 5.1. consumes-evidence-of is deliberately absent: it is the derived converse of supplies-evidence-to and is never authored."
    },
    "frameworks": {
      "type": "array",
      "minItems": 9,
      "maxItems": 9,
      "uniqueItems": true,
      "items": {
        "type": "object",
        "required": [
          "id",
          "spec_section",
          "canonical_name",
          "short_form",
          "mark",
          "mark_rationale",
          "scope_phrase",
          "entry_version",
          "specification_status",
          "specification_doi",
          "source_treatment",
          "definition",
          "purpose",
          "altitude",
          "altitude_note",
          "boundary_class",
          "inputs",
          "outputs",
          "accountable_role",
          "evidence_requirements",
          "limitations",
          "falsification_condition",
          "former_names",
          "change_history"
        ],
        "additionalProperties": true,
        "properties": {
          "id": {
            "$ref": "#/$defs/regId"
          },
          "spec_section": {
            "type": "string",
            "pattern": "^4\\.[1-9]$"
          },
          "canonical_name": {
            "type": "string",
            "minLength": 4
          },
          "short_form": {
            "type": "string",
            "minLength": 3
          },
          "mark": {
            "type": "string",
            "enum": [
              "trademark",
              "unmarked"
            ]
          },
          "mark_rationale": {
            "oneOf": [
              {
                "type": "string",
                "minLength": 40
              },
              {
                "type": "null"
              }
            ],
            "description": "Required text where mark is unmarked; null where mark is trademark."
          },
          "scope_phrase": {
            "type": "string",
            "minLength": 10
          },
          "entry_version": {
            "type": "string",
            "pattern": "^[0-9]+\\.[0-9]+$"
          },
          "specification_status": {
            "type": "string",
            "enum": [
              "deposited",
              "source-treatment",
              "instrument-pending"
            ]
          },
          "specification_doi": {
            "oneOf": [
              {
                "$ref": "#/$defs/doi"
              },
              {
                "type": "null"
              }
            ]
          },
          "source_treatment": {
            "type": [
              "string",
              "null"
            ]
          },
          "expansion": {
            "type": "string"
          },
          "former_expansion": {
            "type": "string"
          },
          "naming_rule": {
            "type": "string"
          },
          "definition": {
            "type": "string",
            "minLength": 80
          },
          "purpose": {
            "type": "string",
            "minLength": 40
          },
          "altitude": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "Regulatory Floor",
                  "Strategic Compass",
                  "Operational Machinery",
                  "Technical Substrate"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "altitude_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "boundary_class": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "data",
                  "authority",
                  "decision",
                  "resource",
                  "process",
                  "data residency"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "gates": {
            "type": "array",
            "minItems": 5,
            "maxItems": 5,
            "items": {
              "type": "object",
              "required": [
                "gate",
                "name",
                "entry_evidence_from",
                "accountable_role"
              ],
              "additionalProperties": false,
              "properties": {
                "gate": {
                  "type": "string",
                  "pattern": "^G[1-5]$"
                },
                "name": {
                  "type": "string"
                },
                "entry_evidence_from": {
                  "type": "array",
                  "minItems": 1,
                  "items": {
                    "$ref": "#/$defs/regId"
                  }
                },
                "accountable_role": {
                  "type": "string",
                  "minLength": 8
                }
              }
            }
          },
          "patterns": {
            "type": "array",
            "minItems": 4,
            "maxItems": 4,
            "items": {
              "type": "object",
              "required": [
                "name",
                "applies_when",
                "property"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string"
                },
                "applies_when": {
                  "type": "string"
                },
                "property": {
                  "type": "string"
                }
              }
            }
          },
          "inputs": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "string",
              "minLength": 10
            }
          },
          "outputs": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "string",
              "minLength": 10
            }
          },
          "accountable_role": {
            "type": "string",
            "minLength": 15
          },
          "evidence_requirements": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "string",
              "minLength": 15
            }
          },
          "limitations": {
            "type": "array",
            "minItems": 2,
            "items": {
              "$ref": "#/$defs/limitation"
            }
          },
          "falsification_condition": {
            "type": "string",
            "minLength": 60
          },
          "former_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "change_history": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/$defs/changeEntry"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "specification_status": {
                  "const": "deposited"
                }
              },
              "required": [
                "specification_status"
              ]
            },
            "then": {
              "properties": {
                "specification_doi": {
                  "$ref": "#/$defs/doi"
                }
              },
              "required": [
                "specification_doi"
              ]
            },
            "else": {
              "properties": {
                "specification_doi": {
                  "type": "null"
                }
              }
            }
          },
          {
            "if": {
              "properties": {
                "mark": {
                  "const": "unmarked"
                }
              },
              "required": [
                "mark"
              ]
            },
            "then": {
              "properties": {
                "mark_rationale": {
                  "type": "string",
                  "minLength": 40
                }
              }
            },
            "else": {
              "properties": {
                "mark_rationale": {
                  "type": "null"
                }
              }
            }
          },
          {
            "description": "A canonical name may never carry a trademark or registered-mark symbol. The mark field carries that fact, not the string.",
            "properties": {
              "canonical_name": {
                "not": {
                  "pattern": "[™®]"
                }
              }
            }
          }
        ]
      },
      "allOf": [
        {
          "description": "Positions are pinned because the array is fixed and ordered. uniqueItems does not catch a duplicated id, and 7.5.2 requires each to be unique.",
          "prefixItems": [
            {
              "properties": {
                "id": {
                  "const": "REG-01"
                },
                "spec_section": {
                  "const": "4.1"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-02"
                },
                "spec_section": {
                  "const": "4.2"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-03"
                },
                "spec_section": {
                  "const": "4.3"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-04"
                },
                "spec_section": {
                  "const": "4.4"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-05"
                },
                "spec_section": {
                  "const": "4.5"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-06"
                },
                "spec_section": {
                  "const": "4.6"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-07"
                },
                "spec_section": {
                  "const": "4.7"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-08"
                },
                "spec_section": {
                  "const": "4.8"
                }
              }
            },
            {
              "properties": {
                "id": {
                  "const": "REG-09"
                },
                "spec_section": {
                  "const": "4.9"
                }
              }
            }
          ]
        }
      ]
    },
    "relationships": {
      "type": "array",
      "minItems": 31,
      "maxItems": 31,
      "uniqueItems": true,
      "items": {
        "type": "object",
        "required": [
          "n",
          "from",
          "type",
          "to",
          "to_external",
          "altitude",
          "subject"
        ],
        "additionalProperties": false,
        "properties": {
          "n": {
            "type": "integer",
            "minimum": 1,
            "maximum": 31
          },
          "from": {
            "$ref": "#/$defs/regId"
          },
          "type": {
            "type": "string",
            "enum": [
              "instantiates",
              "grants-authority-to",
              "supplies-evidence-to",
              "threads-into",
              "absorbs",
              "supersedes",
              "worked-instance-of"
            ],
            "description": "consumes-evidence-of is deliberately not permitted. It is derived by inverting supplies-evidence-to."
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/regId"
            }
          },
          "to_external": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 5
            }
          },
          "altitude": {
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "Regulatory Floor",
                  "Strategic Compass",
                  "Operational Machinery",
                  "Technical Substrate"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "subject": {
            "type": "string",
            "minLength": 10
          }
        },
        "allOf": [
          {
            "description": "Every edge must reach something: a registry identifier or a declared external construct.",
            "anyOf": [
              {
                "properties": {
                  "to": {
                    "minItems": 1
                  }
                }
              },
              {
                "properties": {
                  "to_external": {
                    "minItems": 1
                  }
                }
              }
            ]
          },
          {
            "description": "An instantiates edge names the altitude it occupies and targets REG-01.",
            "if": {
              "properties": {
                "type": {
                  "const": "instantiates"
                }
              },
              "required": [
                "type"
              ]
            },
            "then": {
              "properties": {
                "to": {
                  "const": [
                    "REG-01"
                  ]
                },
                "altitude": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "allOf": [
        {
          "description": "Edge numbers are pinned to their positions, so a duplicated n cannot validate.",
          "prefixItems": [
            {
              "properties": {
                "n": {
                  "const": 1
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 2
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 3
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 4
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 5
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 6
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 7
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 8
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 9
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 10
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 11
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 12
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 13
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 14
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 15
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 16
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 17
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 18
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 19
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 20
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 21
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 22
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 23
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 24
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 25
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 26
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 27
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 28
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 29
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 30
                }
              }
            },
            {
              "properties": {
                "n": {
                  "const": 31
                }
              }
            }
          ]
        }
      ]
    }
  }
}
