Scrivere un Nuovo Check
I check di Zenzic si trovano in src/zenzic/core/. Ogni check è una funzione standalone in
scanner.py (traversal del filesystem) o validator.py (validazione del contenuto). Il wiring
CLI è nel package cli/ (src/zenzic/cli/).
Checklist in Sei Passi
- Implementa la logica nel modulo core appropriato (
zenzic.core.scannerozenzic.core.validator). - Delega la risoluzione a
InMemoryPathResolver— non chiamare maios.path.exists(),Path.is_file(), o qualsiasi altra probe del filesystem all'interno di un loop per-link. Il resolver viene istanziato una volta prima del loop; re-istanziarlo per file annulla la_lookup_mappre-calcolata e riduce il throughput da 430 000+ a meno di 30 000 risoluzioni/s. - Testa l'i18n — se il check riguarda path di file, testalo in tutte e tre le configurazioni i18n (nessuna, folder mode, suffix mode).
- Collega la CLI — aggiungi un comando o sotto-comando corrispondente nel package
cli/. Vedi il riferimento Architettura CLI. Se il tuo comando accetta un argomentoPATH, devi chiamarefind_repo_root(search_from=resolved_path)e invocare_apply_target()per rispettare la Sovranità del Percorso. - Scrivi i test in
tests/che coprano sia i casi passanti che quelli fallenti, inclusa una baseline di performance (5 000 link risolti in < 100 ms su un corpus in-memory mockato). - Aggiorna gli esempi in
examples/per esercitare il nuovo check — Zenzic valida i propri esempi ad ogni commit.
Contratto di performance: il hot path di
zenzic.coredeve rimanere allocation-free. Nessuna costruzione di oggettiPath, nessuna syscall e nessuna chiamatarelative_to()all'interno del loop di risoluzione.
Core Laws
Tutti i check devono rispettare le leggi fondamentali (Core Laws) dello scanner. Prima di scrivere un check, assicurati di familiarizzare con gli invarianti dettagliati nelle Leggi Fondamentali dello Scanner.
Cablaggio CLI
A seconda che tu stia aggiungendo un comando a una sub-app esistente o introducendo una nuova sub-app di primo livello, segui i passaggi seguenti:
Aggiungere un Comando a una Sub-App Esistente
Nel modulo della sub-app appropriata (ad es., src/zenzic/cli/_check.py):
@check_app.command(name="metadata")
def check_metadata(path: Path = ...) -> None:
...
Non sono necessarie modifiche a __init__.py, main.py o _metadata.py.
Aggiungere una Nuova Sub-App di Primo Livello
- Crea un nuovo modulo
src/zenzic/cli/_myfeature.pyche definisce la sub-app:myfeature_app = typer.Typer(...). - Esporta
myfeature_appdasrc/zenzic/cli/__init__.py. - Registra la sub-app in
src/zenzic/main.py:app.add_typer(myfeature_app, name="myfeature", rich_help_panel="..."). - Aggiungi una voce
CommandMeta(...)insrc/zenzic/cli/_metadata.pyaffinché i pannelli di aiuto della radice e l'aiuto breve rimangano autorevoli. - Se la sub-app usa
no_args_is_help=True, aggiungi"myfeature"al frozenset_SUBAPPS_WITH_MENUincli_main()in modo che il banner di Zenzic appaia quando la sub-app viene invocata senza argomenti.
Obbligazioni del Credential Scanner
Se il tuo check tocca il credential scanner o harvest(), vedi il riferimento dedicato
Obbligazioni del Credential Scanner.
Le quattro obbligazioni (Worker Timeout, Regex-Canary, Dual-Stream Invariant, Mutation Score ≥ 90%)
sono applicate ad ogni PR che tocca src/zenzic/core/.
Codici di Finding
Ogni nuovo check deve emettere finding usando un codice registrato in FROZEN_CODES. Prima
di aggiungere un nuovo codice:
- Esegui
zenzic inspect codes— conferma che il codice non esista già. - Aggiungi il codice a
FROZEN_CODESnel tier appropriato (Core,Structure, oGovernance). - Aggiorna
CHANGELOG.mdcon il nuovo codice nello stesso commit.
Non riutilizzare codici ritirati. I codici ritirati rimangono in FROZEN_CODES con stato retired.