Errores comunes
Antipatrones que anulan en silencio el escalado a cero y la seguridad de agentes — y cómo evitarlos.
Estos patrones no dan error. Pasan CI, parecen razonables en un diff, y anulan en silencio una garantía por la que usted paga — el ahorro del escalado a cero o la seguridad de agentes. Cada uno de los siguientes: qué ocurre, por qué duele y la solución.
El código keep-alive derrota al escalado a cero
Un agente añade «servicialmente» código que toca la base de datos con un temporizador. Cada consulta periódica cuenta como actividad y reinicia el temporizador de suspensión, de modo que un endpoint que diseñó para escalar a cero nunca duerme — y la inactividad deja de ser gratuita.
Llega de varias formas. Un heartbeat de frontend o backend:
// runs forever, holds the compute awake forever
setInterval(async () => {
await pool.query("SELECT 1"); // "health check"
}, 30_000);Un monitor externo de disponibilidad apuntado a un endpoint cuyo handler resulta que consulta la BD — de modo que cada sondeo despierta el cómputo:
app.get("/health", async (_req, res) => {
await pool.query("SELECT 1"); // monitored every 60s → never idle
res.send("ok");
});O ajustes del pool de conexiones que mantienen una conexión viva con consultas
de validación — un min por encima de cero, o un «calentador» serverless:
const pool = new Pool({
min: 2, // keeps ≥2 connections open + validated
// a validation/keep-alive query on each idle connection resets the timer
});Solución: audite los diffs escritos por el agente en busca de accesos
periódicos a la base de datos. Mantenga las comprobaciones de vida en la capa
HTTP — sondee la aplicación, no la BD — y deje que el pool se vacíe hasta cero
(min: 0). La vista de cómputo de la consola muestra por qué un endpoint no
está escalando a cero, lo que expone rápidamente un heartbeat perdido.
Entregar al agente las credenciales de main cortocircuita ASCC
Dar a un agente la cadena de conexión de la rama main — o dejarle ejecutar
keon con la sesión iniciada como su propio usuario — elude todo lo que ASCC
aplica: aislamiento del sandbox, presupuestos LEASH, comprobaciones LINT y BLAST,
compuertas de promoción, atribución y anclas de deshacer. El agente ahora
escribe en producción directamente, y nada del bucle que hace seguros los
cambios de agente llega a ejecutarse.
El agente nunca debería sostener una credencial que pueda escribir en main. La
promoción es del lado del servidor por diseño — cp es el único escritor en
producción.
Solución: acuñe una clave de API acotada a agente (capability = agent,
scope = a project, expiración corta) en Settings → API keys, entregue al
agente solo cadenas de conexión de sandbox y retire las credenciales más
potentes de su entorno (sin DATABASE_URL completa, sin ~/.pgpass, sin sesión
keon iniciada en el mismo shell). Consulte Entregar a un agente una
credencial acotada y la sección SCOPE de
Salvaguardas.
Tormentas de reintentos en torno al despertar
La primera conexión tras una suspensión tiene que despertar el cómputo, así que es más lenta que una en caliente. Un agente que ve una única conexión lenta puede «arreglarla» — con tiempos de espera de cliente agresivos y bucles de reintento que martillean el endpoint, o añadiendo un keep-alive (error #1) para no tener que despertar en absoluto. Ambos ceden el ahorro para tapar un coste de una sola vez.
Solución: establezca un connect_timeout de cliente de alrededor de 10 s y
tenga paciencia en la primera conexión. El arranque en frío es de menos de un
segundo dentro de la misma región una vez que las rutas calientes entran en
juego — una conexión ligeramente lenta es esperable, no un defecto que haya que
sortear con ingeniería.
postgresql://…?connect_timeout=10Credenciales confirmadas en el código
Los agentes codifican de forma fija cadenas de conexión y claves de API en el
código fuente y en archivos .env que luego llegan a git. Las claves filtradas
se recolectan a las pocas horas de llegar a un repositorio público (o que luego
se hará público) — la ventana se mide en horas, no en días.
Solución: inyecte los secretos mediante el entorno, nunca los confirme.
Mantenga los archivos .env fuera de git. Ante cualquier filtración, rote de
inmediato desde Settings → API keys — revoque la clave expuesta y acuñe una
nueva.
El DDL directo sobre main elude el bucle de promoción
Ejecutar una migración directamente contra main se salta la captura que hace
un cambio reversible y auditable. Pierde la migración up/down emitida (EMIT), la
entrada firmada del ledger (LEDGER) y el ancla de deshacer (UNDO). El esquema
cambió, pero no hay registro que la plataforma pueda reproducir o revertir.
Solución: sandbox → promoción, incluso para un cambio de esquema «trivial».
El bucle de promoción es lo que produce la migración, la entrada del ledger y el
ancla; un ALTER directo no produce ninguno de ellos.
Las escrituras dentro de una transacción revertida igualmente aterrizan
La captura registra las sentencias que el agente ejecuta — no tiene conciencia
de los límites de transacción. Las sentencias ejecutadas dentro de un BEGIN … ROLLBACK se capturan igualmente, y si ese sandbox se promociona, se reproducen
y se aplican. Un ROLLBACK en el sandbox no las descaptura.
BEGIN;
UPDATE users SET plan = 'pro'; -- captured
ROLLBACK; -- does NOT remove it from the captureSolución: no confíe en ROLLBACK dentro de un sandbox para «deshacer»
trabajo exploratorio. Si quiere que el trabajo desaparezca, descarte el sandbox
— esa es la vía de eliminación que la captura respeta.
Aparcar trabajo en un sandbox más allá de su presupuesto o TTL
Los sandboxes son efímeros. Cuando un sandbox agota su presupuesto LEASH se
descarta automáticamente (status=discarded), y cualquier trabajo sin promover
en él se pierde. Tratar un sandbox como una rama de larga vida a la que
«volverá» es como se esfuman los cambios de un día.
Solución: promociónelo, o vuelva a capturar el trabajo en un sandbox nuevo. Trate los sandboxes como desechables por defecto — el artefacto duradero es la promoción, no el sandbox.
Malinterpretar las garantías
Tres trampas específicas en lo que las comprobaciones realmente prometen:
-
La simulación de radio de impacto es consultiva. Mide lo que una promoción haría — bloqueos, duraciones, recuentos de filas reales — pero nunca controla la promoción. Una simulación limpia es información, no una luz verde; y si una simulación es obligatoria antes de promocionar es decisión de POLICY, no de la simulación.
-
Approve no puede anular un bloqueo de política. Un Approve humano nunca puede dejar pasar un
blockde política ni una sentencia fuera del carril. La única manera de superar un bloqueo es un cambio de política auditado — no hay interruptor de anulación manual, por diseño. -
Un fork enmascarado enmascara valores, no forma. En un fork enmascarado los valores están enmascarados, de modo que el DML dependiente de datos que el agente escribe contra esos valores enmascarados no coincidirá con las filas reales del padre durante la reproducción. El trabajo de carril de esquema es independiente del valor y se reproduce fielmente; el DML dependiente del valor desarrollado contra datos enmascarados no.
Forks enmascarados
Dé a un agente (o a un humano) la forma de producción y nada de su PII — políticas de enmascaramiento, la biblioteca de funciones integradas y cómo las ramas y los sandboxes enmascarados permanecen sellados hasta que el enmascaramiento se confirma.
Entregar a un agente una credencial acotada
Aprovisione una clave de API acotada por capacidad, proyecto y expiración, y ejecute un agente de IA contra su base de datos de forma segura.