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

# Constitución fundacional — RECONSTRUCCIÓN PARA VALIDAR

> Este documento es una reconstrucción, no un original recuperado. La sesión fundacional que produjo las reglas R1–R20 y las seis categorías de puerto no está en este repositorio.

> Traducción. Autoritativo:
> [`../../constitution/founding-constitution.md`](/constitution/founding-constitution).
>
> ⚠️ **Este documento es una reconstrucción, no un original recuperado.**
>
> La sesión fundacional que produjo las reglas R1–R20 y las seis categorías de puerto no está en este
> repositorio. La enmienda A1, los estándares y todo ADR desde el 009 las referencian, así que el
> hueco bloquea TS-002 y la propia enmienda.
>
> Daniel pidió un borrador para validar en vez de un hueco esperando. Por eso cada regla lleva una
> etiqueta con su procedencia, para que la revisión sea rápida donde es segura y lenta donde no:
>
> | Etiqueta        | Significa                                                                              | Cómo revisarla                                              |
> | --------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
> | **\[derived]**  | Enunciado o implicado directamente por material que tenemos                            | Confírmalo contra tu memoria                                |
> | **\[inferred]** | Deducido del stack, de cómo se redactan otras reglas, o de una regla que la referencia | **Léela con cuidado** — acá es donde puedo estar equivocado |
> | **\[proposed]** | Un hueco que llené con criterio. Sin evidencia en ningún sentido                       | **Decide** — acepta, cambia o borra                         |
>
> Nada de esto es vinculante hasta que lo valides. Cuando lo hagas, el contenido de la Parte 1 se muda
> a `AGENTS.md` y este documento queda como el registro de cómo llegó ahí.

Estado: **RECONSTRUCCIÓN PROPUESTA** · Fecha: 2026-08-17 · Valida: `AGENTS.md` §9

***

## Parte 1 — Las reglas

### Arquitectura

**R1. Arquitectura hexagonal, sin excepción.** \[derived]
El código de dominio y de aplicación depende de puertos. Un SDK de vendor importado fuera de un
adaptador es un defecto. *(Reenunciada y extendida por R21 en la enmienda A1, que es en sí evidencia
de que R1 existe en esta forma.)*

**R2. Los puertos existen solo para categorías nombradas.** \[derived]
La lista es cerrada. Inventar una categoría exige una enmienda de constitución revisada línea por
línea por el owner. *(La enmienda A1 existe precisamente porque esta regla hacía imposible agregar
`QueuePort` de otro modo.)*

**R3. Los bindings de adaptador se declaran en un composition root.** \[derived]
El `makeDeps(ctx)` de cada módulo es el único lugar donde un puerto se vincula a un adaptador.
*(Nombrado explícitamente en la R21 de la enmienda A1.)*

