67b55454c815d08700c9b5f6f1fde04b9b90c320
Salieron al ordenar la taxonomía del EN, y son los dos visibles:
1. el H1 del archivo de tag sale del campo `name`, y en el EN los siete tags
se llamaban COMO SU SLUG: /tag/military-cases/ le enseñaba
«military-cases» al lector, con el <title> correcto justo encima. El ES
enseñaba «Casos Militares». Siete páginas indexadas con un slug de titular.
2. `uap` e `investigation` tenían el MISMO meta_title — dos archivos
compitiendo en el SERP con el mismo titular.
Los nombres no se inventaron: salían del meta_title que cada tag ya tenía, o
sea de una decisión editorial que estaba en el campo equivocado. Slugs
intactos: `--name` y `--new-slug` son opciones distintas, así que las siete
URLs siguen dando 200 y no hace falta ninguna redirección.
Renombrar era IMPOSIBLE hasta esta mañana: researchowl casaba los tags por
NOMBRE, así que esto habría creado siete duplicados `-2`. Se pudo porque el
commit 3d8cba6 los pasó a resolver por slug→id.
El detector de «nombre == slug» exige un guion a propósito: `uap` llamándose
«uap» no se lee como slug crudo y marcarlo sería un falso positivo. Hay test.
Y un fallo del propio fichero de tests, encontrado al añadir estos: el bloque
`if __name__ == "__main__"` estaba en MEDIO, así que los tests definidos
después no entraban en globals() y no corrían nunca — pasaban en verde sin
ejecutarse. Movido al final.
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%