Appearance
ANEXO DE GOBERNANZA — SQL CONTRA EL ESQUEMA REAL Y SMOKE DE RITUALES
(Vigente a partir de hoy, en TODOS los turnos)
Contexto e Incidente Origen
El Ritual 6 reescribió convert_demo_to_full_license usando columnas inexistentes (estado, fecha_inicio, fecha_expiracion, duracion_meses, historial) — la función real y funcional quedó rota en producción y requirió restauración de emergencia. Antes hubo otro incidente del mismo tipo (PGRST204 por columnas ficticias en el fix ANTISANA). Esta regla hace ese patrón estructuralmente imposible.
REGLA 1 — ESQUEMA REAL ES LA ÚNICA FUENTE DE VERDAD
Prohibido escribir CREATE OR REPLACE, UPDATE, INSERT o ALTER contra columnas inferidas, recordadas, o leídas de DDL/migraciones del repo. Toda columna referenciada en SQL destinado al operador DEBE estar verificada contra el esquema REAL (output de information_schema del operador, o mapeos vigentes que el operador haya validado en producción). Si no tienes el esquema real de una tabla: DETENTE y pídelo — jamás lo inventes ni lo deduzcas.
REGLA 2 — FUNCIONES EXISTENTES SE MODIFICAN, NO SE REESCRIBEN
Si tu turno toca una función existente (agregar reset, guard, columna nueva): NO la reescribas desde cero contra tu idea del esquema. Pide al operador el cuerpo actual:
sql
SELECT pg_get_functiondef('nombre_funcion(tipos)'::regprocedure);y edita ESE cuerpo con el cambio mínimo, conservando firma y lógica vigente. Un refactor completo de una función en producción solo por instrucción explícita del propietario.
REGLA 3 — DESCALCE REPO vs REAL: GANA EL REAL, Y SE REPORTA
Si el repo/migraciones dice una cosa y el esquema real dice otra, el esquema real GANA y el descalce es un HALLAZGO a reportar (puede ser migración pendiente o residuo histórico) — jamás se "resuelve" sobrescribiendo la función contra el esquema que tú esperabas.
REGLA 4 — TODO RITUAL LLEVA SU SMOKE, DISEÑADO SEGÚN SU GUARD
- a) Funciones SIN guard de identidad: smoke transaccional completo en el mismo entregable:sql
BEGIN; SELECT func(...args de prueba); ROLLBACK; - b) Funciones CON guard de identidad (
is_superadmin()u otro que lea JWT): el SQL Editor corre SIN JWT de app → el guard rechazará por diseño (fail-closed correcto, NO es bug). En ese caso el smoke entregado valida SOLO la lógica (UPDATE equivalente en transacción con las mismas columnas), y la prueba del flujo completo queda designada explícitamente a la pila del operador con sesión autenticada. Decláralo así en la sección de rituales, no dejes el smoke ambiguo.
REGLA 5 — GARANTÍA DE DATOS PARA GUARDS EN EDGE FUNCTIONS
Cuando un guard de Edge dependa de un campo del payload (ej. condoId), el turno debe declarar explícitamente:
- (a) Quién garantiza que el campo siempre llegue (cliente/frontend).
- (b) Qué hace la Edge si falta (
fail-openofail-closed) y por qué es aceptable. Un guard que puede quedar ciego por un payload incompleto sin declaración es un hallazgo.
REGLA 6 — HUECOS DE INSTRUCCIÓN SON HALLAZGOS
Si un punto de la instrucción (ej. "garantía de condoId en todo dispatch") no puedes resolverlo o no queda claro cómo demostrarlo, debe aparecer NOMBRADO en tu reporte como pendiente o resuelto-con-citas. La ausencia silenciosa de un punto exigido se trata como incumplimiento (patrón R12 del proyecto).