Commit Graph
456 Commits
Author SHA1 Message Date
Gitea CI 4ada782f4f ci: update shortsmith image to a5e4ebdd [skip ci] 2026-08-06 14:36:56 +00:00
Gitea CI 320a8b9ffd ci: update researchowl image to 1fd0c1b3 [skip ci] 2026-08-06 14:15:41 +00:00
Gitea CI 9d26f8ffa4 ci: update researchowl image to 96099032 [skip ci] 2026-08-06 14:02:28 +00:00
chemavxandClaude Opus 5 87a4ece6f4 backup-system: barrido semanal de imágenes containerd por nodo
El worker llegó al 80,9% de disco: 223 imágenes para ~20 pods, 62 GB en
containerd. Cada build de CI publica un tag y nadie recoge los viejos —
97 tags de researchowl y 105 de polymarket-bot, decomisada en julio.

El GC de kubelet no basta: solo entra al 85% de imagefs, o sea cuando ya
no queda sitio. Un prune manual dejó el worker en 23% (54 GB) y el master
en 15% (58 GB).

Un CronJob por nodo porque un CronJob programa un solo pod; el nodo se
fija con nodeSelector. Domingos 06:30 y 07:15, el hueco entre backups.

El script hace varias pasadas a propósito: borrar snapshots satura a
containerd y las llamadas siguientes dan DeadlineExceeded. No es fallo,
es cola. Se reintenta mirando la salida, no el código de retorno, porque
crictl devuelve 0 aunque haya borrados fallidos.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 16:14:40 +00:00
chemavxandClaude Fable 5 27f57edb6b researchowl: env de YouTube para /upload_short, claves opcionales a propósito
Las tres secretKeyRef van optional: true: mientras no existan en Infisical
el pod arranca igual y el comando contesta 'no configurado'. Sin optional,
una clave que aún no está deja el Deployment en CreateContainerConfigError
y tira el bot entero por una función sin estrenar.

YOUTUBE_PRIVACY=private documenta el candado: los vídeos por API de un
proyecto sin auditar quedan privados los pidas como los pidas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 15:53:47 +00:00
Gitea CI a73b66bb5f ci: update researchowl image to cc1f0cab [skip ci] 2026-08-05 15:53:08 +00:00
chemavxandClaude Opus 5 fc3be78c9d renovate: fuera polymarket-bot, decomisado el 17-jul
Renovate seguia escaneandolo 6 veces al dia y empujando ramas a un repo
muerto: renovate/uvicorn-0.x se actualizo el 2-ago, 16 dias despues del
decomiso. Misma familia que el bloque de Polymarket del Resumen Diario:
decomisar un servicio no lo saca de las cosas que lo miran.

