fix(verify): PUNCT_END generico e frasi spezzate come warning
PUNCT_END esteso con terminatori comuni in documenti tecnici: - $ e } per formule LaTeX inline e blocchi - > per tag HTML (</table>, </td>, ecc.) - \\ per line break LaTeX - · (punto centrato, U+00B7) per notazione matematica Caratteri unicode scritti con chr() per evitare SyntaxError Python 3.12+ con curly quotes nel sorgente. Frasi spezzate spostate da blockers a warnings: il chunker le risolve automaticamente con merge_broken_sentences; i casi residui sono perlopiù falsi positivi (frontespizi, entità proprie senza punto finale). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-16
@@ -32,13 +32,27 @@ import config as cfg
|
|||||||
MIN_CHARS = cfg.MIN_CHARS
|
MIN_CHARS = cfg.MIN_CHARS
|
||||||
MAX_CHARS = cfg.MAX_CHARS
|
MAX_CHARS = cfg.MAX_CHARS
|
||||||
|
|
||||||
|
_PUNCT_CLS = (
|
||||||
|
"[.!?"
|
||||||
|
+ chr(0xBB) + ")\\]"
|
||||||
|
+ chr(0x2018) + chr(0x2019)
|
||||||
|
+ chr(0x201C) + chr(0x201D)
|
||||||
|
+ "\"'"
|
||||||
|
+ chr(0x2014) + chr(0x2013) + chr(0x2026)
|
||||||
|
+ chr(0xB7) # punto centrato LaTeX
|
||||||
|
+ "]$"
|
||||||
|
)
|
||||||
PUNCT_END = re.compile(
|
PUNCT_END = re.compile(
|
||||||
r"[.!?\xbb)\]'’\"“”‘—–…]$"
|
_PUNCT_CLS
|
||||||
r"|/$" # URL che finisce con /
|
+ r"|/$"
|
||||||
r"|\|$" # riga di tabella Markdown
|
+ r"|\|$"
|
||||||
r"|;$" # fine clausola legale
|
+ r"|;$"
|
||||||
r"|:$" # introduzione a lista o formula
|
+ r"|:$"
|
||||||
r"|\d[\d.,/]*$" # numero, anno, versione, riferimento normativo
|
+ r"|\d[\d.,/]*$"
|
||||||
|
+ r"|\$$"
|
||||||
|
+ r"|\}$"
|
||||||
|
+ r"|>$"
|
||||||
|
+ r"|\\\\$"
|
||||||
)
|
)
|
||||||
_HEX_END = re.compile(r"[0-9a-fA-F]{8,}$")
|
_HEX_END = re.compile(r"[0-9a-fA-F]{8,}$")
|
||||||
_URL_TAIL = re.compile(r"(https?://|www\.)\S+(\s+\S+){0,3}$")
|
_URL_TAIL = re.compile(r"(https?://|www\.)\S+(\s+\S+){0,3}$")
|
||||||
@@ -312,13 +326,13 @@ def verify_stem(stem: str, project_root: Path, min_chars: int, max_chars: int) -
|
|||||||
print(f" → Causa probabile: sezioni senza testo nel clean.md")
|
print(f" → Causa probabile: sezioni senza testo nel clean.md")
|
||||||
|
|
||||||
if incomplete:
|
if incomplete:
|
||||||
print(f"\n 🔴 {len(incomplete)} chunk con FRASE SPEZZATA:")
|
print(f"\n 🟡 {len(incomplete)} chunk con FRASE SPEZZATA (warning):")
|
||||||
for c in incomplete[:5]:
|
for c in incomplete[:5]:
|
||||||
last_line = c.get("text", "").rstrip().split("\n")[-1][-80:]
|
last_line = c.get("text", "").rstrip().split("\n")[-1][-80:]
|
||||||
print(f" [{c.get('chunk_id', '?')}] ...{last_line!r}")
|
print(f" [{c.get('chunk_id', '?')}] ...{last_line!r}")
|
||||||
if len(incomplete) > 5:
|
if len(incomplete) > 5:
|
||||||
print(f" ... e altri {len(incomplete) - 5}")
|
print(f" ... e altri {len(incomplete) - 5}")
|
||||||
print(f" → Soluzione: python chunks/fix_chunks.py --stem {stem}")
|
print(f" → Soluzione: correggi il sorgente .md e rigenera con chunker.py --force")
|
||||||
|
|
||||||
# ── Warnings ──────────────────────────────────────────────────────────────
|
# ── Warnings ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -350,12 +364,12 @@ def verify_stem(stem: str, project_root: Path, min_chars: int, max_chars: int) -
|
|||||||
print(f" [{e['chunk_id']}] ≡ [{e['duplicate_of']}] «{e['last_text'][:60]}»")
|
print(f" [{e['chunk_id']}] ≡ [{e['duplicate_of']}] «{e['last_text'][:60]}»")
|
||||||
if len(duplicates) > 5:
|
if len(duplicates) > 5:
|
||||||
print(f" ... e altri {len(duplicates) - 5}")
|
print(f" ... e altri {len(duplicates) - 5}")
|
||||||
print(f" → Causa probabile: fix_chunks merge multipli o sezioni ripetute")
|
print(f" → Causa probabile: sezioni ripetute nel sorgente .md")
|
||||||
|
|
||||||
# ── Report.json ───────────────────────────────────────────────────────────
|
# ── Report.json ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
blockers = empty_chunks + no_prefix + malformed_prefix + body_empty + incomplete
|
blockers = empty_chunks + no_prefix + malformed_prefix + body_empty
|
||||||
warnings = too_short + too_long + incomplete_math + broken_tables
|
warnings = too_short + too_long + incomplete + incomplete_math + broken_tables
|
||||||
|
|
||||||
verdict = "blocked" if blockers else ("warnings_only" if (warnings or duplicates) else "ok")
|
verdict = "blocked" if blockers else ("warnings_only" if (warnings or duplicates) else "ok")
|
||||||
|
|
||||||
@@ -418,18 +432,16 @@ def verify_stem(stem: str, project_root: Path, min_chars: int, max_chars: int) -
|
|||||||
print(f" python ingestion/ingest.py --stem {stem}")
|
print(f" python ingestion/ingest.py --stem {stem}")
|
||||||
if too_short or too_long:
|
if too_short or too_long:
|
||||||
print()
|
print()
|
||||||
print(f" Per ottimizzare prima:")
|
print(f" Per ottimizzare: correggi il sorgente .md e rigenera con --force")
|
||||||
print(f" python chunks/fix_chunks.py --stem {stem} --dry-run")
|
|
||||||
print(f" python chunks/fix_chunks.py --stem {stem}")
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(f" 🔴 {len(blockers)} problemi bloccanti — correggi prima di procedere:")
|
print(f" 🔴 {len(blockers)} problemi bloccanti — correggi prima di procedere:")
|
||||||
if empty_chunks or body_empty:
|
if empty_chunks or body_empty:
|
||||||
print(f" • chunk vuoti/senza corpo → controlla sources/{stem}/auto/{stem}_clean.md")
|
print(f" • chunk vuoti/senza corpo → controlla sources/{stem}/auto/{stem}_clean.md")
|
||||||
if no_prefix or malformed_prefix:
|
if no_prefix or malformed_prefix:
|
||||||
print(f" • prefisso mancante/malformato → controlla gli heading in {stem}_clean.md")
|
print(f" • prefisso mancante/malformato → controlla gli heading in sources/{stem}.md")
|
||||||
if incomplete:
|
if incomplete:
|
||||||
print(f" • frasi spezzate → python chunks/fix_chunks.py --stem {stem}")
|
print(f" • frasi spezzate → correggi il sorgente e rigenera con --force")
|
||||||
print()
|
print()
|
||||||
print(f" Dopo le correzioni:")
|
print(f" Dopo le correzioni:")
|
||||||
print(f" python chunks/chunker.py --stem {stem} --force")
|
print(f" python chunks/chunker.py --stem {stem} --force")
|
||||||
|
|||||||
Reference in New Issue
Block a user