{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://ver.cy/schemas/card/1.0.0",
  "title": "Vercy catalogue card",
  "description": "One shape for every entry of the Vercy catalogue: world models, enterprise profiles, software and landscape models, registry things. Every section is always present. A section the source does not fill stays empty and its state in `completeness` says why, so a reader can tell 'unknown' from 'nothing to say'. The card store models/cards/ is the single source the site renders from; the files it was built from are recorded in provenance.",
  "type": "object",
  "required": ["schema", "id", "code", "url", "name", "kind", "status", "version", "classifiers", "whatItIs", "purpose", "scope", "distinguishingFeatures", "structure", "agentConduct", "ethics", "owners", "relations", "interaction", "sources", "openQuestions", "provenance", "completeness"],
  "additionalProperties": false,
  "$defs": {
    "text": {"type": "string"},
    "texts": {"type": "array", "items": {"type": "string"}},
    "state": {
      "enum": ["filled", "derived", "thin", "missing", "not-applicable"],
      "description": "filled: written for this section by the source. derived: assembled by the card builder from another part of the source and awaiting review. thin: present but below the minimum (for example bundles without findings). missing: nothing in any source. not-applicable: the section does not apply to this kind of entry, reason in completeness.notes."
    },
    "applicability": {"enum": ["required", "optional", "not-applicable"]},
    "facet": {
      "type": "object",
      "required": ["applicability", "items"],
      "additionalProperties": false,
      "properties": {
        "applicability": {"$ref": "#/$defs/applicability"},
        "items": {"type": "array", "items": {"type": "string"}}
      }
    },
    "question": {
      "type": "object",
      "required": ["text"],
      "properties": {"id": {"type": "string"}, "text": {"type": "string"}, "kind": {"type": "string"}}
    },
    "finding": {
      "type": "object",
      "required": ["name", "questions"],
      "properties": {
        "id": {"type": "string"}, "name": {"type": "string"}, "description": {"type": "string"},
        "questions": {"type": "array", "items": {"$ref": "#/$defs/question"}}
      }
    },
    "layer": {
      "type": "object",
      "required": ["name", "findings"],
      "properties": {
        "id": {"type": "string"}, "name": {"type": "string"}, "description": {"type": "string"},
        "findings": {"type": "array", "items": {"$ref": "#/$defs/finding"}}
      }
    },
    "bundle": {
      "type": "object",
      "required": ["name", "layers"],
      "properties": {
        "id": {"type": "string"}, "name": {"type": "string"}, "description": {"type": "string"},
        "layers": {"type": "array", "items": {"$ref": "#/$defs/layer"}}
      }
    }
  },
  "properties": {
    "schema": {"const": "https://ver.cy/schemas/card/1.0.0"},
    "id": {"type": "string", "description": "Registry identifier, stable across versions (vr.wm-act-005, vr.tr.dog)."},
    "code": {"type": "string", "description": "Card address in the store and in the URL."},
    "url": {"type": "string"},
    "name": {"type": "string"},
    "alternateNames": {"$ref": "#/$defs/texts"},
    "aliasIds": {"$ref": "#/$defs/texts", "description": "Further registry identifiers that resolve to this same card."},
    "kind": {"enum": ["world-model", "enterprise-profile", "enterprise-contour", "software-model", "landscape-model", "thing"]},
    "status": {"enum": ["published", "research-draft", "draft-generated", "legacy", "todo"]},
    "version": {"type": "string"},
    "language": {"type": "string", "description": "Language of the card text (BCP 47)."},
    "classifiers": {
      "type": "object",
      "description": "Where the entry sits in the catalogue and which facets it carries.",
      "properties": {
        "family": {"type": "string"}, "category": {"type": "string"}, "entryKind": {"type": "string"},
        "plane": {"type": "string"}, "domain": {"$ref": "#/$defs/texts"}, "industry": {"$ref": "#/$defs/texts"},
        "navPath": {"type": "string"}, "tags": {"$ref": "#/$defs/texts"}, "facets": {"type": "object"}
      }
    },
    "whatItIs": {"type": "string", "description": "What the thing is: definition and class boundary."},
    "purpose": {"type": "string", "description": "Why the model exists: what an agent can do with it."},
    "scope": {
      "type": "object",
      "properties": {
        "in": {"$ref": "#/$defs/texts"}, "out": {"$ref": "#/$defs/texts"},
        "boundaries": {"type": "array", "items": {"type": "object", "properties": {"neighbor": {"type": "string"}, "distinction": {"type": "string"}}}}
      }
    },
    "distinguishingFeatures": {"$ref": "#/$defs/texts", "description": "What sets it apart from neighbouring and easily confused classes."},
    "structure": {
      "type": "object",
      "required": ["bundles"],
      "description": "Bundle -> Layer -> Finding -> Questions.",
      "properties": {"bundles": {"type": "array", "items": {"$ref": "#/$defs/bundle"}}}
    },
    "agentConduct": {
      "type": "object",
      "description": "What robots and AI agents may do with the entry, must never do, and may do only with a human decision.",
      "properties": {"may": {"$ref": "#/$defs/texts"}, "mustNot": {"$ref": "#/$defs/texts"}, "requiresHuman": {"$ref": "#/$defs/texts"}}
    },
    "ethics": {
      "type": "object",
      "description": "Moral aspects: who can be harmed or wronged, and what has to be respected.",
      "properties": {"considerations": {"$ref": "#/$defs/texts"}, "affectedParties": {"$ref": "#/$defs/texts"}}
    },
    "owners": {
      "type": "object",
      "description": "Neutral owner archetypes: steward of the model, roles, master systems for the facts.",
      "properties": {
        "steward": {"type": "string"},
        "roles": {"type": "array", "items": {"type": "object", "properties": {"name": {"type": "string"}, "responsibilities": {"$ref": "#/$defs/texts"}}}},
        "masterSystems": {"$ref": "#/$defs/texts"}
      }
    },
    "relations": {
      "type": "array",
      "description": "Links to other meta-models.",
      "items": {
        "type": "object",
        "required": ["target", "type"],
        "properties": {
          "target": {"type": "string"},
          "type": {"enum": ["parent", "child", "contains", "part-of", "aligned", "references", "composes", "extends", "imports", "neighbor", "related", "requires"]},
          "note": {"type": "string"}
        }
      }
    },
    "interaction": {
      "type": "object",
      "description": "What else AI and robots need to deal with the physical or digital object itself. Follows the whole-object description profile (https://ver.cy/object-description-profile.yaml).",
      "required": ["identity", "properties", "recognition", "capabilities", "hazards", "interfaces", "context"],
      "properties": {
        "identity": {"$ref": "#/$defs/facet", "description": "Identifiers, master systems, class boundary."},
        "properties": {"$ref": "#/$defs/facet", "description": "Direct properties with units: geometry, mass, material, state."},
        "recognition": {"$ref": "#/$defs/facet", "description": "How to recognise it and what it is confused with."},
        "capabilities": {"$ref": "#/$defs/facet", "description": "Behaviour, states, possible actions, preconditions, effects."},
        "hazards": {"$ref": "#/$defs/facet", "description": "Failure modes and hazards for people, agents and property."},
        "interfaces": {"$ref": "#/$defs/facet", "description": "Standards, protocols, APIs and formats to interact through."},
        "context": {"$ref": "#/$defs/facet", "description": "Origin, location, use, maintenance, applicable rules."}
      }
    },
    "sources": {
      "type": "array",
      "items": {"type": "object", "properties": {"title": {"type": "string"}, "url": {"type": "string"}, "note": {"type": "string"}}}
    },
    "openQuestions": {"$ref": "#/$defs/texts"},
    "resources": {
      "type": "object",
      "description": "Machine files that belong to the entry.",
      "properties": {"spec": {"type": "string"}, "agents": {"type": "string"}, "source": {"type": "string"}, "package": {"type": "string"}}
    },
    "provenance": {
      "type": "object",
      "properties": {
        "origin": {"type": "string"}, "builtFrom": {"$ref": "#/$defs/texts"}, "providers": {"$ref": "#/$defs/texts"},
        "researchStatus": {"type": "string"}, "generatedAt": {"type": "string"}, "builder": {"type": "string"}
      }
    },
    "completeness": {
      "type": "object",
      "required": ["sections", "score"],
      "properties": {
        "sections": {"type": "object", "additionalProperties": {"$ref": "#/$defs/state"}},
        "notes": {"type": "object", "additionalProperties": {"type": "string"}},
        "score": {"type": "number", "minimum": 0, "maximum": 1}
      }
    }
  }
}
