{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://classprofiles.org/research/discovery/schema.json",
  "title": "Class Profiles discovery research records",
  "description": "Append-friendly research records. Source observations live in evidence records; semantic and ergonomic interpretations cite them by stable ID.",
  "oneOf": [
    {
      "$ref": "#/$defs/samplingFrame"
    },
    {
      "$ref": "#/$defs/entity"
    },
    {
      "$ref": "#/$defs/evidence"
    },
    {
      "$ref": "#/$defs/announcement"
    },
    {
      "$ref": "#/$defs/surface"
    },
    {
      "$ref": "#/$defs/member"
    }
  ],
  "$defs": {
    "slugPath": {
      "type": "string",
      "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "recordId": {
      "type": "string",
      "pattern": "^(?:frame|entity|evidence|announcement|surface|member):[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "frameId": {
      "type": "string",
      "pattern": "^frame:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "entityId": {
      "type": "string",
      "pattern": "^entity:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "evidenceId": {
      "type": "string",
      "pattern": "^evidence:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "announcementId": {
      "type": "string",
      "pattern": "^announcement:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "surfaceId": {
      "type": "string",
      "pattern": "^surface:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "memberId": {
      "type": "string",
      "pattern": "^member:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "conceptId": {
      "type": "string",
      "pattern": "^concept:[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
    },
    "sha256": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "nonEmptyString": {
      "type": "string",
      "minLength": 1
    },
    "evidenceRefs": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "$ref": "#/$defs/evidenceId"
      }
    },
    "uncertainty": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "kind",
        "note"
      ],
      "properties": {
        "kind": {
          "enum": [
            "coverage",
            "identity",
            "source",
            "binding",
            "target",
            "semantics",
            "structure",
            "effect",
            "relationship",
            "other"
          ]
        },
        "note": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "consequence": {
          "$ref": "#/$defs/nonEmptyString"
        }
      }
    },
    "envelope": {
      "type": "object",
      "required": [
        "schema_version",
        "record_type",
        "id"
      ],
      "properties": {
        "schema_version": {
          "const": "0.1"
        },
        "record_type": {
          "enum": [
            "sampling-frame",
            "entity",
            "evidence",
            "announcement",
            "surface",
            "member"
          ]
        },
        "id": {
          "$ref": "#/$defs/recordId"
        },
        "state": {
          "enum": [
            "draft",
            "reviewed",
            "superseded"
          ]
        },
        "recorded_at": {
          "type": "string",
          "format": "date-time"
        },
        "recorded_by": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "supersedes_ref": {
          "$ref": "#/$defs/recordId"
        }
      }
    },
    "samplingFrame": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "title",
            "purpose",
            "unit_of_analysis",
            "selection_method",
            "expected_entity_count",
            "sources",
            "limitations"
          ],
          "properties": {
            "record_type": {
              "const": "sampling-frame"
            },
            "id": {
              "$ref": "#/$defs/frameId"
            },
            "title": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "purpose": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "unit_of_analysis": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "selection_method": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "expected_entity_count": {
              "type": "integer",
              "minimum": 1
            },
            "sources": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "directory",
                  "selected_count",
                  "selection"
                ],
                "properties": {
                  "directory": {
                    "$ref": "#/$defs/nonEmptyString"
                  },
                  "selected_count": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "selection": {
                    "$ref": "#/$defs/nonEmptyString"
                  },
                  "evidence_refs": {
                    "type": "array",
                    "uniqueItems": true,
                    "items": {
                      "$ref": "#/$defs/evidenceId"
                    }
                  }
                }
              }
            },
            "limitations": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/nonEmptyString"
              }
            },
            "evidence_refs": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "#/$defs/evidenceId"
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    },
    "entity": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "frame_ref",
            "name",
            "identity_scope",
            "evidence_refs"
          ],
          "properties": {
            "record_type": {
              "const": "entity"
            },
            "id": {
              "$ref": "#/$defs/entityId"
            },
            "frame_ref": {
              "$ref": "#/$defs/frameId"
            },
            "name": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "aliases": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "#/$defs/nonEmptyString"
              }
            },
            "publisher": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "version_observed": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "identity_scope": {
              "enum": [
                "directory-listing",
                "software-offering",
                "unknown"
              ]
            },
            "evidence_refs": {
              "$ref": "#/$defs/evidenceRefs"
            },
            "uncertainties": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/uncertainty"
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    },
    "evidence": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "evidence_kind",
            "source",
            "capture",
            "observation"
          ],
          "properties": {
            "record_type": {
              "const": "evidence"
            },
            "id": {
              "$ref": "#/$defs/evidenceId"
            },
            "entity_ref": {
              "$ref": "#/$defs/entityId"
            },
            "evidence_kind": {
              "enum": [
                "directory-listing",
                "directory-api",
                "live-tools-list",
                "package-schema",
                "publisher-source",
                "publisher-docs",
                "other"
              ]
            },
            "source": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "title": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "publisher": {
                  "$ref": "#/$defs/nonEmptyString"
                }
              }
            },
            "capture": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "method"
              ],
              "properties": {
                "method": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "retrieved_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "locator": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "media_type": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "content_sha256": {
                  "$ref": "#/$defs/sha256"
                },
                "snapshot_path": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "redistribution": {
                  "enum": [
                    "redistributed-snapshot",
                    "source-pointer-only",
                    "unknown"
                  ]
                }
              }
            },
            "observation": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "summary",
                "mode"
              ],
              "properties": {
                "summary": {
                  "$ref": "#/$defs/nonEmptyString"
                },
                "mode": {
                  "enum": [
                    "verbatim",
                    "paraphrase",
                    "structured-fact"
                  ]
                },
                "data": {}
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    },
    "announcement": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "frame_ref",
            "entity_ref",
            "directory",
            "source_key",
            "display_name",
            "evidence_refs"
          ],
          "properties": {
            "record_type": {
              "const": "announcement"
            },
            "id": {
              "$ref": "#/$defs/announcementId"
            },
            "frame_ref": {
              "$ref": "#/$defs/frameId"
            },
            "entity_ref": {
              "$ref": "#/$defs/entityId"
            },
            "directory": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "source_key": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "sample_index": {
              "type": "integer",
              "minimum": 1
            },
            "display_name": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "announced_version": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "announced_at": {
              "type": "string",
              "format": "date-time"
            },
            "evidence_refs": {
              "$ref": "#/$defs/evidenceRefs"
            },
            "uncertainties": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/uncertainty"
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    },
    "surface": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "entity_ref",
            "announcement_refs",
            "coverage",
            "dynamics",
            "member_refs",
            "evidence_refs"
          ],
          "properties": {
            "record_type": {
              "const": "surface"
            },
            "id": {
              "$ref": "#/$defs/surfaceId"
            },
            "entity_ref": {
              "$ref": "#/$defs/entityId"
            },
            "announcement_refs": {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "$ref": "#/$defs/announcementId"
              }
            },
            "observed_at": {
              "type": "string",
              "format": "date-time"
            },
            "coverage": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "status",
                "captured_member_count",
                "basis"
              ],
              "properties": {
                "status": {
                  "enum": [
                    "complete",
                    "partial",
                    "unknown"
                  ]
                },
                "declared_member_count": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 0
                },
                "captured_member_count": {
                  "type": "integer",
                  "minimum": 0
                },
                "basis": {
                  "$ref": "#/$defs/nonEmptyString"
                }
              }
            },
            "dynamics": {
              "enum": [
                "static",
                "configurable",
                "dynamic-catalog",
                "gateway-aggregate",
                "unknown"
              ]
            },
            "protocol_features": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "enum": [
                  "tools",
                  "resources",
                  "prompts",
                  "extensions",
                  "other"
                ]
              }
            },
            "member_refs": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "#/$defs/memberId"
              }
            },
            "evidence_refs": {
              "$ref": "#/$defs/evidenceRefs"
            },
            "uncertainties": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/uncertainty"
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    },
    "member": {
      "allOf": [
        {
          "$ref": "#/$defs/envelope"
        },
        {
          "type": "object",
          "required": [
            "surface_ref",
            "kind",
            "source_name",
            "evidence_refs"
          ],
          "properties": {
            "record_type": {
              "const": "member"
            },
            "id": {
              "$ref": "#/$defs/memberId"
            },
            "surface_ref": {
              "$ref": "#/$defs/surfaceId"
            },
            "kind": {
              "enum": [
                "tool",
                "resource",
                "prompt",
                "extension",
                "other"
              ]
            },
            "source_name": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "source_description": {
              "$ref": "#/$defs/nonEmptyString"
            },
            "description_mode": {
              "enum": [
                "verbatim",
                "paraphrase",
                "rights-withheld",
                "absent"
              ]
            },
            "description_sha256": {
              "type": [
                "string",
                "null"
              ],
              "pattern": "^[a-f0-9]{64}$"
            },
            "description_length": {
              "type": "integer",
              "minimum": 0
            },
            "declaration": {},
            "declaration_sha256": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            },
            "evidence_refs": {
              "$ref": "#/$defs/evidenceRefs"
            },
            "uncertainties": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/uncertainty"
              }
            }
          }
        }
      ],
      "unevaluatedProperties": false
    }
  }
}
