From 36d9abe8c0d767af587afbf6dee9e997056dae0d Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Tue, 15 Sep 2026 15:30:25 -0300 Subject: [PATCH] =?UTF-8?q?docs(plans):=20OPS111=20auto-unblock=20setup=20?= =?UTF-8?q?+=20B32/B34=20lideran=C3=A7as=20verify=20(Related=20#1035,=20Re?= =?UTF-8?q?lated=20#1036)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../b32-b34-liderancas-estabilidade-verify.md | 81 +++++++++++++++++++ ...s111-auto-unblock-homeserver-setup-node.md | 79 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 docs/plans/b32-b34-liderancas-estabilidade-verify.md create mode 100644 docs/plans/ops111-auto-unblock-homeserver-setup-node.md diff --git a/docs/plans/b32-b34-liderancas-estabilidade-verify.md b/docs/plans/b32-b34-liderancas-estabilidade-verify.md new file mode 100644 index 00000000..85121110 --- /dev/null +++ b/docs/plans/b32-b34-liderancas-estabilidade-verify.md @@ -0,0 +1,81 @@ +# B32/B34 — Raiz dos testes de lideranças que quebraram o verify 3 runs seguidos (regressão ou flake sob carga) + +Status: rascunho +Atualizado em: 2026-09-15 +Issue: #1036 (blocked via --plan — promover com agent:ready após merge em main) +Priority: P1 (proposto — validar no gate; alternativa P2 abaixo) +Impeccable: A — N/A sem UI +Rascunho UI: N/A — sem UI +Appetite: ~1–2 dias eng (diagnóstico + fix + prova verde) +Responsável: — + +## Intenção + +Quero saber por que a lista de lideranças quebrou o deploy três vezes seguidas — o auto-save do status (B32) e os chips de municípios (B34) falhando até o retry #2 — e se foi regressão real da trilha C165/B32-B34 ou só flake sob carga. Quero o diagnóstico com prova verde, sem mexer no contrato de deploy. + +## Persona e fluxo + +- **Persona / contexto:** equipe de campanha que usa `/campanha/liderancas` todo dia + quem opera o deploy em `main` e hoje vê o `verify` vermelho sem saber se pode aprovar. +- **Job principal:** confiar que o `verify` full verde significa que a lista de lideranças está estável. +- **Fluxo desejado:** merge em `main` → `verify` full roda → B32 e B34 passam de primeira → deploy segue sem retry manual nem investigação de log. +- **Anti-goals de produto:** não virar redesign da lista de lideranças; não virar segundo mecanismo de estabilidade paralelo ao `verify`. + +## Objetivo e aceite + +- Diagnosticado se B32/B34 é regressão real (ex.: via C165-F1) ou flake sob carga (4 workers), com evidência nos logs dos 3 runs. +- `tests/e2e/campaignLeaderships.e2e.spec.ts:15` (B32) e `:59` (B34) passam de forma estável no `verify` full (hosted, 4 workers). +- Guardrails: sem mudar contrato de deploy; sem mudar comportamento visível da lista salvo se o diagnóstico provar que a UI é a causa (ver Fora de escopo); HEAD atual segue verde — isto é anti-recorrência. + +## Dados (intenção) + +- **Vou apresentar dados?** Não — item de estabilidade de suíte, sem métrica, contagem ou ranking novo. +- **Decisões desbloqueadas:** nenhuma decisão de campanha; a decisão desbloqueada é operacional (aprovar deploy com `verify` verde). +- **Forma:** _adiada ao plano de implementação_ — aqui só a restrição de produto: leitura de estabilidade é no `verify` full, nunca em run local isolado. + +## Dados da decisão (literais) + +- `tests/e2e/campaignLeaderships.e2e.spec.ts:15` (B32 — POST `/campanha/liderancas/support-status`) +- `tests/e2e/campaignLeaderships.e2e.spec.ts:59` (B34 — POST `/campanha/liderancas/municipalities`) +- Runs deploy-push em `main` com `verify` vermelho: `34997300602` (sha `8dece9cd`, "fix(C165-F1)"), `34991826170` (sha `2e2813fe`), `34984805702` (sha `897154b`) +- Contagens run `34997300602`: 232 tests, 1 failed / 227 passed; B32 falha persistente (fail + retry #1 + retry #2) +- B34 passou no retry no run `34997300602`, falhou até retry #2 no run `34991826170` +- Falhas vizinhas nos mesmos runs: `campaignActivity:525` (badge "Sem município", C165), `campaignAiChatResize:44`, `campaignColumnPicker:21`, `campaignMunicipalities:659` (advisor scopes), `campaignSavedFilters:35`, `campaignActivity:55` +- JobIds para logs: `104476711539`, `104458195479`, `104434116739` via `gh api repos/fsolla/teqo/actions/jobs//logs` +- HEAD atual `13aeb9bb` está verde — anti-recorrência + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** specs em `tests/e2e/campaignLeaderships.e2e.spec.ts` + helpers `campaignE2EFixtures.ts` / `expectPostResponse`; rotas `/campanha/liderancas/support-status/` e `/campanha/liderancas/municipalities/` (+ `state-deputies/`); células `LeadershipListSupportStatusControl.tsx`, `LeadershipMunicipalitiesColumnCell.tsx`, `LeadershipStateDeputiesColumnCell.tsx` sobre `shared/RelationChipCell.tsx` / `MunicipalityPortfolioCell`; actions `liderancas` + schemas. +- **Precedente a olhar:** `docs/plans/autosave-status-lista-liderancas.md` (B32) e `docs/plans/chips-municipios-lista-liderancas.md` (B34) — contexto, não suspeitos; OPS83 `#824` já listava `campaignLeaderships:59` (B34); `docs/plans/e2e-flake-cast-rotativa-pos-ops83-impl.md` (o que o #882 cobre — NÃO cobre B32/B34). +- **Risco de acoplamento:** leader lockdown e escopos de assessor nas células da lista; não afrouxar access para fazer o spec passar. + +## Dependências + +- Nenhuma dura. +- Soft: #882 (cast rotativa C131/B176/B197/concepts — escopo distinto, NÃO cobre B32/B34 persistentes); #878 (open, C145 — mesma família de células, outra superfície `/pessoas`); C165 #1010 + C165-F1 #1030 closed/in-prod (regressão via C165-F1 é hipótese, não fato). + +## Fora de escopo + +- Contrato de deploy (workflow `deploy.yml`, jobs `verify`/`deploy-staging`/`deploy-production`, runners) — sem mudança. +- Mudança de UI, salvo se o diagnóstico provar que a causa é visual/comportamental — **condição explícita:** se provar UI, o rascunho `docs/plans/b32-b34-liderancas-estabilidade-verify-ui-draft.html` vira obrigatório antes do registro. +- Reescrita ampla dos specs B32/B34 ou de outras superfícies da cast (`campaignActivity`, `campaignColumnPicker`, `campaignMunicipalities`) — vizinhos são evidência, não alvo. + +## Rabbit holes de produto + +- **Marcar como flaky / aumentar retry como curativo.** Se alguém "só completar": `verify` verde por tolerância, com a regressão viva embaixo. **Corte neste item:** retries e timeouts só entram com diagnóstico que prove flake sob carga; persistência 3/3 começa como regressão. +- **Reabrir a cast rotativa do #882.** Se alguém "só completar": este item vira segundo dono dos flakes C131/B176/B197. **Corte neste item:** #882 segue dono da cast; aqui só B32/B34 + vizinhos como evidência. + +## Questões em aberto (produto) + +- **Regressão real ou flake sob carga?** **Opções:** regressão real via trilha C165/C165-F1 | flake sob carga (4 workers, stream RSC / debounce). **Recomendação:** tratar como regressão até prova de flake, dado o 3/3 persistente do B32 até retry #2 — flake não repete idêntico três runs seguidos. _(assumido — validar com os logs no plano de implementação)_ +- **P1 ou P2?** **Opções:** P1 (classe que quebra `verify`/deploy, precedente #906 P1) | P2 (HEAD verde, anti-recorrência). **Recomendação:** P1 proposto — quebrou deploy 3x seguidas; rebaixar para P2 só se o gate mostrar que o HEAD verde já contém o fix. _(proposto — validar no gate)_ + +## Referências + +- GitHub Issue #1032 (reservado) +- Rascunho UI (gate): N/A +- `tests/e2e/campaignLeaderships.e2e.spec.ts` (specs `:15` B32 e `:59` B34) +- `docs/plans/autosave-status-lista-liderancas.md` (B32, precedente entregue) +- `docs/plans/chips-municipios-lista-liderancas.md` (B34, precedente entregue) +- `docs/plans/e2e-flake-cast-rotativa-pos-ops83-impl.md` (o que o #882 cobre) +- `AGENTS-campaign.md` — camada relevante diff --git a/docs/plans/ops111-auto-unblock-homeserver-setup-node.md b/docs/plans/ops111-auto-unblock-homeserver-setup-node.md new file mode 100644 index 00000000..320d2e61 --- /dev/null +++ b/docs/plans/ops111-auto-unblock-homeserver-setup-node.md @@ -0,0 +1,79 @@ +# OPS111 — Auto-unblock volta a despachar no homeserver (fix do setup pnpm/Node 18) + +Status: rascunho +Atualizado em: 2026-09-15 +Issue: #1035 (blocked via --plan — promover com agent:ready após merge em main) +Priority: P1 (proposto — validar no gate; alternativa P2 abaixo) +Impeccable: A — N/A sem UI +Rascunho UI: N/A — sem UI +Appetite: ~0,5 dia eng; um outcome verificável +Responsável: — + +## Intenção + +O launcher do auto-unblock que o OPS106 entregou nunca chegou a rodar: toda vez que o `verify` fica vermelho, o job morre no setup de pnpm antes de despachar qualquer agente, e a rede de segurança do deploy está morta na prática. Quero que esse launcher saia do `pnpm/action-setup` quebrado no runner Node 18 do homeserver — reordenando o setup do Node 24 para antes, ou pinando/corepackando, o que for dono do concern — e volte a despachar. Nada além disso: sem auto-retry, sem aprovar produção sozinho. + +## Persona e fluxo + +- **Persona / contexto:** eu (mantenedor), com o deploy bloqueado por um `verify` vermelho e ninguém de plantão. +- **Job principal:** ver o auto-unblock despachar um único agente sozinho quando o `verify` falha. +- **Fluxo desejado:** `verify` de push em `main` falha → em minutos vejo o run `Auto-unblock` verde com o registro visível (Issue token ou comentário single-flight) linkando o run vermelho → um único agente `fix/*` trabalhando; se já há agente ativo, a nova falha só comenta. +- **Anti-goals de produto:** virar auto-heal de qualquer job; aprovar produção sozinho; reintroduzir retry automático do deploy. + +## Objetivo e aceite + +- O próximo `verify` vermelho de `push` em `main` gera um run `Auto-unblock: success` (nunca `failure` no setup) com token Issue `auto-unblock` ou comentário single-flight. +- O launcher chega a executar e despacha no máximo um agente por run vermelho, mantendo o single-flight do OPS106. +- Nenhum auto-retry ou auto-approve do deploy é introduzido (proibição do OPS104 continua valendo). +- Guardrails do OPS106 seguem intactos: sem tocar prod/staging, sem segundo agente simultâneo. + +## Dados (intenção) + +- **Vou apresentar dados?** Não — infraestrutura, sem métrica de produto. +- **Decisões desbloqueadas:** N/A — não há decisão de negócio; é reparo do encanamento operacional. +- **Forma:** N/A — sem superfície de dados neste item. + +## Dados da decisão (literais) + +- Step que falha: `pnpm/action-setup@v6` em `.github/workflows/auto-unblock.yml` (bloco das linhas 57–64), com `actions/setup-node@v5` (`node-version: 24`, `package-manager-cache: false`) declarado DEPOIS. +- Erro verbatim: `Node.js v18.19.1` no runner + `TypeError paths[0] undefined em @pnpm/exe/setup.js:64` — os scripts `scripts/auto-unblock.sh` / `scripts/auto-unblock.mjs` nunca rodaram. +- Runs Auto-unblock com essa falha: `34994058878`, `34987287001`, `34999635390` (+ `34971560192` como quarto exemplar); nenhum criou token Issue `auto-unblock`, nenhum subiu agente `fix/*`. +- HEAD de referência: SHA `13aeb9bb`, run `35002372682` com `verify` + staging success e production `waiting` — plano anti-recorrência, não desbloqueio imediato. +- Versões fixas: `packageManager pnpm@10.11.0` (`package.json:199`); runner homeserver em Node 18 vs alvo Node 24. +- Gatilho intocado: só falha do job `verify` de `.github/workflows/deploy.yml`, só `push` em `main`; sem auto-retry, sem auto-approve de production. +- Arquivos donos do concern: `.github/workflows/auto-unblock.yml` + validação; `deploy.yml` intocado (decisão D1 do impl plan do OPS106). + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** `.github/workflows/auto-unblock.yml` (ordem/setup do Node+pnpm no runner self-hosted do homeserver). +- **Precedente a olhar:** plano pai OPS106 (Issue #995, CLOSED/in-prod, imutável); workflows que vivem sem pnpm no runner (`issue-done-on-main-merge.yml:48-53`, `agent-pr-ready-automerge.yml:48-49`, `plan-issue-ready-on-main-merge.yml:56-58`); OPS23; `Dockerfile:7,28` (corepack) + postmortem `2026-09-13-deploy-staging-migrator-corepack.md`; pins `tests/unit/autoUnblockWorkflow.unit.spec.ts`, `tests/unit/autoUnblock.unit.spec.ts`; launcher `scripts/auto-unblock.sh → scripts/auto-unblock.mjs → scripts/auto-unblock-agent.mjs` + `scripts/lib/auto-unblock.mjs` (puros, intocados salvo necessidade). +- **Risco de acoplamento:** mexer só no setup do launcher; single-flight (token Issue + flock), guardrails de banco local e `deploy.yml` intocado não podem regredir. + +## Dependências + +- Nenhuma dura. Suave (herdada do pai): #882 (flakes de e2e em main) pode amplificar falso positivo do gatilho, mas não bloqueia. + +## Fora de escopo + +- Auto-retry / auto-heal / auto-dispatch do deploy; auto-approve de production. +- Qualquer mudança em `deploy.yml` (verify, staging, production, requeue). +- Ressurreição do pool de agentes (OPS65), tick agendado, dashboard/telemetria de agentes. +- Falhas de PR-CI e flakes de main (seguem em #882 e cia.). + +## Rabbit holes de produto + +- **"Já que o setup quebrou, reescrever o launcher".** Vira segundo dispatcher paralelo ao owner. **Corte neste item:** editar o owner, não duplicar. +- **"Aproveitar e dar retry no deploy junto".** Reabre o anti-goal do OPS104. **Corte neste item:** só o despacho voltar a funcionar. +- **"Cobrir todos os runners/versões de Node".** Vira matriz de compatibilidade. **Corte neste item:** só o runner homeserver + Node 24. + +## Questões em aberto (produto) + +- **Prioridade P1 ou P2?** **Opções:** P1 (rede de segurança do deploy está morta) | P2 (pai era P2 e o HEAD está verde). **Recomendação:** P1 — sem o despacho, o OPS106 não existe em produção; o HEAD verde só adia a próxima falha. _(proposto — validar com produto no gate)_ +- **Como provar o aceite sem quebrar main de propósito?** **Opções:** A) aguardar o próximo `verify` vermelho real | B) disparo manual controlado do workflow em run vermelho existente. **Recomendação:** A como aceite, B só como smoke se o executor julgar seguro e sem tocar prod. _(assumido — validar com produto)_ + +## Referências + +- GitHub Issue #1031 (reservado) +- Plano pai (imutável, só precedente): `docs/plans/ops106-auto-unblock-verify-falha-agente.md` (Issue #995) +- Owner a editar: `.github/workflows/auto-unblock.yml` +- `AGENTS-infra.md` (seção Auto-unblock do `verify`/OPS106)