Cómo hicimos que saltarse la moderación fuera arquitectónicamente imposible
Por Ronny Cruz Alvarez, fundador de Open Feed Network (Candor Network). Fundador en solitario, una plataforma en producción, y muchas opiniones sobre rutas de escritura.
El bug que me convenció
Hace unas semanas encontré un bug en mi propia plataforma que debería quitarle el sueño a cualquier ingeniero de confianza y seguridad (trust & safety).
Candor filtra las transmisiones en vivo. La identidad del transmisor viaja en un JWT para que el pipeline de filtrado sepa quién está transmitiendo. En algún punto de esa ruta, la verificación del token podía fallar — y cuando fallaba, el código recurría a una identidad por defecto. Algo así:
jsconst broadcaster = verifiedUser || 'anonymous';
Un solo ||. Escrito a la defensiva, con buenas intenciones, probablemente a la 1 de la madrugada. El efecto: después del login, cada sesión caía silenciosamente en "anonymous" — y las sesiones anónimas tomaban una ruta de código que evadía todo el sistema de filtrado. No un clasificador. Todos.
Nada se rompió. Nada registró un error. El sistema de moderación estaba completamente desplegado, completamente funcional, y no estaba corriendo.
Y aquí está lo importante: este no es un bug raro. Es el modo de fallo normal de cómo toda la industria conecta la moderación. Y es la razón por la que dejé de confiar en la arquitectura estándar y reconstruí la mía alrededor de un solo invariante.
La arquitectura estándar es una promesa, no una garantía
Casi todas las plataformas — sin importar qué proveedor de moderación usen — funcionan así:
contenido del usuario → código de aplicación → [llamar al API de moderación, ojalá] → base de datos → feed
El filtrado y el almacenamiento son dos sistemas separados, conectados por código de aplicación. Lo que significa que la garantía de "todo se filtra" es tan fuerte como cada ruta de código que pueda escribir en la base de datos. Cada endpoint. Cada trabajo en segundo plano. Cada script de migración. Cada fallback bien intencionado escrito a la 1 de la madrugada.
Esa garantía se degrada de maneras que nunca aparecen en un demo:
Un ingeniero agrega una nueva ruta de escritura y olvida la llamada al filtrado.
Una condición de carrera sirve el contenido antes de que regrese el filtrado asíncrono.
El servicio de moderación está caído y el código "falla abierto" para no bloquear a los usuarios.
Un fallback silencioso (ver arriba) le da la vuelta a la verificación por completo.
Cuando algo eventualmente se cuela y alguien pregunta "¿tu moderación corrió sobre esta publicación?", lo único que tienes es un log de aplicación afirmando que la verificación ocurrió. Los logs se contradicen con otros logs. Un log es una afirmación, no una prueba.
El invariante
El feed de Candor está construido sobre una sola oración, y cada decisión arquitectónica se verifica contra ella:
La base de datos acepta únicamente contenido filtrado, porque la base de datos no olvida nada.
Dos propiedades, y una fuerza a la otra:
El almacén es de solo-anexar (append-only) e inmutable. Las entradas del feed forman una cadena criptográfica de hashes: cada entrada compromete el hash de la anterior. Alterar cualquier entrada pasada rompe todos los hashes subsiguientes. La manipulación no está prohibida por política — es matemáticamente detectable.
Como no existe el "lo borro después", el filtrado tiene que correr antes de la escritura. En un almacén inmutable, guardar-y-luego-filtrar no es un orden peor. Es un orden prohibido, por definición. La puerta es la guardiana de un acto irreversible.
Así que la arquitectura no es "llama al API de moderación antes de guardar, y con code review nos aseguramos de que todos lo hagan". Es: la puerta de filtrado y la ruta de escritura al almacén son el mismo sistema. No existe ruta de escritura hacia el almacén del feed que no haya pasado ya por la puerta — no como convención, como propiedad estructural. La clase de bug del || 'anonymous' ya no puede evadir el filtrado, porque no hay nada del otro lado del filtrado a donde caer.
"Espera — ¿inmutable? ¿Y las órdenes legales de eliminación?"
Esta es la primera objeción que todo el mundo levanta, y es buena. El derecho al olvido del GDPR, las órdenes judiciales y los contenidos que genuinamente se cuelan son reales. Un feed inmutable que no puede cumplir con la ley de remoción de contenido no sirve.
La respuesta es la redacción por lápida (tombstone redaction). Cada entrada almacena permanentemente hash(contenido) — un compromiso de contenido — separado del contenido mismo. Cuando la remoción es legalmente requerida, el contenido se elimina, pero el espacio de la entrada, su hash comprometido y sus enlaces de cadena permanecen, reemplazados por una lápida: aquí existió una entrada; removida por la razón X; fecha Y; autoridad Z.
La validación de la cadena corre contra el hash comprometido, así que redactar una entrada nunca rompe la verificabilidad de ninguna otra. Obtienes ambas cosas: el contenido desaparece de verdad, y el registro de que existió, fue filtrado y fue removido bajo autoridad declarada es permanente y demostrable. Este fue el componente más delicado de construir.
Fallar cerrado — pero no en todo, y ese es el punto
"Fallar cerrado" (fail-closed) es un gran eslogan y una pésima política universal. Si cada error de filtrado bloqueara cada publicación, una sola dependencia inestable tumbaría la plataforma, y el arreglo de la guardia terminaría siendo… un parche que falla abierto. Felicidades: reinventaste el bypass silencioso, ahora con pasos extra.
Así que la puerta tiene una matriz de fallos por severidad:
Ruta de filtradoAnte un errorPor quéContenido terrorista / extremismo violentoFalla cerrado — no se almacenaRuta de daño catastróficoCSAM (comparación de hashes)Falla cerrado — no se almacenaLegal + catastróficoPuntuación de credibilidadPuede fallar abierto — se almacena sin puntuaciónUna puntuación faltante degrada una función; no daña a nadieVerificación de discurso protegidoSolo-degrada — puede reducir la severidad de un veredicto, nunca puede bloquear, nunca puede saltarse el filtradoPreviene la sobre-censura y evita que "la propaganda disfrazada" use la verificación de contexto como bypass
Una puntuación de credibilidad perdida y una verificación de CSAM perdida no son el mismo fallo. Tratarlas igual es como terminas siendo o inusable o inseguro.
La regla compañera es fallar ruidosamente (fail-loud): en Candor, un secreto faltante al arrancar es process.exit(1), nunca un valor por defecto. Nada de || 'change-me'. Nada de || 'anonymous'. Esa regla me ha atrapado personalmente bugs que de otra forma habrían sido invisibles — incluyendo uno donde un manejador de errores devolvía un valor con apariencia segura de "ninguna señal detectada" que en realidad estaba enmascarando fallos del API upstream. Un falso "todo despejado" es la peor salida posible de un sistema de seguridad, y la única defensa confiable que he encontrado es negarse a que cualquier ruta de código pueda fabricar uno.
Limitaciones honestas
Algunas cosas que esta arquitectura no resuelve mágicamente, porque los artículos de arquitectura que declaran victoria total están mintiendo:
Las transmisiones en vivo no se pueden pre-filtrar. No puedes poner una puerta a audio/video en vivo antes de que exista. Los streams corren un modelo distinto: transcripción en tiempo real distribuida a los analizadores, con detección en línea y respuesta a nivel del stream. La garantía de inmutabilidad-en-ingreso aplica al feed y a los mensajes; el contenido en vivo se gobierna por velocidad de detección, y sigo activamente reduciendo esa latencia.
La garantía es estructural, y la prueba criptográfica externa está en desarrollo. La cadena de hashes hace la manipulación internamente detectable hoy; publicar los hashes de la cabeza de la cadena en un ancla externa — para que la prueba sea verificable por terceros que no confían en mí — está diseñado y en progreso, no terminado.
La calidad del filtrado sigue siendo un problema de clasificadores. Esta arquitectura garantiza que el filtrado corrió; no hace al clasificador perfecto. Lo que cambia es la clase de fallo: de "la verificación silenciosamente no ocurrió" a "la verificación ocurrió y aquí está el registro".
Soy un fundador en solitario con un solo despliegue en producción — mi propia plataforma, que lleva corriendo esto en producción con una beta en vivo desde el 4 de julio. Esa es la escala honesta de la evidencia hoy. Cada capacidad que afirmo está verificada contra el sistema corriendo, con sondas fechadas, no inferida del código ni de la intención; esa disciplina existe porque una vez atrapé a mi propio sistema desplegado desviándose de su diseño, silenciosamente, un atajo fácil a la vez. El análisis de patente sobre la arquitectura está en curso con asesoría legal.
Una nota más, específica para esta versión: la plataforma se construyó bilingüe, inglés y español, desde el diseño — la detección de crisis y la transcripción de streams operan en ambos idiomas. La moderación en español es una carencia documentada de toda la industria; para nosotros no es una traducción añadida después, es parte del sistema.
Por qué creo que este orden gana
La regulación se está moviendo de "¿moderaste?" a "demuestra que moderaste". La Ley de Servicios Digitales (DSA) de la Unión Europea ya apunta en esa dirección. Cuando esa pregunta llegue a tu plataforma, un log de aplicación es una respuesta débil. Una capa de almacenamiento que estructuralmente no puede aceptar contenido sin filtrar — con una cadena a prueba de manipulación mostrando exactamente qué se filtró, cuándo, y qué se removió bajo qué autoridad — es otro tipo de respuesta.
Guardar-y-luego-filtrar tenía sentido cuando el almacenamiento era mutable y la moderación era una idea de último momento. En un almacén inmutable, filtrar-antes-de-guardar no es una preferencia. Es el único orden legal. Esa restricción resultó ser la decisión de diseño más clarificadora que he tomado.
Candor Network es el despliegue de referencia. Los módulos individuales de filtrado (detección de crisis, clasificación de extremismo, puntuación de desinformación, detección de sextorsión) también están disponibles como APIs independientes — en inglés y español. Si administras una plataforma o comunidad y algo de esto se parece a un problema que tienes — o quieres decirme por qué estoy equivocado sobre la matriz de fallos — escríbeme a candortheopenfeednetwork@gmail.com. Contesto todo yo mismo, en el idioma que prefieras.
Top comments (0)