# Audit 02 - Uso subagenti: contro-analisi e stato

**Documento verificato:** [`20260923_audit_02_subagent_usage.md`](20260923_audit_02_subagent_usage.md)
**Baseline Git:** `6346a2f360926817bbb9d42e6b5f96e51d5d7065`
**Data verifica:** 2026-09-23, Windows 11, codex-cli 0.145.0

L'archivio dell'incidente (`codex_chat_con_subagenti.zip`) non e' nel repository, quindi i numeri della sezione 2 dell'audit non sono riproducibili qui. Al loro posto ho misurato i rollout Codex reali di questa macchina con il nuovo parser read-only (`scripts/runtime/subagent-usage-audit.js`): conteggi aggregati, id hashati, nessun testo di task o messaggio.

## 1. Affermazioni verificate

| # | Affermazione dell'audit | Esito | Evidenza |
|---|---|---|---|
| 2.1 | Il fan-out comprende root, subagent `thread_spawn` e `guardian` | **Confermata** sui dati locali | 540 rollout: 129 root, 246 subagent (tutti depth 1), 162 `guardian`, 3 unknown. `source.subagent.other = "guardian"` e' una categoria distinta |
| 2.2 | Esisteva una policy "use sub-agents liberally ... reduces token consumption" | **Non presente in questo repo, nemmeno nella history** (`git log -S liberally`) | La copia obsoleta arrivava da fuori. Causa A (deriva della distribuzione) confermata come rischio: lo script `.bat` di distribuzione non versiona e non verifica |
| 2.3 | Uso token dei subagent superiore al root | **Confermata** | Token cumulativi dei subagent / root = **2,61** (540 rollout), **3,69** negli ultimi 400. Cached input dei subagent 97% |
| 2.4 | Spawn falliti per modello non supportato | **Confermata** | 2 `Unknown model` (`gpt-5.4-mini`, `gpt-5.5`). **Nuovo:** 71 spawn su 303 passano un `model` esplicito (52 volte `gpt-5.4-mini`) e 89 un `reasoning_effort`. I modelli obsoleti arrivano anche dagli argomenti di spawn scelti dal main agent, non solo dai profili |
| 2.5 | Fork con `fork_turns = "all"` | **Confermata** | 101 spawn su 303 (33%) usano `fork_turns = "all"` o `fork_context = true` |
| 2.7 | `guardian_review` non e' fan-out Sophia | **Confermata** | Classificati a parte in audit e KPI |
| 3.1 | Default opt-in gia' presente | **Confermata** | `subagentMode = off` senza `!agents` o richiesta esplicita |
| 3.2 | Resolver limitato | **Confermata, ma con `!agents` raccomandava fino a 2 ruoli** | `slice(0, explicit ? 1 : 2)` |
| 3.3 | "token/cost optimization" come scopo primario | **Confermata** | `AGENTS.md`, `local-orchestration-playbook.md`, testo del hook in modalita' `requested` ("when token/cost efficient") |
| 3.4 | Modelli concreti nei profili generati | **Confermata** | Trattata nell'audit 03 (vedi §4) |
| 3.5 | Chiavi `[agents]` di Codex | **Confermata sul binario 0.145.0** | Help integrato: `enabled`, `max_concurrent_threads_per_session`, `max_depth (V1 only; ignored by V2)`, `default_subagent_model`, `default_subagent_reasoning_effort`. Il parser rifiuta un valore di tipo errato |

## 2. Finding nuovi o corretti

