63 Commits

Author SHA1 Message Date
davide 444942dc8f feat: demota #→## quando il documento usa h1 per sezioni principali
Aggiunge _t_demote_h1 in _headers.py: se il documento contiene ≥5
header # con contenuto testuale (lettere iniziali), i # vengono
demotati a ## creando la gerarchia ## (parti) → ### (sezioni)
invece di # → ###.

Utile per manuali strutturati in parti principali (h1) con sezioni
(h3) senza livello intermedio h2. La soglia di 5 evita falsi positivi
su documenti con un solo titolo h1 o h1 da artefatti di encoding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 16:21:02 +02:00
davide 3f4689e8fd feat: rileva note bibliografiche e raccolte multi-articolo in pipeline
Risolve la conversione errata di note a piè di pagina accademiche in
header Markdown nei testi giuridici (es. dirittopubblico: da 424 h2
errati → 27 h2 semanticamente corretti).

- _BIB_MARKERS_RE: aggiunge ibid., cfr., op. cit., cit., ivi
- _FOOTNOTE_AUTHOR_RE: nuovo pattern per "A. COGNOME" (es. G. GUZZETTA)
- _num_repl / _aphorism_repl / _list_section_repl: usano entrambi i
  guard per non convertire note bibliografiche in sezioni
- _t_promote_chapter_headers: usa max-count ≥ 3 per distinguere
  raccolte multi-articolo (non promuovere) da libri con capitoli
  sequenziali (promuovere); preserva il comportamento corretto su anatomia
- _t_remove_page_markers / _t_remove_page_numbers / _t_remove_separators:
  nuove transform per page marker PDF, numeri isolati, separatori underscore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 16:12:50 +02:00
