hreflang: Grusch apuntaba al artículo equivocado, y el tool no sabía retirar

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>
This commit is contained in:
ChemaVX
2026-07-29 08:53:58 +00:00
co-authored by Claude Opus 5
parent 9ba1eaf766
commit 158b5166a1
2 changed files with 48 additions and 4 deletions
+14 -2
View File
@@ -89,8 +89,20 @@ sim 0.881 222
sim 0.842 david grusch
EN david-grusch-capitol-2026-whistleblower-uap-disclosure
David Grusch at the Capitol: The Whistleblower Claims, the Congressional Obstruction,
ES el-testimonio-de-david-grusch-el-denunciante-que-cambio-la-conversacion-sobre-ovnis-en-el-congreso-de-ee-uu
El Testimonio de David Grusch: El Denunciante que Cambió la Conversación sobre OVNIs e
ES grusch-capitolio-9-junio-2026-divulgacion-uap
Grusch en el Capitolio: el día que la divulgación UAP pasó del testimonio a la exigenc
NOTA (2026-07-29, corregida): apuntaba a «el-testimonio-de-david-grusch», que trata la
comparecencia JURADA DE JULIO DE 2023 ante el Congreso. El EN trata el acto del 9 de
JUNIO DE 2026 en las escaleras del Capitolio. Mismo protagonista, tres años de
diferencia: declarados espejo, le decían a Google que dos artículos distintos son el
mismo. El espejo real es este, publicado un día después del acto (10-jun frente al
9-jun) y con extensión pareja (1.481 frente a 1.647 palabras).
El ES de 2023 se queda SIN pareja: no hay artículo inglés sobre esa comparecencia. Y el
adelanto del EN (grusch-capitol-june-9-2026, «[Preview]», publicado el 31-may) tampoco
la lleva, porque está canonizado hacia el largo — y un canonizado no debe declarar
hreflang propio.
El fallo enseña dónde mirar: con casos históricos el año del título ya identifica el
hecho, pero con NOTICIAS el mismo protagonista vuelve, y el título no basta.
decision: SI
sim 0.838 aaro
+34 -2
View File
@@ -104,7 +104,39 @@ def trae(site, slugs):
posts = json.load(open(path))["posts"]
finally:
os.unlink(path)
return {p["slug"]: p for p in posts if p["slug"] in slugs}
return {p["slug"]: p for p in posts if slugs is None or p["slug"] in slugs}
def desmarca(actual):
"""Quita NUESTRO bloque y deja intacto lo demás. Devuelve None si no había."""
actual = actual or ""
if INICIO not in actual or FIN not in actual:
return None
limpio = re.sub(re.escape(INICIO) + r".*?" + re.escape(FIN), "", actual, flags=re.S)
return re.sub(r"\n{3,}", "\n\n", limpio).strip()
def huerfanos(parejas):
"""Posts que llevan nuestro bloque y YA NO están en ninguna pareja SI.
Sin esto, repuntar una pareja deja media declaración viva. Pasó con Grusch
el 2026-07-29: el ES de la comparecencia de 2023 estaba emparejado por error
con el EN del acto de 2026, y al corregirlo el ES viejo se habría quedado
señalando a un artículo que ya no le señala a él. Un hreflang que no es
recíproco Google lo ignora, pero el que sobra sigue afirmando algo falso.
Se busca en TODO el corpus, no solo en los slugs de las parejas: el que hay
que limpiar es justamente el que ha dejado de estar en la lista.
"""
fuera = []
for site, dentro in (("en", {a for a, _ in parejas}), ("es", {b for _, b in parejas})):
for slug, p in trae(site, None).items():
if slug in dentro:
continue
limpio = desmarca(p.get("codeinjection_head"))
if limpio is not None:
fuera.append((site, p, limpio))
return fuera
def cambios():
@@ -126,7 +158,7 @@ def cambios():
nuevo = fusiona(p.get("codeinjection_head"), blq)
if nuevo != (p.get("codeinjection_head") or ""):
plan.append((site, p, nuevo))
return plan, avisos, parejas
return plan + huerfanos(parejas), avisos, parejas
def violaciones(post, site, parejas=None):