## Flow replay: guardar un flujo web como función reproducible Cuando una acción web se hace **más de una vez** (login en un panel, reiniciar un servidor desde su consola, rellenar un formulario recurrente, descargar un export), deja de hacerse a mano: se **graba una vez y se promueve a función del registry**. Es la doctrina del issue 0087 aplicada a la navegación — el registry crece convirtiendo secuencias repetidas en operaciones de un solo paso, no inflando funciones existentes. Grupo de capacidad: `flow-replay`. Página madre: `docs/capabilities/flow-replay.md`. Graba con el grupo `web-proxy`; destila y reproduce con `flow-replay`. ### El patrón: grabar → destilar → reproducir 1. **Grabar** (una vez, con browser + proxy): `web_proxy` ON, haces la acción a mano, exportas el tramo a HAR (`query_mitm_flows --har`). 2. **Destilar**: `har_filter_flows_py_cybersecurity` (quita ruido) → `har_extract_calls_py_cybersecurity` (call specs reproducibles). 3. **Reproducir**, en esta jerarquía de preferencia (de barato a caro): | Nivel | Mecanismo | Cuándo | |---|---|---| | **1 — HTTP puro** | `http_replay_sequence_py_infra` | **Por defecto.** Rápido, headless, scriptable. La mayoría de paneles admin funcionan con cookie de sesión + requests. | | **2 — headless chromium** | action recipe (reutiliza `cdp_extract_recipe` + `cdp_save_storage_state`) | Token dinámico firmado en cliente, challenge JS obligatorio, WAF con fingerprint. | | **3 — chromium visible + humanizado** | `cdp_click_xy_human`, `cdp_move_mouse_human` | Headless detectado/bloqueado. Último recurso. | **Empieza SIEMPRE por el Nivel 1.** Solo baja de nivel cuando el anterior demuestre no reproducir el efecto. Construir el runner de Nivel 2/3 por adelantado, sin un caso que lo exija, es especular (KISS): se monta cuando un flujo real falle en HTTP puro. ### Flujo de autoría (cómo guardar una función-acción nueva) 1. Grabar el flujo y exportar el HAR del tramo. 2. `har_filter_flows` + `har_extract_calls` → boceto de la secuencia. El agente **lee** el HAR (es texto) e identifica los 2-4 requests que producen el efecto (auth + acción + confirmación), descartando el resto. 3. Parametrizar: marcar los valores variables (ids, tokens) como `{{param}}`; definir las reglas `extract` para los tokens que una respuesta genera y otro request consume. 4. Validar el replay con `http_replay_sequence`. Si reproduce el efecto sin navegador → Nivel 1. 5. **Promover a función del registry**: delegar a `fn-constructor` una función-acción nombrada con verbo (`reboot_vps_server_`, `login_`, `export__report`) que internamente llama a `http_replay_sequence` con su secuencia fija, recibe los parámetros del caller y resuelve los secretos desde `pass`/vault. Tag de grupo `flow-replay` + el dominio que toque (infra, cybersecurity, …). `fn index` + usar en el mismo turno. ### Reglas duras de seguridad - **El HAR es un secreto**: lleva cookies/tokens en crudo. Gitignored, no subir a Gitea, no indexar, borrar tras destilar. El output de `har_extract_calls` también, hasta sustituir por `{{param}}`. - **Secretos a `pass`/vault**, jamás hardcodeados en la función-acción. - **Replay con efectos = peligroso.** Una acción destructiva o irreversible (reiniciar, borrar, pagar, enviar) NUNCA se reproduce a ciegas: la función-acción exige confirmación o un flag explícito (`confirm=True` / `--yes`) antes de disparar. - `http_replay_sequence` usa `verify_tls=True` y sigue redirects por defecto; la extracción JSON es dot-path simple, no JSONPath completo. ### Anti-patrones | Anti-patrón | Por qué es malo | Sustituir por | |---|---|---| | Repetir el flujo a mano cada vez | No capitaliza; lento; propenso a error | Grabar una vez → función-acción | | Reescribir requests inline en un heredoc/app cada vez | Reinvento, sin telemetría | Función-acción que llama `http_replay_sequence` | | Empezar por chromium headless "por si acaso" | Más caro y frágil que HTTP puro | Nivel 1 primero, bajar solo si falla | | Hardcodear cookie/token del HAR en el código | Secreto filtrado + caduca | `{{param}}` desde `pass`/vault | | Commitear el HAR o el output crudo de extract | Filtración de credenciales | Tratar como secreto, gitignored | | Replay ciego de un POST destructivo | Daño irreversible | Confirmación / flag explícito | ### Relación con otras reglas - [[registry_first]] — buscar/reutilizar antes de escribir; la función-acción se delega a `fn-constructor`, no se escribe inline. - [[function_growth_and_self_docs]] — el registry crece por promoción de composiciones repetidas a funciones one-shot (issue 0087); esto es ese patrón para la navegación. - [[registry_calls]] — invocar las funciones del grupo por los patrones canónicos (MCP / `fn run` / heredoc que importa). - Grupo `web-proxy` (`docs/capabilities/web-proxy.md`) — la captura que alimenta la Fase 0.