mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 09:34:46 +08:00
docs: a vps-fresh-onboarding entrou no CI — as frases que a davam como fora venceram
O PR #983 tirou a `vps-fresh-onboarding.spec.ts` da `FORA_DO_CI` e a pôs
para rodar na `SPECS_PARTE_4` do `e2e.yml` (matrix `parte: [1, 2, 3, 4]`;
o agregador obrigatório `e2e` tem `needs: [e2e-alcance, e2e-parte]`).
Medido em origin/main @ af6730f0f: a `FORA_DO_CI` lista só
`inbox-tempo-real` e `cadastro-sem-confirmacao-de-email`.
Com isso, venceram as afirmações de que a jornada de instalação fresca
segue sem gate e de que `e2e` verde não a prova:
- CLAUDE.md (item `e2e` dos checks obrigatórios): a frase vira histórico
datado e a pergunta passa a ser respondida pelo comando python que o
próprio item já traz, amarrado ao `e2e-cobertura-completa.test.ts`.
- AGENTS.md (Limitações conhecidas): o item carrega o comando que mede a
`FORA_DO_CI` e o histórico em uma frase. Também a linha "`e2e` roda
três partes", que venceu no mesmo PR, vira comando.
- docs/current-state.md §4.1 e docs/harness-audit.md: são retratos
datados, então ganham nota de atualização em vez de reescrita.
A ressalva que continua verdadeira fica escrita em todos: PR que não
alcança o `e2e` (scripts/pr-alcanca-o-e2e.sh) pula as partes, e ali o
verde não prova tela nenhuma.
Só documentação: não muda comportamento para quem opera VPS, então não
leva fragmento em .changes/.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
af6730f0fc
commit
21017b8a83
@@ -169,8 +169,10 @@ gh api repos/melgarafael/DeskcommCRM/branches/main/protection \
|
||||
--jq '.required_status_checks.contexts|join(", ")'
|
||||
```
|
||||
|
||||
`e2e` roda três partes em paralelo; as specs de fora estão declaradas, **com motivo escrito**, em
|
||||
`FORA_DO_CI` dentro de `.github/workflows/e2e.yml`. Leia em vez de supor:
|
||||
`e2e` roda as partes da sua matrix em paralelo (quantas:
|
||||
`git show origin/main:.github/workflows/e2e.yml | grep -E '^ +parte: \['` — esta linha dizia
|
||||
"três" até o PR #983 acrescentar a quarta); as specs de fora estão declaradas, **com motivo
|
||||
escrito**, em `FORA_DO_CI` dentro de `.github/workflows/e2e.yml`. Leia em vez de supor:
|
||||
|
||||
```bash
|
||||
git show origin/main:.github/workflows/e2e.yml | grep -A4 'FORA_DO_CI:'
|
||||
@@ -379,12 +381,20 @@ itens envelhecem em ritmos diferentes, e o cabeçalho passava a mentir por todos
|
||||
(O SHA `789dfa6`, que ficava aqui, ficou para trás — meça com
|
||||
`git rev-list --count 789dfa6..origin/main`.)
|
||||
|
||||
- **As specs E2E fora do CI são exatamente as declaradas em `FORA_DO_CI`** — hoje
|
||||
`vps-fresh-onboarding` é a P0 entre elas —, e o `e2e` **é** check obrigatório. Ou seja: um PR
|
||||
que quebre o `e2e` não entra — mas a jornada de
|
||||
instalação fresca, que é o produto que se vende, continua sem gate. Se você mexeu nela, a
|
||||
prova é sua. O número e a contagem que ficavam aqui eram de uma fotografia de agosto, e o
|
||||
disco já tinha mudado desde então.
|
||||
- **As specs E2E fora do CI são exatamente as declaradas em `FORA_DO_CI`**, e o `e2e` **é** check
|
||||
obrigatório: um PR que quebre o `e2e` não entra. Quais ficam fora, meça:
|
||||
|
||||
```bash
|
||||
git show origin/main:.github/workflows/e2e.yml | \
|
||||
python3 -c "import sys,re; y=sys.stdin.read(); print(sorted({s for _,c in re.findall(r'(FORA_DO_CI):\s*>-\n((?:[ ]{8,}.*\n)+)',y) for s in re.findall(r'[a-z0-9-]+\.spec\.ts',c)}))"
|
||||
```
|
||||
|
||||
Até 2026-09-19 a `vps-fresh-onboarding` — a P0, a jornada de instalação fresca, que é o
|
||||
produto que se vende — estava nessa lista e seguia sem gate; desde o PR #983 ela roda na
|
||||
`SPECS_PARTE_4`. O gate vale só em PR que alcança o `e2e` (regra em
|
||||
`scripts/pr-alcanca-o-e2e.sh`): o que pula as partes sai com `e2e` verde sem ter provado tela
|
||||
nenhuma, a da instalação fresca inclusive. O número e a contagem que ficavam aqui eram de uma
|
||||
fotografia de agosto, e o disco já tinha mudado desde então.
|
||||
- Rate limit HTTP: `lib/auth/rate-limit.ts` cobre **login, signup, recuperação de senha e
|
||||
aceite de convite** (contando por IP **e** por identificador hasheado); `checkRateLimit` cobre
|
||||
o webhook de captação e o dispatcher de IA. **Crons e MCP seguem sem.** Meça antes de agir:
|
||||
|
||||
@@ -435,7 +435,7 @@ Checks **obrigatórios** na branch protection da `main` (verificado na configura
|
||||
python3 -c "import sys,re; y=sys.stdin.read(); print(sorted({s for _,c in re.findall(r'(FORA_DO_CI):\s*>-\n((?:[ ]{8,}.*\n)+)',y) for s in re.findall(r'[a-z0-9-]+\.spec\.ts',c)}))"
|
||||
```
|
||||
|
||||
Esta frase já dizia "a **única** de fora é `vps-fresh-onboarding`" e estava errada: em 2026-09-04 a variável listava **duas** (`inbox-tempo-real` entrou depois). É o mesmo defeito que o parágrafo acima descreve — afirmação de estado que envelhece —, cometido na frase seguinte à que o denuncia. O que continua verdade e é o que importa: `vps-fresh-onboarding` é a **P0** da doutrina de QA Visual, então `e2e` verde **não** prova a jornada de instalação fresca, que é o produto que se vende.
|
||||
Esta frase já dizia "a **única** de fora é `vps-fresh-onboarding`" e estava errada: em 2026-09-04 a variável listava **duas** (`inbox-tempo-real` entrou depois). É o mesmo defeito que o parágrafo acima descreve — afirmação de estado que envelhece —, cometido na frase seguinte à que o denuncia. E a frase que a substituiu envelheceu do mesmo jeito: afirmava que `e2e` verde **não** prova a jornada de instalação fresca, porque a `vps-fresh-onboarding` — a **P0** da doutrina de QA Visual — estava fora. Valeu até 2026-09-19; desde o PR #983 ela roda na `SPECS_PARTE_4`. Em vez de uma terceira frase de estado, a pergunta que importa — *o `e2e` verde cobre a instalação fresca?* — se responde com o comando acima: se `vps-fresh-onboarding` não está na saída, ela roda, porque `tests/unit/e2e-cobertura-completa.test.ts` reprova spec que não esteja nem numa `SPECS_PARTE_*` nem na `FORA_DO_CI`. A ressalva do começo do item continua de pé: em PR que pula as partes, o verde não prova tela nenhuma — a da instalação fresca inclusive.
|
||||
|
||||
**Não confie em `grep` no arquivo inteiro.** `grep -oE '[a-z0-9-]+\.spec\.ts' .github/workflows/e2e.yml | sort -u | wc -l` conta quem é CITADO, não quem é INVOCADO: a `FORA_DO_CI` é uma variável YAML como as outras e entra na conta. (Até 2026-08-14 este parágrafo culpava "menções em comentários", e isso é falso — medido, o conjunto de specs citadas fora de variável é **vazio**.) O que roda são as `SPECS_PARTE_*`:
|
||||
|
||||
|
||||
+14
-1
@@ -169,6 +169,18 @@ protection em 2026-08-13 e saiu desta lista em 2026-08-14.)*
|
||||
|
||||
### 4.1 Os E2E quase não rodam no CI 🟠 — parcialmente resolvido em 2026-07-30
|
||||
|
||||
> **Atualização (2026-09-19, PR #983):** a `vps-fresh-onboarding` saiu da `FORA_DO_CI` e passou
|
||||
> a rodar no CI, na `SPECS_PARTE_4` do `e2e.yml`, sozinha numa parte. Tudo abaixo que a dá como
|
||||
> fora, ou que conclui que "`e2e` verde não prova a instalação fresca", é registro de antes
|
||||
> dessa data. Uma ressalva continua valendo: PR que não alcança o `e2e` (regra em
|
||||
> `scripts/pr-alcanca-o-e2e.sh`) pula as partes, e ali o verde não prova tela nenhuma. O que
|
||||
> fica fora hoje não se lê deste documento — meça:
|
||||
>
|
||||
> ```bash
|
||||
> git show origin/main:.github/workflows/e2e.yml | \
|
||||
> python3 -c "import sys,re; y=sys.stdin.read(); print(sorted({s for _,c in re.findall(r'(FORA_DO_CI):\s*>-\n((?:[ ]{8,}.*\n)+)',y) for s in re.findall(r'[a-z0-9-]+\.spec\.ts',c)}))"
|
||||
> ```
|
||||
>
|
||||
> **Atualização (2026-08-14 @ `741c4ec8`):** `e2e.yml` roda **45 das 46 specs**, e o `e2e` **é
|
||||
> check obrigatório** na branch protection desde 2026-08-08 (junto com `verify`,
|
||||
> `build-and-size`, `invariants` e `imagens-ok` — **cinco**). A única spec fora é
|
||||
@@ -192,7 +204,8 @@ O que continua fora (2026-08-14): **1 das 46 specs Playwright**. A
|
||||
rodar** no `e2e.yml`. Mas a `vps-fresh-onboarding.spec.ts` — a jornada que a doutrina de QA
|
||||
Visual classifica como o caminho mais crítico do produto — continua fora, porque exige WAHA +
|
||||
Redis + Resend + Nuvemshop no runner. Regressão nela passa sem detecção (issue #63), e é por
|
||||
isso que **`e2e` verde não prova a instalação fresca**.
|
||||
isso que **`e2e` verde não prova a instalação fresca**. *(Superado em 2026-09-19 pelo PR #983 —
|
||||
ver a atualização no topo desta seção.)*
|
||||
|
||||
O `e2e` **é** check obrigatório desde 2026-08-08; um PR que o quebre não entra na `main`.
|
||||
|
||||
|
||||
+18
-2
@@ -53,7 +53,7 @@ verificados por leitura de arquivo, config e workflow.
|
||||
| H2 — Reproduzível | ✅ | Quickstart no README, `docs/SETUP.md`, `.nvmrc` (22), `packageManager` fixo, `pnpm-lock.yaml`, `docker-compose.yml`, `install.sh` do kit self-host, `baseline.sql` |
|
||||
| H3 — Verificável | ✅ | `lint` + `typecheck` + `test:unit` + `build`; CI roda os 3 primeiros em PR |
|
||||
| H4 — Preparado para agentes | ✅ | `CLAUDE.md` doutrinal forte; `AGENTS.md` **criado nesta auditoria**; documentação técnica extensa; **e o CI roda o gate de isolamento RLS** (job `invariants` → `pnpm test:db`) |
|
||||
| H5 — Automação avançada | ⚠️ **parcial** | CI confiável e ambiente isolado ✅ (Postgres efêmero pg15, worktrees, gov-loop com maker≠checker e hash-check). Falta: **1 das 46 specs E2E fora do CI** (45 rodam via `e2e.yml`, **obrigatório desde 2026-08-08**; a de fora é `vps-fresh-onboarding`, que é justamente a P0), `format:check` fora do CI, e o comando único local (`gov:verify`) não cobre `test:db`/`test:e2e`. *(Números recontados em 2026-08-14 @ `741c4ec8`; a redação anterior — "4 das 32, não-obrigatório" — apodreceu.)* |
|
||||
| H5 — Automação avançada | ⚠️ **parcial** | CI confiável e ambiente isolado ✅ (Postgres efêmero pg15, worktrees, gov-loop com maker≠checker e hash-check). Falta: **1 das 46 specs E2E fora do CI** (45 rodam via `e2e.yml`, **obrigatório desde 2026-08-08**; a de fora é `vps-fresh-onboarding`, que é justamente a P0), `format:check` fora do CI, e o comando único local (`gov:verify`) não cobre `test:db`/`test:e2e`. *(Números recontados em 2026-08-14 @ `741c4ec8`; a redação anterior — "4 das 32, não-obrigatório" — apodreceu.)* *(Nota de 2026-09-19: a `vps-fresh-onboarding` deixou de estar fora — desde o PR #983 roda na `SPECS_PARTE_4`. O que fica fora hoje: ver a nota logo abaixo de "O que separa de H5".)* |
|
||||
|
||||
**Por que H4 e não H5:** a instrução da auditoria é explícita — não atribuir nível só
|
||||
porque os arquivos existem, avaliar se o processo está implementado. Aqui está: o gate de
|
||||
@@ -67,6 +67,17 @@ como o caminho mais crítico do produto. E `pnpm gov:verify`, o comando único q
|
||||
naturalmente usa como critério de pronto, **não** inclui `test:db` nem `test:e2e`: o CI
|
||||
pega o que ele deixa passar, mas só depois do push.
|
||||
|
||||
> **Nota de 2026-09-19 (PR #983):** a `vps-fresh-onboarding.spec.ts` citada acima como fora do
|
||||
> CI passou a rodar na `SPECS_PARTE_4` do `e2e.yml`. Em PR que alcança o `e2e` (regra em
|
||||
> `scripts/pr-alcanca-o-e2e.sh`), o verde agora cobre a jornada de instalação fresca; em PR
|
||||
> que pula as partes, continua não provando tela nenhuma. O parágrafo acima é retrato de antes
|
||||
> e fica como está. O que fica fora hoje não se lê deste documento — meça:
|
||||
>
|
||||
> ```bash
|
||||
> git show origin/main:.github/workflows/e2e.yml | \
|
||||
> python3 -c "import sys,re; y=sys.stdin.read(); print(sorted({s for _,c in re.findall(r'(FORA_DO_CI):\s*>-\n((?:[ ]{8,}.*\n)+)',y) for s in re.findall(r'[a-z0-9-]+\.spec\.ts',c)}))"
|
||||
> ```
|
||||
|
||||
**O que puxa este projeto para cima e é incomum num CRM open-source:** doutrina escrita e
|
||||
específica (`CLAUDE.md`), Definition of Done de 13 itens, **56 arquivos de invariantes de
|
||||
banco**, gate de install+update do `baseline.sql` num Postgres descartável rodando em CI,
|
||||
@@ -93,7 +104,7 @@ Legenda: ✅ existente e funcional · ⚠️ existente mas incompleto · ❌ nã
|
||||
| 10 | Checagem de tipos | ✅ | `pnpm typecheck` (`tsc --noEmit`, TS 6 estrito), roda no CI |
|
||||
| 11 | Testes unitários | ✅ | 221 arquivos `*.test.ts(x)`; `pnpm test:unit` no CI |
|
||||
| 12 | Testes de integração | ✅ | **56 arquivos** de invariantes em `tests/invariants/` + `tests/api/`. Excluídos do `test:unit` de propósito (`vitest.config.ts:12`) e rodados pelo job `invariants` do CI via `pnpm test:db` |
|
||||
| 13 | Testes E2E | ⚠️ | 20 specs Playwright. **10 rodam no CI** (`e2e.yml`, ainda não-obrigatório), incluindo o P0 `vps-webhook-outbound-ssrf`; o P0 `vps-fresh-onboarding` continua fora (issue #63) |
|
||||
| 13 | Testes E2E | ⚠️ | 20 specs Playwright. **10 rodam no CI** (`e2e.yml`, ainda não-obrigatório), incluindo o P0 `vps-webhook-outbound-ssrf`; o P0 `vps-fresh-onboarding` continua fora (issue #63) *(Nota de 2026-09-19: desde o PR #983 ela roda na `SPECS_PARTE_4` — ver a nota logo abaixo de "O que separa de H5".)* |
|
||||
| 14 | Comando único de verificação | ⚠️ | `pnpm gov:verify` = `typecheck && lint && test:unit`. **Omite `test:db` e `test:e2e`** — verde localmente não significa verificado. O CI cobre `test:db`, mas só depois do push |
|
||||
| 15 | CI executando verificações | ✅ | `ci.yml` tem 2 jobs: `verify` (typecheck + lint + test:unit) e **`invariants` (`pnpm test:db` — isolamento RLS + invariantes de governança, em job paralelo com timeout de 20min)**. Falta E2E e `format:check`. `perf.yml` faz build + bundle size; `publish-image.yml` publica no GHCR |
|
||||
| 16 | Proteção contra secrets | ⚠️ | `.gitignore` cobre `.env*` (exceção só para os `.example`) e o Sentry tem `beforeSend` que higieniza PII. **Sem** gitleaks/trufflehog no CI, **sem** pre-commit hook |
|
||||
@@ -123,6 +134,11 @@ doutrina classifica como o caminho mais crítico do produto, e
|
||||
`vps-webhook-outbound-ssrf.spec.ts` é a única prova automatizada do guard de SSRF. Rodar
|
||||
em PR pode ser lento; um workflow nightly + trigger manual já elimina a regressão silenciosa.
|
||||
|
||||
> **Nota de 2026-09-19:** as duas specs que este item cita entraram no CI obrigatório, em PR — não
|
||||
> num nightly: a `vps-webhook-outbound-ssrf.spec.ts` entrou antes (item 13 da tabela acima), e a
|
||||
> `vps-fresh-onboarding.spec.ts` entrou no PR #983, na `SPECS_PARTE_4`. O que ainda fica fora:
|
||||
> ver a nota logo abaixo de "O que separa de H5".
|
||||
|
||||
### 2. Renomear/reforçar o comando único 🟠 · custo: 2 linhas
|
||||
|
||||
Duas opções: (a) `gov:verify` passa a incluir `test:db` (exige Docker em toda máquina de
|
||||
|
||||
Reference in New Issue
Block a user