Sistema di Scoring — Il Punteggio di Qualità Deterministico
"Un Exclusion Zone deve saper dire esattamente quanto è solido il suo molo."
Un link rotto degrada l'esperienza utente. Una credenziale esposta richiede una risposta immediata all'incidente. Un punteggio di 97 significa tre finding ancora irrisolti.
Il Deterministic Quality Score (DQS) è un valore da 0 a 100 calcolato dal conteggio concreto dei problemi rilevati da ogni controllo. Zero problemi significa 100/100. Nessun credito parziale, nessun arrotondamento favorevole, nessuna sorpresa. Dati gli stessi file sorgente e la stessa versione di Zenzic, il punteggio è identico su ogni macchina — nessun campionamento, nessun peso basato sull'età del file, nessuna componente soggettiva.
Per le formule esatte e la specifica matematica, consulta il Riferimento Algoritmo di Scoring.
Cosa Misura il Punteggio
Il Punteggio di Qualità è un composito pesato di quattro categorie di controllo.
Ogni categoria corrisponde direttamente a un sotto-comando zenzic check e ai
codici di finding Zxxx che emette.
| Categoria | Comando | Codici Finding | Peso |
|---|---|---|---|
| Integrità Strutturale | zenzic check links [PATH] | Z101, Z102, Z104, Z105, Z107, Z108 | 30 % |
| Eccellenza dei Contenuti | zenzic check all [PATH] | Z403, Z501, Z502, Z503, Z505 | 20 % |
| Navigazione | zenzic check orphans [PATH] | Z301, Z302, Z303, Z401, Z402 | 25 % |
| Brand & Asset | zenzic check assets [PATH] | Z404, Z405, Z406, Z601 | 25 % |
Come leggere i pesi. I due pesi maggiori — Strutturale e Governance — riflettono il principio di design di Zenzic: la correttezza (link che si risolvono davvero) e la fiducia (conformità al brand e ai contratti) contano più della qualità estetica dei contenuti.
Se viene rilevato un finding di sicurezza — Z201 (credential scanner), Z202 o Z203 (path traversal guard) — il Punteggio di Qualità crolla a 0/100 incondizionatamente. Una sorgente documentale che perde attivamente una credenziale non può ricevere un Punteggio di Qualità.
La Tabella di Penalità
Ogni codice di finding porta una deduzione fissa in punti all'interno della sua categoria. Le deduzioni si accumulano; una volta che il contributo di una categoria raggiunge zero, ulteriori violazioni in quella categoria non hanno ulteriori effetti sul punteggio totale — questo è il Category Cap (Tetto di Categoria).
| Codice | Descrizione | Penalità (pts) | Categoria |
|---|---|---|---|
| Z2xx | Violazione di Sicurezza | Override → 0/100 | — |
| Z503 | Errore Sintassi Snippet | 10.0 | Content |
| Z101 | Link Interrotto | 8.0 | Structural |
| Z104 | File Non Trovato | 8.0 | Structural |
| Z102 | Ancora Mancante | 5.0 | Structural |
| Z402 | Pagina Orfana | 4.0 | Navigation |
| Z401 | Indice Directory Mancante | 2.0 | Navigation |
| Z601 | Brand Obsoleto | 2.0 | Brand |
| Z405 | Asset Non Utilizzato | 3.0 | Brand |
| Z404 | Asset Config Mancante | 3.0 | Brand |
| Z501 | Placeholder (TODO / FIXME) | 2.0 | Content |
| Z406 | Errore Nav Contract | 2.0 | Brand |
| Z105 | Percorso Assoluto | 2.0 | Structural |
| Z502 | Contenuto Breve | 1.0 | Content |
| Z505 | Blocco di Codice Non Etichettato | 1.0 | Content |
| Z403 | Alt Text Mancante | 1.0 | Content |
| Z107 | Ancora Circolare | 1.0 | Structural |
| Z106 | Link Circolare | 0.0 | Informativo |
| Z108 | Empty Link Text | 1.0 | Structural |
Z106 è una diagnostica di integrità dei link, ma non sottrae punti. Z108 è la nuova penalità strutturale per le etichette di link malformate.
Filosofia di Calibrazione delle Penalità
Le penalità sono assegnate a uno di tre livelli, indipendentemente dal bucket di appartenenza:
| Livello | Esempi | Punti |
|---|---|---|
| Critico | Z503 (errore snippet) | 10.0 |
| Alto | Z301, Z402 (link rotto, pagina orfana) | 3.0 – 4.0 |
| Standard | Z104, Z401, Z403 … | 1.0 – 2.0 |
Una penalità Critica (10 pts) segnala che il contenuto è attivamente dannoso per i lettori (un esempio di codice non funzionante). Una penalità Alta segnala un difetto strutturale che il lettore incontrerà direttamente (un link morto, una pagina irraggiungibile). Una penalità Standard segnala un deficit di qualità che degrada l'esperienza nel tempo.
Invariante del Category Cap
Le deduzioni di categoria sono limitate dal peso della categoria:
- Tetto Structural: 30 pts (30% × 100)
- Tetto Content: 20 pts (20% × 100)
- Tetto Navigation: 25 pts (25% × 100)
- Tetto Brand: 25 pts (25% × 100)
Esempio: 100 × Z505 (1,0 pt ciascuno) genera 100 pts di deduzione potenziale contro la categoria Content — ma il tetto limita la perdita effettiva a 20 pts. Le altre tre categorie rimangono inalterate: 80/100 totale.
Separazione Score vs. Gate
Lo Score e la soglia fail_under sono indipendenti:
- Score (la Metrica): Misurazione oggettiva della qualità, limitata dai Category Cap.
fail_under(il Gate): La tua policy di enforcement in.zenzic.toml.
Uno score di 70/100 con fail_under = 80 esce comunque con codice 1. Il Category Cap
impedisce che un tipo di violazione rumoroso mascheri la salute strutturale —
non indebolisce il tuo gate.
Il punteggio finale 0–100 è la somma dei contributi di categoria pesati:
Come Interpretare il Tuo Punteggio
| Punteggio | Interpretazione |
|---|---|
| 95 – 100 | Eccellente — finding residui minimi |
| 80 – 94 | Buono — alcuni finding non critici |
| 60 – 79 | Discreto — lacune di qualità significative |
| 40 – 59 | Scarso — problemi sistematici che richiedono attenzione |
| < 40 | Critico — integrità della documentazione a rischio |
Esecuzione del Punteggio
# Calcola e mostra il punteggio (nessun file scritto)
zenzic score [PATH]
# Calcola, mostra e persiste in .zenzic-score.json
zenzic score [PATH] --save
# Calcola e fallisce se il punteggio scende sotto N
zenzic score [PATH] --fail-under 80
# Confronta il punteggio attuale con il baseline salvato (gate di regressione CI)
zenzic diff [PATH]
Lo snapshot è scritto in .zenzic-score.json nella root del repository. È un file
JSON leggibile dalle macchine — committalo nel repository affinché zenzic diff
abbia un baseline con cui confrontarsi.
Pattern CI consigliato
# Sui push al branch main: salva il nuovo baseline
- run: zenzic score --save --fail-under 80
# Sulle pull request: fallisce se il punteggio è sceso
- run: zenzic diff --threshold 0
zenzic diff esce con 1 se il punteggio attuale è inferiore al baseline salvato
(aggiustato da --threshold). Non fallisce se il punteggio è stabile o migliorante.
Soppressione e Gate di Governance
Esistono due meccanismi che interagiscono diversamente con il punteggio.
Soppressione (.zenzic-ignore) — rimuove un finding specifico dall'output. Il
finding soppresso non viene penalizzato. Usa la soppressione solo per eccezioni
deliberate e documentate.
Gate di governance — alcuni codici (Z602 I18N_PARITY) attivano un gate forzato:
zenzic check termina con codice 2 indipendentemente dal DQS. Il DQS stesso non è
influenzato perché i codici gate sono esclusi dalla matrice di penalità per design. Un
progetto può ottenere 100 e comunque fallire il gate se è presente una violazione di
parità delle traduzioni.
Regressione di Qualità — Z504
Quando zenzic diff rileva una diminuzione del punteggio, emette
Z504 QUALITY_REGRESSION come finding. Questo è l'unico codice di finding
che fa da ponte tra il layer di scoring e il layer di finding — significa:
"qualcosa che hai cambiato ha peggiorato il punteggio."
Z504 non viene pesato nel punteggio stesso (sarebbe circolare). È il segnale che comunica quale commit ha introdotto una regressione.
La Garanzia Exclusion Zone
Quando zenzic score restituisce 100/100, è una garanzia formale che:
- Ogni link interno si risolve (zero Z101/Z102/Z103/Z104/Z105)
- Ogni riferimento ad ancora si risolve (zero Z107)
- Ogni pagina è raggiungibile da almeno un punto di ingresso di navigazione (zero Z402)
- Ogni snippet di codice è sintatticamente valido (zero Z503)
- Non esiste contenuto placeholder (zero Z501)
- Non esistono blocchi di codice non etichettati (zero Z505)
- Non esistono asset non utilizzati (zero Z405)
- Non esistono violazioni del contratto di navigazione (zero Z406)
- Non esistono riferimenti di brand obsoleti (zero Z601)
- Il credential scanner non ha trovato credenziali in alcun file (zero Z201 — implicito, azzera il punteggio)
Questo è il Zenzic Audit Badge: lo stato in cui la documentazione è strutturalmente completa, pulita nei contenuti e verificata dalla sicurezza.
Porta il Sigillo nel tuo README: una volta raggiunto il 100/100, esegui
zenzic score --savee aggiungi il badge di punteggio dinamico al tuo progetto. Fai vedere ai contributor lo standard a cui si stanno impegnando. Consulta Badge Ufficiali per le URL dei badge pronte all'uso.
Invarianti di Ingegneria
Il Punteggio di Qualità è la prova operativa dei Tre Pilastri di Zenzic:
1. Analizza la Sorgente, Non il Build. Il punteggio è calcolato dall'analisi del sorgente Markdown grezzo — mai dall'output HTML o da un server web in esecuzione. Il peso del 30% per la categoria strutturale premia una sorgente che è internamente coerente prima che qualsiasi passo di build venga eseguito.
2. Zero Sottoprocessi.
compute_score() in core/scorer.py è una funzione Python pura — nessuna chiamata
shell, nessun subprocess.run, nessuna richiesta di rete. Riceve una mappa
findings_counts: dict[str, int] e restituisce uno ScoreReport. Questo garantisce
risultati identici su ogni OS e versione Python nella matrice CI
(ubuntu / windows / macos × Python 3.10–3.14).
3. Funzioni Pure Prima di Tutto.
compute_score() non ha effetti collaterali. save_snapshot() è l'unica funzione
di I/O e viene chiamata esplicitamente solo quando l'utente passa --save. La suite
di test verifica i calcoli del punteggio con test basati su proprietà (Hypothesis)
per garantire gli invarianti matematici.
Integrità del Nav Contract — Categorizzata come Brand & Asset
Quello che gli utenti talvolta chiamano "Nav Isolation" è formalmente Nav Contract Integrity (Z406).
Z406 scatta quando un file dichiarato nella configurazione di navigazione del motore (es. una voce nav: di mkdocs.yml
o una voce esplicita di Docusaurus sidebars.ts) non esiste su disco. Ogni violazione Z406
contribuisce alla categoria Brand & Asset (25%) usando la stessa penalità per codice
degli altri finding con score (Z406: 2,0 pts per violazione).
Esempio Pratico
Supponiamo un progetto con:
- 2 × Z503 SNIPPET_ERROR → 2 × 10.0 = 20.0 pts (al limite — riempie il bucket Content)
- 1 × Z301 DANGLING_REF → 4.0 pts (Navigation)
- 1 × Z405 UNUSED_ASSET → 3.0 pts (Brand)
Deduzione Structural = 0
Deduzione Navigation = min(4.0, 25) = 4.0 → contribuisce 4.0 × (25/25) = 4.0 pesato
Deduzione Content = min(20.0, 20) = 20.0 → contribuisce 20.0 × (20/20) = 20.0 pesato
Deduzione Brand = min(3.0, 25) = 3.0 → contribuisce 3.0 × (25/25) = 3.0 pesato
DQS = 100 − (0 + 4.0 + 20.0 + 3.0) = 73
I due errori di snippet da soli ridurrebbero il punteggio di 20 punti; correggerli recupera il bucket Content nella sua interezza.
Pagine Correlate
- Riferimento Algoritmo di Scoring — pesi formali, tabella delle penalità e specifica matematica
- Codici di Finding — catalogo completo di tutti i Z-code
- Policy di Soppressione — come i finding soppressi incidono sul Punteggio di Qualità