Error Taxonomy (classes, severity, retryability)

mandatory

Vocabulário canônico de erros da Koder Stack: o enum fechado de CLASSES (categorias funcionais — `DL`, `UP`, `AU`, `NW`, `DB`, `UI`, `IO`, `PM`, `VL`, `XX`), a definição semântica + regra de desempate de cada classe, a escala de SEVERIDADE (`fatal`/`error`/`warning`/`info`) e a classificação de RETRYABILITY. É a fonte de verdade dos campos `error_category` e `severity` que `specs/errors/reporting.kmd` (Group D) captura e que o Error ID de `specs/errors/user-facing-messages.kmd §4` encurta. Não define texto exibido (user-facing-messages), captura/telemetria (reporting), padrões de código (code/error-handling) nem o envelope de wire (model).

Define o vocabulário dos erros (classes, severidade, retryability). O shape máquina-legível é specs/errors/model.kmd; o texto humano é specs/errors/user-facing-messages.kmd; a captura/telemetria é specs/errors/reporting.kmd; os padrões de código são specs/code/error-handling.kmd. Esta spec é a fonte única dos campos error_category e severity que aqueles documentos consomem.

Applicability

Toda superfície Koder que produz, classifica, transmite, exibe ou registra um erro — apps mobiledesktopTV/web, CLIs, landing pages, serviços backend, e qualquer binding SDK. A classe e a severidade de um erro são as mesmas em todas as camadas: o backend que origina, o envelope que transporta, a telemetria que captura e a UI que exibe usam o mesmo valor.


R1 — Classe de erro (enum fechado)

Todo erro pertence a exatamente uma classe. O enum é fechado: um produto nunca inventa uma categoria nova — ele cria novos CODE dentro de uma categoria existente (ver user-facing-messages.kmd §4). Se nenhuma classe encaixa, é XX (e provavelmente um gap desta spec — abrir ticket).

Classe Nome Domínio (o que falhou)
DL Download Obtenção de bytes de um recurso remoto para o dispositivo
UP Upload Envio de bytes do dispositivo para um recurso remoto
AU Authentication Identidade do chamador não pôde ser estabelecida/provada
NW Network Transporte/conectividade (DNS, TLS, timeout, sem rota)
DB Database / storage Camada de persistência remota (query, constraint, indisponível)
UI UI render Renderizaçãolayoutbinding na camada de apresentação
IO Filesystem / local I/O Sistema de arquivos local, dispositivo, periférico
PM Permission Identidade conhecida mas não autorizada para a ação
VL Validation Input não satisfaz uma regra (ver specs/data/validation.kmd)
XX Unknown Não classificável; fallback exclusivo

Os 2 caracteres são o componente CATEGORY do Error ID (<PRODUCT>-<CATEGORY>-<CODE>-<SEQ>) e o valor de error_category no envelope (model.kmd) e na telemetria (reporting.kmd Group D).


R2 — Definição semântica + regra de desempate

Pares de classes confundem-se na prática. A tabela abaixo é normativa para o desempate; havendo ambiguidade, vale a coluna "Decisão".

Confusão Classe A Classe B Decisão
Não logado vs sem permissão AU (quem é você?) PM (você não pode) 401-equivalente → AU; 403-equivalente → PM. Identidade ausente/expirada = AU; identidade válida mas escopo insuficiente = PM
Falha de rede vs storage remoto NW (transporte) DB (a query/recurso) Não chegou ao servidor (timeout, DNS, TLS, connection refused) = NW. Chegou e o backend de persistência falhou (5xx de query, constraint, lock) = DB
Download vs network DL (semântica: obter recurso) NW (mecânica: transporte) Se o propósito da operação é baixar um recurso identificável, DL mesmo que a causa raiz seja de rede — a classe descreve a operação do usuário, a causa raiz vai em cause/http_status do envelope. NW é para falha de conectividade sem semântica de recurso (ex.: health-check, handshake)
Filesystem local vs storage remoto IO (local) DB (remoto) Discoarquivodispositivo na máquina = IO. Persistência atrás de uma API/rede = DB
Input inválido vs erro de UI VL (dado não passa regra) UI (render quebrou) Valor que viola uma regra de campo = VL. Falha ao desenhar/compor a tela = UI

Princípio: a classe descreve a operação que o usuário tentava (intent), não necessariamente a camada técnica da causa raiz. A causa raiz vive em causehttp_statusupstream_dependency do envelope (model.kmd).


R3 — Severidade (escala fechada)

Todo erro carrega uma severidade. Enum fechado, ordenado:

