La pipeline di validazione
La pipeline è la prima cosa da costruire e il pezzo che accumula valore nel tempo.
Nasce come CLI, non come servizio: usabile localmente, invocata da CI come subprocess,
e successivamente avvolta dal validation-service.
Ordine di esecuzione
1. Snapshot del tree → hash del contenuto H
2. Check deterministici → eseguiti su H
3. Check LLM → advisory, eseguiti su H
4. Build → da H
5. Commit → oggetto creato da H
6. Registrazione → utente, task, H, esiti, commit SHA
Check prima, build dopo, commit per ultimo — il commit è il passo più difficile da annullare. Se la build fallisce, Git non viene mai toccato.
Perché lo snapshot è importante
Se i check leggono la working directory live e il commit la rilegge, il tree può cambiare nel mezzo. Congelare su un hash del contenuto è ciò che rende "questo esatto contenuto ha superato questi check ed è diventato questo commit" un'affermazione verificabile invece che una speranza.
Check deterministici (bloccanti)
Economici, riproducibili, oggettivi — e visibili al collaboratore prima che inizino, il che conta quando non hanno contesto più ampio.
| Check | Strumento |
|---|---|
| Struttura: lunghezza file e funzioni, conteggio parametri, profondità nesting, export per modulo | — |
| Complessità: soglie di complessità ciclomatica e cognitiva | — |
| Duplicazione: rilevamento copy-paste con tetto percentuale | — |
| Architettura come codice: no circular import, no cross-service import, boundary layer applicati | dependency-cruiser, eslint-plugin-boundaries |
| Test: copertura line e branch; mutation testing per verificare che i test effettivamente asseriscano | Stryker |
| Sicurezza: segreti hardcoded, vulnerabilità nelle dipendenze, pattern pericolosi, taint analysis; regole custom | Semgrep |
Tipi: strict mode, no implicit any, no @ts-ignore non giustificato | — |
| Conformance contrattuale: implementazione validata rispetto all'OpenAPI o JSON Schema specificato dalla challenge | — |
La conformance contrattuale è il check più potente disponibile in questo modello.
Check LLM (advisory, mai bloccanti)
Riservati ai giudizi che richiedono intento, che nessuno strumento può fare:
- Il codice fa ciò che la challenge specificava?
- Qualità semantica dei nomi
- Appropriatezza dell'astrazione scelta
- Commenti che contraddicono il codice
- Edge case non gestiti
- Se i test asseriscono qualcosa di significativo
- Coerenza con le convenzioni interne non scritte
Regole:
- Un check per prompt. Sette domande in un prompt danno sette risposte mediocri.
- Output JSON strutturato, stesso schema dei finding deterministici, con severità e confidence.
- Ogni finding cita file e riga. I finding non ancorati sono solitamente fabbricati.
- Il risultato vuoto deve essere esplicitamente permesso e inquadrato come normale.
- Passa la specifica della challenge, non solo il diff — senza di essa il check più prezioso è impossibile.
- Traccia i falsi positivi per tipo di check. Quei dati decidono quali check possono mai diventare bloccanti.
L'uso migliore è prima della submission, non solo durante: esegui gli stessi prompt nell'assistente del collaboratore mentre lavora. I finding arrivano quando possono ancora essere corretti gratuitamente, e la coda del revisore si riduce.
Contratto del risultato
Lo schema di output è la decisione di design con la leva più alta nella pipeline. UI, audit trail, statistiche dei contributori e ripetibilità si basano tutti su di esso.
Per finding: check id, severità, flag bloccante, file, riga, messaggio, confidence (solo LLM), sorgente (deterministica | llm).
Per run: hash del contenuto, versione del profilo, timestamp, esiti per step, verdetto complessivo.
Versionarlo dalla prima release.
Profilo di validazione
Un file dichiarativo nel repository, versionato, che indica quali check si applicano a quale microservizio, con quali soglie e quali sono bloccanti. I requisiti diventano trasparenti per il collaboratore e modificabili senza toccare il codice della pipeline.