{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://machinereadyknowledge.com/mrk-1.1.schema.json",
  "title": "MRK-1.1 (DRAFT) - Machine-Ready Knowledge article front matter",
  "description": "DRAFT successor to MRK-1.0. Strictly additive: every article valid under mrk-1.0.schema.json is valid here. New fields are optional; `self_contained` is relaxed from const:true to a real boolean; `applies_to`'s plan/region requirement moves into the support-saas profile; and every NEW constraint (typed-section shapes, profile requirements) is gated behind an explicit `mrk_version: \"1.1\"` opt-in, so legacy instances are never newly rejected. Editorial clauses still hold out of band: sections truly stand alone (self_contained is a human attestation) and identifiers stay stable across history (audited from revision control). Full standard: https://machinereadyknowledge.com",
  "type": "object",
  "required": ["id", "title", "applies_to", "owner", "lifecycle", "verified", "sections"],
  "properties": {
    "mrk_version": {
      "enum": ["1.0", "1.1"],
      "description": "Optional. Absent is treated as 1.0. Declaring \"1.1\" opts the article into the new normative constraints (typed-section shapes, profile requirements)."
    },
    "profile": {
      "enum": ["support-saas", "software-product", "regulated", "general"],
      "description": "Applicability profile. Selects which applies_to dimensions are required (see allOf). support-saas preserves the MRK-1.0 plan+region contract."
    },
    "id": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*-[0-9]+$",
      "description": "Immutable once assigned. Never reused, never renamed."
    },
    "title": { "type": "string", "minLength": 1 },
    "type": {
      "type": "string",
      "description": "Article topic type. Free string for forward-compat; RECOGNIZED values (issue-resolution, task, concept, reference) gain section-shape rules when mrk_version is 1.1. Unknown values remain permitted and unconstrained."
    },
    "applies_to": { "$ref": "#/$defs/applicability" },
    "owner": { "type": "string" },
    "lifecycle": {
      "enum": ["draft", "unreleased", "current", "superseded", "retired", "expired"],
      "description": "1.0 values (current/superseded/retired) plus draft/unreleased/expired. Adding values is backward-compatible."
    },
    "visibility": {
      "enum": ["public", "internal", "confidential"],
      "description": "Answer-safety gate. Absent means public. A compliant consumer MUST NOT serve internal/confidential content into an answer for an unentitled reader."
    },
    "entitlement": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Entitlement keys a reader must hold to be served this article. Absent/empty = unrestricted."
    },
    "locale": {
      "type": "string",
      "description": "BCP-47 language tag for this article's prose (e.g. en, en-GB, de-DE)."
    },
    "localized_from": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*-[0-9]+$",
      "description": "Source article id this is a localization of."
    },
    "verified": { "type": "string", "format": "date" },
    "supersedes": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*-[0-9]+$",
      "description": "Retained from 1.0. Equivalent to a relations entry { rel: supersedes, target }."
    },
    "concepts": { "$ref": "#/$defs/conceptList" },
    "provenance": { "$ref": "#/$defs/provenance" },
    "relations": {
      "type": "array",
      "items": { "$ref": "#/$defs/relation" },
      "description": "Typed edges to other articles/sections. The seed of the knowledge graph an MRK corpus projects into (see mrk-1.1.context.jsonld)."
    },
    "sections": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/section" }
    }
  },
  "allOf": [
    {
      "$comment": "Typed-section shape for issue-resolution. Gated behind mrk_version:1.1 so legacy issue-resolution articles (which have no section roles) are never newly rejected.",
      "if": {
        "properties": { "mrk_version": { "const": "1.1" }, "type": { "const": "issue-resolution" } },
        "required": ["mrk_version", "type"]
      },
      "then": {
        "properties": {
          "sections": {
            "allOf": [
              { "contains": { "properties": { "role": { "const": "cause" } }, "required": ["role"] } },
              { "contains": { "properties": { "role": { "const": "resolution" } }, "required": ["role"] } },
              { "contains": { "properties": { "role": { "const": "verification" } }, "required": ["role"] } }
            ]
          }
        }
      }
    },
    {
      "$comment": "A 1.1 task article must carry at least one procedure section.",
      "if": {
        "properties": { "mrk_version": { "const": "1.1" }, "type": { "const": "task" } },
        "required": ["mrk_version", "type"]
      },
      "then": {
        "properties": {
          "sections": { "contains": { "properties": { "role": { "const": "procedure" } }, "required": ["role"] } }
        }
      }
    },
    {
      "$comment": "support-saas profile preserves the MRK-1.0 plan+region requirement.",
      "if": { "properties": { "profile": { "const": "support-saas" } }, "required": ["profile"] },
      "then": { "properties": { "applies_to": { "required": ["plan", "region"] } } }
    },
    {
      "$comment": "software-product profile requires a product dimension instead.",
      "if": { "properties": { "profile": { "const": "software-product" } }, "required": ["profile"] },
      "then": { "properties": { "applies_to": { "required": ["product"] } } }
    },
    {
      "$comment": "regulated profile requires an explicit jurisdiction dimension.",
      "if": { "properties": { "profile": { "const": "regulated" } }, "required": ["profile"] },
      "then": { "properties": { "applies_to": { "required": ["jurisdiction"] } } }
    }
  ],
  "$defs": {
    "applicability": {
      "type": "object",
      "minProperties": 1,
      "description": "At least one applicability dimension. plan/region are kept for the support-saas profile (required only under it); product/component/audience/role and the open `dimensions` map generalize MRK beyond SaaS. Structured version_* fields replace free-text `version`.",
      "properties": {
        "plan": { "type": "array", "minItems": 1, "items": { "type": "string" } },
        "region": { "type": ["string", "array"] },
        "product": { "type": ["string", "array"] },
        "component": { "type": ["string", "array"] },
        "audience": { "type": ["string", "array"] },
        "role": { "type": ["string", "array"] },
        "jurisdiction": { "type": ["string", "array"] },
        "version": { "type": "string", "description": "Legacy free-text (MRK-1.0). Prefer version_min/version_max/version_exact." },
        "version_min": { "type": "string" },
        "version_max": { "type": "string" },
        "version_exact": { "type": "string" },
        "dimensions": {
          "type": "object",
          "description": "Open, domain-specific applicability axes for knowledge that plan/region/product cannot express.",
          "additionalProperties": { "type": ["string", "array", "boolean", "number"] }
        }
      }
    },
    "conceptList": {
      "type": "array",
      "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
      "description": "Canonical term ids from the vocabulary layer. Project to SKOS concepts; bind prose to a governed taxonomy so entities resolve without guessing."
    },
    "provenance": {
      "type": "object",
      "description": "Lineage of the article. Ties the graduation model's operational history into the artifact itself.",
      "properties": {
        "derived_from": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Source references the article graduated from (case/thread/incident ids or URIs)."
        },
        "validated_by": { "type": "string" },
        "graduated_from": {
          "enum": ["conversation", "community", "kb", "official-docs", "training", "product"],
          "description": "Graduation-ladder rung this content originated on."
        },
        "confidence": { "enum": ["low", "medium", "high"] }
      }
    },
    "relation": {
      "type": "object",
      "required": ["rel", "target"],
      "properties": {
        "rel": { "enum": ["depends_on", "prerequisite_of", "references", "part_of", "supersedes", "see_also", "applies_with"] },
        "target": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9-]*-[0-9]+(#[a-z][a-z0-9-]*)?$",
          "description": "An article id or a section id (article-id#section-slug)."
        }
      }
    },
    "section": {
      "type": "object",
      "required": ["id", "self_contained"],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9-]*-[0-9]+#[a-z][a-z0-9-]*$"
        },
        "self_contained": {
          "type": "boolean",
          "description": "MRK-1.1 relaxes this from const:true to a real boolean. false honestly records a section that does not yet stand alone, so a corpus can enumerate and measure its §1 gap instead of being unable to represent failure. Attested by a human curator, not inferred."
        },
        "role": {
          "enum": ["context", "symptom", "cause", "resolution", "procedure", "verification", "concept", "reference", "prerequisite", "result", "caveat", "example"],
          "description": "Functional/semantic type of the section - the DITA information-typing analogue in plain language. Lets a machine know a section is the remedy vs. the cause without parsing a heading string."
        },
        "concepts": { "$ref": "#/$defs/conceptList" },
        "requires": {
          "type": "array",
          "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*-[0-9]+#[a-z][a-z0-9-]*$" },
          "description": "Section ids this section logically depends on. Self-containment still holds (prerequisites are restated inline); `requires` records the link that inlining erases - enabling graph projection and drift-linting between the canonical source and the inlined copy."
        }
      }
    }
  }
}