davide 2c0b7a462e feat: migliora pipeline PDF→MD per RAG — frontmatter e page marker
- extract.py: aggiunge extract_metadata() — title, author, year, pages via fitz
- extract.py: aggiunge markdown_page_separator con <!-- page: N --> tra pagine
- extract.py: aggiunge replace_invalid_chars=" " per testo più pulito
- runner.py: prepend YAML frontmatter (source/title/author/year/pages) al clean.md
- runner.py: mostra title e author rilevati durante validazione

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:58:09 +02:00
davide 6e755c0b6c fix(clear.sh): esclude _pipeline/ dal batch e supporta stem singolo
- Aggiunge argomento opzionale <stem>: cancella solo quella cartella
- Esclude dal batch le dir che iniziano con _ o __ (es. _pipeline/)
- Rimuove flag -f non documentato: la modalità singolo stem non chiede conferma

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:53:17 +02:00
davide 9598209f12 chore: aggiorna .gitignore — esclude __pycache__ e rimuove riferimento a transforms/
Aggiunge esclusione esplicita di _pipeline/__pycache__/ per compensare
la regola di negazione !conversione/_pipeline/**. Rimuove dall'indice
tutti i file .pyc precedentemente tracciati per errore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:44:40 +02:00
davide 64dc403e80 refactor: ottimizza pipeline PDF→Markdown — struttura piatta e verbosità
- Unifica deps.py + checker.py + converter.py in extract.py (fronte PDF)
- Sposta transforms/ in _pipeline/ (struttura piatta, no sottocartelle)
- Aggiunge spinner animato (thread) durante conversione opendataloader-pdf
- Aggiunge progresso step-by-step [i/37] per apply_transforms via callback
- Mostra punteggio qualità (score/100 grade) a fine elaborazione
- Fix: _DOTLEADER_RE spostata in _constants.py (non più definita inline)
- Fix: report.py importa regex da _constants invece di ridefinirle
- Fix: _t_remove_urls ora conta e ritorna le rimozioni effettive

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:30:41 +02:00
davide afbf29514d Aggiorna CLAUDE.md 2026-05-07 13:51:55 +02:00
davide ab4036591f temp 2026-04-30 15:26:52 +02:00
davide e41fcae248 refactor: modularizza pipeline in conversione/_pipeline/
Sostituisce i file monolitici pipeline.py e validate.py con il package
_pipeline/ a responsabilità separate. Entry point unificato in __main__.py
(convert + validate dallo stesso comando).

Moduli aggiunti:
- __main__.py       — CLI unificata (--stem, --force, validate, --detail)
- _pipeline/__init__.py — re-export pubblico
- _pipeline/checker.py  — validazione PDF
- _pipeline/deps.py     — verifica dipendenze Java + opendataloader
- _pipeline/structure.py — analyze() + strategia chunking

Moduli già committati in precedenza:
- _pipeline/converter.py, transforms.py, report.py, runner.py, validator.py

Aggiornamenti collaterali:
- .gitignore: exception !conversione/_pipeline/** per tracciare il package
- CLAUDE.md: documentazione aggiornata alla nuova architettura; fix riferimenti
  obsoleti a conversione/pipeline.py → conversione/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 14:59:55 +02:00
davide faa8acae84 feat(pipeline): ottimizzazione completa PDF→Markdown senza revisione manuale
- converter: parametri adattivi (use_struct_tree per PDF taggati, table_method=cluster, content_safety_off)
- transforms: +20 PUA bracket TeX U+F8EB-F8FE (290 simboli corretti su analisi1)
- transforms: _t_math_header_demotion — demota header ##/### che sono enunciati esercizi o formule
- report: metrica formula_headers_residui con esempi
- validator: penalità formula_headers (−3/cad, cap −15), colonna fhdr nel report tabellare

Risultato su analisi1: voto 92/A, PUA residui 0, formula-hdr residui 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 14:58:15 +02:00
davide a158634378 refactor: riduci repo alla sola fase di conversione PDF → Markdown
Rimossi chunks/, step-8/, ollama/, chroma_db/, rag.py, retrieve.py,
config.py e chromadb da requirements. Aggiornati README e CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 12:20:00 +02:00
davide fe0ecc24ad feat(chunks): sentence-boundary flush, math incomplete detection, structure profile export
- chunker: estrai _flush_chunk() con estensione al confine di frase (max 120%)
- verify: rileva chunk matematici incompleti come warning, gestisci hash hex e URL
- conversione: esporta structure_profile.json nell'output dir
2026-04-20 12:28:03 +02:00
davide 995a8be735 chore: pulisci .gitignore — rimuovi step-2..6, aggiungi chunks/ 2026-04-20 12:25:04 +02:00
davide c87a7cb3eb refactor: rimuovi step-5/ e step-6/, sostituiti da chunks/ 2026-04-20 12:22:21 +02:00
davide 4c0e0db2a5 feat(chunks): aggiungi pipeline chunking consolidata
Nuova cartella chunks/ con chunker.py (step 5), verify_chunks.py e
fix_chunks.py (step 6). Tutto l'I/O va in chunks/<stem>/ invece di
step-5/ e step-6/ separati. Input: conversione/<stem>/clean.md
2026-04-20 11:36:24 +02:00
davide 5215f53ad0 docs: compatta README — rimuovi sezioni verbose, mantieni l'essenziale 2026-04-20 11:21:01 +02:00
davide 4f28358ec1 feat: pipeline RAG consolidata — conversione unificata, refactor struttura, CLAUDE.md minimale
Branch ollama introduce:
- Pipeline conversione PDF → Markdown unificata (conversione/pipeline.py) con 30+ transform
  che sostituisce i vecchi step-0..step-4
- Ambiente Ollama (ollama/) con check_env.py e test_ollama.py
- Rimozione cartelle step-0..step-4, step-7, step-9 obsolete
- Consolidamento script alla root
- CLAUDE.md riscritto: path reali, istruzioni minime, agnostico alla struttura step-X
- validate.py con scoring orientato a chunking/vettorizzazione
- README riallineato alla struttura reale del repo
2026-04-20 11:06:18 +02:00
davide 6f8785d90a docs(CLAUDE.md): semplifica istruzioni, rimuovi path step-X hardcoded 2026-04-20 11:05:20 +02:00
davide c8167d4f01 fix: aggiorna path step-4/ → conversione/ e riferimenti step-X
- chunker.py: input da conversione/<stem>/ (era step-4/, non esistente)
- verify_chunks.py: messaggi errore aggiornati a conversione/
- config.py: commenti step-8 → ingest.py
2026-04-19 00:03:43 +02:00
davide e4dc0856bb refactor: pulizia files 2026-04-17 18:52:37 +02:00
davide af9ffc0559 docs(README): riscrittura per struttura reale del progetto
Sostituisce la struttura step-0…step-10 con la pipeline
effettiva: conversione/, revisione /prepare-md, chunking,
verifica, ollama/, vettorizzazione, interrogazione
2026-04-17 18:51:15 +02:00
davide e02e3496a3 chore(requirements): rimuovi commenti step-X obsoleti 2026-04-17 18:50:53 +02:00
davide 12effa1a51 refactor: elimina step-7 e step-9, consolida script alla root
- step-9/: config.py, rag.py, retrieve.py → root;
  test_ollama.py → ollama/
- step-7/: eliminata, già coperta da ollama/
- sys.path aggiornati in rag.py, retrieve.py, ingest.py,
  check_env.py (step-7 e ollama)
- Riferimenti step-9/config.py → config.py in tutti i file
2026-04-17 18:50:36 +02:00
davide fc457e8525 feat(ollama): aggiungi step 7 — verifica ambiente Ollama
Script check_env.py e README per controllare prerequisiti prima
della vettorizzazione: ollama nel PATH, modelli embedding e LLM
disponibili, chromadb importabile
2026-04-17 18:16:40 +02:00
davide 610d4db348 feat(conversione): pipeline unificata PDF → Markdown, sostituisce step-0..4
Consolida in un unico modulo (conversione/pipeline.py) l'intera catena di
conversione che prima era distribuita tra step-0 (validazione PDF), step-1
(ispezione qualità), step-2 (conversione pymupdf4llm), step-3 (rilevamento
struttura) e step-4 (revisione euristica).

Miglioramenti principali rispetto agli step separati:
- libreria di conversione XY-Cut++ (ordine di lettura più preciso)
- 30+ trasformazioni euristiche vs le 7 originali di step-4
- validazione, struttura e profilo chunking prodotti in un solo passaggio
- validate.py con scoring orientato a chunking/vettorizzazione
2026-04-17 16:05:20 +02:00
davide 82f205faa2 chore: rimuovi cartelle step-0..step-4 ora obsolete
La logica è consolidata in conversione/pipeline.py.
2026-04-17 16:04:59 +02:00
davide 368530bc25 refactor(docs): skill prepare-md sostituisce step4-review, CLAUDE.md senza step-X 2026-04-17 13:44:41 +02:00
davide cdb2d4cab9 fix(conversione): PUA Symbol, garbage headers, merge+bib guard, math EN 2026-04-17 13:44:30 +02:00
davide ef8f56fdba fix(conversione): 5 fix robustezza e precisione transform
- _t_remove_footnotes: rimuove marcatori superscript inline e righe
  corpo-nota (¹ testo, [N] testo) — nuovo transform in posizione early
- _t_numbered_sections: esclude voci bibliografiche (anno, pp., vol.,
  DOI, ISBN) dalla promozione a ### header
- _t_remove_toc: intercetta voci con numero pagina finale nel contesto
  TOC — rimosso _t_remove_toc_page_list standalone
- _t_remove_frontmatter: limitata alle prime ~20% sezioni del documento
- _t_remove_recurring_lines: soglia 3->5, Counter spostato a top-level
2026-04-17 12:06:25 +02:00
davide 0a8d98279c feat(conversione): robustezza e 7 nuovi transform
- check_pdf: file < 1KB, campione esteso 15pp, MemoryError
- convert_pdf: validazione output ≥ 100 char
- analyze: rilevamento gerarchia invertita h3 > h2
- _detect_language: supporto FR/DE/ES
- 7 nuovi transform: fix_math_symbols, remove_recurring_lines,
  normalize_numbered_headings, remove_toc_page_list,
  restore_poetry_lines, demote_verse_headers, remove_watermarks
- bug fix: tabelle MD, garbage headers lowercase, empty headers
- run(): MemoryError / UnicodeDecodeError / PermissionError
2026-04-17 11:53:42 +02:00
davide 757df26bc2 refactor(pipeline): modularizza apply_transforms in 26 funzioni _t_xxx
Estrae ogni trasformazione strutturale in una funzione dedicata
_t_xxx(text) -> tuple[str, int], sostituendo la mega-function da
418 righe con un loop su lista di coppie (stat_key, fn). Aggiunge
_parse_sections_with_body() condivisa tra analyze() e build_report().
Output identico verificato su tutti e 5 gli stem esistenti
2026-04-17 09:46:59 +02:00
davide 875a342efa feat(validate): scoring orientato a chunking/vettorizzazione, flag --detail
- _score() ritorna (int, list[str]) con dettaglio penalità applicate
- Rimossi criteri non pertinenti al chunking: sezioni_corte, sezioni_lunghe,
  mediana, p25 — il chunker le normalizza già in fase di suddivisione
- Aggiunte penalità per residui che impattano i vettori: br_inline,
  simboli_encoding, formule_inline
- Flag --detail / -d per mostrare breakdown penalità per documento
- Colonne tabella aggiornate: btk, br, enc, url, med
2026-04-17 09:20:21 +02:00
davide ea721774da feat(pipeline): 10 nuovi transform e metriche residui estese
- 0_br: rimozione tag <br> residui da tabelle PDF
- 0_tabsep: rimozione separatori | | e |---| (doppio pass pre/post merge)
- 0a2: correzione encoding " → × (moltiplicazione, solo digit-before)
- 0a3: correzione encoding ! → µ prima di unità SI
- 0a4: rimozione label formule inline [N.M]
- 9c: filtro garbage headers — simboli puri, abbreviazioni brevi, prefisso ...
- 9d: rimozione sezioni frontmatter (URL, email, copyright, affiliazione)
- build_report: tracking esteso br_inline, simboli_encoding, formule_inline
2026-04-17 09:19:53 +02:00
davide 9910a70823 feat(conversione): aggiungi clear.sh per pulizia batch cartelle stem
Script bash con conferma interattiva e flag -f per eliminare in blocco
le cartelle stem gitignorate in conversione/*/
2026-04-17 09:19:30 +02:00
davide 265ac92b6c feat(conversione): 7 nuovi transform pipeline, refactor validate — media 92→99/100
- dot-leader continui, strip "- " in allcaps, backtick orfani LaTeX
- TOC list removal, extract_article_headers, extract_math_environments, merge_title_headers
- validate.py: interfaccia semplificata, rimosso codice morto
2026-04-17 07:47:56 +02:00
davide bcf2e688aa feat(validate): support single-file flags and explicit markdown score output 2026-04-16 16:05:03 +02:00
davide 5b6940e479 feat(pdf-to-md): sostituisci report.md con report.json + validate.py
pipeline.py produce conversione/<stem>/report.json invece di
structure_profile.json + report.md. Il JSON contiene tutto:
trasformazioni, struttura, distribuzione lunghezze sezioni,
anomalie (bare_headers, short/long sections) e residui con esempi.

