Skip to content

Piano Finale di Implementazione per Ottimizzazione Token

Obiettivo

Ridurre in modo sostanziale il consumo token del progetto senza degradare:

  • copertura della superficie di attacco
  • numero di finding trovati
  • qualità del reasoning
  • qualità della verification
  • qualità del chain discovery
  • qualità delle evidenze e del reporting

Questo piano incorpora:

  • la diagnosi iniziale
  • il piano operativo precedente
  • i feedback della review di Opus High

L'obiettivo non è "fare meno pentest". L'obiettivo è:

spendere meno token per ottenere lo stesso lavoro utile, eliminando costo statico, costo duplicato, costo di orchestration difettosa e costo speso in run morte o impossibili.

Principi guida

  1. Prima si blocca il burn inutile, poi si ottimizza il prompt tax
  2. Nessun downgrade di modello nella fase iniziale
  3. Ogni ottimizzazione deve essere misurabile
  4. Ogni ottimizzazione deve essere feature-flagged
  5. Qualsiasi rischio di regressione su coverage o findings richiede shadow mode
  6. La metodologia offensiva non si tocca; si tocca il veicolo che la trasporta

Sintesi esecutiva

Se dovessi partire davvero con l'implementazione, farei in quest'ordine:

  1. Strumentazione completa
  2. Hardening del bug bounty loop
  3. Split di skill-boilerplate.md
  4. Budget max-turns per skill
  5. Decomposizione POC di test-injection con cross-type signal forwarding
  6. Novelty gate sul proxy analyzer
  7. Differential rediscovery con full rediscovery periodico
  8. Compattazione dispatch/preamble e decomposizione di altre skill pesanti
  9. Solo infine: routing di task deterministici su lane shadow

Risultato atteso

Stima prudente:

  • Pentest flow principale: riduzione 40-70%
  • Bug bounty loop: riduzione 70-90% se il loop attuale sta davvero bruciando quota in spawn storm/rate limit

Cosa implementerei davvero


Fase 0: Metriche e Osservabilità

Obiettivo

Sapere con precisione dove vengono spesi i token prima e dopo ogni modifica.

File che toccherei

Implementazioni

0.1 Wrapper di metrica per ogni claude -p

Ogni invocazione deve scrivere un record JSONL con:

  • timestamp start
  • timestamp end
  • family:
  • bb-loop
  • bb-hunt
  • pentest
  • proxy-analyzer
  • runner
  • knowledge-refresh
  • caller file
  • target / engagement / program / session id
  • prompt source:
  • inline
  • file path
  • prompt digest
  • prompt char count
  • estimated prompt tokens
  • supporting_files_count
  • supporting_files_bytes
  • max_turns
  • model
  • output format
  • exit code
  • rate-limit detected
  • run classification

0.2 Classificazione standard dei run

Classi:

  • useful
  • rate_limited_immediate
  • rate_limited_midrun
  • dead_run_short
  • error
  • cancelled

0.3 Materializzazione metrica in runtime dirs

Path proposti:

  • bugbounty/.runtime/metrics/claude-invocations.jsonl
  • engagements/<name>/runtime/claude-invocations.jsonl
  • dashboard/data/runtime/proxy-analysis-metrics.jsonl

0.4 Aggregatore locale

Script di aggregazione per calcolare:

  • spawn/hour
  • run/hour
  • dead-run ratio
  • rate-limit ratio
  • avg prompt chars
  • estimated static prompt tax by family
  • token per useful run
  • token per confirmed finding

Feature flag

  • CLAUDE_METRICS=1

Condizione di completamento

Prima di ogni altra fase, devo poter rispondere con numeri a:

  • quali family consumano di più
  • quanti run sono morti
  • quanta parte del costo è bootstrap statico
  • quanto pesa il proxy analyzer

Fase 1: Hardening del Bug Bounty Loop

Obiettivo

Bloccare il burn inutile causato da orchestration difettosa, sessioni duplicate, backoff inesistente e run che partono già in rate limit.

File che toccherei

Implementazioni

1.1 Single-instance lock globale

Implementerei un lock atomico:

  • bugbounty/.runtime/loop.lock

Semantica:

  • se il lock è vivo e PID/processo corrisponde: niente nuovo start
  • se il lock è stale: takeover controllato e loggato
  • nessun doppio orchestratore attivo contemporaneamente

1.2 Control plane unico

Unificherei i percorsi:

  • PERPETUAL-HUNTING-LOOP.sh
  • loop-manager.sh
  • /bb-loop

in una sola semantica.

Decisione:

  • loop-manager.sh diventa il control plane reale
  • PERPETUAL-HUNTING-LOOP.sh diventa worker orchestrator o entrypoint thin ma non più semantica concorrente
  • /bb-loop documenta e usa solo quel path

