# CONTRIBUTING.md — Public V7 / Concordia

> Como contribuir sem violar a constituição (`AGENTS.md`), as decisões (`wiki/adr/`)
> e o planejamento (`wiki/implementation/README.md`).
>
> **Regra de ouro:** simplicidade, determinismo e padrão único. "O caminho correto é o de menor
> resistência." (ADR-001 · plano 02)

---

## 1. Antes de tocar em código

1. `kd prime` — protocolo da memória entre agentes (uma vez por sessão).
2. `kd ask "<pergunta>"` — **procure antes de criar**.
3. Leia o **ADR** e a **spec/plano** relevantes; o `README.md` de `/wiki` diz por onde começar.
4. Confirme a task em `kd task list --ready` (o trabalho é **sequencial**).
5. Suba o ambiente: `make up` (tudo roda **dentro do container**).

> Nunca edite `vendor/` nem `notas/` à mão. Nunca `rm -rf` (descarte em `.pi/trash/`).

---

## 2. Fluxo de branch e merge request

- **Trunk estável:** `main` só recebe código que passou em todos os gates.
- **Branches curtas e temáticas:**

| Prefixo | Uso |
|---|---|
| `feat/` | nova capacidade (módulo, service, tela) |
| `fix/` | correção de defeito |
| `refactor/` | mudança interna sem alterar comportamento |
| `test/` | testes/e2e/a11y |
| `docs/` | wiki/ADR/specs |
| `chore/` | build, CI, deps, tooling |
| `perf/` | desempenho (medido antes/depois) |

- **Nome:** `prefixo/token-canonico-curto` (ex.: `feat/noticia-rascunho`, `fix/csp-etag`).
- **MR pequeno:** um assunto por MR; descreva *o quê*, *por quê* (ADR/plano) e *como validar*.
- **Merge:** squash na `main`; a mensagem de squash segue o padrão de commit abaixo.

---

## 3. Commits (Conventional Commits)

```
<tipo>(<escopo>): <resumo no imperativo, ≤72 colunas>

<por quê / decisão / ADR>
<evidência: testes, gates, links>
```

- **Tipos:** `feat` · `fix` · `refactor` · `test` · `docs` · `chore` · `perf` · `build` · `ci`.
- **Escopo = token canônico** (ADR-004): módulo, service, camada ou artefato
  (ex.: `feat(noticia): ...`, `fix(media): ...`, `docs(adr-030): ...`).
- Exemplos: `feat(noticia): rascunho com agendamento`, `fix(seo): 301 com query preservada`.

---

## 4. Granularidade e rastreabilidade (`kd`)

- Todo trabalho nasce de uma **task** do knudge (`epic ⊃ {issue | task}`), ancorada no
  arquivo de `wiki/implementation/*.md`.
- Uma task = **uma fase/entrega coesa**, fechada ao fim com `kd task close --id ... --outcome ...`.
- Decisões, erros e riscos **viram nota** (`kd write`, uma asserção por nota, com `--anchor`).
- Ao comprimir contexto, escreva `.STAGING.md`.

---

## 5. Definition of Done (DoD)

Uma contribuição só termina quando **todos** os itens abaixo forem verdadeiros:

- [ ] **`make check` verde** — Pint `--test` · PHPStan `level: max` **0 erros** · PHPUnit estrito ·
  cobertura `src/` **≥90%** · gates · a11y. O comando **corrige o estilo preventivamente**
  (Pint + Prettier/ESLint `--fix`, logando **antes/depois**) — rode-o e o código já sai formatado.
- [ ] **`make check E2E=1` verde ao menos 1× ao fechar o escopo** — acrescenta **e2e Playwright + axe
  + perf**; é opt-in por ser o mais lento (~1,5 min com 4 workers) e só ser afetado por UI/HTML/CSS/JS/rota.
- [ ] `make check` verde **duas vezes seguidas** (sem *flaky* — determinismo, ADR-001).
- [ ] Boundaries (`tools/arch-check`), grep-friendly (`tools/name-check`), `tools/migration-check`,
  `tools/vendor-check` e `php artisan optimize` — **cobertos pelo `make check`**.
- [ ] ADR criado/atualizado para decisão relevante; spec/plano coerentes.
- [ ] `declare(strict_types=1)` em todo PHP novo; logs estruturados onde houver fluxo.
- [ ] Teste vermelho → verde para bugs; teste estrutural durante o build de features.

### 5.1 Feedback local (um comando)

```bash
make check              # validação completa sem e2e: estilo (antes/depois) + estático + gates + testes/cobertura + a11y
make check E2E=1        # + e2e Playwright/axe + perf (≥1× ao fechar o escopo; o CI roda sempre assim)
make up                 # sobe os containers (o `make check` provisiona/migra/compila)

CHECK_QUIET=1     make check E2E=1   # só resumo + falhas
CHECK_FORCE_PREP=1 make check        # ignora os stamps e roda todo passo caro (depuração)
CHECK_ASSETS=1    make check         # força rebuild de assets
E2E_WORKERS=8     make check E2E=1   # paralelismo do Playwright (default 4)
COVERAGE_WORKERS=8 make check        # paralelismo do PHPUnit/ParaTest (default 4)
```

**Contrato de ciclo (o ciclo é infraestrutura):** alvo **≤ 100 s** sem e2e e **≤ 3 min** com `E2E=1`.
Medido em 2026-10-20 após o B9 (12 vCPU): `make check` **82–92 s**, `make check E2E=1` **2m39s**.
O relatório imprime o tempo de cada check — use-o antes de "otimizar" qualquer coisa.