Fix: bare_headers flagga solo header senza corpo < 30 chars;
header numerati con corpo lungo (aforismi) non sono anomalie.

Nuovo validate.py legge tutti i report.json e stampa tabella
di stato per ogni stem ( / ⚠️ / ) con soglie configurabili.

README aggiornato con sezione validazione batch e struttura report.json.
2026-04-16 15:54:21 +02:00
davide 6ec54c8616 docs(pdf-to-md): aggiungi README per conversione/
Spiega requisiti (Java 11+, opendataloader-pdf), setup, utilizzo,
output prodotti, tutte le trasformazioni strutturali e i tipi di
documento supportati.
2026-04-16 15:35:58 +02:00
davide 2545d834a9 refactor(pdf-to-md): rimuovi riferimenti agli step interni da conversione/
pipeline.py è una pipeline autonoma e non deve nominare la suddivisione
interna del progetto (step-0..4). Aggiornati docstring, commenti sezione,
messaggi di output e argparse description.
2026-04-16 15:31:03 +02:00
davide b7994100e7 feat(pdf-to-md): aggiungi pipeline automatica PDF → Markdown pulito
Nuova cartella conversione/ con pipeline.py che sostituisce
step-0+1+2+3+4 in un singolo comando senza operazioni manuali.
Usa opendataloader-pdf (algoritmo XY-Cut++ per ordine di lettura).

