{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://embeddedknowledge.io/schemas/lesson.schema.json",
  "title": "EmbeddedKnowledge lesson pack metadata v3",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "format",
    "id",
    "version",
    "status",
    "riskTier",
    "title",
    "language",
    "outcomes",
    "prerequisites",
    "objectives",
    "estimatedMinutes",
    "scenes",
    "authors",
    "license",
    "files",
    "sourceConfidence",
    "aiAssistance",
    "thirdPartyAssets"
  ],
  "properties": {
    "schemaVersion": {
      "const": 3
    },
    "format": {
      "const": "embeddedknowledge-lesson-v1"
    },
    "id": {
      "type": "string",
      "pattern": "^(?:PREM|PSY)-[A-Z]{3}-[0-9]{3}$"
    },
    "version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
    },
    "status": {
      "enum": [
        "draft",
        "in-review",
        "adjudicated",
        "published"
      ]
    },
    "riskTier": {
      "enum": [
        "rephrasing",
        "minor-correction",
        "standard",
        "high-impact"
      ]
    },
    "title": {
      "type": "string",
      "minLength": 8,
      "maxLength": 160
    },
    "language": {
      "type": "string",
      "pattern": "^[a-z]{2,3}(-[A-Z]{2})?$"
    },
    "outcomes": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "$ref": "#/$defs/outcomeId"
      }
    },
    "prerequisites": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "$ref": "#/$defs/outcomeId"
      }
    },
    "objectives": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/objective"
      }
    },
    "estimatedMinutes": {
      "type": "integer",
      "minimum": 15,
      "maximum": 1200
    },
    "scenes": {
      "type": "array",
      "minItems": 4,
      "items": {
        "$ref": "#/$defs/scene"
      }
    },
    "authors": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/actor"
      }
    },
    "license": {
      "const": "CC-BY-4.0"
    },
    "files": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "assessment",
        "references",
        "claims",
        "glossary",
        "attribution"
      ],
      "properties": {
        "assessment": {
          "$ref": "#/$defs/jsonPath"
        },
        "references": {
          "$ref": "#/$defs/jsonPath"
        },
        "claims": {
          "$ref": "#/$defs/jsonPath"
        },
        "glossary": {
          "$ref": "#/$defs/jsonPath"
        },
        "attribution": {
          "$ref": "#/$defs/markdownPath"
        }
      }
    },
    "sourceConfidence": {
      "enum": [
        "pending-review",
        "low",
        "medium",
        "medium-high",
        "high"
      ]
    },
    "aiAssistance": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "used",
        "disclosure"
      ],
      "properties": {
        "used": {
          "type": "boolean"
        },
        "disclosure": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 2000
        }
      }
    },
    "thirdPartyAssets": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "path",
          "source",
          "title",
          "creator",
          "license",
          "rightsEvidence",
          "attribution",
          "modified",
          "modifications"
        ],
        "properties": {
          "path": {
            "$ref": "#/$defs/packPath"
          },
          "source": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "creator": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "license": {
            "enum": [
              "CC-BY-4.0",
              "CC0-1.0",
              "Public-Domain",
              "Written-Permission"
            ]
          },
          "rightsEvidence": {
            "type": "string",
            "minLength": 12,
            "maxLength": 2000
          },
          "attribution": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "modified": {
            "type": "boolean"
          },
          "modifications": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "modified": {
                  "const": true
                }
              }
            },
            "then": {
              "properties": {
                "modifications": {
                  "type": "string",
                  "minLength": 3
                }
              }
            },
            "else": {
              "properties": {
                "modifications": {
                  "type": "null"
                }
              }
            }
          }
        ]
      }
    },
    "originalAssets": {
      "type": "array",
      "uniqueItems": true,
      "description": "Pack-relative paths of image assets created for this lesson. Every image a scene shows must be either declared here or recorded in thirdPartyAssets, so an undeclared image cannot reach a learner.",
      "items": {
        "$ref": "#/$defs/packPath"
      }
    }
  },
  "$defs": {
    "outcomeId": {
      "type": "string",
      "pattern": "^topic-[a-z0-9-]+$"
    },
    "packPath": {
      "type": "string",
      "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\)[A-Za-z0-9][A-Za-z0-9._/-]*$"
    },
    "jsonPath": {
      "type": "string",
      "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\)[A-Za-z0-9][A-Za-z0-9._/-]*\\.json$"
    },
    "markdownPath": {
      "type": "string",
      "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\)[A-Za-z0-9][A-Za-z0-9._/-]*\\.md$"
    },
    "objective": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "statement",
        "outcomeIds"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^objective-[a-z0-9-]+$"
        },
        "statement": {
          "type": "string",
          "minLength": 12,
          "maxLength": 500
        },
        "outcomeIds": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/outcomeId"
          }
        }
      }
    },
    "scene": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "title",
        "kind",
        "source",
        "estimatedMinutes",
        "required",
        "claimCoverage"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^scene-[a-z0-9-]+$"
        },
        "title": {
          "type": "string",
          "minLength": 3,
          "maxLength": 120
        },
        "kind": {
          "enum": [
            "orientation",
            "diagnostic",
            "concept",
            "definition",
            "derivation",
            "worked-example",
            "investigation",
            "retrieval-check",
            "misconception",
            "practice",
            "transfer",
            "synthesis",
            "assessment",
            "references"
          ]
        },
        "source": {
          "type": "string",
          "pattern": "^content/[a-z0-9][a-z0-9._-]*\\.md$"
        },
        "estimatedMinutes": {
          "type": "integer",
          "minimum": 1,
          "maximum": 240
        },
        "required": {
          "type": "boolean"
        },
        "claimCoverage": {
          "enum": [
            "claims-mapped",
            "no-material-claims"
          ]
        }
      }
    },
    "actor": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "principalId",
        "displayName",
        "agent"
      ],
      "properties": {
        "principalId": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@/-]{2,127}$"
        },
        "displayName": {
          "type": "string",
          "minLength": 2,
          "maxLength": 120
        },
        "agent": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "system",
                "provider",
                "model",
                "version",
                "runId",
                "instructionsDigest"
              ],
              "properties": {
                "system": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 80
                },
                "provider": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 80
                },
                "model": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 120
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "runId": {
                  "type": "string",
                  "minLength": 6,
                  "maxLength": 160
                },
                "instructionsDigest": {
                  "type": "string",
                  "pattern": "^sha256:[a-f0-9]{64}$"
                }
              }
            }
          ]
        }
      }
    }
  }
}
