f772703051dd698bc5c06dd9f3c39c8cdd696a26
El ES nunca se había auditado: no había wrapper hasta hoy (ghst-es). Corre
ambos por defecto y emite un informe con una sección por sitio.
Detalles del diseño:
* canónico invertido entre sitios (EN www, ES apex) → SITES parametriza url,
cli y host.
* seo_rules.SITE_HOST se reasigna en runtime desde use_site(): ese fichero se
vendoriza byte a byte en ResearchOwl y la CI lo verifica, así que no se
puede parametrizar en origen.
* huella de estado por sitio (dict), para que un cambio en uno no reabra la
notificación del otro por accidente.
* un sitio caído no tumba el informe del otro: run_site va en try/except y
el error se reporta como hallazgo de ese sitio.
Primera pasada real: EN 0 hallazgos; ES 152 violaciones del auditor (28 sin
alt-text — todos —, 27 con enlazado flojo, 21 sin OG/Twitter). Ninguna dispara
Telegram: las violaciones de reglas son inventario, no regresión — solo avisan
los enlaces rotos/no canónicos/prematuros/envejecidos y el sitemap.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 viaghst-en).seo_validate.py— Tool C: single-post pre-publish validator (seo-checkwraps 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.
Languages
Python
100%