Cifrado de secretos en reposo
Todo secreto de servicio (API keys, tokens) se almacena cifrado con AES-256-GCM; nunca en texto plano en la base de datos.
src/lib/crypto.ts28 requerimientos no funcionales agrupados por categoría de calidad (alineadas a ISO/IEC 25010): seguridad, confiabilidad/disponibilidad, eficiencia de desempeño, mantenibilidad y usabilidad/accesibilidad. Filtra por estado o prioridad, o busca por ID, título o ruta.
No hay requerimientos que coincidan con los filtros.
Todo secreto de servicio (API keys, tokens) se almacena cifrado con AES-256-GCM; nunca en texto plano en la base de datos.
src/lib/crypto.tsSolo los logins de GitHub explícitamente permitidos obtienen sesión de administrador, sin excepción.
src/lib/auth.tsCualquier fallo en blocklist, rate limiting o sensor deja pasar el request; el enforcement nunca puede tumbar el sitio.
src/middleware.tsTodo bloqueo de IP y todo chaos flag tiene TTL obligatorio; el sistema se autocorrige sin intervención manual.
blocked_ips.expiresAtchaos_flags.expiresAtLa IP se enmascara/hashea antes de exponerse fuera del panel admin; Web Vitals no capturan datos personales.
security_events.ipHashNingún clasificador de ruta (rate limiting, bloqueo en modo demo, gate de admin, portal) puede cambiar de veredicto porque la URL lleve un prefijo de idioma delante.
src/i18n/routing.ts (delocalizePathisLocalizedPrivateRequest)src/middleware.tsUn mismo idempotencyKey nunca genera dos cobros, incluso ante doble clic o reintento de red.
payments.idempotencyKeyLos estados terminales de un pago (approved/declined/error/voided) nunca retroceden ante webhooks fuera de orden.
src/lib/payments.tsSi el health check post-deploy falla, el pipeline revierte automáticamente a la última versión saludable.
ci_runs.healthOkCada servicio monitoreado puede evaluarse contra un objetivo configurable (por defecto 99.5% en ventana de 30 días).
src/lib/slo.tsEl estado del limitador de tasa persiste en base de datos, no se resetea con cada despliegue.
rate_limit_bucketsUna consulta que falla en una página pública pinta el dato como ausente, nunca como error ni como 404: la portada, /status, /security, /certifications y /engineering siguen sirviendo su contenido aunque la base de datos no responda.
src/lib/safe-query.tsusado en src/pages/index.astrostatus.astrosecurity.astrocertifications.astro y engineering.astroCuando la base de datos no responde, las páginas públicas no se limitan a omitir el dato (RNF-26): lo sirven desde una fuente alterna real. La portada pinta los proyectos desde una instantánea capturada de la propia base, y /status mide la disponibilidad y la latencia sondeando los endpoints públicos en el momento del render, sin base de datos de por medio.
src/lib/fallback/ (rastreador.tsinstantanea.tssondeo-vivo.ts)src/data/instantanea.jsonsrc/data/respaldo-monitores.tsscripts/capturar-instantanea.mjsToda ruta declarada en la sección de crons de vercel.json existe como archivo, exporta un handler GET, comprueba CRON_SECRET y no cuelga del gate de sesión de /api/admin.
vercel.json (crons)tests/crons.test.tsLa clasificación de cada request (regex/lookup en memoria) no debe añadir latencia perceptible; la escritura es fire-and-forget.
src/lib/security/sensor.tsLCP, INP y CLS del sitio público deben mantenerse en la banda "good" según el p75 medido en producción.
web_vitalsBlocklist y flags de chaos se leen con cache en memoria (30s) para no golpear la base de datos en cada request.
src/lib/security/blocklist.tsRequerimientos, casos de uso e iteraciones se definen en TypeScript tipado, no en documentos externos desincronizables.
src/data/documentacion.tsCada decisión técnica relevante por proyecto queda documentada con contexto, alternativas y consecuencias (ADR).
project_adrsEl entorno de desarrollo (Node 22.12, navegador de Playwright, bases de datos) se define como código en un devcontainer, de modo que clonar el repositorio y abrirlo produce el mismo entorno en cualquier máquina.
.devcontainer/ (Dockerfilecompose.yamldevcontainer.json)compose.yamlLa suite e2e puede ejecutarse contra un servidor libSQL (sqld) en contenedor además de contra bases en archivo, ejerciendo el mismo protocolo HTTP/hrana que Turso en producción.
compose.yamlplaywright.config.ts (E2E_DB_MODE)scripts/wait-libsql.mjsscripts/seed-e2e.mjsLas decisiones de publicar, revertir y ejecutar están separadas en tres niveles de autoridad, y cada frontera se sostiene en un mecanismo del repositorio, no en la disciplina de quien programa. La matriz RACI de las actividades críticas es un dato tipado con sus reglas comprobadas en CI.
src/data/gobernanza.tssrc/lib/gobernanza-estilos.tssrc/pages/docs/roles.astrosrc/pages/docs/raci.astro; mecanismos: .github/workflows/ci.yml (health check + rollback)regla de deploys en CLAUDE.mdallowlist en src/middleware.tspolítica de migraciones aditivas en drizzle/Los checks de monitoreo y eventos de seguridad crudos se purgan pasados 90 días para no inflar el almacenamiento.
monitor_checkssecurity_eventsEl coste en filas leídas de una página pública no crece con la antigüedad del sistema: /status lee un resumen diario precalculado (una fila por monitor y día, ~720) más el día en curso, en vez de agregar los 90 días crudos de monitor_checks en cada render. Las pruebas de carga se niegan a arrancar si el objetivo está conectado a una base remota.
monitor_dailysrc/lib/monitor-rollup.tssrc/pages/api/cron/monitor-rollup.tssrc/pages/status.astrosrc/lib/db-target.tslab/k6/lib/perfil.jsEl panel admin y sus subpáginas son usables en viewport móvil (drawer de navegación colapsable).
src/layouts/AdminLayout.astroCada push corre axe-core sobre Playwright contra las 8 páginas públicas y reporta las violaciones al panel del LAB como hallazgos rastreables.
scripts/a11y-scan.mjs.github/workflows/a11y.ymlEl portal de clientes ofrece salto al contenido, región aria-live para el resultado de las acciones y devolución explícita del foco tras enviar un formulario.
src/layouts/PortalLayout.astroUna clave añadida al diccionario español sin su par en inglés rompe el type-check, y ningún hreflang ni entrada de sitemap apunta a una URL traducida que no exista.
src/i18n/en.ts (satisfies typeof es)src/i18n/routing.ts (TRANSLATED_ROUTEStranslatedAlternates)¿Cambiar a inglés?
Tu navegador está en inglés. Puedo mostrarte el sitio en ese idioma.