Commit Graph
100 Commits
Author SHA1 Message Date
chemavxandClaude Opus 4.8 5d0078c8e8 monitoring: los 12 estados de servicio miden el servicio, no el namespace
Los paneles heredados preguntaban "cuántos pods hay Running en el namespace".
Para n8n u ollama da igual, pero el panel llamado "grafana" contaba los 7 pods
de monitoring y el de "argocd" los suyos: se habrían quedado en verde con
Grafana muerta mientras Prometheus siguiera en pie. Lo mismo en "authentik" y
"gitea", que sumaban su Postgres, su Redis y el runner.

Ahora los 12 usan la misma forma: ¿están en pie TODOS los componentes de los
que depende el servicio?

  min((kube_deployment_status_replicas_available{SEL} >= bool 1)
      or (kube_statefulset_status_replicas_ready{SEL} >= bool 1)) or vector(0)

El selector define qué es el servicio: el namespace entero cuando el namespace
ES el servicio (argocd, authentik); acotado cuando alberga varias cosas
(grafana dentro de monitoring, researchowl/searxng); y en gitea sólo el
StatefulSet, porque si cae el runner se paran los builds pero Gitea sigue
sirviendo — pintarlo "Down" sería una falsa alarma.

Cambio invisible salvo cuando algo falla: los 12 mapean 0 -> "Down" y >=1 ->
"Running", así que en pantalla nunca se vio el número. Y además exige réplicas
*disponibles*, no pods en fase Running: un pod arrancado pero que no pasa el
readiness ya no cuenta como sano.

Verificado los 12 en verde y los 12 en rojo (simulando escasez de réplicas), y
el caso que de verdad importa: UN solo componente caído entre sanos arrastra el
panel a 0 (probado con dex-server en argocd y con el Postgres de authentik).
Después, los 12 otra vez a través del proxy de datasource de Grafana.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 08:21:03 +00:00
chemavxandClaude Opus 4.8 886fee9292 monitoring: los blogs y ResearchOwl entran en el dashboard
Faltaban justo los servicios de cara al público. Se añaden cuatro estados de
pod (ghost-en, zona-exclusion, researchowl, searxng), que completan la fila de
servicios, y una fila nueva con memoria, CPU y la antigüedad de la última copia
correcta de researchowl.db (CronJob diario de las 03:00 con integrity_check).

Los stat nuevos preguntan por kube_deployment_status_replicas_available del
deployment concreto, no por "todos los pods del namespace" como los antiguos:
esa consulta heredada hace que el panel llamado "grafana" cuente en realidad
los 7 pods de monitoring, y el de "argocd" todos los suyos. No los toco aquí.

Descartado a propósito un panel de uso de PVC: con local-path todos los
volúmenes de un nodo reportan el disco entero (ghost-en, zona-exclusion y
researchowl marcan los mismos 78 GB), así que habría mentido.

La primera versión de los cuatro stat estaba mal: "métrica{...} or vector(0)"
sobre una métrica CON etiquetas no sustituye, añade — devolvían 2 series y el
panel podía pintar un Down falso. Los paneles viejos se libran porque su sum()
deja la serie sin etiquetas. Corregido envolviendo en sum().

Verificado consulta a consulta contra Prometheus, incluido el caso "deployment
inexistente" (da 0 -> Down en rojo), y luego las 7 a través del proxy de
datasource de Grafana, no por fuera.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 08:14:07 +00:00
chemavxandClaude Opus 4.8 28f16314d8 monitoring: fuera los restos de polymarket y la datasource Alertmanager
El dashboard «ChemaVX Homelab Overview» tenía 4 paneles Infinity apuntando a
api.polymarket-bot.svc.cluster.local:8000, decomisado el 2026-07-17, más dos
stat de servicios cuyos namespaces ya no existen (polymarket-bot, open-webui)
que se veían como un 0 sospechoso en vez de como ausencia. 24 -> 17 paneles, y
la rejilla de servicios reempaquetada (arrastraba huecos de borrados viejos).

La datasource Alertmanager apuntaba a un servicio inexistente (alertmanager
está desactivado a propósito) y devolvía 500. Dos sorpresas: no la apaga
alertmanager.enabled, sino grafana.sidecar.datasources.alertmanager.enabled; y
quitarla del provisioning NO la borra de grafana.db — hace falta una directiva
deleteDatasources de un solo uso. Igual para la Infinity, creada por UI.

Auditando el Deployment contra el render aparecieron dos campos puestos a mano
que el chart no genera y que sólo seguían vivos por el three-way merge de Helm,
el mismo agujero que 0501aab: GF_INSTALL_PLUGINS (ya sin uso, retirado junto al
plugin de 48 MB) y TELEGRAM_BOT_TOKEN/CHAT_ID, que sí son críticos — el contact
point usa ${TELEGRAM_BOT_TOKEN}, así que reconstruir el release desde cero
habría dejado las alertas mudas. Declarados ya en values.

Verificado: render == desplegado salvo defaults del API server; Grafana
reiniciada y arrancando sin errores, 1 datasource, 25 dashboards, 5 reglas y el
contact point de Telegram con token resuelto.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 08:02:48 +00:00
chemavxandClaude Opus 4.8 f5bcb76738 monitoring: la contraseña de Grafana en git no abría nada
Los sidecars de dashboards y datasources autentican contra la API de Grafana con
las credenciales del secret del chart, y recibían 401 en cada recarga. El valor
en values era adminPassword: admin, que no es la contraseña de nadie.

Lo que apareció al investigarlo cambia el diagnóstico que traíamos anotado. La
cuenta admin local se configuró el 26-abr y NO se ha usado desde entonces
(last_seen_at y updated, ambos de esa fecha): no hubo ninguna rotación reciente
en la UI. El acceso real a Grafana es por Authentik — de ahí el usuario akadmin
—, así que la contraseña de esa cuenta no la sabía nadie y era irrecuperable,
por ser un hash bcrypt.

Conservar la contraseña existente era por tanto imposible: no había ninguna que
conservar. Se genera una aleatoria de 28 caracteres, se escribe en el Secret
grafana-admin y se resetea la de Grafana para que coincidan (leyendo del secret
por stdin: nunca pasa por argv ni se imprime). La cuenta queda como acceso de
emergencia; nadie tiene que memorizarla. Para leerla:

  kubectl get secret grafana-admin -n monitoring \
    -o jsonpath='{.data.admin-password}' | base64 -d; echo

