Tenho visto uma enxurrada de ‘arquivos de regras’ para IAs nas redes, focados em performance e redução de alucinações. Mas e para os humanos do time?

Diferente dos agentes, nós não inferimos padrões instantaneamente. Pelo contrário: gastamos energia cognitiva refletindo sobre detalhes triviais, como a formatação de um if ou um loop, o que cumulativamente leva à fadiga de decisão. Para piorar, muitas vezes ignoramos os padrões por perguiça. Um comportamento que, curiosamente, estudos recententes indicam que as IAs também aprenderam.

Nós, desenvolvedores humanos, não temos a mesma capacidade e velocidade de inferência de padrões que um agente de IA. Além de termos a tendência de refletir sobre pequenas questões como usar ou não chaves em determinado ponto, o que leva a fadiga de decisão. Outra tendência que nós temos, é de deixar de seguir alguns padrões por preguiça (o que parece não ser exclusividade nossa, alguns papers recentes mostram que a IA também).

.editorconfig - Fácil de usar e os seus agentes também vão agradecer

Mais do que regras de estilo, este arquivo economiza tokens e provê contexto implícito. O fato do .editorconfig ser consumido nativamente por linters e IDEs permite mover regras que estariam em wikis desatualizadas, em prompts de sistema ou, mais provavelmente, em lugar nenhum, para um local centralizado e com feedback instantâneo.

Por definir práticas globais de código, a manutenção é baixíssima (necessária apenas quando a linguagem ganha novas features). Como raramente exige exceções por projeto, criar um template padrão para a organização é a melhor estratégia para evitar retrabalho e unificar o estilo do codebase.

A compatibilidade é universal: funciona nativamente na maioria das IDEs ou via plugins. Você pode conferir a lista completa de suporte no site oficial.

Mas, embora seja agnóstico a linguagens, é no ecossistema .NET que essa especificação ganha superpoderes.

Análise estática com Roslyn

Na maioria das linguagens, a aplicação do .editorconfig se limita a quebras de linhas, usar espaços no lugar de tab, níveis de indentação e itens mais simples, no .NET podemos controlar os Roslyn Analyzers, transformando sugestões em regras rígidas de código.

Assim, garantimos que os analisadores estão configurados de maneira uniforme para o time.

Dois links que valem a pena visitar:

  1. Documentação dos analisadores de código do .NET
  2. Seção específica para .editorconfig

O padrão ouro dos .editorconfigs - Repositório do AspNetCore

Para desenvolvedores .Net, a melhor a opção é começar com o arquivo do projeto do aspnetcore e adicionar regras conforme o necessário. Você pode baixar o editorconfig no GitHub do projeto: https://github.com/dotnet/aspnetcore/blob/main/.editorconfig.

Algumas das regras já contidas no arquivo

  • File scoped namespaces
  • Uso exclusivo de var para declaração de variáveis
  • Proibição de this e fields internos/privados em _camelCase
  • Proibição de múltiplas quebras de linhas consecutivas
  • Algumas boas práticas para Exceptions

Nada revolucionário ou que integre profundamente no seu codebase, mas já garante boas regras de estética para os desenvolvedores e agentes.

Algumas regras que costumo adicionar ao arquivo O arquivo do time do AspNetCore não usa muitas regras experimentais, então costumo complementar com as seguintes:

RegraEfeito
csharp_style_allow_embedded_statements_on_same_line_experimental = falseProíbe if(true) return; na mesma linha
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = falseRemove linhas vazias entre chaves }}
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = falseRemove linha vazia após : no construtor da classe base
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = falseEvita quebras estranhas dentro de ternários ? :
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = falseRemove espaço vertical excessivo em Expression Bodies =>

Nota
Quando falamos em linhas vazias, é bom esclarecer:

if (something)
{
    {
        DoStuff();
    }
} // Correto, não é linha vazia
if (something)
{
    {
        DoStuff();
    }

} // ERRADO, aqui sim temos uma linha vazia e desnecessária
if (something)
{
    {
        DoStuff();
    }} // ERRADO, aqui a quebra é obrigatória e ajuda na interpretação.
       // Mas a regra quebrada é outra.

Garantindo o seguimento das regras

Warnings de compilador são facilmente ignorados quando o prazo aperta (o famoso “depois eu arrumo”). Para garantir que o projeto continue limpo, precisamos de algumas travas.

TreatWarningsAsErrors: A inclusão desta tag, trata os avisos gerados com nível igual ou maior a Warning como erro. O problema que temos aqui é que ela vem desabilitada por padrão e tem que ser configurada projeto a projeto. O que podemos corrigir com:

Directory.Build.props: Tanto para os warnings quanto para quaisquer configurações que desejemos ter em todos os projetos da solução, podemos criar um arquivo Directory.Build.props na raiz e popular com estas propriedades. Por exemplo:

<Project>
  <PropertyGroup>
    <TreatWarningsAsErrors>True</TreatWarningsAsErrors>
    <Copyright>João Bateloche</Copyright>
  </PropertyGroup>
</Project>

Pre-commit hooks: Usando Husky ou qualquer outra ferramenta do tipo, conseguimos impedir que o código fora de padrão chegue ao repositório. A vantagem aqui, é que este pode ser o início de uma suíte mais interessante que pode passar a incluir outros passos como Sonar e varredura por secrets.

Concluindo

Não se trata apenas de regras ou contexto, mas de carga cognitiva. Nós lemos mais facilmente códigos com estrutura uniforme e regras padronizadas. Porém, temos dificuldade natural de manter esse padrão sem a ajuda de alguns guardrails.

O .editorconfig há muito tempo virou um dos primeiros arquivos que crio em qualquer projeto novo, e o fato de termos agora agentes de IA trabalhando no mesmo repositório torna sua utilização não apenas uma boa prática, mas um requisito essencial.