# 05 — Routing e overlap analysis

Fonti: `instruction-conflicts.raw.json` (E), `instruction-supply-chain.raw.json` (B), `skill-inventory.raw.json` (A), sintesi main agent. Branch: `master`; impatti del branch candidato marcati.

## Mappa dei trigger (sintesi)

I trigger vivono in 3 forme: (1) `description` nel frontmatter di ogni SKILL.md (fonte del catalogo generato); (2) keywords/promptPatterns estratti dal catalogo + tabelle hand-curated `DOMAIN_KEYWORDS`/`SKILL_HINTS` nel hook; (3) prosa di routing in AGENTS.md §2 e GLOBAL.md "Minimal skill map". FACT: le tre forme sono manutenute indipendentemente e la terza è drift-ata rispetto all'inventario (GLOBAL.md:43-55 = 11 voci vs 21 skill reali).

Anti-trigger: presenti come sezioni esplicite solo in ~metà delle skill (orchestrator:87, technical-analyst:70, skill-miner:13, analytics-operator:8, runtime-integrator:9, frontend-perf:4, mantis-writers). Assenti del tutto in `mcp-database-expert` (FACT: file intero 1-36 senza rimandi).

## Overlap tra skill

| Overlap | Disambiguato? | Valutazione Fable |
| --- | --- | --- |
| technical-analyst ↔ master-orchestrator (analisi da ticket+commit+allegati) | SÌ — gate pass/fail su entrambe (analyst:61-71, orchestrator:43-56) | Boundary adeguato oggi, ma è il punto a maggior costo di falso positivo: l'orchestrator nel frontmatter include "technical analysis that starts from tickets..." (orchestrator:3) che *intercetta* il caso primario dell'analyst. Con un modello frontier capace di fare l'analisi direttamente, il routing verso orchestrator è una decomposizione potenzialmente superflua → candidato n.1 per ablation ABL-01/03/13 |
| grid-ui-debugger ↔ frontend-perf-debugger ↔ browser-automation | SÌ — cross-reference reciproche e simmetriche | Miglior esempio di overlap gestito nel repo; da preservare come pattern |
| mantis-test-writer ↔ mantis-ticket-writer | SÌ — anti-trigger reciproci simmetrici | Sano |
| code-reviewer ↔ technical-analyst | SÌ — confine bidirezionale | Sano |
| docs-navigator ↔ memory-operator ("salva questa conoscenza") | **NO** — criterio "docs ufficiali vs memoria operativa" solo qualitativo | Ambiguo per qualunque modello; serve un criterio pass/fail (es. "riusabile cross-progetto e validato → docs; contestuale/session-scoped → memory") |
| database-expert ↔ analyst/orchestrator (indagine dati mista) | **NO** — nessun anti-trigger in database-expert | Gap reale; fix XS (aggiungere sezione routing sul modello delle sorelle) |
| skill-miner ↔ analytics-operator; analytics-operator ↔ runtime-integrator | **Parziale** — puntamenti mono-direzionali | Rischio basso ma il sintomo condiviso "sorgente assente" ha rimedi opposti (config vs bug fix): rimando reciproco mancante |

## Conflitti analyst / orchestrator / specialist

- **Matrice decisionale dell'orchestrator incompleta** (FACT): `mcp-master-orchestrator/SKILL.md:12-30` omette 8 skill esistenti (code-reviewer, i 2 mantis writer, handoff-pack, analytics-operator, skill-miner, grid-ui-debugger, frontend-perf-debugger) mentre diverse di queste dichiarano escalation *verso* l'orchestrator → puntatori one-way. Il router dichiarato per i task multi-fase non conosce un terzo del proprio parco skill.
- **Tripla lista di routing divergente** (FACT): AGENTS.md §2 (essenziale), GLOBAL.md Minimal skill map (11 voci, stale), matrice orchestrator (parziale). Più il catalogo generato e le tabelle nel hook = 5 superfici totali.
- **Unica regola incompatibile trovata** (FACT): docs-node lookup per CFML "must attempt if available" in `mcp-code-reviewer:117` vs "verifica opzionale, non prerequisito" in `mcp-coldfusion-developer:67`, senza dichiarazione che la differenza dipende dalla fase (review vs dev).

## Primary vs sidecar

I sidecar (handoff-pack, memory-operator) hanno confini chiari e piccole dimensioni; il rischio è l'attivazione impropria del *primary* al loro posto (es. orchestrator che "chiude con handoff" invece di instradare a handoff-pack). Nessun conflitto testuale rilevato (FACT); rischio operativo basso.