Quedan 11 ramas renovate/* en el repo; se limpian aparte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 21:23:36 +00:00
Gitea CI e27a46be4b ci: update researchowl image to 20c8d03a [skip ci] 2026-08-01 21:58:31 +00:00
Gitea CI edf8bb8261 ci: update shortsmith image to 42dcb408 [skip ci] 2026-08-01 17:12:46 +00:00
Gitea CI 7593ec8019 ci: update shortsmith image to dae4b12d [skip ci] 2026-08-01 17:08:59 +00:00
Gitea CI 1c5289d381 ci: update shortsmith image to 5dc59d08 [skip ci] 2026-08-01 17:00:13 +00:00
Gitea CI b4f4112e23 ci: update shortsmith image to 854f9144 [skip ci] 2026-08-01 16:43:01 +00:00
chemavxandClaude Opus 5 aeb31eae59 shortsmith: recursos medidos en el pod, no en el host
El primer render real murio OOMKilled con el limite de 1Gi que salia de medir en
la maquina de desarrollo. El host lleva ffmpeg 4.4.2 y la imagen 7.1.5, y 7.0
reescribio la transcodificacion sobre un planificador con colas de fotogramas
decodificados entre componentes: pasarle el WAV como segunda entrada dejaba al
decodificador de video correr por delante y llenar una cola con fotogramas de
6,2 MB. Arreglado partiendo el encode en dos pasos (repo shortsmith), y aqui van
las cifras nuevas, medidas dentro del pod.

requests 768Mi (pico anon 640 MB), limits 1536Mi. El limite no es 1Gi por el
caso techo de 180 s: ahi el pico era 940 MB de 1024 y sobrevivia solo porque
quedaba cache reclamable que soltar. A 1.5Gi memory.events da max 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 16:40:24 +00:00
Gitea CI 0a6d0e9b58 ci: update shortsmith image to 46b39256 [skip ci] 2026-08-01 16:13:58 +00:00
Gitea CI 4edd7575e6 ci: update shortsmith image to 171dc544 [skip ci] 2026-08-01 15:44:25 +00:00
chemavxandClaude Opus 5 60235a75c9 shortsmith: deployment, service, PVC y Application
Renderizador determinista JSON->MP4 para Shorts. API interna sin Ingress, en
shortsmith-svc:8080; la cola es por proceso y la SQLite va en RWO, de ahí la
replica unica con estrategia Recreate.

Los recursos van medidos, no estimados, y la tabla con las cifras queda en el
propio manifiesto: el pico son 522 MB de anon y lo pone entero el encode, no el
render. Ojo al comentario sobre por que los workers salen del limite de CPU y no
del request.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 15:18:46 +00:00
chemavxandClaude Opus 5 97ff13cc83 docs: leer la sqlite de n8n con cp se salta el WAL
Un barrido hecho con cp dijo que un cambio recien escrito no estaba, media
hora despues de escribirlo. La copia no tiene los ultimos commits y no da
ningun error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 16:15:30 +00:00
chemavxandClaude Opus 5 d9e8de9e17 CLAUDE.md: tras publicar por SQLite hay que reiniciar el pod de n8n
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 09:00:49 +00:00
chemavxandClaude Opus 5 bd92f5ae9d Distinguir "no se reinicio" de "no pude comprobarlo"
El GET de comprobacion no miraba su propio codigo HTTP. Un 403 devuelve un
objeto Status, que parsea como JSON perfectamente y luego revienta en
dep.spec.replicas ("Cannot read properties of undefined (reading 'replicas')").
El aviso resultante decia "reinicio fallido, intervencion manual necesaria"
cuando el reinicio habia ido BIEN y lo unico roto era la verificacion.

Falso negativo, mucho menos grave que el falso positivo de ayer -- pero te
levanta de la cama para nada, y estando Jose fuera eso importa.

Ahora el nodo marca verificable:false cuando no ha podido comprobar (HTTP no
2xx, cuerpo ilegible o error de red) y el aviso lo dice con esas palabras,
con el codigo de la comprobacion aparte del codigo del PATCH.

Reproducido en produccion: POST legitimo a las 08:43:22 (PATCH ok, restartedAt
cambia), permiso retirado a los 15 s, GET a los 60 s con 403. Ejecucion de
60,394 s, o sea el camino completo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:46:25 +00:00
chemavxandClaude Opus 5 f0e99635bf CLAUDE.md: el auto-reinicio ahora falla en cerrado y con permisos por nombre
Anade tambien como leer por que rama fue una ejecucion cuando
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none ya la ha vaciado: por la duracion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:08:50 +00:00
chemavxandClaude Opus 5 50f090bbea Cerrar el auto-reinicio: fail-closed, permisos por nombre y fallo visible
Tres agujeros que encontro una review adversarial de Codex sobre el trabajo
de ayer. Los tres verificados contra el fichero antes de tocar nada.

1. El webhook publico fallaba en ABIERTO. Con `optional: true` y un
   `if (secreto && ...)`, la ausencia del secreto equivalia a autorizacion:
   cualquier POST con heartbeat.status=0 y un monitor.name del mapa reiniciaba
   n8n, Gitea, ArgoCD, Vaultwarden o los blogs. El argumento para dejarlo asi
   era "que un despiste no te deje sin avisos", y era falso: el aviso de caida
   lo manda Kuma por su notificacion 1, directa, no por este webhook.
   Ahora el secreto es obligatorio (sin `optional`) y la puerta rechaza si
   falta. Secreto ausente da error ruidoso; cabecera que no casa, vacio.

2. El ClusterRole permitia patch sobre CUALQUIER deployment de 10 namespaces,
   y la SA va montada en el pod entero de n8n: cualquier workflow con un nodo
   Code heredaba eso. Ahora son Roles por namespace con resourceNames sobre
   los 12 workloads exactos del SERVICE_MAP.

3. El flujo daba exito aunque el PATCH fallara. `restartOk` se calculaba y se
   tiraba: `K8s API Check Status` construia un objeto nuevo sin el, y el IF
   final solo miraba `statusOk`. Un 403 sobre un servicio ya sano mandaba
   "reiniciado correctamente". Ahora hay rama de fallo tras el PATCH y el
   exito exige observedGeneration >= la generation que devolvio el PATCH.
   Se compara con >= porque selfHeal de ArgoCD revierte la anotacion y vuelve
   a subir la generation; con == daria un fallo falso.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:02:07 +00:00
chemavxandClaude Opus 5 6454b56fe3 CLAUDE.md: las trampas que enganan al mirarlas
Este directorio es el WorkingDirectory de hermes-bot, o sea el sitio donde un
agente lee el contexto del cluster, y no tenia ninguno.

Se ha notado hoy: tras poner EXECUTIONS_DATA_SAVE_ON_SUCCESS=none en n8n, las
ejecuciones exitosas quedan como status='running' con deletedAt puesta hasta que
pasa el barrido. Hermes las vio, las tomo por ejecuciones colgadas y se gasto un
turno entero de quince minutos diagnosticando una averia inexistente en un
workflow que corria clavado cada cinco minutos.

Solo van aqui las cosas que enganan: lo que parece roto y no lo esta, y lo que
parece inofensivo y no lo es. El resto sigue en el skill k8s-infra.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 21:03:59 +00:00
chemavxandClaude Opus 5 125cdc9de0 n8n: cerrar el webhook del auto-reinicio con un secreto compartido
/webhook/uptime-kuma-restart es publico y sin autenticar. Mientras no reiniciaba
nada daba igual; desde hoy reinicia doce servicios, los dos blogs incluidos, asi
que cualquiera que diera con la ruta podia zarandear el cluster.

Uptime Kuma manda ahora la cabecera X-Kuma-Token (webhookAdditionalHeaders de la
notificacion "n8n Auto-Restart") y el primer nodo Code la compara con
KUMA_WEBHOOK_TOKEN antes de hacer nada.

La comprobacion falla en ABIERTO si el secreto no esta configurado en n8n: un
despiste de configuracion degrada al comportamiento de antes en vez de dejar de
avisar en silencio, que es el fallo que no se ve venir. Si esta configurado y no
coincide, se devuelve vacio: ni reinicio, ni Telegram, ni fila de error que se
pueda llenar a base de peticiones.

El secret n8n-kuma-webhook se crea con kubectl y NO esta en git; el env va con
optional: true para que la ausencia no impida arrancar el pod.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:25:17 +00:00
chemavxandClaude Opus 5 9d42dac312 argocd: excluir los exports de workflow de la app n8n
Una Application de tipo directorio lee *.yaml, *.yml y *.json indistintamente,
asi que la copia del workflow que acabo de meter en n8n/ entraba como si fuera
un manifiesto y dejaba la app en ComparisonError: "Object 'Kind' is missing".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:20:18 +00:00
chemavxandClaude Opus 5 cbfbc8bf16 n8n: copia en git del workflow del auto-reinicio
Los workflows viven solo en la SQLite, que ya se revirtio sola una vez (16-jul,
a un snapshot de abril) y se llevo por delante mes y medio de trabajo. Este en
concreto es el que reacciona a las caidas, asi que conviene tenerlo fuera.

Ya no hay nada secreto que ocultar: los tres nodos de Telegram leen el token de
$env.TELEGRAM_BOT_TOKEN en vez de llevarlo incrustado.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:19:20 +00:00
chemavxandClaude Opus 5 07521216c7 n8n: el auto-reinicio alcanza tambien a los dos blogs
Ghost EN y ES son lo unico del mapa que da la cara al publico y lo que peor se
lleva con dos semanas sin nadie mirando. Entran en el SERVICE_MAP con la clave
igual al nombre exacto del monitor de Kuma.

El monitor "www.zonadeexclusion.com (301->apex)" se queda fuera a proposito:
que ese 301 falle es cosa de Traefik o del DNS, no de Ghost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 20:15:08 +00:00
chemavxandClaude Opus 5 440eb5b6a1 n8n: dar permisos de reinicio al auto-restart de Uptime Kuma
El workflow "Uptime Kuma -> K8s Auto-Restart" lleva desde siempre sin poder
reiniciar nada: hacia el PATCH con el token de la ServiceAccount "default" del
namespace, que no tiene ni un permiso, y el API contestaba 403. Se iba entonces
por la rama de "reinicio fallido" y mandaba el aviso por Telegram -- que se
enviaba bien, y por eso los 23 "exitos" de workflow_statistics. La integracion
parecia viva y no lo estaba.

SA propia (n8n-restarter) en vez de la default, y un RoleBinding por namespace
en lugar de un ClusterRoleBinding: el webhook que dispara esto es publico y sin
autenticar, asi que el alcance se limita al SERVICE_MAP del workflow.

El ClusterRole incluye get ademas de patch porque el workflow relee el objeto a
los 60 s para comprobar readyReplicas (sin get: "Cannot read properties of
undefined"), y statefulsets ademas de deployments porque Gitea es lo primero.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:58:29 +00:00
chemavx 3112f92fea n8n: permitir modulos internos de Node en los nodos Code
Tres workflows ACTIVOS fallaban con "Module 'https' is disallowed" sin que
saltara ninguna alerta, porque estaba NODE_FUNCTION_ALLOW_EXTERNAL (paquetes
npm) pero no NODE_FUNCTION_ALLOW_BUILTIN (modulos internos):

  - Uptime Kuma -> K8s Auto-Restart  ultimo exito 2026-07-23 07:51
  - TLS Certs -> Alerta Telegram     ultimo exito 2026-04-13
  - Resumen Diario - Metricas K8s    30 fallos, 0 exitos

Es decir: el auto-reinicio que dispara Uptime Kuma llevaba una semana
muerto. Se rompio al reiniciarse el pod la tarde del 23-jul, cuando el task
runner empezo a bloquear require() de modulos internos.

Lista explicita (fs,http,https) en vez de '*': es justo lo que piden los
nodos Code de esos workflows, y asi un modulo nuevo falla a la vista en vez
de estar concedido de antemano.
2026-07-30 16:56:50 +00:00
chemavx c48ea74878 n8n: no guardar el payload de las ejecuciones exitosas
La poda por edad ya estaba activa de serie (n8n 2.15.1, prune=true, 336 h):
los IDs de ejecucion empiezan en 22.634 con 7.052 filas, o sea que ya habia
borrado ~22.600 el solo. El tar diario crecia 0,4 MB/dia y estaba llegando a
meseta, asi que no habia desbocamiento: la premisa era falsa.

El problema real era la composicion. De 322 MB de execution_data, 246 MB
(76%) eran las 3.436 ejecuciones EXITOSAS de 'Real Madrid RSS -> Twitter',
que corre cada 5 min y guarda 73 KB por vuelta. Sus errores -lo unico que
sirve para depurar- ocupaban 2 MB.

Y no es un problema de disco (21%, 699 GB libres) sino de backup: n8n esta
en CROWN, asi que ese .tar.gz de 101 MB viajaba entero a MEGA cada dia y a
B2 en las dos ultimas copias. Es justo el gasto que revento la cuota el
2026-07-25.

Nada depende de ese historico: el monitor de reversion solo lee
workflow_entity, el panel de Grafana mira replicas del deployment y
'Resumen Diario' saca metricas de k8s por un nodo Code.
2026-07-30 16:30:34 +00:00
Gitea CI 7dce3c43f6 ci: update researchowl image to 8b81ef87 [skip ci] 2026-07-30 10:14:53 +00:00
Gitea CI 859d80242e ci: update roswell-corpus image to 1005cab3 [skip ci] 2026-07-28 16:08:00 +00:00
Gitea CI 747db8579a ci: update roswell-corpus image to d838837b [skip ci] 2026-07-28 16:03:39 +00:00
Gitea CI 56cc4d6c1c ci: update roswell-corpus image to 6b3eb8cf [skip ci] 2026-07-28 16:01:14 +00:00
Gitea CI ec67146149 ci: update roswell-corpus image to b9e597af [skip ci] 2026-07-28 15:57:52 +00:00
Gitea CI 58cd3425a1 ci: update roswell-corpus image to 99fb7da1 [skip ci] 2026-07-28 15:55:49 +00:00
Gitea CI 4380e2f696 ci: update roswell-corpus image to 2a415354 [skip ci] 2026-07-28 15:53:58 +00:00
Gitea CI eb14115a89 ci: update roswell-corpus image to 14a8257c [skip ci] 2026-07-28 15:51:46 +00:00
Gitea CI 42627d3395 ci: update roswell-corpus image to b31562f3 [skip ci] 2026-07-28 15:40:43 +00:00
Gitea CI 197a32c07d ci: update roswell-corpus image to 4ba68021 [skip ci] 2026-07-28 15:35:18 +00:00
Gitea CI d05bf0d5ae ci: update roswell-corpus image to de3b2e34 [skip ci] 2026-07-28 15:26:22 +00:00
Gitea CI faafba1869 ci: update roswell-corpus image to e9476a63 [skip ci] 2026-07-28 15:17:59 +00:00
Gitea CI 6ebad58434 ci: update roswell-corpus image to 03b0d9a7 [skip ci] 2026-07-28 14:51:23 +00:00
Gitea CI 59d7d6b86c ci: update roswell-corpus image to 0dd1ef38 [skip ci] 2026-07-28 14:06:05 +00:00
Gitea CI 50398bb3f8 ci: update roswell-corpus image to e25e27e5 [skip ci] 2026-07-28 13:54:33 +00:00
Gitea CI 6047333230 ci: update roswell-corpus image to e6afe7d1 [skip ci] 2026-07-28 13:42:36 +00:00
Gitea CI ca5b27a1cc ci: update roswell-corpus image to b9bdeef2 [skip ci] 2026-07-28 13:35:32 +00:00
Gitea CI fa9f3c32ed ci: update roswell-corpus image to 4c2b40fe [skip ci] 2026-07-28 13:27:18 +00:00
Gitea CI 7f56a6ad2e ci: update roswell-corpus image to d8154523 [skip ci] 2026-07-28 12:28:32 +00:00
Gitea CI 6c9c529986 ci: update roswell-corpus image to 8181cca6 [skip ci] 2026-07-28 12:20:39 +00:00
Gitea CI 878ae4855a ci: update roswell-corpus image to 4b02af00 [skip ci] 2026-07-28 12:01:03 +00:00