seo_exceptions: ámbito por sitio — los dos blogs, independientes de verdad

Los waivers se indexaban SOLO por slug. Hoy no hay colisiones (los slugs ES
van en español), pero nada lo impedía: un slug repetido entre blogs habría
aplicado en silencio la excepción del sitio equivocado, y ese post habría
dejado de auditarse sin que nadie se enterara. Riesgo latente, no activo — pero
'no pasa hoy' no es lo mismo que 'no puede pasar'.

  EXCEPTIONS[site][familia][slug] = razón
  accepted_reason(rule, slug, site='en')

El default 'en' mantiene funcionando a seo_audit.py sin tocarlo (es EN-only).
seo_watch y seo_finish pasan el sitio activo explícitamente.

Añadido collisions(): lista los slugs waiveados en más de un sitio. Debe estar
siempre vacío; si algo aparece ahí, hay una excepción ambigua que revisar.

Verificado: mismo slug waiveado en EN se audita con normalidad en ES; los 16
waivers EN intactos; seo_audit, seo_watch (ambos sitios) y seo_finish (ambos
sitios) siguen dando los mismos resultados que antes del cambio.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ChemaVX
2026-07-20 16:16:47 +00:00
co-authored by Claude Opus 4.8
parent f9f90f8999
commit 7b92079c41
3 changed files with 42 additions and 14 deletions
+3 -3
View File
@@ -216,14 +216,14 @@ def check_sitemap():
return len(urls), malos
def check_rules(posts):
def check_rules(posts, site):
"""Violaciones accionables (excluye waivers e INFO), agrupadas por regla."""
out = {}
for p in posts:
if p.get("status") != "published":
continue
for v in R.check_post(p):
if v.severity == R.INFO or X.accepted_reason(v.rule, p["slug"]):
if v.severity == R.INFO or X.accepted_reason(v.rule, p["slug"], site):
continue
out.setdefault(v.rule, []).append(p["slug"])
return out
@@ -287,7 +287,7 @@ def run_site(site):
roto, nocanon, prematuro = check_links(posts)
envejecido = check_link_aging(posts)
n_sm, sm_malos = check_sitemap()
reglas = check_rules(posts)
reglas = check_rules(posts, site)
body = build_report(roto, nocanon, prematuro, envejecido, n_sm, sm_malos, reglas)
pub = sum(1 for p in posts if p.get("status") == "published")