5b63c423cc
- chunker.py: scrive meta.json con strategia e soglie effettive (target,
min_chars, max_chars) per ogni documento chunked
- verify_chunks.py:
* _load_thresholds(): legge min/max da meta.json invece del TARGET_CHARS
globale, eliminando il mismatch tra soglie chunker e verify
(h3_aware target=600 -> range 450-750, non piu' validato a 225-375)
* _ROMAN_END: esclude numeri romani finali (XV, XIV...) dagli incompleti
perche' sono artefatti indice PDF, non frasi spezzate
* PUNCT_END: aggiunge ; come fine valida (clausole legali italiane)
- fix_chunks.py:
* _load_thresholds(): usa max_chars da meta.json per split coerente
* _SECONDARY_END: split secondario su ; per testo legale multi-clausola
* Fase 1 (convergenza): risolve solo blockers (incomplete, empty,
no_prefix) senza toccare warnings -- elimina il ciclo
merge->too_long->split->incomplete->merge
* Fase 2 (finale): una sola passata di merge too_short + split too_long
dopo che i blockers sono azzerati
Risultato su dirittopenale: da blocked (265 incomplete) a warnings_only
in 2 iterazioni, senza cicli infiniti.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>