{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://skillcatalog.dev/schemas/skillcatalog-yml.schema.json",
  "title": "SkillCatalog Committed Profile Manifest",
  "description": "The .skillcatalog/skillcatalog.yml file committed to a project repository. Declares catalog references and which skills, stacks, or bundles to deliver. A legacy root-level skillcatalog.yml is still read when this path is absent; having both is a layout conflict.",
  "type": "object",
  "required": [
    "profile",
    "entries"
  ],
  "additionalProperties": false,
  "allOf": [
    {
      "if": {
        "properties": {
          "entries": {
            "type": "array",
            "minItems": 1
          }
        },
        "required": [
          "entries"
        ]
      },
      "then": {
        "required": [
          "catalogs"
        ],
        "properties": {
          "catalogs": {
            "type": "object",
            "minProperties": 1
          }
        }
      }
    }
  ],
  "properties": {
    "profile": {
      "type": "object",
      "required": [
        "id",
        "display_name"
      ],
      "additionalProperties": false,
      "description": "Identity of the committed profile.",
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$",
          "not": {
            "const": "home"
          },
          "description": "Stable profile slug. Must not be 'home' (reserved for the global home profile)."
        },
        "display_name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 500,
          "description": "Human-readable profile name."
        }
      }
    },
    "catalogs": {
      "type": [
        "object",
        "null"
      ],
      "description": "Catalog references keyed by the intrinsic catalog id from catalog.yaml. Required and non-empty when entries are present; may be omitted, null, or empty only for a no-op manifest with no entries.",
      "propertyNames": {
        "minLength": 2,
        "maxLength": 64,
        "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$"
      },
      "additionalProperties": {
        "type": "object",
        "required": [
          "source"
        ],
        "additionalProperties": false,
        "properties": {
          "source": {
            "type": "string",
            "minLength": 1,
            "anyOf": [
              {
                "pattern": "^git@[^\\s?#]*$"
              },
              {
                "pattern": "^[Ss][Ss][Hh]://(?![^\\s?#/]*:[^\\s?#/]*@)[^\\s?#]*$"
              },
              {
                "pattern": "^[Hh][Tt][Tt][Pp][Ss]?://[^/?#\\s@]+(?:/[^\\s?#]*)?$"
              }
            ],
            "description": "Remote Git catalog source. Accepts git@host:path, ssh:// (scheme case-insensitive; user, port, IPv6 literal and colon-path forms all allowed, but no password in the userinfo), and HTTP(S) with a non-empty authority and no userinfo. Query strings, fragments, embedded whitespace, local filesystem paths and file:// URLs are rejected."
          }
        }
      }
    },
    "entries": {
      "type": "array",
      "description": "Ordered list of skills, stacks, or bundles to include in this profile. No duplicates with the same catalog_id + kind + slug; the runtime rejects them.",
      "items": {
        "type": "object",
        "required": [
          "catalog_id",
          "kind",
          "slug"
        ],
        "additionalProperties": false,
        "properties": {
          "catalog_id": {
            "type": "string",
            "minLength": 2,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$",
            "description": "Intrinsic catalog id this entry resolves against."
          },
          "kind": {
            "type": "string",
            "enum": [
              "skill",
              "stack",
              "bundle"
            ],
            "description": "Type of catalog entry."
          },
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,127}$",
            "description": "Slug of the entry in the referenced catalog."
          }
        }
      },
      "uniqueItems": true
    }
  }
}
