mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
docs(testing-audit): relatório da run 2 + entrada de changelog (movimentos, fix do metrics, recidiva #906)
This commit is contained in:
parent
ee4ba83535
commit
5af65a2c84
2 changed files with 130 additions and 0 deletions
13
docs/changelog/2026-08-25-ops96-testing-audit-run2.md
Normal file
13
docs/changelog/2026-08-25-ops96-testing-audit-run2.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# 2026-08-25 — testing-audit run 2: 4 movimentos int→unit + fix do metrics, recidiva #906 com resíduo
|
||||
|
||||
Segunda execução da skill `/testing-audit` na mesma data (relatório `docs/testing-audits/2026-08-25-run2.md`; a run 1 vive em `2026-08-25.md`). Inventário por 3 leitores read-only → rubrica validada contra o fonte → 5 melhorias com prova verde antes/depois e commits separados, PR único ready SEM auto-merge (desarme via `testing-audit-disarm.mjs`, rearm pós-push):
|
||||
|
||||
1. **M1** — `payloadTransaction` int→unit (10 testes; stub puro, zero Payload/DB).
|
||||
2. **M2** — `contactPhoneNormalization` int→unit (4; hook do Contact via stub).
|
||||
3. **M3** — pins zod de `municipalityUpdateCreateSchema` extraídos do spec int que boota Payload → unit (2; Local API permanece int).
|
||||
4. **M4** — helpers puros de identidade do `campaignAuth.int.spec` (telefone/schema/whatsapp/guarda de migração) → unit (13; RBAC do arquivo intacto).
|
||||
5. **F1** — `parseVitestStdout` no core do metrics: suite vermelha voltou a imprimir o retrato (sufixo `ELIFECYCLE` do pnpm quebrava o parse; +5 testes unit no spec do core).
|
||||
|
||||
Conservação exata em todos os movimentos (unit+int = 3361). Nenhum teste removido; intocáveis (LGPD/RBAC/lockdown/e2e/estruturais) sem diff.
|
||||
|
||||
**Flake #906 recidivou com nova assinatura**: 7 runs full verdes → 8 runs com falhas só na família Google Calendar (1 falha com `VITEST_MAX_WORKERS=1`); `google_calendar_sync` acumula 38 linhas de resíduo por run full e o teste "no-op…not-configured" (`googleCalendarSyncAction.int.spec.ts:145`) lê doc residual; `db:reset` não curou. Fixes pertencem à Issue #906; nada editado na família à noite.
|
||||
117
docs/testing-audits/2026-08-25-run2.md
Normal file
117
docs/testing-audits/2026-08-25-run2.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Testing audit — 2026-08-25 (run 2)
|
||||
|
||||
Segunda execução da skill `/testing-audit` na mesma data da primeira noite (`2026-08-25.md`, PR #907). Como o arquivo `<YYYY-MM-DD>.md` já existia commitado com o relatório da run 1, esta noite usa o sufixo `-run2` para preservar os dois relatórios — única divergência do template (anotada aqui por transparência).
|
||||
|
||||
## Sumário executivo
|
||||
|
||||
- **4 movimentos int→unit aplicados (29 testes)** com conservação exata: unit+int = 3361 testes em todos os passos. Nenhum teste removido, nenhum enfraquecido.
|
||||
- `payloadTransaction` (10) — stub puro do wrapper de transação, zero Payload/DB.
|
||||
- `contactPhoneNormalization` (4) — hook do Contact exercitado via stub.
|
||||
- `municipalityUpdateCreateSchema` (2) — pins puros de zod extraídos do spec int que boota Payload.
|
||||
- `campaignAuthIdentity` (13) — helpers de identidade (telefone/schema/whatsapp/guarda de migração) extraídos do `campaignAuth.int.spec`; RBAC do arquivo intacto.
|
||||
- **1 fix no tooling first-party**: `parseVitestStdout` no core do metrics — suite vermelha agora imprime o retrato (contrato do próprio script), tolerando o sufixo `ELIFECYCLE` do pnpm. +5 testes unit no spec do core.
|
||||
- **Recidiva do flake #906 com nova assinatura**: após 7 runs full verdes no início da noite, a família Google Calendar passou a falhar de forma persistente sob a mesma carga; com `VITEST_MAX_WORKERS=1` o fracasso colapsa em UM teste determinístico (`googleCalendarSyncAction` "no-op…not-configured") causado por ~38 linhas de resíduo em `google_calendar_sync` deixadas pelo spec C114 num único run full. Reset completo do DB de teste (`db:reset`, OPS88) não resolveu — a família recria o resíduo dentro do próprio run. Evidência em #906 via relatório (sem escrita no tracker).
|
||||
- Nenhuma edição em: intocáveis absolutos (LGPD/RBAC/lockdown de liderança), intocáveis estruturais (ci-scope, e2e-manifest, workflows, husky), specs e2e, e nenhuma remoção autônoma de teste.
|
||||
- 0 passos revertidos.
|
||||
|
||||
## Metodologia e tetos respeitados
|
||||
|
||||
Fases: baseline (13:43) → inventário paralelo (3 leitores Task read-only, ~25min) → rubrica com validação de cada achado contra o fonte (~25min) → loop de melhorias sequencial (5 passos) → fecho. Tetos: budget ~6h ✓ (uso real ≈ 2h); ≤6 melhorias ✓ (5); ≤45min inventário ✓; ≤30min/passo ✓ (passo mais longo: ~8min); debug de AFTER ≤10min ✓ (nenhum AFTER falhou — as falhas posteriores são do flake conhecido, não das edições).
|
||||
|
||||
## Retrato da suíte
|
||||
|
||||
### Baseline (13:43–13:44, SHA 8199e2ee)
|
||||
|
||||
| camada | arquivos | testes | parede |
|
||||
| ------ | -------: | -----: | ---------: |
|
||||
| unit | 277 | 2620 | 30,9s |
|
||||
| int | 80 | 741 | 51,4s |
|
||||
| e2e | 44 | 208 | não medido |
|
||||
|
||||
### Final (SHA deste PR, 008b1ee7)
|
||||
|
||||
| camada | arquivos | testes | parede |
|
||||
| ------ | -------: | -----------: | ---------: |
|
||||
| unit | 281 (+4) | 2654 (+34)\* | 40,8s |
|
||||
| int | 78 (−2) | 712 (−29) | ~184s† |
|
||||
| e2e | 44 (=) | 208 (=) | não medido |
|
||||
|
||||
\* +29 movidos +5 novos do `parseVitestStdout`. Conservação global nos passos de movimento: unit+int = 3361 constante.
|
||||
† parede int na medição vermelha (flake); a parede verde do mesmo SHA foi 51,4s.
|
||||
|
||||
Top-8 unit mais lentas no SHA final (tabela completa: `node scripts/testing-audit-metrics.mjs unit --top 15`):
|
||||
|
||||
| arquivo | testes | duração | teste mais lento |
|
||||
| --------------------------------------------------- | -----: | ------: | ---------------------------------------------------------------- |
|
||||
| tests/unit/activityOverlay.unit.spec.tsx | 14 | 4,7s | troca dia no calendário e hora/minuto nos selects inline… (2,0s) |
|
||||
| tests/unit/petitionLead.unit.spec.tsx | 4 | 2,6s | fires exactly one Lead… (1,2s) |
|
||||
| tests/unit/municipalityRelationEditor.unit.spec.tsx | 9 | 2,4s | serializes same-cell mutations… (0,7s) |
|
||||
| tests/unit/campaignCellEditOverlay.unit.spec.ts | 19 | 2,0s | opens 'tendência' in a Drawer… (0,3s) |
|
||||
| tests/unit/eslintConventions.unit.spec.ts | 12 | 2,0s | enforces PascalCase… (1,7s) |
|
||||
| tests/unit/campaignQuickActionsDrawer.unit.spec.tsx | 15 | 1,8s | posts home-search… (0,4s) |
|
||||
| tests/unit/campaignColumnPicker.unit.spec.ts | 8 | 1,4s | batches a whole editing session… (0,4s) |
|
||||
| tests/unit/codebaseConventions.unit.spec.ts | 25 | 1,3s | keeps conflict markers out… (0,9s) |
|
||||
|
||||
Cobertura diagnóstica disponível sob flag (nunca regra): `pnpm vitest run --config ./vitest.unit.config.mts --coverage <filtro>`.
|
||||
|
||||
## Disposições
|
||||
|
||||
| id | camada | candidato | disposição | prioridade | prova/decisão |
|
||||
| ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| M1 | int→unit | payloadTransaction.int.spec (10 testes, stub de `Payload['db']`, zero DB) | mover ✓ | alta | `tests/int/payloadTransaction.int.spec.ts:23-43` stubs; conservação +10/−10 |
|
||||
| M2 | int→unit | contactPhoneNormalization.int.spec (hook do Contact via stub, `importOriginal`) | mover ✓ | alta | `tests/int/contactPhoneNormalization.int.spec.ts:24-35`; conservação +4/−4 |
|
||||
| M3 | int→unit | 2 pins zod de municipalityUpdateCreateSchema dentro de spec que boota Payload | mover ✓ | alta | `tests/int/campaignMunicipalityUpdate.int.spec.ts:71-140` puros; Local API (:142+) permanece int |
|
||||
| M4 | int→unit | helpers puros de identidade no campaignAuth.int.spec (telefone/schema/whatsapp/migração) | mover ✓ | alta | blocos :441-452 e :551-603 sem payload; RBAC :454-549 intocado; conservação +13/−13 |
|
||||
| F1 | tooling | metrics CLI morria em suite vermelha (sufixo ELIFECYCLE do pnpm quebrava o JSON.parse) | reforçar ✓ | média | contrato do próprio script ("a red suite still prints its portrait"); `parseVitestStdout` no core + 5 tests |
|
||||
| P1 | unit | catálogos quick-action repinados (registry × domínio × v2) | proposta | baixa | U1/U3: seams distintos como na run 1 (K1) — duplicata não comprovada |
|
||||
| P2 | unit | scan de conflict-markers pinado em codebaseConventions + conflictMarkers.unit + CI | proposta | baixa | U2: o describe do codebaseConventions roda `git ls-files` inteiro a cada run |
|
||||
| P3 | unit | 6 specs do agent-pool sobre scripts dormentes (OPS65) | proposta | baixa | U6: decisão de produto (remover ou suíte "dormant" separada) |
|
||||
| P4 | int | origin policy pinada 2× (campaignInvite.int :393-550 × campaignInviteOrigin.unit) | proposta | média | I6: casos únicos em cada lado — merge exige toque em arquivo com conteúdo consent (369-391 intocável) |
|
||||
| P5 | int | campaignInvite.int :298-607 blocos puros (token/whatsapp/schema) | proposta | média | I5: split parcial em arquivo com consent e RBAC — risco > valor à noite |
|
||||
| P6 | int | cleanup de fixtures pinado 2× (campaignFixtures × campaignFixturesRowCounts) | proposta | baixa | I7: variante row-count estritamente mais forte; remoção exige prova forte |
|
||||
| P7 | unit | campaignLoginAction asserta mock contra mock (`objectContaining({ login: mocks.login })`) | manter | baixa | U4: pin fraco, inofensivo; os pins reais (mapeamento/TTL) têm valor; remover asserção não é reforçar |
|
||||
| P8 | unit | campaignAuthMemoization reimplementa `react.cache` num Map caseiro | manter | baixa | U5: asserção de identidade de promise (:69) é o sinal real; limitação documentada |
|
||||
| P9 | unit | eslintConventions/codebaseConventions/campaignCompositionCleanup pesados (ESLint real, scans full-tree) | manter | baixa | U7/U8/U10: locks de convenção com valor alto; otimização é proposta, não melhoria noturna |
|
||||
| E1–E12 | e2e | inventário: duplicatas com int (C113 agenda feed, C130 party facet, TTL×3, C143, C88), http-disfarçados, setup.e2e prewarm morto | proposta | variada | leitor e2e; e2e nunca editado/executado à noite — trilho OPS87/medição para as duplicatas HTTP |
|
||||
|
||||
Intocáveis varridos e intactos: consentimento/LGPD (hash do consent no campaignInvite mantido no lugar), RBAC (`campaignAuth` :454-549, lockdown de liderança, I9 triple-pin mantido), intocáveis estruturais sem diff.
|
||||
|
||||
## Evidências verde antes/depois
|
||||
|
||||
| passo | antes | depois | commit |
|
||||
| ----- | --------------------------------------- | ---------------------------------------------------------- | -------- |
|
||||
| M1 | 13:54:34 unit 277/2620 ✓ · int 80/741 ✓ | 13:56:04 unit 278/2630 ✓ · int 79/731 ✓ (conservação 3361) | 7de9822f |
|
||||
| M2 | = anterior | 13:57:42 unit 279/2634 ✓ · int 78/727 ✓ (conservação 3361) | adcfb39a |
|
||||
| M3 | = anterior | 13:59:40 unit 280/2636 ✓ · int 78/725 ✓ (conservação 3361) | d8866d90 |
|
||||
| M4 | = anterior | 14:01:47 unit 281/2649 ✓ · int 78/712 ✓ (conservação 3361) | 62a7dab8 |
|
||||
| F1 | spec core isolado 10/10 ✓ | 14:09:29 spec core 15/15 ✓ · unit full 281/2654 ✓ | 008b1ee7 |
|
||||
|
||||
Provas executadas bare (nunca piped). A partir de 14:05 os runs full de int passaram a falhar APENAS na família #906 (ver abaixo) — as provas AFTER de M1–M4 são anteriores ao surto e verdes.
|
||||
|
||||
## Flake #906 — recidiva com nova assinatura (evidência desta noite)
|
||||
|
||||
- 7 runs full verdes (13:43–14:03) → 8 runs seguintes com falhas na família Google Calendar: 25 falhas com workers default (14:05, 14:07, 14:12), 25 com `VITEST_MAX_WORKERS=4` (14:10), 1 falha com `VITEST_MAX_WORKERS=1` (14:14, 14:18, 14:22, 14:36).
|
||||
- A família isolada segue verde (14:13:45 `googleCalendarSync` 25/25 em 7,8s) — mesma assinatura "verde isolada, vermelho full" da noite anterior.
|
||||
- **Nova evidência causal**: `google_calendar_sync` acumulou **38 linhas de resíduo** após um único run full; o teste `googleCalendarSyncAction.int.spec.ts:121-146` ("no-op…not-configured") apaga só 1 doc stale (`limit: 1` no :124-131) e o action então lê outro doc residual → `expected 'synced' to be 'not-configured'` (:145). A hipótese: o afterChange do engine recria docs de config depois do cleanup do spec (corrida hook × passes), e o resíduo faz a falha persistir entre runs.
|
||||
- `db:reset` completo (OPS88, 14:12) NÃO curou — a família recria o resíduo dentro do próprio run.
|
||||
- **Conclusão**: recidiva do #906 com evidência de resíduo nova; os fixes pertencem ao trilho da Issue (Fase 1 planejada: assertar `outcome.status === 'synced'` na família; a esta evidência soma-se: cleanup do no-op deve apagar TODOS os docs stale, e a família precisa de tear-down resiliente ao hook). Nada editado nesta família à noite.
|
||||
|
||||
## Propostas não executadas (com razão)
|
||||
|
||||
| proposta | por quê não executou |
|
||||
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| P1/P2/P3 (unit: catálogos re-pinados, scan de markers, agent-pool dormente) | decisão de produto/consolidação exige humano; scans de convenção têm valor de lock |
|
||||
| P4/P5 (int: origin policy 2×, blocos puros do campaignInvite) | split parcial em arquivo com consent/RBAC — risco > valor no turno noturno |
|
||||
| P6 (int: cleanup de fixtures 2×) | remoção exige prova forte; variante row-count é mais forte, mas duplicata parcial |
|
||||
| E1–E12 (e2e) | e2e é inventariado, nunca executado/editado à noite; trilho OPS87 + medição para as HTTP |
|
||||
| Otimizações de latência (U7/U8/U10: cache de scans, tier de conventions) | refactor de specs de convenção sem ganho de cobertura — proposta, não melhoria segura |
|
||||
|
||||
Descartados pela triage (sem valor real): P7/P8/P9 (manter — ver disposições); dedup de sugestões wizard×home-search (I8, seams distintos); triple-pin de lockdown (I9, intocável).
|
||||
|
||||
## Estado final do PR
|
||||
|
||||
Preenchido na Fase 5 (ver seção de desarme abaixo).
|
||||
|
||||
## Fase 5 — desarme do auto-merge
|
||||
|
||||
Protocolo determinístico desta skill: criação ready → desarme → verificação `autoMergeRequest === null && isDraft === false` num ÚNICO comando (`scripts/testing-audit-disarm.mjs`), repetido imediatamente após cada push, nunca "aguardar o CI" para desarmar. Status preenchido abaixo após o fecho.
|
||||
Loading…
Reference in a new issue