{
  "documentType": "codex-security.hardening-analysis",
  "schemaVersion": "1.0",
  "analysisId": "session_migration_v2_20260726",
  "sourceEvidence": {
    "kind": "document_collection",
    "label": "Código y consumidores de autenticación de cursor-mobile-bridge",
    "collectionSha256": "3298d316d7ed3d21b166363116d22948fb2d4448d585ba94d272965b26070126",
    "artifactCount": 9,
    "sourceDrift": "unknown"
  },
  "assessment": {
    "outcome": "opportunities_identified",
    "summary": "La credencial raíz compartida debe migrarse gradualmente a sesiones humanas y credenciales de servicio con capacidades; el corte inmediato rompería consumidores confirmados."
  },
  "constraints": {
    "profile": "balanced",
    "changeHorizons": ["incremental", "medium_term"],
    "nonNegotiables": [
      "No romper aplicaciones vecinas ni clientes no navegador",
      "No exponer secretos en frontend, URL o logs",
      "Mantener acceso por Tailscale",
      "No modificar otros proyectos sin autorización específica"
    ],
    "assumptions": [
      "No se proporcionó un presupuesto medido de latencia o memoria.",
      "Pueden existir consumidores fuera de la raíz externa de proyectos inspeccionada.",
      "El acceso remoto comprobado sigue usando HTTP y requiere una decisión HTTPS."
    ]
  },
  "opportunities": [
    {
      "opportunityId": "centralize-bridge-session",
      "title": "Centralizar y segmentar la sesión del bridge",
      "summary": "Separar sesiones humanas y credenciales de servicio con capacidades antes de retirar la cabecera heredada.",
      "diagnosis": "Una credencial ambiental compartida representa navegadores, bots, scripts y servicios y concede acceso a capacidades de riesgo desigual.",
      "evidence": [
        {"claimType":"observed","sourceKind":"source","evidenceId":"E001","path":"server.js","claim":"Cookie de sesión y X-Bridge-Token son aceptados por el mismo middleware; las sesiones están en memoria."},
        {"claimType":"observed","sourceKind":"source","evidenceId":"E002-E006","path":"static","claim":"Varios clientes web conservan almacenamiento o cabecera heredada."},
        {"claimType":"observed","sourceKind":"source","evidenceId":"E007-E010","path":"lib/bridge-telegram-hub.js","claim":"Telegram, herramientas y un portal externo tienen consumidores no navegador confirmados."},
        {"claimType":"inferred","sourceKind":"source","evidenceId":"E001","path":"server.js","claim":"La autoridad compartida aumenta el radio de impacto y obliga a rotación global."}
      ],
      "desiredInvariants": [
        "Los navegadores solo conservan sesión en cookie HttpOnly, Secure y SameSite=Strict sobre HTTPS.",
        "Cada cliente de servicio tiene identidad, caducidad, revocación y capacidades mínimas.",
        "El uso heredado llega a cero antes de retirar X-Bridge-Token.",
        "Ningún token se acepta o propaga mediante URL."
      ],
      "proposalPath": "proposals/centralize-bridge-session.md",
      "options": [
        {
          "optionId": "harden-legacy-header",
          "title": "Compatibilidad endurecida",
          "kind": "baseline",
          "summary": "Mantener la cabecera con allowlist, rate limit, auditoría y migración web a cookie.",
          "diagramPaths": {"before":"diagrams/centralize-bridge-session-before.mmd","after":"diagrams/centralize-bridge-session-compatibility-after.mmd"},
          "evidenceCoverage": [
            {"evidenceId":"E001","effect":"mitigates","tacticalFixRequired":true,"rationale":"Refuerza el borde pero conserva autoridad compartida."},
            {"evidenceId":"E002-E010","effect":"mitigates","tacticalFixRequired":true,"rationale":"Mantiene compatibilidad y permite migración web parcial."},
            {"evidenceId":"E012","effect":"unaffected","tacticalFixRequired":true,"rationale":"No aporta HTTPS."}
          ],
          "tradeoffs": [
            {"dimension":"security","direction":"improves","confidence":"medium","basis":"source-derived","assessment":"Reduce exposición web y abuso no inventariado, pero conserva el secreto raíz.","validationPlan":"Probar rechazo por origen/cliente y revisar todas las rutas protegidas."},
            {"dimension":"performance","direction":"neutral","confidence":"medium","basis":"hypothetical","assessment":"Allowlist y rate limit añaden trabajo acotado por petición.","validationPlan":"Comparar p50/p95 y SSE con el bridge actual."},
            {"dimension":"memory","direction":"neutral","confidence":"medium","basis":"hypothetical","assessment":"Solo requiere contadores y metadatos acotados.","validationPlan":"Comparar RSS y tamaño de tablas de rate limit."},
            {"dimension":"reliability","direction":"improves","confidence":"medium","basis":"source-derived","assessment":"Preserva clientes actuales, aunque la rotación global sigue siendo frágil.","validationPlan":"Ensayar rotación y rollback con todos los consumidores."},
            {"dimension":"operability","direction":"regresses","confidence":"medium","basis":"hypothetical","assessment":"Añade observabilidad sin eliminar deuda heredada.","validationPlan":"Validar alertas y runbook de expiración de allowlists."},
            {"dimension":"migration","direction":"improves","confidence":"high","basis":"source-derived","assessment":"Es la opción más compatible a corto plazo.","validationPlan":"Matriz funcional de los 12 clientes y servicios."}
          ],
          "residualRisks": ["Una sola filtración conserva autoridad amplia.","La identidad por red/cliente puede falsificarse si no se liga criptográficamente."],
          "implementationReadiness": {"affectedComponents":["server.js","static","lib/bridge-telegram-hub.js","tools"],"workPackages":["Inventario y auditoría","Migración web","Rotación coordinada"],"acceptanceCriteria":["Ningún frontend guarda el token raíz","Todos los consumidores conocidos siguen operativos"],"migrationNotes":["No cortar X-Bridge-Token"],"rollback":"Restaurar temporalmente la política anterior sin revertir la rotación."}
        },
        {
          "optionId": "phased-capability-sessions",
          "title": "Migración gradual por capacidades",
          "kind": "structural",
          "summary": "Separar sesiones persistentes de navegador y credenciales de servicio limitadas, con adaptador heredado temporal observado.",
          "diagramPaths": {"before":"diagrams/centralize-bridge-session-before.mmd","after":"diagrams/centralize-bridge-session-phased-session-after.mmd"},
          "evidenceCoverage": [
            {"evidenceId":"E001","effect":"addresses","tacticalFixRequired":true,"rationale":"Reduce autoridad ambiental y centraliza política."},
            {"evidenceId":"E002-E006","effect":"addresses","tacticalFixRequired":true,"rationale":"Migra navegadores a cookie sin token accesible."},
            {"evidenceId":"E007-E010","effect":"addresses","tacticalFixRequired":true,"rationale":"Asigna identidad y capacidades a servicios."},
            {"evidenceId":"E012","effect":"mitigates","tacticalFixRequired":true,"rationale":"Requiere HTTPS y mantiene Tailscale como perímetro adicional."}
          ],
          "tradeoffs": [
            {"dimension":"security","direction":"improves","confidence":"high","basis":"source-derived","assessment":"Limita el blast radius y permite revocación individual.","validationPlan":"Pruebas negativas por capacidad y simulación de credencial comprometida."},
            {"dimension":"performance","direction":"regresses","confidence":"low","basis":"hypothetical","assessment":"La política añade una consulta acotada por petición; el efecto no está medido.","validationPlan":"Comparar p50/p95, throughput y estabilidad SSE antes/después."},
            {"dimension":"memory","direction":"regresses","confidence":"low","basis":"hypothetical","assessment":"El store persistente y caché de políticas consumen recursos adicionales.","validationPlan":"Medir RSS y tamaño del store con carga representativa."},
            {"dimension":"reliability","direction":"improves","confidence":"medium","basis":"hypothetical","assessment":"Las sesiones pueden sobrevivir reinicios y los fallos se aíslan por cliente, pero el store añade dependencia.","validationPlan":"Pruebas de reinicio, corrupción, backup y recuperación."},
            {"dimension":"operability","direction":"regresses","confidence":"medium","basis":"hypothetical","assessment":"Exige inventario, emisión, revocación, métricas y runbooks.","validationPlan":"Ejercicio de alta, revocación, rotación e incidente."},
            {"dimension":"migration","direction":"regresses","confidence":"high","basis":"source-derived","assessment":"Requiere dual stack y migrar cada consumidor.","validationPlan":"Canary por cliente y ventana con cero uso heredado."}
          ],
          "residualRisks": ["Capacidades demasiado amplias por error de diseño.","Compromiso del almacén de sesiones.","XSS de mismo origen durante la transición."],
          "implementationReadiness": {"affectedComponents":["server.js","static","lib/bridge-telegram-hub.js","tools","config"],"workPackages":["Inventario y telemetría","HTTPS","Store de sesión","Política de capacidades","Migración web","Migración de servicios","Rotación y corte"],"acceptanceCriteria":["Cero uso heredado durante la ventana acordada","Pruebas de capacidad, revocación y reinicio superadas","Ningún secreto en frontend, URL o logs"],"migrationNotes":["Otros proyectos requieren autorización separada"],"rollback":"Rehabilitar el adaptador heredado con caducidad mientras se conserva el modelo nuevo."}
        },
        {
          "optionId": "immediate-strict-cutover",
          "title": "Corte global inmediato",
          "kind": "foundational",
          "summary": "Eliminar la cabecera, rotar y migrar todos los consumidores en una única ventana.",
          "diagramPaths": {"before":"diagrams/centralize-bridge-session-before.mmd","after":"diagrams/centralize-bridge-session-strict-session-after.mmd"},
          "evidenceCoverage": [
            {"evidenceId":"E001","effect":"addresses","tacticalFixRequired":true,"rationale":"Elimina la aceptación del token raíz."},
            {"evidenceId":"E002-E010","effect":"unknown","tacticalFixRequired":true,"rationale":"Consumidores confirmados fallan hasta migrarse simultáneamente."},
            {"evidenceId":"E012","effect":"mitigates","tacticalFixRequired":true,"rationale":"El estado final requiere HTTPS aún no seleccionado."}
          ],
          "tradeoffs": [
            {"dimension":"security","direction":"improves","confidence":"high","basis":"source-derived","assessment":"Retira inmediatamente el camino heredado.","validationPlan":"Verificar rechazo universal de X-Bridge-Token y rotación efectiva."},
            {"dimension":"performance","direction":"unknown","confidence":"low","basis":"hypothetical","assessment":"Depende del store y política elegidos para reemplazarlo.","validationPlan":"Benchmark de la implementación concreta."},
            {"dimension":"memory","direction":"unknown","confidence":"low","basis":"hypothetical","assessment":"Depende del reemplazo de sesión y credenciales.","validationPlan":"Medición RSS y almacenamiento."},
            {"dimension":"reliability","direction":"regresses","confidence":"high","basis":"source-derived","assessment":"Rompe consumidores confirmados si no se coordinan todos en la ventana.","validationPlan":"Ensayo completo previo y plan de reversión."},
            {"dimension":"operability","direction":"improves","confidence":"medium","basis":"hypothetical","assessment":"El estado final es simple, pero el cutover concentra riesgo operativo.","validationPlan":"Simulacro de ventana, comunicación y recuperación."},
            {"dimension":"migration","direction":"regresses","confidence":"high","basis":"source-derived","assessment":"Requiere modificar consumidores externos fuera del alcance actual.","validationPlan":"Aprobación y test firmado por propietario de cada consumidor."}
          ],
          "residualRisks": ["Consumidores desconocidos quedan fuera de servicio.","Un rollback apresurado puede restaurar el secreto expuesto."],
          "implementationReadiness": {"affectedComponents":["server.js","static","lib","tools","consumidores externos"],"workPackages":["Migración simultánea y rotación"],"acceptanceCriteria":["Todos los consumidores inventariados pasan pruebas en ensayo"],"migrationNotes":["No autorizado con el alcance actual"],"rollback":"Restaurar temporalmente la cabecera con el token nuevo y registrar el incidente."}
        }
      ],
      "recommendedOptionId": "phased-capability-sessions",
      "recommendation": "Elegir la migración gradual tras completar inventario, propietarios y HTTPS; no retirar ni rotar todavía."
    }
  ],
  "openQuestions": [
    "¿Qué consumidores existen fuera de la raíz externa de proyectos inspeccionada?",
    "¿Qué capacidades necesitan Telegram y el portal LAB?",
    "¿Existe Tailscale Funnel y cuáles son las ACL y dispositivos autorizados?",
    "¿Qué terminación HTTPS se seleccionará?",
    "¿Qué persistencia, duración y ventana de relogin son aceptables?"
  ]
}