El secret se crea FUERA del chart y se referencia con grafana.admin.existingSecret,
en vez de parchear el secret que genera Helm: con adminPassword en values, el
siguiente upgrade lo habría revertido a "admin". Es la misma trampa que el
montaje del alerting de hace un rato, y por eso adminPassword desaparece de git.

Verificado por el camino real y no por deducción: creando un ConfigMap de prueba
con la etiqueta grafana_dashboard, el sidecar escribe el fichero y la recarga
responde 200 OK "Dashboards config reloaded" — antes 401. ConfigMap de prueba
eliminado. Grafana sano tras el rollout (database ok, 12.4.2), las 5 reglas de
alerta provisionadas siguen activas, 25 dashboards y los 3 ficheros de alerting
en su sitio.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 17:24:02 +00:00
chemavxandClaude Opus 4.8 0501aab6e8 monitoring: el alerting de Grafana colgaba de un montaje no declarado
El ConfigMap grafana-alerting (reglas provisionadas + contact points + política
de notificación → Telegram) se monta en el Deployment de Grafana, pero el chart
NO generaba ese volumen: se había añadido a mano en algún momento y sobrevivía
únicamente por el three-way merge de Helm, que preserva lo que no aparece ni en
el render viejo ni en el nuevo.

O sea que todo el alerting de Grafana dependía de un accidente afortunado. Un
`helm upgrade --force`, un `kubectl replace` desde la salida del chart, un
cambio del chart que reestructurase `volumes`, o reconstruir el release desde el
fichero de valores que acabo de añadir en el commit anterior — cualquiera de las
cuatro se lo habría llevado por delante. Y en silencio: los paneles seguirían
pintando igual, solo dejarían de llegar los avisos.

Se declara con grafana.extraConfigmapMounts. Comprobado antes de aplicar que el
spec renderizado es equivalente al vivo (subPath/readOnly a null y defaultMode
420 son los valores por defecto), así que el pod NO se ha reiniciado: mismo
nombre antes y después. Y verificado lo que de verdad importaba: renderizando
SOLO desde values-kube-prometheus-stack.yaml, el volumen aparece — el fichero ya
basta para reconstruir el release entero sin perder el alerting.

Encontrado haciendo el chequeo posterior al upgrade de las alertas de ruido, no
por el upgrade en sí: llevaba así desde que se montó.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 17:09:44 +00:00
chemavxandClaude Opus 4.8 d9d616fd26 monitoring: silencia 4 alertas que llevaban meses sin significar nada
Tres eran falsos positivos de k3s: KubeControllerManagerDown, KubeSchedulerDown
y KubeProxyDown llevaban 92 DÍAS disparadas en severidad critical. En k3s esos
tres componentes van embebidos en el proceso del servidor y no exponen las
métricas que espera el chart, así que sus ServiceMonitors nunca conectaban: la
alerta no medía la salud de nada, solo la ausencia de un target imposible.

La cuarta, PrometheusNotConnectedToAlertmanagers, llevaba disparada desde el
reinicio del máster del 16-jul. La causa es de diseño: alertmanager.enabled es
false y los avisos van por Grafana→Telegram y Kuma→Telegram. Ya se había
desactivado el grupo de reglas `alertmanager`, pero esta alerta vive en el
grupo `prometheus`, así que sobrevivió; se quita por nombre con
defaultRules.disabled.

Tres "critical" permanentes no son un aviso, son entrenamiento para ignorar el
panel: cuando algo se rompa de verdad, se perderá entre el ruido.

Hecho por Helm y no a mano (rev 1 → 2, mismo chart 83.2.0), que es lo único que
sobrevive a un futuro upgrade. Verificado ANTES de aplicar renderizando el chart
con y sin los valores nuevos: el diff quita exactamente esas 4 alertas (141 →
137) y ningún recurso nuevo aparece. Comprobado además que el render reproduce
el manifiesto ya desplegado, o sea que no había ediciones a mano que el upgrade
fuese a aplastar.

Después: 1 sola alerta disparada (Watchdog, el latido intencionado del chart,
severity none) y los 15 targets de scrape en up — antes 3 fallaban siempre.
Grafana sano (api/health ok, 12.4.2) y su contraseña rotada intacta, porque
GF_SECURITY_ADMIN_PASSWORD solo aplica en el primer arranque.

Se añade values-kube-prometheus-stack.yaml: este namespace no está bajo ArgoCD y
hasta hoy los valores del release solo vivían dentro de Helm, sin forma de saber
cómo estaba configurado sin interrogarlo. Se refresca el export del ConfigMap de
reglas y se borran 3 dashboards que el upgrade eliminó del cluster.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 17:04:29 +00:00
chemavxandClaude Opus 4.8 999efe6956 researchowl: SEO_AUTOFILL on → dryrun
Cierra el cambio de orden del flujo editorial. Con 'on', ResearchOwl escribía
el SEO en el borrador nada más generarlo — pero el SEO es DERIVADO del
artículo, y la revisión editorial posterior cambia el texto: la meta acababa
describiendo algo que ya no existía y había que rehacerla a mano en cada post.
Caso real del 2026-07-20: la meta del artículo belga decía 'A declassified
case unsolved' cuando el artículo argumenta que los datos crudos siguen
clasificados.

Con 'dryrun' el borrador se crea sin SEO y autofill solo lo PROPONE por
Telegram. El SEO se deriva del texto FINAL en el remate (seo_finish.py), que
además escribe el feature_image_alt — imposible en generación porque la imagen
destacada aún no se ha elegido (de ahí el 'human adds later' de autofill.py,
un paso humano que no ocurría: 9 posts publicados sin alt entre el 29-jun y
el 16-jul).

Contrapartida asumida: si un post se publica SIN pasar por el remate, saldrá
sin SEO. Red de seguridad: seo_watch marca meta_description.missing como HIGH,
y seo-check sigue disponible como puerta pre-publicación.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 11:27:38 +00:00
chemavxandClaude Fable 5 e00c520a26 Decomisión de openclaw
- Elimina manifests openclaw/ y argocd/application-openclaw.yaml
- backup-system: fuera del backup diario, crown-jewels, expected y retain;
  fuera el mount hostPath del cronjob y la fila de RESTORE.md
