# 12 — Audit corrections (follow-up 2026-07-19/20)

Revisione dei soli deliverable dell'audit, senza riesecuzione dell'audit generale e senza modifiche a codice applicativo. Unica azione runtime: esecuzione di `node scripts/build-routing-catalog.mjs` su `master` (rigenera `scripts/hooks/routing-catalog.json`, file **gitignored/generato** — non è una modifica a file versionati; contenuto risultato identico al precedente al netto di `generatedAt`, backup conservato in scratchpad).

## 1. Verifica runtime SKAUD-001 (metodo e attribuzione)

Metodo: (a) lettura diretta dei frontmatter delle 6 skill indicate; (b) esecuzione reale del generatore del catalogo su master; (c) ispezione delle entry generate (`triggers.keywords`, `description`, `promptPatterns`).

Esito per attribuzione:

| Ipotesi | Verdetto | Evidenza |
| --- | --- | --- |
| Frontmatter malformati | **NO** — tutti block scalar YAML validi (`>` / `>-`) | es. `skills/mcp-technical-analyst/SKILL.md:3-9`, `skills/svg/SKILL.md:3-9` |
| Parser del catalogo | **NO** — description parsate integralmente; keywords estratte: technical-analyst 30 (+1 promptPattern), frontend-perf 49, grid-ui 40, skill-miner 59, svg 42 | catalogo rigenerato 2026-07-19 |
| Estrattore del subagente A | **SÌ** — l'estrattore naive ha letto la prima riga dopo `description: >` (o testo adiacente) invece del blocco scalare, producendo description come "\| Task \| Reference \|", "Usa questa skill quando serve:" ecc. | `skill-inventory.raw.json`, campi description |

**Il finding "6 description frontmatter malformate" è un FALSO POSITIVO** ed è stato ritirato da: `01-executive-summary.md` (Cluster 1, priorità, PR), `02-skill-inventory.csv` (6 righe), `05-routing-and-overlap-analysis.md` (sezione "Skill mai selezionabili"), backlog (SKAUD-001 sostituito). `11-evidence-index.csv`: aggiunta F-046.

**Finding reale emerso dalla stessa verifica (nuovo, FACT)**: `mcp-runtime-integrator` è assente dal catalogo routing — `build-routing-catalog.mjs:29` scandisce solo `<repo>/skills`, mai `.agents/skills/` (catalogo = 20 skill su 21). Evidenza F-047. Il nuovo SKAUD-001 traccia la decisione inclusione-vs-esclusione-documentata.

**Verifica collaterale risolta**: il confronto tra catalogo pre-esistente (generatedAt 2026-07-16) e rigenerato è **identico** al netto di `generatedAt` → l'incertezza di freshness del subagente B (F-043) è chiusa: nessun drift. F-043 aggiornata a "RISOLTO"; `03-instruction-supply-chain.md` corretto (rischio da Media a Bassa).

## 2. Riconciliazione outcome eval (matrice vs SKAUD-013)

Le due affermazioni non erano contraddittorie ma usavano "outcome" con due significati. Distinzione ora esplicitata in `07-eval-gap-analysis.md` (nuova sezione) e F-048:

- **Outcome dichiarato (documentale)**: `expected_output`/`expectations` in fixture JSON mai eseguiti da alcun harness — 15 file eval. È ciò che la matrice per-skill chiama "outcome".
- **Outcome eseguito e verificato**: runner che esegue il prompt contro un modello e giudica il risultato — **0 in tutto il repo**.

SKAUD-013 riformulato di conseguenza: prima **eval schema v2** (retro-compatibile, `success_criteria[]` machine-checkable) + **runner eseguibile** (`scripts/run-skill-evals.mjs`); l'aggiunta/migrazione dei casi è scorporata nel nuovo **SKAUD-025** (dipendente da 013).

## 3. SKAUD-014 → specifica implementativa

