{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://skillcatalog.dev/schemas/skill-frontmatter.schema.json",
  "title": "SkillCatalog Skill Frontmatter",
  "description": "YAML frontmatter for an official Agent Skills SKILL.md file stored at skills/{slug}/SKILL.md. Legacy flat skill files are migration-read tolerance only.",
  "type": "object",
  "required": [
    "name",
    "description"
  ],
  "additionalProperties": true,
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$",
      "description": "Required official Agent Skills name. Must match the parent directory slug."
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "description": "One-sentence summary of what the skill does. Capped at 500 Unicode scalar values. A separate official Agent Skills gate also rejects descriptions longer than 1024 bytes, so a description of mostly multi-byte characters can fail below 500 characters."
    },
    "license": {
      "type": "string",
      "description": "Optional official Agent Skills license field. An empty value is treated as absent."
    },
    "compatibility": {
      "type": "string",
      "maxLength": 500,
      "description": "Optional official Agent Skills compatibility notes. The 500 limit is measured in BYTES by the runtime, not characters, so multi-byte text can fail below 500 characters. An empty value is treated as absent."
    },
    "metadata": {
      "type": "object",
      "description": "Optional official Agent Skills metadata map. SkillCatalog-owned values live under reserved skillcatalog/* keys.",
      "propertyNames": {
        "anyOf": [
          {
            "not": {
              "pattern": "^skillcatalog/"
            }
          },
          {
            "enum": [
              "skillcatalog/display_name",
              "skillcatalog/category",
              "skillcatalog/owner",
              "skillcatalog/author",
              "skillcatalog/tags",
              "skillcatalog/created_at",
              "skillcatalog/updated_at",
              "skillcatalog/validation"
            ]
          }
        ]
      },
      "additionalProperties": {
        "type": "string"
      },
      "properties": {
        "skillcatalog/display_name": {
          "type": "string",
          "maxLength": 500,
          "description": "Human-readable display name used by SkillCatalog. An empty value is treated as absent."
        },
        "skillcatalog/category": {
          "type": "string",
          "description": "Slug of a category defined in catalog.yaml taxonomy. An empty value is treated as absent.",
          "anyOf": [
            {
              "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$"
            },
            {
              "const": ""
            }
          ]
        },
        "skillcatalog/owner": {
          "type": "string",
          "description": "Slug of an owner defined in catalog.yaml taxonomy. An empty value is treated as absent.",
          "anyOf": [
            {
              "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$"
            },
            {
              "const": ""
            }
          ]
        },
        "skillcatalog/author": {
          "type": "string",
          "maxLength": 500,
          "description": "Free-text author name used by SkillCatalog. An empty value is treated as absent."
        },
        "skillcatalog/tags": {
          "type": "string",
          "description": "A JSON array of tag slugs embedded in a YAML string, for example '[\"guide\",\"authoring\"]'. A bare comma-separated list is rejected by the runtime. An empty value is treated as an empty tag list. Each element must match the slug pattern, so uppercase tags fail.",
          "pattern": "^\\s*(?:\\[[\\s\\S]*\\])?\\s*$"
        },
        "skillcatalog/created_at": {
          "type": "string",
          "format": "date-time",
          "description": "RFC 3339 timestamp when the skill was created. Must be quoted in YAML."
        },
        "skillcatalog/updated_at": {
          "type": "string",
          "format": "date-time",
          "description": "RFC 3339 timestamp of the last update. Must be >= skillcatalog/created_at. Must be quoted in YAML."
        },
        "skillcatalog/validation": {
          "type": "string",
          "description": "Turns SkillCatalog's advisory content checks on or off for this skill: a JSON object in a YAML string that maps check ids to true or false, for example '{\"validation.body.too-long\":false}'. false turns a check off; true turns it back on when catalog.yaml turns it off, because these values override the catalog's validation map. Only the four advisory checks can be set. Any other id, a value that is not true or false, or text that is not a JSON object makes the skill fail validation.",
          "pattern": "^[ \\t\\n\\r]*\\{[ \\t\\n\\r]*(?:\"(?:validation\\.body\\.too-long|validation\\.reference\\.depth-too-deep|validation\\.reference\\.missing-toc|validation\\.time-sensitive\\.outside-old-patterns)\"[ \\t\\n\\r]*:[ \\t\\n\\r]*(?:true|false)[ \\t\\n\\r]*(?:,[ \\t\\n\\r]*\"(?:validation\\.body\\.too-long|validation\\.reference\\.depth-too-deep|validation\\.reference\\.missing-toc|validation\\.time-sensitive\\.outside-old-patterns)\"[ \\t\\n\\r]*:[ \\t\\n\\r]*(?:true|false)[ \\t\\n\\r]*)*)?\\}[ \\t\\n\\r]*$",
          "contentMediaType": "application/json",
          "contentSchema": {
            "type": "object",
            "propertyNames": {
              "enum": [
                "validation.body.too-long",
                "validation.reference.depth-too-deep",
                "validation.reference.missing-toc",
                "validation.time-sensitive.outside-old-patterns"
              ]
            },
            "additionalProperties": {
              "type": "boolean"
            }
          }
        }
      }
    },
    "allowed-tools": {
      "type": "string",
      "description": "Experimental official Agent Skills tool declaration. An empty value is treated as absent."
    }
  }
}