Trasformazioni strutturali:
- accenti backtick da PDF LaTeX (es. `e→è, puo`→può)
- rimozione dot-leader TOC e numerali romani pagina (i, ii, iii)
- normalizzazione header a gerarchia uniforme h1/h2/h3
- conversione sezioni numerate e aforismi → header ###
- rilevamento sezioni Esercizi → disabilita conversione numerazioni
- watermark URL rimossi, header vuoti scartati
2026-04-16 15:27:53 +02:00
davide 70924a575a feat(step-9): aggiungi retrieve.py per retrieval puro senza LLM
Nuovo script interattivo che vettorizza la query e restituisce i chunk
più simili da ChromaDB senza chiamare Ollama per la generation.
Utile per debug del retrieval e verifica della qualità dei chunk.
Aggiornato README con rag.py e retrieve.py come opzioni alla pari.
2026-04-15 14:25:44 +02:00
davide 0b46c73006 docs(README): aggiungi istruzioni manuali senza Claude per step 4 e 6
Step 4: sostituisce la sezione "Revisione manuale residua" con 6 check
grep/python eseguibili da terminale (sillabazione, righe orfane, frasi
spezzate, header, sezioni vuote, gerarchia).

Step 6: aggiunge sottosezione "Senza Claude Code" con tabella delle 3
condizioni di output di verify_chunks, spiegazione delle operazioni di
fix_chunks --dry-run e tabella dei 4 casi di 🔴 persistenti con la
correzione specifica in clean.md.
2026-04-15 13:34:02 +02:00
davide 87e7ba67ec fix(step-6): riconosci _word._ come terminatore valido in verify_chunks
Rimuove falsi positivi per chunk che terminano con marcatori markdown
di enfasi (_) dopo punteggiatura di fine frase (es. _parola._).
Aggiunge U+2026 (…) alla lista di terminatori accettati.
2026-04-15 13:33:45 +02:00
davide dabad93131 feat(skills): potenzia step4-review e step6-fix con check concreti
step4-review: aggiunge 6 check con grep/python eseguibili (sillabazione,
righe orfane, frasi spezzate, header sospetti, sezioni vuote, gerarchia);
carica revision_log e structure_profile per contesto immediato.

