✓ FR-INT-009: acepta un webhook correctamente firmado ✓ FR-INT-009: rechaza cuerpo alterado, secreto equivocado y firma falsificada ✓ FR-INT-009: ventana de tiempo contra repeticiones tardías ✓ FR-INT-009: cabeceras mal formadas se rechazan sin errores ✓ FR-INT-009: rotación de secretos y varias firmas v1 ✓ FR-INT-009: un evento repetido se detecta, pero solo tras autenticar ✓ FR-INT-007: los secretos débiles se rechazan ✓ NFR-SEC-006: se permite un destino HTTPS de la lista blanca con IP pública ✓ NFR-SEC-006: esquema, credenciales en la URL y puertos ✓ NFR-SEC-006: trucos de parseo de URL no eluden la lista blanca ✓ NFR-SEC-006: las IP literales y sus notaciones alternativas se rechazan ✓ NFR-SEC-006: un nombre permitido que resuelve a red interna se bloquea (anti-DNS-rebinding) ✓ NFR-SEC-006: clasificación de direcciones públicas y reservadas ✓ FR-IAM-002: política de contraseñas ✓ FR-IAM-002: no se admite información del propio usuario ✓ FR-API-007: validación de la clave de idempotencia ✓ FR-API-007 / AC-011: misma clave y petición → repetición; otra petición → conflicto ✓ FR-API-007: la huella separa organizaciones, clientes, métodos y rutas ✓ FR-IAM-002: sustituciones tipo "leet" no eluden la lista de contraseñas comunes ✓ NFR-SEC-006: nombres de host mal formados se rechazan aunque coincidan con el comodín ✓ FR-IAM-002: la longitud mínima es exactamente 12 caracteres ✓ NFR-SEC-013: usuario del tenant A accede a recursos del tenant A ✓ FR-TEN-004: usuario del tenant A NO accede a recursos del tenant B y se oculta su existencia ✓ NFR-SEC-013: token de integración del tenant A no opera en el tenant B ✓ FR-RBAC-003: denegación por defecto ante permisos desconocidos o ajenos al rol ✓ sin autenticación, con actor inactivo o sin membresía se deniega ✓ FR-TEN-005 / INV-016: organización suspendida no ejecuta operaciones de negocio ✓ 3.1.1: el administrador de plataforma no tiene acceso automático al contenido de organizaciones ✓ un administrador de organización no obtiene permisos de plataforma ✓ FR-RBAC-004: separación de funciones impide aprobar la propia solicitud ✓ FR-RBAC-001: el catálogo de roles es coherente ✓ FR-AUD-004: una cadena íntegra no reporta discrepancias ✓ el primer evento enlaza con el hash génesis y cada evento con el anterior ✓ AC-009: detecta contenido alterado ✓ AC-009: detecta un evento eliminado ✓ AC-009: detecta eventos reordenados ✓ detecta alteración aunque el atacante recalcule el hash del evento modificado ✓ FR-AUD-007: la auditoría no conserva secretos ni credenciales ✓ FR-AUD-004: el hash cubre el hash anterior y el formato está fijado (vector de referencia) ✓ FR-AUD-004: la serialización canónica es reproducible ✓ FR-WF-006: operadores de comparación ✓ números y cadenas numéricas se comparan como números ✓ vacío y no vacío: el cero y false NO se consideran vacíos ✓ tipos no comparables dan falso sin lanzar error ✓ combinaciones AND / OR anidadas y campos con ruta ✓ FR-RULE-004: la evaluación es determinista ✓ FR-RULE-005: la traza explica la decisión sin copiar valores reales ✓ FR-RULE-002: validación rechaza definiciones inseguras o mal formadas ✓ FR-WF-006: profundidad y tamaño máximos ✓ FR-DOC-002: acepta archivos válidos cuyo MIME detectado coincide ✓ FR-DOC-003: rechaza ejecutables, scripts y dobles extensiones ✓ FR-DOC-002: no se confía en el Content-Type del cliente (MIME detectado distinto) ✓ nombres con recorrido de ruta, bytes de control o sin extensión se rechazan ✓ tamaño: vacío y excedido ✓ sección 12.2: la clave de almacenamiento es interna, fragmentada y sin extensión ✓ la clave rechaza identificadores con recorrido de ruta o formato inválido ✓ FR-DOC-007: hash SHA-256 por flujo coincide con el hash del archivo, con memoria acotada ✓ FR-DOC-007: el hash detecta cualquier modificación del contenido ✓ ADR-010: umbrales de inodos del perfil Stellar ✓ ADR-010: cuotas por organización y bloqueo por inodos de la cuenta ✓ FR-JOB-004: espera progresiva con tope y sin desbordamiento ✓ FR-JOB-004: no se reintenta indefinidamente ✓ FR-JOB-005: la clave de idempotencia es estable y distingue trabajos ✓ FR-DOS-002: transiciones válidas del ciclo de vida ✓ FR-DOS-002: no se permiten saltos arbitrarios de estado ✓ los estados terminales no admiten transiciones ✓ un estado enviado por el cliente se valida contra la lista cerrada ✓ todo estado no terminal puede llegar a un estado terminal ✓ AC-006: flujo secuencial completo hasta la aprobación ✓ FR-WF-010: el rechazo aplica la ruta configurada y no crea las tareas siguientes ✓ FR-WF-009: solo el responsable asignado (usuario o rol) puede decidir ✓ FR-RBAC-004: separación de funciones impide que el solicitante apruebe ✓ INV-006 / FR-WF-015: reintento idéntico es idempotente; decisión contradictoria es conflicto ✓ FR-TASK-004: control optimista de concurrencia por versión ✓ AC-007: ramas paralelas con convergencia "todas" ✓ un rechazo en una rama que va al fin cancela las demás tareas abiertas ✓ FR-WF-005: convergencia "todas" con una rama rechazada hacia la unión termina rechazada ✓ FR-WF-005: convergencia por mínimo de aprobaciones (1 de 2) ✓ FR-WF-011: devolución para corrección conserva el historial y vuelve al aprobador ✓ un resultado que el flujo no define se rechaza ✓ FR-WF-006: la decisión elige la ruta según los metadatos y deja traza ✓ INV-012: las acciones de sistema se devuelven como efectos, no se ejecutan en el motor ✓ un flujo cíclico sin intervención humana se corta por seguridad ✓ cancelación: termina la instancia, cancela tareas y bloquea nuevas decisiones ✓ FR-WF-012: vencimientos y FR-WF-013: reasignación que reabre la tarea ✓ reasignación: validaciones ✓ INV-004: la instancia conserva el hash exacto de su definición ✓ una definición inválida nunca se ejecuta ✓ FR-RULE-004: el motor es determinista y su estado se puede persistir como JSON ✓ un generador de identificadores propio (p. ej. ULID) se respeta ✓ FR-WF-005: al cumplirse la convergencia, las ramas restantes se cancelan aunque el flujo continúe ✓ FR-WF-012: una tarea vence exactamente en su fecha límite ✓ defensa en profundidad: un estado persistido inconsistente no permite decidir ✓ AC-006: workflow secuencial de dos actividades es válido ✓ AC-007: workflow con ramas paralelas y convergencia es válido ✓ FR-WF-005: convergencia mal configurada se rechaza ✓ FR-WF-010: toda aprobación define las rutas de aprobado y rechazado ✓ defectos estructurales se detectan antes de publicar ✓ FR-WF-006: condiciones solo en nodos de decisión y deben ser válidas ✓ FR-WF-005: convergencia "todas" es determinista ✓ FR-WF-005: convergencia por mínimo de aprobaciones ✓ la convergencia no depende del orden de las tareas ✓ FR-WF-001: todo nodo final declara un resultado válido Pruebas: 103/103 correctas