1.3 Cooldown globale su rate limit

Riutilizzerei la logica regex già presente in pentest-autoresume.py.

Semantica:

  • se qualunque subprocess rileva out of extra usage o pattern equivalente:
  • scrive stato globale di pausa
  • nessun nuovo claude -p parte
  • il loop entra in cooldown globale

Backoff:

  • evento 1: attesa fino al reset parseato o 15 minuti
  • evento 2 ravvicinato: 30 minuti
  • eventi ripetuti: blocco fino a reset reale

1.4 Dead-run classification

Una sessione è dead_run_short se:

  • <= 3 turni
  • oppure < 90 secondi
  • oppure rate limit immediato
  • oppure nessun comando reale eseguito

Questi run:

  • non fanno avanzare il loop come run utile
  • non aggiornano ranking come se fosse stata una vera hunt
  • attivano backoff
  • non generano nuova ondata di spawn immediato

1.5 Quota-aware scheduler

Il loop deve diventare quota-aware:

  • se quota disponibile: comportamento normale
  • se quota incerta: riduzione concurrency
  • se quota esaurita: pausa globale

1.6 Prompt dump e log runtime separati

Sposterei:

  • .prompt-*
  • .session-prompt-*
  • .hunt-*.log
  • PERPETUAL-HUNTING.log
  • perpetual-hunting-console.log

in:

  • bugbounty/.runtime/prompts/
  • bugbounty/.runtime/logs/

Più:

  • rotazione
  • retention
  • compressione opzionale

Feature flags

  • BB_LOOP_SINGLETON_LOCK=1
  • BB_GLOBAL_RATE_LIMIT_GUARD=1
  • BB_DEAD_RUN_CLASSIFIER=1
  • BB_RUNTIME_LOG_SEPARATION=1

Perché lo farei subito

Perché è l’intervento con miglior rapporto:

  • impatto altissimo
  • rischio regressione quasi nullo
  • nessun cambiamento metodologico

Fase 2: Split di skill-boilerplate.md

Obiettivo

Ridurre il costo statico pagato da quasi ogni subprocess di test.

File che toccherei

Implementazioni

2.1 Split in moduli

Creerei:

  • skill-boilerplate-core.md
  • skill-boilerplate-stealth.md
  • skill-boilerplate-ratelimit.md
  • opzionale skill-boilerplate-bugbounty.md
  • opzionale skill-boilerplate-proxy.md

2.2 Contenuto del core

Nel core:

  • PATH isolation
  • EDIR setup
  • python command detection
  • logging base
  • kill switch base
  • token counting base
  • auth setup

2.3 Contenuto lazy

Moduli caricati solo quando servono:

  • stealth avanzato: solo se stealth mode attivo
  • rate-limit handler completo: solo al primo 429 o when needed
  • bug bounty policy enforcement: solo se bug_bounty=true
  • proxy-specific helpers: solo se proxy attivo

2.4 Refactoring dei riferimenti

Ogni skill non dirà più “carica tutto il boilerplate”.

Dirà invece:

  • carica core sempre
  • carica moduli aggiuntivi in base a condizioni runtime o scope

Feature flags

  • SKILL_BOILERPLATE_SPLIT=1
  • SKILL_LAZY_LOAD=1

Perché lo farei prima delle decomposizioni skill

Perché questo da solo può portare un risparmio enorme senza cambiare la metodologia delle skill.


Fase 3: Budget max-turns per classe di skill

Obiettivo

Smettere di dare 250 turni a skill che realisticamente non ne usano o non ne hanno bisogno.

File che toccherei

Implementazioni

3.1 Classi di budget

Proposta:

  • Deterministic:
  • test-infra
  • test-crypto
  • test-client
  • budget 80-120

  • Medium:

  • test-api
  • test-ssrf
  • test-cloud
  • budget 150

  • High:

  • test-injection
  • test-auth
  • test-access
  • test-logic
  • budget 250

  • Very high:

  • chaining / verification complesse
  • budget 250+

3.2 Telemetria di utilizzo turni

Prima raccolgo:

  • turni effettivamente usati per skill
  • quante skill finiscono molto prima del budget

Poi imposto le soglie.

Feature flag

  • SKILL_MAX_TURNS_BUDGETING=1

Rischio

Basso, se i budget vengono prima inferiti dai dati e non “indovinati”.


Fase 4: Decomposizione POC di test-injection

Obiettivo

Validare il pattern “skill monolitica -> router + sub-skill scope-specifiche” sulla skill più costosa.

File che toccherei

  • test-injection/SKILL.md
  • supporting files dichiarati da test-injection
  • nuovi path suggeriti:
  • .claude/skills/test-injection-router/
  • .claude/skills/test-injection-sqli/
  • .claude/skills/test-injection-xss/
  • .claude/skills/test-injection-ssti/
  • .claude/skills/test-injection-xxe/
  • .claude/skills/test-injection-cmdi/

