diff --git a/CHANGELOG.md b/CHANGELOG.md index 41e658c..8c89bc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## v0.10.7.5 — Public docs, changelog and national validation refresh + +### Added +- Public documentation freshness guard: `scripts/check_public_docs_freshness.py`. +- Changelog/public-page refresh for the Andalucía distributor research pipeline. +- Public audit closeout for the current national/distributor validation state. + +### Andalucía distributor research status +- Andalucía municipal GeoJSON features: 786. +- Existing public distributor hints: 254. +- Pending review queue rows: 532. +- Batch 2 candidate workbench rows: 532. +- Candidate workbench remains manual-review-only; no distributor hints are imported by this release. + +### Validation +- `check_distributor_hints.py` passes. +- `check_distributor_data_version.py` passes. +- `check_andalucia_pending_review_queue.py` passes. +- `check_andalucia_batch2_candidate_workbench.py` passes. +- Public smoke with expected distributor version passes. +- National geographic coverage guards are part of the validation flow. + +### Safety +- No CUPS. +- No addresses. +- No exact user coordinates. +- No customer data. +- No private grid inventory. +- No raw external API responses. + + ## v0.10.6.4-distributor-confidence-labels - Mejora las etiquetas públicas de fiabilidad de pistas de distribuidora. diff --git a/README.md b/README.md index 2c4d8b2..0661965 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,23 @@ Ese documento resume qué hallazgos se corrigieron, en qué PRs se cerraron y qu ## Validación post-merge +Validaciones adicionales actuales: + +- `python3 scripts/check_distributor_data_version.py --repo-root .` +- `python3 scripts/check_andalucia_pending_review_queue.py` +- `python3 scripts/check_andalucia_batch2_candidate_workbench.py` +- `python3 scripts/check_public_docs_freshness.py` +- `scripts/run_public_smoke_expected_version.sh` + +Estado Andalucía distribuidoras: + +- 786 municipios/zones geográficas. +- 254 hints públicos ya cubiertos. +- 532 filas pendientes de revisión municipal. +- 532 candidatos batch 2 en modo revisión manual. +- Sin importación automática; cualquier futuro alta debe ser `verified_partial` y estar respaldada por fuente pública. + + Después de mergear cambios relevantes en `main`, se recomienda ejecutar: ```bash diff --git a/docs/audit/public-docs-national-validation-v1075.md b/docs/audit/public-docs-national-validation-v1075.md new file mode 100644 index 0000000..44fb8e1 --- /dev/null +++ b/docs/audit/public-docs-national-validation-v1075.md @@ -0,0 +1,58 @@ +# Public docs and national validation refresh v0.10.7.5 + +## Summary + +This document records the public documentation refresh and validation state after the Andalucía distributor research pipeline work. + +## Current public version + +- VERSION: v0.10.6.4-distributor-confidence-labels +- Public distributor JSON version expected: v0.10.6.4-distributor-confidence-labels +- Public distributor hint zones: 2610 + +## Andalucía distributor research baseline + +- Andalucía municipal GeoJSON source: frontend/public/data/andalucia_municipios.geojson +- Andalucía GeoJSON features: 786 +- Existing public Andalucía distributor hints: 254 +- Pending municipal review queue rows: 532 +- Batch 2 candidate workbench rows: 532 + +## Current Andalucía guard scripts + +- scripts/check_andalucia_pending_review_queue.py +- scripts/check_andalucia_batch2_candidate_workbench.py + +## Current public/version guard scripts + +- scripts/check_distributor_data_version.py +- scripts/check_public_deploy_smoke.py +- scripts/run_public_smoke_expected_version.sh +- scripts/check_public_docs_freshness.py + +## National coverage checks to keep running + +- node --check frontend/src/geo/datasets.js +- python3 scripts/check_all_scope_datasets.py +- python3 scripts/audit_geo_datasets.py +- python3 scripts/check_spain_geo_coverage.py +- bash scripts/repo_guard.sh --no-build +- npm --prefix frontend run build + +## Safety constraints + +The refreshed docs and guards must not add: + +- CUPS. +- Addresses. +- Exact user coordinates. +- Customer data. +- Private grid inventory. +- Raw external API responses. +- Secrets, tokens, logs or backups. + +## Next safe data step + +The next data step should select a small, source-backed Andalucía subset from the batch 2 workbench and manually review it before any import. + +No automatic import should be performed from the workbench. diff --git a/frontend/public/changelog.html b/frontend/public/changelog.html index cf2239a..a04735b 100644 --- a/frontend/public/changelog.html +++ b/frontend/public/changelog.html @@ -1266,6 +1266,28 @@

Historial técnico reciente desde Git

+ +
+

v0.10.7.5 — Public docs, changelog and national validation refresh

+

+ Se actualiza la documentación pública y el changelog para reflejar el trabajo + reciente de validación nacional y la preparación conservadora del batch 2 de + distribuidoras en Andalucía. +

