# Ronda 33 — Loop hardcap, política de DMs, directiva BTCPay, inbox 10050, aprobaciones por reacción (OpenCode/GLM, operador patternn) > Deuda corregida: el doc de la r32 quedó sin PR al cerrar esa ronda — se > incluye aquí como archivo aparte (2026-11-03-r32-postmerge-faseb-reportes.md). ## 1. Loop de rollback en hardcap — RESUELTO - **Estado al abrir**: producción hardcap en `a5c2f59` (build del 1-nov), sirviendo 200; **34 rollbacks** entre 15:10:06 y 16:09:58 UTC (uno por ciclo de 3 min), todos `build-id '' != 'c453b2df'`. - **Causa raíz** (dos capas): (a) el fetch de GitHub del VPS llevaba roto desde el 1-nov (arreglado en r32 con deploy key read-only); (b) al revivir el fetch, el check de identidad grep-ea `meta name="build-id"` que main **nunca renderizó** (gh#10 lo añade; sigue abierto) → rollback eterno. - **Arreglos** (PR cayce-ops #65 + instalados): 1. identidad de hardcap exigida **solo si ESTE main renderiza la meta** (`git grep name=.build-id. layout.tsx`) — con gh#10 mergeado y desplegado el check se reactiva solo; 2. `dm_once`/`dm_clear`: **un DM por incidente** (subject `repo:causa`), limpiado por deploy exitoso; journal completo vía `say` (silencio en DM, no en audit). - **Resultado verificado**: deploy manual exit=0 → `hardcap-news → c453b2d (200)` — main del 3-nov EN producción (hubs /topics/* 200, texto del travel-security-kit corregido) — y `bitcoinhotels → 5dbff23` (4ª guía viva). - Sitio caído = urgencia real: cubierto por urgent-watch (caída >15 min), no por el rollback (que mantiene el sitio arriba en el build anterior). ## 2. Política de DMs — REEMPLAZADA (PR #66 + instalada) - urgent-watch v2: DM inmediato SOLO (1) kill switch manual o fuga (violaciones del watcher), (2) servicio/sitio caído >15 min, (3) backup fallido **2 días seguidos**, (4) gasto Gemini > umbral. Fuera: mudos, CODEOWNERS, initiative, rollbacks recuperados, publicaciones, rechazos → SOLO resumen diario 23:50 (verificado OnCalendar=23:50). Ciclos pausados a propósito (promo) sin alertas. - Dedup por **tipo:sujeto** (24 h). **Tope 3 urgentes/día**: al 4º, diferido a `.dm-deferred.log` → una línea en el resumen (sección 2b nueva). - **Conteo 24 h (evidencia del antes)**: **83 DMs** — 18 rollback hardcap, 26 codeowners, 6 mudos, 6 aborts dirty, 10 copias del reporte diario (bug de reenvío anotado), resto varios. - **Simulación DRYRUN de cada tipo** (estados falsos en /tmp, sin enviar): killswitch:manual ✓ · fuga:watcher ✓ · down:fake-down.service (20 min) ✓ · backup:2días ✓ · gasto:gemini ($9>$1) ✓ · tope→deferred ✓ (evidencia en `.dm-deferred.log` del simulacro). ## 3. Directiva BTCPay — DESACTIVADA - `CAYCE_DIRECTIVE_BTCPAY=0` en /srv/cayce-core/.env (generación de nuevas oportunidades BTCPay cortada de raíz). - Archivados: drafts **#50, #51, #52** (los tres BTCPay generados HOY por la directiva: 02:00, 08:00 y 16:00) + verificación de que **#33** y la oportunidad **#106** ya estaban archived. Audit: actions_log id 1306. - **Qué publicó initiative hoy**: 3 ciclos (02:00/08:00/16:00) pero **UNA sola nota nostr publicada** — id 381, 08:00:15 UTC, event `7389a478df83e39f0648b6c42295b4205c454ea9277827245923af9578f92417`, texto: "Event ticketing infrastructure that forces custodial payment processors or third-party tracking degrades bitcoiner operational security. Open-source merchant rails like BTCPay Server paired with local, peer-to-peer directories eliminate trusted third parties at the physical layer." **Guard: APROBADO** (canal nostr, tipo initiative_note, postgres temporal aislado) → se queda; no hubo que borrar nada con kind 5. - Pendiente reportado: 20 oportunidades BTCPay en estado `identified` quedan en el pipeline (sin nueva generación); si las quieres archivadas, dilo y lo hago. El producto vive solo en cayce/btcpay-events (repo intacto). ## 4. Inbox de Cayce (kind 10050) — PUBLICADO - Diagnóstico: el daemon **lee** gift wraps NIP-17 (kind 1059 → seal 13 → chat 14 del supervisor, con manejo de comandos) pero **nunca publicó el kind 10050** — de ahí "DM inbox relays not found" en tu cliente. - `publish-10050.mjs` (en /srv/cayce-nostr, herramienta operativa): consultó los 5 relays → **0 existentes** → publicó event `7694c0f61b747c45a76555d84a8c2281fa32db25039f5509afa8e4a4ddf05dee` (pubkey 59ef3b5d…, relays damnos/nos.lol/primal/snort/wellorder) **verificado en 5/5**. Idempotente (no república si hay uno <30 días). - **Prueba pendiente tuya**: mándame un DM NIP-17 — en el journal del daemon aparecerá `[DM supervisor NIP-17] …` (24 h últimas: 0, nunca llegó ninguno porque el cliente no encontraba el inbox). Nota: /srv/cayce-nostr no es repo git — drift pendiente de versionar (igual que el daemon). ## 5. Aprobación por reacción — IMPLEMENTADA (entity PR #10, WIP, LO MERGEAS TÚ) Diseño completo en `docs-approvals.md` (dentro del PR). Resumen: - Pregunta por DM NIP-17 con **ID único, acción, efecto y vencimiento 48 h**. - Aprobación = reacción 👍 o **+** a ESE mensaje, **seal NIP-17 firmado por SUPERVISOR_NPUB_HEX** (fallback: kind 7 pública con #e). 👎/otra/nada = no se hace nada. - Ejecución **idempotente** (FOR UPDATE + executed_at): `merge_pr` (ci-bot, para PRs de paths protegidos), `resume_promo`/`pause_promo`, registro `approved:` para campañas/zona roja. Audit en actions_log con el event id de la reacción; confirmación SOLO en el resumen diario. - **Tests 6/6 en CI** (postgres temporal): otra pubkey ignorada · otro mensaje ignorado · 👎 ignorada · vencida no ejecuta · válida ejecuta UNA vez · sweep de vencidas. - **Prueba real preparada**: tras tu merge, abro un PR de prueba tocando un path protegido, te llega la pregunta, reaccionas 👍 y verificamos el merge por ci-bot. ## Incidencias propias de la ronda 1. Al instalar el autodeploy parcheado, un pase lo estaba ejecutando (bash lee incrementalmente) → errores transitorios por 1 ciclo (16:13:36, documentados en journal); el pase siguiente y el manual salieron limpios. Lección aplicada: instalar scripts solo tras `flock` o entre ciclos. 2. El primer commit del PR entity arrastró el .pgtmp de pruebas → limpieza en el mismo PR antes de que lo tocaras. ## Pendientes del operador 1. **Merge gh#10** (meta build-id de hardcap; CI verde) — reactiva el check de identidad de hardcap al desplegarse. 2. **Merge entity PR #10** (aprobaciones, WIP a propósito) → instalo la unit y corremos la prueba real de reacción. 3. Mándame un DM NIP-17 para cerrar la prueba del inbox. 4. PRs cayce-ops #65/#66 (auto-mergeables) y el doc de esta ronda.