Antes de planejar qualquer teste, um sistema de QA precisa saber o que existe no alvo: quais rotas, quais funções, quais arquivos. Se essa lista muda a cada execução, tudo o que vem depois (plano, cobertura, decisão de release) é construído em areia. No QAOS, a lista é chamada de inventário, e ele não pode ser escrito por um modelo de linguagem.
Mesmo repositório, três respostas
Numa medição interna de 20 de setembro de 2026, o QAOS leu três vezes o mesmo repositório de exemplo (o petclinic, um projeto Java open source) com a enumeração feita pelo Code Reader. O modelo listou 33, 39 e 17 funções. Mesmo código, mesmo prompt, três denominadores diferentes.
O problema não era só o número. Com a lista variando, o Test Planner chegou a enviar controllers que não eram isoláveis para o teste unitário. Cobertura calculada sobre uma lista instável não é cobertura: é opinião com casas decimais.
Regra: o que o modelo escolhe listar não fixa o denominador. Quem fixa é o código.
O universo vem do Git, não do modelo
O inventário parte de git ls-files: todo arquivo versionado entra na conta. Cada um termina de duas formas, lido ou não lido com caminho e motivo fechado. O texto enviado ao modelo e o inventário saem do mesmo clone, então não há como divergirem.
Parser lê o código, modelo interpreta
Para Python, a extração usa ast. Para Java, tree-sitter-java. Em nenhum dos casos o QAOS importa ou executa o código do alvo dentro da API; ele só o analisa.
O Code Reader continua existindo, mas com outro papel: recebe referências numeradas e interpreta o que cada trecho faz. Uma guarda em código reconstrói método, caminho, assinatura, visibilidade e status a partir do parser. Se o modelo citar um endpoint ou uma função que o parser não encontrou, o item é descartado.
Antes
O modelo escolhia o que listar. A contagem variava entre execuções e o plano herdava a variação.
Agora
O parser fixa a lista. O modelo só acrescenta interpretação, e o que ele inventa é descartado.
Arquivo não lido tem motivo
Nem todo arquivo vale ser enviado ao modelo: lockfiles, licenças, código gerado e arquivos enormes só gastam contexto. Mas “deixar de fora” não pode significar “esquecer”. Esses arquivos continuam no inventário, marcados como não lidos, com um motivo de uma lista fechada: por exemplo asset, lockfile, licenca, gerado ou acima-de-500kb. A decisão sai só do caminho no índice, sem abrir o arquivo.
O inventário também publica o commit e um digest do estado analisado. Dois inventários só são comparáveis se o formato for o mesmo, e o sistema versiona isso.
Quem confere o inventário
Um script verificador independente, fora do caminho principal, confere o JSON contra o Git, contra um segundo parser Python (tree-sitter-python), contra o bytecode Java (javap) e contra as rotas do framework quando há referências disponíveis. O bytecode ficou de fora do produto de propósito: obrigaria a API a compilar o alvo, com JDK, dependências e rede.
O mesmo critério vale para medir estabilidade. O comparador do portão de qualidade exige inventário disponível e igual nas três execuções; o que variar de interpretação aparece como dispersão, não como acordo.
Limites que o sistema declara
- Autenticação e pureza de uma função continuam sendo interpretação do modelo, e são rotuladas assim onde aparecem.
- O formato de resposta de um endpoint fica nulo nas stacks com parser: uma linha literal não prova a semântica do formato.
- Stacks sem parser usam a origem
modeloe declaram que a garantia de inventário determinístico não existe ali.
É a mesma regra do resto do produto: onde não há fato, o sistema diz que não há.
Quer ver o QAOS rodando no seu sistema? Conte o seu cenário e a gente mostra o fluxo completo.
Falar com a NoirCode ↗