2afe52b73183ac99be4fd99e58b9e6127e2de780
El hub del EN estaba bien escrito y por eso mismo se pudrió: decía «all 31
cases» con 33 publicados, y los dos últimos artículos (Ariel School,
Vilas-Boas) no estaban enlazados desde ningún sitio. El ES no tenía índice
ninguno. Un índice que se actualiza a mano caduca el día que dejas de
acordarte, así que lo que envejece lo calcula la herramienta y lo que hay que
pensar sigue en un fichero curado — el mismo reparto que hreflang-parejas.md.
La herramienta NUNCA escribe una frase. La descripción de una línea de cada
caso es lo único que hace útil un índice y sale de haber leído el artículo; la
meta_description está escrita para el SERP y suena a catálogo en fila con otras
treinta. `revisa` solo AVISA de lo que falta, y sale con código 1 para poder
colgarlo del vigilante.
Lo que sí calcula: el recuento ({N} en el texto, que era justo el dato falso),
publicados fuera del índice, entradas que apuntan a un post inexistente, y
enlaces PREMATUROS a programados — que darían 404 hasta que publiquen, la misma
piedra que ya documenta seo_link.py.
EXCLUIDOS existe por un caso concreto: el stub [Preview] de Grusch está
canonizado al artículo bueno y el hub enlazaba LOS DOS. Eso es sembrar
canibalización a mano. Sin una lista de exclusiones a propósito, la única forma
de callar a `revisa` sería volver a enlazarlo.
Cicatrices del CLI, documentadas donde muerden:
- `page list` sin --formats html devuelve la página SIN html: la primera
verificación contó cero enlaces sobre una página perfectamente escrita
- `page create|update` no expone meta_title ni meta_description, y --slug es
LOOKUP, no asignación. Se escribe lo que se puede y se AVISA del resto en
vez de dar por hechas unas metas que no están
Estado: EN aplicado y verificado (32 enlaces). ES creado como BORRADOR con 31
enlaces — publicar es decisión de Jose, y antes hay que ponerle el slug y las
metas a mano en el editor.
Co-Authored-By: Claude Opus 5 <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%