131 lines
7.9 KiB
Markdown
131 lines
7.9 KiB
Markdown
# CLAUDE.md — Reglas del proyecto
|
|
|
|
> Este archivo lo carga el agente (Claude Code) por defecto. Contiene lo que aplica a **TODO** el
|
|
> proyecto: reglas no negociables, decisiones ya tomadas, política de iniciativa y verificaciones
|
|
> pre-entrega. El agente NO puede re-decidir lo que está acá. (Patrón B.4.)
|
|
|
|
---
|
|
|
|
## Identidad del proyecto
|
|
|
|
Plataforma de encuestas con soberanía de datos. Caso fundacional: mapeo de cuidadores en empresas.
|
|
Objetivo macro: "economía de la discapacidad" en Paraguay. Trata **datos sensibles** (salud/
|
|
discapacidad) → la privacidad no es una feature, es una restricción de diseño.
|
|
|
|
---
|
|
|
|
## Reglas no negociables (datos y privacidad)
|
|
|
|
1. **Anonimato es por-encuesta**, no global. Cada encuesta declara su modo; el esquema y la lógica
|
|
de guardado lo respetan. Nunca asumir anonimato por defecto ni quitarlo por conveniencia.
|
|
2. **En encuestas anónimas, NUNCA escribir una clave de individuo** (`respondent_id`) ni cookie de
|
|
sesión linkeable. La deduplicación se hace con `ip_hash` (hash unidireccional + salt), nunca con
|
|
identidad.
|
|
3. **El umbral de k-anonimato es mandatorio en toda visualización compartida.** Ninguna celda,
|
|
gráfico o tabla expuesta a una empresa puede mostrar un segmento con **n < UMBRAL_K** (config del
|
|
proyecto, default 5). Esto aplica AUNQUE la encuesta sea anónima.
|
|
4. **El texto libre NO entra al store analítico crudo.** Se excluye o se categoriza antes (es un
|
|
vector de re-identificación). El gráfico/reporte trabaja sobre categorías, no sobre texto crudo.
|
|
5. **El consentimiento es evidencia, no UI.** Cada respuesta guarda un registro de consentimiento
|
|
versionado, con timestamp, inmutable, contra la versión del texto vigente al momento. Cambiar el
|
|
wording del consentimiento NO altera registros viejos. (Ver ADR-003.)
|
|
6. **La elección granular del titular (el respondente) siempre gana** sobre cualquier documento
|
|
firmado por la empresa. La empresa autoriza el despliegue; el individuo consiente el tratamiento
|
|
de su propio dato.
|
|
7. **Modo de responsable (`controller_role`) define el flujo de datos:**
|
|
- **Modo A** (nosotros = responsable): el dato puede alimentar el macro a todos los niveles que el
|
|
titular consintió.
|
|
- **Modo B** (empresa = responsable, nosotros = encargado): el dato **solo** puede alimentar el
|
|
macro vía **Nivel 1 anonimizado irreversible**. Nunca Nivel 2/3.
|
|
- **v1 corre solo Modo A.** El campo existe pero la lógica dual no se construye todavía.
|
|
8. **La empresa nunca accede a dato individual crudo.** Solo recibe agregados/dashboards autorizados
|
|
por encima del umbral. (Coherente con Modo A + k-anonimato.)
|
|
9. **Manejo de API keys de Supabase — transversal y crítico.** La `anon` key es pública y **respeta
|
|
RLS**: es la única que puede tocar el frontend/cliente. La `service_role` key **bypassa RLS por
|
|
completo** y por lo tanto saltea k-anonimato, consentimiento y todo el modelo de ADR-001. Reglas:
|
|
- La `service_role` **NUNCA** va al frontend, al cliente, a un artefacto público ni a git. Solo
|
|
vive server-side (Edge Functions / backend), cargada desde variable de entorno.
|
|
- `.env` y `.env.*` siempre en `.gitignore`. Una `service_role` en el historial de git es un
|
|
incidente de seguridad aunque el repo sea privado → rotar la key de inmediato.
|
|
- Toda operación de cara al respondente o a la empresa usa `anon` key + RLS. Si algo "necesita"
|
|
`service_role` para funcionar en el cliente, está mal diseñado: revisar las policies, no exponer
|
|
la key.
|
|
10. **El flujo del respondente NUNCA se ata a un IdP / SSO.** Encuestas anónimas = sin login, sin
|
|
Keycloak, sin cookie de sesión identificable. El SSO (Keycloak) es solo para staff interno. RLS
|
|
lee claims por nombre (`org_id`, `role`) para que el emisor del token sea intercambiable; nunca
|
|
basar RLS en `user_metadata` (modificable por el usuario). (Ver ADR-004.)
|
|
|
|
---
|
|
|
|
## Distinción que NO se puede volver a confundir: anónimo vs pseudónimo
|
|
|
|
- **Comparar segmentos** ("alguien de 25, sector X, zona A" vs "alguien de 25, sector X, zona B") se
|
|
hace con los **cuasi-identificadores guardados en cada fila**. NO requiere `respondent_id`. Vive en
|
|
datos 100% anónimos.
|
|
- **`respondent_id`** (clave pseudónima) sirve para vincular varias respuestas a la **misma persona
|
|
desconocida** (longitudinal individual, re-contacto, dedup avanzado). **Nada de eso es caso de v1.**
|
|
- Por lo tanto: anónimo a nivel respondente **alcanza** para la comparación que el producto necesita.
|
|
La comparación individuo-vs-individuo (n=1) está **prohibida** en dashboards compartidos.
|
|
|
|
---
|
|
|
|
## Política de iniciativa proactiva (clasificar antes de actuar)
|
|
|
|
Ante una mejora fuera del scope, el agente clasifica el impacto y actúa según el nivel. Evaluar en
|
|
este orden; el primero que aplique decide:
|
|
|
|
1. ¿Resuelve un ítem de `TECH_DEBT.md` / `BACKLOG.md` / planificación? → **Nivel 3**.
|
|
2. ¿Choca con restricción explícita del prompt ("NO entra", "NO tocar", "agendado para etapa Z")? → **Nivel 3**.
|
|
3. ¿Toca privacidad, anonimato, consentimiento, clasificación de datos o RLS? → **Nivel 3 SIEMPRE**.
|
|
4. ¿Modifica paginación, layout, cantidad de archivos o estructura de salida? → **Nivel 2 mínimo**.
|
|
5. ¿Es visible al usuario final (texto, color, posición, contenido)? → **Nivel 2 mínimo**.
|
|
6. ¿Afecta marca, identidad, dependencias o configuración? → **Nivel 3**.
|
|
7. Si nada aplica → **Nivel 1**.
|
|
|
|
- **Nivel 1** (interno, invisible, reversible): ejecutar; mencionar al final si fueron varios.
|
|
- **Nivel 2** (visible reversible): ejecutar **y reportar** como "decisión proactiva — validar/revertir".
|
|
- **Nivel 3** (marca/arquitectura/datos/privacidad): **NO ejecutar. Consultar antes** con el formato:
|
|
```
|
|
PROPUESTA DE CAMBIO NIVEL 3 — requiere aprobación
|
|
Cambio sugerido: [descripción] Justificación: [por qué] Impacto: [qué afecta] Alternativa si se rechaza: [qué hacer]
|
|
```
|
|
|
|
Argumentos que NO bajan de nivel: "es legibilidad", "es consistencia", "es trivial de revertir",
|
|
"es un bug menor", "el usuario lo va a agradecer". Si está en TECH_DEBT/BACKLOG, es Nivel 3 sin
|
|
importar el tamaño técnico.
|
|
|
|
---
|
|
|
|
## Verificaciones obligatorias antes de entregar (toda etapa)
|
|
|
|
1. `git diff --name-only HEAD` → solo archivos autorizados por el prompt. Si aparece uno no
|
|
autorizado: revertir (`git checkout HEAD -- <archivo>`), listar bajo "Conflictos de scope", no incluirlo.
|
|
2. Si una restricción del prompt (`NO tocar X`) colisiona con otro requisito (build limpio):
|
|
**DETENERSE y reportar el conflicto**, no resolver unilateralmente.
|
|
3. Reporte con **datos concretos**, no descripciones ("PDF: 78 KB, 4 págs, tabla 11 filas",
|
|
no "PDF generado correctamente").
|
|
4. Separar explícitamente **Verificado** vs **Asumido** vs **Hallazgos no esperados**.
|
|
5. Tests verdes **NO** es etapa terminada. Si hay artefacto visible, el humano lo abre (validación
|
|
visual la hace el director, no el agente).
|
|
|
|
---
|
|
|
|
## Decisiones ya tomadas (no consultar de nuevo)
|
|
|
|
- Etapa 1 = una encuesta fija (mapeo cuidadores) multi-empresa. **NO** builder visual.
|
|
- Las 4 encuestas de v1: anónimas a nivel respondente + confidenciales (seguridad).
|
|
- Se conservan `company_id` + cuasi-identificadores. NO se usa `respondent_id`.
|
|
- Modo A (nosotros responsables). Sin Nivel 3 atribuible en esta etapa.
|
|
- Empresas actúan sobre agregados, nunca sobre individuos nombrados.
|
|
- Dedup por `ip_hash`. Consentimiento granular versionado e inmutable.
|
|
- Umbral de k-anonimato default = 5 (parametrizable por proyecto).
|
|
- Separador de miles y formato de cifras: **definir en `CONVENTIONS.md`** (ver Decisiones abiertas).
|
|
|
|
---
|
|
|
|
## Decisiones abiertas (requieren al director, no las cierra el agente)
|
|
|
|
- **Nombre/marca del producto** (Nivel 3).
|
|
- **Residencia de datos**: Supabase Cloud vs self-host (ADR-002).
|
|
- **`CONVENTIONS.md`**: formato de cifras, idioma de la UI, tono de los mensajes. Apenas una
|
|
convención se pregunte 2 veces, documentarla acá (anti-patrón AP.4). |