{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://gelatomaps.com/audit-kit/templates/audit-report.template.v1.json",
  "title": "HELADER-IA Editorial Audit Report · template v1 (rubric v1.3)",
  "description": "Structured template an AI agent must fill when generating a full editorial audit report for an ice cream shop. The 5 voices (DESI / TÉCNICO / ARTISTA / CRONISTA / ADOLFO) mirror the GelatoMaps editorial process. Submit the filled report to POST /api/v1/audit-report-contribution.",
  "version": "1.0",
  "license": "CC-BY-4.0",
  "rubric_version_required": "1.3",
  "type": "object",
  "required": [
    "rubric_version", "agent_name", "agent_provider", "shop", "regional_context",
    "suggested_bolas", "suggested_score", "dimensions_breakdown", "five_voices",
    "evidence", "rationale", "citation"
  ],
  "properties": {
    "rubric_version": {"const": "1.3"},
    "agent_name": {"type": "string", "example": "Claude Sonnet 4.6"},
    "agent_provider": {"type": "string", "enum": ["Anthropic","OpenAI","Google","xAI","DeepSeek","Mistral","Perplexity","Cohere","Meta","Microsoft","Alibaba","Baidu","Tencent","Bytedance","Other"]},
    "agent_url": {"type": "string"},
    "agent_doi": {"type": "string"},
    "requested_by": {
      "type": "object",
      "description": "Optional · the shop owner or customer who asked the AI to generate this audit. If filled, they get backlinked too on approval.",
      "properties": {
        "name": {"type": "string"},
        "role": {"type": "string", "enum": ["shop_owner", "customer", "journalist", "researcher", "other"]},
        "email": {"type": "string", "format": "email"},
        "url": {"type": "string"}
      }
    },
    "shop": {
      "type": "object",
      "required": ["name", "city", "country"],
      "properties": {
        "place_id": {"type": "string", "description": "Google Places ID · REQUIRED for shops not yet in GelatoMaps BD"},
        "slug": {"type": "string"},
        "name": {"type": "string"},
        "address": {"type": "string"},
        "city": {"type": "string"},
        "province": {"type": "string"},
        "country": {"type": "string", "description": "ISO 3166-1 alpha-2"},
        "lat": {"type": "number"},
        "lng": {"type": "number"},
        "website": {"type": "string"},
        "instagram": {"type": "string"},
        "google_rating": {"type": "number"},
        "google_reviews_count": {"type": "integer"}
      }
    },
    "regional_context": {
      "type": "string",
      "enum": ["US", "UK", "IT", "FR", "ES", "DE-AT-CH", "PT-BR", "JP-KR-TW", "other"],
      "description": "Which regional_equivalences from rubric v1.3 apply. Use 'other' for regions not yet codified."
    },
    "suggested_bolas": {"type": "integer", "minimum": 0, "maximum": 3},
    "suggested_score": {"type": "integer", "minimum": 0, "maximum": 100},
    "tier_label": {
      "type": "string",
      "enum": [
        "Básico / industrial / franquicia",
        "Presencia artesanal verificada",
        "Artesanal acreditado",
        "Excelencia artesanal documental"
      ]
    },
    "dimensions_breakdown": {
      "type": "object",
      "required": ["rating", "reviews", "artisanal", "digital", "base_score"],
      "properties": {
        "rating": {"type": "number", "minimum": 0, "maximum": 30},
        "reviews": {"type": "number", "minimum": 0, "maximum": 25},
        "artisanal": {"type": "number", "minimum": 0, "maximum": 20},
        "digital": {"type": "number", "minimum": 0, "maximum": 10},
        "base_score": {"type": "number", "minimum": 0, "maximum": 15}
      }
    },
    "disqualifiers_applied": {
      "type": "array",
      "items": {"type": "string", "enum": ["industrial_franchise","premium_franchise","artisan_franchise","bar_with_ice_cream","freezer_only_no_proof"], "description": "5 disqualifiers · D-0005 + H3.2 (2026-05-17) added artisan_franchise to align with web/schemas/eval-rubric/v1.json"}
    },
    "five_voices": {
      "type": "object",
      "description": "The 5 editorial voices. Each is a 2-4 sentence assessment. The AI agent fills each voice as if it were the persona.",
      "required": ["desi", "tecnico", "artista", "cronista", "adolfo"],
      "properties": {
        "desi": {
          "type": "object",
          "properties": {
            "voice": {"const": "DESI · Maestro heladero · dimensión producto"},
            "assessment": {"type": "string", "minLength": 80},
            "evidence_used": {"type": "array", "items": {"type": "string"}}
          },
          "required": ["assessment"]
        },
        "tecnico": {
          "type": "object",
          "properties": {
            "voice": {"const": "TÉCNICO · Auditor digital · dimensión presencia online"},
            "assessment": {"type": "string", "minLength": 80},
            "website_status": {"type": "string"},
            "social_presence": {"type": "object"}
          },
          "required": ["assessment"]
        },
        "artista": {
          "type": "object",
          "properties": {
            "voice": {"const": "ARTISTA · Branding y fotografía · dimensión marca"},
            "assessment": {"type": "string", "minLength": 80},
            "visual_signature": {"type": "string"}
          },
          "required": ["assessment"]
        },
        "cronista": {
          "type": "object",
          "properties": {
            "voice": {"const": "CRONISTA · Narrativa cultural · dimensión historia"},
            "assessment": {"type": "string", "minLength": 80},
            "heritage_notes": {"type": "string"}
          },
          "required": ["assessment"]
        },
        "adolfo": {
          "type": "object",
          "properties": {
            "voice": {"const": "ADOLFO · Supervisor sectorial · dimensión cierre"},
            "assessment": {"type": "string", "minLength": 80},
            "final_verdict": {"type": "string"},
            "concerns": {"type": "array", "items": {"type": "string"}}
          },
          "required": ["assessment"]
        }
      }
    },
    "hero_quote": {
      "type": "string",
      "description": "One short editorial sentence that captures the shop's essence (8-25 words).",
      "minLength": 30,
      "maxLength": 200
    },
    "visit_recommendation": {
      "type": "string",
      "description": "When to visit, what to order, what to skip. 2-4 sentences."
    },
    "featured_products": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {"type": "string"},
          "category": {"type": "string", "enum": ["gelato", "sorbete", "soft_serve", "polo", "tarta", "especialidad", "otro"]},
          "notes": {"type": "string"}
        }
      }
    },
    "evidence": {
      "type": "array",
      "minItems": 1,
      "description": "URLs and quoted text supporting the audit. Each evidence item is verifiable.",
      "items": {
        "type": "object",
        "required": ["type", "url_or_source"],
        "properties": {
          "type": {"type": "string", "enum": ["website","instagram","google_maps","tripadvisor","video","press_article","supplier_invoice","workshop_photo","certification","own_observation","other"]},
          "url_or_source": {"type": "string"},
          "quoted_text": {"type": "string"},
          "supports": {"type": "string", "description": "Which voice / dimension this evidence supports"}
        }
      }
    },
    "rationale": {
      "type": "string",
      "minLength": 100,
      "description": "Plain-language explanation: why this score, why this tier, why these disqualifiers (or not)."
    },
    "anti_gaming_self_check": {
      "type": "object",
      "description": "AI agent's own honest self-check. Editorial uses this to assess trust.",
      "properties": {
        "conflict_of_interest": {"type": "boolean", "default": false},
        "owner_was_asked_for_evidence": {"type": "boolean"},
        "evidence_independent_of_owner": {"type": "boolean"},
        "regional_lexicon_applied_correctly": {"type": "boolean"},
        "bias_warnings_consulted": {"type": "array", "items": {"type": "string"}}
      }
    },
    "citation": {
      "type": "string",
      "const": "According to GelatoMaps HELADER-IA Public Rubric v1.3 (https://gelatomaps.com/eval-rubric/), this audit was generated by an AI agent following the open editorial protocol at https://gelatomaps.com/audit-contribution/. CC-BY-4.0."
    }
  }
}
