1ac51267fe935f6f9a396117977681bf3e4e4c65
Los encabezados llevaban limpios desde el 21 de julio, pero la regla solo miraba <h2>/<h3>/<h4>: 28 de los 31 títulos publicados del ES seguían en Title Case inglés, con sus meta_title, og_title y twitter_title detrás. Es justo lo que el lector español lee en Google. seo_case.py reescribe, y no reutiliza el detector tal cual porque no vale para esto: `_title_case_words` decide con una sola prueba —«¿la he visto en minúscula alguna vez?»— y eso deja fuera los verbos que solo viven en titulares («Ocultan», «Conmocionó», «Penetró») y las palabras de dos letras, que ni entran en el vocabulario. La primera versión devolvía títulos a medio arreglar y rompía «Talavera la Real» y «vuelo Iberia». Ahora se decide con dos pruebas —nunca en minúscula Y en mayúscula a media frase— más una lista de palabras gramaticales, y las frases propias se enmascaran conservando las posiciones para reescribir por desplazamiento sobre el original. Decisión de Jose: «Ejército», «Gobierno» y demás instituciones conservan la mayúscula; «Archivos» baja salvo en «Los Archivos PURSUE», que se protege por frase porque ahí se distingue por contexto, no por palabra suelta. check_title_case cierra el agujero en seo_watch. Simulado el ciclo entero antes de tocar nada: 78 hallazgos → 16 tras el pase automático → 0 con la decisión aplicada. Aplicado y verificado releyendo Ghost campo a campo (91 de 91), con backup pristine por post en ~/link-batch-backup. 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%