--- episode_id: "72f29fa1-496e-418c-be19-8c4096816a8f" puente_flat: "TRAZA_decisin-arquitectnica-con-datos_S20260602.R26_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD" session_code: "S20260602.GRAFO_GRAPHIFY_CURADURIA" acto_dialogico: "informar" actor_flujo: "multi_actor" criticidad_aegis: "low" skill_dominante: "AEGIS" fase_proyecto: "operations" tipo_semantico: "troubleshooting" summary_one_line: "EPISODIO 26 — BLINDADAS: Decisión arquitectónica (con datos)" source_type: "claude_code" trust_boundary: "internal" created_at: "2026-06-06T11:01:30.107493+00:00" relectura_tagged: false forgejo_commit_sha: "pending" --- **🎯 Diagnóstico FINAL — `stop-enricher.py:437-438` SÍ invoca `push_pending_to_server()` (paso 11b "DETERMINISTIC PUSH").** La cadena client→server existe completa: 1. `stop-enricher.py:435-438` invoca push (cada Stop) ✓ 2. `push_to_server.py` SCP a `crisol/inbox/` server (vivo, 498 .md ahí hoy) ✓ 3. `crisol_run.py` server lo procesa (cron horario activo) ✓ 4. Si éxito → `clear_all_pending()` limpia manifest **ENTONCES ¿por qué los 82 payloads NO se drenan?** El except handler `stop-enricher.py:439` captura silenciosamente. Si el push falla, clear NO se ejecuta, manifest crece. Hipótesis runtime ponderadas: | H | Hipótesis | Evidencia | Test mínimo | Confidence | |---|---|---|---|---| | **H1** | `TIMEOUT_SSH=300s` insuficiente con lote crecido (82 payloads ≈ 250-410s en crisol_run F0-F6) — repite bug S20260516 ya documentado en `push_to_server.py:75-87` | Lote 82 × 1s SCP + 3s conexión = ~85s; crisol_run × 82 episodios excede 300s | leer 1 entry del log último intento push | **0.65** | | **H2** | Drift de stores: `push_pending_to_server` lee de `session_state.json::pending_qdrant_payloads` pero writer escribe en `pending_memory_push.json` (manifest separado) | `batch_push_to_qdrant.get_pending_payloads()` lee STATE_FILE; el manifest es otro archivo | `diff` los 2 archivos | **0.20** | | **H3** | `push_pending_to_server()` falla por otro motivo (auth, key SSH, permisos, container) silenciado por except L439 | El except amplio L439-... captura todo sin log explícito visible | Grep telemetría push_log | **0.15** | ★ **Insight ─────────────────────────────────────** H1 es el "déjà vu del bug ya documentado": `push_to_server.py:81-87` literalmente cita *"Bug #15 fix S20260515: 120s→300s; lotes >8 episodios excede 300s → cola NO se limpia → re-push + duplicados"*. El lote actual es **82 episodios**, **10× sobre el umbral** documentado. El fix S20260515 era escalar timeout, pero **el lote sigue creciendo más rápido que el timeout**. Fix real = chunks acotados + clear parcial. **─────────────────────────────────────────────────** ## Decisión arquitectónica (con datos) **Opción A (refinada R41):** modificar `push_to_server.py::push_pending_to_server()` para: 1. **Chunk size cap** (max 20 payloads por SCP/SSH batch) → cada chunk <60s timeout SSH. 2. **Clear PARCIAL atomic** (limpiar payloads cuyos hashes confirmen `pg_inserted` server-side, no todo-o-nada). 3. **Telemetría JSONL explícita** (`push_to_server_attempts.jsonl`) — cada attempt loguea status, no más silencio. 4. **Idempotency dedup** por `content_sha256` antes de SCP (evita re-push de los ya procesados). Estimación: ~40-60 líneas en `push_to_server.py` (no fabricación nueva, refactor del existente con tests). ## Tres caminos finales para ti 1. **Verificar H1 empírico primero** (1 comando SSH: `tail /home/johnember/logs/push_gateway*.log`) → ~3K tokens. Si confirma timeout → fabrico A refinado con seguridad. 2. **GO directo Opción A refinada** asumiendo H1 (0.65 confidence + 2 fixes previos en código apuntan a timeout) → ~60K tokens fabricar + tests + deploy. 3. **Pausar + revisar mañana** con `FORENSE_L3` ya completo (todo el trabajo preserved). **Mi inclinación honesta:** **Camino 1 → Camino 2 si H1 confirma**. Costo total ~65K, cabe holgado. El verificar primero descarta especulación. ¿Cuál?