Regression Tests per Bug
Toda correção de bug exige teste de regressão (3 categorias: behavioral, golden, estrutural) que falhe sem o fix e passe com ele. Testes ficam em tests/regression/. Registry: registries/regression-test-cases.md.
When fixing any bug in any module of the monorepo, you must create a regression test that:
- Reproduces the bug — the test fails if the fix is reverted.
- Passes after the fix.
- Stays permanently in the repository as regression protection.
Directory Structure (per module)
modulo/
tests/
regression/
NNN-descricao-do-bug.test.{ext}NNN: sequential number per module (001,002, ...).{ext}: language-specific extension of the module (.kd,.go,.ts,.dart,.py,.sh, etc.).- Language-specific conventions override when the test runner requires a fixed filename format:
- Go (
go testdiscovers only*_test.go): useNNN_descricao_test.go(e.g.001_sighup_reload_test.go). - Rust: tests live in
tests/withNNN_descricao.rs. - Python (pytest): prefer
test_NNN_descricao.py. - Other languages (
.kd,.ts,.dart,.sh, etc.): followNNN-descricao.test.{ext}.
- Go (
Test Header
Every regression test must start with a comment containing:
- Reference to the backlog ticket (if any).
- Description of the bug in one line.
- Expected behavior (correct) vs buggy behavior.
Rules
- Simple and focused — test only the specific bug, not the whole system.
- No unstable external dependencies (APIs, network, third-party services).
- No UI tests coupled to layout — test logic/behavior, not pixels.
- If the module has no
tests/regression/yet, create it on the first bug. - Name the file descriptively (e.g.
003-argv-variable-mismatch.test.kd).
Test Categories (preference order)
6.a — Behavioral (default)
Executes the code and validates observable behavior (output, exit code, state, side effects). Default choice. Any bug fix should try this category first.
6.b — Golden
Validates invariance/contract between multiple representations of the same data via roundtrip, diff, or direct comparison. First-class category, not a workaround. Use when the goal isn't "X does Y" but "A and B agree on X". Typical cases: DSL↔generated code, encoder↔decoder, single-source-of-truth with multiple consumers, binary↔text formats. The test runs something and checks exit code, but the "behavior" tested is consistency, not business logic.
Validate by injecting drift (e.g. intentionally alter one side and confirm the test fails) before committing. Mark as golden in the "Revisão?" column of the registry. Canonical examples: 023-opcode-dsl-consistency.test.sh, 024-kbcb-roundtrip.test.sh, 025-kode-disasm.test.sh, 026-bytekode-loc-sourcemap.test.sh in engines/lang/lang/tests/regression/.
6.c — Structural as stopgap (exception)
When the target module has no executable runtime harness and building one is out of scope for the fix, a structural test (grep/AST on source) is acceptable only if all of these hold:
- (a) the test fails if the fix is reverted (verify with
git stashbefore committing); - (b) an open backlog ticket tracks the construction of the harness, and is referenced in the test's comment header;
- (c) the test's top comment explains why a behavioral test isn't viable today;
- (d) the registry entry (
meta/context/registries/regression-test-cases.md) is marked withestruturalin the "Revisão?" column to ease future auditing.
Structural stopgaps must be replaced with behavioral tests as soon as the harness exists.
7 — MUST: Generator-coverage backfill (auto-melhoria do gate de teste)
O teste de regressão (§1–6) guarda aquele bug. Esta seção garante que a classe inteira do bug passe a ser pega automaticamente, antes da release, pelos geradores de teste do SDK — fechando o buraco que deixou o bug chegar à release. Diretiva do Owner (2026-06-07): regra normativa.
Gatilho: logo após identificar a causa-raiz de QUALQUER erro encontrado durante a execução/uso de qualquer componente da Koder Stack (bug em produção, em dev, em release, ou relatado pelo Owner) — antes de fechar o trabalho.
Passos (obrigatórios):
- O erro é detectável por TDD? Ou seja, existe um teste determinístico/automatizável
que o reproduza (lógicaestadocontrato/comportamento headless)?
- Não (exige julgamento visual humano, hardware externo, não-determinismo irredutível):
registrar por quê não é TDD-detectável; o teste de regressão de §1–6 ainda se aplica onde for possível. Encerra esta seção.
- Sim: seguir ao passo 2.
- Não (exige julgamento visual humano, hardware externo, não-determinismo irredutível):
- O SDKframework de geradores `k-test` JÁ tem a capacidade de auto-gerar o TDD que
reproduziria essa classe de bug — de modo que rodaria como gate de release do módulo (e teria barrado o bug antes de publicar)?
- Sim (capacidade existe): garantir que o componente está ligado à categoria/
gerador correto (o gate teria pego); se não estava, esse é o fix de fato. Anotar.
- Não (capacidade ausente): ir ao passo 3.
- Sim (capacidade existe): garantir que o componente está ligado à categoria/
- Avaliar viabilidade + importância da capacidade de geração faltante:
- É implementável no SDK (existe forma headless/determinística de emitir o TDD dessa
classe a partir do manifestcontrato)? É *ecorrenteimportante*o bastante?
- Se SIM (viável E importante/necessária): a própria IA DEVE, na mesma sessão:
a. Abrir ticket(s) no backlog do SDK dono da capacidade (ex.: o framework de geradores em
projects/koder-stack, ouengines/sdk/koder_kit, ou o SDK específico), descrevendo a categoria/gerador faltante + a classe de bug que ele deve cobrir + o binding de gate de release. b. Inserir um alerta emmeta/context/notices/active/(schema broadcast-alerts) para a próxima sessão pegar o ticket e implementar (kind: reminder/courtesy, apontando o ticket). Se o SDK estiver sob lock de outra sessão, é cortesia + ticket (não editar o source locked —lock-carve-out). - Se NÃO (inviável agora ou não-importante): registrar a decisão + o motivo (no ticket
do bug ou no registry), sem inventar trabalho.
- É implementável no SDK (existe forma headless/determinística de emitir o TDD dessa
Relação com o resto: §1–6 (regressão do bug) e §7 (backfill do gerador) são complementares e ambos obrigatórios quando aplicáveis. A regressão prova o fix; o backfill faz o gate de release evoluir pra nunca mais deixar a classe passar.
Exemplo trabalhado (2026-06-07): bug do Dek "Pause reinicia o áudio" + "tap na waveform não faz seek" → causa-raiz: contrato de transporte de mídia não testado + widget compartilhado ausente. Backfill: regressão do bug (#952) + ticket da capacidade de geração (projects/koder-stack#185 categoria media-control + gate; engines/sdk/
koder_kit#076 widget+TDD) + alerta/cortesia à sessão dona dos geradores.
Registry
- The registry is a directory of one-file-per-case under
meta/context/registries/regression-test-cases/(concurrent-safe; mirrors thenotices/andbacklog/per-file stores — metadocsstack#191). The siblingregression-test-cases.mdis a GENERATED index (read-only); do not edit it by hand. There is no shared counter — case IDs are content-addressed, so concurrent sessions never collide. - Each new regression test adds a case file, not a table row. Add it with
python3 meta/context/registries/regression-registry.py add --date <YYYY-MM-DD> --module <path> --test <file> --commit <fix> --review <não|golden|estrutural> --desc "<bug summary>"(createsregression-test-cases/<id>-<slug>.kmdand regenerates the index). Committing the new file underregression-test-cases/is collision-free; never re-append to the generated.md. - Scenario id na linha (stack-RFC-013 fase 4): quando o teste deriva de
(ou cobre) um
#### Scenario:da gramática Requirement/Scenario, a linha do registry cita o Scenario id estável (<spec-slug>#<requirement-slug>/<scenario-slug>) — é o que torna a cobertura spec→teste auditável entre releases (o gate FASE 4.5 do/k-teste o/k-test-genFASE 1.5 usam o mesmo id). - While the counter ≤ 30 cases, review this policy and the process at each new case to identify improvements (recurring patterns, bug categories, needed helpers, structural adjustments). Apply improvements to the policy and inform the user.
- After 30 cases, the policy is considered mature — stop automatic reviews. The user can request a manual review at any time.