Passa al contenuto principale

Riferimento Controlli

Riferimento Controlli

Zenzic esegue sei controlli indipendenti. Ciascuno affronta una categoria distinta di degrado documentale — il deterioramento silenzioso che avviene quando un progetto cresce e la manutenzione della documentazione resta indietro rispetto allo sviluppo.

ControlloCLICosa individua
Controllo Linkzenzic check linksLink interni rotti, ancore morte, URL irraggiungibili
Orfanizenzic check orphansFile .md presenti su disco ma assenti dalla navigazione
Snippetzenzic check snippetsErrori di sintassi Python/YAML/JSON/TOML nei blocchi di codice
Segnapostozenzic check placeholdersPagine stub con basso conteggio parole o pattern TODO
Assetzenzic check assetsMedia mai referenziati da alcuna pagina
Riferimentizenzic check referencesRef-link pendenti, definizioni morte, credenziali esposte

CLI: zenzic check links [--strict]

Il link rot è uno dei difetti più comuni e visibili nella documentazione. Uno sviluppatore rinomina una pagina, sposta una sezione o elimina un'ancora, e i link che puntavano ad essa diventano silenziosamente vicoli ciechi.

zenzic check links utilizza un parser Python nativo — nessun sottoprocesso, nessuna dipendenza dal build driver. Scansiona ogni file .md sotto docs/, estrae tutti i link Markdown con una macchina a stati consapevole dei blocchi di codice, e li valida in due livelli.

Come funziona la Virtual Site Map

Quando Zenzic valida i link, non si limita a verificare se il file di destinazione esiste su disco. Costruisce invece una Virtual Site Map (VSM) — una proiezione puramente in memoria di ciò che il build engine servirà effettivamente ai lettori.

La VSM associa ogni URL canonico a una voce Route:

CampoSignificato
urlL'URL che un browser richiederebbe, es. /guide/install/
sourceIl file sorgente che produce questo URL, es. guide/install.md
statusSe la pagina è raggiungibile, orfana, ignorata o in conflitto
anchorsAncore degli heading pre-calcolate dal file sorgente

Ogni route porta uno stato che indica a Zenzic come trattare i link che vi puntano:

StatoSignificatoRisultato link
REACHABLELa pagina è elencata nella navigazione o è una route di localizzazioneValido
ORPHAN_BUT_EXISTINGIl file esiste su disco ma non nella navigazione del sitoAvviso Z002
IGNOREDEscluso dalla configurazione (es. file README, directory private)Errore Z001
CONFLICTDue file sorgente producono lo stesso URL canonicoErrore Z001

Perché è importante: Un file può esistere nel filesystem ed essere comunque IGNORED nella VSM. Un URL può essere REACHABLE nella VSM senza avere un file corrispondente su disco (ad esempio, le route indice delle localizzazioni). La VSM è l'autorità — Zenzic verifica la raggiungibilità, non la semplice esistenza del file.

Questo design fa sì che zenzic check links individui problemi che un semplice controllo di esistenza del file non coglierebbe: pagine rimosse dalla navigazione, route in conflitto e contenuti orfani che i lettori non possono scoprire navigando normalmente.

