> ## 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.

# Enmienda A1 de la constitución — Categorías de puerto, binding por módulo, estándares nuevos

> Agrega QueuePort y NotificationChannelPort a la lista cerrada de categorías de puerto, y fija el binding de adaptadores por módulo en el composition root.

> Traducción. Autoritativo:
> [`../../constitution/amendment-A1-ports-and-standards.md`](/constitution/amendment-A1-ports-and-standards).

Estado: PROPUESTA (requiere la aprobación línea por línea de Daniel antes de tocar el CLAUDE.md raíz)
Fecha: 2026-08-15 · Referencias: DEC-C3, DEC-C4, DEC-E1..E8, ADR-19

## Justificación

Los módulos Engage/CRM introducen dos preocupaciones de infraestructura que las seis categorías de
puerto actuales no cubren: colas de jobs y canales de notificación. Según la constitución, los
puertos existen solo para categorías nombradas; por lo tanto, la lista debe enmendarse antes de que
cualquier agente pueda definir estas interfaces.

## Cambio 1 — Agregar dos categorías de puerto (editar la sección "Ports" del CLAUDE.md raíz)

Agregar a la lista cerrada de categorías permitidas:

7. **QueuePort** — publicación asíncrona de jobs.
   * Contrato (packages/core): `publish(queue, payload, opts)`, `schedule(queue, payload, runAt)`.
   * Los consumidores DEBEN seguir `/docs/standards/jobs.md` (idempotencia vía `core.processed_jobs`,
     política de reintentos, dead letters).
8. **NotificationChannelPort** — entrega saliente por un canal.
   * Contrato (packages/core): `send(recipient, renderedContent, opts) -> ProviderResult`.
   * Un adaptador por canal (ResendEmailAdapter, FcmPushAdapter, InAppAdapter, WebhookAdapter;
     SmsAdapter llega en F1b tras su ADR).
   * La resolución de canal NUNCA es trabajo del adaptador: los adaptadores entregan;
     `/docs/standards/notifications.md` gobierna el enrutamiento.

## Cambio 2 — Regla nueva: binding de adaptador por módulo (agregar como R21)

**R21.** La arquitectura hexagonal aplica a todo el proyecto SIN EXCEPCIÓN. Los bindings de adaptador
se declaran exclusivamente en el composition root de cada módulo (`makeDeps(ctx)`); el código de
dominio y de aplicación DEBE depender solo de puertos. Módulos distintos PUEDEN vincular adaptadores
distintos para el mismo puerto (por ejemplo, messaging sobre QStash mientras loyalty sigue en Vercel
Queues) con la justificación registrada en el spec del módulo. Introducir un vendor o dependencia
NUEVA para cualquier adaptador sigue exigiendo un ADR antes del primer import (regla existente sin
cambios). Binding por defecto para todos los módulos en F1: Vercel Queues (QueuePort); Resend, FCM,
in-app y webhook (NotificationChannelPort).

## Cambio 3 — Registrar estándares nuevos y actualizados (editar el índice de estándares del CLAUDE.md raíz)

* AGREGAR: `/docs/standards/notifications.md` (resolución de canal en cascada, prioridades,
  trazabilidad).
* ACTUALIZADOS (mayor): `data.md` (tablas paramétricas, dinero, particionamiento, clasificación de
  datos), `events.md` (correlación), `jobs.md` (colas y workers), `api.md` (rutas por módulo, nombres
  de permisos), `security.md` (roles de máquina, manejo de `national_id`).

## No-cambios (explícito)

* Las seis categorías de puerto existentes no cambian.
* R1–R20 no cambian.
* La regla de stack cerrado no cambia; esta enmienda NO agrega dependencias.
