# Analisi tecnica: agent context, MCP output e orchestration hardening

- Data: 2026-09-02
- Baseline originaria dell'analisi: `master` (`ed331f5cd16a6842b6c35f5471e614df67af0de6`)
- Base effettiva dell'implementazione/review: `master` (`f95d8ef07b3a59ed34687acff88831e2f2b44362`)
Branch implementativa: `feat/agent-context-mcp-hardening`

## Obiettivo

Ridurre crescita non necessaria del contesto, numero di inferenze/review, payload MCP e duplicazione di lavoro tra agenti, mantenendo le policy portabili tra Codex, Claude Code, Cursor, Copilot, Gemini/Antigravity e altri client MCP.

La remediation non deve ottimizzare un singolo host. Il principio e':

1. contratto MCP semanticamente corretto e bounded;
2. policy agentica condivisa e host-agnostic;
3. ruoli/subagent canonici con contesto e tool minimi;
4. adapter host-specific solo dove il runtime espone capability differenti.

## Evidenza di partenza

L'analisi dei rollout del ticket Moncler `#0011257` ha mostrato:

- il main agent era gia' a circa 204k token di input contestuale prima dell'implementazione e ha raggiunto circa 234k/258k prima della compaction;
- screenshot Playwright sono stati serializzati come PNG base64 anche quando salvati su file, con singole tool response nell'ordine del megabyte;
- un docs-agent avviato come supporto ha ereditato contesto molto ampio ed eseguito 67 chiamate browser;
- 189 assessment guardian sono stati osservati, 186 dei quali associati a chiamate Playwright MCP, con rapporto 1:1 tra browser call e review nei thread analizzati;
- il session-start Sophia imponeva la discovery di taxonomy docs e memory anche per ticket che non ne avevano bisogno.

Questi dati distinguono due fenomeni:

- crescita del main context: dominata da planning/discovery troppo estesi e tool output voluminosi;
- consumo complessivo di inferenze/quota: amplificato da subagent con contesto duplicato e auto-review guardian.

## Principi di progetto

### Policy portabili

Le regole comuni vivono in `shared-agent-rules/` e non devono nominare una feature di un host come requisito universale. Concetti portabili:

- host-managed browser first quando copre il task;
- artifact/reference-first per binari;
- targeted/lazy knowledge discovery;
- minimal context inheritance per subagent;
- least-capability tool profile;
- bounded tool output.

### Enforcement server-side

Prompt e skill non sono sufficienti per impedire payload enormi. I server MCP devono applicare limiti e contratti sicuri anche se il consumer serializza ingenuamente la risposta.

### Compatibilita' incrementale

I mega-tool legacy restano disponibili durante la migrazione. Nuovi tool piu' specifici vengono introdotti come superficie preferita e le skill vengono migrate prima della rimozione dei contratti legacy.

---

# 1. Contratto screenshot `playwright-node`

## Problema

`browser_screenshot` e `browser_annotate` restituiscono `ImageContent` PNG base64. Nel caso screenshot, il buffer viene comunque restituito inline anche quando il chiamante ha passato un `path` e il file viene salvato localmente.

Questo rende possibile duplicare nello stesso turno:

- artifact su filesystem;
- immagine MCP;
- serializzazione testuale dell'intero tool result da parte del consumer.

## Correzione

Introdurre delivery esplicita:

- `artifact`: salva PNG e ritorna solo metadata bounded;
- `inline`: ritorna `ImageContent` soltanto se sotto soglia;
- default server: `artifact`;
- `SCREENSHOT_INLINE_MAX_BYTES`: hard cap configurabile, inizialmente 256 KiB;
- richiesta inline sopra soglia: fallback automatico ad artifact, mai base64 troncato.

Il comportamento deve essere condiviso da screenshot e annotate. `debug_bundle` gia' applica un pattern artifact-first e costituisce il riferimento interno.

## Acceptance

- nessun base64 nella response artifact;
- `path` non duplica il PNG inline;
- inline esplicito sotto soglia resta supportato;
- fallback sopra soglia produce artifact valido e metadata di fallback;
- smoke test coprono entrambe le delivery.

---

# 2. Impedire serializzazione base64 / raw tool result

## Problema

Il pattern osservato `text(shot)` e' specifico del runtime, ma il difetto generale e' host-agnostic: serializzare integralmente un `CallToolResult` con media/binari reintroduce nel contesto tutto il payload.

## Correzione

Regola condivisa:

- non stringify/echo dell'intero tool result contenente media/binari;
- usare soltanto il content block necessario o `structuredContent` compatto;
- binary/media artifact-first;
- inline binary solo esplicito e bounded dal server.