I percorsi relativi e site-absolute vengono risolti rispetto alla directory docs/ in memoria. Il file di destinazione deve esistere nel set di file scansionati. Vengono risolti anche i percorsi senza estensione (setup) e i percorsi directory-index (setup/). Se il link include un #fragment, Zenzic estrae le ancore degli heading dal file di destinazione e verifica la corrispondenza del frammento.

  • [testo](pagina-mancante.md) → file di destinazione non trovato
  • [testo](pagina.md#ancora-mancante) → ancora non trovata nel file di destinazione

Tutti i file .md vengono letti una sola volta; le ancore sono pre-calcolate dagli heading (# Titolo#titolo). Nessuna I/O aggiuntiva per link.

Con --strict, ogni URL http:// e https:// nella documentazione viene validato tramite richieste HTTP HEAD concorrenti usando httpx. Fino a 20 connessioni simultanee. I server che rifiutano HEAD ricevono un fallback GET. Lo stesso URL referenziato in più pagine viene verificato una sola volta.

I server che restituiscono 401, 403 o 429 sono trattati come raggiungibili — indicano restrizioni di accesso, non link rotti. Timeout (>10 s) ed errori di connessione vengono segnalati come fallimenti.

Cosa non viene mai validato

  • Link dentro blocchi di codice o span di codice inline — l'estrattore li salta
  • Schemi mailto:, data:, ftp:, tel: e simili non-HTTP
  • Ancore alla stessa pagina (#sezione) — non validate di default; abilitare con validate_same_page_anchors = true
Validazione ancore stessa pagina

Di default, link come [testo](#sezione) che puntano a un heading nello stesso file non vengono validati. Per abilitare:

# zenzic.toml
validate_same_page_anchors = true

Codici di violazione

CodiceSeveritàSignificato
Z001erroreLink rotto — il target non esiste nella VSM
Z002avvisoLink orfano — il target esiste su disco ma non nella navigazione del sito
ABSOLUTE_PATHerrorePercorso assoluto — il link usa un percorso site-absolute (/docs/pagina) invece di un percorso relativo (../pagina)

Z001 blocca sempre la pipeline (exit code 1). Z002 è un avviso — appare nel report ma non fa fallire la CI a meno che non venga passato --strict. ABSOLUTE_PATH è un errore perché i percorsi assoluti compromettono la portabilità quando il sito è ospitato in una sottodirectory.

Coerenza Fisica — perché i percorsi relativi contano

Alcuni build engine (es. Docusaurus) permettono override slug nel frontmatter che disaccoppiano l'URL di una pagina dalla sua posizione nel filesystem. Quando questo accade, la "directory padre" per la risoluzione dei link relativi può differire tra il build engine (che risolve dall'URL) e Zenzic (che risolve dal percorso del file).

Best practice: mantieni la struttura del filesystem allineata alla struttura degli URL. Se sposti un file in guides/checks.mdx, lascia che il suo URL diventi /docs/guides/checks piuttosto che forzare uno slug a /docs/checks. Questo garantisce che i link ../ si risolvano in modo identico sia per il linter che per il build engine.

Output Sentinel — reporter gutter:

docs/guide.md
[FILE_NOT_FOUND]'intro.md' non raggiungibile dalla nav
15 prima di continuare.
16Consulta la pagina introduttiva per i dettagli.
17 Poi configura il tuo ambiente.

Blood Sentinel — traversamento path di sistema

Blood Sentinel tratta il traversamento host-path come un evento di sicurezza, non come routine di igiene dei link. Se un link esce da docs/ e si risolve verso path di sistema operativo (/etc/, /root/, /var/, /proc/, /sys/, /usr/), Zenzic emette PATH_TRAVERSAL_SUSPICIOUS ed esce con codice 3.

CodiceSeveritàExit codeSignificato
PATH_TRAVERSAL_SUSPICIOUSincidente_sicurezza3L'href punta a una directory di sistema OS
PATH_TRAVERSALerrore1L'href esce da docs/ verso un percorso non di sistema
Exit Code 3 — Blood Sentinel

Un risultato PATH_TRAVERSAL_SUSPICIOUS significa che un file sorgente della documentazione contiene un link il cui target risolto punta a /etc/passwd, /root/, o un altro path di sistema OS. Questo può indicare una template injection, una toolchain di documentazione compromessa, o un errore dell'autore che rivela dettagli dell'infrastruttura interna. Trattarlo come un incidente di sicurezza bloccante per la build.

🚨 BLOOD SENTINEL — PATH TRAVERSAL
Finding:PATH_TRAVERSAL_SUSPICIOUS
Location:docs/setup.md:18
Target:/etc/passwd
Exit code:3

Come funziona lo Shield

Lo Zenzic Shield utilizza un'architettura a doppio flusso per garantire che nessuna parte di un file sfugga alla scansione delle credenziali.

Quando il Reference Scanner elabora un file, crea due flussi indipendenti:

┌─────────────────────────────────┐
│ Reference Scanner │
│ │
File su disco ──►│ Flusso SHIELD │
│ vede TUTTE le righe (incluso │
│ il frontmatter YAML) │
│ │
│ Flusso CONTENUTI │
│ salta frontmatter + blocchi │
│ di codice (analizza │
│ riferimenti e immagini) │
└─────────────────────────────────┘

I due flussi hanno regole di filtraggio opposte per design. Il flusso Contenuti deve saltare il frontmatter YAML per evitare di interpretare metadati come author: Jane Doe come una definizione reference rotta. Il flusso Shield deve vedere il frontmatter perché una chiave come aws_key: AKIA... nascosta nei metadati YAML è un segreto reale che deve essere intercettato. I flussi non condividono mai una sorgente dati — unirli creerebbe un punto cieco.

Normalizzatore Pre-Scansione. Prima di eseguire i pattern di rilevamento, lo Shield normalizza ogni riga per contrastare l'offuscamento. I backtick di codice inline vengono rimossi, gli operatori di concatenazione eliminati e i caratteri pipe delle tabelle collassati. Questo significa che un segreto spezzato tra colonne di una tabella Markdown — come una chiave AWS divisa in `AKIA` + `suffisso` — viene riassemblato prima della scansione. Vengono verificate sia la forma grezza che quella normalizzata, e un set di deduplicazione previene le doppie segnalazioni.

Protezione ReDoS. Se aggiungi pattern regex personalizzati tramite [[custom_rules]] in zenzic.toml, Zenzic sottopone ogni pattern a uno stress test con un canary di 100 ms prima che venga eseguito sui tuoi file. I pattern che presentano backtracking catastrofico vengono rifiutati all'avvio con un errore chiaro. Come seconda rete di sicurezza, ogni processo worker ha un timeout di 30 secondi — se un pattern riesce comunque a bloccarsi a runtime, il file interessato riceve un risultato Z009: ANALYSIS_TIMEOUT invece di bloccare la tua pipeline CI indefinitamente.

Il rilevamento dei cicli viene calcolato una sola volta con DFS iterativo durante la costruzione del resolver (Fase 1.5, Θ(V+E)). Ogni lookup di appartenenza in Fase 2 contro il registro dei cicli è O(1).

CodiceSeveritàExit codeSignificato
CIRCULAR_LINKinfoIl target risolto è membro di un ciclo di link
Risultato livello info — soppresso di default

I risultati CIRCULAR_LINK sono nascosti dall'output standard. Usa --show-info per visualizzarli:

zenzic check all --show-info

Non influenzano mai gli exit code, né in modalità normale né in modalità --strict.


Orfani

CLI: zenzic check orphans

Una pagina orfana esiste su disco ma non è elencata nella navigazione del sito. È invisibile ai lettori che seguono l'albero di navigazione — può essere raggiunta solo indovinando l'URL o trovando un link diretto.

Cosa individua:

  • Pagine create su disco ma mai aggiunte alla nav
  • Pagine la cui voce nella nav è stata rimossa senza eliminare il file
Orphan Detection
[ORPHAN]docs/old-guide.md
[ORPHAN]docs/drafts/wip-page.md
2 files on disk but absent from site navigation

Snippet

CLI: zenzic check snippets

Gli esempi di codice nella documentazione vengono testati con meno rigore rispetto al codice di produzione. Uno snippet che funzionava quando è stato scritto può avere un errore di sintassi introdotto da un refactoring, un errore di copia-incolla o una modifica manuale mai revisionata.

Linguaggi supportati

Tag linguaggioParserCosa viene verificato
python, pycompile() in modalità execSintassi Python 3.11+
yaml, ymlyaml.safe_load()Struttura YAML 1.1
jsonjson.loads()Sintassi JSON
tomltomllib.loads() (stdlib 3.11+)Sintassi TOML v1.0

I blocchi con qualsiasi altro tag linguaggio (bash, javascript, mermaid, ecc.) sono trattati come testo puro e non vengono verificati sintatticamente. Tuttavia, ogni blocco di codice è comunque scansionato dallo Zenzic Shield per pattern di credenziali.

Cosa individua

  • Python: SyntaxError — due punti mancanti, parentesi non bilanciate, espressioni non valide
  • YAML: errori strutturali — sequenze non chiuse, mapping non validi, chiavi duplicate
  • JSON: JSONDecodeError — virgole finali, virgolette mancanti, parentesi non bilanciate
  • TOML: TOMLDecodeError — virgolette mancanti sui valori, sintassi chiave non valida
docs/tutorial.md
[SYNTAX_ERROR]Python block at line 24 fails to compile
23│ ```python
24def hello(name
25│ print(f"Hello {name}")
Configurazione

Usa snippet_min_lines in zenzic.toml per saltare i blocchi brevi. Il default di 1 controlla tutto. Impostalo a 3 o superiore per ignorare gli stub di import.

# zenzic.toml
snippet_min_lines = 3

Segnaposto

CLI: zenzic check placeholders

Le pagine segnaposto sono pagine create come stub e mai completate. Sono debito documentale.

Segnale 1 — conteggio parole

Le pagine con meno di placeholder_max_words parole (default: 50) vengono segnalate come short-content.

Segnale 2 — corrispondenza pattern

Le righe contenenti qualsiasi stringa da placeholder_patterns (case-insensitive) vengono segnalate come placeholder-text. I pattern predefiniti includono: coming soon, work in progress, wip, todo, to do, stub, placeholder, fixme, tbd, draft, da completare, in costruzione, bozza, prossimamente.

Entrambi i segnali sono indipendenti. Una pagina può attivarne uno, entrambi o nessuno.

Configurazione
# zenzic.toml
placeholder_max_words = 100
placeholder_patterns = ["coming soon", "wip", "fixme", "tbd", "draft"]

Asset

CLI:

  • zenzic check assets — Controlla file asset inutilizzati
  • zenzic clean assets — Rimuovi in sicurezza gli asset inutilizzati
Autofix disponibile

Usa zenzic clean assets per eliminare automaticamente gli asset inutilizzati trovati da questo controllo. Passa -y per saltare la conferma, o --dry-run per un'anteprima. Zenzic non cancellerà mai file corrispondenti ai tuoi pattern excluded_assets, excluded_dirs o excluded_build_artifacts.

Un asset è considerato usato se appare come link immagine Markdown (![alt](percorso)) o tag HTML <img src="..."> in qualsiasi file .md. I percorsi vengono normalizzati usando l'aritmetica dei percorsi POSIX.

Sempre esclusi: i file .css, .js, .yml non vengono mai segnalati come inutilizzati — sono tipicamente override del tema o configurazione di build.

Cosa individua:

  • Screenshot caricati ma mai incorporati
  • Immagini rimaste dopo una riorganizzazione delle pagine
  • Allegati collegati da una pagina che non esiste più

Riferimenti

CLI: zenzic check references

Il controllo di sicurezza e integrità dei link per i link in stile reference di Markdown. Funge anche da superficie primaria per lo Zenzic Shield.

Pipeline Reference a Tre Passaggi

PassaggioNomeCosa succede
1RaccoltaProcessa ogni riga; registra le definizioni [id]: url; esegue Shield su ogni URL e riga
2Verifica IncrociataRisolve ogni utilizzo [testo][id] contro la ReferenceMap completa; segnala gli ID non risolvibili
3Report IntegritàCalcola il punteggio di integrità per file; aggiunge avvisi su Definizioni Morte e alt-text

Il Passaggio 2 inizia solo quando il Passaggio 1 si completa senza risultati Shield.

Codici di violazione riferimenti

CodiceSeveritàExit codeSignificato
DANGLING_REFerrore1[testo][id]id non ha definizione nel file
DEAD_DEFavviso0 / 1 --strict[id]: url definito ma mai referenziato
DUPLICATE_DEFavviso0 / 1 --strictStesso id definito due volte; il primo vince
MISSING_ALTavviso0 / 1 --strictImmagine con alt text vuoto o assente
Corrispondenza pattern Shieldviolazione_sicurezza2Credenziale rilevata in qualsiasi riga o URL

Zenzic Shield — rilevamento credenziali

Lo Shield scansiona ogni riga di ogni file durante il Passaggio 1, incluse le righe dentro blocchi di codice.

Famiglie di pattern rilevati:

PatternCosa individua
openai-api-keyChiavi API OpenAI (sk-…)
github-tokenToken personali / OAuth GitHub (gh[pousr]_…)
aws-access-keyID chiave di accesso AWS IAM (AKIA…)
stripe-live-keyChiavi segrete live Stripe (sk_live_…)
slack-tokenToken bot / utente / app Slack (xox[baprs]-…)
google-api-keyChiavi API Google Cloud / Maps (AIza…)
private-keyChiavi private PEM (-----BEGIN … PRIVATE KEY-----)
hex-encoded-payloadSequenze di byte hex-encoded (3+ escape \xNN consecutivi)
gitlab-patGitLab Personal Access Token (glpat-…)

Exit Code 2 è riservato agli eventi Shield. Non viene mai soppresso da --exit-zero o exit_zero = true in zenzic.toml.

Se ricevi exit code 2

Ruota la credenziale esposta immediatamente, poi rimuovi o sostituisci la riga incriminata. Non committare il segreto nella cronologia del repository.

VIOLAZIONE SICUREZZA RILEVATA
Trovato:Token GitHub rilevato
Posizione:docs/tutorial.md:42
Credenziale:ghp_************3456
Azione:Ruota questa credenziale immediatamente e rimuovila dalla cronologia del repository.
✘ 2 errori⚠ 1 avviso• 1 file con rilevamenti
FALLITO: Uno o più controlli hanno fallito.