Severity Significado is_fatal Ação típica
fatal Estado irrecuperável; o fluxo (ou o processo) não pode continuar com segurança true Abortar boundary, crash report, exit code ≠ 0
error A operação falhou mas o app/serviço segue vivo; o usuário pode tentar de novo ou outra ação false Exibir mensagem humanizada (user-facing-messages), permitir retry/abandono
warning A operação prosseguiu de forma degradada; resultado parcial ou fallback usado false Sinalizar de forma não-bloqueante; logar
info Evento notável que não é falha (ex.: cancelado pelo usuário, no-op esperado) false Geralmente não exibir como erro
  • O campo booleano is_fatal de reporting.kmd Group D é derivado:

    is_fatal == (severity == "fatal"). Não há fonte independente.

  • fatal mapeia ao panicabort de `codeerror-handling.kmd §R2`

    (invariante violada / estado impossível). Erro recuperável de input, IO ou rede nunca é fatal — é error (ou warning se houve fallback).

  • info/cancelamento: user-facing-messages.kmd §2 já manda não exibir

    erro em cancelamento do usuário — esse caso é severity: info.


R4 — Retryability

Ortogonal à severidade. Todo erro é classificável em retryability, e o valor deve alinhar com a política operacional de code/error-handling.kmd §R9.

Retryability Quando Exemplos de classe/código
retryable Repetir a mesma operação pode ter sucesso sem mudança de input NW timeout, DBDLUP 5xx (idempotentes), 429 (respeitar Retry-After)
not-retryable Repetir sem mudança falha de novo VL (input não-corrigível por retry), AUPM (credencialescopo não melhoram), 4xx exceto 408/429
conditional Retry só após uma correção/ação (re-login, liberar espaço, corrigir campo) AU expirado (após re-auth), IO sem espaço (após liberar), VL (após corrigir)

O envelope (model.kmd) expõe retryable: bool (com conditional mapeado a false + um recovery hint). Esta tabela é a regra de classificação; o mecanismo de backoff/circuit-breaker é de error-handling.kmd §R9–R10.


R5 — Fingerprint (agrupamento)

O campo fingerprint de reporting.kmd Group D agrupa ocorrências do "mesmo" erro para deduplicação e contagem agregada. Regra de composição canônica:

fingerprint = hash(error_category + ":" + code + ":" + normalized_call_site)
  • normalized_call_site = file:symbol (sem número de linha — linha muda

    a cada edição e fragmentaria o agrupamento).

  • Não incluir valores variáveis (IDs, paths, timestamps) no fingerprint

    — isso explodiria a cardinalidade (anti-padrão de policies/observability-first.kmd).

  • Dois call sites com a mesma category+code têm fingerprints distintos

    (é o que o SEQ do Error ID também desambigua).


R6 — Extensão por produto

  • Produtos adicionam CODEs, nunca classes. O CODE é HTTP status

    (503, 404) para erros HTTP, ou um numérico curto definido pelo produto (user-facing-messages.kmd §4).

  • Cada produto registra seus pares `(category, code) → condição, mensagem,

    call-site, severity, retryability em productdocstechnical/errors.md (o registry que user-facing-messages.kmd §4 e o errors-catalog.md` gerado já consomem).

  • Severidade e retryability de um (category, code) são *ropriedade do

    registry do produto* classificadas segundo R3/R4 desta spec.


R7 — Audit determinístico

errors-taxonomy-audit.sh (advisory), rodável por /k-housekeep:

  1. Todo error_category emitido em código/registry pertence ao enum de R1

    (qualquer outro valor → error).

  2. Todo severity emitido pertence ao enum de R3 (→ error).
  3. is_fatal sem severity == "fatal" correspondente → warning (campo

    derivado fora de sincronia).

  4. Registry de produto (docs/technical/errors.md) com entrada sem

    severity/retryability classificados → warning.

  5. fingerprint contendo dígitos de linha ou IDs variáveis → warning

    (cardinalidade/fragmentação).


  • specs/errors/model.kmd — envelope máquina-legível que carrega

    error_categoryseverityretryable definidos aqui.

  • specs/errors/user-facing-messages.kmd — Error ID (§4 referencia o

    enum desta spec) + texto humano.

  • specs/errors/reporting.kmd — Group D captura error_category,

    severity, is_fatal, fingerprint (definidos aqui).

  • specs/code/error-handling.kmd§R2 (fatal↔panic), §R9 (retry),

    §R10 (circuit breaker).

  • specs/data/validation.kmd — origem dos erros de classe VL.
  • policies/observability-first.kmd — budget de cardinalidade (fingerprint, labels).