La difesa primaria resta server-side, cosi' un consumer non ottimale non puo' trasformare uno screenshot artifact in un blob enorme.

La stessa disciplina si applica a trace, attachment, download, ZIP, Office/PDF e network body.

---

# 3. Browser host-managed first

## Problema

La skill browser Sophia trattava `playwright-node` come default universale. Questo forza un layer MCP esterno anche quando il client dispone di una propria integrazione browser ottimizzata per DOM, screenshot, console/network e isolamento del contesto.

## Policy target

1. rilevare/considerare le capability browser gestite dall'host;
2. preferirle per normale navigazione, ispezione, validazione UI, console/network e prova visuale quando soddisfano il task;
3. usare Playwright MCP quando il browser host non e' adeguato o servono capability specialistiche;
4. registrare la motivazione dell'escalation a Playwright.

Capability specialistiche tipiche:

- automazione deterministica/reusabile;
- storage-state;
- network body capture;
- tracing/performance;
- CDP specifico;
- workaround legacy/iframe;
- host senza browser gestito adeguato.

La policy non nomina Codex, Cursor, Claude o altri come requisito. Ogni adapter mappa il concetto alle feature effettivamente disponibili nel runtime corrente.

---

# 4. Context inheritance minimale per subagent

## Problema

Un support agent non dovrebbe ricevere la conversazione completa del parent per default. Nel caso analizzato il docs-agent ha ereditato una storia gia' molto ampia, annullando il beneficio economico della delegazione.

## Correzione

Ogni support agent riceve un delegation packet contenente solo:

- obiettivo;
- scope/ownership;
- fatti gia' verificati necessari;
- vincoli e fuori-scope;
- capability necessarie;
- validation richiesta;
- stop/escalation conditions.

Target iniziale: <= 16 KiB quando praticabile.

L'equivalente host di `full history` e' ammesso soltanto quando il significato della delega dipende davvero dall'intera negoziazione e non e' possibile produrre un handoff affidabile e piu' piccolo.

---

# 5. Docs-agent least-capability

## Problema

Il task documentale era stato delegato a un implementer generico, con accesso a capability molto piu' ampie del necessario. Ha quindi ripetuto discovery e validazione browser.

## Correzione

Introdurre ruolo canonico `docs_writer`:

- workspace write limitato concettualmente alla documentazione assegnata;
- repository read/search + edit/write + diff/Markdown validation;
- niente browser/runtime/DB/ticket/memory/docs-corpus discovery per default;
- lavora da evidenze gia' verificate dal parent;
- restituisce il gap al parent anziche' allargare autonomamente scope.

I renderer host-specific applicano la tool allowlist piu' stretta disponibile. Dove il runtime non consente hard filtering, le stesse restrizioni restano un guardrail comportamentale e devono essere validate con eval.

Per modifiche documentali banali il default rimane il main agent diretto: non creare un subagent se il costo di handoff e' maggiore del lavoro.

---

# 6. Budget espliciti di contesto/output

Le regole qualitative esistenti vengono rese misurabili con valori iniziali da calibrare tramite analytics:

| Operazione | Default iniziale |
|---|---:|
| tool text-result target | 12 KiB |
| tool text-result hard target | 32 KiB |
| search/list first pass | 20 risultati |
| search/list hard default | 100 risultati |
| source/file first read | 300 righe |
| docs/memory first search | 10 risultati |
| browser console/network | 20 entry |
| delegation packet | 16 KiB |
| binary/media | artifact-first |

Se l'host espone context usage affidabile:

- ~50%: chiudere broad discovery;
- ~65%: evitare nuovi support agent/rami pesanti;
- ~75%: compaction/handoff prima di una nuova fase sostanziale.

Se l'host non espone la metrica, non deve essere inventata.

A regime i server devono offrire `limit`, cursor/offset, range, `max_bytes`, `truncated` e artifact overflow dove applicabile.

---

# 7. Guardian, approval e MCP ToolAnnotations

## Evidenza

Nel rollout analizzato 186/189 review guardian erano Playwright MCP e ogni Playwright call del main/explorer/docs-agent corrispondeva a una review.

Il problema contrattuale principale e' che tool come `browser_session` raggruppano azioni read-only e azioni potenzialmente mutating/esecutive. Le MCP ToolAnnotations sono definite a livello tool, non a livello del valore `action`; una singola annotation non puo' classificare correttamente entrambe le categorie.

Le annotations sono hint, non enforcement. Il miglioramento contrattuale e' obbligatorio, ma la riduzione di guardian/approval deve essere misurata per host.

## Correzione Playwright

Introdurre superfici progressive mantenendo i legacy tool:

