Skip to content

plano: expandir proptest/fuzzing escopado + lint de struct-initializer + matriz de invocação headless em CI #68

Description

@wesleysimplicio

Contexto

Segue diretamente de #67 e do hub cross-repo simplicio-loop#579. O framework de DoD escopado (DOD.md, adicionado nesta sessão) e o primeiro property test (crates/codegen/simplicio-runtime-client/tests/fake_server_handshake_proptest.rs, cobrindo o handshake MCP) já implementam a base do item 1 de #67 para simplicio-runtime-client. Esta issue detalha os próximos passos concretos que ficaram fora do escopo cirúrgico daquele PR: os itens (b) e (c) de #67, mais a extensão de (a) para o resto do escopo genuinamente Simplicio.

Motivação (recapitulando #67): 3 bugs reais encontrados nesta sessão no escopo genuinamente Simplicio — code#63 (rede no build sem fallback), code#64 (search_backend construído e descartado do struct-literal de AgentRebuildSpec), code#66 (--always-approve trava indefinidamente em modo headless).

Plano passo a passo

(a) Expandir proptest/fuzzing — só nos crates genuinamente Simplicio

Escopo confirmado em DOD.md: crates/codegen/simplicio-runtime-client, crates/codegen/xai-grok-models, lógica de permissão/aprovação headless. Fora de escopo: a árvore xai-grok-*/xai-acp-* herdada (66+ crates upstream).

  1. simplicio-runtime-client — já tem o property test de handshake (esta sessão). Próximo: um segundo property test para secure_relative_path/secure_glob (as funções de sandbox/path-escape) — gerar combinações de segmentos ../, paths absolutos, símbolos Windows (C:\), unicode/paths mistos /+\, e verificar que a função nunca deixa escapar do repo (nunca retorna Ok para um path fora de repo). Essas funções já têm testes por exemplo; fuzzing generalizaria a garantia de sandbox que é o ponto mais crítico do crate.
  2. xai-grok-models — inspecionar crates/codegen/xai-grok-models/src/lib.rs (196 linhas) e identificar qualquer função de parsing/validação de config de modelo (ex. resolução de aliases, parsing de tencent/hy3:free, seleção de provider) que mereça um property test equivalente.
  3. Lógica de permissão/aprovação headless — hoje vive espalhada entre xai-grok-pager/xai-grok-shell (flags --always-approve, --permission-mode). Depois que code#66 fechar (correção em andamento nesta sessão numa branch separada), adicionar um property test ou pelo menos uma tabela de casos exaustiva cobrindo toda combinação {--always-approve, --permission-mode=*} × {-p, posicional} × {tty, sem tty} contra o dispatch de aprovação, para travar a classe de bug que code#66 é (duas flags documentadas como equivalentes divergindo silenciosamente).

(b) Lint customizado — pegar "campo construído, nunca passado ao struct"

Proposto originalmente em #67 item 2. Abordagem sugerida (grep-based, sem exigir plugin de clippy):

  1. Script scripts/check-unused-struct-locals.sh (ou .py) que, para cada .rs sob o escopo Simplicio (mesma lista de DOD.md), varre funções que:
    • declaram uma let <nome> = ...; (variável local simples, não _-prefixada), E
    • depois, dentro do mesmo bloco de função, constroem um struct-literal (SomeStruct { ... }) que não referencia <nome> em nenhum campo (nem por shorthand nome, nem por campo: nome / campo: nome.clone()/Some(nome...)),
    • reporta como candidato a revisão manual (não é 100% preciso — variáveis legitimamente não usadas no struct são comuns — então o script deve ser um relatório de candidatos para revisão humana em PR, não um gate hard-fail automático inicialmente).
  2. Rodar o script como um step não-bloqueante em .github/workflows/ci.yml (comentário informativo no PR, não falha o build), pelo menos até calibrar a taxa de falso-positivo em algumas rodadas contra o histórico do repo (git log dos últimos commits que tocaram struct literals).
  3. Se a taxa de falso-positivo for baixa o suficiente após calibração, promover a hard-fail scoped aos crates Simplicio (nunca à árvore xai-grok-* herdada).
  4. Alternativa mais barata caso o grep-based prove ruidoso demais: adicionar #[deny(dead_code)]/#[warn(unused_variables)] mais agressivo já cobre parte disso via o compilador quando a variável realmente não é usada em lugar nenhum — mas o bug code#64 especificamente tinha a variável usada (só não nesse struct-literal específico), então o lint do compilador não pega; documentar essa limitação explicitamente se a alternativa mais barata for escolhida em vez do script.

(c) Matriz de modos de invocação em CI — o gate que pegaria code#66

  1. Novo job em .github/workflows/ci.yml (ou workflow dedicado invocation-matrix.yml) que roda simplicio-code (ou o binário xai-grok-pager-bin) contra uma matriz cruzando:
    • modo de prompt: -p "ping" vs. posicional ("ping" sem -p);
    • presença de TTY: dentro de script -qec "..." (pty real) vs. execução direta (sem pty — já documentado em code#66 como falhando com os error 6, então esse cruzamento específico é esperado falhar de forma rápida e com mensagem clara, não travar);
    • --permission-mode (bypassPermissions, outros valores documentados) vs. --always-approve;
    • cada combinação com timeout <N> curto (ex. 15-20s) e asserção de que o processo termina (sucesso OU erro rápido e claro) — nunca trava até o timeout externo matar.
  2. Requer um provider/modelo mockável ou um modo --check/dry-run que não precise de OPENROUTER_API_KEY real em CI — investigar se simplicio-code já tem esse modo (ver docs/ e --help) antes de decidir se o job precisa de um secret de CI real ou consegue rodar 100% offline/mockado.
  3. Este job teria pego code#66 diretamente: a combinação --always-approve + posicional + pty real é exatamente a que trava; qualquer combinação que trave até o timeout externo falha o job com um log claro de qual combinação travou, em vez de exigir que alguém tropece nisso manualmente rodando um benchmark real.

Referências

  • #67 — proposta original, itens (a)/(b)/(c)/(d) fonte deste plano.
  • simplicio-loop#579 — hub cross-repo, motivação completa dos 2 bugs achados em outros repos que geraram a rodada de issues irmãs.
  • code#63, code#64, code#66 — os 3 bugs reais motivadores citados em DOD.md.
  • DOD.md (raiz do repo, adicionado junto com esta issue) — escopo dos 4 gates e do que fica fora.
  • crates/codegen/simplicio-runtime-client/tests/fake_server_handshake_proptest.rs — primeiro property test já implementado (parte de (a) para este crate).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions