diff --git a/README.md b/README.md index 659a0f9d..00d6194d 100644 --- a/README.md +++ b/README.md @@ -124,4 +124,4 @@ Internal campaign tool for electoral nuclei, local leaderships, vote estimates, ## Roadmap -Backlog and future plans live in [`docs/roadmap.md`](docs/roadmap.md) (blockers, public site, `/campanha` next cycles, admin RBAC, white-label). +Backlog and future plans live as tracked [GitHub Issues](https://github.com/fsolla/teqo/issues) (spec + deps + prio + model per issue; flow skills: `plan-issue` → `work-issue` → `project-status`; `docs/roadmap.md` is a frozen legacy stub). diff --git a/docs/AGENT-OPS.md b/docs/AGENT-OPS.md index c5693752..4adab044 100644 --- a/docs/AGENT-OPS.md +++ b/docs/AGENT-OPS.md @@ -19,23 +19,27 @@ claim → feature branch → PR --base stage → CI PR green → auto-merge em s stage → CI stage green → (humano) pnpm agent:promote --i-am-human → main → Vercel prod ``` -- **Agente faz sozinho:** `pnpm agent:claim` (pega a próxima Issue `ready` desbloqueada por `prio:P0..P3`, lock otimista ready→in-progress) → implementa → fast gate → `gh pr create --base stage` com `Closes #N` → **PARA**. PR para `stage` mergeia sozinho quando o CI fica verde (auto-merge nativo + protection em `stage`). +**Skills do fluxo (desde 2026-07-30):** `plan-issue` (ideia → plano completo + gate de confirmação + Issue via `agent:register --model`) → `work-issue` (claim → verificação de modelo → freshness audit → execução → /simplify → PR `--base stage` → acompanha CI até o merge) → `project-status` (overview/fila/mermaid/bloqueios/consolidação, read-only). `docs/roadmap.md` = **legado congelado** (stub); a fonte canônica são as GitHub Issues. + +- **Agente faz sozinho:** `pnpm agent:claim` (pega a próxima Issue `ready` desbloqueada por `prio:P0..P3`, lock otimista ready→in-progress) → implementa → fast gate → `gh pr create --base stage` com `Closes #N` → acompanha `gh pr checks --watch` até o merge (falha → corrige na mesma branch). O flip `in-progress→done` é determinístico no CI (workflow `issue-done-on-stage-merge.yml`). - **Só humano:** `pnpm agent:promote --i-am-human` (PR `stage→main` + merge com CI stage + ci-pr green; recusa se `main` divergiu de `stage` — merge main em stage antes), `pnpm db:refresh:stage` (refresh semanal do snapshot), editar envs Vercel/Neon, rodar `pnpm build` contra qualquer banco remoto. - Se `main` divergir de `stage` (hotfix): merge/rebase de `main` em `stage` + CI stage green de novo, só depois promote. +- **Engineering-audit é solitário:** quando roda, o paralelismo pausa (nenhum outro agente no repo) e o agente do audit executa as remediações P0/P1 na mesma sessão; inclui o harvest `kind:agent-miss` → guardrails. ## Comandos -| Comando | Faz | -| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `pnpm agent:claim [-- --dry-run]` | Fila ready+unblocked por prio → `in-progress` + brief no stdout. Deps sem Issue = itens entregues do roadmap (satisfeitas, avisadas no brief) | -| `pnpm agent:register -- --id X --title T [--prio P1] [--depends A,B] [--plan docs/plans/x.md]` | Cria Issue (spec + labels) | -| `pnpm agent:prioritize -- ` | Troca a label `prio:*` | -| `pnpm agent:file-miss -- --title ...` | Issue `kind:agent-miss` → harvest em guardrail (`docs/GUARDRAILS.md`) | -| `pnpm agent:promote -- --i-am-human` | **Humano:** PR `stage→main` + merge se CI green | -| `pnpm db:seed:minimal` | DB mínimo sintético (contrato: [`scripts/lib/seed-minimal-manifest.mjs`](../scripts/lib/seed-minimal-manifest.mjs), pin `tests/unit/seedMinimalManifest.unit.spec.ts`) | -| `pnpm db:refresh:stage` | **Humano:** nova Neon branch `stage` de prod + swap do secret `STAGE_DATABASE_URL` (requer `NEON_API_KEY`) | +| Comando | Faz | +| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `pnpm agent:claim [-- --dry-run]` | Fila ready+unblocked por prio → `in-progress` + brief no stdout. Deps sem Issue = itens entregues do roadmap (satisfeitas, avisadas no brief) | +| `pnpm agent:register -- --id X --title T [--prio P1] [--depends A,B] [--plan docs/plans/x.md] [--model slug]` | Cria Issue (spec + labels + frontmatter com `model:` quando informado) | +| `pnpm agent:status` | Read-only: overview, fila na ordem do claim (com `model:`), mermaid, bloqueios, sugestões de consolidação | +| `pnpm agent:prioritize -- ` | Troca a label `prio:*` | +| `pnpm agent:file-miss -- --title ...` | Issue `kind:agent-miss` → harvest em guardrail (`docs/GUARDRAILS.md`) | +| `pnpm agent:promote -- --i-am-human` | **Humano:** PR `stage→main` + merge se CI green | +| `pnpm db:seed:minimal` | DB mínimo sintético (contrato: [`scripts/lib/seed-minimal-manifest.mjs`](../scripts/lib/seed-minimal-manifest.mjs), pin `tests/unit/seedMinimalManifest.unit.spec.ts`) | +| `pnpm db:refresh:stage` | **Humano:** nova Neon branch `stage` de prod + swap do secret `STAGE_DATABASE_URL` (requer `NEON_API_KEY`) | -Labels: estado `ready|in-progress|blocked|done|in-prod`, `prio:P0..P3`, `kind:feature|defect|chore|agent-miss`, `needs:migration|consent`, `requirements-changed`. Issues carregam frontmatter `id/depends/serializes/priority` no body. +Labels: estado `ready|in-progress|blocked|done|in-prod`, `prio:P0..P3`, `kind:feature|defect|chore|agent-miss`, `needs:migration|consent`, `requirements-changed`. Issues carregam frontmatter `id/depends/serializes/priority/model` no body. ## Contrato de PR (toda entrega) diff --git a/docs/CHANGELOG-AGENTS.md b/docs/CHANGELOG-AGENTS.md index 240b253f..ec05a818 100644 --- a/docs/CHANGELOG-AGENTS.md +++ b/docs/CHANGELOG-AGENTS.md @@ -39,6 +39,8 @@ Backlog consolidado (bloqueadores, site, campanha, white-label): [`docs/roadmap. **Recently resolved (2026-07-25): Engineering Consolidation Pass 2** (tracker: [`docs/IMPROVE-CODE-QUALITY-PLAN.md`](docs/IMPROVE-CODE-QUALITY-PLAN.md) § Pass 2; architecture: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md); agent map: `.cursor/rules/codebase-map.mdc`). Highlights: **W1 sistema de listas** — colunas como dado em `CampaignTable` (seams B17/B18), URL state compartilhado (`campaignListUrl` + módulos por domínio; o god module `municipalityUi.ts` virou `municipalityListUrl`/`municipalityListFilters`/`municipalityLabels`/`municipalitySignal`), shells (`CampaignListFooter`, `CampaignListEmptyState`), 8 superfícies migradas (municípios, lideranças, organizações, dobradinhas, demandas, apoiadores, assessores, atividades-shells), B16+ absorvido (`useOptimistic`, hrefs por serializador canônico, facet por slugs, facets no mesmo `Promise.all`); **W2** — fronteiras: `slug`/`phone`/`wordStartFilter`/`voteEstimate` movidos para `lib/`, 21 loaders `server-only`, `campaignRoles.ts` client-safe (sidebar sem o barrel de access), `votePledgeViews` (contract) vs `votePledgeData` (loaders), ciclo supporter quebrado, `components/campaign` em 15 subpastas de domínio; decisão D1: sem `src/domains/`, sem ports-and-adapters; **W4a** — `electionInsights.ts` (941 linhas, 2 exports vivos) deletado; sobreviventes em `electionFormat.ts`/`voteTrend.ts`; E10 nasce limpo; **W4b** — knip `exports`/`types`/`enumMembers` em **ERROR** no CI (0 findings; kit ui sem peças mortas); **W4c** — tabs das páginas de detalhe extraídas (`MunicipalityDetailTabs`, `ActivityOverviewTab`) + factory `detailTabUi`; **W4d** — `runCampaignFormAction` fecha o C8 F4 (13 ações em 7 arquivos; exceções documentadas); **W4e** — tipos de fonte única; **W4f** — copy "Praça"→"Município" varrida (apoiadores desambiguado: cidade do contato = "Cidade"); **D3** — consent do WhatsApp por chave estável (`whatsapp-inscricao`, fail-closed). Suites: 46 unit / 48 int / 7 e2e. +**Recently resolved (2026-07-30): Unificação das skills do fluxo (OPS1/OPS2)** — as 7 skills do ciclo roadmap foram fundidas em três: **`plan-issue`** (fundiu `roadmap-item`/`roadmap-items` + profundidade de `implement-roadmap-item`; GATE de confirmação com overview + wireframes ASCII antes de criar qualquer Issue; sugestão de modelo vira propriedade `model:` no frontmatter), **`work-issue`** (claim → verificação assimétrica de modelo → freshness audit → execução → /simplify → PR `--base stage` com CI acompanhado até o merge; promote continua humano) e **`project-status`** (`pnpm agent:status` — overview/fila com `model:`/mermaid/bloqueios/sugestões de consolidação; read-only, nunca toca `in-progress`). Suporte: `agent:register --model`; brief do `agent:claim` imprime `model:`; workflow `issue-done-on-stage-merge.yml` faz o flip `in-progress→done` deterministicamente no merge em stage. Conversão: as 38 Issues do seed ganharam `model:` (tabela ID→modelo aprovada pelo usuário); 6 itens abertos do roadmap legacy viraram Issues (C11 #44, PUB1–PUB4 #45–#48, ADM1 #49); guarda-chuvas ("UX-1", "Higiene PascalCase", smoke/onboarding, white-label, ledger TECH-DEBT) citados, não registrados; `docs/roadmap.md` virou **stub legado congelado**. Deletadas: `roadmap-item`, `roadmap-items`, `implement-roadmap-item`, `suggest-next-roadmap-items`, `ship-to-main`, `close-delivery`, `compile-roadmap`; referências vivas varridas (`model-selection`, `rebase-on-main`, notebooks de projeto, IMPROVE-CODE-QUALITY-PLAN). `capture-review-debts` registra via `agent:register`/`agent:file-miss` e **nunca** edita Issue `in-progress` (débito do mesmo pai = Issue nova com `depends: [pai]`); `engineering-audit` declarado **solitário** (pausa o paralelismo; executa remediações P0/P1 na sessão) com harvest `kind:agent-miss` → `docs/GUARDRAILS.md`. Docs: `docs/AGENT-OPS.md`, `README.md`. + **Recently resolved (2026-07-30):** **B77** Simplificar wizard ajuste de votos — `WizardExpectedVotesStep` reescrito: três cenários numa tela (`VoteEstimateScenarioInputs` compact + strip + atalhos no foco); validação `pessimistic ≤ central ≤ optimistic` só no confirm com `Alert` + highlight do par conflitante (`getWizardVoteViolationHighlights`); POST batch inalterado (`MUNICIPALITY_EXPECTED_VOTES_ENDPOINT`); `?cenario=` legado redireciona para URL canônica sem param (`hasWizardScenarioParam` + `wizardActionHref` sem 3º arg); órfãos do ritual B61 removidos de `wizardVoteEstimate`/`campaignWizardCopy`. `VoteEstimateScenarioInputs` compact ganhou `activeScenario`/`onFocusScenario`/`errorScenarios`/`disabled` (lista inalterada). Sem migration. Plano: [`docs/plans/simplificar-ajuste-votos-wizard.md`](docs/plans/simplificar-ajuste-votos-wizard.md). **Recently resolved (2026-07-30):** **B70** Wizard atualizar liderança — `/campanha/acoes/atualizar-lideranca` substitui o stub B60 por `WizardLeadershipStep` (grid 2/3/4 + tile Adicionar + info Drawer + Tooltip de `notes` no hover fine) e `WizardLeadershipForm` (6 campos incl. `exclusive` B69); `loadWizardLeadershipTiles` no RSC; writes `updateLeadershipWizard`/`createLeadershipWizard` em transação Contact+Leadership (não `updateLeadershipInternal`); `WIZARD_ENTRY_ACTION_QUERY_KEY` + skip via `trailingAction` quando `entryAction !== 'update-leadership'`; Continuar após Salvar dirty → Início + toast; `truncateNameAtWordBoundary` em `lib/`. Sem migration. Plano: [`docs/plans/wizard-atualizar-lideranca.md`](docs/plans/wizard-atualizar-lideranca.md). Desbloqueia wiring A1 embutido.