diff --git a/docs/assets/screenshots/screenshot-hero.svg b/docs/assets/screenshots/screenshot-hero.svg index 0c1f28a..c9e2eac 100644 --- a/docs/assets/screenshots/screenshot-hero.svg +++ b/docs/assets/screenshots/screenshot-hero.svg @@ -142,7 +142,7 @@ zenzic check all -╭─────────────────────────── 🛡  ZENZIC SENTINEL  v0.5.0a3 ───────────────────────────╮ +╭─────────────────────────── 🛡  ZENZIC SENTINEL  v0.5.0a4 ───────────────────────────╮ mkdocs • 3 files (3 docs, 0 assets) • 0.0s diff --git a/docs/assets/stylesheets/extra.css b/docs/assets/stylesheets/extra.css index dc88c18..b5d2ea5 100644 --- a/docs/assets/stylesheets/extra.css +++ b/docs/assets/stylesheets/extra.css @@ -866,3 +866,21 @@ .md-footer { border-top: 1px solid var(--zz-border-subtle); } + +/* Documentation cards - structural consistency */ +.md-typeset .grid.cards > ul > li { + border: 1px solid var(--md-code-fg-color--transparent); + border-radius: 0.2rem; + padding: 1.2rem; + transition: border-color 0.25s, background-color 0.25s; +} + +.md-typeset .grid.cards > ul > li:hover { + border-color: var(--md-accent-fg-color); + background-color: var(--md-accent-fg-color--transparent); +} + +/* Remove extra margin from lists inside cards */ +.md-typeset .grid.cards ul { + margin-bottom: 0; +} diff --git a/docs/checks.md b/docs/checks.md index 2ba401a..6d19387 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -170,10 +170,12 @@ suppressed by `--exit-zero`. FAILED: One or more checks failed. ``` - Exit code: **3** ![Zenzic Sentinel — Blood Report: PATH_TRAVERSAL_SUSPICIOUS finding in blood red](assets/screenshots/screenshot-blood.svg) +See also: [Exit codes reference](usage/commands.md#exit-codes) for a summary of how exit +code 3 compares to other Zenzic exit codes. + ### Circular links Zenzic detects link cycles using an iterative depth-first search over the link adjacency @@ -188,7 +190,10 @@ common, intentional, and do not cause rendering problems for any static site gen For this reason, `CIRCULAR_LINK` is reported at severity `info`. It appears in the Sentinel panel and contributes to the "N files with findings" count, but it never affects exit codes in normal or `--strict` mode. Teams that want to enforce strict DAG topology can inspect -the info findings as part of their review process. +the info findings as part of their review process. Info findings are hidden by default to +keep routine scans focused on blocking violations; use `--show-info` to display them. +For the design decision behind this severity choice, see +[ADR 003 — Root Discovery Protocol](adr/003-discovery-logic.md). | Code | Severity | Exit code | Meaning | | :--- | :---: | :---: | :--- | @@ -208,21 +213,6 @@ the info findings as part of their review process. ✔ All checks passed. ``` -!!! note "Info-level finding — suppressed by default" - `CIRCULAR_LINK` findings are reported at severity `info` and are __not shown__ - in standard output to avoid cluttering routine scans. Mutual navigation links - are common and intentional in hypertext documentation structures. - - Use `--show-info` to display them: - - ```bash - zenzic check all --show-info - ``` - - They never block the build or affect exit codes in any mode. - For the design decision behind this severity choice, see - [ADR 003 — Root Discovery Protocol](adr/003-discovery-logic.md). - ![Zenzic Sentinel — Circle Discovery: CIRCULAR_LINK findings displayed with --show-info](assets/screenshots/screenshot-circular.svg) --- diff --git a/docs/developers/plugins.md b/docs/developers/plugins.md index 273ad77..7a5b2ad 100644 --- a/docs/developers/plugins.md +++ b/docs/developers/plugins.md @@ -286,5 +286,17 @@ refuses to start. Fix the rule before running Zenzic. - [ ] Entry-point registered under `zenzic.rules` in `pyproject.toml`. - [ ] Plugin ID listed in the project's `zenzic.toml` under `plugins`. +!!! abstract "Next Steps" + Bridge your rule from implementation to production Sentinel flow: + + 1. Register and enable the plugin ID in `zenzic.toml` under `plugins` + (see [Enabling plugins](#enabling-plugins)). + 2. Validate the rule under strict pipeline semantics: + `zenzic check all --strict`. + For run-time policy controls, see + [CLI Commands: Global flags](../usage/commands.md#global-flags). + 3. If your rule is nav-aware, map expected Ghost Route behavior against the VSM model: + [VSM Engine — Ghost Route](../arch/vsm_engine.md#example-d-ghost-route-reachable-without-a-file). + [ep]: https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata [api-baserule]: ../reference/api.md diff --git a/docs/developers/writing-an-adapter.md b/docs/developers/writing-an-adapter.md index c1ad6d1..2407063 100644 --- a/docs/developers/writing-an-adapter.md +++ b/docs/developers/writing-an-adapter.md @@ -258,3 +258,15 @@ def test_nav_paths_relative() -> None: assert "guide/setup.md" in paths assert all(not p.startswith("/") for p in paths) ``` + +!!! abstract "Next Steps" + Connect adapter code to deployment truth: + + 1. Register engine identity in project configuration via `[build_context] engine` + (see [Adapters & Engine Configuration](../configuration/adapters-config.md)). + 2. Validate adapter behavior under strict Sentinel policy: + `zenzic check all --engine myengine --strict`. + For run controls, see [CLI Commands: Global flags](../usage/commands.md#global-flags). + 3. If your engine generates synthetic locale routes, explicitly map Ghost Route + expectations against the VSM reference: + [VSM Engine — Ghost Route](../arch/vsm_engine.md#example-d-ghost-route-reachable-without-a-file). diff --git a/docs/guide/engines.md b/docs/guide/engines.md index 6b739ab..0d2ce1d 100644 --- a/docs/guide/engines.md +++ b/docs/guide/engines.md @@ -60,6 +60,15 @@ If `[build_context]` is absent entirely, Zenzic auto-detects: - `mkdocs.yml` present → `MkDocsAdapter` - neither config present, no locales declared → `VanillaAdapter` (orphan check disabled) +!!! abstract "CLI bridge — Signal-to-noise controls" + Engine selection and Sentinel verbosity are independent concerns. Use + [CLI Commands: Global flags](../usage/commands.md#global-flags) to tune policy per run: + + 1. `--strict` to elevate warnings and enforce external URL validation. + 2. `--exit-zero` for non-blocking observation runs. + 3. `--show-info` to inspect informational topology findings. + 4. `--quiet` for one-line CI/pre-commit output. + --- ## MkDocs diff --git a/docs/guide/index.md b/docs/guide/index.md index bfa3179..0cf4eec 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -41,35 +41,21 @@ Beyond reporting, Zenzic provides **autofix utilities** (like `zenzic clean asse - :lucide-play:   **User Guide** - --- - Installation, all CLI commands, quality scoring, CI/CD integration, and badges. - - [Getting Started](../usage/index.md) - - [Available Checks](../checks.md) - - [Configuration](../configuration/index.md) - - [Engines](engines.md) - - [CI/CD Integration](../ci-cd.md) - - [Badges](../usage/badges.md) - - [FAQs](../community/faqs.md) + [:octicons-arrow-right-24: Getting Started](../usage/index.md) · [Checks](../checks.md) · [Configuration](../configuration/index.md) · [Engines](engines.md) · [CI/CD](../ci-cd.md) · [Badges](../usage/badges.md) · [FAQs](../community/faqs.md) - :lucide-book:   **Developer Guide** - --- - Architecture internals and auto-generated API documentation. - - [Architecture](../architecture.md) - - [API Reference](../reference/api.md) + [:octicons-arrow-right-24: Architecture](../architecture.md) · [API Reference](../reference/api.md) - :lucide-users:   **Community** - --- - Report issues, request features, improve the docs, or open a pull request. - - [Get Involved](../community/index.md) - - [How to Contribute](../community/contribute/index.md) + [:octicons-arrow-right-24: Get Involved](../community/index.md) · [How to Contribute](../community/contribute/index.md) diff --git a/docs/guide/migration.md b/docs/guide/migration.md index d1f186f..c552f07 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -186,6 +186,15 @@ reported as orphans. ## Migration playbook +!!! abstract "CLI bridge — Global flags" + Engine migration changes adapters, not Sentinel policy. Keep run behavior aligned with + [CLI Commands: Global flags](../usage/commands.md#global-flags): + + 1. `--strict` for hard-gate validation during cutover. + 2. `--exit-zero` for observation windows without breaking the pipeline. + 3. `--show-info` to inspect link-graph signals (for example `CIRCULAR_LINK`). + 4. `--quiet` for silent builders in CI hooks. + ### Phase 1 — Establish a baseline Run the full check suite and lock in a quality baseline before changing anything: diff --git a/docs/it/developers/plugins.md b/docs/it/developers/plugins.md index 10e9980..30cedd4 100644 --- a/docs/it/developers/plugins.md +++ b/docs/it/developers/plugins.md @@ -293,4 +293,16 @@ Zenzic. - [ ] Entry-point registrato sotto `zenzic.rules` nel `pyproject.toml`. - [ ] Plugin ID elencato nel `zenzic.toml` del progetto sotto `plugins`. +!!! abstract "Passaggi Successivi" + Collega la regola dal codice al flusso Sentinel in produzione: + + 1. Registra e abilita il plugin ID nel `zenzic.toml` sotto `plugins` + (vedi [Abilitare i plugin](#abilitare-i-plugin)). + 2. Valida la regola in semantica pipeline strict: + `zenzic check all --strict`. + Per i controlli di run, vedi [Comandi CLI: Flag globali](../usage/commands.md#flag-globali). + 3. Se la regola è nav-aware, mappa il comportamento atteso delle Ghost Route rispetto + al modello VSM: + [VSM Engine — Esempio D: Ghost Route](../arch/vsm_engine.md#esempio-d-ghost-route-raggiungibile-senza-file). + [api-baserule]: ../../reference/api.md diff --git a/docs/it/developers/writing-an-adapter.md b/docs/it/developers/writing-an-adapter.md index 85b5626..8d5972f 100644 --- a/docs/it/developers/writing-an-adapter.md +++ b/docs/it/developers/writing-an-adapter.md @@ -102,6 +102,18 @@ zenzic check all --engine myengine Le `[[custom_rules]]` dichiarate in `zenzic.toml` si attivano identicamente con qualsiasi adapter — incluso il tuo. Non è richiesta alcuna integrazione speciale. +!!! abstract "Passaggi Successivi" + Collega il lavoro sull'adapter alla verità operativa del progetto: + + 1. Registra l'identità engine in configurazione tramite `[build_context] engine` + (vedi [Adapter e Configurazione del Motore](../configuration/adapters-config.md)). + 2. Valida il comportamento adapter in policy Sentinel strict: + `zenzic check all --engine myengine --strict`. + Per i controlli di run, vedi [Comandi CLI: Flag globali](../usage/commands.md#flag-globali). + 3. Se il tuo engine genera route locali sintetiche, mappa esplicitamente le Ghost Route + rispetto al riferimento VSM: + [VSM Engine — Esempio D: Ghost Route](../arch/vsm_engine.md#esempio-d-ghost-route-raggiungibile-senza-file). + --- Per la documentazione completa del protocollo, gli esempi di test e la checklist di conformità, diff --git a/docs/it/guide/engines.md b/docs/it/guide/engines.md index e84556e..1474ebc 100644 --- a/docs/it/guide/engines.md +++ b/docs/it/guide/engines.md @@ -63,6 +63,15 @@ Se `[build_context]` è assente, Zenzic rileva automaticamente: - `mkdocs.yml` presente → `MkDocsAdapter` - nessuna configurazione presente, nessun locale dichiarato → `VanillaAdapter` (controllo orphan disabilitato) +!!! abstract "Ponte CLI — Controlli signal-to-noise" + Selezione engine e verbosità Sentinel sono aspetti separati. Usa + [Comandi CLI: Flag globali](../usage/commands.md#flag-globali) per calibrare la policy per run: + + 1. `--strict` per elevare warning e imporre validazione URL esterni. + 2. `--exit-zero` per run osservativi non bloccanti. + 3. `--show-info` per ispezionare finding informativi di topologia. + 4. `--quiet` per output CI/pre-commit a riga singola. + --- ## MkDocs diff --git a/docs/it/guide/index.md b/docs/it/guide/index.md index f84a7aa..440ebf3 100644 --- a/docs/it/guide/index.md +++ b/docs/it/guide/index.md @@ -41,35 +41,21 @@ Oltre alla pura reportistica, Zenzic fornisce **utility di autofix** (come `zenz - :lucide-play:   **Guida Utente** - --- - Installazione, tutti i comandi CLI, quality scoring, integrazione CI/CD e badge. - - [Primi Passi](../usage/index.md) - - [Controlli Disponibili](../checks.md) - - [Configurazione](../configuration/index.md) - - [Motori](engines.md) - - [Integrazione CI/CD](../ci-cd.md) - - [Badge](../usage/badges.md) - - [FAQ](../community/faqs.md) + [:octicons-arrow-right-24: Primi Passi](../usage/index.md) · [Controlli](../checks.md) · [Configurazione](../configuration/index.md) · [Motori](engines.md) · [CI/CD](../ci-cd.md) · [Badge](../usage/badges.md) · [FAQ](../community/faqs.md) - :lucide-book:   **Guida Sviluppatore** - --- - Architettura interna e documentazione API auto-generata. - - [Architettura](../architecture.md) - - [Riferimento API](../reference/api.md) + [:octicons-arrow-right-24: Architettura](../architecture.md) · [Riferimento API](../reference/api.md) - :lucide-users:   **Comunità** - --- - Segnala problemi, richiedi funzionalità, migliora i docs o apri una pull request. - - [Partecipa](../community/index.md) - - [Come Contribuire](../community/contribute/index.md) + [:octicons-arrow-right-24: Partecipa](../community/index.md) · [Come Contribuire](../community/contribute/index.md) diff --git a/docs/it/guide/migration.md b/docs/it/guide/migration.md index d105ac5..81174cb 100644 --- a/docs/it/guide/migration.md +++ b/docs/it/guide/migration.md @@ -188,6 +188,15 @@ Map in modo che non vengano mai segnalate come orfane. ## Piano di migrazione +!!! abstract "Ponte CLI — Flag globali" + La migrazione engine cambia gli adapter, non la policy Sentinel. Mantieni il comportamento + di esecuzione allineato a [Comandi CLI: Flag globali](../usage/commands.md#flag-globali): + + 1. `--strict` per validazione hard-gate durante il cutover. + 2. `--exit-zero` per finestre di osservazione senza interrompere la pipeline. + 3. `--show-info` per ispezionare segnali del grafo link (esempio `CIRCULAR_LINK`). + 4. `--quiet` per Silent Builders negli hook CI. + ### Fase 1 — Stabilisci un baseline Esegui la suite completa di controlli e registra un baseline (punto di riferimento) di diff --git a/docs/it/usage/advanced.md b/docs/it/usage/advanced.md index 4ee30b6..570e8e3 100644 --- a/docs/it/usage/advanced.md +++ b/docs/it/usage/advanced.md @@ -79,7 +79,7 @@ per intercettare segreti nella prosa normale. | `slack-token` | `xox[baprs]-[0-9a-zA-Z]{10,48}` | Token bot/utente/app Slack | | `google-api-key` | `AIza[0-9A-Za-z\-_]{35}` | Chiavi API Google Cloud / Maps | | `private-key` | `-----BEGIN [A-Z ]+ PRIVATE KEY-----` | Chiavi private PEM (RSA, EC, ecc.) | -| `hex-encoded-payload` | `(?:\\x[0-9a-fA-F]{2}){3,}` | Sequenze di byte hex-encoded (3+ sequenze `\xNN` consecutive) | +| `hex-encoded-payload` | `(?:\\x[0-9a-fA-F]{2}){3,}` | Rileva tentativi di offuscamento di payload o credenziali tramite escape esadecimali. Questa tecnica è comunemente usata per evadere i linter di stringhe semplici e Zenzic la considera una violazione critica della trasparenza del sorgente. | ### Comportamento dello Shield { #shield-behaviour } diff --git a/docs/it/usage/commands.md b/docs/it/usage/commands.md index 14acae6..98bc80b 100644 --- a/docs/it/usage/commands.md +++ b/docs/it/usage/commands.md @@ -27,10 +27,17 @@ zenzic check all # Esegue tutti i controlli zenzic check all --strict # Valida anche gli URL esterni; tratta i warning come errori zenzic check all --format json # Output machine-readable zenzic check all --exit-zero # Segnala problemi ma esce sempre con codice 0 +zenzic check all --quiet # Output minimale a riga singola per pre-commit e CI zenzic check all --engine mkdocs # Sovrascrive il motore rilevato +zenzic check links --show-info # Mostra finding di livello info (es. link circolari) ``` -### Flag `--strict` +## Flag globali + +Questi flag controllano il profilo signal-to-noise di Zenzic tra scansioni quotidiane, +gate CI e risposta agli incidenti. + +### `--strict` | Comando | Effetto | | :--- | :--- | @@ -41,14 +48,44 @@ zenzic check all --engine mkdocs # Sovrascrive il motore rilevato Puoi anche impostare `strict = true` in `zenzic.toml` per renderlo il default permanente. -### Flag `--exit-zero` +### `--exit-zero` Esce sempre con codice `0` anche quando vengono trovati problemi. Tutti i problemi vengono comunque stampati e inclusi nel punteggio — solo il codice di uscita viene soppresso. Utile per pipeline di sola osservazione. +Gli eventi di sicurezza non vengono mai declassati da questo flag: Exit 2 (violazione Shield) +ed Exit 3 (incidente Blood Sentinel su path di sistema) mantengono sempre priorità sui fallimenti ordinari. + Puoi anche impostare `exit_zero = true` in `zenzic.toml` per renderlo il default permanente. +### `--show-info` + +Per impostazione predefinita, i finding di livello info sono nascosti per mantenere l'output +quotidiano concentrato sulle violazioni azionabili. Usa `--show-info` quando vuoi piena visibilità +Sentinel sui segnali non bloccanti, come la topologia dei cicli link (`CIRCULAR_LINK`). + +Disponibile su tutti i comandi `zenzic check`. + +```bash +zenzic check links --show-info +zenzic check all --show-info +``` + +### `--quiet` + +`--quiet` è disponibile su `zenzic check all` ed è pensato per i Silent Builders +(pre-commit e hook CI) che richiedono output minimo. + +- Sopprime il pannello Sentinel ricco e il report verboso per file. +- Stampa una sintesi compatta a riga singola per errori/warning. +- Stampa una riga di sicurezza esplicita per violazioni Shield (Exit 2). +- Mantiene comunque l'enforcement degli exit code fatali, inclusa la priorità sicurezza (`3 > 2 > 1`). + +```bash +zenzic check all --quiet +``` + --- ## Inizializzazione @@ -130,6 +167,7 @@ zensical. L'errore `Address already in use` non può mai provenire dall'engine. | `0` | Tutti i controlli selezionati sono passati (o `--exit-zero` era impostato) | | `1` | Uno o più controlli hanno segnalato problemi | | **`2`** | **SECURITY CRITICAL — Zenzic Shield ha rilevato una credenziale esposta** | +| **`3`** | **INCIDENTE DI SICUREZZA — Blood Sentinel: il link punta a una directory di sistema dell'OS** | !!! danger "Il codice di uscita 2 è riservato agli eventi di sicurezza" Il codice 2 viene emesso esclusivamente da `zenzic check references` quando lo Shield @@ -137,6 +175,13 @@ zensical. L'errore `Address already in use` non può mai provenire dall'engine. usato per i fallimenti ordinari dei controlli. Se ricevi il codice di uscita 2, trattalo come un incidente di sicurezza bloccante e **ruota immediatamente la credenziale esposta**. +!!! danger "Codice di uscita 3 — Incidente di Sicurezza Blood Sentinel" + Il codice 3 viene emesso quando il Blood Sentinel rileva un link che risolve verso una + directory di sistema dell'OS (`/etc/`, `/root/`, `/var/`, `/proc/`, `/sys/`, `/usr/`). + A differenza del codice 1, questo è un incidente di sicurezza e ha priorità su tutti gli + altri codici di uscita. Non viene mai soppresso da `--exit-zero`. Consultare + [Controlli: Blood Sentinel](../checks.md#blood-sentinel-system-path-traversal) per i dettagli. + --- ## Output JSON diff --git a/docs/usage/advanced.md b/docs/usage/advanced.md index 40a442e..243e0eb 100644 --- a/docs/usage/advanced.md +++ b/docs/usage/advanced.md @@ -77,7 +77,7 @@ applies a defence-in-depth pass to non-definition lines to catch secrets in plai | `slack-token` | `xox[baprs]-[0-9a-zA-Z]{10,48}` | Slack bot/user/app tokens | | `google-api-key` | `AIza[0-9A-Za-z\-_]{35}` | Google Cloud / Maps API keys | | `private-key` | `-----BEGIN [A-Z ]+ PRIVATE KEY-----` | PEM private keys (RSA, EC, etc.) | -| `hex-encoded-payload` | `(?:\\x[0-9a-fA-F]{2}){3,}` | Hex-encoded byte sequences (3+ consecutive `\xNN` escapes) | +| `hex-encoded-payload` | `(?:\\x[0-9a-fA-F]{2}){3,}` | Detects obfuscation attempts that hide payloads or credentials via hex escapes. This technique is commonly used to evade naive string linters and is treated as a critical source-transparency violation. | ### Shield behaviour diff --git a/docs/usage/commands.md b/docs/usage/commands.md index 82d3ed6..e005573 100644 --- a/docs/usage/commands.md +++ b/docs/usage/commands.md @@ -27,10 +27,17 @@ zenzic check all # Run all checks zenzic check all --strict # Also validate external URLs; treat warnings as errors zenzic check all --format json # Machine-readable output zenzic check all --exit-zero # Report issues but always exit 0 +zenzic check all --quiet # Minimal one-line output for pre-commit and CI hooks zenzic check all --engine mkdocs # Override detected build engine adapter +zenzic check links --show-info # Show info-level findings (e.g. circular links) ``` -### `--strict` flag +## Global flags + +These flags control Zenzic's signal-to-noise profile across routine scans, CI gates, +and incident response workflows. + +### `--strict` | Command | Effect | | :--- | :--- | @@ -41,13 +48,43 @@ zenzic check all --engine mkdocs # Override detected build engine adapter You can also set `strict = true` in `zenzic.toml` to make it the permanent default. -### `--exit-zero` flag +### `--exit-zero` Always exits with code `0` even when issues are found. All findings are still printed and scored — only the exit code is suppressed. Useful for observation-only pipelines. +Security events are never downgraded by this flag: Exit 2 (Shield credential breach) and +Exit 3 (Blood Sentinel system-path incident) always keep priority over ordinary failures. + You can also set `exit_zero = true` in `zenzic.toml` to make it the permanent default. +### `--show-info` + +By default, info-level findings are hidden to keep everyday output focused on actionable +violations. Use `--show-info` when you want full Sentinel visibility into non-blocking +signals such as link-cycle topology (`CIRCULAR_LINK`). + +Available on all `zenzic check` commands. + +```bash +zenzic check links --show-info +zenzic check all --show-info +``` + +### `--quiet` + +`--quiet` is available on `zenzic check all` and is designed for silent builders +(pre-commit and CI hooks) that need minimal output. + +- Suppresses the rich Sentinel panel and per-file verbose report. +- Prints a compact one-line summary for error/warning totals. +- Prints an explicit security one-liner for Shield breaches (Exit 2). +- Still enforces fatal exit behavior, including security priority (`3 > 2 > 1`). + +```bash +zenzic check all --quiet +``` + --- ## Initialization @@ -128,6 +165,7 @@ subprocess, then passes `--dev-addr 127.0.0.1:{port}` to mkdocs or zensical. The | `0` | All selected checks passed (or `--exit-zero` was set) | | `1` | One or more checks reported issues | | **`2`** | **SECURITY CRITICAL — Zenzic Shield detected a leaked credential** | +| **`3`** | **SECURITY INCIDENT — Blood Sentinel: link targets an OS system directory** | !!! danger "Exit code 2 is reserved for security events" Exit code 2 is issued exclusively by `zenzic check references` when the Shield detects a @@ -135,6 +173,13 @@ subprocess, then passes `--dev-addr 127.0.0.1:{port}` to mkdocs or zensical. The failures. If you receive exit code 2, treat it as a build-blocking security incident and **rotate the exposed credential immediately**. +!!! danger "Exit code 3 — Blood Sentinel Incident" + Exit code 3 is issued when the Blood Sentinel detects a link that resolves to an OS + system directory (`/etc/`, `/root/`, `/var/`, `/proc/`, `/sys/`, `/usr/`). Unlike exit + code 1, this is a security incident and takes priority over all other exit codes. It is + never suppressed by `--exit-zero`. See + [Checks: Blood Sentinel](../checks.md#blood-sentinel-system-path-traversal) for details. + --- ## JSON output