Aggiunta a `08-ablation-test-plan.md` la sezione "Specifica implementativa" con: struttura directory (`fixtures/ablation/` + `ablation-results/`), schema fixture `task.json`, schema run-result JSONL, rubriche (check deterministici vs LLM-judge, judge unico a temperatura 0), acquisizione metriche (tool call/handoff dal transcript o da `hooks/events.jsonl`; token dai campi usage; modello id/versione/config registrati per-run), 3 ripetizioni con criterio di stabilità modale ≥2/3, criterio di confronto **gerarchico** (safety → success → routing → efficienza, mai media unica; varianti poi ristrutturate in A/B/C/D/E1/E2 nella revisione finale), e separazione esplicita **routing failure vs execution failure** (con valutazione dell'esecuzione anche su run con routing sbagliato, per misurare la compensazione dei modelli capaci). SKAUD-014 ora punta alla specifica.

## 4. Riclassificazione requisiti del branch candidato

Correzione: la telemetria ambiguity era stata elencata tra i guardrail "pre-merge o immediatamente dopo" — errato, dato che gate (`enabled:false`) e resolver (mai importato) restano spenti: il merge non attiva nulla. Nuova classificazione (tabella completa in `06-*.md`):

| Fase | Requisiti |
| --- | --- |
| Pre-merge (davvero) | SKAUD-019 (decisione test-affected), SKAUD-004 (dichiarazione scaffolding) |
| Post-merge, pre-shadow | SKAUD-003 (telemetria ambiguity/candidateScores), SKAUD-020 (version manifest) |
| Pre-evaluator | minimizzazione/redazione prompt, transport con timeout/cache/circuit breaker, test integrazione su failure reali (fuori backlog audit) |
| Pre-boost | dati shadow per tarare soglie, ABL-09/10 verdi, wiring resolver + telemetria decisioni |

Verdetto branch invariato (**READY_WITH_GUARDRAILS**) ma con guardrail pre-merge ridotti ai soli due a costo XS.

## 5. Normalizzazione backlog

`change_type` ora sempre nell'enum del mandato. Rimappature principali: SKAUD-002/015/016/021 → `MAKE_CONDITIONAL`; SKAUD-003/007/023 e nuovo SKAUD-001 → `REFACTOR_ROUTING`; SKAUD-004/010/011/020 → `VERSION`; SKAUD-005/006/012/013/014/025 → `ADD_EVAL`; SKAUD-009/022/024 → `MOVE_TO_REFERENCE`; SKAUD-017/018/026 → `MOVE_TO_TOOL_SCHEMA`; SKAUD-019 → `REMOVE_CANDIDATE`; SKAUD-008 → `DEPRECATE` (invariato).

Task scorporati (una PR = un task coeso):
- **SKAUD-018** ridotto alla sola fase 1 (annotations cf_bridge, XS, nessun cambio comportamentale); fase 2 → nuovo **SKAUD-026** (guard server-side, decisione aperta, richiede analisi CF-side).
- **SKAUD-013** ridotto a schema v2 + runner; migrazione casi → nuovo **SKAUD-025**.
- Le PR aggregate della vecchia tabella (PR2 = 003+004+020; PR5 = 002+021+016+024) sono state sciolte in PR mono-task.

## Riepilogo formale

**Finding confermati (invariati)**: tutte le evidenze F-001…F-045 tranne quelle sotto; in particolare: 4-5 fonti di routing divergenti, matrice orchestrator incompleta (8 skill), database-expert senza anti-trigger, 21 compensazioni skill→tool, zero eval eseguiti, branch senza chiamate LLM con default fail-closed, telemetria ambiguity non cablata.

**Finding corretti**:
- F-043 (freshness catalogo): da rischio Medio a RISOLTO/Basso (nessun drift, verificato).
- Cluster 3 / SKAUD-013: riformulato da "mancano outcome eval" a "manca l'infrastruttura di esecuzione" (outcome dichiarato ≠ eseguito).
- Requisiti branch: telemetria spostata da pre-merge a post-merge/pre-shadow.

**Falsi positivi (ritirati)**:
- "6 skill con description frontmatter malformate" (SKAUD-001 originale) — artefatto dell'estrattore del subagente A; smentito da verifica runtime.

**Task rinumerati o sostituiti**:
- SKAUD-001: **sostituito** (stesso ID, nuovo contenuto: inclusione/esclusione documentata di mcp-runtime-integrator dal catalogo).
- SKAUD-025: **nuovo** (scorporo da SKAUD-013 — migrazione casi outcome a v2).
- SKAUD-026: **nuovo** (scorporo da SKAUD-018 — guard server-side cf_bridge).
- Nessun altro ID rinumerato; contenuti aggiornati in place.

## Revisione finale tecnica (follow-up 2, 2026-07-20)

Verifiche dirette eseguite su: `cf-node/index.js`, `cf-node/mcp_tool/mcp_agent.cfm`, `cf-node/.env.example`, `skills/mcp-coldfusion-developer/SKILL.md`, `.agents/skills/mcp-runtime-integrator/SKILL.md`, `docs/mcp-skills-agents-development-guide.md`, `scripts/build-routing-catalog.mjs`. Solo letture; nessun file di codice modificato.

### Finding corretti

1. **Protezione `cf_bridge.evaluate`** (FACT): esiste già una denylist deterministica server-side (`mcp_agent.cfm:134-139`: cfhttp, cfquery, cfexecute, cfregistry, cffile, cfdirectory, cfmail, `createObject(`, `invoke(` via FindNoCase). Non è però una sandbox completa: pattern-matching testuale, funzioni script equivalenti non elencate (es. `queryExecute(`, `fileWrite(`), possibili bypass per composizione dinamica e side effect indiretti via `Evaluate`. Il guardrail testuale della skill è **difesa in profondità, non unica barriera**. Corretti: 01, 04 (riga 2, enforcement server-side parziale rappresentato nei campi descrittivi senza estendere gli enum), 09 (punto 2), 11 (F-022/F-023 + F-049). Ritirata ovunque la formulazione "privo di qualsiasi restrizione".
2. **Annotation per-action impossibili** (FACT): `cf_bridge` è un singolo tool MCP con parametro `action`; le annotation MCP descrivono il tool complessivo. La vecchia proposta di SKAUD-018 (destructiveHint su evaluate + readOnlyHint su logs_*) non era implementabile: riformulata come description per-azione + annotation conservative sul tool intero, senza promesse di enforcement.
3. **Esclusione `mcp-runtime-integrator` dal catalogo** (FACT + INFERENCE): la guida viva:68 dichiara la skill "repository-only … non distribuibile nei runtime utente" → l'assenza dal catalogo runtime è coerente con un **confine distributivo intenzionale** (`skills/` distribuibili vs `.agents/skills/` repository-only), non un bug. Il "20 su 21" non va letto come drift silenzioso. Corretti: 01, 05, 11 (F-051).
4. **Varianti ablation B e D non isolate**: nella versione precedente B includeva il routing attivo (≡D), impedendo di separare l'effetto skill dall'effetto router. Matrice sostituita con A/B/C/D/E1/E2 (B/C senza hook; D con router master; confronti canonici B-A, C-B, D-B, E1-D, E2-D) in 08 e SKAUD-014.
5. **Shadow mode non valutabile sull'outcome**: E1 (gate shadow) per definizione non cambia la decisione finale — misurata solo su metriche di gate (attivazione, precisione, FP/FN, stabilità, costo), mai confrontata con D sull'esito. E2 con evaluation sintetiche misura policy resolver/bounds/lock, non valida il modello router.

### Nuovo finding

- **Token ColdFusion di fallback condiviso e hardcoded** (FACT, F-050): stesso valore `Secret_CF_MCP_2026` in `cf-node/index.js:13` (DEFAULT_TOKEN, usato se `.env` assente), `mcp_agent.cfm:6` (EXPECTED_TOKEN) e `.env.example`. Rischio contenuto su localhost, reale se `CF_BRIDGE_URL` espone il bridge su rete/VM condivise. → Nuovo task **SKAUD-027** (P2, VERSION, migrazione incrementale verso fail-closed con finestra legacy).

### Decisioni aggiornate

- **SKAUD-001** → declassato a **P3** e trasformato in "Documentare e testare l'esclusione delle skill repository-only dal catalogo runtime" (change_type VERSION; non aggiungere `.agents/skills/` al catalogo distribuito).
- **SKAUD-018** → limitato a description e annotation conservative del **tool intero** (nessuna annotation per-action, nessun cambio comportamentale, denylist mantenuta, verifica compatibilità SDK preventiva).
- **SKAUD-026** → esteso a: security review della denylist esistente (bypass, equivalenti script, allowlist vs denylist) + valutazione — non prescrizione — della separazione in `cf_evaluate`/`cf_logs_list`/`cf_logs_read` con `cf_bridge` come alias legacy, previa analisi compatibilità client.
- **SKAUD-027** → aggiunto (v. sopra).
- **SKAUD-014** → aggiornato alle varianti A/B/C/D/E1/E2 con judge blind e variante C generata da trasformazione versionata riproducibile.
- Blind judging aggiunto anche al runner di SKAUD-013 (07 aggiornato).

### Controlli di consistenza backlog (eseguiti)

27 task, ID unici; `change_type` tutti nell'enum del mandato (validato via script); dipendenze puntano a task esistenti (006→005, 013→006, 014→013, 025→013, 026→018, 003/020/023→merge branch); nessun P1 dipende da un P3; SKAUD-001 = P3; SKAUD-027 presente; SKAUD-003 resta post-merge/pre-shadow; SKAUD-019 e SKAUD-004 restano gli unici requisiti pre-merge; JSON sintatticamente valido.

**Nuova sequenza PR consigliata**:

1. SKAUD-019 (base: hooks-routing-llm) — decisione test-affected. ECONOMIC / review FABLE.
2. SKAUD-004 (base: hooks-routing-llm) — dichiarazione scaffolding. ECONOMIC / review INTERMEDIATE. → **merge del branch**.
3. SKAUD-005 (master) — schema eval mantis-test-writer. ECONOMIC / INTERMEDIATE.
4. SKAUD-006 (master) — wiring check evals in npm test. ECONOMIC / INTERMEDIATE.
5. SKAUD-002 (master) — anti-trigger database-expert. ECONOMIC / INTERMEDIATE.
6. (post-merge) SKAUD-003 — telemetria ambiguity (pre-shadow). INTERMEDIATE / INTERMEDIATE.
7. SKAUD-013 — schema v2 + runner. INTERMEDIATE / FABLE.
8. SKAUD-027 — migrazione token fallback bridge CF (P2). INTERMEDIATE / FABLE.

(SKAUD-001, ora P3 documentale, esce dalla sequenza immediata.)

## Chiusura editoriale finale (follow-up 3, 2026-07-20)

Correzioni di sola consistenza editoriale; **nessun nuovo finding tecnico, nessuna modifica al codice applicativo** (sole letture di verifica).

- **Esempio run variante B corretto** in 08: `hook_active:false`, `catalog_fingerprint:null`, `hints_emitted:[]`; chiarito che per A/B/C `skill_selected_by_model` è la strategia scelta autonomamente dal modello, non una decisione del routing hook.
- **Blind judging reso vincolante in SKAUD-013**: requisito nel proposed_change (payload anonimo; niente modello/variante/skill/routing/costi prima del giudizio; ricongiunzione metadata solo post-giudizio; applicabile anche all'harness ablation che riusa judge e rubriche), 4 acceptance criteria dedicati e test unitario del payload blind.
- **Riferimenti A/B/C/D/E aggiornati ad A/B/C/D/E1/E2** in 07 (ablation eval), 08 (commento harness, metriche per D/E1/E2, ABL-09 con criteri distinti E1/E2), SKAUD-014 (problem) e in questa cronologia (annotazione storica qualificata).
- **Rischio telemetria riclassificato definitivamente come pre-shadow** in 01 §Rischi per il merge: il merge dello scaffolding non richiede la telemetria (gate disabilitato, resolver non cablato); resta rischio pre-merge solo il cambio fuori tema a `test-affected.mjs`.
- **Raccomandazione pre-merge ridotta a SKAUD-019 + SKAUD-004** in 01 (rimosso il riferimento residuo a "4 guardrail").
- **Distinzione routing / gate / execution failure** formalizzata in 08: routing failure applicabile a D ed E2; per E1 si registra separatamente il gate failure (`gate` / `gate_and_execution`), mai confuso con routing o execution failure; per A/B/C nessun routing failure; `failure.type` esteso descrittivamente a `none|routing|gate|execution|routing_and_execution|gate_and_execution`. Aggiunta tabella dei campi routing applicabili per variante.
- Indice evidenze: aggiunta la sola riga di consistenza F-052 (nessun finding tecnico nuovo).

**Stato finale: `AUDIT_READY_FOR_IMPLEMENTATION`.**
