# ADR-001 — Fundamentos: determinismo, padronização, nativo primeiro e simplicidade

| Campo | Valor |
|---|---|
| **Status** | Aceito (2026-10-16) |
| **Data** | 2026-10-14 |
| **Plano de origem** | `wiki/plan/01-analise-e-decisoes.md` · `wiki/plan/00-index.md` (Fundamento) |
| **Relacionadas** | ADR-002, ADR-004, ADR-008, ADR-013, ADR-014, ADR-016, ADR-022, ADR-023 |

## Contexto

Projetos como o `cms/` acumulam abstrações (Result, traits, casts, repositórios) que, embora
bem-intencionadas, aumentam a carga cognitiva e a superfície de manutenção. Pior que a
complexidade é a **imprevisibilidade**: comportamento que depende de estado escondido, ordem de
iteração instável, aleatoriedade/`now()` espalhados, dados semeados de forma não-idempotente e
builds que não se repetem. Isso torna o sistema difícil de **integrar, atualizar e materializar**
e produz **testes instáveis** (flaky), que corroem a confiança no próprio gate.

O time valoriza **PHP concreto, funcional e legível**, com **injeção de dependência**, e quer que
o resultado seja **determinístico, previsível e padronizado** — do ambiente ao comportamento.

## Decisão

### 0. Fundamento (vale para todos os demais ADRs)

O projeto persegue, **antes de tudo**, ser **determinístico, previsível e padronizado**. Toda
decisão, plano e teste deve reforçar isso.

- **Determinismo** — mesma entrada ⇒ mesma saída:
  - **builds reprodutíveis**: lockfiles commitados, imagens pinadas **por digest**, assets
    vendorizados/buildados localmente (ADR-002); nada de download em runtime;
  - **conteúdo público com corpo determinístico** (habilita `ETag`/`304` — ADR-022);
  - **ordem estável**: discovery/manifesto de módulos, slots e presets com ordenação
    **explícita** (ADR-014/ADR-016); nunca depender de ordem de hash/diretório;
  - **sem `now()`/`rand()`/estado global escondido** no corpo das regras — tempo, aleatoriedade
    e id-gen são **injetados** (clock/`Random\Randomizer`/UUIDv7 — ADR-007);
  - **dados de referência idempotentes** (migrations) e **seeds só demo** (ADR-017); rodar
    2× produz o mesmo estado.
- **Previsibilidade** — fluxo explícito, sem mágica:
  - comportamento lê de cima a baixo; **erros explícitos** (exceções nativas → RFC 7807), nunca
    silenciosos (ADR-024);
  - **contratos estáveis** (Core ports; ADR-013) e **paridade dev/prod** (mesmo container);
  - **padrões verificáveis por gate** — o que não é determinístico falha no CI, não em produção.
- **Padronização** — uma convenção só, aplicada em todo lugar:
  - **token canônico** por feature (ADR-004); arquivos/pastas/nomes/migrations/rotas por
    convenção; **um único arquivo-raiz** por módulo (ADR-014);
  - **Pint + Prettier/ESLint** e `make` como interface única de operação;
  - `.editorconfig` e stubs derivados do blueprint (ADR-013), para que o "jeito certo" seja
    também o mais fácil.
- **Objetivo prático:** ser **fácil de integrar, atualizar e materializar como código efetivo**,
  fechando com **testes exaustivos finais e determinísticos** (sem flaky) — o critério de pronto.

### 1. Nativo primeiro

Antes de qualquer classe nova, esgotar o **Laravel 12 / PHP 8.4** (FormRequest, Validation,
Casts, Events, Jobs, Policies/Gate, Resources, Blade Components, Flysystem, Cache, Scheduler).

### 2. Funcional com DI

Regras em funções/Actions focadas e **puras quando possível**; dependências (DB, clock, id-gen,
storage) **injetadas** por parâmetro/clausura — nunca `new`/`resolve` no corpo. `pipe(...)` em
vez de loop mutável.