step6-fix: aggiunge Passo 0 di ri-verifica fresca, mostra last_text dei
chunk problematici, exit immediato su verdict=ok, delta chunk pre/post.
2026-04-15 11:39:09 +02:00
davide 94766d67cc docs(CLAUDE.md): riscrivi con regole operative e tabella file critici
Espande CLAUDE.md da 6 a ~80 righe per orientare Claude Code sulle
convenzioni critiche del progetto: pipeline visiva, sincronizzazione
soglie chunking su 3 file, coerenza EMBED_MODEL, skills custom.
2026-04-15 11:38:51 +02:00
davide 80bd563000 step-9: add dynamic epilog and improve argparse help text
- description spiega scopo e prerequisiti
- help di --stem rimosso riferimento al documento specifico
- epilog mostra sintassi del loop interattivo
- epilog lista le collection ChromaDB disponibili a runtime
2026-04-14 19:45:19 +02:00
davide 1a0ebafda5 docs(step-8): aggiungi regole per parametri ottimali
fix(step-9): passa SYSTEM_PROMPT come campo system nell'API Ollama
anziche concatenato nel prompt — risolve risposte di fallback errate
con modelli piccoli
2026-04-14 19:10:43 +02:00
davide 6594033673 feat(step-7,8): leggi modello da config.py, allinea EMBED_MODELS al README
- step-8/ingest.py: rimuove EMBED_MODEL e OLLAMA_URL hardcoded;
  li importa da step-9/config.py (fonte di verita unica)
- step-7/check_env.py: aggiorna EMBED_MODELS con tutti i modelli
  del README (aggiunge qwen3-embedding, nomic-embed-text-v2-moe,
  paraphrase-multilingual); mostra il modello configurato in config.py
  e verifica proprio quello, non un qualsiasi modello embedding
- step-8/README.md: creato
2026-04-14 18:22:14 +02:00
davide f62b5bc871 chore: rimuovi .env.example e traccia sources/.gitkeep
- .env.example eliminato: le istruzioni per le variabili d'ambiente sono documentate nel README
- sources/.gitkeep aggiunto con --force per tracciare la directory sources/ (ignorata da .gitignore) senza committarne il contenuto
2026-04-14 18:01:02 +02:00
davide 8fa07784ae docs: allinea README alla struttura reale del progetto
Corregge struttura progetto (step-N/ invece di scripts/ e processed/),
aggiorna script, comandi e path per step 1–3, rimuove riferimenti a
marker-pdf (sostituito da pymupdf4llm), snellisce step 7 e 9 con
rimando ai README dedicati, segna step 10 come da implementare
2026-04-14 15:57:49 +02:00