Las parejas se curan a mano, pero solo se pueden declarar cuando los dos
lados están publicados: un hreflang a una URL programada apunta a un 404.
Había cinco esperando, repartidas entre el 4 y el 27 de agosto, y la
alternativa era acordarse de correr `aplicar` cinco veces en las fechas
justas. Eso no es una solución: es una lista que se cumple a medias, y el
hreflang que falta no da error en ninguna parte, así que nadie se entera.
- hreflang_watch.py + timer diario a las 06:40 UTC (40 min tras la cola,
antes de canibal-watch). Telegram SOLO si algo se ha abierto o ha
fallado: 26 días de cada 31 no habrá nada, y si esos días avisara, el
día que importa se leería igual que los otros.
- `aplica()` extraída de cmd_aplicar: el automático escribe por el MISMO
camino que el manual, no por una copia suya.
- `comprueba` separa PENDIENTE de ROTO. Antes daba diez ✗ de 404 fijos por
los espejos programados; diez rojos permanentes que no se pueden
arreglar son un informe que se deja de leer.
Verificado por el camino real, no en seco: se le quitó el bloque al lado ES
de la pareja de Varginha (avería visible en la web pública, 0 hreflang), el
vigilante la detectó, la escribió, la verificó contra las URLs exactas y
avisó por Telegram. Restaurada y comprobada después. Y `verifica()` se ve
fallar con una pareja cruzada a propósito, así que el ✅ no es vacuo.
Nueve tests. Ensayado además arrancando el unit por systemd, que es donde
los CLIs de node mueren con 127 si falta el bin de nvm en el PATH.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
El NIVEL C decía «nada convincente» en belgium, jal-1628 y libro azul, pero eso
era del escáner de vectores: el espejo ES existe y está en la cola de agosto,
no publicado cuando se escaneó. Abiertos los dos lados de cada uno:
SÍ Bélgica 89-90 mismas noches (Eupen, 30/31-mar), Petit-Rechain, SOBEPS
SÍ JAL 1628 mismo vuelo del 17-nov-86, Terauchi, Callahan y la FAA
SÍ Libro Azul mismo programa y mismas cifras (12.618 / 701)
SÍ Colares 1977 misma isla, Operação Prato, testimonio de Hollanda
SÍ Teherán 1976 misma madrugada, los dos F-4, el documento de la DIA
NO bases nucleares el EN son DOS casos (Malmstrom y Rendlesham); el ES es la
apertura de PURSUE y CINCO bases. Solo comparten Malmstrom
Libro Azul es el que enseña dónde está la línea: los apartados NO coinciden y
aun así es SÍ, porque el SUJETO de los dos es el mismo programa histórico. En
AARO el sujeto del ES era la confrontación con Grusch, y por eso es NO. Y las
bases nucleares traen la lección de AARO repetida: coincidían hasta en el
recuento —1.264 palabras exactas los dos— y no son el mismo artículo. Un número
que cuadra no es prueba de equivalencia.
Declararlas destapó un falso positivo: `violaciones()` solo miraba que ESTE
lado estuviera publicado, así que los tres EN ya publicados con el ES aún
programado salieron como hreflang.missing, recetando un `aplicar` que se niega
—y con razón— porque apuntaría a una URL que no existe. Ahora exige los dos
lados publicados. Un aviso que no se puede atender es ruido, y el ruido acaba
con que nadie mire el informe.
Auditores 42 y 40 limpios, seo-watch sin hallazgos.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La pareja decía que «David Grusch at the Capitol» (el acto del 9 de junio de
2026) y «El testimonio de David Grusch» (la comparecencia jurada de julio de
2023) son el mismo artículo en otro idioma. Son dos hechos con tres años de
diferencia. El espejo real es grusch-capitolio-9-junio-2026, publicado un día
después del acto y con extensión pareja.
Se coló porque las 16 parejas se validaron por firma de título, y con casos
históricos el año identifica el hecho, pero con NOTICIAS el mismo protagonista
vuelve. Revisadas a fondo las otras 15 con ese criterio —abriendo los dos
artículos, no comparando títulos—: correctas. Las dos de noticia que quedaban
(222 archivos y la segunda desclasificación) se publicaron el MISMO DÍA en los
dos sitios y con extensión casi idéntica, que es la firma de una pareja real.
Y el arreglo destapó un agujero: `cambios()` solo escribía las parejas del
fichero, así que repuntar una dejaba la anterior declarada por su lado. Se
habría quedado el ES de 2023 señalando a un EN que ya no le señala a él.
`huerfanos()` recorre ahora todo el corpus y retira nuestro bloque de quien ha
dejado de estar en la lista; `desmarca()` quita solo lo nuestro.
Aplicado y verificado en la web pública: 3 posts, las dos páginas de la pareja
nueva declaran las dos versiones y el ES de 2023 se queda sin hreflang, que es
lo correcto porque no hay artículo inglés sobre esa comparecencia.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hasta ahora el hreflang era un estado —puesto una vez a mano— y no una
regla. Un slug que cambiara habría dejado el enlace apuntando al artículo
viejo sin que nada avisara.
El auditor gana dos reglas: hreflang.missing (pareja declarada sin bloque)
y hreflang.stale (bloque que ya no coincide con la pareja). Viven en
seo_hreflang y no en seo_rules porque necesitan hreflang-parejas.md, que es
una decisión editorial curada; el motor sigue sin saber que hay parejas.
Probadas en los cinco estados, no solo en el feliz: dispara sin bloque,
dispara con el bloque apuntando a un slug viejo, y se calla cuando está
correcto, cuando el post no es de ninguna pareja y cuando aún es borrador.
Y el remate gana el paso 3c: buscar el espejo en el otro idioma y dejarlo
en el informe. Con la advertencia explícita de decidir por TÍTULO y no por
vector, y las dos reglas duras — solo espejos publicados, y uno a uno.
Hasta hoy no había NI UN hreflang en ninguno de los dos blogs. Google no
tenía forma de saber que los artículos del mismo caso en los dos idiomas
son la misma pieza, así que servía el que le parecía y las señales de cada
uno se quedaban sueltas en su lado.
Las parejas NO se infieren, se curan a mano en hreflang-parejas.md. Los
embeddings no valen a esta granularidad y conviene que quede escrito: los
DOS artículos de Immaculate Constellation puntúan 0,774 entre sí y uno sin
relación puntúa 0,778; y el espejo real del artículo ES de bases nucleares
puntúa 0,719, por debajo de tres PURSUE que no lo son. La firma del título
(año + nombre propio) decide; el vector solo desempata.
Dos descartes con motivo: el forense del vídeo de Roswell no es el espejo
de la pieza ES de tres hilos (comparten un hecho, no un artículo), y
ninguno de los tres PURSUE es la traducción del artículo ES de bases
nucleares — ese espejo se llama «Nuclear Bases and UAP» y está PROGRAMADO,
así que entra en agosto.
Escribe entre marcas en codeinjection_head, así que es reescribible y no
pisa lo que hubiera. Verificado contra las 32 páginas PÚBLICAS comparando
las URLs exactas, no solo la presencia de las etiquetas: un par cruzado
declararía las dos versiones y habría pasado una comprobación laxa.