diff --git a/docs/artifacts/CORE_ARTIFACT_SCHEMAS.es.md b/docs/artifacts/CORE_ARTIFACT_SCHEMAS.es.md
new file mode 100644
index 00000000..212eb420
--- /dev/null
+++ b/docs/artifacts/CORE_ARTIFACT_SCHEMAS.es.md
@@ -0,0 +1,92 @@
+# Esquemas canónicos de artefacto que publica Evolith Core
+
+> **Navegación bilingüe:** [English](./CORE_ARTIFACT_SCHEMAS.md) · Español (este documento)
+
+`PhaseArtifactCatalog` le dice a un tenant que un `prd` es **obligatorio** en discovery. Hasta ahora
+no le decía a nadie **qué debe contener un PRD**, porque el catálogo lleva solo `ArtifactKind`,
+`Label` y `Required` — ninguna referencia a la forma canónica. Este documento es ese enlace que
+faltaba (`GAP-020`).
+
+## Qué es esto, y qué no es
+
+**Es** un puntero a la forma que el Core publica para un artefacto, para que quien vaya a rellenar
+uno pueda ver los campos canónicos.
+
+**No es** una restricción sobre lo que un tenant puede registrar. Según
+[`T-056`](../adrs/T-056-three-layer-separation.es.md), la validación de contenido es configuración
+del tenant y no código del motor: los campos propios que un tenant añade con `ArtifactFieldSchema`
+siguen siendo suyos, y los tipos de evidencia que declara (`ci-result`, `regression`,
+`release-notes`) no salen de ninguna lista cerrada de aguas arriba.
+
+## Por qué el enlace es una URL y no una ruta
+
+Las definiciones de gate del Core llevan `requiredArtifacts[].schemaRef` como ruta relativa al
+repositorio. Esas rutas estaban **rotas** hasta `evolith_arch32#378`: escritas
+`../schema/prd.schema.json`, resolvían desde el directorio de gates a
+`reference/governance/sdlc/schema/`, un directorio que no existe, mientras los ficheros están en
+`src/rulesets/schema/`. Nadie podía dereferenciarlas, aguas arriba incluido.
+
+Ya son correctas, y aun así este documento enlaza por **`$id`** y no por ruta — a propósito. Una ruta
+es un hecho sobre dónde está un fichero en un repositorio en un momento; el `$id` es la identidad
+publicada del esquema y sobrevive a que el fichero se mueva. Un satélite que enlazara por ruta se
+rompería la próxima vez que el Core reorganice su árbol.
+
+## Los artefactos que tienen esquema canónico
+
+**Catorce** de los veinticuatro artefactos obligatorios del Core publican uno. Se da la clase del Tracker
+porque los nombres **no** coinciden mecánicamente — la correspondencia es una decisión, escrita aquí
+en vez de derivada de un slug.
+
+| Fase | Clase en el Tracker | Artefacto del Core | Esquema canónico |
+|---|---|---|---|
+| discovery | `prd` | PRD | [`prd.schema.json`](https://evolith.dev/schema/prd.schema.json) |
+| discovery | *(sin clase en el catálogo)* | Discovery Canvas | [`discovery-canvas.schema.json`](https://evolith.dev/schema/discovery-canvas.schema.json) |
+| discovery | `technical-feasibility-canvas` | Technical Feasibility Canvas | [`technical-feasibility.schema.json`](https://evolith.dev/schema/technical-feasibility.schema.json) |
+| discovery | *(sin clase en el catálogo)* | Ballpark Estimation | [`ballpark-estimation.schema.json`](https://evolith.dev/schema/ballpark-estimation.schema.json) |
+| discovery | `build-versus-compose-analysis` | Build-versus-Compose Analysis | [`build-vs-compose.schema.json`](https://evolith.dev/schema/build-vs-compose.schema.json) |
+| design | `bounded-context-map` | Bounded Context Map | [`bounded-context-map.schema.json`](https://evolith.dev/schema/bounded-context-map.schema.json) |
+| construction | `definition-of-done-checklist` | Definition of Done Checklist | [`definition-of-done-checklist.schema.json`](https://evolith.dev/schema/definition-of-done-checklist.schema.json) |
+| qa | `test-summary-report` | Test Summary Report | [`test-summary-report.schema.json`](https://evolith.dev/schema/test-summary-report.schema.json) |
+| qa | `security-scan-result` | Security Scan **Report** | [`security-scan-report.schema.json`](https://evolith.dev/schema/security-scan-report.schema.json) |
+| qa | *(sin clase en el catálogo)* | Integration Evidence | [`integration-evidence.schema.json`](https://evolith.dev/schema/integration-evidence.schema.json) |
+| release | `release-notes` | Release Notes | [`release-notes.schema.json`](https://evolith.dev/schema/release-notes.schema.json) |
+| release | `observability-readiness` | Observability **Validation** | [`observability-validation.schema.json`](https://evolith.dev/schema/observability-validation.schema.json) |
+| release | `rollback-plan` | Rollback **Procedure** | [`rollback-rehearsal.schema.json`](https://evolith.dev/schema/rollback-rehearsal.schema.json) |
+| release | *(sin clase en el catálogo)* | On-Call Handoff | [`on-call-handoff.schema.json`](https://evolith.dev/schema/on-call-handoff.schema.json) |
+
+Tres filas merecen atención en vez de un mapeo silencioso:
+
+- **`security-scan-result` ⇄ Security Scan Report**, **`rollback-plan` ⇄ Rollback Procedure** y
+ **`observability-readiness` ⇄ Observability Validation** son el mismo artefacto con nombres
+ distintos. Una herramienta que emparejara por slug fallaría en los tres.
+- **Integration Evidence** y **On-Call Handoff** tienen esquema aguas arriba y **ninguna clase en el
+ catálogo del Tracker**. Se listan igualmente, porque quien los busque debe enterarse de que
+ existen en vez de concluir que no.
+
+## Los artefactos que no tienen esquema, y por qué
+
+Diez de los veinticuatro no están cubiertos, y se dividen en dos grupos que piden respuestas
+distintas.
+
+**Tres son salida de herramienta, y a propósito no llevan esquema de Evolith** — declaran
+`producedBy` en su lugar:
+
+| Artefacto | Lo emite |
+|---|---|
+| CI Pipeline | el registro nativo de ejecución del proveedor de CI |
+| Coverage Report | `cobertura` / `lcov` / `jacoco` |
+| Pyramid Distribution | derivado del reporter de tests |
+
+Inventarles una forma canónica sería repetir lo que la herramienta ya publica, forzar una traducción
+con pérdida, y quedar obsoleto el día que la herramienta cambie.
+
+**Siete no tienen esquema todavía:** MoSCoW Prioritization Matrix, ADR Registry, Reference Blueprint
+Alignment, Simplicity Checklist Phase 1, Documentation Delta, Acceptance Validation y Deployment
+Evidence.
+
+`adr.schema.json` **no** se cablea a *ADR Registry* aunque los nombres lo inviten: un registro es una
+*lista* de ADRs y no un ADR, así que la correspondencia daría una validación que falla contra el
+artefacto real — cobertura en el papel, falso negativo en la práctica.
+
+Donde no hay esquema, la forma es la que diga el `ArtifactFieldSchema` del tenant, y nada de aguas
+arriba la contradice.
\ No newline at end of file
diff --git a/docs/artifacts/CORE_ARTIFACT_SCHEMAS.md b/docs/artifacts/CORE_ARTIFACT_SCHEMAS.md
new file mode 100644
index 00000000..bd18c873
--- /dev/null
+++ b/docs/artifacts/CORE_ARTIFACT_SCHEMAS.md
@@ -0,0 +1,90 @@
+# Canonical artifact schemas published by Evolith Core
+
+> **Bilingual Navigation:** English (this document) · [Versión en Español](./CORE_ARTIFACT_SCHEMAS.es.md)
+
+`PhaseArtifactCatalog` tells a tenant that a `prd` is **required** in discovery. Until now it did
+not tell anybody **what a PRD is supposed to contain**, because the catalog carries only
+`ArtifactKind`, `Label` and `Required` — no reference to the canonical shape. This document is that
+missing link (`GAP-020`).
+
+## What this is, and what it is not
+
+It **is** a pointer to the shape the Core publishes for an artifact, so that someone filling one in
+can see the canonical fields.
+
+It is **not** a constraint on what a tenant may record. Per [`T-056`](../adrs/T-056-three-layer-separation.md),
+content validation is the tenant's configuration and not engine code: the custom fields a tenant
+adds through `ArtifactFieldSchema` remain theirs, and the evidence item types they declare
+(`ci-result`, `regression`, `release-notes`) are not drawn from any closed upstream list.
+
+## Why the link is a URL and not a path
+
+The Core's gate definitions carry `requiredArtifacts[].schemaRef` as a repo-relative path. Those
+paths were **broken** until `evolith_arch32#378`: written `../schema/prd.schema.json`, they resolved
+from the gates directory to `reference/governance/sdlc/schema/`, a directory that does not exist,
+while the files live in `src/rulesets/schema/`. Nobody could dereference them, upstream included.
+
+They are correct now, and this document still links by **`$id`** rather than by path — deliberately.
+A path is a fact about where a file sits in one repository at one moment; the `$id` is the schema's
+own published identity and survives the file being moved. A satellite that linked by path would break
+the next time the Core reorganised its tree.
+
+## The artifacts that have a canonical schema
+
+**Fourteen** of the Core's twenty-four required artifacts publish one. The Tracker kind is given because the
+names do **not** match mechanically — the correspondence is a decision, written down here rather
+than derived from a slug.
+
+| Phase | Tracker kind | Core artifact | Canonical schema |
+|---|---|---|---|
+| discovery | `prd` | PRD | [`prd.schema.json`](https://evolith.dev/schema/prd.schema.json) |
+| discovery | *(no catalog kind)* | Discovery Canvas | [`discovery-canvas.schema.json`](https://evolith.dev/schema/discovery-canvas.schema.json) |
+| discovery | `technical-feasibility-canvas` | Technical Feasibility Canvas | [`technical-feasibility.schema.json`](https://evolith.dev/schema/technical-feasibility.schema.json) |
+| discovery | *(no catalog kind)* | Ballpark Estimation | [`ballpark-estimation.schema.json`](https://evolith.dev/schema/ballpark-estimation.schema.json) |
+| discovery | `build-versus-compose-analysis` | Build-versus-Compose Analysis | [`build-vs-compose.schema.json`](https://evolith.dev/schema/build-vs-compose.schema.json) |
+| design | `bounded-context-map` | Bounded Context Map | [`bounded-context-map.schema.json`](https://evolith.dev/schema/bounded-context-map.schema.json) |
+| construction | `definition-of-done-checklist` | Definition of Done Checklist | [`definition-of-done-checklist.schema.json`](https://evolith.dev/schema/definition-of-done-checklist.schema.json) |
+| qa | `test-summary-report` | Test Summary Report | [`test-summary-report.schema.json`](https://evolith.dev/schema/test-summary-report.schema.json) |
+| qa | `security-scan-result` | Security Scan **Report** | [`security-scan-report.schema.json`](https://evolith.dev/schema/security-scan-report.schema.json) |
+| qa | *(no catalog kind)* | Integration Evidence | [`integration-evidence.schema.json`](https://evolith.dev/schema/integration-evidence.schema.json) |
+| release | `release-notes` | Release Notes | [`release-notes.schema.json`](https://evolith.dev/schema/release-notes.schema.json) |
+| release | `observability-readiness` | Observability **Validation** | [`observability-validation.schema.json`](https://evolith.dev/schema/observability-validation.schema.json) |
+| release | `rollback-plan` | Rollback **Procedure** | [`rollback-rehearsal.schema.json`](https://evolith.dev/schema/rollback-rehearsal.schema.json) |
+| release | *(no catalog kind)* | On-Call Handoff | [`on-call-handoff.schema.json`](https://evolith.dev/schema/on-call-handoff.schema.json) |
+
+Three rows deserve attention rather than a silent mapping:
+
+- **`security-scan-result` ⇄ Security Scan Report**, **`rollback-plan` ⇄ Rollback Procedure** and
+ **`observability-readiness` ⇄ Observability Validation** are the same artifact under different
+ names. A tool that matched by slug would miss all three.
+- **Integration Evidence** and **On-Call Handoff** have an upstream schema and **no kind in the
+ Tracker's catalog**. They are listed anyway, because a reader looking for them should find out
+ they exist rather than conclude they do not.
+
+## The artifacts that have no schema, and why
+
+Ten of the twenty-four are not covered, and they split into two groups that call for different
+answers.
+
+**Three are tool output, and deliberately have no Evolith schema** — they declare `producedBy`
+instead:
+
+| Artifact | Emitted by |
+|---|---|
+| CI Pipeline | the CI provider's native run record |
+| Coverage Report | `cobertura` / `lcov` / `jacoco` |
+| Pyramid Distribution | derived from the test reporter |
+
+Inventing a canonical shape for these would restate what the tool already publishes, force a lossy
+translation, and rot the day the tool changes.
+
+**Seven have no schema yet:** MoSCoW Prioritization Matrix, ADR Registry, Reference Blueprint
+Alignment, Simplicity Checklist Phase 1, Documentation Delta, Acceptance Validation and Deployment
+Evidence.
+
+`adr.schema.json` is **not** wired to *ADR Registry* even though the names invite it: a registry is a
+*list* of ADRs and not an ADR, so the mapping would produce a validation that fails against the real
+artifact — coverage on paper, a false negative in practice.
+
+Where there is no schema, the shape is whatever the tenant's `ArtifactFieldSchema` says, and nothing
+upstream contradicts it.
\ No newline at end of file
diff --git a/docs/audit/tracker-gaps-opportunities-tracking.md b/docs/audit/tracker-gaps-opportunities-tracking.md
index fe9e3727..75db4800 100644
--- a/docs/audit/tracker-gaps-opportunities-tracking.md
+++ b/docs/audit/tracker-gaps-opportunities-tracking.md
@@ -420,7 +420,12 @@ This document is the only operational gap register in this repository. The maste
- **Criticality:** 🟡 MEDIUM
- **Complexity:** 🟡 MEDIUM
- **Description:** Artifact Schema URLs from Core Missing
-- **Next Step:** Define owner and remediation action before execution.
+- **Scope, established 2026-08-01 (the row had none — its next step said "define owner and remediation action before execution", and nobody ever had):** `PhaseArtifactCatalog` carries `ArtifactKind`, `Label` and `Required`, and **no schema reference at all**. So a consumer of `PhaseArtifactProfileDto` learns that a `prd` is required in discovery and has no way to find out what a PRD is supposed to contain.
+- **What the Core actually publishes:** its gate definitions (`reference/governance/sdlc/gates/gate-f*.json`) declared `requiredArtifacts[].schemaRef` for **10 of 24** required artifacts when this row was scoped; `evolith_arch32#378` took that to **14**, declared 3 more as tool output (`producedBy`) and left 7 uncovered — `PRD`, `Technical Feasibility Canvas`, `Build-versus-Compose Analysis`, `Test Summary Report`, `Security Scan Report`, `Integration Evidence`, `Release Notes`, `Observability Validation`, `Rollback Procedure` and `On-Call Handoff`. The other 14 have no schema upstream, so there is nothing to link and this row must not pretend otherwise.
+- **Upstream defect found while scoping this (belongs to the Core, not here):** those `schemaRef` values are **broken relative paths**. `../schema/prd.schema.json` resolves from the gates directory to `reference/governance/sdlc/schema/`, which does not exist; the files actually live in `src/rulesets/schema/`. So the refs cannot be dereferenced as paths by anybody. What IS stable and usable is each schema's public `$id` — `https://evolith.dev/schema/prd.schema.json` and peers — and that is what this satellite links to.
+- **Naming does not match, and mapping by string would be wrong:** the Tracker's kinds and the Core's artifact names agree for some (`prd`, `release-notes`, `test-summary-report`) and diverge for others (`security-scan-result` vs `Security Scan Report`, `rollback-plan` vs `Rollback Procedure`, `observability-readiness` vs `Observability Validation`). The correspondence is a decision, not a transformation, so it is written down explicitly rather than derived from a slug.
+- **Deliberately NOT in scope: coupling the vocabularies.** Forcing the Tracker's artifact kinds — or the tenant-declared evidence item types (`ci-result`, `regression`, `release-notes`) — into a closed Core-published list is precisely what `T-056` refuses: content validation is the tenant's configuration, not engine code. This row links to the canonical shape; it does not make the Core the authority over what a tenant may record.
+- **Next Step:** DONE — `docs/artifacts/CORE_ARTIFACT_SCHEMAS.md` links the 14 artifacts that have an upstream schema to its published `$id`, lists the 3 that are tool output, and names the 7 that have none. The broken paths were fixed upstream in the same wave.
[Back to master register](#master-register)
diff --git a/src/apps/tracker-api/Tracker.Application/Governance/ArtifactFieldSchema/PhaseArtifactCatalog.cs b/src/apps/tracker-api/Tracker.Application/Governance/ArtifactFieldSchema/PhaseArtifactCatalog.cs
index ce838004..88d3fd43 100644
--- a/src/apps/tracker-api/Tracker.Application/Governance/ArtifactFieldSchema/PhaseArtifactCatalog.cs
+++ b/src/apps/tracker-api/Tracker.Application/Governance/ArtifactFieldSchema/PhaseArtifactCatalog.cs
@@ -6,6 +6,14 @@ namespace Tracker.Application.Governance.ArtifactFieldSchema;
/// Registry in Design, …). This is READ-ONLY for a tenant: required artifacts cannot be removed;
/// the tenant configures custom fields per artifact (via ArtifactFieldSchema keyed by the
/// artifact kind) and — for optional artifacts — their applicability.
+///
+/// GAP-020 — este catálogo dice que un `prd` es obligatorio y NO dice qué debe contener. La
+/// forma canónica, para los 10 de 24 artefactos que la tienen aguas arriba, está enlazada en
+/// docs/artifacts/CORE_ARTIFACT_SCHEMAS.md. No se enlaza desde aquí como dato porque los
+/// nombres no coinciden mecánicamente (`security-scan-result` ⇄ Security Scan Report,
+/// `rollback-plan` ⇄ Rollback Procedure) y la correspondencia es una decisión escrita, no una
+/// transformación de cadena — y porque el `schemaRef` que publican los gates del Core es una ruta
+/// relativa ROTA: resuelve a un directorio que no existe.
///
public static class PhaseArtifactCatalog
{