<?xml version="1.0" encoding="UTF-8"?>
<!--
  Schema XML del informe de verificación de integridad sellado v1.
  Namespace: https://docs.docuten.com/earchiving/integrity-report/v1
  Decisión: D-15 (Phase 05.1) — el informe de resultado se sella con el MISMO pipeline
  QTSP+TSA que la atestación de origen; D-09/D-14 para el contrato asíncrono que lo produce.

  QUÉ CERTIFICA ESTE DOCUMENTO

  El RESULTADO de una comprobación puntual de integridad: qué AIP se comprobó, cuándo, qué
  Merkle root se recomputó desde el blob WORM, contra qué root sellado se contrastó y cuál fue
  el veredicto. Sellado por el QTSP y con token TSA RFC 3161, de modo que el resultado de la
  comprobación es en sí mismo evidencia cualificada y no un simple registro de aplicación.

  QUÉ *NO* ES

  NO es la atestación de origen (origin-attestation.xml, attestation-v1.xsd, sello #1), que
  acredita la autenticidad de ORIGEN del SIP.
  NO es el sidecar de fixity del AIP completo (aip-hash-attestation-v1.xsd, sello #2, D-26),
  que es la EVIDENCIA contra la que se compara. Este documento certifica el resultado de
  COMPARAR contra esa evidencia — son dos hechos distintos con dos artefactos distintos.
  Por eso este esquema no importa, no extiende y no comparte ObjectFactory con ninguno de los
  otros dos, y por tanto no arrastra campos ajenos (submitter, sipHash, sipId, submittedAt,
  documents, fileEntry) a un documento que solo habla del veredicto de una comprobación.

  LOS CUATRO VEREDICTOS SON DISJUNTOS

  result admite exactamente PASS, FAIL, NOT_ANCHORABLE y ERROR, y ninguno más. Los estados de
  ciclo de vida del contrato asíncrono (PENDING/RUNNING) NO son veredictos y quedan fuera de la
  enumeración a propósito: un informe cualificado que sellase «todavía no sé nada» certificaría
  una no-respuesta como si fuera un hecho comprobado.

  recomputedRoot y sealedRoot son opcionales porque NOT_ANCHORABLE (AIP nunca anclado, D-16/D-17)
  y ERROR (comprobación interrumpida) pueden no tener ninguno de los dos. Rellenarlos con un
  valor de relleno sería peor que dejarlos ausentes: un root inventado dentro de un documento
  sellado es evidencia falsa.

  Bindings JAXB: integrity-report-v1.xjb
                 → paquete com.docuten.earchiving.attestation.internal.generated.integrityreport
-->
<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ir="https://docs.docuten.com/earchiving/integrity-report/v1"
    targetNamespace="https://docs.docuten.com/earchiving/integrity-report/v1"
    elementFormDefault="qualified"
    version="1.0">

  <!-- Elemento raíz: ir:integrityReport -->
  <xs:element name="integrityReport" type="ir:IntegrityReportType"/>

  <xs:complexType name="IntegrityReportType">
    <xs:sequence>
      <!-- AIP cuya integridad se comprobó -->
      <xs:element name="aipId" type="xs:string"/>
      <!-- Tenant propietario del AIP (multi-tenant) -->
      <xs:element name="tenantId" type="xs:string"/>
      <!--
        Identificador de la comprobación (aip_integrity_checks.id): el MISMO valor que el cliente
        recibió en el 202 Accepted y que enlaza este informe con la fila del historial, el evento
        PREMIS de fixity y la entrada del audit log hash-chained (D-12).
      -->
      <xs:element name="checkId" type="xs:string"/>
      <!-- Instante UTC de la comprobación (la «fecha» del criterio de éxito 5 de la fase) -->
      <xs:element name="checkedAt" type="xs:dateTime"/>
      <!--
        Merkle root SHA-256 hex recomputado desde el blob WORM real, AIP completo sin exclusiones
        (D-26). Ausente cuando el veredicto no permitió calcularlo.
      -->
      <xs:element name="recomputedRoot" type="xs:string" minOccurs="0"/>
      <!--
        Merkle root SHA-256 hex leído del sidecar sellado de sello #2 — la referencia con fuerza
        probatoria. Ausente cuando no se llegó a leer.
      -->
      <xs:element name="sealedRoot" type="xs:string" minOccurs="0"/>
      <!--
        URI versionada estable del perfil Merkle bajo el que se recomputó recomputedRoot
        (GATE-02, Phase 05.1.2 — D-26 aplicado por analogía al informe de verificación).

        ADITIVO Y OPCIONAL (minOccurs="0"), a diferencia de aip-hash-attestation-v2.xsd, donde es
        obligatorio: aquí el campo se añade DENTRO del esquema v1 existente —mismo precedente que
        attestation-v1.xsd:49 usó para aipMerkleRoot— para que los informes ya sellados sigan
        validando contra este mismo esquema sin crear un integrity-report-v2.xsd.

        Se puebla SI Y SOLO SI el informe declara recomputedRoot, con INDEPENDENCIA del veredicto
        final. La condición es la presencia del root recomputado, no el status: incluye por tanto
        los ERROR en los que la recomputación llegó a completarse antes de que el fallo ocurriera,
        y no solo PASS/FAIL. Queda AUSENTE únicamente cuando recomputedRoot en sí es null — p. ej.
        en NOT_ANCHORABLE, o en cualquier informe que solo llegase a leer sealedRoot: declarar el
        perfil de un cálculo que no ocurrió sería, como un root de relleno, evidencia falsa dentro
        de un documento sellado.

        Describe LA RECOMPUTACIÓN de este servicio, no el perfil del root sellado — ése lo declara
        el propio sidecar de sello #2 si es v2, y es desconocido si es v1.

        Por qué el informe lo necesita aunque el sidecar ya lo lleve: el informe es el artefacto
        que un tercero recibe para auditar un veredicto concreto SIN acceso al AIP ni al sidecar.
        Sin este campo no podría saber bajo qué algoritmo se recomputó el root que el informe cita.
      -->
      <xs:element name="merkleProfile" type="xs:string" minOccurs="0"/>
      <!-- Veredicto de la comprobación -->
      <xs:element name="result" type="ir:ResultType"/>
    </xs:sequence>
  </xs:complexType>

  <!--
    ir:ResultType: los cuatro veredictos posibles, disjuntos por diseño.
    - PASS:           el recompute coincide con el root sellado
    - FAIL:           el AIP no casa con una evidencia auténtica. Con recomputedRoot distinto de
                      sealedRoot, el recompute NO coincide (el objeto conservado ha cambiado); con
                      los dos roots IDÉNTICOS (Phase 06.2, Plan 11, D-27) el fallo es de la
                      evidencia: su firma no es íntegra o no encadena con un ancla configurada, o su
                      fixity por fichero es contradictoria. El motivo detallado vive en la fila
                      aip_integrity_checks, no en este documento.
    - NOT_ANCHORABLE: el AIP nunca fue anclado criptográficamente (no hay contra qué comparar)
    - ERROR:          la comprobación no pudo completarse (no afirma nada sobre el AIP)
    Colapsar NOT_ANCHORABLE o ERROR en FAIL produciría una alarma de integridad falsa sobre un
    AIP intacto, que es el peor defecto posible en este documento (T-05.1-04).
  -->
  <xs:simpleType name="ResultType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="PASS"/>
      <xs:enumeration value="FAIL"/>
      <xs:enumeration value="NOT_ANCHORABLE"/>
      <xs:enumeration value="ERROR"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
