ChemaVXandClaude Opus 4.8 d381c0225c seo_watch/seo_link: dos fallos que se manifestaban callándose
1) El corpus se pedía con --limit 100. Con 40 posts en EN y 29 en ES sobraba,
   pero a 2 por semana habría cruzado los 100 hacia 2027 y se habría truncado
   EN SILENCIO. Y un corpus truncado no da error: da falsos «enlaces rotos»
   contra los posts que faltan, que es peor que no mirar. Pasa a --limit all
   y, sobre todo, se comprueba el número contra meta.pagination.total: eso es
   lo que convierte un fallo mudo en uno que se oye. En seo_link el truncado
   era aún peor, porque haría rechazar como inexistente un destino que sí
   está.

2) check_sitemap daba VERDE cuando curl fallaba: 0 URLs descargadas son 0
   problemas encontrados, y el informe decía « sin hallazgos». O sea que
   justo el rato en que el sitio está caído era cuando este check se callaba.
   Un sitemap vacío pasa a ser hallazgo con mensaje propio; en un blog con
   29-40 artículos nunca lo está legítimamente.

Probado con casos que DEBEN fallar: corpus recortado a 3 de 40 (revienta y lo
dice), corpus completo (pasa limpio), y sitemap vacío (hallazgo, informe claro
y notificaría). Y en real contra los dos blogs: EN 40 posts / 33 URLs, ES 29 /
31, ambos sin hallazgos.

No toca seo_rules.py, así que el vendor-sync con ResearchOwl sigue en verde.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 16:01:28 +00:00

seo-tools

SEO rule engine + tooling for the Ghost blogs (EN: theexclusionzone.com).

  • seo_rules.py — shared rule engine (pure functions, no I/O). Single source of truth for thresholds + checks. Consumed by the auditor, the validator, and (vendored) by ResearchOwl's blog pipeline.
  • seo_audit.py — Tool A: site-wide auditor (reads all published posts via ghst-en).
  • seo_validate.py — Tool C: single-post pre-publish validator (seo-check wraps this).
  • seo_exceptions.py — documented, consciously-accepted waivers (auditor reporting filter).
  • seo_mirror.py — OG/Twitter mirroring helper.
  • phase2_*.py/json — one-off batch helpers (kept for provenance).

No secrets live here. Ghost access is via the ghst-en wrapper (~/.local/bin), which fetches a staff token on demand from the pod and never writes it to disk.

S
Description
No description provided
Readme
683 KiB
Languages
Python 100%