# 09 — Do not change

Elementi da preservare, tutti con evidenza. Nessuno di questi va semplificato o rimosso senza ablation test dedicato, indipendentemente da quanto "ridondante" appaia a un modello capace.

1. **Enforcement SQL read-only lato server** — `sql-node/index.js` blocca INSERT/UPDATE/DELETE/DDL/multi-statement a livello di codice (`isQueryReadOnly`, righe ~248-250). La regola prosa in `GLOBAL.md:12,30` è il complemento per client senza hook. È difesa in profondità, non ridondanza.

2. **Guardrail `cf_bridge.evaluate` passive-only nella skill** (`mcp-coldfusion-developer/SKILL.md:64`) **e denylist server-side esistente** (`cf-node/mcp_tool/mcp_agent.cfm:134-139`: blocco di cfhttp/cfquery/cfexecute/cfregistry/cffile/cfdirectory/cfmail/createObject(/invoke() — [corretto 2026-07-20] la denylist c'è ma non è una sandbox completa (pattern-matching testuale, funzioni script equivalenti non elencate, side effect indiretti via `Evaluate`): skill e denylist sono **difesa in profondità complementare**, nessuna delle due va rimossa. Il contratto MCP-side resta privo di annotation (`cf-node/index.js:46-72`).

3. **Protocollo two-step delete di analytics-node** (dry_run → confirm_delete + confirm_plan_id, `analytics-node/src/index.ts`, annotations destructiveHint) e la regola skill "se il piano è cambiato, rifai dry-run" (`mcp-analytics-operator/SKILL.md:83-93`). Miglior contratto distruttivo del repo; pattern di riferimento.

4. **Igiene memoria** — no segreti/token/payload sensibili, search-before-write (`GLOBAL.md:57-70`, `mcp-memory-operator/SKILL.md:24-27`, hook `sophia-pretool-memory.mjs`). POLICY_REQUIRED di privacy.

5. **Copy-before-write per documenti Office** (`mcp-office-expert/SKILL.md:31,87`) — le scritture word/excel sono in-place e non reversibili dal tool (nessun backup/dry-run in `office-node`). INVARIANT di conservazione dati finché il tool non offre alternativa.

6. **Dry-run prima di apply nelle operazioni docs di massa** — `correlate apply:false` prima di `apply:true`, `confirm_replace` solo dopo verifica impatto (`mcp-docs-navigator/SKILL.md:18,47-50`; `docs-node/index.js:2346-2355,2418`).

7. **Fallback deterministici del routing** — catalogo assente/invalido → catalogo vuoto senza crash (`sophia-user-prompt-submit.mjs:38-56`); soglia score ≥3; cap a 2 hint; negation-aware matching (testato in `tests/routing-hooks.test.mjs`). Sono ciò che rende il routing sicuro su ogni client e offline.

8. **Default fail-closed del branch candidato** — `DEFAULT_AMBIGUITY_CONFIG.enabled:false` (`routing-ambiguity-gate.mjs:16-18`), `DEFAULT_ROUTING_POLICY.mode:'off'` (`routing-policy-resolver.mjs:11-19`), divieto di displacement di skill locked/explicit/hard-excluded (`routing-policy-resolver.mjs:215-219`). Qualunque attivazione futura deve preservare questi default e passare da shadow mode osservabile.

9. **Pattern di compatibilità legacy `action`/`project_path`/`save_path`** (AGENTS.md §3) e la lettura delle variabili `.env` dal progetto target, non dal repo MCP — vincolo LEGACY_REQUIRED verificato in tutti gli 11 server (`tool-contracts.raw.json`).

10. **Anti-trigger reciproci e simmetrici** tra grid-ui-debugger ↔ frontend-performance-debugger ↔ browser-automation e tra i due mantis writer (`instruction-conflicts.raw.json`, overlaps #2-3) — è il pattern di disambiguazione che funziona; le semplificazioni "per ridurre file" lo distruggerebbero. Analogo: `mantis_add_note` forza note private (`mantis-node/index.js:113-124`) — comportamento privacy-protettivo da non "sbloccare" senza decisione esplicita.

**Nota trasversale**: la duplicazione prosa↔hook dei guardrail (SQL, ColdFusion, memory, ProjectFS) è in parte *by design*: la prosa serve i client senza hook (portabilità), il hook serve l'enforcement runtime. L'intervento corretto è il meccanismo anti-drift (fonte unica + generazione o check di sincronia), NON la rimozione di uno dei due lati.