- monitoring: eliminado panel openclaw del dashboard homelab-overview
- n8n: openclaw y polymarket fuera del health-check (espejo del workflow vivo)
- cluster-wide/namespaces.yaml: fuera openclaw + añadidos separadores '---'
  que faltaban (el archivo era un único doc YAML donde ganaba el último ns)

Cluster ya limpio: app ArgoCD, namespace, PVC/PV, RBAC cluster-scoped y
monitor de Uptime Kuma. Backup final: ~/decommissioned/openclaw-final-2026-07-18.tar.gz

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 14:57:46 +00:00
chemavxandClaude Fable 5 09643943cb feat(portfolio): refresh de la landing — fix /ze/, fuera Open WebUI, nuevos servicios y proyectos
- fix: card ze apunta a /ze/ (el redirect de nginx a http:// caía en 404 de Traefik)
- fuera Open WebUI (chat.chemavx.xyz no existe) y card duplicada de polymarket en Services
- nuevos servicios: Uptime Kuma, Infisical, Trilium, Files, Umami, Ollama
- Projects: blogs The Exclusion Zone (EN) y Zona de Exclusión (ES) + ResearchOwl
- badges de infra bajo el header y subtítulos en las cards; Status en el footer

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:44:58 +00:00
chemavxandClaude Fable 5 376eab68b6 decommission(F4): retirar polymarket-bot — Application y manifests
Fase final de la decomisión: namespace y Application borrados del cluster,
manifests fuera de git. Dump definitivo verificado y offsite en
/data/backups/backups/polymarket-decommission/ (espejo en mega:k3s-backups/).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:29:10 +00:00
chemavxandClaude Fable 5 c99d0a978e chore(backup-system): consolidar config rclone en Infisical (mega+b2)
El bloque [b2] ya vive en RCLONE_CONF (Infisical /backup-system); los 3
CronJobs vuelven a rclone-conf-infisical y se elimina el secret
out-of-band rclone-conf-b2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 19:18:32 +00:00
chemavxandClaude Fable 5 c364d46ac6 feat(backup-system): segundo offsite Backblaze B2 (crown jewels)
- b2-crown-jewels.sh: sync diario 04:00 de las 2 copias mas recientes de
  cada servicio irremplazable (todo menos uptime-kuma) a
  b2:chemavx-k3s-backups/crown-jewels/ (~2GB, tier gratuito).
- reddit-intel.sh sube tambien a B2 (retencion 3d).
- verify.sh comprueba Mega (completo) + B2 (crown jewels).
- Config via Secret out-of-band rclone-conf-b2 (mega+b2, kubectl, NO git);
  consolidar en Infisical RCLONE_CONF cuando se anada [b2] por UI (la
  identity del operator es read-only por API).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 17:24:02 +00:00
chemavxandClaude Fable 5 39ea16fe91 fix(backup-system): excluir binarios reproducibles del tar de home (.warp, .local/share/claude, .local/lib)
1.5G -> ~500M por dia de churn en Mega; .local/bin y .local/state se conservan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:44:10 +00:00
chemavxandClaude Fable 5 e9eb8c4ae2 fix(backup-system): kubectl via ServiceAccount in-cluster, no kubeconfig del host
El k3s.yaml del host apunta a 127.0.0.1:6443 (inalcanzable desde el pod).
El script antiguo solo funcionaba porque su KUBECONFIG apuntaba a un
fichero inexistente y kubectl caia en fallback al SA. Se hace explicito:
unset KUBECONFIG + RBAC con apps/deployments,statefulsets get (para
kubectl exec deploy/...) y se retira el mount del kubeconfig.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:39:25 +00:00
chemavxandClaude Fable 5 ed3d886090 feat(backup-system): cobertura completa del homelab + sync diario a Mega
- backup.sh: fix openclaw (tar-eaba un hostPath stub vacio, 104 bytes/dia
  desde hace meses); ahora resuelve el PVC real via local-path.
- Nuevos servicios: ghost-en/zona-exclusion (VACUUM INTO consistente via
  node del pod + tar del content), gitea (sqlite .backup + repos + conf,
  sin packages 6.4G reconstruibles), researchowl (sqlite backup API via
  python3), roswell-pg, umami-pg, infisical-pg, trilium, vaultwarden,
  uptime-kuma (sqlite3 .backup), filebrowser-db, home-master (sin ~/.ssh
  ni caches), k3s token + /etc/rancher/k3s (cadena de restauracion).
- Validacion por artefacto: gzip -t + tamano minimo; el job sale 1 si
  falta algo -> alerta Grafana->Telegram existente.
- rclone-mega: de semanal a diario (03:30); --exclude reddit-intel/.
- Nuevo CronJob reddit-intel-backup en n97 (unico dato del worker fuera
  de k3s; su cron local escribia en el mismo disco).
- verify.sh: lista completa (20 servicios + reddit-intel), diario,
  ventana de frescura 3 dias (BusyBox-safe).
- backoffLimit 1 (retry recrearia artefactos y romperia la retencion).
- RESTORE.md: runbook con la cadena token->state.db->infisical-secrets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 16:12:27 +00:00
chemavxandClaude Fable 5 005b13bd91 feat(roswell): corte a secretos Infisical — refs *-infisical en deployment, postgres y backup
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:37:14 +00:00
chemavxandClaude Fable 5 1b9a7bdddc fix(roswell): un InfisicalStaticSecret por target — el operator ignora targets extra
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:31:04 +00:00
chemavxandClaude Fable 5 d903fd4631 feat(roswell): postgres a ClusterIP y secretos Infisical preparados (alta manual pendiente en /roswell)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:20:25 +00:00
chemavxandClaude Fable 5 7e60b5e8d5 fix(roswell): pin a chemavx-k8 y límite 6Gi — Whisper large-v3 OOMKilled con 4Gi en el nodo pequeño
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:05:03 +00:00
chemavxandClaude Fable 5 6416c6c3af feat(roswell): despliegue GitOps del corpus — bot+scheduler, backup pg_dump diario, postgres adoptado
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:29:19 +00:00
chemavxandClaude Fable 5 91bf7d2909 fix(researchowl): memory limit 1Gi → 2Gi
El pod fue OOMKilled el 2026-07-10 durante un research: 20 fuentes
concurrentes con PDFs grandes y pdfplumber superaron 1Gi. El scraper
se endurece en paralelo (cap PDF 15MB, contenido 300k chars), pero el
margen extra evita que un pico legítimo mate la tarea en memoria.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 09:38:53 +00:00
chemavxandClaude Fable 5 395102a85e feat(n8n): auto-reload del deployment al cambiar n8n-secret-infisical (operator Infisical)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 15:16:33 +00:00
chemavxandClaude Fable 5 9dbcb0896e fix(n8n): N8N_BLOCK_ENV_ACCESS_IN_NODE=false — n8n bloquea $env por defecto y el autopost no podía leer GETXAPI_TOKEN
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:38:32 +00:00
chemavxandClaude Fable 5 f29256ca55 feat(n8n): inyectar GETXAPI_TOKEN desde n8n-secret-infisical (rotación token X autopost)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:30:20 +00:00
chemavxandClaude Fable 5 e1a25329d4 feat(monitoring): alerta Telegram para jobs fallidos de backup-system
Regla homelab-backup-job-failed (kube_job_status_failed{namespace="backup-system"} > 0)
en el grupo homelab-infra; cubre backup, rclone-mega-backup y backup-verify.
Aplicado con kubectl replace + rollout restart de Grafana (namespace manual).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:37:28 +00:00
chemavxandClaude Fable 5 d1d2fac287 feat(backup-system): migración completa a GitOps
- CronJob rclone-mega-backup entra en git (solo existía imperativo)
- Scripts backup.sh/verify.sh/rclone-mega.sh como ConfigMap backup-scripts
  (antes hostPath /data/backups/scripts — cambios ahora pasan por git+ArgoCD)
- rclone.conf vía InfisicalStaticSecret (homelab/prod//backup-system → RCLONE_CONF),
  sustituye al hostPath de ~/.config/rclone/rclone.conf
- Imágenes pinneadas: rclone 1.74.3, bitnami/kubectl por digest (v1.36.2)
- ClusterRole/CRB de backup-sa entran en git
- Application ArgoCD backup-system (auto-sync + prune + selfHeal)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:33:35 +00:00
chemavxandClaude Fable 5 ae0b5f9492 feat(reddit-intel): manifiestos preparados, INACTIVOS hasta promoción
App corre en docker compose en n97 (semana de calibración). El app-of-apps
no es recursivo: nada de este directorio se sincroniza hasta aplicar a mano
argocd-app.yaml. Checklist de activación en PROMOTION.md (imagen construida,
secrets en Infisical /reddit-intel, copia de la BD al PVC).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 17:14:06 +00:00
chemavx f059470fde decommission(F3): activar tarjeta Archived del bot en el portfolio
Merge de feat/portfolio-polymarket-archived con las cifras finales de
cierre (12 trades, +$247.78 realized, 239k evaluaciones, 81 días).
El widget deja de consultar la API (apagada) y pasa a tarjeta estática
con enlace al case study.
2026-07-06 12:20:48 +00:00
chemavx 6cf4615596 decommission(F3): apagar postgres (replicas 0)
El dump definitivo de cierre está tomado y verificado (restore 11/11 en
/data/backups/backups/polymarket-decommission/). El PVC se conserva.
2026-07-06 12:19:33 +00:00
chemavx dd10f26f31 decommission(F3): suspender cronjobs metrics-retention y outcomes-joiner
Sin bot ni postgres ya no hay nada que retener ni joinear; suspend en vez
de borrar para conservar la definición durante la semana de gracia.
2026-07-06 12:19:33 +00:00
chemavx 8a89d0bd46 feat(portfolio): cifras finales del widget al cierre real (239k evaluaciones)
Snapshot del apagado 2026-07-06 con el bot ya detenido: 12 trades,
realized +$247.78, 239.462 evaluaciones, 81 días observados.
2026-07-06 12:16:23 +00:00
chemavx 0f8bd407f4 decommission(F3): apagar bot, api y dashboard (replicas 0)
Primer paso del apagado ordenado: se detiene el ciclo de evaluación con
postgres aún vivo, para que el dump final sea la foto exacta del cierre
sin ciclos a medias. Postgres y cronjobs se apagan en commits siguientes.
2026-07-06 12:05:43 +00:00
chemavx dc45c913a5 decommission(F2): silenciar notificaciones Telegram de la app polymarket-bot
Se retiran las suscripciones on-sync-failed / on-health-degraded: durante
el apagado (F3) generarían ruido sin valor. No hay trigger 'informativo'
viable: escalar a 0 vía git deja la app Synced/Healthy. El resto de apps
conservan sus notificaciones.
2026-07-06 11:47:33 +00:00
chemavx abcb38bd6d decommission(F2): retirar smoke test PostSync de polymarket-bot
El Job notificaba a Telegram tras cada sync; en decomisión ya no hay
deploys que verificar y sus avisos serían ruido durante el apagado.
2026-07-06 11:47:11 +00:00
chemavxandClaude Fable 5 59bc269923 feat(portfolio): tarjeta Polymarket Bot pasa a Archived / case study
Sustituye el widget live (fetch a polymarket.chemavx.xyz/api/summary) por
una tarjeta estática con las cifras finales del paper trading y enlace al
case study en el repo. La tarjeta de servicio apunta al repo de Gitea en
lugar del dominio, que desaparecerá con el apagado.

NO MERGEAR HASTA F2/F3: mientras el bot siga vivo, main mantiene el
widget live. Aplicar esta rama cuando se apague el bot (Fase 3 del plan
de decomisión).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 07:40:09 +00:00
chemavxandClaude Fable 5 98a939fb22 feat(researchowl): activa ENABLE_NEWS_SEED (seed Bing News RSS)
Flag flip aislado — el código (a23810b) ya está desplegado con el flag
en False por defecto.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 11:03:08 +00:00
chemavxandClaude Fable 5 ca520d3ca3 feat(researchowl): daily SQLite backup CronJob + 5Gi backups PVC
Online-safe sqlite3 .backup at 03:00 Europe/Madrid, integrity check,
7-day retention. Data PVC mounted RW (WAL -shm requirement) but only read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 10:43:41 +00:00
chemavxandClaude Fable 5 214b4a10a4 feat(researchowl): MAX_SOURCES 150 -> 200
Tras el plan F1-F4 del scraper, el seed descubre hasta ~285 fuentes en
topics documentados y el cap de 150 descartaba la mitad (incluida la
recursión que encuentra los PDFs de archive.org). 200 cubre casi todos
los resultados directos + margen de recursión. Implica +2-4 min por
research de topic rico y céntimos más de scoring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 15:53:18 +00:00
chemavxandClaude Fable 5 29714cdc29 fix(vaultwarden): bump 1.35.4 -> 1.36.0 (support Bitwarden 2026.x clients)
Extension login failed with 'No Bitwarden-Client-Version header provided'
after the Mac browser extension auto-updated. 1.36.0 supports the new
client login flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 11:24:04 +00:00
chemavxandClaude Fable 5 7dc2b41d63 feat(researchowl): activar monitor de noticias RSS (NEWS_ENABLED=true)
Flip del flag que deja operativo el monitor F0-F2 ya desplegado en
b1c5bc73. Defaults: poll cada 6h, digest al primer TELEGRAM_ALLOWED_USERS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:01:58 +00:00
chemavxandClaude Fable 5 1e143a1468 feat(polymarket-bot): CronJob diario outcomes-joiner (Replay R2)
Corre python -m bot.outcomes a las 00:30 UTC (tras metrics-retention a
las 00:10): resoluciones UMA-finales de Gamma -> market_outcomes + reporte
de calibración. Solo-análisis: no toca tablas de trading. Idempotente por
market_id, seguro relanzarlo a mano. Misma imagen del bot; CI bumpa el tag
(cambio correspondiente en polymarket-bot/.gitea/workflows/ci.yml).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 20:20:51 +00:00
chemavxandClaude Opus 4.8 71c552f3d5 chore(n8n): remove vestigial ignoreDifferences (secret now Infisical-managed)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 08:01:51 +00:00
chemavxandClaude Opus 4.8 9bcb84ebc8 fix(cloudflare-ddns): add theexclusionzone.com zone with per-domain PROXIED
The theexclusionzone.com (Ghost EN) zone was never in DOMAINS, so favonia
never updated its origin A records. When the ISP rotated the public IP, the
EN records went stale and Cloudflare returned 522 (apex+www are proxied).

Add all three EN records to DOMAINS and use favonia 1.16.2's per-domain
PROXIED expression so apex+www stay orange while the wildcard and the
chemavx/zona zones stay grey, all from one DDNS instance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:01:23 +00:00
chemavx c7e8e28abd feat(researchowl): enable SEO autofill (SEO_AUTOFILL=on)
Activates the autofill publish path in production. Drafts now get
meta/OG/Twitter/tags/internal-links best-effort; status stays draft.
2026-06-25 15:02:29 +00:00
chemavxandClaude Opus 4.8 48ed88cc8d zona-exclusion: serve www + 301 redirect to apex, add www to TLS SAN
Adds www.zonadeexclusion.com to the Ingress (rules + tls hosts) so cert-manager
re-issues zona-exclusion-tls covering apex + www via HTTP-01, and a Traefik
redirectRegex Middleware that 301s www -> apex (ES canonical = apex). Mirrors the
EN redirect-to-www-https middleware, inverted. DNS for www was fixed in Phase 1
(stale explicit A removed; now resolves via the favonia wildcard).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 06:55:56 +00:00
chemavxandClaude Opus 4.8 81745dee4b n8n: decommission old n8n-secret (remove empty stub + ignoreDifferences)
3c: n8n now sources the encryption key from n8n-secret-infisical (Infisical).
Remove the empty CreateOnly stub manifest and the now-dead ignoreDifferences
/data stanza so ArgoCD prunes the old out-of-band n8n-secret.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:35:46 +00:00
chemavxandClaude Opus 4.8 77f55fb100 n8n: repoint encryption-key secretKeyRef to n8n-secret-infisical + Recreate
Cut n8n over to the Infisical-synced encryption key (byte-identical, key never
changes -> credentials stay decryptable) and switch RollingUpdate -> Recreate
(485MB SQLite + WAL on RWO must not have two writers during a roll).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:31:10 +00:00
chemavxandClaude Opus 4.8 5c7323c533 n8n: add InfisicalStaticSecret for n8n-secret (centralize N8N_ENCRYPTION_KEY)
Out-of-band Secret -> Infisical homelab/prod /n8n. Parallel-name target
n8n-secret-infisical (Owner), passthrough of the single key encryption-key
(n8n's irrecoverable credentials-encryption root, lifted byte-identical).
Old secret stays live until decommission. ArgoCD-managed -> git->sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:30:28 +00:00
chemavxandClaude Opus 4.8 88cab601b2 authentik: repoint server+worker secretKeyRefs to authentik-secrets-infisical
Both AUTHENTIK_SECRET_KEY and AUTHENTIK_POSTGRESQL__PASSWORD (env) -> key
POSTGRES_PASSWORD now sourced from the Infisical-synced secret. Stateless re: DB
(media PVC only), DB-retry logic -> stay RollingUpdate, no Recreate flip.
Applied via kubectl (not ArgoCD-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:16:24 +00:00
chemavxandClaude Opus 4.8 77b0b2385d authentik: repoint postgres sts POSTGRES_PASSWORD to authentik-secrets-infisical
Postgres-first cutover step. Already-initialized PG17 ignores POSTGRES_PASSWORD
on restart (role pw in pg_authid), so this byte-identical roll is benign.
StatefulSet RollingUpdate is ordered terminate-then-create (no two-postmaster
surge), so no Recreate flip. Applied via kubectl (not ArgoCD-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:14:52 +00:00
chemavxandClaude Opus 4.8 26871ef0c3 authentik: add InfisicalStaticSecret for authentik-secrets (centralize SSO secret)
Out-of-band Secret -> Infisical homelab/prod /authentik. Parallel-name target
authentik-secrets-infisical (Owner), passthrough of the 2 LIVE keys
(AUTHENTIK_SECRET_KEY, POSTGRES_PASSWORD). The dead orphan key
AUTHENTIK_POSTGRESQL__PASSWORD is intentionally dropped. Old secret stays live
until decommission. Applied via kubectl (not ArgoCD-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 11:14:18 +00:00
chemavxandClaude Opus 4.8 74c00cc7b7 vaultwarden: repoint envFrom to vaultwarden-secret-infisical + Recreate strategy
Cut the Deployment over to the Infisical-synced Secret and switch to Recreate
(SQLite/WAL on a RWO PVC must not have two writers during a roll). Applied via
kubectl (not ArgoCD-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 10:57:13 +00:00
chemavxandClaude Opus 4.8 f87f03d542 vaultwarden: add InfisicalStaticSecret for vaultwarden-secret (centralize ADMIN_TOKEN/DOMAIN/SIGNUPS_ALLOWED)
Out-of-band Secret -> Infisical homelab/prod /vaultwarden. Parallel-name
target vaultwarden-secret-infisical (Owner), passthrough. Old vaultwarden-secret
stays live until decommission. Applied via kubectl (not ArgoCD-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 10:56:13 +00:00
chemavxandClaude Opus 4.8 184c5f4815 umami: drop dead umami-secrets ignoreDifferences stanza (3c)
Old out-of-band umami-secrets deleted (kubectl); the /data ignoreDifferences
stanza referencing it is now dead. Removed from both the registered app
manifest and the in-dir duplicate. umami-secrets-infisical is Owner-managed
by the operator, not a git-tracked Secret, so no ignore rule is needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:58:20 +00:00
chemavxandClaude Opus 4.8 b566fe3d96 umami: repoint umami app to Infisical secret (3b-ii)
DATABASE_URL + APP_SECRET now reference umami-secrets-infisical. Postgres
(3b-i) already healthy on the same secret; umami's wait-for-postgres
initContainer enforces ordering. Old umami-secrets stays live until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:56:37 +00:00
chemavxandClaude Opus 4.8 9e2971f1bc umami: repoint postgres to Infisical secret + flip to Recreate (3b-i)
POSTGRES_PASSWORD now references umami-secrets-infisical. Adds strategy:
Recreate (single-replica RWO PVC — avoids two postmasters racing PGDATA
during a roll), permanent. Data dir already initialized, so the
byte-identical POSTGRES_PASSWORD is never re-applied on restart (benign).
umami still on old umami-secrets (both live in parallel = zero gap).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:55:59 +00:00
chemavxandClaude Opus 4.8 a86934c264 umami: add Infisical StaticSecret (/umami passthrough, parallel name)
3a of the umami-secrets centralization. Adds umami-secrets-infisical synced
from homelab/prod /umami (3 lowercase-hyphenated keys, passthrough).
Parallel name — old out-of-band umami-secrets stays live until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:55:11 +00:00
chemavxandClaude Opus 4.8 384c3e4542 researchowl: repoint to Infisical secret + flip to Recreate
3b of the centralization. All 5 secretKeyRefs now reference
researchowl-secrets-infisical (synced from /researchowl). Also adds
strategy: Recreate (single-replica RWO SQLite/WAL — avoids two pods
briefly sharing /data/researchowl.db during a roll), permanent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:40:21 +00:00
chemavxandClaude Opus 4.8 428f708fe2 researchowl: add Infisical StaticSecret (/researchowl passthrough, parallel name)
3a of the researchowl-secrets centralization. Adds researchowl-secrets-infisical
synced from homelab/prod /researchowl (5 lowercase-hyphenated keys, passthrough).
Parallel name — old out-of-band researchowl-secrets stays live until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 06:38:59 +00:00
chemavxandClaude Opus 4.8 1dbedead2f zona-exclusion: drop dead zona-exclusion-secrets ignoreDifferences (3c)
Old out-of-band zona-exclusion-secrets deleted (kubectl); SMTP now sourced from
Infisical-backed zona-exclusion-secrets-infisical. Remove the obsolete /data
ignoreDifferences stanza from both app manifests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:12:57 +00:00
chemavxandClaude Opus 4.8 fd207da3cc zona-exclusion: repoint SMTP to Infisical secret + Recreate strategy (3b)
- mail__options__auth__user/pass secretKeyRef
    zona-exclusion-secrets -> zona-exclusion-secrets-infisical (remapped keys)
- strategy RollingUpdate -> Recreate (single-replica RWO SQLite Ghost; avoids
    two-pods-on-one-ghost.db overlap during rolls)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:11:34 +00:00
chemavxandClaude Opus 4.8 6043e7d66c zona-exclusion: stage Infisical-backed SMTP secret with key remap (3a)
InfisicalStaticSecret syncs shared /smtp-gmail -> zona-exclusion-secrets-infisical,
template-remapping UPPER_SNAKE -> hyphenated lowercase smtp-user/smtp-pass to match
the deployment secretKeyRef. Old secret stays live until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:10:48 +00:00
chemavxandClaude Opus 4.8 dd28956d76 ghost-en: drop dead ghost-en-smtp ignoreDifferences (3c)
Old out-of-band ghost-en-smtp secret deleted (kubectl); SMTP now sourced from
Infisical-backed ghost-en-smtp-infisical. Remove the now-obsolete /data
ignoreDifferences stanza from both app manifests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:09:15 +00:00
chemavxandClaude Opus 4.8 bafbdc8a3b ghost-en: repoint SMTP to Infisical-backed secret (3b)
mail__options__auth__user/pass secretKeyRef
  ghost-en-smtp -> ghost-en-smtp-infisical
Recreate roll picks up the Infisical-synced credentials.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:06:41 +00:00
chemavxandClaude Opus 4.8 d3bd1a3503 ghost-en: stage Infisical-backed SMTP secret (3a)
InfisicalStaticSecret syncs shared /smtp-gmail -> ghost-en-smtp-infisical
(parallel name, passthrough SMTP_USER/SMTP_PASS). Old secret stays live until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:06:04 +00:00
chemavxandClaude Opus 4.8 29d817547b gitea-runner: repoint token to Infisical-backed secret (3b, out-of-band)
env GITEA_RUNNER_REGISTRATION_TOKEN secretKeyRef
  gitea-runner-secret -> gitea-runner-secret-infisical
Rolls the pod: fresh emptyDir -> act_runner re-registers with same-value token.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:49:16 +00:00
chemavxandClaude Opus 4.8 8e162130dd gitea-runner: stage Infisical-backed secret (3a, out-of-band)
InfisicalStaticSecret syncs /gitea-runner -> gitea-runner-secret-infisical
(parallel name). Out-of-band: created via kubectl apply; commit is for record.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 21:48:46 +00:00
chemavxandClaude Opus 4.8 41a4f13bc3 Repoint cloudflare-ddns deployment to cloudflare-ddns-secret-infisical (cloudflare-ddns 3b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:58:14 +00:00
chemavxandClaude Opus 4.8 c6efbdc469 Add cloudflare-ddns InfisicalStaticSecret from /cloudflare-ddns (cloudflare-ddns 3a, out-of-band)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:57:49 +00:00
chemavxandClaude Opus 4.8 48a2577f2a Repoint renovate cronjob to renovate-token-infisical (renovate 3b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:52:41 +00:00
chemavxandClaude Opus 4.8 442e329c89 Add renovate-token InfisicalStaticSecret from /renovate (renovate 3a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:51:53 +00:00
chemavxandClaude Opus 4.8 f5364500f6 Remove plaintext grafana-telegram Secret from git (monitoring 3c)
7th and final copy of the Telegram bot token leaving git. monitoring is
out-of-band (not ArgoCD-managed), so the live secret is pruned manually with
kubectl. Grafana already reads grafana-telegram-infisical (from /telegram).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:34:08 +00:00
chemavxandClaude Opus 4.8 e1fd0c9283 Repoint grafana TELEGRAM_* env to grafana-telegram-infisical (monitoring 3b, out-of-band)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:30:24 +00:00
chemavxandClaude Opus 4.8 a89d6e9a9a Add grafana-telegram InfisicalStaticSecret from /telegram (monitoring 3a, out-of-band)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:28:51 +00:00
chemavxandClaude Opus 4.8 07aacc6878 Remove plaintext bot-secrets Secret from git (polymarket-bot 3c)
Last plaintext secret leaving git; the 6th/last copy of the Telegram token.
ArgoCD prunes the live bot-secrets Secret (and its cleartext
last-applied-configuration annotation). Consumers already on bot-secrets-infisical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:21:53 +00:00
chemavxandClaude Opus 4.8 dc0d24ded6 Repoint api/bot envFrom + cronjob to bot-secrets-infisical + bot-config (polymarket-bot 3b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:18:35 +00:00
chemavxandClaude Opus 4.8 fb9170ec5b Add bot-secrets InfisicalStaticSecret + bot-config ConfigMap (parallel, polymarket-bot 3a)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:16:24 +00:00
chemavxandClaude Opus 4.8 318d66303a Remove plaintext htpasswd Secret from git (filebrowser)
Phase 3c of migration #2: drop the Secret stanza from auth.yaml; the Middleware
stays and references filebrowser-auth-infisical (synced from homelab/prod
/filebrowser). ArgoCD prunes the old plaintext filebrowser-auth secret — the
bcrypt htpasswd leaves git. Completes migration #2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:52:24 +00:00
chemavxandClaude Opus 4.8 7e9ee295e4 Repoint filebrowser Traefik Middleware to filebrowser-auth-infisical
Phase 3b of migration #2: Middleware.spec.basicAuth.secret now references the
Infisical-managed secret. Secret stanza in auth.yaml left in place as fallback
until 3b is verified (401 w/o creds, 200 w/ creds), then removed in 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:46:46 +00:00
chemavxandClaude Opus 4.8 58851adf9a Add filebrowser InfisicalStaticSecret for basic-auth (parallel)
Phase 3a of migration #2: syncs FILEBROWSER_USERS from homelab/prod /filebrowser
via read-only infisical-operator/infisical-auth, template-remapped to the
lowercase 'users' key Traefik basic-auth requires, into parallel-name
filebrowser-auth-infisical. Old plaintext filebrowser-auth secret + the Traefik
Middleware untouched (repoint=3b, removal of the Secret stanza=3c).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:45:12 +00:00
chemavxandClaude Opus 4.8 0e50d88b54 Remove plaintext telegram-notify secrets from git (n8n/portfolio/openclaw/polymarket-bot)
Phase 3c: hooks now read telegram-notify-infisical (synced from homelab/prod
/telegram). Deleting these 4 manifests prunes the old plaintext secrets — the
bot token leaves git for the remaining 4 namespaces. Completes migration #1.

NOTE: polymarket-bot/bot-secrets still embeds the same token (migration #3).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:34:16 +00:00
chemavxandClaude Opus 4.8 b124f128e6 Repoint PostSync hooks to telegram-notify-infisical (n8n/portfolio/openclaw/polymarket-bot)
Phase 3b: all 4 hooks' secretKeyRefs now read the Infisical-managed secret.
Old plaintext telegram-notify secrets stay as fallback until 3c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:31:02 +00:00
chemavxandClaude Opus 4.8 7b1f2da613 Add InfisicalStaticSecret for telegram-notify in n8n/portfolio/openclaw/polymarket-bot (parallel)
Phase 3a of telegram-notify migration: each syncs TELEGRAM_BOT_TOKEN/
TELEGRAM_CHAT_ID from shared homelab/prod /telegram via read-only
infisical-operator/infisical-auth, into parallel-name telegram-notify-infisical.
Old plaintext secrets + hooks untouched (repoint=3b, removal=3c).
polymarket-bot: standalone secret only; bot-secrets copy is migration #3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:28:30 +00:00
chemavxandClaude Opus 4.8 c52e7c751a Remove plaintext telegram-notify secret from git (researchowl)
The PostSync hook now reads telegram-notify-infisical (synced from
homelab/prod /telegram). Deleting this manifest prunes the old plaintext
secret — the bot token leaves git for researchowl. Security win.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:26:08 +00:00
chemavxandClaude Opus 4.8 c12c41fb63 Repoint researchowl PostSync hook to telegram-notify-infisical
Both secretKeyRefs (TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID) now read the
Infisical-managed secret instead of the plaintext-in-git telegram-notify.
Old secret stays as fallback until 3c removes its manifest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:21:30 +00:00
chemavxandClaude Opus 4.8 5445722ab1 Add researchowl InfisicalStaticSecret for telegram-notify (parallel)
Syncs TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID from shared homelab/prod /telegram
via the read-only infisical-operator/infisical-auth. Targets parallel-name
telegram-notify-infisical; old plaintext telegram-notify stays live until the
hook is repointed (3b) and the old manifest removed (3c).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 20:20:15 +00:00
chemavxandClaude Opus 4.8 f1ad60b046 Cut over polymarket-bot deployments to Infisical-managed pull secret
api/bot: imagePullSecrets gitea-registry -> gitea-registry-infisical.
dashboard: add gitea-registry-infisical (previously had NO pull secret
despite pulling a private image — fixes latent ErrImagePull-on-reschedule
bug). Old gitea-registry stays as rollback net until decommission.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 06:37:55 +00:00
chemavxandClaude Opus 4.8 3957b69b10 Add polymarket-bot InfisicalStaticSecret for gitea-registry pull secret
Reconstructs the dockerconfigjson pull secret from the shared /registry v3
fields (GITEA_REGISTRY_USERNAME/GITEA_REGISTRY_TOKEN) via the shared
infisical-operator/infisical-auth. Targets parallel-name
gitea-registry-infisical; old gitea-registry stays live until cutover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 06:27:47 +00:00
chemavxandClaude Opus 4.8 9d2dd78542 Cut over researchowl deployment to Infisical-managed pull secret
imagePullSecrets: gitea-registry -> gitea-registry-infisical (the
InfisicalStaticSecret-managed dockerconfigjson). Old gitea-registry stays
as rollback net until decommission.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 06:17:38 +00:00
chemavxandClaude Opus 4.8 36296ad5ea Add researchowl InfisicalStaticSecret for gitea-registry pull secret
Reconstructs the dockerconfigjson pull secret from the discrete
GITEA_REGISTRY_USERNAME/GITEA_REGISTRY_TOKEN fields at homelab/prod /registry,
via the shared infisical-operator/infisical-auth. Targets parallel-name
gitea-registry-infisical; old gitea-registry stays live until cutover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 06:11:41 +00:00
chemavxandClaude Opus 4.8 5a0fd04598 Add shared Infisical auth layer (InfisicalConnection + InfisicalAuth)
Phase 2: GitOps-managed shared auth layer in infisical-operator ns —
InfisicalConnection (https://infisical.chemavx.xyz) + InfisicalAuth
(kubernetes method, operator SA via TokenReview) + identity-ID Secret
(non-secret UUID; auth is via SA token, so safe in git). To be referenced
cross-namespace by per-app InfisicalStaticSecret CRs later. No real secret yet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 20:39:30 +00:00
chemavxandClaude Opus 4.8 5f6b491ed3 Add Infisical token-reviewer RBAC for Kubernetes Auth
Phase 2 Step 2: dedicated SA infisical-token-reviewer bound to
system:auth-delegator (TokenReview), explicit long-lived SA token Secret
(k8s 1.34 doesn't auto-create). ArgoCD ignores /data so selfHeal won't
strip the controller-populated token. Token value never committed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 16:05:59 +00:00
chemavxandClaude Opus 4.8 2c81ab03a7 Add Infisical Kubernetes operator (secrets-operator v0.11.1)
Phase 2 Step 1: controller-only, dedicated infisical-operator namespace,
hostAPI -> self-hosted instance, cluster-scoped, ServerSideApply for CRDs.
No InfisicalSecret CRs yet — operator sits idle until later UI config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 15:42:14 +00:00
chemavxandClaude Opus 4.8 c459eb3930 fix(infisical): single-source Helm with inline values
The multi-source variant ($values git ref) caused the infisical app to
prune its own Application object on first sync (controller pruned
Application/argocd/infisical, orphaning the workloads). Switch to a
single-source Helm app with inline valuesObject (same chart 1.9.0, same
DB/Redis passwords) and drop the hand-written tracking-id annotation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 06:51:23 +00:00
chemavxandClaude Opus 4.8 e548a06ebc feat(infisical): add Infisical platform (Phase 1, chart-managed pg/redis)
Deploy infisical-standalone 1.9.0 (Infisical v0.158.0) in a dedicated
'infisical' namespace via a multi-source ArgoCD app (chart + values).
Bundled Postgres (dedicated local-path PVC, 8Gi) + Redis. Ingress via
Traefik + cert-manager (letsencrypt-prod) at infisical.chemavx.xyz.

Crown-jewel secrets (ENCRYPTION_KEY, AUTH_SECRET, SITE_URL) are injected
out-of-band via the 'infisical-secrets' Secret (kubectl, IgnoreExtraneous),
NOT in git. Postgres/Redis passwords guard ClusterIP-only in-cluster
services holding ciphertext; acceptable in values per design review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 06:39:26 +00:00
chemavxandClaude Opus 4.8 6036b8d67b chore(polymarket-bot): remove gitea-registry secret from GitOps
The dockerconfigjson held the old account password (now rotated/revoked)
in plaintext. Manage this image-pull secret out-of-band via kubectl
(like researchowl), so no registry credential lives in git going forward.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 20:17:52 +00:00
chemavxandClaude Opus 4.8 6d30c0f3e0 fix(ghost-en): stage redirects via initContainer, not read-only mount
A ConfigMap volume is read-only at the FS level, so the Ghost entrypoint's
chown -R on content/ failed ("Read-only file system") and crash-looped.
Copy redirects.yaml onto the writable PVC with an initContainer instead;
still GitOps-sourced and refreshed on every pod start.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 10:40:07 +00:00
chemavxandClaude Opus 4.8 797471f744 feat(ghost-en): GitOps-managed redirect for old Pentagon slug
Recover ~454 GSC impressions stranded on a 404. Adds a ghost-en-redirects
ConfigMap (content/data/redirects.yaml) 301-redirecting the old slug
/pentagon-second-uap-declassification-may-2026-apollo-12-sandia/ to the
live /pentagon-uap-second-release-may-2026/. Mounted read-only via subPath
so it survives content PVC recreation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 10:35:33 +00:00
chemavxandClaude Fable 5 e42896a8c1 feat(ollama): enable prune, guarded by Prune=false on the models PVC
Last app without prune; now consistent with the rest of the cluster.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 15:58:50 +00:00
chemavxandClaude Fable 5 729e3ac4af fix: Prune=false guard on every PVC under a prune-enabled Application
Same protection already given to polymarket-bot postgres and n8n: without
it, removing a PVC manifest from git (rename, multi-doc refactor) would
make ArgoCD destroy the volume and its data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 15:55:23 +00:00