### 3. Simplicidade acima de tudo

**Sem traits, sem classes abstratas, sem genéricos** e sem hierarquias de OO. Classes só onde o
framework exige (Provider, Model, Middleware, Cast, Component). Autocontido e objetivo —
**duplicação eventual é preferível à abstração desnecessária**. O critério de qualidade é
**funcionalidade e efetividade**, não contagem de linhas.

### 4. Padrão de código

Toda ação emite log estruturado (ADR-024). Formatação: **Pint** (PHP) e **Prettier + ESLint**
(JS/TS), obrigatórios em `make check`/`make check` e no CI.

## Justificativa (alternativas descartadas)

- **`Result<T>` + genéricos** — descartada: complexidade sem ganho; exceções nativas bastam.
- **Traits/classes abstratas** — descartada: escondem o fluxo e dificultam o rastreio.
- **Repository pattern universal** — descartada: duplica o Eloquent sem necessidade.
- **"Funciona na minha máquina" / heurística implícita** — descartada: ordem de diretório,
  `now()`/`rand()` e dados não-idempotentes geram flaky e divergência dev/prod.
- **Configuração manual fora do `make`** — descartada: padronizar importa mais que a liberdade.

## Consequências

**Positivas**
- Código lê de cima a baixo, sem saltar hierarquias; testes baratos com stub.
- **Builds e deploys reprodutíveis**; **testes não-flaky**; CI confiável.
- **Integração e atualização previsíveis** (mesma convenção em toda a base; `make`/blueprint).
- Menos superfície de manutenção e menos dependências.

**Custos / negativas**
- Exige disciplina (injetar clock/aleatoriedade, ordenar explicitamente, não usar `now()` solto).
- Duplicação ocasional entre módulos é **aceita** por decisão.
- Interfaces existem **só** onde há porta/DI real (não como cerimônia).
- Padronizar às vezes significa abrir mão de um atalho local — aceito em troca da previsibilidade.

## Exemplo mínimo (comparativo)

```php
// ❌ Imprevisível: relógio/aleatório globais, ordem implícita, dados não-idempotentes
function noticiaPublicar(Noticia $n): void {
    $n->update(['publicado_em' => now(), 'hash' => md5(random_bytes(4))]);
}

// ✅ Determinístico: dependências injetadas, sem surpresa
function noticiaPublicar(Noticia $n, Clock $clock, IdGen $ids, AuditWriter $audit): void {
    $n->update(['publicado_em' => $clock->now()]);
    $audit->registrar('noticia', 'publicar', $n->id);   // UUIDv7 via IdGen
}
```

```php
// ❌ Ordem instável (depende do filesystem)
$modules = glob(__DIR__ . '/*');

// ✅ Ordem explícita e estável
$modules = collect(glob(__DIR__ . '/*'))->sort()->values()->all();
```

## Verificação

- Revisão/PHPStan: `Result<`, `trait `, `abstract class`, `@template` são itens de bloqueio.
- Grep de bloqueio: `now()`/`rand(`/`mt_rand(`/`random_int(`/`md5(` fora de locais permitidos
  (clock/id-gen/serviços de borda) falham no gate.
- `make check`/`make check` verdes; `make check` verde **2× seguidas sem flaky**.
- Migrações/seeds idempotentes: rodar 2× produz o mesmo estado (plano 08).
- Build reprodutível: imagens por digest, lockfiles, assets vendorizados (ADR-002).
- `ETag`/`304` estáveis no conteúdo público (corpo determinístico — ADR-022).

## Referências

- `wiki/plan/00-index.md` (princípio 0, "constituição"); `wiki/plan/01-analise-e-decisoes.md`;
  `wiki/plan/05-qualidade-phpstan-max.md`; `wiki/plan/08-servicos-headless-persistencia.md`;
  `wiki/plan/15-cicd-deploy-legado.md`; ADR-002, ADR-004, ADR-007, ADR-014, ADR-017, ADR-022.