- **N1 - Un fork full-history clona il main agent.** Il messaggio host, visto 42 volte, dice: "Full-history forked agents inherit the parent agent type, model, and reasoning effort; omit agent_type, model, and reasoning_effort". Un figlio con `fork_turns = "all"` e' quindi il main agent stesso: modello di punta, reasoning alto, contesto intero. Il ruolo richiesto viene rifiutato. E' il meccanismo di costo piu' forte, piu' della semplice quantita' di spawn.
- **N2 - L'hint a keyword `subagents` invitava a delegare anche con `subagentMode = off`.** Parole come "subagent", "spawn", "worker", "scout" o "delegazione" iniettavano "delegate only bounded side tasks": di fatto un invito, anche quando l'utente stava solo parlando di delega (e' successo in questa stessa sessione). Ora, con `off`, l'hint dice esplicitamente di non spawnare.
- **N3 - Ruoli non canonici predominanti.** `agent_type`: `explorer` 142, `worker` 45, `default` 14, assente 44, contro 58 ruoli canonici. E' il perimetro dell'audit 03; qui e' solo misurato.
- **N4 - Il limite di thread dell'host viene gia' raggiunto** (7 `agent thread limit reached`). Dopo uno spawn fallito ci sono stati 49 retry.
- **N5 - Istruzioni di fan-out senza gate oltre quelle citate dall'audit:**
  - `ticket-implementation-checklist.md` ("sub-agent a basso costo");
  - `mcp-skill-miner` (un sub-agent per fonte, 4 o piu');
  - `legacy-pre-migration-audit.md` (sub-agent paralleli per dominio);
  - `motion-improvement-workflow.md` (un subagent per categoria);
  - playbook impeccable `layout`/`typeset`/`critique` ("whenever a sub-agent tool is exposed": spawn automatico non appena lo strumento esiste);
  - `impeccable-live`;
  - `workflows.md` dell'orchestrator: profondita' consigliata **2 livelli**, in contraddizione con il budget.
- **N6 - `scripts/copy-agent-rules.bat` sovrascrive anche l'`AGENTS.md` dei progetti**, senza backup e senza rilevare personalizzazioni.

## 3. Implementazione

| Fase | Stato | Note |
|---|---|---|
| 0 - Parser fan-out | **Fatto** | `scripts/runtime/subagent-usage-audit.js`. Posizione in `scripts/runtime/` per la copertura del planner. Classifica root, subagent, guardian e internal; esiti degli spawn (`ok`, `rejected_full_history_override`, `unknown_model`, `thread_limit`); full history, modello esplicito, deleghe annidate, retry, ruoli canonici e non. Rispetta `CODEX_HOME`. Test su fixture sintetiche inline |
| 1 - Policy canonica | **Fatto** | Rimosso "token/cost optimization" come scopo (`AGENTS.md`, playbook, testo del hook). Aggiunta a `SUBAGENTS.md` la sezione "Activation and budget"; le analisi storiche restano, con una nota di superamento |
| 2 - Gate autorevole | **Fatto** | Hint "off" per le keyword di delega; orchestrator: "orchestrare skill != orchestrare subagent" e esecuzione sequenziale con `off`; gate applicato a tutte le istruzioni di N5. Test di regressione: prompt complessi senza opt-in producono 0 raccomandazioni e nessun hint di delega |
| 3 - Budget | **Fatto** | `SUBAGENT_BUDGET` (1 di default, massimo 2, depth 1, 1 retry, contesto isolato, nessuna ricorsione). Il resolver raccomanda 1 ruolo, 2 solo se l'utente chiede esplicitamente piu' agenti (`requestedAgentCount`) |
| 4 - Cap host-side Codex | **Fatto** | `[agents] max_concurrent_threads_per_session = 2`, `max_depth = 1` aggiunti solo se assenti; un valore utente e' preservato e riportato. Gli altri client non hanno una chiave verificata, quindi resta solo la policy |
| 5 - Niente full history | **Fatto** (istruzione + telemetria) | `SUBAGENTS.md` e il testo del hook: `fork_turns = "none"` o un numero piccolo, mai `"all"`, con la motivazione di N1. Sophia non puo' forzare l'argomento dell'host: la violazione e' misurata dal parser (`fullHistory`) |
| 6 - Modelli resilienti | **Rimandata all'audit 03** | L'audit 03 (§48) chiede esplicitamente di non fare due migrazioni concorrenti dello stesso schema. Nel frattempo la policy vieta `model`/`reasoning_effort` negli spawn salvo richiesta dell'utente |
| 7 - Retry | **Fatto** (policy) | Massimo 1 retry senza override, mai un modello piu' forte, nessun loop dopo `thread limit`. Il parser misura `retrySpawns` |
| 8 - Distribuzione shared rules | **Fatto** | Manifest `schemaVersion 2`, `subagentPolicyVersion` e `sha256` normalizzato LF. `scripts/runtime/shared-agent-rules.js` con `check`, `sync` (dry-run, backup, `AGENTS.md` personalizzato protetto), `update-manifest` e `verify-manifest`. `test:routing` fallisce se il manifest non e' allineato o se le regole contengono formulazioni legacy |
| 9 - Installer/checker | **Fatto** | Installer: budget `[agents]`. `check-user-runtime`: sezione "Subagent Delegation Policy" (valori `[agents]`, deriva del manifest, formulazioni legacy in `~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, `~/.gemini/GEMINI.md`). La deriva dei profili agenti installati resta coperta dai check esistenti dei link |
| 10 - Ruoli portabili | **Fatto** | Invariante comune iniettata dal renderer in tutti i runtime ("Do not spawn or delegate to other agents unless the parent task explicitly authorizes nested delegation"); profili rigenerati con `sync-portable-agents.js` e verificati con `check-agents-doc.js` |
| 11 - Workflow fan-out | **Fatto** | Vedi N5; `workflows.md`: 1 scout di default, profondita' 1 |
| 12 - Telemetria | **Parziale** | KPI disponibili dal parser offline. Nessun evento runtime `subagent_spawn` nel DB analytics: l'integrazione con `analytics-node` e' nel perimetro degli audit 03 (planned vs actual) e 05 |

Graphify (`.agents/skills/graphify`, un subagent `worker` per chunk) e' una skill vendorizzata, repository-only e CI-owned: e' lasciata agli audit 03 (ruolo canonico) e 04 (exception ledger).

## 4. Baseline per il confronto before/after

Da ripetere con lo stesso comando dopo qualche giorno d'uso con la nuova policy:

```bash
node scripts/runtime/subagent-usage-audit.js --limit 400
```

| KPI (ultimi 400 rollout, 2026-09-23) | Before |
|---|---:|
| Subagent per thread root | 3,23 |
| Token subagent / root | 3,69 |
| Spawn full-history | 89 / 231 |
| Spawn con `model` esplicito | 22 / 231 |
| Rifiuti full-history + modello sconosciuto + thread limit | 31 + 2 + 4 |
| Retry dopo uno spawn fallito | 35 |
| Deleghe annidate | 4 |
| Guardian contati come subagent | 0 (separati) |

## 5. Limiti

- Sophia non intercetta `spawn_agent`: il gate e' fatto di istruzioni autorevoli piu' misura, non di enforcement. L'unico enforcement reale e' il cap `[agents]` di Codex.
- `max_depth` vale solo per il backend V1 di Codex.
- Il benchmark before/after sullo scenario dell'incidente (§9 dell'audit) richiede sessioni reali: il parser e' pronto per produrlo.
