{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://copiloto.edilia.tech/especificacion/deteccion-marca-ia/v0/schema.json",
  "title": "AI-generated content detection result (draft 0.1)",
  "description": "Draft schema for a common detection result, proposed by Edilia Tech S.L. as input to the Ad-hoc Working Group on Interoperability of Task Force 1 (Code of Practice on Transparency of AI-generated Content). Work in progress: field names will follow whatever the group agrees. License: CC BY 4.0.",
  "type": "object",
  "required": ["schema_version", "outcome", "checked_marks", "marks", "ai_involvement", "validation_state", "integrity", "declared", "detector", "checked_at", "processing", "retention", "missing"],
  "properties": {
    "schema_version": { "type": "string", "const": "0.1" },
    "outcome": { "$ref": "#/$defs/outcome", "description": "Overall outcome. When several marks are checked: DETECTED if at least one mark is DETECTED; otherwise INCONCLUSIVE if at least one is INCONCLUSIVE; otherwise NOT_DETECTED. NOT_SUPPORTED and ERROR only when they apply to every mark checked. NOT_DETECTED and NOT_SUPPORTED must never be shown to end users as 'not AI'." },
    "checked_marks": { "type": "array", "items": { "type": "string" }, "description": "Marking techniques the detector checked for." },
    "marks": { "type": "array", "items": { "$ref": "#/$defs/mark" }, "description": "One entry per mark checked; conflicting results stay visible here." },
    "ai_involvement": { "enum": ["generated", "manipulated", "unknown"] },
    "validation_state": { "$ref": "#/$defs/validation_state" },
    "integrity": { "$ref": "#/$defs/integrity" },
    "declared": { "$ref": "#/$defs/declared" },
    "detector": {
      "type": "object",
      "required": ["name", "version", "operator", "id"],
      "properties": {
        "name": { "type": "string" },
        "version": { "type": "string" },
        "operator": { "type": "string" },
        "id": { "type": "string", "format": "uri" }
      }
    },
    "checked_at": { "type": "string", "format": "date-time", "description": "Time of the check, distinct from the content's generation time." },
    "processing": { "enum": ["local", "remote"], "description": "Whether the content left the user's device." },
    "retention": {
      "type": "object",
      "required": ["policy"],
      "properties": {
        "policy": { "enum": ["none", "transient", "stored"] },
        "period": { "type": "string", "description": "ISO 8601 duration, when policy is transient or stored." }
      }
    },
    "missing": { "type": "array", "items": { "type": "string" }, "description": "Fields the detector could not determine. Absent information is listed, not dropped." },
    "error": { "type": "string" },
    "receipt": { "$ref": "#/$defs/receipt" }
  },
  "$defs": {
    "outcome": { "enum": ["DETECTED", "NOT_DETECTED", "INCONCLUSIVE", "NOT_SUPPORTED", "ERROR"] },
    "validation_state": { "enum": ["valid", "invalid", "not_validated"] },
    "integrity": { "enum": ["intact", "modified", "unknown"], "description": "Whether the content is unchanged since marking. 'unknown' when the mark does not bind the content itself." },
    "declared": {
      "type": "object",
      "description": "Information declared by the content or the provider, not verified unless validation_state is valid.",
      "properties": {
        "provider": { "type": "string" },
        "digital_source_type": { "type": "string" },
        "generated_at": { "type": "string" },
        "legal_basis": { "type": "string" }
      }
    },
    "mark": {
      "type": "object",
      "required": ["type", "method", "outcome", "validation_state", "integrity", "declared"],
      "properties": {
        "type": { "type": "string" },
        "method": { "enum": ["cryptographic_signature", "watermark", "provider_record_lookup", "fingerprint", "forensic_inference"] },
        "outcome": { "$ref": "#/$defs/outcome" },
        "validation_state": { "$ref": "#/$defs/validation_state" },
        "integrity": { "$ref": "#/$defs/integrity" },
        "confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "Only for probabilistic methods; omitted for cryptographic verification." },
        "declared": { "$ref": "#/$defs/declared" }
      }
    },
    "receipt": {
      "type": "object",
      "description": "In-band signed result. 'payload' is base64 of a JSON object with sorted keys: schema_version, outcome, validation_state, integrity, content_sha256, detector_id, detector_version, checked_at. 'signature' is a detached signature over the decoded payload bytes. Public keys are published at key_url (JWKS).",
      "required": ["alg", "key_id", "key_url", "payload", "signature"],
      "properties": {
        "alg": { "type": "string", "examples": ["ed25519"] },
        "key_id": { "type": "string" },
        "key_url": { "type": "string", "format": "uri" },
        "payload": { "type": "string", "contentEncoding": "base64" },
        "signature": { "type": "string", "contentEncoding": "base64" }
      }
    }
  }
}
