> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Supresión y portabilidad (derechos ARCO)

> Cuando esto se entregue, una persona podrá pedir que la borren y efectivamente ocurrirá en toda la suite, dentro de un plazo comprometido y con prueba de que ocurrió.

> Traducción. Autoritativo: [`fs-core-0014-erasure-portability.md`](/modules/core/features/fs-core-0014-erasure-portability).

## Contexto

La Ley 21.719 entra en plena vigencia el 2026-12-01, y la supresión es el derecho que más directamente
choca con cómo está construido el resto del sistema. Los libros de puntos son append-only por
integridad contable; los registros de auditoría existen precisamente para que nada desaparezca.

DEC-J3 resuelve el conflicto sin fingir que no existe: **el perfil y los eventos se borran; las filas
del libro se anonimizan a un tombstone**. La anonimización satisface el derecho —el dato deja de ser
atribuible a una persona— mientras la contabilidad queda entera. El plazo comprometido es ≤30 días y
el proceso es automatizado, porque un proceso manual es un proceso que llega tarde justo el mes en
que todos están ocupados.

La orquestación vive en core y no en cada módulo. Un solo lugar decide qué significa suprimir, y los
módulos obedecen.

## Alcance *(normativo)*

* `core.subject_requests`: solicitudes de supresión y portabilidad con su ciclo de vida.
* Orquestación de la supresión entre todos los módulos, con acuse por módulo.
* Borrado de contacto y eventos; anonimización del libro instruida a fidelización.
* Exportación de portabilidad: todo sobre el titular en un formato estructurado y de uso común.
* Prueba de ejecución retenida después de que el dato ya no está.
* El SLA de 30 días con escalamiento antes de incumplirlo.

## Fuera de alcance *(normativo)*

* Verificar la identidad del solicitante. Esa es la obligación del tenant como responsable (DEC-J1);
  nosotros ejecutamos una instrucción de un tenant autenticado.
* El formulario de solicitud para el member — `frontend/portal`.
* Borrar un tenant. Eso es offboarding, otro runbook.

## Comportamiento *(normativo)*

1. Una solicitud tiene ciclo de vida: `received → validated → executing → completed`, con timestamp en
   cada paso. La línea de tiempo es la evidencia.
2. El SLA es **≤30 días** y escala en el día 21. Descubrir un incumplimiento el día 31 es descubrirlo
   demasiado tarde.
3. La supresión se orquesta: core instruye a cada módulo y **espera su acuse**. Un módulo que no acusa
   bloquea la finalización — una supresión parcial reportada como completa es el peor resultado
   posible.
4. Por módulo: `core` borra perfil, identidades, consentimientos y eventos. `loyalty` **anonimiza**
   las filas del libro a un tombstone y no borra nada. `messaging` borra el contenido de los envíos y
   conserva los conteos agregados. `crm` borra notas y actividades.
5. Las supresiones (de envío) **sobreviven a la supresión (de datos)**, como identificador hasheado
   sin perfil asociado. Borrarlas permitiría volver a escribirle a esa dirección, que es lo contrario
   de lo que la persona pidió.
6. **La prueba de ejecución sobrevive**: una fila de auditoría registra que la supresión ocurrió, para
   quién (como referencia opaca), cuándo, y qué módulos acusaron. La prueba es lo único que debe
   sobrevivir al dato.
7. La portabilidad exporta todo sobre el titular en formato estructurado y de uso común, entregado por
   un enlace firmado que expira.
8. Una supresión es **irreversible y se confirma antes de ejecutar**. No hay deshacer, y la API lo
   dice.
9. Los respaldos vencen por su propia retención; la solicitud lo deja registrado y no afirma otra
   cosa. Prometer borrado instantáneo de los respaldos sería una promesa que no podemos sostener.

## Datos *(normativo)*

| Tabla                   | Invariantes clave                                                                                                                                                                                                                   |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `core.subject_requests` | `tenant_id`; `contact_ref` opaca tras la ejecución; `kind` erasure\|portability; `status`; `received_at`, `due_at`, `completed_at`; `module_acks` JSONB; append-only salvo transiciones de estado; retenida más allá del dato mismo |

## API *(normativo)*

| Endpoint                              | Clase      | Permiso                      | Presupuesto               |
| ------------------------------------- | ---------- | ---------------------------- | ------------------------- |
| `POST /v1/core/contacts/{id}/erasure` | Management | `core.contacts.erase`        | p95 \<1 s (asíncrono)     |
| `GET /v1/core/contacts/{id}/export`   | Management | `core.contacts.export`       | asíncrono, enlace firmado |
| `GET /v1/core/subject-requests`       | Management | `core.subject_requests.read` | p95 \<1 s                 |

## Eventos *(normativo)*

`core.contact.erased` en el outbox, para que todo consumidor —incluido el webhook del propio tenant—
descarte su copia. Un tenant que espejó nuestros contactos debe enterarse.

## Criterios de aceptación *(normativo)*

1. La supresión borra perfil, identidades, consentimientos y eventos, y deja las filas del libro
   anonimizadas con el total de puntos pendientes del programa **sin cambios**.
2. Un módulo que no acusa bloquea la finalización, y la solicitud queda en `executing`.
3. La fila de auditoría de prueba de ejecución sobrevive y nombra los módulos que acusaron.
4. Una supresión de envío sobrevive como identificador hasheado y sigue bloqueando un envío a esa
   dirección.
5. La exportación de portabilidad contiene todas las categorías listadas en el RAT y es JSON válido.
6. El enlace de exportación expira y se rechaza después.
7. El escalamiento del día 21 se dispara para una solicitud aún incompleta.
8. **Negativo:** ningún camino de supresión borra una fila del libro, y ninguna finalización se
   reporta sin el acuse de todos los módulos.

## Ejecución

Pipeline asíncrono. Orquestador en `backend/workers`, monitoreo del SLA en `backend/scheduler`. Cada
módulo expone un handler interno de supresión; core nunca entra a las tablas de otro módulo.

## Preguntas abiertas

| # | Pregunta                                                                                                 | Decide           | Para                            |
| - | -------------------------------------------------------------------------------------------------------- | ---------------- | ------------------------------- |
| 1 | ¿El tenant tiene una ventana para objetar antes de ejecutar, o la supresión es inmediata a la solicitud? | Daniel + abogado | antes del lanzamiento comercial |
| 2 | ¿Cuánto retenemos `subject_requests` tras completarse — hay máximo, o es para siempre?                   | Daniel + abogado | antes del lanzamiento comercial |

## Changelog

| Versión | Fecha      | Cambio           | Por qué | Autor                  |
| ------- | ---------- | ---------------- | ------- | ---------------------- |
| 0.1.0   | 2026-08-17 | Borrador inicial | —       | daniel + claude-opus-5 |

## Registro de entrega

*Aún no implementado.*
