Spaces:
Runtime error
Runtime error
Tales-Cunha commited on
Commit ·
59372df
1
Parent(s): 4e2e30e
docs: create tester development history
Browse files- Historico_Desenvolvimento_Tester.md +57 -0
- data/benchmark_summary.json +18 -66
Historico_Desenvolvimento_Tester.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Histórico de Desenvolvimento: Agente Tester
|
| 2 |
+
|
| 3 |
+
Este documento consolida a evolução da arquitetura do **Agente Gerador de PoCs (Tester)**, mapeando como ele evoluiu de um simples gerador de código para um agente autônomo complexo.
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## v1.0 - Implementação Base e Grafo Linear
|
| 8 |
+
* **Commits base:** `b6cd2805`, `21e1e333`
|
| 9 |
+
* **Arquitetura Inicial:** O agente foi concebido como um simples StateGraph linear. Ele recebia o relatório do Auditor, passava para um LLM que gerava o código do teste (`generatePoCNode`), e retornava o código.
|
| 10 |
+
* **Limitações:** Não havia execução real do código, logo, a maior parte dos testes gerados falhava por erros de sintaxe ou de importação se fossem rodados na vida real.
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
## v2.0 - O Oráculo e Execução em Loop
|
| 15 |
+
* **Commits base:** `0adaeb16`, `29b9e2b4`
|
| 16 |
+
* **Introdução do Oráculo (`oracleNode`):** Criamos a primeira versão do Oráculo, responsável por pré-processar o contrato alvo e criar um "Scaffold" (um esqueleto do arquivo de teste com a função `setUp()` e assinaturas de deploy corretas).
|
| 17 |
+
* **O Loop Foundry (`runFoundryNode` & `reflectNode`):** O agente deixou de ser "one-shot" e passou a rodar em loop. O código gerado era salvo em um ambiente isolado (sandbox), executado via `forge test`, e a saída bruta era devolvida ao LLM caso o teste falhasse.
|
| 18 |
+
* **Prompts:** Nesta fase, havia essencialmente um único prompt genérico: "Escreva o teste. Se falhar, conserte baseado no erro".
|
| 19 |
+
* **Resultados Iniciais no Benchmark:** Ao testar no dataset real, o agente não passava de **27%** de sucesso. A maior parte das falhas ocorria porque o LLM ficava preso em um loop infinito tentando consertar erros de `File not found` (dependências faltando) repetindo o mesmo erro.
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## v3.0 - Roteamento de Erros e Minimal Interface
|
| 24 |
+
* **Commits base:** `1929f1bf`
|
| 25 |
+
* **Evolução do Prompt:** Percebeu-se que pedir para o LLM "consertar o erro" sem contexto não funcionava. O `generatePoCNode` foi reescrito para utilizar diferentes "modos de prompt" dependendo do tipo de falha detectada pelo `logAnalyzer`.
|
| 26 |
+
* **`INITIAL`**: Cria o teste.
|
| 27 |
+
* **`FIX_COMPILE`**: Prompt focado estritamente em resolver erros de sintaxe e dependência.
|
| 28 |
+
* **`FIX_LOGIC`**: Prompt focado em resolver reverts na EVM (`assert` falhando, `setUp` incorreto). Foram adicionados padrões comuns (ex: avisar ao LLM sobre callbacks de reentrância ou a necessidade de checar retornos boleanos).
|
| 29 |
+
* **Escape Hatch (`MINIMAL_INTERFACE`):** A maior inovação desta versão. Se o agente detectasse 3 falhas seguidas de compilação, ele ativava este modo. O prompt instruía o LLM a apagar *todos* os imports de repositório e injetar interfaces `interface IERC20 {...}` cruas diretamente no arquivo.
|
| 30 |
+
* **Resultado:** O agente quebrou o platô e saltou para **45%** de sucesso, provando que contornar erros de compilação era a chave.
|
| 31 |
+
|
| 32 |
+
---
|
| 33 |
+
|
| 34 |
+
## v4.0 - Contexto de Repositório e Dependency Stubbing
|
| 35 |
+
* **Commits base:** `4b0ab735`
|
| 36 |
+
* **O Problema da Especificidade:** Observamos que o agente tinha **0% de Specificity Rate** no benchmark. Descobriu-se que o script bash não estava aplicando o patch de correção corretamente no repositório. Criamos a função `applyPatchSmart` para corrigir isso, e passamos o `patchDiff` real para o LLM.
|
| 37 |
+
* **O Problema do Contexto Cego:** O agente estava falhando em projetos complexos porque usava imports incorretos.
|
| 38 |
+
* Criamos o **`projectContextExtractor`**: Ele usa BFS para varrer o projeto, extrai o `remappings.txt` e encontra arquivos de teste existentes para ensinar ao LLM o "padrão de importação" correto daquele repositório.
|
| 39 |
+
* **O Problema das Bibliotecas Ausentes:** Muitos projetos falhavam porque tentavam importar pacotes do NPM (como `@openzeppelin`) que não existiam na sandbox.
|
| 40 |
+
* Criamos o **`dependencyStubber`**: Antes de escrever o teste, o agente roda um `forge build` falso. O compilador reclama das bibliotecas faltando, e o Stubber escreve automaticamente arquivos falsos `.sol` (Stubs) contendo contratos/interfaces vazias apenas para satisfazer o compilador.
|
| 41 |
+
* **Limpeza da Sandbox:** Adicionado mecanismo para deletar testes antigos do projeto (`.t.sol`) que davam conflito com o nosso gerador.
|
| 42 |
+
* **Resultado:** A taxa de sucesso global subiu para incríveis **54.5%**.
|
| 43 |
+
|
| 44 |
+
---
|
| 45 |
+
|
| 46 |
+
## v5.0 - Alinhamento com Produção (Fechando o Gap)
|
| 47 |
+
* **Commits base:** `b77ea464`
|
| 48 |
+
* **O Problema:** Todas as melhorias incríveis da V4 rodavam perfeitamente no *Benchmark*, mas não eram utilizadas na vida real (`server.ts`), pois a API não transferia os dados da auditoria para o testador.
|
| 49 |
+
* **A Correção:**
|
| 50 |
+
* O mapeador `mapFindingToReport` foi reescrito para incluir todo o texto do *Judge Review*, as recomendações de correção e as trilhas de ataque passo-a-passo no relatório que vai para o Tester.
|
| 51 |
+
* O `server.ts` passou a fornecer o contexto estrutural do projeto (`repoContext`) e apontar o testador para usar a pasta real (`customSandboxDir`) onde o código foi salvo.
|
| 52 |
+
* **Resultado:** O pipeline de Produção e o Benchmark foram perfeitamente sincronizados.
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## Próximos Passos (v6.0 Planejada)
|
| 57 |
+
* **LLM Routing / Multi-Model Cascade:** Dividir a execução entre LLMs. Utilizar um modelo potente (`gemini-2.5-pro` ou equivalente) apenas para o `analyzeVulnerabilityNode` e o `INITIAL` generation, economizando créditos nos loops de `FIX_COMPILE` que serão roteados para modelos menores, rápidos e baratos (como o `gemini-3.1-flash-lite`).
|
data/benchmark_summary.json
CHANGED
|
@@ -1,30 +1,18 @@
|
|
| 1 |
{
|
| 2 |
"summary": {
|
| 3 |
-
"timestamp": "2026-06-
|
| 4 |
-
"total_processed":
|
| 5 |
-
"reproducibility_rate":
|
| 6 |
-
"specificity_rate":
|
| 7 |
-
"overall_ground_truth_rate":
|
| 8 |
-
"average_iterations": 7.
|
| 9 |
},
|
| 10 |
"details": [
|
| 11 |
-
{
|
| 12 |
-
"id": "001",
|
| 13 |
-
"reproducible": true,
|
| 14 |
-
"specific": false,
|
| 15 |
-
"iterations": 9
|
| 16 |
-
},
|
| 17 |
-
{
|
| 18 |
-
"id": "003",
|
| 19 |
-
"reproducible": true,
|
| 20 |
-
"specific": false,
|
| 21 |
-
"iterations": 5
|
| 22 |
-
},
|
| 23 |
{
|
| 24 |
"id": "008",
|
| 25 |
"reproducible": true,
|
| 26 |
"specific": false,
|
| 27 |
-
"iterations":
|
| 28 |
},
|
| 29 |
{
|
| 30 |
"id": "009",
|
|
@@ -32,12 +20,6 @@
|
|
| 32 |
"specific": false,
|
| 33 |
"iterations": 10
|
| 34 |
},
|
| 35 |
-
{
|
| 36 |
-
"id": "015",
|
| 37 |
-
"reproducible": true,
|
| 38 |
-
"specific": false,
|
| 39 |
-
"iterations": 5
|
| 40 |
-
},
|
| 41 |
{
|
| 42 |
"id": "018",
|
| 43 |
"reproducible": false,
|
|
@@ -64,15 +46,15 @@
|
|
| 64 |
},
|
| 65 |
{
|
| 66 |
"id": "039",
|
| 67 |
-
"reproducible":
|
| 68 |
"specific": false,
|
| 69 |
-
"iterations":
|
| 70 |
},
|
| 71 |
{
|
| 72 |
"id": "041",
|
| 73 |
-
"reproducible":
|
| 74 |
"specific": false,
|
| 75 |
-
"iterations":
|
| 76 |
},
|
| 77 |
{
|
| 78 |
"id": "042",
|
|
@@ -80,6 +62,12 @@
|
|
| 80 |
"specific": false,
|
| 81 |
"iterations": 10
|
| 82 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
{
|
| 84 |
"id": "048",
|
| 85 |
"reproducible": false,
|
|
@@ -92,52 +80,16 @@
|
|
| 92 |
"specific": false,
|
| 93 |
"iterations": 10
|
| 94 |
},
|
| 95 |
-
{
|
| 96 |
-
"id": "051",
|
| 97 |
-
"reproducible": true,
|
| 98 |
-
"specific": false,
|
| 99 |
-
"iterations": 2
|
| 100 |
-
},
|
| 101 |
-
{
|
| 102 |
-
"id": "054",
|
| 103 |
-
"reproducible": true,
|
| 104 |
-
"specific": false,
|
| 105 |
-
"iterations": 7
|
| 106 |
-
},
|
| 107 |
-
{
|
| 108 |
-
"id": "058",
|
| 109 |
-
"reproducible": true,
|
| 110 |
-
"specific": false,
|
| 111 |
-
"iterations": 5
|
| 112 |
-
},
|
| 113 |
-
{
|
| 114 |
-
"id": "066",
|
| 115 |
-
"reproducible": true,
|
| 116 |
-
"specific": false,
|
| 117 |
-
"iterations": 8
|
| 118 |
-
},
|
| 119 |
{
|
| 120 |
"id": "070",
|
| 121 |
"reproducible": false,
|
| 122 |
"specific": false,
|
| 123 |
"iterations": 10
|
| 124 |
},
|
| 125 |
-
{
|
| 126 |
-
"id": "077",
|
| 127 |
-
"reproducible": true,
|
| 128 |
-
"specific": false,
|
| 129 |
-
"iterations": 8
|
| 130 |
-
},
|
| 131 |
-
{
|
| 132 |
-
"id": "091",
|
| 133 |
-
"reproducible": true,
|
| 134 |
-
"specific": false,
|
| 135 |
-
"iterations": 9
|
| 136 |
-
},
|
| 137 |
{
|
| 138 |
"id": "098",
|
| 139 |
"reproducible": true,
|
| 140 |
-
"specific":
|
| 141 |
"iterations": 2
|
| 142 |
}
|
| 143 |
]
|
|
|
|
| 1 |
{
|
| 2 |
"summary": {
|
| 3 |
+
"timestamp": "2026-06-09T17:52:42.551Z",
|
| 4 |
+
"total_processed": 14,
|
| 5 |
+
"reproducibility_rate": 42.857142857142854,
|
| 6 |
+
"specificity_rate": 16.666666666666664,
|
| 7 |
+
"overall_ground_truth_rate": 7.142857142857142,
|
| 8 |
+
"average_iterations": 7.857142857142857
|
| 9 |
},
|
| 10 |
"details": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
{
|
| 12 |
"id": "008",
|
| 13 |
"reproducible": true,
|
| 14 |
"specific": false,
|
| 15 |
+
"iterations": 3
|
| 16 |
},
|
| 17 |
{
|
| 18 |
"id": "009",
|
|
|
|
| 20 |
"specific": false,
|
| 21 |
"iterations": 10
|
| 22 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
{
|
| 24 |
"id": "018",
|
| 25 |
"reproducible": false,
|
|
|
|
| 46 |
},
|
| 47 |
{
|
| 48 |
"id": "039",
|
| 49 |
+
"reproducible": true,
|
| 50 |
"specific": false,
|
| 51 |
+
"iterations": 8
|
| 52 |
},
|
| 53 |
{
|
| 54 |
"id": "041",
|
| 55 |
+
"reproducible": true,
|
| 56 |
"specific": false,
|
| 57 |
+
"iterations": 6
|
| 58 |
},
|
| 59 |
{
|
| 60 |
"id": "042",
|
|
|
|
| 62 |
"specific": false,
|
| 63 |
"iterations": 10
|
| 64 |
},
|
| 65 |
+
{
|
| 66 |
+
"id": "046",
|
| 67 |
+
"reproducible": true,
|
| 68 |
+
"specific": false,
|
| 69 |
+
"iterations": 7
|
| 70 |
+
},
|
| 71 |
{
|
| 72 |
"id": "048",
|
| 73 |
"reproducible": false,
|
|
|
|
| 80 |
"specific": false,
|
| 81 |
"iterations": 10
|
| 82 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
{
|
| 84 |
"id": "070",
|
| 85 |
"reproducible": false,
|
| 86 |
"specific": false,
|
| 87 |
"iterations": 10
|
| 88 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
{
|
| 90 |
"id": "098",
|
| 91 |
"reproducible": true,
|
| 92 |
+
"specific": true,
|
| 93 |
"iterations": 2
|
| 94 |
}
|
| 95 |
]
|