ConstructiCat Logo
CodeBust.
Browse section ▾

Nomenclatura Cega ao Contexto.

Um assistente de IA nomeia código novo com placeholders genéricos ou uma convenção nova que ignora os identificadores existentes e o vocabulário do domínio do repositório, corroendo a legibilidade e gerando conceitos duplicados e mal descritos.

##Signs and Symptoms

Um revisor identifica Nomenclatura Cega ao Contexto quando os nomes em um diff de autoria da IA são localmente plausíveis, mas desconectados do repositório ao redor. Sinais reveladores:

  • Placeholders genéricos em código de domínio: data, result, temp, item, obj, payload, response, value, handleStuff, processData onde o módulo já fala uma linguagem específica (grossPremium, Customer, getCustomerById).
  • Deriva de convenções: um símbolo snake_case jogado em um arquivo camelCase, um prefixo booleano is/has ausente, ou um novo verbo CRUD (fetch*) em uma base de código que padronizou em get*. Cada diff "segue qualquer que seja o estilo que encontrou por último, introduzindo uma quarta convenção. E então uma quinta."
  • Proliferação de sinônimos / conceitos duplicados: a IA inventa fetchUser quando getCustomerById já existe, ou mistura customer/client/user para uma única entidade — reimplementando em vez de reutilizar.
  • Nomes que descrevem o mecanismo, não a intenção — ou que mentem sobre o comportamento: processData() que na verdade calcula imposto sobre vendas. Os agentes (e o próximo agente) "leem processData() e prosseguem como se aquele nome contasse toda a história", então o significado errado se propaga para cada ponto de chamada.
// O repositório já exporta getCustomerById(id: CustomerId): Promise<Customer>
// A IA adiciona uma quase-duplicata com nomes cegos ao contexto:
async function fetchData(id: string) {          // verbo genérico, tipo frouxo
  const result = await db.query("select * from customers where id = $1", [id]);
  const temp = result.rows[0];                  // 'temp' esconde que é um Customer
  return temp;                                  // nada aqui diz "Customer"
}

##Reasons for the Problem

Por que os modelos a produzem

  • Viés de frequência do próximo token. Em todo o corpus de treinamento, data/result/temp/foo são os identificadores de maior probabilidade, especialmente no código de tutorial e boilerplate que os LLMs ingerem intensamente. Gerar o nome estatisticamente médio é exatamente o que um preditor de próximo token é otimizado para fazer, o que apaga a intenção do domínio (Towards Data Science).
  • Sem contexto do repositório (ou truncado). O modelo raramente vê o glossário do módulo irmão ou o getCustomerById existente. A GitClear liga o aumento de duplicação diretamente a isso: o assistente "tem menos probabilidade de propor reutilizar uma função similar em outro lugar... em parte por causa do tamanho de contexto limitado" (GitClear 2025).
  • Otimização local / instinto fraco de refatoração. Cada turno otimiza o prompt imediato, "sem considerar o impacto arquitetural cumulativo". A OX Security encontrou Evitação de Refatorações em 80–90% do código de IA, então o modelo adiciona um símbolo recém-nomeado em vez de renomear ou reutilizar um existente (relatório OX).
  • Defasagem do corte de treinamento. Convenções e nomes de API de corpora mais antigos ressurgem mesmo depois que um projeto já seguiu em frente.

Por que isso prejudica

  • Legibilidade/manutenibilidade: nomes são a principal documentação de uma base de código; os genéricos forçam cada leitor a rederivar a intenção a partir do corpo.
  • Duplicação e defeitos: renomear um conceito gera uma implementação paralela. A GitClear mediu um aumento de ~8x em blocos duplicados e o copy/paste ultrapassando as linhas movidas (refatoradas) pela primeira vez em 2024; clones carregam um número estimado de 15–50% mais defeitos.
  • Loop de feedback de agentes (o dano específico de IA): nomes são a interface que o próximo agente lê ao pé da letra. Um nome enganoso ou genérico "propaga erros por todo o código gerado por agentes que se baseia nele" (AI Pattern Book).
  • Carga de revisão & correção: os revisores precisam mapear mentalmente temp/data de volta a conceitos de domínio, o que esconde bugs; nomes enganosos causam uso incorreto nos pontos de chamada.
  • Pontos cegos de segurança/auditoria: um segredo ou token estacionado em uma variável chamada data/tmp escapa de greps baseados em nomes e da atenção da revisão.

Observação: pesquisas como a arXiv 2509.20491 mostram que ferramentas estáticas capturam bem smells locais e explícitos, mas a faceta de significado de domínio aqui depende de valor/intenção e escapa em grande parte da detecção automatizada.

##Treatment

Táticas de revisão & prompting

  • Alimente as convenções e o glossário no contexto. Mantenha um guia de nomenclatura curto (casing, prefixos booleanos, verbos CRUD, termos de domínio) em CLAUDE.md/docs de estilo e exija que o modelo o siga. Aplique os termos do glossário de domínio de forma consistente para que os sinônimos colapsem em uma única palavra.
  • Force a reutilização antes da criação. Prompt: "Procure no repositório por uma função/tipo existente para isto antes de adicionar uma nova; reutilize-a." Isso combate diretamente a falha de conceito duplicado que a GitClear e a OX sinalizam.
  • Nomeie as coisas no prompt. "Nomeie o handler como createRefund" é melhor do que "adicione processamento de reembolso". Especifique nomes de domínio (monthlyRevenue, não float1).
  • Exija que o linter + a varredura de duplicação rodem no diff (naming-convention + id-denylist + jscpd) e faça o modelo corrigir as violações em vez de você fazê-lo à mão.

A refatoração — aplique Renomear Variável/Função ("Mudar Declaração de Função" de Fowler), corrigindo o smell Nome Misterioso, e Consolidar Código Duplicado reutilizando o símbolo existente em vez do novo.

Antes:

async function fetchData(id: string) {
  const result = await db.query("select * from customers where id = $1", [id]);
  const temp = result.rows[0];
  return temp;
}

Depois (reutilize a função de repositório existente; nomes e tipos que revelam a intenção e respeitam a convenção):

// Não consulte de novo — reutilize getCustomerById e mantenha o vocabulário do domínio.
async function getCustomerById(id: CustomerId): Promise<Customer | null> {
  const { rows } = await db.query<Customer>(
    "select * from customers where id = $1",
    [id],
  );
  return rows[0] ?? null;
}

Se um nome enganoso já foi entregue, renomeie-o para corresponder ao comportamento (processDatacalculateSalesTax) antes de construir em cima dele, para que agentes e humanos a jusante herdem o sinal correto.

##Detected by

  • ESLint (core) id-denylistProíbe identificadores especificados
  • ESLint (core) id-lengthImpõe comprimento mínimo/máximo de identificador
  • typescript-eslint @typescript-eslint/naming-conventionImpõe convenções de nomenclatura (casing/prefixos)
  • eslint-plugin-unicorn unicorn/prevent-abbreviationsPrevine abreviações / nomes excessivamente genéricos
  • SonarQube / SonarSource typescript:S117Nomes de variáveis locais e parâmetros devem obedecer a uma convenção de nomenclatura
  • jscpd copy-paste-detectionDetecta blocos duplicados criados quando um conceito renomeado duplica um existente