Implementazioni

4.1 Router leggero

Il router decide il ramo da caricare in base a:

  • --scope
  • segnale dal target
  • tipo endpoint
  • tech stack

4.2 Sub-skill minimali

Ogni sub-skill dichiara solo i supporting-files necessari.

Esempio:

  • SQLi:
  • knowledge-sqli
  • cheatsheet-sqli

  • XSS:

  • knowledge-xss
  • cheatsheet-xss

  • XXE:

  • knowledge-xxe
  • cheatsheet-xxe solo se serve

4.3 Cross-type signal forwarding

Questo è obbligatorio.

Ogni sub-skill deve poter emettere segnali verso altre classi:

  • SQLi vede reflection HTML -> segnala XSS
  • XSS vede sintassi template -> segnala SSTI
  • XXE vede URL fetch behavior -> segnala SSRF
  • SQLi vede output di shell o path insoliti -> segnala CMDi

Path suggerito:

  • $EDIR/signals/cross-type-signals.jsonl

4.4 Router che consuma i segnali

Il router deve leggere quei segnali e dispatchare follow-up mirati.

Feature flags

  • TEST_INJECTION_SPLIT=1
  • CROSS_TYPE_SIGNAL_FORWARDING=1

Criterio di successo

Se questa POC regge, poi applico lo stesso pattern a:

  • test-auth
  • test-access
  • test-client
  • test-logic

Fase 5: Novelty Gate per il Proxy Analyzer

Obiettivo

Ridurre il background token burn del proxy analyzer senza perdere le request ad alto signal.

File che toccherei

Implementazioni

5.1 Semantic fingerprint

Cluster key basata su:

  • method
  • normalized route
  • param names
  • auth present/absent
  • status bucket
  • response content-type
  • response shape hash

5.2 Batch solo su novelty

Inviare a Claude solo:

  • cluster nuovi
  • cluster con delta significativo
  • request che matchano signal forti

5.3 Keep list di richieste sempre interessanti

Mai droppare:

  • nuovi endpoint
  • 4xx/5xx interessanti
  • redirect params
  • reflection
  • token leakage
  • GraphQL
  • webhook/callback
  • upload
  • admin/internal
  • auth flow nuovi

5.4 Manual realtime sempre attivo

L’analisi manuale single-request deve restare sempre disponibile.

5.5 Default operativo

Io non flippo subito il default auto_analyze=False.

Lo faccio solo:

  • dietro flag
  • oppure dopo parity positiva

Feature flags

  • PROXY_AI_NOVELTY_GATE=1
  • PROXY_AUTO_ANALYZE_DEFAULT_OFF=0 inizialmente

Fase 6: Differential Rediscovery

Obiettivo

Smettere di rifare discovery completa su programmi già noti quando la superficie non è davvero cambiata.

File che toccherei

Implementazioni

6.1 Manifest di freshness

Per programma salvo:

  • homepage hash
  • robots/sitemap hash
  • JS manifest hash
  • auth surface fingerprint
  • tech stack fingerprint
  • route set hash
  • endpoint methods
  • GraphQL presence/schema hash se disponibile

6.2 Delta check leggero all’inizio

Ogni ritorno su programma già noto parte da:

  • lightweight freshness probe
  • confronto col manifest

6.3 Routing decision

Se delta forte:

  • full rediscovery

Se delta debole:

  • reuse baseline
  • delta crawl mirato
  • focus su:
  • untested endpoints
  • next steps storici
  • nuovi segnali

6.4 Force full rediscovery periodico

Obbligatorio.

Proposta:

  • full rediscovery ogni N cicli
  • o ogni M giorni

per safety net contro false negative sottili.

Feature flags

  • BB_DIFFERENTIAL_REDISCOVERY=1
  • BB_FORCE_FULL_REDISCOVERY_EVERY_N=5 ad esempio

Fase 7: Compattazione di agent-dispatch.md e dei preamble ripetuti

Obiettivo

Ridurre altro testo statico che viene pagato spesso ma è in gran parte tabelle/lookup.

File che toccherei

Implementazioni

7.1 Convertire tabelle in config compatta

Le mappe:

  • model routing
  • thinking budget
  • agents per wave
  • parallelism config

vanno in JSON/YAML compatti, non in markdown narrativo lungo.

7.2 Ridurre framing duplicato nelle skill

Centralizzare il preamble condiviso e lasciare nelle skill solo il delta domain-specific.

Feature flags

  • DISPATCH_CONFIG_COMPACTION=1

Fase 8: Decomposizione delle altre skill pesanti

Obiettivo

Applicare il pattern validato su test-injection alle skill con ROI successivo più alto.