**R4. Un vendor o dependencia nueva exige un ADR antes de su primer import.** \[derived]
El stack es cerrado por defecto. *(Referenciado repetidamente en el material como "la regla de stack
cerrado".)*

**R5. El monorepo es la unidad de entrega.** \[inferred]
Un repositorio, un lockfile, una versión. Los imports entre proyectos van por paquetes del workspace,
nunca por rutas relativas que crucen límites.

### Multi-tenancy y datos

**R6. Toda tabla con alcance de tenant lleva `tenant_id` y `cell_id`.** \[derived]
`cell_id` es la costura para el particionamiento regional futuro; está presente desde la primera
migración y sin uso hasta que llegue multi-región.

**R7. La row-level security es obligatoria en toda tabla con alcance de tenant.** \[derived]
La RLS no es defensa en profundidad sobre las verificaciones de aplicación — es el límite. Un bug de
aplicación no debe poder cruzar un tenant.

**R8. El acceso a la base va solo por `getDb(tenantCtx)`.** \[derived]
No hay camino a una conexión que no lleve un contexto de tenant. *(Nombrado textualmente en
`standards/data.md`.)*

**R9. La unicidad sobre datos con alcance de tenant siempre incluye `tenant_id`.** \[derived]
Agregada a `standards/data.md` §2b el 2026-08-17. Va listada acá porque pertenece con R6–R8 y quien
lea en el futuro debería encontrar juntas las reglas de tenancy.

**R10. Nunca un enum de Postgres para un valor de negocio.** \[derived]
Los conjuntos cerrados viven en tablas paramétricas con un `code` estable. *(`standards/data.md` §2.)*

**R11. Nunca un monto monetario sin su moneda.** \[derived]
`amount` BIGINT en unidades menores más `currency_code`. Nunca floats. *(`standards/data.md` §3.)*

### Comandos, eventos y estado

**R12. Un comando, una transacción.** \[derived]
El cambio de estado, el evento del outbox y la fila de auditoría confirman juntos o no confirman.
*(ADR-017 ratifica esto como CQRS-lite, lo que implica que la regla lo precede.)*

**R13. Los eventos de dominio salen solo por el outbox transaccional.** \[derived]
La publicación directa está prohibida. *(`standards/events.md`.)*

**R14. Las lecturas son proyecciones con procedimiento de reconstrucción documentado.** \[derived]
Una proyección que no se puede reconstruir es una segunda fuente de verdad. *(ADR-017.)*

**R15. Todo cambio de estado queda auditado con actor tipado y diff completo.** \[derived]
*(`standards/data.md` §7, DEC-C2.)*

### API y acceso

**R16. Cada endpoint declara exactamente un permiso.** \[derived]
`{module}.{resource}.{action}`. Los permisos se agrupan en roles; los roles se asignan a usuarios y a
máquinas. *(DEC-D5, `standards/api.md`.)*

**R17. Nuestras propias superficies consumen solo la API pública.** \[derived]
Consola, portal, widget y mobile van por `packages/api-client`. Si nuestra UI necesita algo que la API
no tiene, la API está incompleta. *(Llamada "la regla de oro" en `standards/api.md`; DEC-F5.)*

**R18. Los presupuestos de latencia son ítems del Definition of Done.** \[derived]
No son objetivos ni aspiraciones. Se verifican con tests de carga en certificación. *(DEC-D7.)*

### Proceso

**R19. La documentación es parte del cambio.** \[inferred]
Tocar un schema o un endpoint sin actualizar su spec es un cambio incompleto. Una decisión nueva va a
un ADR, no a un comentario en el código.

**R20. Las stop conditions son vinculantes.** \[inferred]
Cuando una tarea exige una decisión no cubierta por un DEC, un estándar o un ADR, el agente se detiene
y pregunta. No elige y sigue.

**R21. Binding de adaptador por módulo.** \[enmienda A1 — pendiente de tu aprobación]
Módulos distintos pueden vincular adaptadores distintos para el mismo puerto, con la justificación en
el spec de ese módulo.

***

## Parte 2 — Las seis categorías de puerto

> ⚠️ **Esta es la parte más débil de la reconstrucción.** La enmienda A1 nos dice que son exactamente
> seis y que las colas no estaban entre ellas. No nos dice cuáles son. Lo que sigue está deducido de
> los vendors que la suite ya usa y de para qué necesitaría existir un puerto. Trata cada línea como
> una pregunta.

| # | Categoría             | Contrato                                                           | Adaptadores que el stack implica | Confianza                                                                                                                                              |
| - | --------------------- | ------------------------------------------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | **StoragePort**       | `put(path, bytes, opts)`, `get(path)`, `signedUrl(path, ttl)`      | Supabase Storage                 | **\[inferred]** — los exports de retención escriben NDJSON en Storage, y ese camino pasa por algo                                                      |
| 2 | **RealtimePort**      | `publish(canal, evento, payload)`, `authorize(canal, sujeto)`      | Pusher                           | **\[inferred]** — Pusher aparece en la lista de subencargados y en la de consumidores del outbox                                                       |
| 3 | **CachePort**         | `get`, `set`, `del`, `incr`, token buckets                         | Upstash Redis                    | **\[inferred]** — rate limiting, cachés de reglas compiladas y de catálogos nombran todos a Upstash                                                    |
| 4 | **PaymentPort**       | `charge(monto, moneda, método)`, `refund`, verificación de webhook | Fintoc, Paddle                   | **\[inferred]** — DEC-G4 nombra a ambos tras un rating engine, que es como se ve un puerto                                                             |
| 5 | **ObservabilityPort** | `log`, `metric`, `span`, todos con `tenant_id` y `correlation_id`  | BetterStack, Vercel              | **\[inferred]** — y `packages/observability` se especificó como puerto exactamente por esto                                                            |
| 6 | **InvoicingPort**     | `issue(tipoDocumento, líneas)`, `void`, poll de estado             | LibreDTE para el SII             | **\[proposed]** — LibreDTE aparece en DEC-G4, pero si se ganó una categoría de puerto o vive dentro del adaptador de pagos es genuinamente desconocido |

**Las categorías 7 y 8** — `QueuePort` y `NotificationChannelPort` — vienen de la enmienda A1 y no
están en cuestión.

### Lo que no pude determinar

* Si el **acceso a la base de datos** es una categoría de puerto o está deliberadamente excluido. El
  `getDb(tenantCtx)` de R8 sugiere que la base **no** está detrás de un puerto — es una dependencia
  directa con alcance de tenant, que es una elección defendible dado que Drizzle es un query builder
  y no un SDK de vendor. **\[inferred]**
* Si la **autenticación** es un puerto. Better Auth se configura, no se llama por una interfaz, lo que
  argumenta que no. **\[inferred]**
* Si el sexto lugar es `InvoicingPort` siquiera, o algo en lo que no he pensado.

Si alguna de estas seis está mal, corregirlo ahora es barato y después de que TS-002 defina
adaptadores contra ellas es caro.

***

## Parte 3 — Lo que deliberadamente NO se reconstruye

**Estándares v1.** Seis estándares de este repositorio están marcados "v2" y dicen que enmiendan una
base v1. Propongo **declarar los v2 autocontenidos y retirar la idea de una v1** en vez de
reconstruir seis documentos más por inferencia. Ya enuncian sus reglas completas; la etiqueta "v2"
describe su historia, no una dependencia. Si recuerdas una regla de v1 que falte, agregarla al
documento v2 es un cambio de una línea.

**ADR-001 … ADR-008.** Reconstruidos como archivos separados, cada uno con el mismo etiquetado que
este documento. Ver [`../adr/`](/es/adr/overview) — numerados 001 a 008, con estado
`Propuesto (reconstrucción)`.

**El slice `createInitiative`.** Reconstruido en
[`../slices/create-initiative.md`](/es/slices/create-initiative), ya que cada task spec declara un
arquetipo y la mitad declara ese.

***

## Cómo validar esto

Lee la Parte 1 primero y detente solo en las cuatro reglas **\[inferred]** y **\[proposed]** — R5, R19,
R20 y todo lo de la Parte 2. Las **\[derived]** las puedes confirmar por reconocimiento.

Después dime, por ítem: *correcta*, *incorrecta y la real es esta*, o *nunca existió esa regla*. Todo
lo que digas que nunca fue una regla se borra en vez de conservarse "por si acaso" — una constitución
con reglas inventadas es peor que una con huecos, porque los agentes obedecen igual.

Una vez validada, la Parte 1 se muda a `AGENTS.md`, `AGENTS.md` §9 desaparece, y TS-002 se
desbloquea.

## Changelog

| Versión | Fecha      | Cambio                              | Por qué                                                                                   | Autor                  |
| ------- | ---------- | ----------------------------------- | ----------------------------------------------------------------------------------------- | ---------------------- |
| 0.1.0   | 2026-08-17 | Reconstrucción inicial para validar | El hueco bloquea TS-002 y la enmienda A1; el owner pidió un borrador en vez de una espera | daniel + claude-opus-5 |
