{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "microsoft:learn:1.0",
  "title": "Microsoft Learn article metadata",
  "description": "The YAML front matter Microsoft Learn requires and recommends on a documentation article. Five attributes are required — omitting any of them fails the Learn build — and two of them carry format rules that catch mistakes no generic date or length check would: `ms.date` is `MM/DD/YYYY`, not ISO 8601, and `description` has a documented 75-300 character range. `ms.topic` is a string rather than an enum on purpose: the authoritative list is an internal Microsoft taxonomy, the published docfx-era set and the values Azure repositories actually use disagree, and an invented enum would fail correct articles. Attribute names are case-sensitive. See https://learn.microsoft.com/en-us/contribute/content/metadata",
  "type": "object",
  "required": ["title", "description", "author", "ms.author", "ms.date"],
  "additionalProperties": true,
  "$defs": {
    "textList": {
      "if": { "type": "array" },
      "then": { "items": { "type": "string" } },
      "else": { "type": "string" }
    }
  },
  "properties": {
    "title": {
      "type": "string",
      "minLength": 1,
      "description": "The page title shown on the browser tab. Required, and the single most important attribute for search."
    },
    "description": {
      "type": "string",
      "minLength": 75,
      "maxLength": 300,
      "description": "A summary of the article, used in site search. Required. Microsoft documents the hard range as 75-300 characters and recommends 115-145; only the hard range is enforced here."
    },
    "author": {
      "type": "string",
      "minLength": 1,
      "description": "The author's GitHub account ID — not a display name. Required."
    },
    "ms.author": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[^@\\s]+$",
      "description": "The owner's Microsoft alias, without `@microsoft.com`. Required. The pattern rejects a full email address, which is the usual way this one is written wrong."
    },
    "ms.date": {
      "type": "string",
      "pattern": "^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])/[0-9]{4}$",
      "description": "The date of the last substantial edit, in `MM/DD/YYYY`. Required. Note that this is *not* ISO 8601: `2026-08-23` is rejected, `08/23/2026` is correct."
    },
    "ms.topic": {
      "type": "string",
      "minLength": 1,
      "description": "The kind of article, such as `how-to`, `conceptual`, `quickstart`, `tutorial` or `overview`. Not enumerated — see this schema's description for why."
    },
    "ms.service": {
      "type": "string",
      "description": "The service the article documents."
    },
    "ms.subservice": {
      "type": "string",
      "description": "A component within `ms.service`."
    },
    "ms.custom": {
      "$ref": "#/$defs/textList",
      "description": "Free-form tags used for reporting and campaign tracking."
    },
    "ms.collection": {
      "$ref": "#/$defs/textList",
      "description": "Collections this article belongs to."
    },
    "ms.reviewer": {
      "type": "string",
      "description": "Microsoft alias of the technical reviewer."
    },
    "ms.devlang": {
      "$ref": "#/$defs/textList",
      "description": "Programming languages the article covers."
    },
    "ms.prod": {
      "type": "string",
      "description": "The product, for repositories that use `ms.prod` instead of `ms.service`."
    },
    "ms.technology": {
      "type": "string",
      "description": "A technology within `ms.prod`."
    },
    "keywords": {
      "$ref": "#/$defs/textList",
      "description": "Search keywords for the article."
    },
    "zone_pivot_groups": {
      "type": "string",
      "description": "The pivot group enabling tabbed variants of the article."
    }
  }
}