| Regra | Por quê |
|---|---|
| Passo caro **e idempotente** (autoload, `migrate`, `optimize`, build de assets) **gated por staleness** (`SKIP` visível) | repetir trabalho já feito não valida nada: era ~48 s por run |
| **Nunca** pular verificação para ganhar tempo (cobertura, gates, a11y, e2e do DoD) | velocidade vem de remover repetição e paralelizar o independente, não de afrouxar (ADR-038) |
| E2E paraleliza **por arquivo**; `fullyParallel: true` **proibido** | dentro do arquivo a ordem é contrato; dois testes do lote da galeria mutam o mesmo catálogo (medido: 99/100) |
| PHPUnit paraleliza **por arquivo** com banco por worker (`concordia_test_<token>`) | a cobertura é mesclada no clover; testes que mutam `src/` (geradores) coordenam lock e o cache é limpo por teste |
| Ao adicionar um passo, informe o **custo medido** | um passo > ~10 s precisa justificar (ou ser gated); `CheckPipelineTest` trava a regressão |

Se o ciclo estourar o alvo em **código seu**: meça por check no relatório, gate o que for idempotente e
paralelize o que for independente — não desligue o gate (bug de performance é bug, ADR-001).

- **Banco de teste:** `concordia_test`, criado por `tools/test-db.sh` (rodado pelo `make check`); configuração nas `<env>` de `phpunit.xml`
  e `<env>` de `phpunit.xml`. `CoreTestCase` **aborta** se `DB_DATABASE` não terminar em `_test`.
- **Non-regression:** todo bug corrigido entra com o teste **vermelho → verde** no mesmo MR. As
  validações são **estruturais no fluxo dev** (`make check`), não dependentes do CI. Sem hook de
  pre-commit (descartado — ADR-040).
- **Cobertura ≥90% (ADR-038):** o gate bloqueia abaixo do piso; priorize **e2e/não-regressão**.

---

## 6. Convenções de código (resumo)

- **PHP nativo e concreto** (ADR-001): sem `trait`, `abstract`, generics nem `Result<T>`;
  **duplicação é aceitável** quando reduz acoplamento.
- **Uma Action por arquivo**, focada e testável: dependências **injetadas** (nada de `new`/`resolve`
  no corpo), `declare(strict_types=1)`, cabeçalho `@intent`/`@see`/`@debt`.
- **Contract-First:** Action concreta → teste; interfaces **só** onde há porta/DI real.
- **Nativo primeiro:** esgote Laravel/PHP antes de qualquer pacote. Dependência nova exige
  justificativa e licença permissiva (ADR-002) — `vendor/` nunca editado à mão.
- **Determinismo:** clock/aleatoriedade **injetados**; ordem **explícita**; dados **idempotentes**;
  nada de `now()`/`rand()` soltos.
- **Dados:** `jsonb` para conteúdo; **nunca** HTML/CSS/flag de UI no banco; `down()` nunca dropa
  (→ `backup_<tabela>_<ts>`) (ADR-017).
- **Fronteiras:** `modules/*` nunca importa `modules/*`; comunicação via Events/Listeners e
  portas do `core` (ADR-013/014).
- **Grep-friendly:** um token canônico por feature deriva nomes de classes, rotas, views,
  tabelas, testes, slots e logs (ADR-004).
- **Lint/fmt:** o `make check` corrige Pint + Prettier/ESLint antes de validar; não há alvo de
  correção separado.
- **JS moderno (ES2025):** ESM, `const`/`let` (nunca `var`), `===`, `??`/`?.`, `async/await`,
  `Promise.withResolvers`; o ESLint (`ecmaVersion: 2025`) é o gate (`no-var`, `prefer-const`,
  `eqeqeq`, `prefer-template`, `no-throw-literal`). Assets em `src/**/Assets/js` (o boilerplate
  `resources/js` do Laravel foi removido — sem `axios`).

---

## 7. Acessibilidade e UX (requisitos, não extras)

- Meta **WCAG 2.2 AA + eMAG** (ADR-025). Foco visível, navegação por teclado, alvos ≥ 44px,
  contraste adequado, `prefers-reduced-motion`, HTML semântico, ARIA só quando necessário.
- Referências: `.agents/skills/web-accessibility/` e a seção de acessibilidade de `wiki/DESIGN.md`.
- Violação de a11y **bloqueia** o merge.

---

## 8. Segurança e privacidade

- CSP estrita e *cacheável*, **sem inline** (ADR-020/022); Trusted Types; `__Host-`; Argon2id.
- **Nunca** commitar segredos (`.env` fora do versionamento); use `.env.example`.
- LGPD: classificar dado pessoal, minimizar coleta, respeitar retenção e **DSAR** (ADR-019).

---

## 9. Documentação

- Toda decisão relevante vira **ADR** em `wiki/adr/` (uma por decisão).
- Planejamento em `wiki/plan/` (00..19) e execução sequencial em `wiki/implementation/` (F0..F6).
- Specs em `wiki/specs/` com **dono** e **status**; `make exec cmd='bash tools/docs-check.sh'` valida índice/status.
- A raiz do repositório é Laravel típico; `/src` contém **apenas**
  `core`, `services`, `layout`, `modules` e `tests-e2e` (ADR-003).

---

## 10. Revisão (checklist do revisor)

- [ ] Escopo único e rastreável à task/ADR.
- [ ] Fronteiras e `strict_types` respeitados; nenhuma dependência nova sem justificativa.
- [ ] DoD da seção 5 comprovado (anexar saída dos gates no MR).
- [ ] Nenhum segredo, nenhum `vendor/` editado, nenhum arquivo de cPanel versionado.
- [ ] Texto/documentação em pt-BR quando voltado a operação; código em inglês técnico.