+ +

+ Privacidad: sin CUPS, sin direcciones, sin coordenadas exactas, sin datos de + clientes y sin inventario privado de red. +

+
+ diff --git a/scripts/check_public_docs_freshness.py b/scripts/check_public_docs_freshness.py new file mode 100755 index 0000000..8da543e --- /dev/null +++ b/scripts/check_public_docs_freshness.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import re +import sys +from pathlib import Path + +APP_VER = "v0.10.6.4-distributor-confidence-labels" + +REQUIRED_FILES = [ + Path("README.md"), + Path("CHANGELOG.md"), + Path("frontend/public/changelog.html"), + Path("docs/audit/andalucia-distributor-pending-audit-v1070.md"), + Path("docs/audit/andalucia-geo-source-locator-v1071.md"), + Path("docs/audit/andalucia-pending-review-queue-v1072.md"), + Path("docs/audit/andalucia-v1072-closeout.md"), + Path("docs/audit/andalucia-batch2-candidate-workbench-v1074.md"), + Path("docs/audit/public-docs-national-validation-v1075.md"), + Path("scripts/check_distributor_data_version.py"), + Path("scripts/check_andalucia_pending_review_queue.py"), + Path("scripts/check_andalucia_batch2_candidate_workbench.py"), + Path("scripts/run_public_smoke_expected_version.sh"), +] + +REQUIRED_TEXT_CASE_INSENSITIVE = { + "README.md": [ + "versión actual visible: v0.10.6.4-distributor-confidence-labels", + "andalucía", + "scripts/post_merge_validate.sh", + "check_public_docs_freshness.py", + ], + "CHANGELOG.md": [ + "andalucía", + "batch 2", + "532", + "check_andalucia_batch2_candidate_workbench.py", + ], + "frontend/public/changelog.html": [ + "andalucía", + "batch 2", + "532", + "v0.10.7.5", + ], + "scripts/post_merge_validate.sh": [ + "check_distributor_data_version.py", + "check_andalucia_pending_review_queue.py", + "check_andalucia_batch2_candidate_workbench.py", + "check_public_docs_freshness.py", + ], + "docs/audit/public-docs-national-validation-v1075.md": [ + "2610", + "786", + "254", + "532", + "check_public_docs_freshness.py", + ], +} + +# Patrones de secretos reales. No bloquea variables documentadas vacías tipo +# TURNSTILE_SECRET_KEY= porque aparecen en README/.env.example como ejemplo. +FORBIDDEN_PATTERNS = [ + re.compile(r"gho_[A-Za-z0-9_]{20,}"), + re.compile(r"github_pat_[A-Za-z0-9_]{20,}"), + re.compile(r"-----BEGIN (RSA|OPENSSH|EC|DSA) PRIVATE KEY-----"), +] + + +def read(path: Path) -> str: + return path.read_text(encoding="utf-8", errors="ignore") + + +def main() -> int: + errors: list[str] = [] + + for path in REQUIRED_FILES: + if not path.exists(): + errors.append(f"missing required file: {path}") + + for file_name, snippets in REQUIRED_TEXT_CASE_INSENSITIVE.items(): + path = Path(file_name) + if not path.exists(): + errors.append(f"missing text-check file: {path}") + continue + + text = read(path).lower() + for snippet in snippets: + if snippet.lower() not in text: + errors.append(f"{path}: missing snippet: {snippet}") + + for path in [ + Path("README.md"), + Path("CHANGELOG.md"), + Path("frontend/public/changelog.html"), + Path("docs/audit/public-docs-national-validation-v1075.md"), + ]: + if not path.exists(): + continue + + text = read(path) + for pattern in FORBIDDEN_PATTERNS: + if pattern.search(text): + errors.append(f"{path}: forbidden sensitive pattern: {pattern.pattern}") + + version_path = Path("VERSION") + if version_path.exists(): + version = read(version_path).strip() + if version != APP_VER: + errors.append(f"VERSION mismatch: {version} != {APP_VER}") + + if errors: + print("FAIL public docs freshness") + for err in errors: + print(f"- {err}") + return 1 + + print("OK public docs freshness") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/post_merge_validate.sh b/scripts/post_merge_validate.sh index 1823acc..f9acae6 100755 --- a/scripts/post_merge_validate.sh +++ b/scripts/post_merge_validate.sh @@ -48,6 +48,8 @@ echo '--- check_andalucia_pending_review_queue ---' python3 scripts/check_andalucia_pending_review_queue.py echo '--- check_andalucia_batch2_candidate_workbench ---' python3 scripts/check_andalucia_batch2_candidate_workbench.py +echo '--- check_public_docs_freshness ---' +python3 scripts/check_public_docs_freshness.py python3 scripts/generate_distributor_coverage_matrix.py --check python3 scripts/check_public_distributor_coverage_page.py python3 scripts/check_public_coverage_linking.py