## Routing deterministico (master): valutazione

Punti di forza (FACT, da B): fallback a catalogo vuoto (fail-open deterministico senza crash), negazioni gestite (`negation-aware phrase matching` testato in routing-hooks.test.mjs), intents con priorità esplicite (300/200/100), soglia score ≥3, cap a 2 hint (contiene il rumore in contesto).

Debolezze:
1. **Dipendenza da keyword** (INFERENCE): lo scoring è interamente lessicale (+3/+1/+5/+4); i prompt parafrasati o colloquiali senza keyword (caso ABL-09) non attivano nulla o attivano la skill sbagliata. È il problema che il branch candidato prepara a risolvere.
2. **Prompt composti**: esistono `composites` nel catalogo (FACT) ma la copertura reale dei casi composti è testata solo su fixture sintetiche; l'hint cap a 2 può troncare una metà del task.
3. **Doppia curatela** DOMAIN_KEYWORDS/SKILL_HINTS vs catalogo (v. 03): il vero rischio di regressione del routing non è il codice ma la manutenzione divergente dei dati.
4. **Hint ≠ enforcement**: il hook *suggerisce*; il modello può ignorare. Coerente con capacità crescenti dei modelli (giusto), ma rende la telemetria "skill suggerita vs skill effettivamente usata" indispensabile — oggi si logga solo il suggerimento (FACT).

## Routing candidato (branch): delta

Il branch NON cambia il routing di produzione (equivalenza testata). Aggiunge: metadata semantici (categoria/capabilities/notFor/routingRole) che rendono *possibile* un ranking non solo lessicale; candidate evidence per l'osservabilità; ambiguity gate spento. Rischi di regressione al momento dell'attivazione futura: (a) soglie del gate non tarabili senza telemetria (oggi assente); (b) oscillazione tra skill se il boost semantico entra in competizione con i lock deterministici — mitigato dal divieto di displacement nel resolver (FACT); (c) costo del router vs costo del task, da misurare (HYPOTHESIS).

## Skill mai selezionabili / che intercettano troppo

- **[CORRETTO 2026-07-19, verifica runtime — v. `12-audit-corrections.md`]** Il finding originario "6 skill con description frontmatter malformate" era un **falso positivo** prodotto dall'estrattore naive del subagente A. Verifica eseguita: frontmatter letti direttamente (block scalar YAML `>`/`>-` validi) + esecuzione reale di `scripts/build-routing-catalog.mjs` su master + ispezione del catalogo generato: tutte le description sono parsate integralmente e producono keywords sane (technical-analyst 30 kw + 1 promptPattern, frontend-perf 49 kw, grid-ui 40 kw, skill-miner 59 kw, svg 42 kw).
- **Finding emerso dalla verifica, riqualificato 2026-07-20 (FACT + INFERENCE)**: `mcp-runtime-integrator` è l'unica skill assente dal catalogo routing — `build-routing-catalog.mjs:29` scandisce solo `<repo>/skills` (catalogo = 20 skill su 21). Non è però un bug: la guida viva la dichiara "skill repository-only … non distribuibile nei runtime utente" (`docs/mcp-skills-agents-development-guide.md:68`), quindi l'esclusione riflette un **confine distributivo intenzionale** (`skills/` = distribuibili e instradabili; `.agents/skills/` = repository-only). Ciò che manca è la documentazione esplicita del confine nel builder/guida e un test che impedisca la distribuzione accidentale (SKAUD-001, P3).
- Intercettano troppo: `mcp-master-orchestrator` (frontmatter con lista lunghissima di domini incl. "technical analysis"), mitigato dai gate ma da monitorare con ABL-13.

## Azioni raccomandate (dettaglio nel backlog)

1. Documentare e testare il confine distributivo `skills/` vs `.agents/skills/` (esclusione intenzionale di runtime-integrator dal catalogo) — SKAUD-001, P3 (XS, economico).
2. Aggiungere routing/anti-trigger a database-expert (XS, economico).
3. Completare la matrice orchestrator o dichiararne esplicitamente lo scope (S, intermedio).
4. Deprecare la Minimal skill map di GLOBAL.md a favore di un rimando (XS, economico).
5. Criterio pass/fail docs vs memory (S, intermedio).
6. Risolvere l'incompatibilità docs-node CFML dichiarando la dipendenza dalla fase (XS, economico).
