Code Comments

code specs/code/comments.kmd

Filosofia e regras de comentários cross-language: WHY-not-WHAT por default; comentário só quando o motivo é não-óbvio; doc comments per-lang com formato canônico; TODO/FIXME/HACK com handle + ticket; commented-out code proibido; license header quando aplicável; module docstring quando obrigatório. Anti-patterns enumerados.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — Code Comments

Facet Code do Koder Design.

Codifica formalmente a regra global do CLAUDE.md ("default to no comments") como spec auditável + estende com formato per-lang, doc styles, TODO conventions e anti-patterns.

Filosofia: WHY-not-WHAT

Default: não escrever comentário. Identificadores bem nomeados (per code/naming.kmd) + funções curtas (per code/functions.kmd) são a documentação primária do que o código faz.

Escrever comentário só quando:

  • Esconde-se um WHY não-óbvio (constraint de negócio, invariante sutil, workaround por bug específico, comportamento que surpreende)
  • O comportamento depende de algo fora do arquivo (spec externa, protocolo de terceiros, RFC, ticket de incidente)
  • A escolha entre alternativas igualmente válidas precisa de justificativa pra evitar refactor inútil futuro

Não escrever comentário quando:

  • Apenas repete o nome do identificador (# increment counter em cima de counter += 1)
  • Descreve o WHAT que já é óbvio do código
  • Referencia o "task atual"/"este fix"/"caller X" — isso pertence à PR description, não ao código (commit message + git blame preservam a referência sem rotação)
  • Marca código removido (# was: foo()) — git history tem isso

Exemplos

# ❌ Comenta o WHAT óbvio
# increment retry counter
retries += 1

# ✅ Comenta o WHY não-óbvio
# OAuth2 server occasionally returns 502 mid-handshake (vendor bug
# tracked in #4471); retry up to MAX_RETRIES with backoff before
# surfacing failure
retries += 1

# ❌ Referencia task atual (rotaciona)
# Added for the new login flow PR-#1234
def authenticate(token)

# ✅ Pertence ao PR/commit, não ao código
def authenticate(token)

Estilo léxico per-language

Linguagem Single-line Multi-line Doc comment
Koda # (não tem; usar # consecutivos) #: em linhas consecutivas (3+)
Go // (não tem; usar // consecutivos) // PascalName ... antes de export
Dart // /* */ /// ou /** */ (dartdoc)
Python # (não tem) """...""" triple-quoted (PEP 257)
Rust // /* */ /// ou //! (módulo)
JS/TS // /* */ /** */ (JSDoc/TSDoc)
Shell # (não tem) n/a
SQL -- /* */ n/a

Princípio: usar o formato idiomático da linguagem; não forçar uniformidade total que viola o uso esperado pelo IDE/linter.

Doc comments

R1 — Quando obrigatório

  • Toda função/método/classe pública (exportada do módulo)
  • Toda constant pública não-trivial (não óbvia pelo nome)
  • Todo módulo/package (docstring no topo)

R2 — Quando opcional

  • Funções privadas curtas (≤10 linhas) com nome auto-explicativo
  • Test functions (nome test_ ou it_should_ é a doc)

R3 — Formato

Mínimo: 1 linha de resumo. Quando relevante: 1 linha em branco + detalhes (parâmetros, retorno, raises, exemplos).

def hash_password(password: str) -> str:
    """Hash a password with Argon2id."""
def hash_password(password: str, *, time_cost: int = 3) -> str:
    """Hash a password with Argon2id.

    Time cost defaults to 3 (OWASP 2024 recommendation). Use higher
    values for high-security contexts; benchmark target: ~50ms on
    modern CPU.

    Args:
      password: Plaintext password (max 72 bytes effective).
      time_cost: Argon2 t parameter; 3 ≤ t ≤ 10.

    Returns:
      PHC-format hash string (`$argon2id$v=19$...`).

    Raises:
      ValueError: If password is empty or time_cost out of range.
    """

R4 — Koda specific (#: triple-line)

Ver code/languages/koda-style.kmd § Doc comments. Resumo:

#: Compute SHA-256 hash of a string.
#:
#: Returns 64-char lowercase hex. Raises EncodingError on
#: invalid UTF-8.
def sha256(s)
  ...
end

TODO / FIXME / HACK / XXX / NOTE / WARN

R5 — Formato canônico

# TODO(@handle, ticket): description
# FIXME(@handle, ticket): description
# HACK(@handle, ticket): description — explanation of why
# XXX(@handle): something dangerous; needs careful review
# NOTE: something readers should know but isn't actionable
# WARN: behavior that surprises; non-obvious side effect

R6 — Quando usar cada um

Marker Significado
TODO Trabalho planejado, não-urgente; tem ticket
FIXME Bug conhecido; deve ter ticket
HACK Workaround consciente; explicar o porquê + ticket de remoção
XXX Algo perigoso/duvidoso que merece revisão
NOTE Informação útil pro leitor, não-actionable
WARN Comportamento surpreendente; alerta defensivo

R7 — Regras

  • TODO/FIXME/HACK devem ter (@handle, ticket) — autor + ticket de tracking
  • Linter falha se TODO/FIXME sem ticket após 30 dias
  • HACK exige explicação do porquê após : (não pode ser só # HACK: fix later)
  • XXX não exige ticket mas exige revisão code-review
  • Markers em inglês (mesmo em comentário pt-BR raro — markers são vocabulário fechado universal)

R8 — Heisenbug workarounds

Caso especial: diagnóstico que "acidentalmente conserta" um bug pode ser shipado como workaround permanente, mas exige:

  • Comentário explícito explicando que é workaround
  • Ticket de follow-up pra root-cause investigation
  • Marker HACK ou XXX

(Padrão registrado em memory feedback_heisenbug_workaround_pattern.)

Commented-out code

Proibido. Delete + git history. Linter falha se ≥5 linhas consecutivas comentadas com sintaxe que casa com a linguagem.

# ❌
def foo():
    bar()
    # baz()
    # qux()
    # frob()
    return bar.result()

# ✅
def foo():
    bar()
    return bar.result()
# git blame mostra o que foi removido

Exceção rara: bloco de exemplo/template em README ou doc comment (aceito porque o # está dentro de docstring/markdown).

Section headers

Quando arquivo tem ≥200 linhas e seções lógicas distintas, usar section headers:

# ============================================================
# Public API
# ============================================================

def authenticate(...): ...
def logout(...): ...

# ============================================================
# Internal helpers
# ============================================================

def _hash(...): ...

Não obrigatório; não adicionar em arquivos curtos onde o file outline do IDE já dá a estrutura.

License header

R9 — Política Koder

Default: não exigir license header em todo arquivo. Razões:

  • LICENSE no root do repo é canônica
  • Header em todo arquivo polui git diff e onboarding
  • Tooling moderno (SBOM, REUSE) lê do LICENSE direto

Exceção: arquivos publicados como SDK público pra terceiros (em engines/sdk/* quando publicado em registry público) — seguem SPDX short-form:

// SPDX-License-Identifier: Apache-2.0
// Copyright (c) Koder. See LICENSE file in the project root.

Auditor verifica per-módulo via koder.toml [license_header] opcional.

Module-level docstring

Obrigatório quando o módulo expõe API pública:

"""Identity service client for the Koder ID OIDC provider.

Provides authentication primitives compatible with the
specs/identity/login-resolution.kmd contract. Used by all Koder apps
via koder_kit.
"""
// Package identity provides the OIDC client for Koder ID.
//
// See specs/identity/login-resolution.kmd for the resolution contract.
package identity

Anti-patterns

AP-C1 — Comentário que repete o nome

# ❌
def get_user_by_id(user_id):
    """Get user by id."""
    ...

AP-C2 — Comentário desatualizado vs código

Se o comentário diverge do código, deletar o comentário (não "corrigir" — o código é a verdade).

AP-C3 — Banner "Created by X on Y"

# ❌
# Author: Joe Smith
# Created: 2024-01-15
# Last modified: 2024-12-20

Git tem essa informação. Linter falha.

AP-C4 — Long-form blog post em comentário

Se a explicação tem >20 linhas, mover pra:

  • Doc adjacente (<file>.md ou docs/<topic>.kmd)
  • ADR/RFC se for decisão arquitetural

Comentário curto referencia o doc.

AP-C5 — Emoji em comentário sem motivo

Comentários técnicos não usam emoji por default. Exceção: marker formal WARN pode ser // ⚠️ WARN: ... em algumas codebases — manter consistência por projeto.

AP-C6 — Disclaimer/legal boilerplate inline

Pertence ao LICENSE ou NOTICE, não ao top de cada arquivo.

Audit deterministic

comments-audit.sh:

  1. TODO/FIXME/HACK sem (@handle, ticket) → warning (>30 dias = error)
  2. ≥5 linhas consecutivas comentadas (commented-out code) → error
  3. Banner "Author/Created/Modified" → error
  4. Doc comment ausente em export pública → warning
  5. Module docstring ausente em módulo com API pública → warning

Severidade medium por enquanto (warning não-bloqueante); migrar pra hard quando coverage estabilizar.

  • Regra global "default to no comments" em CLAUDE.md (policies/ global)
  • code/naming.kmd — nomes auto-explicativos reduzem necessidade de comentário
  • code/functions.kmd — funções curtas reduzem necessidade
  • code/languages/koda-style.kmd — KodaDoc #: específico
  • readmes/products.kmd — onde docs maiores vivem

References