Ordine che userei

  1. test-auth
  2. test-access
  3. test-llm
  4. test-client
  5. test-logic

Motivo

  • test-auth e test-access sono molto pesanti e frequenti
  • test-llm è enorme quando attivo
  • test-client e test-logic hanno un buon potenziale di riduzione

Guardrail obbligatori

Ogni decomposizione deve avere:

  • signal forwarding
  • parity test
  • feature flag
  • rollback facile

Fase 9: Search Hygiene e Ignore Rules

Obiettivo

Ridurre il rischio di contaminazione del contesto tool da directory enormi o inutili.

File che toccherei

  • .gitignore
  • nuovo .rgignore
  • opzionale .claudeignore se supportato

Implementazioni

Esclusioni:

  • .claude/worktrees/
  • dashboard/frontend/node_modules/
  • payloads/ dove non serve
  • ingest/data/
  • bugbounty/.runtime/
  • log runtime
  • prompt dump runtime

Rischio

Praticamente nullo.


Fase 10: Lane B opzionale, solo dopo parity

Obiettivo

Fare l’ultimo miglio di ottimizzazione su task veramente deterministici.

Cosa sposterei, ma solo in shadow

  • clustering
  • response hashing
  • route normalization
  • sitemap parsing
  • robots parsing
  • manifest diff

Cosa NON sposterei

  • exploit reasoning
  • verification
  • chain discovery
  • final acceptance
  • stuck resolution

Condizione

Mai prima di avere parity positiva sulle fasi precedenti.


Cosa NON farei adesso

  1. Non rifarei in modo aggressivo CLAUDE.md
  2. Non spegnerei brutalmente il proxy analyzer senza shadow
  3. Non ridurrei numero di skill o di wave
  4. Non abbasserei i modelli nelle fasi critiche
  5. Non introdurrei troppe ottimizzazioni insieme senza misurarle separatamente

Feature flags complessive

Quelle che introdurrei:

  • CLAUDE_METRICS=1
  • BB_LOOP_SINGLETON_LOCK=1
  • BB_GLOBAL_RATE_LIMIT_GUARD=1
  • BB_DEAD_RUN_CLASSIFIER=1
  • BB_RUNTIME_LOG_SEPARATION=1
  • SKILL_BOILERPLATE_SPLIT=1
  • SKILL_LAZY_LOAD=1
  • SKILL_MAX_TURNS_BUDGETING=1
  • TEST_INJECTION_SPLIT=1
  • CROSS_TYPE_SIGNAL_FORWARDING=1
  • PROXY_AI_NOVELTY_GATE=1
  • PROXY_AUTO_ANALYZE_DEFAULT_OFF=0
  • BB_DIFFERENTIAL_REDISCOVERY=1
  • BB_FORCE_FULL_REDISCOVERY_EVERY_N=5
  • DISPATCH_CONFIG_COMPACTION=1

Piano di validazione

Dataset minimo

  • almeno un flusso pentest standard
  • almeno un flusso bug bounty loop
  • almeno un flusso con proxy analyzer attivo
  • almeno un ritorno su programma già noto

Metriche da confrontare

  • token totali
  • token per family
  • prompt size medio
  • run morti
  • rate-limit ratio
  • endpoint coverage
  • crown jewel coverage
  • findings confermati
  • quality of evidence
  • chain coverage

Go / No-go

Una fase si considera approvata solo se:

  • findings parity è uguale o migliore
  • coverage parity è uguale o migliore
  • verification parity è uguale o migliore
  • costo token migliora in modo significativo

Piano di rollback

Ogni fase deve poter essere disattivata con il suo feature flag.

Regola:

  • se una fase produce peggioramento di findings o coverage, si rollbacka solo quella fase

Ordine finale che seguirei davvero

Step 1

  • Fase 0
  • Fase 1

Step 2

  • Fase 2
  • Fase 3

Step 3

  • Fase 4

Step 4

  • Fase 5
  • Fase 6

Step 5

  • Fase 7
  • Fase 8

Step 6

  • Fase 9
  • Fase 10 opzionale

Decisione pratica

Se tu mi dicessi di procedere per davvero, io partirei con questo pacchetto iniziale:

  1. metriche complete
  2. loop hardening
  3. split boilerplate
  4. max-turn budgets

Questo pacchetto, da solo, è quello che considero il miglior punto di equilibrio tra:

  • impatto alto
  • rischio basso
  • trasparenza metodologica quasi totale

La decomposizione delle skill la farei subito dopo, ma solo una alla volta e partendo da test-injection.

In una frase

Il piano che seguirei non prova a rendere il pentest "più corto"; prova a rendere molto più efficiente tutto ciò che succede prima, attorno e tra i momenti in cui Opus fa il lavoro veramente ad alto valore.