Leggi Fondamentali dello Scanner
Queste regole proteggono le garanzie di prestazioni e determinismo di src/zenzic/core/. Qualsiasi modifica al core di analisi deve rispettare questi invarianti.
Zero I/O nel Hot Path
src/zenzic/core/ non deve mai chiamare Path.exists(), Path.is_file(), open(), o qualsiasi altra operazione su filesystem o sottoprocesso all'interno di un ciclo per-link o per-file.
Le due fasi di I/O consentite sono:
| Fase | Dove | Cosa |
|---|---|---|
| Passo 1 | preambolo di validate_links_async | traversal rglob per costruire md_contents e known_assets |
Costruzione di InMemoryPathResolver | __init__ | Costruzione di _lookup_map dal dizionario dei contenuti pre-letti |
Tutto ciò che segue il Passo 1 deve utilizzare solo strutture dati in memoria:
- Risoluzione
.mdinterna →InMemoryPathResolver.resolve() - Risoluzione degli asset non
.md→asset_str in known_assets(frozenset[str], O(1))
Determinismo i18n
src/zenzic/core/ deve produrre risultati identici e codici di uscita identici in tutte e tre le configurazioni i18n:
| Configurazione | Struttura radice |
|---|---|
| Nessuna i18n | solo docs/*.md |
| Modalità cartella (Folder) | docs/ + i18n/<locale>/docusaurus-plugin-content-docs/current/ |
| Suffix mode | docs/*.md + docs/*.it.md |
Qualsiasi controllo che produca risultati diversi a seconda della configurazione del locale presenta un bug. Il rilevamento del locale avviene a livello di adapter; il core deve essere indipendente dal locale.
Consapevolezza delle Ghost Route
Qualsiasi controllo che validi collegamenti o percorsi deve interrogare la VSM, non il filesystem:
# ❌ Violazione di Grado-1 — interroga il filesystem, perde le Ghost Route
if not (docs_root / resolved_path).exists():
yield Finding(...)
# ✅ Corretto — interroga la VSM
if route_info.status == RouteStatus.ORPHAN_AND_ABSENT:
yield Finding(...)
Le Ghost Route sono pagine generate da Docusaurus durante la compilazione (elenchi di tag, indici paginati, pagine degli autori) che non hanno un file sorgente Markdown fisico sul disco. Un controllo sul filesystem le segnalerà sempre come interrotte.
Sovranità della VSM
Durante la creazione o l'interrogazione del modello di navigazione:
- Utilizzare solo la superficie dell'adapter:
get_nav_paths()/get_route_info(). - Non analizzare mai
mkdocs.yml,docusaurus.config.tso qualsiasi altro file di configurazione del motore direttamente all'interno di un controllo. Questa responsabilità appartiene esclusivamente all'adapter. - Non chiamare mai
subprocessper eseguire il motore di compilazione. Zenzic legge la configurazione come dati, non come codice eseguibile.
Contratto dell'Adapter
Quando un controllo necessita dei dati dell'adapter, deve interrogare l'istanza dell'adapter:
# ✅ Corretto — usa l'adapter
route_info = adapter.get_route_info(rel_path)
# ❌ Errato — non analizzare mai mkdocs.yml per dati di locale all'interno di un controllo
with open("mkdocs.yml") as f:
config = yaml.safe_load(f)
locale = config.get("plugins", {}).get("i18n", {}).get("default_locale", "en")