Skip to content

Naming Conventions

code specs/code/naming.kmd

Convenções de naming cross-linguagem da Koder Stack: variables/funcs per idiom da linguagem, classes/types sempre PascalCase, constantes SCREAMING_SNAKE_CASE, files snake_case (códigos) ou kebab-case (.kmd), acronyms tratados como palavra (HttpClient não HTTPClient), booleans com prefixo is_/has_/can_/should_. Cross-language exceptions documentadas.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — Naming Conventions

Facet Code do Koder Design.

Pra naming de binários/CLI ver binaries-and-cli/naming.kmd (k<slug> em CLI, paths /opt/koder/<slug>/, etc.).

Pra naming de produtos/marcas ver naming/brand-score.kmd.

Princípio cross-cutting

Cada linguagem tem o seu idiom nativo que a comunidade respeita — forçar uniformidade total atrapalha quem lê. A Koder respeita o idiom da linguagem para identificadores in-source, MAS uniformiza:

  • Classes/Types: sempre PascalCase
  • Constants: sempre SCREAMING_SNAKE_CASE
  • Files: snake_case pra código, kebab-case pra docs
  • Acronyms: tratados como palavra (HttpClient não HTTPClient)
  • Booleans: prefixo semântico

Tabela cross-linguagem

CategoriaKodaGoDartPythonRustJS/TSSQLShell
Variável localsnake_casecamelCasecamelCasesnake_casesnake_casecamelCasesnake_casesnake_case
Variável global/modulesnake_casePascalCase (export) / camelCase (priv)camelCasesnake_casesnake_casecamelCasesnake_casesnake_case
Functionsnake_casePascalCase (export) / camelCase (priv)camelCasesnake_casesnake_casecamelCasen/asnake_case
Class/Type/StructPascalCasePascalCasePascalCasePascalCasePascalCasePascalCasen/an/a
Interface/Trait/ProtocolPascalCasePascalCase (sufixo er opcional: Reader)PascalCasePascalCasePascalCasePascalCasen/an/a
ConstantSCREAMING_SNAKE_CASEPascalCase (Go idiom override OK)kCamelCase (Dart idiom) ou SCREAMING_SNAKESCREAMING_SNAKE_CASESCREAMING_SNAKE_CASESCREAMING_SNAKE_CASEUPPERCASESCREAMING_SNAKE_CASE
Enum valuePascalCasePascalCasecamelCase (Dart idiom)SCREAMING_SNAKE_CASEPascalCasePascalCasen/an/a
Module/Packagesnake_caselowercase (sem _)snake_casesnake_casesnake_casekebab-case (npm) ou camelCasen/asnake_case
File de códigosnake_case.<ext>snake_case.gosnake_case.dartsnake_case.pysnake_case.rssnake_case.ts ou kebab-case.tssnake_case.sqlsnake_case.sh
Test file<name>_test.<ext> ou test_<name>.py (idiom da linguagem)
Doc filekebab-case.kmd ou kebab-case.md

Override Go: Go usa case pra controle de visibilidade (PascalCase = exported, camelCase = unexported). A Koder respeita isso — não tenta forçar snake_case que quebraria compilação.

R1 — Acronyms tratados como palavra

❌ Errado✅ Certo
HTTPClientHttpClient
URLParserUrlParser
IDTokenIdToken
XMLDocumentXmlDocument
parseJSONparseJson
userIDuserId
koderIDkoderId

Vale pra todas as linguagens. Acronym de 2 letras também (Id, não ID).

Exceção rara: nomes oficiais de arquivos/protocolos onde "URL" aparece em string literal ("URL" em config) — a string fica como está; só o identificador segue R1.

R2 — Boolean naming

Booleans (variáveis, retornos, flags) devem ter prefixo semântico:

PrefixoSignificado
is_Estado atual: is_active, is_dirty, is_authenticated
has_Posse/inclusão: has_children, has_permission
can_Capacidade: can_edit, can_delete
should_Decisão/política: should_retry, should_redirect
was_Estado passado: was_modified, was_seen
will_Futuro próximo: will_expire, will_redirect

Negação não usa not_ ou no_ — usar a forma positiva e negar no uso: is_active = false em vez de is_inactive = true.

R3 — Naming verbs vs nouns

TipoConvenção
FunctionVerb phrase: get_user, compute_total, send_email
Boolean functionis_*/has_*/can_*/should_* (mesmo critério de var)
Class/TypeNoun: User, OrderSummary, EmailValidator
Interface/TraitAdjective ou -er: Comparable, Reader, Serializable
ConstantNoun: MAX_RETRIES, DEFAULT_TIMEOUT_SECONDS
EnumSingular noun: Status (não Statuses); values são noun: Active, Pending

R4 — Tamanho

  • Local var em escopo curto (≤10 linhas): pode ser curto (i, n, err)
  • Local var em escopo longo: nome completo (item_count)
  • Module/global: sempre nome completo
  • Function arg: nome completo, exceto receivers Go (r *Repo), iteradores funcionais (x), ou matemática (a, b)
  • Não abreviar arbitrariamente: usr ❌, user ✅; cfg ❌, config
  • Abreviações canônicas aceitas (lista fechada): id, ip, url, db, api, cli, tui, ui, ux, ai, ml, os, vm, kv, js, ts, http, ssh, tls, dns, oidc, pat, sdk, lhs/rhs

R5 — Plurais

Coleções no plural; itens no singular:

users = []         # lista
for user in users  # item

Mapas: users_by_id, count_by_status, etc. (sufixo _by_<key>).

R6 — Negação dupla proibida

not_disabled = true   # ❌
enabled = true        # ✅

R7 — Filenames

  • Código: snake_case.<ext> em todas as linguagens, exceto onde o ecosistema impõe outra convenção (npm kebab-case aceito; Dart exige snake_case por package convention)
  • Docs (.kmd/.md): kebab-case.kmd
  • Config (.toml/.yaml): snake_case ou kebab-case (consistência por projeto)

R8 — Reserved prefixes/sufixes Koder

Identificadores começando com koder_*, kode_*, k_*, _rt_* (runtime), ou terminados em _kmd são reservados a infra Koder. Não usar pra user code dentro de produtos.

Audit (deterministic)

naming-audit.sh (a criar em ticket follow-up) verifica via tree-sitter:

  1. Class/Type/Struct → PascalCase
  2. Constants → SCREAMING_SNAKE_CASE
  3. Acronyms → tratados como palavra (regex)
  4. Booleans → prefixo semântico
  5. Filenames → snake_case ou kebab-case (per-tipo)
  6. No reserved prefix conflict

Severidade medium: warning não-bloqueante por enquanto (linguagem em si pode forçar idiom). Migrar pra hard quando coverage estiver alta o suficiente.

  • code/indentation.kmd — formatação irmã
  • code/languages/<lang>-style.kmd — overrides per-linguagem
  • binaries-and-cli/naming.kmd — naming de surfaces externas
  • naming/brand-score.kmd — naming de produtos/marcas
  • policies/design-governance.kmd

References