ADR 009: Sovranità del Percorso — La Configurazione Segue il Target
Stato: Attivo Decisore: Architecture Lead Data: 2026-04-12 (CEO-052)
Contesto
find_repo_root() cerca verso l'alto a partire da os.getcwd()
— la directory di lavoro corrente della shell invocante. Funzionava correttamente
per il caso standard in cui l'utente esegue Zenzic dall'interno del repository
che vuole analizzare.
Falliva in qualsiasi scenario in cui la directory di lavoro del chiamante differiva dal repository target:
# CWD = /home/user/my-tools
# Target = /home/user/another-project/docs
zenzic check all /home/user/another-project/docs
In questo caso, find_repo_root() avrebbe navigato verso l'alto da
/home/user/my-tools, trovato il .zenzic.toml di quel repository, e caricato
la configurazione di quel repository — inclusi il suo engine, docs_dir,
excluded_dirs e le regole personalizzate. Il target di analisi era
another-project, ma la configurazione applicata era quella di my-tools.
Questo è un Context Hijacking.
Decisione
"La configurazione segue il target, non il chiamante."
Quando viene fornito un argomento PATH esplicito a qualsiasi comando CLI che
interagisce con il filesystem, find_repo_root() viene chiamato con
search_from=target_path — navigando verso l'alto dal target, non dalla CWD:
# core/scanner.py
def find_repo_root(
search_from: Path | None = None,
fallback_to_cwd: bool = False,
) -> Path:
start = search_from or Path.cwd()
for parent in [start, *start.parents]:
if (parent / ".git").exists() or (parent / ".zenzic.toml").exists():
return parent
if fallback_to_cwd:
return start
raise RuntimeError(...)
_apply_target() in cli/_target_resolver.py orchestra la ricalibrazione del
docs-root dopo la risoluzione del target: preserva docs_dir configurato
quando il target è la radice del repo, oppure aggiorna docs_dir dal target
risolto.
L'Invariante _apply_target()
Quando target == repo_root (l'utente punta direttamente alla radice del repo,
non a una sottodirectory), docs_dir viene preservato dalla config invece di
essere sovrascritto con ".". Questo previene una regressione sottile: un utente
che esegue zenzic check all /path/to/repo deve rispettare l'impostazione
docs_dir = "docs" di quel repo, non appiattirla alla radice.
# _apply_target() — logica canonica
if resolved_target == repo_root:
# Il target È la radice del repo: rispetta il docs_dir della config.
docs_root = repo_root / config.docs_dir
else:
# Il target è una sottodirectory: trattala direttamente come docs root.
docs_root = resolved_target
Motivazione
1. Il Principio dell'Integrità Contestuale
Un file di configurazione appartiene al progetto in cui risiede. Caricare un
.zenzic.toml straniero per una coincidenza di directory di lavoro è una
vulnerabilità della supply chain di configurazione — l'analisi è segretamente
governata da regole che l'utente non intendeva applicare.
2. Correttezza CI/CD
Nelle pipeline CI, la directory di lavoro è spesso la home del runner, una
workspace root, o una directory di strumenti — non il repository di
documentazione. La Sovranità del Percorso assicura che zenzic check all $DOCS_PATH
in CI applichi sempre le regole specifiche del progetto corretto,
indipendentemente da $PWD del runner.
3. Simmetria con ADR-007
ADR-007 (Sandbox Sovrano) ha stabilito che il perimetro segue il target. ADR-009 completa il quadro: anche la configurazione segue il target. Insieme garantiscono che ogni aspetto di un'analisi — cosa viene scansionato, quali regole si applicano e quali fughe sono vietate — sia determinato esclusivamente dal repository target.
Ambito
La Sovranità del Percorso si applica a ogni comando CLI che accetta un argomento
posizionale PATH opzionale (Regola R18 — Simmetria CLI Totale):
| Comando | Semantica PATH |
|---|---|
zenzic check all [PATH] | Radice sovrana: find_repo_root(search_from=PATH) |
zenzic score [PATH] | Identica |
zenzic diff [PATH] | Identica; percorso snapshot derivato dalla repo_root risolta |
zenzic init [PATH] | Genesis Nomad: PATH è la repo_root direttamente; creata se assente |
zenzic lab, zenzic inspect | Nessun argomento PATH — esenti |
Conseguenze
-
Eseguire Zenzic da qualsiasi directory produce risultati identici a eseguirlo dall'interno del repository target — nessuna sorpresa per gli operatori CI.
-
Il parametro
fallback_to_cwd=Truedifind_repo_root()è un percorso difallback vincolato. Usalo solo dove la semantica del comando richiede esplicitamente un fallback alla directory corrente, evitando di introdurlo come default nei flussi di comando PATH-targeted.