{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://oto-enterprise-os-dtp/qa/audit_4big.schema.json",
  "title": "Rapport d'audit 4Big qualite genere depuis quality_spec.json + les faits du depot",
  "description": "Contrat de sortie du generateur audit_4big_gen.py. Valide par le validateur maison Publiciste (zero pip) dans le job CI qa-audit-4big-tests.",
  "type": "object",
  "additionalProperties": false,
  "required": ["audit", "version", "reference_cadre", "pass_score", "coverage", "criteria", "modules", "totals", "verdict", "notes"],
  "properties": {
    "audit": { "type": "string", "const": "OTO QA · Audit 4Big Qualité" },
    "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+$" },
    "reference_cadre": { "type": "string", "minLength": 1 },
    "pass_score": { "type": "integer", "minimum": 1, "maximum": 100 },
    "coverage": {
      "type": "object",
      "additionalProperties": false,
      "required": ["ok", "ci_modules_count", "registry_modules_count", "missing_in_registry", "missing_in_ci", "not_in_gate", "self_module_excluded"],
      "properties": {
        "ok": { "type": "boolean" },
        "ci_modules_count": { "type": "integer", "minimum": 0 },
        "registry_modules_count": { "type": "integer", "minimum": 0 },
        "missing_in_registry": { "type": "array", "items": { "type": "string", "minLength": 1 } },
        "missing_in_ci": { "type": "array", "items": { "type": "string", "minLength": 1 } },
        "not_in_gate": { "type": "array", "items": { "type": "string", "minLength": 1 } },
        "self_module_excluded": { "type": "string", "minLength": 1 }
      }
    },
    "criteria": {
      "type": "array",
      "minItems": 5,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "label", "weight"],
        "properties": {
          "id": { "type": "string", "enum": ["DOC", "CONTRAT", "TESTS", "CLI", "HANDOFF"] },
          "label": { "type": "string", "minLength": 1 },
          "weight": { "type": "integer", "minimum": 1 }
        }
      }
    },
    "modules": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "path", "sprint", "archetype", "applicable_weight", "earned_weight", "score", "verdict", "checks"],
        "properties": {
          "id": { "type": "string", "minLength": 1 },
          "path": { "type": "string", "minLength": 1 },
          "sprint": { "type": "string", "pattern": "^S[0-9]+$" },
          "archetype": { "type": "string", "enum": ["generator", "data_room", "parser", "contract"] },
          "applicable_weight": { "type": "integer", "minimum": 1 },
          "earned_weight": { "type": "integer", "minimum": 0 },
          "score": { "type": "integer", "minimum": 0, "maximum": 100 },
          "verdict": { "type": "string", "enum": ["PASS", "FAIL"] },
          "checks": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["criterion", "weight", "passed", "evidence"],
              "properties": {
                "criterion": { "type": "string", "enum": ["DOC", "CONTRAT", "TESTS", "CLI", "HANDOFF"] },
                "weight": { "type": "integer", "minimum": 1 },
                "passed": { "type": "boolean" },
                "evidence": { "type": "string", "minLength": 1 }
              }
            }
          }
        }
      }
    },
    "totals": {
      "type": "object",
      "additionalProperties": false,
      "required": ["modules", "pass", "fail", "min_score", "max_score", "pass_rate_pct"],
      "properties": {
        "modules": { "type": "integer", "minimum": 1 },
        "pass": { "type": "integer", "minimum": 0 },
        "fail": { "type": "integer", "minimum": 0 },
        "min_score": { "type": "integer", "minimum": 0, "maximum": 100 },
        "max_score": { "type": "integer", "minimum": 0, "maximum": 100 },
        "pass_rate_pct": { "type": "integer", "minimum": 0, "maximum": 100 }
      }
    },
    "verdict": { "type": "string", "enum": ["PASS", "FAIL"] },
    "notes": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 }
    }
  }
}
