Passa al contenuto principale

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.

CategoriaComandoCodici FindingPeso
Integrità Strutturalezenzic check links [PATH]Z101, Z102, Z104, Z105, Z107, Z10830 %
Eccellenza dei Contenutizenzic check all [PATH]Z403, Z501, Z502, Z503, Z50520 %
Navigazionezenzic check orphans [PATH]Z301, Z302, Z303, Z401, Z40225 %
Brand & Assetzenzic check assets [PATH]Z404, Z405, Z406, Z60125 %

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.

Override di Sicurezza

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).

CodiceDescrizionePenalità (pts)Categoria
Z2xxViolazione di SicurezzaOverride → 0/100
Z503Errore Sintassi Snippet10.0Content
Z101Link Interrotto8.0Structural
Z104File Non Trovato8.0Structural
Z102Ancora Mancante5.0Structural
Z402Pagina Orfana4.0Navigation
Z401Indice Directory Mancante2.0Navigation
Z601Brand Obsoleto2.0Brand
Z405Asset Non Utilizzato3.0Brand
Z404Asset Config Mancante3.0Brand
Z501Placeholder (TODO / FIXME)2.0Content
Z406Errore Nav Contract2.0Brand
Z105Percorso Assoluto2.0Structural
Z502Contenuto Breve1.0Content
Z505Blocco di Codice Non Etichettato1.0Content
Z403Alt Text Mancante1.0Content
Z107Ancora Circolare1.0Structural
Z106Link Circolare0.0Informativo
Z108Empty Link Text1.0Structural

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:

LivelloEsempiPunti
CriticoZ503 (errore snippet)10.0
AltoZ301, Z402 (link rotto, pagina orfana)3.0 – 4.0
StandardZ104, 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:

score=imax(0, wi×100deduzionii)\text{score} = \left\lfloor \sum_i \max\bigl(0,\ w_i \times 100 - \text{deduzioni}_i\bigr) \right\rceil

Come Interpretare il Tuo Punteggio

PunteggioInterpretazione
95 – 100Eccellente — finding residui minimi
80 – 94Buono — alcuni finding non critici
60 – 79Discreto — lacune di qualità significative
40 – 59Scarso — problemi sistematici che richiedono attenzione
< 40Critico — 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

.github/workflows/zenzic.yml
# 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)
Structural Integrity30 pts0 broken links
Navigation25 pts0 orphan pages
Content Excellence20 pts0 placeholders
Brand & Assets25 pts0 brand violations
🏆Quality Score:100 / 100◆ Zenzic Audit Badge
credential scanner: no credentials detected
path traversal guard: no path-traversal attempts
Files scanned: 47  ·  Elapsed: 0.28 s

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 --save e 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