# Dos reglas con la misma fecha de creación: tu motor de políticas no decide siempre lo mismo

> Si tus reglas se ordenan por fecha de creación y se sembraron en la misma transacción, comparten el instante exacto. El desempate lo pone el motor, y con él la decisión.

- Publicado: 19 de octubre de 2026
- Autor: Equipo de IntegraLaIA
- Categoría: Ingeniería
- Temas: Postgres, Producción, Gobernanza
- Original: https://integralaia.com/blog/reglas-empatadas-fecha-creacion-orden-indeterminado
- Cómo se hizo: Borrador asistido por IA (Claude); revisado, editado y verificado por Equipo de IntegraLaIA el 19 de octubre de 2026. Ilustración generada con IA.

---

Una tabla de reglas, dos que aplican al mismo caso y un motor que se queda con la primera del rango más alto. Funciona durante meses. Después la misma situación muestra un motivo, y al rato otro, sin que nadie haya tocado nada.

## La fecha de creación iguala, no desempata

El orden más natural para una tabla de reglas es la fecha de creación. Parece un criterio total, y no lo es.

La documentación de PostgreSQL es explícita: `now()` y `CURRENT_TIMESTAMP` devuelven el inicio de la transacción en curso, no el momento de cada fila. Una siembra que inserta de una vez todas las reglas de un cliente las deja a todas con el mismo instante, al microsegundo. Y ahí el `ORDER BY` deja de ordenar: el manual advierte que un orden solo está garantizado si se pide explícitamente, y que las expresiones posteriores ordenan lo que empata en las anteriores. Sin ninguna, las devuelve como le convenga, que suele ser su orden físico en disco.

## Primero se nota en el motivo, no en la decisión

Mientras las dos reglas empatadas digan lo mismo, la decisión no cambia: si las dos prohíben, el caso se frena igual. Lo que varía es **cuál queda registrada**: el motivo que lee quien atiende y la regla de la bitácora.

Un motivo que cambia sin causa es una explicación que nadie puede auditar, y auditar es lo que se le pide a un sistema que decide por obligación legal, como el que [programa la Ley 2300 en el código](/blog/ley-2300-agente-cobranza-colombia) en vez de pedírselo al modelo. Y el día que el empate cae entre dos reglas con efecto distinto, una que prohíbe y otra que pide aprobación, lo que cambia es la decisión.

## Repartir las fechas no arregla la siembra siguiente

La corrección de reflejo es separar cada fila unos microsegundos y seguir ordenando por ahí. Arregla lo que ya existe y deja intacta la causa: la próxima siembra vuelve a insertarlas todas en una transacción.

La salida es un orden total que no dependa del reloj: un orden declarado para el catálogo de reglas y el identificador como último criterio. Da lo mismo en cada entorno y en cada consulta.

## Y una prohibición no se gana por orden de llegada

Un motor que se queda con la primera regla que aplica implementa lo que el estándar XACML de OASIS llama *first-applicable*. Cuando hay una prohibición en juego, el algoritmo que corresponde es otro: en *deny-overrides*, si una sola regla evalúa a Deny, el resultado combinado es Deny, pase lo que pase con las demás.

En código propio: la prohibición se evalúa aparte y por sí sola, con los mismos hechos, y si se cumple manda. Deja de importar quién ganó el desempate.

Lo que se lleva cualquiera con una tabla de reglas: **ordena por algo único de verdad, y que un veto no compita por orden de llegada.** Esto sale de operar agentes con clientes reales, en [casos](/casos), y de cómo tratamos datos y accesos, en [seguridad](/seguridad).
---

## Sobre qué se escribió

- PostgreSQL, documentación oficial, 9.9.5. Current Date/Time (now, CURRENT_TIMESTAMP y transaction_timestamp devuelven el inicio de la transacción en curso), consultado el 19 de octubre de 2026: https://www.postgresql.org/docs/current/functions-datetime.html
- PostgreSQL, documentación oficial, 7.5. Sorting Rows (ORDER BY): sin ordenación explícita las filas salen en un orden no especificado, y las expresiones posteriores ordenan las filas que empatan en las anteriores. Consultado el 19 de octubre de 2026: https://www.postgresql.org/docs/current/queries-order.html
- OASIS, eXtensible Access Control Markup Language (XACML) Version 3.0, algoritmo de combinación Deny-overrides, consultado el 19 de octubre de 2026: https://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-en.html

IntegraLaIA (https://integralaia.com). Publicado bajo el enlace original; cítalo si lo reutilizas.
