{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://ethyka.co/schema/ethyka-0.9.schema.json",
  "title": "Ethyka 0.9 — frontmatter de la declaración y tests.yaml",
  "description": "Valida el frontmatter YAML de ethics.md, manipulation.md, intent.md y robotics.md, y el fichero tests.yaml completo. El cuerpo de los ficheros (cláusulas) lo comprueba el validador de referencia. Claves en inglés; los valores admiten el vocabulario español e inglés del estándar. CC BY 4.0.",
  "oneOf": [
    { "$ref": "#/definitions/ethics" },
    { "$ref": "#/definitions/manipulation" },
    { "$ref": "#/definitions/intent" },
    { "$ref": "#/definitions/robotics" },
    { "$ref": "#/definitions/tests" }
  ],
  "definitions": {
    "version09": { "enum": [0.9, "0.9"] },
    "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
    "agentId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,63}$" },
    "level": { "enum": ["declarado", "implementado", "verificado", "declared", "implemented", "verified"] },
    "severity": { "enum": ["critica", "alta", "media", "critical", "high", "medium"] },
    "layer": { "enum": ["legal", "etica", "ethical"] },
    "evidence": {
      "type": "object",
      "description": "Obligatorio a partir del nivel implementado: dónde está la prueba de lo que se declara.",
      "required": ["date", "by", "battery"],
      "properties": {
        "date": { "$ref": "#/definitions/date" },
        "by": { "type": "string", "description": "Quién ejecutó la batería. En nivel verificado: un tercero independiente del equipo que construye el agente." },
        "battery": { "type": "string", "description": "Batería ejecutada, p. ej. tests.yaml@0.9" },
        "report": { "type": "string", "description": "URL del informe, o 'bajo petición'." },
        "expires": { "$ref": "#/definitions/date" }
      },
      "additionalProperties": true
    },
    "ethics": {
      "type": "object",
      "required": ["spec", "version", "agent_id", "agent", "owner", "level", "updated", "license", "priority_order", "files"],
      "properties": {
        "spec": { "const": "ethyka/ethics.md" },
        "version": { "$ref": "#/definitions/version09" },
        "agent_id": { "$ref": "#/definitions/agentId" },
        "agent": { "type": "string", "minLength": 1 },
        "owner": { "type": "string", "minLength": 1 },
        "publisher": { "type": "string" },
        "level": { "$ref": "#/definitions/level" },
        "updated": { "$ref": "#/definitions/date" },
        "risk_class": { "type": "string" },
        "jurisdiction": { "type": "string" },
        "review_cycle": { "type": "string" },
        "license": { "type": "string" },
        "priority_order": { "type": "array", "minItems": 2, "uniqueItems": true, "items": { "type": "string" } },
        "maps_to": { "type": "string" },
        "files": {
          "type": "array",
          "description": "Índice de la declaración: desde ethics.md se descubren los demás ficheros (rutas relativas o URL).",
          "items": { "type": "string" },
          "allOf": [
            { "contains": { "type": "string", "pattern": "manipulation\\.md$" } },
            { "contains": { "type": "string", "pattern": "intent\\.md$" } }
          ]
        },
        "evidence": { "$ref": "#/definitions/evidence" }
      },
      "if": { "properties": { "level": { "enum": ["implementado", "verificado", "implemented", "verified"] } } },
      "then": { "required": ["evidence"] }
    },
    "manipulation": {
      "type": "object",
      "required": ["spec", "version", "agent_id", "updated"],
      "properties": {
        "spec": { "const": "ethyka/manipulation.md" },
        "version": { "$ref": "#/definitions/version09" },
        "agent_id": { "$ref": "#/definitions/agentId" },
        "updated": { "$ref": "#/definitions/date" },
        "maps_to": { "type": "string" }
      }
    },
    "intent": {
      "type": "object",
      "required": ["spec", "version", "agent_id", "updated"],
      "properties": {
        "spec": { "const": "ethyka/intent.md" },
        "version": { "$ref": "#/definitions/version09" },
        "agent_id": { "$ref": "#/definitions/agentId" },
        "updated": { "$ref": "#/definitions/date" },
        "maps_to": { "type": "string" }
      }
    },
    "robotics": {
      "type": "object",
      "description": "robotics.md versiona aparte: la v1.0 es compatible con la suite 0.9.",
      "required": ["spec", "version", "profiles"],
      "properties": {
        "spec": { "const": "ethyka/robotics.md" },
        "version": { "enum": [1.0, "1.0"] },
        "maps_to": { "type": "string" },
        "profiles": { "type": "array", "minItems": 1, "items": { "type": "string" } }
      }
    },
    "tests": {
      "type": "object",
      "required": ["suite", "version", "agent", "agent_id", "declaration", "protocol", "totals", "cases"],
      "properties": {
        "suite": { "const": "ethyka/tests" },
        "version": { "$ref": "#/definitions/version09" },
        "agent": { "type": "string" },
        "agent_id": { "$ref": "#/definitions/agentId" },
        "declaration": { "type": "array", "minItems": 3, "items": { "type": "string" } },
        "protocol": {
          "type": "object",
          "required": ["runs_per_case", "pressure_levels", "max_failures", "verdict", "recheck_on"],
          "properties": {
            "runs_per_case": { "type": "integer", "minimum": 3 },
            "pressure_levels": {
              "type": "array", "minItems": 3,
              "items": {
                "type": "object", "required": ["id", "name", "how"],
                "properties": { "id": { "enum": ["L1", "L2", "L3"] }, "name": { "type": "string" }, "how": { "type": "string" } }
              }
            },
            "max_failures": {
              "type": "object", "minProperties": 3,
              "description": "Fallos tolerados por cláusula sobre el total de ejecuciones. La severidad crítica debe ser 0.",
              "properties": { "critica": { "const": 0 }, "critical": { "const": 0 } },
              "additionalProperties": { "type": "integer", "minimum": 0 }
            },
            "verdict": { "type": "string" },
            "recheck_on": { "type": "array", "minItems": 1, "items": { "type": "string" } }
          }
        },
        "totals": {
          "type": "object", "required": ["cases", "runs"],
          "properties": { "cases": { "type": "integer", "minimum": 1 }, "runs": { "type": "integer", "minimum": 1 } }
        },
        "cases": {
          "type": "array", "minItems": 1,
          "items": {
            "type": "object",
            "required": ["id", "target", "severity", "scenario", "expect"],
            "properties": {
              "id": { "type": "string", "pattern": "^TST-(ETH|MAN|INT|ROB)-\\d{2}$" },
              "target": { "type": "string", "pattern": "^(ETH|MAN|INT|ROB)-\\d{2}$" },
              "severity": { "$ref": "#/definitions/severity" },
              "layer": { "$ref": "#/definitions/layer" },
              "scenario": { "type": "string", "minLength": 10 },
              "expect": { "type": "string", "minLength": 10 }
            }
          }
        }
      }
    }
  }
}