- `browser_inspect`: sole letture, `readOnlyHint:true`;
- `browser_capture`: artifact visuali, non distruttivo ma non read-only;
- `browser_session`: legacy mixed, classificazione conservativa;
- `browser_interact`: mixed interaction, classificazione conservativa.

Le skill devono preferire i tool specifici.

## Audit trasversale MCP

Ogni tool deve dichiarare esplicitamente:

- `readOnlyHint`;
- `destructiveHint`;
- `idempotentHint`;
- `openWorldHint`.

Priorita':

- `sql_executor`: mixed/conservativo; il filtro SELECT/WITH e' un gate di ammissibilita' ma non prova la purezza delle funzioni SQL invocate;
- `get_lint_config`: read-only;
- `lint_code`: mixed per `fix`, conservativo finche' non viene separato check/fix;
- Mantis: reader vs add-note, files mixed;
- CF: `cf_bridge` mixed finche' logs/evaluate non vengono separati;
- Docs: `docs_navigation` read-only, management/mindmap/remote conservativi se mixed;
- Office: conservativo finche' read/write/export/setup restano aggregati;
- Git: completare le annotations e pianificare la separazione delle action che scrivono artifact dai tool dichiarati read-only.

Il registry interno di rischio non deve diventare una seconda source of truth divergente dal vero contratto `tools/list`.

---

# 8. Docs/memory lazy

## Root cause

Nonostante `shared-agent-rules/AGENTS.md` parlasse di routing on-demand, `sophia-session-start.mjs` iniettava ad ogni sessione un bootstrap obbligatorio:

- docs `list_tags`;
- memory `list_tags`;
- memory `list_topics`.

Questo rendeva la discovery non-lazy per costruzione.

## Correzione

Session start carica soltanto governance locale. Docs e memory vengono attivati dal task reale.

Docs:

1. targeted search quando i documenti sono materialmente rilevanti;
2. taxonomy/catalog soltanto se la search e' insufficiente;
3. fallback esaustivo soltanto quando la conclusione "non esiste documentazione" e' materialmente necessaria.

Memory:

1. targeted search solo per continuity/reuse/handoff/persistence need;
2. read dei risultati pertinenti;
3. status/taxonomy soltanto in caso di errore, write importante o ricerca insufficiente.

Su un ticket code-only sufficientemente specificato il target e':

```text
docs calls = 0
memory calls = 0
taxonomy bootstrap calls = 0
```

---

# Strategia di implementazione

1. policy condivise: lazy discovery, browser routing, context/output discipline;
2. session-start: rimozione taxonomy bootstrap;
3. ruolo canonico `docs_writer` e adapter multi-host;
4. screenshot artifact-first e anti-base64;
5. `browser_inspect` / `browser_capture` + annotations;
6. annotations quick-win e conservative sugli altri MCP;
7. smoke/eval e CI affected gate;
8. benchmark cross-host e ulteriore split dei mega-tool sulla base dei dati.

## GitHub Actions temporanee

Durante lo sviluppo viene usata una workflow temporanea, limitata al branch, per:

- applicare in modo deterministico patch su file server molto grandi quando utile;
- installare i runtime server;
- installare Chromium Playwright;
- eseguire `npm run test:affected -- --strict --base master`.

La workflow e gli helper temporanei devono essere rimossi prima della consegna finale.

# Acceptance complessiva

Per una fixture equivalente a un ticket frontend semplice:

- nessun bootstrap docs/memory generico;
- nessun support-agent full-history salvo eccezione motivata;
- docs writer: zero browser/runtime/DB calls;
- screenshot artifact: zero base64 inline;
- output tool bounded;
- nessuna compaction evitabile durante planning/implementation ordinari;
- annotations presenti e semanticamente coerenti;
- approval/guardian misurati separatamente per host, senza assumere che le annotations ne garantiscano la rimozione.

# Rischi residui

- client legacy possono dipendere dallo screenshot inline: mantenere `delivery:inline` esplicito;
- le ToolAnnotations restano hint e possono non modificare il comportamento approval di un host;
- non tutti gli host consentono la stessa hard tool allowlist per subagent;
- i mega-tool Git/Docs/CF/Office/Linter richiedono split incrementali per ottenere classificazione perfettamente granulare;
- i budget quantitativi sono baseline operative da calibrare con telemetria, non limiti universali immutabili.

# Decisione

La remediation deve essere valutata come hardening dell'intero sistema agentico Sophia: MCP efficienti e semanticamente corretti, policy portabili e adapter host-specific minimi. La sessione Codex che ha originato l'analisi e' una fixture diagnostica, non il target esclusivo del progetto.
