Separate intention plans from engineering execution in agent skills.
plan-issue now shapes product intent only; agent-work-issue (pool) and work-issue (human gate) deliberate the implementation plan before coding.
This commit is contained in:
parent
906008ef5d
commit
8bca9d8e82
22 changed files with 592 additions and 681 deletions
|
|
@ -11,7 +11,7 @@ description: >-
|
|||
|
||||
# Agent pool — operação do supervisor remoto
|
||||
|
||||
O pool mantém até **5 Cursor Cloud Agents** (configurável, máx 12) rodando `work-issue` sobre Issues `ready` elegíveis para autonomia. O supervisor é **determinístico** (não é um agente): workflow **`.github/workflows/agent-pool.yml`** (tick stateless a cada 10 min + a cada merge em `main` + sob dispatch) rodando `scripts/agent-pool.mjs`. Arquitetura e elegibilidade: `docs/plans/agent-pool-orchestrator.md`.
|
||||
O pool mantém até **5 Cursor Cloud Agents** (configurável, máx 12) rodando `agent-work-issue` sobre Issues `ready` elegíveis para autonomia. O supervisor é **determinístico** (não é um agente): workflow **`.github/workflows/agent-pool.yml`** (tick stateless a cada 10 min + a cada merge em `main` + sob dispatch) rodando `scripts/agent-pool.mjs`. Arquitetura e elegibilidade: `docs/plans/agent-pool-orchestrator.md`.
|
||||
|
||||
**O pool NUNCA deploya** — deploy gated fica em `ci.yml` após merge em `main`.
|
||||
|
||||
|
|
|
|||
107
.cursor/skills/agent-work-issue/SKILL.md
Normal file
107
.cursor/skills/agent-work-issue/SKILL.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
---
|
||||
name: agent-work-issue
|
||||
description: >-
|
||||
Executa uma Issue já claimada de ponta a ponta para workers do agent pool:
|
||||
Plan mode → plano de implementação (engenharia deliberada a partir da
|
||||
intenção) → execução → /simplify → capture-review-debts → PR Ready em main
|
||||
com auto-merge. Use quando o pool spawna um worker, quando a Issue já está
|
||||
in-progress, ou quando o usuário pedir /agent-work-issue.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Agent work-issue (autônomo)
|
||||
|
||||
Conduz **uma** Issue já claimada do plano de implementação ao merge em `main`. É o contrato dos workers do **agent pool** e a base de execução de `work-issue` (versão humana só adiciona claim + pausa).
|
||||
|
||||
**Proibido:** DB de prod / `ALLOW_REMOTE_DB`; merge sem CI green; editar outras Issues `in-progress`; pular `/simplify`; entregar Draft ou sem auto-merge.
|
||||
|
||||
**Fonte de produto:** plano de intenção (`docs/plans/<slug>.md`) + body da Issue.
|
||||
**Fonte de engenharia:** o `*-impl.md` que **você** cria — não o plano de intenção.
|
||||
|
||||
## Relação com outras skills
|
||||
|
||||
| Skill | Papel |
|
||||
| ----- | ----- |
|
||||
| `plan-issue` | Intenção (já feita) |
|
||||
| **`agent-work-issue` (esta)** | Impl plan → execução → simplify → débitos → PR |
|
||||
| `work-issue` | Igual, mas claim + **confirmação humana** do impl plan |
|
||||
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] 0. Prep: `pnpm i` se preciso; Cloud → §Prep Cloud (sem Docker)
|
||||
- [ ] 1. Sessão: rename_chat + open_resource na intenção
|
||||
- [ ] 2. Modelo (best effort) vs `model:` da Issue
|
||||
- [ ] 3. Plan mode → plano de implementação (`*-impl.md`)
|
||||
- [ ] 4. Executar o impl plan (schema/server → UI → gates)
|
||||
- [ ] 5. /simplify → fixes; capture-review-debts (modo autônomo)
|
||||
- [ ] 6. PR Ready `--base main` + auto-merge + checks --required
|
||||
```
|
||||
|
||||
## Passo 0 — Prep
|
||||
|
||||
```bash
|
||||
pnpm i # se node_modules ausente/stale
|
||||
```
|
||||
|
||||
### Cloud (sem Docker)
|
||||
|
||||
Não use `pnpm db:start`. Postgres via `.cursor/environment.json`. `gate:fast` / `gate:push` não precisam de DB. **Proibido** `git push --no-verify` no fechamento.
|
||||
|
||||
## Passo 1 — Sessão (Issue já claimada)
|
||||
|
||||
**Não** rode `pnpm agent:claim` — o pool (ou o humano via `work-issue`) já claimou.
|
||||
|
||||
1. `rename_chat` → `#<N> <id> — <título>` (padrão canônico; truncar só o título).
|
||||
2. `open_resource` no plano de intenção (`docs/plans/<slug>.md`).
|
||||
|
||||
## Passo 2 — Modelo
|
||||
|
||||
Compare `model:` da Issue com a sessão (`model-selection`):
|
||||
|
||||
- Sessão mais fraca → informa e segue
|
||||
- Sessão mais forte → informa; em autonomia do pool, **segue** (o spawn já fixou o modelo)
|
||||
- Ausente → trate como `composer-2.5`
|
||||
|
||||
## Passo 3 — Plano de implementação (Plan mode)
|
||||
|
||||
1. `SwitchMode` → `plan` (explique: deliberar engenharia a partir da intenção).
|
||||
2. Leia [engineering-brief.md](../work-issue/engineering-brief.md) e aplique skills/princípios sob demanda.
|
||||
3. Explore o código o bastante para **reavaliar** a “Direção no codebase” da intenção — você **deve** escolher a melhor abordagem maintainable, mesmo que difira da hipótese do plano de intenção, desde que o **aceite de produto** se mantenha.
|
||||
4. Escreva `docs/plans/<slug>-impl.md` via [implementation-template.md](../work-issue/implementation-template.md). Qualidade: [decision-quality.md](../work-issue/decision-quality.md) ≥4/5.
|
||||
5. Em autonomia: marque Status `aprovado` e **siga sem pausa**. (Em `work-issue`, o humano confirma antes.)
|
||||
|
||||
**Divergência material de produto** (aceite/persona/lockdown da intenção não cabem na abordagem): pare, comente na Issue, flip para `blocked` se pool — não invente produto novo.
|
||||
|
||||
## Passo 4 — Executar
|
||||
|
||||
`SwitchMode` → `agent` se ainda estiver em plan. Ordem:
|
||||
|
||||
1. **Schema/server** — migrations (`payload-migrations`), utilities, actions, testes de domínio. Invariantes do engineering-brief.
|
||||
2. **UI** — se Impeccable B/C/D: shape → craft → critique → polish (harden/optimize só sob gatilho). Tokens `data-theme='campaign'`; shells existentes.
|
||||
3. **Gates** — `pnpm gate:fast` na iteração; entrega com `pnpm push` (não `git push` nu).
|
||||
|
||||
Tracer bullet cedo se o item for grande. Inclua o `*-impl.md` no commit da entrega.
|
||||
|
||||
## Passo 5 — `/simplify` + débitos
|
||||
|
||||
1. Rode o comando `/simplify` completo (3 reviewers paralelos via Task, read-only) no diff da sessão.
|
||||
2. Aplique fixes pontuais que preservem comportamento.
|
||||
3. Rode `capture-review-debts` em **modo autônomo**:
|
||||
- Colha e pontue como a skill manda
|
||||
- **Sem** gate humano: registre só `expensive_lock` com score ≥4 (Issues novas com `depends: [<id-pai>]` se necessário)
|
||||
- Score ≤3 / cheap_polish / defer_trigger → defer com gatilho no `*-impl.md` ou descarte — **não** polua a fila
|
||||
- Nunca edite a Issue `in-progress` atual para absorver débitos
|
||||
|
||||
## Passo 6 — Fechar em main
|
||||
|
||||
1. Branch `agent/<id>-<slug>` (worktrees Cursor podem já ter criado).
|
||||
2. **`pnpm push -u origin HEAD`**
|
||||
3. PR **Ready** (nunca draft): `gh pr create --base main` com `Closes #<N>` — ou Cloud `ManagePullRequest` com `draft: false`
|
||||
4. `gh pr merge --auto --merge` imediatamente
|
||||
5. `gh pr checks <PR> --watch --required` (`checks` + `migration-lock`; ignore Vercel Git)
|
||||
6. CI flipa `done`/`in-prod` no merge. Comente na Issue o desfecho em uma linha.
|
||||
|
||||
## Resumo final
|
||||
|
||||
Issue · impl plan (abordagem escolhida + rejeitadas) · o que divergiu da hipótese de direção · simplify + débitos registrados/deferidos · PR + estado do merge.
|
||||
|
|
@ -9,7 +9,7 @@ Após um ciclo de entrega, `/simplify` e `/impeccable` deixam achados **maiores
|
|||
|
||||
**Regra inviolável — nunca editar Issue `in-progress`.** Nem para absorver um débito do mesmo pai: registra como **Issue nova** com `depends: [<id-do-pai>]` no frontmatter — assim ela destrava sozinha na fila quando o pai flipar `done` — ou defer com gatilho. Editar a Issue que um agente está executando é esquecimento/conflito garantido.
|
||||
|
||||
**Qualidade de decisão:** [decision-quality.md](../plan-issue/decision-quality.md) — caro vs barato, defer+gatilho, depth/YAGNI. Score sozinho não basta: classifique o **tipo de decisão** na triage. Sem tour de fases.
|
||||
**Qualidade de decisão:** [decision-quality.md](../work-issue/decision-quality.md) — caro vs barato, defer+gatilho, depth/YAGNI. Score sozinho não basta: classifique o **tipo de decisão** na triage. Sem tour de fases.
|
||||
|
||||
## Checklist
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ Mostre ao usuário **antes** de editar docs:
|
|||
|
||||
Inclua baldes **já_resolvido**, **descartar** e **defer** com uma linha de racional/gatilho cada (transparência > silêncio).
|
||||
|
||||
**Pare e confirme.** Só avance ao Passo 6 com aprovação explícita (ou ajuste pedido). Sem confirmação = não cria Issue nem toca `docs/plans/`.
|
||||
**Pare e confirme** — exceto em **modo autônomo** (`agent-work-issue` / pool): aí aplique a seção Modo autônomo abaixo e pule o AskQuestion. Só avance ao Passo 6 com aprovação explícita (humano) ou com as regras do modo autônomo. Sem isso = não cria Issue nem toca `docs/plans/`.
|
||||
|
||||
## Passo 6 — Registrar via `agent:register` / `agent:file-miss`
|
||||
|
||||
|
|
@ -139,9 +139,18 @@ Para cada lote com destino **registrar** ou **absorver**:
|
|||
- **Explicitamente fora** (skips dos revisores + descartes + defers com gatilho deste triage)
|
||||
6. Self-score de decisão ≥4/5 antes de gravar; classe Impeccable A–D conforme o lote (só-backend = A; UX pós-critique = B/C).
|
||||
|
||||
Não implemente as fases aqui. Execução é via `work-issue` (claim → merge em stage), só se o usuário pedir em seguida.
|
||||
Não implemente as fases aqui. Execução é via `work-issue` / `agent-work-issue`, só se o usuário (ou o pipeline autônomo) seguir.
|
||||
|
||||
**Próximo no fluxo de entrega:** após a triage confirmada (ou no-op sem débitos), o fechamento da sessão segue o Passo 6 da skill `work-issue` (fast gate → PR `--base stage` com `Closes #N` → acompanhar CI até o merge).
|
||||
**Próximo no fluxo de entrega:** após a triage (confirmada ou modo autônomo), o fechamento segue o Passo 6 de `agent-work-issue` / `work-issue` (`pnpm push` → PR `--base main` com `Closes #N` → auto-merge → CI).
|
||||
|
||||
## Modo autônomo (`agent-work-issue` / pool)
|
||||
|
||||
Quando não há humano no gate (Passo 5):
|
||||
|
||||
1. Faça colheita, dedup, score e tipo como de costume.
|
||||
2. **Registre** só itens `expensive_lock` com score ≥4 (Issue nova + `depends` no pai se preciso; plano curto se score ≥3 eng).
|
||||
3. Todo o resto → **defer** (gatilho no `*-impl.md` / Explicitamente fora) ou **descartar** — não abra AskQuestion.
|
||||
4. Resuma no comentário/fechamento o que registrou vs deferiu.
|
||||
|
||||
## Anti-padrões (baseline)
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Read, in this order:
|
|||
2. `.cursor/rules/codebase-map.mdc` — dependency direction, where things live, the list system, invariants.
|
||||
3. `docs/ARCHITECTURE.md` — layers, bounded contexts, decision log.
|
||||
4. `AGENTS.md` — operational rules + "Recently resolved" history (Pass 1, Pass 2, every post-Pass-2 delivery's /simplify findings).
|
||||
5. `docs/AGENT-OPS.md` — paradigma de agentes paralelos vigente (claim→PR→stage→promote humano, skills plan-issue/work-issue/project-status). O audit avalia o repo **contra** esse fluxo, não contra o fluxo legacy de roadmap.md.
|
||||
5. `docs/AGENT-OPS.md` — paradigma de agentes paralelos vigente (claim→PR→main, skills plan-issue / work-issue / agent-work-issue / project-status). O audit avalia o repo **contra** esse fluxo, não contra o fluxo legacy de roadmap.md.
|
||||
6. `docs/IMPROVE-CODE-QUALITY-PLAN.md` — what the earlier passes already swept. Don't re-register what they fixed; verify fixes held.
|
||||
7. `docs/TECH-DEBT.md` — open ledger. New findings de-dup against it; verify each open row still exists, close stale ones.
|
||||
8. `docs/TESTING.md` — safety-net map: what is pinned, where the gaps are.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Production is a live **Neon Postgres** with real citizens' PII. Local developmen
|
|||
|
||||
## Cursor Cloud (sem Docker)
|
||||
|
||||
VMs Cloud **não rodam** `docker compose` / `pnpm db:start`. Postgres nativo: `.cursor/environment.json` (`cloud-setup.sh` + `ensure-postgres.sh`). Mesmos URLs `localhost:5432/teqo` e `teqo_test`. Agentes em `work-issue`: não tente Docker; `gate:fast`/`gate:push` não precisam de banco.
|
||||
VMs Cloud **não rodam** `docker compose` / `pnpm db:start`. Postgres nativo: `.cursor/environment.json` (`cloud-setup.sh` + `ensure-postgres.sh`). Mesmos URLs `localhost:5432/teqo` e `teqo_test`. Agentes em `work-issue` / `agent-work-issue`: não tente Docker; `gate:fast`/`gate:push` não precisam de banco.
|
||||
|
||||
## Local connection values
|
||||
|
||||
|
|
|
|||
|
|
@ -58,14 +58,11 @@ Depois de escolher Grok, **obrigatório** pickar um effort. Escreva o slug compl
|
|||
| `kimi-k3-low` | `kimi-k3` | `reasoning=low` |
|
||||
| `composer-2.5` | `composer-2.5` | `fast=false` |
|
||||
|
||||
## Issues muito complexas (bipartir)
|
||||
## Issues muito complexas
|
||||
|
||||
Quando o blast radius é alto (refactor amplo, simplify repo-wide, migration+RBAC), `plan-issue` **registra duas Issues encadeadas**:
|
||||
O plano de **implementação** nasce em `work-issue` / `agent-work-issue` (`*-impl.md`), não em `plan-issue`. Preferir **uma** Issue de intenção + Grok no `model:` quando a deliberação de engenharia for cara.
|
||||
|
||||
1. `{id}-plan` — `model: cursor-grok-4.5-high` — entregável = plano em `docs/plans/…` + critérios de aceite da execução
|
||||
2. `{id}` ou `{id}-exec` — `model: kimi-k3-low`, `depends: [{id}-plan]` — executa o plano
|
||||
|
||||
Não despachar Kimi K3 Low sem plano fechado na Issue de plan.
|
||||
Bipartir (`{id}-plan` Grok High → `{id}-exec` `kimi-k3-low`) só sob pedido explícito ou blast radius extremo (refactor repo-wide / simplify amplo). Não despachar Kimi K3 Low sem plano de implementação fechado.
|
||||
|
||||
## Regras
|
||||
|
||||
|
|
@ -86,6 +83,7 @@ Não despachar Kimi K3 Low sem plano fechado na Issue de plan.
|
|||
## Gates por fluxo
|
||||
|
||||
- **`/simplify`:** herda o modelo da sessão. Preferir sessão em Kimi K3 Low **só** quando houver Issue de exec bipartida; caso contrário Composer ou Grok (effort pela tabela) conforme complexidade.
|
||||
- **`work-issue`:** verifica `model:` da Issue (assimétrico: sessão mais fraca → informa e segue; mais forte → informa e pausa). Ausente → aplica esta tabela **incluindo** o effort Grok.
|
||||
- **`plan-issue`:** sugere via esta tabela (slug completo com effort); em issues muito complexas, registra o par plan/exec.
|
||||
- **`work-issue`:** verifica `model:` (assimétrico: mais fraca → informa e segue; mais forte → informa e **pausa**). Ausente → aplica esta tabela.
|
||||
- **`agent-work-issue`:** pool já fixou o modelo no spawn; sessão mais forte → informa e segue.
|
||||
- **`plan-issue`:** sugere via esta tabela (slug completo com effort); bipartição só sob blast radius extremo / pedido explícito.
|
||||
- **`agent-pool` smoke:** Composer default; Grok com effort explícito / Kimi K3 Low em Issues de teste bipartidas.
|
||||
|
|
|
|||
|
|
@ -1,127 +1,125 @@
|
|||
---
|
||||
name: plan-issue
|
||||
description: Registra uma ou VÁRIAS ideias/features/débitos do Teqo como GitHub Issues rastreáveis — classifica, explora o código, produz plano completo em docs/plans/<slug>.md por item (premissas, critérios de aceite, fases verticais, tracer bullet), sugere modelo × effort (model-selection) e passa por um GATE de confirmação (overview + wireframes ASCII + premissas) antes de criar qualquer Issue via `pnpm agent:register`. Usar quando o usuário pedir para adicionar/registrar algo ("adiciona ao roadmap", "registra essa ideia", "cria um plano para", "planeja a issue", "registra tudo isso"), em lote ou avulso.
|
||||
description: >-
|
||||
Transforma ideias humanas em Issues GitHub + planos de intenção em
|
||||
docs/plans/ (persona, fluxo, objetivo, direção suave no código — sem
|
||||
decisões duras de engenharia). Divide o pedido nas menores tarefas que
|
||||
ainda fazem sentido. Use quando o usuário pedir /plan-issue, planejar
|
||||
features, fatiar um pedido em Issues, ou registrar trabalho novo na fila.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Planejar e registrar Issues (1..N ideias)
|
||||
# Planejar Issues (intenção, não engenharia)
|
||||
|
||||
Esta skill transforma ideias soltas em: (1) um **plano completo** em `docs/plans/<slug>.md` por item, e (2) uma **GitHub Issue rastreável** por item (`pnpm agent:register`, frontmatter `id/depends/serializes/priority/model`). **GitHub Issues são a fonte canônica** de spec/status/deps/prio/modelo — `docs/roadmap.md` é legado congelado e **nunca** é editado aqui.
|
||||
Esta skill transforma ideias soltas em: (1) um **plano de intenção** em `docs/plans/<slug>.md` por item, e (2) uma **GitHub Issue rastreável** (`pnpm agent:register`, frontmatter `id/depends/serializes/priority/model`). GitHub Issues são a fonte canônica de spec/status/deps/prio/modelo — `docs/roadmap.md` é legado congelado e **nunca** é editado aqui.
|
||||
|
||||
**Gate de confirmação (obrigatório):** nenhuma Issue é criada no GitHub antes do usuário aprovar o overview do lote (Passo 5). Planos locais podem ser rascunhados antes; Issues, não.
|
||||
|
||||
**Divisão com `work-issue`:** aqui se classifica a superfície UI (A–D), semeia âncoras de design, escreve o plano (spec + fatias). **Não** se implementa código nem se roda Impeccable craft/critique/polish — isso pertence a `work-issue` (incremental + TDD + gates).
|
||||
## Divisão com as skills de execução
|
||||
|
||||
**Mapa das skills de planejamento:** o que absorver vs. rotear — [skills-map.md](skills-map.md). Princípios em silêncio; sem tour.
|
||||
| Skill | Papel |
|
||||
| ----- | ----- |
|
||||
| **`plan-issue` (esta)** | Intenção humana: o quê / para quem / por quê / outcome. Direção suave no codebase. **Proibido** travar schema, signatures, migrations, abstrações ou “Abordagem” de engenharia. |
|
||||
| **`work-issue`** | Humano supervisiona: claim → plano de **implementação** (Plan mode) → **pausa** para confirmação → executa. |
|
||||
| **`agent-work-issue`** | Pool / autonomia: Issue já claimada → plano de implementação → executa sem pausa → `/simplify` → `capture-review-debts` → PR Ready + auto-merge. |
|
||||
|
||||
**Qualidade de decisão (não é tour):** aplique [decision-quality.md](decision-quality.md) em silêncio — filtro caro vs barato, Opções+Recomendação+rejeitadas, appetite, rabbit holes, depth check, fatias verticais, doubt em decisão cara, self-score ≥4 antes de gravar.
|
||||
Aqui **não** se implementa código, **não** se escreve plano de implementação, **não** se roda Impeccable craft/critique/polish.
|
||||
|
||||
**Dados → decisão → apresentação:** se o item produz, agrega ou exibe números/séries/mapas/KPIs, aplique [data-presentation.md](data-presentation.md) em silêncio antes de travar a Abordagem. Se não há superfície de dados, `Dados: N/A` no plano.
|
||||
**Shaping (não tour):** aplique [shaping.md](shaping.md) em silêncio — appetite, fatia mínima útil, rabbit holes de produto, self-score ≥4 antes de gravar.
|
||||
|
||||
## Checklist do fluxo
|
||||
**Dados (intenção):** se o item envolve números/KPIs/mapas, aplique [data-presentation.md](data-presentation.md) só até “quem decide o quê com este dado”. A **forma** (chart/mapa/KPI) fica para o plano de implementação.
|
||||
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] 1. Parse do lote + dedup (intra-lote, Issues existentes, docs/plans, roadmap legacy)
|
||||
- [ ] 1b. Clareza: ideia vaga → idea-refine leve / perguntar; senão premissas explícitas
|
||||
- [ ] 2. Reserva de IDs de uma vez por trilha (roadmap legacy + issuesById())
|
||||
- [ ] 3. Por item (ordem topológica): classificar → explorar código → Impeccable A–D → dados
|
||||
→ decisões (doubt se caro) → fases verticais + tracer → posicionamento → plano completo
|
||||
- [ ] 3. Por item (ordem topológica): classificar → fatiar → explorar só o suficiente → intenção completa
|
||||
- [ ] 4. Sugestão de modelo × effort via model-selection (uma linha por item)
|
||||
- [ ] 5. GATE: overview do lote + premissas + wireframes ASCII (B/C/D) → confirmar/iterar
|
||||
- [ ] 6. Registro: pnpm agent:register (com --model) por item + commit dos planos
|
||||
- [ ] 5. GATE: overview do lote + esboços de fluxo (B/C/D) → confirmar/iterar
|
||||
- [ ] 6. Registro: pnpm agent:register (com --model) por item + commit dos planos de intenção
|
||||
```
|
||||
|
||||
## Passo 1 — Parse do lote e dedup
|
||||
## Passo 1 — Parse e dedup
|
||||
|
||||
1. **Separe os itens.** A entrada pode vir como 1 ideia ou N (lista, parágrafo, notas). Se a separação for ambígua, assuma a leitura mais provável e liste como você entendeu — a confirmação vai junto do gate.
|
||||
2. **Deduplique dentro do lote.** Desfechos: **mesclar** (um item, plano único), **absorver** (vira fase de plano existente, sem ID novo), ou **manter separados** com dependência explícita.
|
||||
3. **Deduplique contra o que já existe:** `gh issue list --state all` (frontmatter `id` via `issuesById()` em `scripts/lib/agent-github.mjs`), grep em `docs/plans/*.md` e em `docs/roadmap.md` (legado). Três desfechos por item: **já coberto** → aponte a Issue/plano existente e não crie nada; **é fase de plano existente** → adicione ao plano existente; **realmente novo** → siga.
|
||||
|
||||
## Passo 1b — Clareza e premissas (antes de reservar ID / escrever plano)
|
||||
|
||||
Inspirado em `idea-refine` + `spec-driven-development` + `using-agent-skills` (“Surface Assumptions”) — **leve**, sem sessão divergente completa.
|
||||
|
||||
1. **Ideia ainda vaga?** (não dá para escrever Objetivos testáveis, persona, ou 1 fatia vertical). Desfechos:
|
||||
- **Roteiar** para `idea-refine` / `interview-me` se o usuário quiser explorar; ou
|
||||
- **Uma rodada** de 3–5 sharpening questions (quem, sucesso, constraints, o que já tentou, por quê agora) + recomendação; **não** avance ao Passo 2 até haver um HMW / problema em uma frase e um MVP óbvio.
|
||||
2. **Premissas explícitas.** Antes de redigir o plano, liste o que está assumindo (produto, schema, papel, escopo). Formato no plano e no gate:
|
||||
|
||||
```text
|
||||
PREMISSAS:
|
||||
1. …
|
||||
2. …
|
||||
→ Corrija agora ou sigo com estas.
|
||||
```
|
||||
|
||||
Não preencha ambiguidade em silêncio. Assunções que forem default de produto ficam marcadas _(assumido — validar com produto)_ nas Questões em aberto.
|
||||
3. **Pedido vago → critérios de sucesso.** Reframe (“deixar o dashboard mais rápido”) em condições testáveis antes da Abordagem. Se não der para medir/verificar → ainda está vago (voltar ao item 1).
|
||||
1. **Separe os itens.** Entrada pode ser 1 ideia ou N. Se ambíguo, assuma a leitura mais provável e liste — a confirmação vai no gate.
|
||||
2. **Fatia mínima útil.** Prefira várias Issues pequenas a um epic. Cada item deve caber num appetite curto e entregar um outcome verificável sozinho. Mesclar só quando separar criaria trabalho inútil (mesmo fluxo, mesma persona, mesma superfície sem valor incremental).
|
||||
3. **Dedup intra-lote:** mesclar | absorver (fase de plano existente, sem ID novo) | manter separados com `depends`.
|
||||
4. **Dedup contra o existente:** `gh issue list --state all` + `issuesById()` + grep em `docs/plans/*.md` e `docs/roadmap.md` (legado). Já coberto → apontar e não criar; fase de plano existente → editar aquele plano; novo → seguir.
|
||||
|
||||
## Passo 2 — Reserva de IDs
|
||||
|
||||
Levante o último ID usado por trilha (A/B/C/D/E) olhando o roadmap legacy + `issuesById()` e distribua sequencialmente para os itens do lote **antes de escrever qualquer plano** (ex.: trilha B em `B78` → os dois itens de B viram `B79`, `B80`). IDs fora de trilha (chore/ops) seguem o prefixo do seu domínio conforme precedentes (`O0+`, `FD+`, `RS+`) ou a trilha temática mais próxima.
|
||||
Último ID por trilha (A/B/C/D/E) via roadmap legacy + `issuesById()`; distribua **antes** de escrever planos. Fora de trilha: prefixos `O0+`, `FD+`, `RS+` ou trilha temática mais próxima.
|
||||
|
||||
## Passo 3 — Por item: do tipo ao plano completo
|
||||
## Passo 3 — Por item: intenção completa
|
||||
|
||||
Ordem topológica intra-lote (o plano do dependente cita o ID do dependido, que já existe). Por item:
|
||||
Ordem topológica (dependente cita ID do dependido). Por item:
|
||||
|
||||
1. **Classificar o tipo:**
|
||||
1. **Tipo**
|
||||
|
||||
| Tipo | Destino |
|
||||
| ---- | ------- |
|
||||
| Feature de `/campanha` ou site público com escopo próprio | Issue `kind:feature` com plano |
|
||||
| Tarefa pequena / chore / débito de engenharia | Issue `kind:chore` + plano curto (ou body direto se trivial) |
|
||||
| Défice comportamental do fluxo de agentes | `pnpm agent:file-miss` (`kind:agent-miss`), não aqui |
|
||||
| Bloqueio externo (jurídico/LGPD) | Issue `blocked` + label `needs:consent`/`needs:migration`; texto novo entra no lote jurídico existente, nunca rodada separada |
|
||||
| Evidência de usuário ainda inexistente (discovery) | `blocked` / defer+gatilho — não inventar feature; ver `continuous-discovery` só se o usuário pedir discovery |
|
||||
| Feature `/campanha` ou site com escopo próprio | `kind:feature` + plano de intenção |
|
||||
| Chore / débito pequeno | `kind:chore` + plano curto (ou body se trivial) |
|
||||
| Défice do fluxo de agentes | `pnpm agent:file-miss` (`kind:agent-miss`) — não aqui |
|
||||
| Bloqueio externo (jurídico/LGPD) | `blocked` + `needs:consent`/`needs:migration`; texto no lote jurídico existente |
|
||||
| Decisão de NÃO fazer | Comentário/doc, não Issue |
|
||||
|
||||
2. **Explorar o código** (depth check): onde a feature se pluga, o que reusar de `src/utilities/*`, `src/components/campaign/*`, `src/lib/*`; schema novo → migration (caro de reverter → Decisão travada com rejeitadas); pessoa → join com `Contact`; opt-in/PII → `Consent` por chave estável falhando fechado. Precedente análogo em `docs/plans/` dita o nível de detalhe. Cite **caminhos reais** (context-engineering: plano legível sem dump do repo).
|
||||
3. **Classificar superfície UI (A–D)** e semear âncoras: `PRODUCT.md`/`DESIGN.md`, design-ref em `docs/design-refs/latest/` se houver, shells existentes. Classe C exige **brief compacto** (persona, job, estratégia de cor, anti-goals) no plano. Proibido: rodar craft/critique/polish aqui.
|
||||
4. **Dados → decisão → apresentação** ([data-presentation.md](data-presentation.md)) ou `Dados: N/A`.
|
||||
5. **Decisões caras + doubt (quando couber):** para cada decisão caro-de-reverter (schema, access, Consent, URL imutável, multi-collection), use a forma Opções+Recomendação+rejeitadas. Se a decisão for **não trivial** no sentido de [decision-quality.md](decision-quality.md) § Doubt, faça um ciclo curto CLAIM → adversarial self-check (ou `Task` fresh-context) **antes** de gravar como Decisão travada. Não doubt em rename/copy.
|
||||
6. **Posicionamento:** prioridade `P0..P3` (jurídico/caminho crítico > base de dados > operação de campo > inteligência > plataforma), `depends` (IDs duros), appetite, janela do calendário eleitoral quando relevante, `serializes` quando toca recurso compartilhado (ex.: migrations).
|
||||
7. **Fatiar em fases verticais** ([decision-quality.md](decision-quality.md) § Fatias): não “toda a DB → toda a API → toda a UI”. Cada fase = caminho fino ponta a ponta (ou o pedaço mínimo que deixa o sistema verde), com **aceite**, **verify** (`pnpm gate:fast` / pin unit|int / check manual), arquivos prováveis, tamanho S/M. **Fase 1 = tracer bullet** (schema mínimo → uma action → uma superfície, ou o menor path que prova a aposta). High-risk / incerteza primeiro. Se a fatia seria L/XL (≫5 arquivos ou >1 sessão focada) → mais fases **ou** Issue bipartida `{id}-plan` / `{id}-exec`.
|
||||
8. **Boundaries Teqo** no plano (sempre, compacto): o que esta entrega **Always** / **Ask first** / **Never** — ver template. Defaults do repo (overrideAccess, transação, Consent fail-closed, sem Neon) entram em Always/Never sem inventário genérico.
|
||||
9. **Source-driven (flag, não fetch):** se a Abordagem depende de API de framework (Payload Local API, Next App Router, WebAuthn), anote na fase: “na implementação, verificar docs oficiais da versão em `package.json`” — o fetch é de `work-issue` / `source-driven-development`.
|
||||
10. **Plano completo** em `docs/plans/<slug>.md` seguindo [plan-template.md](plan-template.md) à risca — cabeçalho, Premissas, Objetivos como aceite, Decisões, Fases verificáveis (quota do appetite), Dados, wireframe ASCII se B/C/D com layout, guardrails, rabbit holes, adiados. Self-score ≥4/5 antes de gravar.
|
||||
2. **Explorar o código o mínimo** — só para apontar **direção** (rotas/pastas/domínios prováveis) e evitar duplicar algo já entregue. Não inventar signatures, collections novas como decisão travada, nem diagramas de componentes.
|
||||
3. **Superfície UI (A–D)** como dica para quem for executar — não semear brief Impeccable completo nem wireframe de implementação. Classe C/D: esboço de fluxo persona (ASCII curto) no gate, não especificação de layout.
|
||||
4. **Dados (intenção)** ou `Dados: N/A`.
|
||||
5. **Posicionamento:** `P0..P3`, `depends`, appetite, janela eleitoral se relevante, `serializes` se tocar recurso compartilhado (ex. migrations) — sem detalhar a migration.
|
||||
6. **Plano de intenção** em `docs/plans/<slug>.md` via [intention-template.md](intention-template.md). Self-score ≥4/5 ([shaping.md](shaping.md)).
|
||||
|
||||
## Passo 4 — Sugestão de modelo × effort
|
||||
### O que é proibido no plano de intenção
|
||||
|
||||
Aplique a skill `model-selection` (tabela canônica) por item e registre a sugestão no cabeçalho do plano (`Model:`) e no resumo do gate. Caminho feliz único:
|
||||
- Decisões de schema / collection / unicidade / Consent key concreta como “travadas”
|
||||
- Assinaturas de funções, nomes de arquivos novos obrigatórios, mermaid de arquitetura de solução
|
||||
- “Abordagem proposta” com componentes e migration nomeada
|
||||
- Fases de implementação verificáveis com quota de engenharia
|
||||
- Forçar o executor a uma única forma técnica
|
||||
|
||||
- `composer-2.5` — default (features, chores simples, fixes localizados, docs leves)
|
||||
- `cursor-grok-4.5-low` | `cursor-grok-4.5-medium` | `cursor-grok-4.5-high` — Grok com **effort explícito** (ver model-selection: Low = mecânico com julgamento; Medium = discovery/análise; High = multi-domínio / falha cara)
|
||||
- `kimi-k3-low` — **só** fase de execução de issues bipartidas (refactor / simplify / migration+RBAC de blast radius alto)
|
||||
### O que é obrigatório
|
||||
|
||||
**Issues muito complexas:** registre **duas** Issues encadeadas — `{id}-plan` (`model: cursor-grok-4.5-high`, entregável = plano + critérios de aceite) e `{id}`/`{id}-exec` (`model: kimi-k3-low`, `depends: [{id}-plan]`). O valor vai ao frontmatter `model:` — propriedade da Issue, verificada (não recalculada) por `work-issue`.
|
||||
- Intenção do humano (problema/oportunidade)
|
||||
- Persona(s) e fluxo desejado (job / outcome)
|
||||
- Critérios de aceite em linguagem de produto
|
||||
- Appetite e fora de escopo (produto)
|
||||
- **Direção provável no codebase** (pastas/rotas/domínios — hipotética, revisável)
|
||||
- Questões em aberto com **Opções + Recomendação de produto** (não de engenharia)
|
||||
|
||||
## Passo 5 — GATE de confirmação (obrigatório)
|
||||
## Passo 4 — Modelo × effort
|
||||
|
||||
Apresente no chat, **antes de criar qualquer Issue**:
|
||||
Skill `model-selection`. Registre no cabeçalho (`Model:`) e no gate.
|
||||
|
||||
- **Overview do lote** — uma linha por plano: ID, título, prio, depends, appetite, modelo sugerido, link do plano local.
|
||||
- **Premissas** por item (ou bloco compartilhado do lote) — “corrija agora ou sigo”.
|
||||
- **Wireframes ASCII** das superfícies B/C/D (copiados dos planos).
|
||||
- **Fases em uma linha** (F1 tracer → …) quando o item tiver >1 fase.
|
||||
- Perguntas acumuladas (se houver) em uma única rodada, recomendação primeiro.
|
||||
- Default: `composer-2.5`
|
||||
- Grok com effort explícito quando discovery/multi-domínio / falha cara de **produto**
|
||||
- Não crie par `{id}-plan` / `{id}-exec` por default — o plano de implementação nasce em `work-issue` / `agent-work-issue`. Reserve bipartição só para blast radius extremo (refactor repo-wide) se o humano pedir.
|
||||
|
||||
O usuário confirma ou pede modificações; itere até confirmar. **Só depois** avance ao Passo 6. Planos em `docs/plans/` podem ser rascunhados antes do gate (arquivos locais isolados); ajuste-os conforme a resposta.
|
||||
## Passo 5 — GATE
|
||||
|
||||
Antes de criar Issues:
|
||||
|
||||
- Overview: ID, título, prio, depends, appetite, modelo, link do plano local
|
||||
- Esboços de fluxo persona para superfícies B/C/D (se houver)
|
||||
- Perguntas acumuladas numa rodada, recomendação de produto primeiro
|
||||
|
||||
Itere até confirmação. Só então Passo 6.
|
||||
|
||||
## Passo 6 — Registro
|
||||
|
||||
Por item confirmado:
|
||||
|
||||
```bash
|
||||
pnpm agent:register -- --id <ID> --title "<título>" --prio <P0..P3> \
|
||||
--depends <A,B> --kind <feature|chore|...> --plan docs/plans/<slug>.md \
|
||||
--model <slug> [--blocked] [--labels extra]
|
||||
```
|
||||
|
||||
A Issue nasce `ready` (ou `blocked`) com frontmatter `id/depends/serializes/priority/model` + spec + link do plano. Atualize o cabeçalho do plano (`Issue: #N`). Commit dos planos (commits lógicos por item ou por lote).
|
||||
Atualize `Issue: #N` no plano. Commit dos planos de intenção.
|
||||
|
||||
**PR só de plano (`docs/plans/` exclusivamente):** nunca use `Closes #N` / `Fixes` / `Resolves` no body — use `Related #N`. O CI (`plans-only-closes`) bloqueia keywords de fechamento; a implementação fecha a Issue em outro PR (`work-issue`).
|
||||
**PR só de plano:** nunca `Closes #N` — use `Related #N` (`plans-only-closes`).
|
||||
|
||||
**NÃO faz:** editar `docs/roadmap.md` (legado congelado), implementar código, claim (`pnpm agent:claim` é de `work-issue`), abrir jornada `design-code-architecture`, gravar `tasks/plan.md` / `tasks/todo.md` (artefato Teqo = `docs/plans/<slug>.md`).
|
||||
**NÃO faz:** editar `docs/roadmap.md`, implementar, claim, escrever `*-impl.md`.
|
||||
|
||||
## Resumo final
|
||||
|
||||
Tabela do lote (ID, título, prio, depends, appetite, modelo, Issue #N, plano) + em prosa: mesclados/absorvidos/descartados por duplicidade, premissas que o gate confirmou ou corrigiu, decisões assumidas _(validar com produto)_, e o que o gate decidiu.
|
||||
Tabela do lote + mesclados/absorvidos/descartados + decisões de produto assumidas _(validar)_ + o que o gate decidiu.
|
||||
|
|
|
|||
|
|
@ -1,112 +1,39 @@
|
|||
# Dados → decisão → apresentação
|
||||
# Dados → decisão (intenção) → forma (implementação)
|
||||
|
||||
Filtro obrigatório quando um item do roadmap **produz, agrega ou exibe** números, séries, rankings, mapas ou KPIs. Inspirado em `visualization-choice-reporting` (pergunta → tipo de chart → narrativa acionável) e no kernel Teqo (`PRODUCT.md` §5 + `docs/research/`). **Não** é um tour de dashboard design — são três perguntas com resposta registrada no plano. Decisão silenciosa (“só coloca um gráfico”) é defeito.
|
||||
Quando um item **produz, agrega ou exibe** números, séries, rankings, mapas ou KPIs. Kernel Teqo: `PRODUCT.md` §5 + `docs/research/` — disputa de DF é relativa/local, não % estadual absoluto.
|
||||
|
||||
Aplique em silêncio em `plan-issue` (ao semear o plano) e em `work-issue` (ao auditar e fatiar UI). Se o item **não** apresenta dados (ex.: migration de Consent, invite WhatsApp, form CRUD sem métrica), escreva `Dados: N/A` no plano e pule o resto.
|
||||
| Fase | Skill | O que decide |
|
||||
| ---- | ----- | ------------ |
|
||||
| Intenção | `plan-issue` | Vou apresentar dados? Quais **decisões de ator** isso desbloqueia? Restrições de produto. |
|
||||
| Implementação | `work-issue` / `agent-work-issue` | Forma concreta (número+contexto / lista / série / mapa / chart) + rejeitadas técnicas. |
|
||||
|
||||
## As três perguntas (ordem fixa)
|
||||
Se o item **não** apresenta dados: `Dados: N/A` no plano de intenção e pule o resto.
|
||||
|
||||
Responda nesta ordem. Pular para “qual chart?” antes de fechar (1)–(2) é o erro clássico.
|
||||
## Na intenção (`plan-issue`)
|
||||
|
||||
Ordem fixa:
|
||||
|
||||
```text
|
||||
1. Vou apresentar dados?
|
||||
2. Quais decisões serão tomadas a partir destes dados?
|
||||
3. Como apresentar estes dados para auxiliar essa decisão de forma efetiva?
|
||||
```
|
||||
|
||||
### 1. Vou apresentar dados?
|
||||
|
||||
| Resposta | Critério | Ação no plano |
|
||||
| ------------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------- |
|
||||
| **Não** | Só schema/action/access; nenhum número lido por humano nesta entrega | `Dados: N/A` — fim |
|
||||
| **Sim, derivado / API só** | Utility/aggregate que **outra** superfície já consome (ou item futuro) | Registrar payload + quem consome; UI fica no dono |
|
||||
| **Sim, superfície neste item** | Lista, detalhe, dashboard, mapa, CSV export legível, card de insight | Preencher seção completa abaixo |
|
||||
| Resposta | Ação |
|
||||
| -------- | ---- |
|
||||
| **Não** | `Dados: N/A` |
|
||||
| **Sim, derivado / API só** | Registrar quem consome; UI no dono |
|
||||
| **Sim, superfície neste item** | Preencher decisões desbloqueadas + restrições |
|
||||
|
||||
Se “sim”: profile rápido do dado — tipo (categórico / numérico / temporal / geo), granularidade (praça / município / TI / estado), tamanho típico (1 KPI vs 436 linhas vs série 3 anos), e se é **absoluto ou relativo** (no `/campanha` electoral, preferir relativo/local — ver anti-goals).
|
||||
Profile rápido (opcional): tipo / granularidade / absoluto vs relativo.
|
||||
|
||||
### 2. Quais decisões serão tomadas a partir destes dados?
|
||||
### 2. Decisões desbloqueadas
|
||||
|
||||
Uma frase por decisão, no formato **ator + escolha**. Sem decisão nomeável → o dado é vaidade; corte ou rebaixe a “contexto secundário”.
|
||||
Formato **ator + escolha**. Sem decisão nomeável → vaidade; corte.
|
||||
|
||||
Exemplos Teqo bons:
|
||||
**Não** escolha chart/mapa/KPI aqui. Registre só anti-goals de produto (ex.: sem gauge SaaS, sem % estadual absoluto).
|
||||
|
||||
- Coordenador: “nesta semana, atacar déficit descoberto em quais Praças?”
|
||||
- Assessor: “minha meta fecha? se não, renegociar pledge ou abrir demanda?”
|
||||
- Staff: “comparar candidato X vs Solla neste município — manter ou pivotar discurso?”
|
||||
## Na implementação (`*-impl.md`)
|
||||
|
||||
Exemplos ruins (rejeitar):
|
||||
|
||||
- “Ter visibilidade do % estadual” (anti-goal; não decide alocação)
|
||||
- “Ver quantos apoiadores cadastrados” sem vínculo a cobertura/meta
|
||||
- “Dashboard bonito para impressionar”
|
||||
|
||||
Se o item toca inteligência de campanha / mapa / metas / fila: consulte **antes** o playbook em `docs/research/relatorio-entrevista-persona-campanha.md` (§6 padrões dado→decisão) e o anti-catálogo do plano-mestre `docs/plans/inteligencia-campanha.md`. Não invente métrica que o research vetou.
|
||||
|
||||
### 3. Como apresentar para auxiliar essa decisão?
|
||||
|
||||
Escolha a **forma mais pobre que ainda responde a decisão** (depth: reusar shell existente > chart novo > lib de charts). Registre no plano: forma + racional + o que foi rejeitado.
|
||||
|
||||
**Escada de pobreza (preferir o degrau mais baixo que resolve):**
|
||||
|
||||
| Degrau | Quando usar | Reuso Teqo típico |
|
||||
| ------------------------------ | ----------------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| **Número + contexto** | 1–2 valores, “fecha / não fecha”, delta vs meta/semana | `CampaignMetricStrip`, linha no overview |
|
||||
| **Tabela / lista ranqueada** | Comparar muitas entidades (Praças), ordenar por déficit/cobertura | `PlazaList` + colunas; fila de alocação |
|
||||
| **Série temporal simples** | Evolução curta (3–5 pontos: 2014/2018/2022 ou delta semanal) | sparkline / tabela ano×valor; não multi-eixo |
|
||||
| **Mapa (cor / símbolo)** | Decisão é **onde** agir; geo é central à pergunta | `BahiaMap` + escala relativa (quantil/LQ), não % est. |
|
||||
| **Chart (barra / linha)** | Comparação de poucas categorias ou tendência com >~5 pontos | shadcn/`src/components/ui`; tokens `campaign` |
|
||||
| **Chart composto / dashboard** | Só se appetite e research pedirem; senão rabbit hole | Adiar com gatilho |
|
||||
|
||||
**Família de pergunta → forma** (resumo de visualization-choice-reporting, calibrado ao Field Desk):
|
||||
|
||||
| Pergunta que o dado responde | Preferir | Evitar neste produto |
|
||||
| ---------------------------------- | -------------------------------- | ----------------------------------- |
|
||||
| Quanto falta / cobre a meta? | Número + % cobertura + delta | Gauge/velocímetro SaaS, hero-metric |
|
||||
| Onde está o buraco / oportunidade? | Mapa relativo ou lista ranqueada | Choropleth de % estadual absoluto |
|
||||
| Como evoluiu no tempo? | Linha/sparkline ou tabela anos | Pie; dual Y-axis |
|
||||
| Como A se compara a B (poucos)? | Barra horizontal ou tabela | Pie com muitas fatias; 3D |
|
||||
| Qual a composição do todo? | Stacked bar ou tabela | Donut decorativo |
|
||||
| Correlação / nuvem de pontos? | Quase nunca em v1 `/campanha` | Scatter exploratório sem decisão |
|
||||
|
||||
**Narrativa mínima na UI** (mesmo sem relatório formal): o bloco de dados deve permitir ler, nesta ordem — **insight → padrão → contexto (vs meta/histórico) → implicação → próxima ação possível**. Título descritivo (“Votos por mês”) sem insight é falha. Em `/campanha`, a “ação” é menu para julgamento humano (nunca auto-decisão) — alinhado ao research.
|
||||
|
||||
## Anti-goals Teqo (não negociar sem fonte nova)
|
||||
|
||||
- KPI de **% estadual absoluto** como escala principal (achatamento; DF ≠ majoritária).
|
||||
- Contagem bruta de cadastros / “vanity metrics” sem vínculo a cobertura/meta/fila.
|
||||
- Cartograma, gauge, rainbow choropleth, dual-axis enganoso.
|
||||
- Mapa bonito com pergunta errada (visualização serve à análise; análise serve à decisão — research § ordem Brewer/Pickle).
|
||||
- Segunda lib de charts / design system paralelo; inventar paleta fora de `data-theme='campaign'`.
|
||||
- Sugestão automática sem registro de decisão humana (C12 / motor de sugestões).
|
||||
|
||||
## Quando NÃO usar gráfico
|
||||
|
||||
- Um único número decisivo → número tipográfico + unidade + vs quê.
|
||||
- Dois números → lado a lado com delta %.
|
||||
- Poucas linhas densas de auditoria → tabela.
|
||||
- Export/CSV para operação → tabela; chart é opcional depois.
|
||||
|
||||
## Caro vs barato nesta superfície
|
||||
|
||||
| Caro (Decisão travada + rejeitadas) | Barato (Não escopo / Adiado) |
|
||||
| ------------------------------------------------ | ----------------------------------------- |
|
||||
| Métrica canônica (fórmula, denominador, quem vê) | Cor da barra, ordem de colunas |
|
||||
| Escala do mapa (absoluta vs % vs quantil/LQ) | Tooltip copy |
|
||||
| Staff-only vs leader-visible | Sparkline vs número só |
|
||||
| Persistência de derivado vs compute on read | Biblioteca de chart (se já há shadcn/SVG) |
|
||||
|
||||
## Self-check (30s, só se Dados ≠ N/A)
|
||||
|
||||
Antes de gravar o plano ou declarar a fase de UI pronta — 1 ponto cada; **<3 → corrigir**:
|
||||
|
||||
1. As três perguntas estão respondidas por escrito?
|
||||
2. Há pelo menos uma **decisão nomeável** (ator + escolha)?
|
||||
3. A forma escolhida é o degrau mais pobre que resolve — com alternativas rejeitadas?
|
||||
4. Anti-goals do research/`PRODUCT.md` §5 não foram violados?
|
||||
5. Depth: reusa `CampaignMetricStrip` / lista / `BahiaMap` / tabela existente quando bastam?
|
||||
|
||||
## Onde registrar
|
||||
|
||||
- **`plan-issue`:** seção **Dados → decisão → apresentação** no `docs/plans/<slug>.md` (template). Se N/A, uma linha basta.
|
||||
- **`work-issue`:** auditar essa seção no Passo 4; se ausente e o item claramente apresenta dados → defasado (completar no Passo 7). Nas fases de UI, a escolha de forma é input do craft/critique — não reinventar no meio do polish.
|
||||
- Skills externas (opcional, leitura sob demanda): `visualization-choice-reporting` (famílias de chart + narrativa); `.agents/skills/refactoring-ui/references/data-visualization.md` (quando NÃO chartar); Mapbox patterns só se o item for mapa Mapbox (hoje o mapa Teqo é Leaflet/`BahiaMap`).
|
||||
Responda a pergunta 3 com Opções + Recomendação + rejeitadas, alinhado a [decision-quality.md](../work-issue/decision-quality.md) e ao research Teqo. Preferir a forma mais pobre que ainda desbloqueia a decisão.
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
# Qualidade de decisão (roadmap / implementação / débitos)
|
||||
|
||||
Inspirado em `design-code-architecture` e nas skills que ela compõe (37signals, software-design-philosophy, clean-architecture, DDD), mais destilados de `spec-driven-development`, `planning-and-task-breakdown`, `incremental-implementation` e `doubt-driven-development` — **sem** jornada guiada por fases. Use estes filtros automaticamente ao redigir planos, implementar ou triar débitos. Decisão silenciosa é defeito.
|
||||
|
||||
Mapa completo do que absorver vs. rotear: [skills-map.md](skills-map.md).
|
||||
|
||||
## Filtro caro vs barato
|
||||
|
||||
Delibere e registre só o **caro de reverter**. O barato vira Não escopo, fill-in, ou “mais simples que funciona” com **gatilho de revisitação** (não “depois”).
|
||||
|
||||
| Caro (decidir agora + alternativas rejeitadas) | Barato (adiar / mais simples) |
|
||||
| ------------------------------------------------------------------------ | ----------------------------------- |
|
||||
| Collection nova, unicidade, modelo de access | Polish cosmético, 2º estilo de card |
|
||||
| Nova chave `Consent` / superfície PII | Copy, motion, a11y P3 |
|
||||
| Semântica de escrita multi-collection / locks | Prefetch, apresentação de KPI |
|
||||
| URL pública / slug imutável | Ordem de colunas na lista |
|
||||
| Separar item de trilha vs absorver em plano | Rename de pureza, naming cosmético |
|
||||
| Fronteira de módulo em ponto de volatilidade real (DB, vendor, delivery) | Adapter/interface com 1 call site |
|
||||
|
||||
Converter caro em barato: colocar um boundary na frente (fail-closed por chave, join em `Contact`, chips opt-in em vez de igualdade forçada) — o conjunto irredutível de decisões caras deve caber nas Decisões travadas.
|
||||
|
||||
## Forma obrigatória de decisão
|
||||
|
||||
Toda decisão não trivial (posicionamento, classe Impeccable B↔C, absorver vs registrar, default de produto, schema vs não):
|
||||
|
||||
```text
|
||||
Opções: A | B | C
|
||||
Recomendação: B — porque …
|
||||
Alternativas rejeitadas: A porque …; C porque …
|
||||
```
|
||||
|
||||
No plano: Decisões travadas = **decisão + por quê + fonte/data + alternativas rejeitadas**. Em Questões em aberto: **Opções + Recomendação** (nunca pergunta sem posição). Assuma o default e marque _(assumido — validar com produto)_ — não abra tour de confirmações.
|
||||
|
||||
## Premissas (antes da Abordagem)
|
||||
|
||||
Não preencha ambiguidade em silêncio. Liste premissas no plano e no gate:
|
||||
|
||||
```text
|
||||
PREMISSAS:
|
||||
1. …
|
||||
→ Corrija agora ou sigo com estas.
|
||||
```
|
||||
|
||||
Pedido vago → **reframe em critérios de aceite testáveis** antes de desenhar componentes. Se não dá para marcar um checkbox de Objetivo ao fim da Issue, a ideia ainda não está shaped (Passo 1b / `idea-refine`).
|
||||
|
||||
## Appetite (tempo fixo, escopo flexível)
|
||||
|
||||
Além da **janela** eleitoral, declare um **appetite** (quanto o slice vale), não uma estimativa aberta:
|
||||
|
||||
- Exemplos: `~0,5 dia eng, só utility` · `~1–2 dias, migration + 1 action + encaixe em lista` · `~1 ciclo curto, UI nova 1 rota`.
|
||||
- Se a Abordagem proposta estourar o appetite → cortar rabbit holes / Não escopo, não inflar o item.
|
||||
- Em `work-issue`, cada fase declara quanto do appetite consome; preferir um **tracer bullet** cedo (schema → uma action → uma superfície UI) antes de polish paralelo.
|
||||
|
||||
## Fatias verticais (fases do plano)
|
||||
|
||||
De `planning-and-task-breakdown` + `incremental-implementation` — no artefato Teqo (`docs/plans/`), não em `tasks/todo.md`.
|
||||
|
||||
**Ruim (horizontal):** schema completo → todas as actions → toda a UI → “ligar”.
|
||||
**Bom (vertical):** Fase 1 prova um path fino ponta a ponta; Fase 2 alarga.
|
||||
|
||||
Regras:
|
||||
|
||||
1. **Ordem = grafo de dependência**, não “o que parece importante”. Fundações (migration, access) só o mínimo para o tracer.
|
||||
2. **Cada fase** tem aceite (≤3 bullets), verify (comando/pin), files, tamanho **S** (1–2 files) ou **M** (3–5). **L/XL** → partir a fase ou bipartir a Issue.
|
||||
3. **Fase 1 = tracer bullet** (ou risk-first se a aposta arriscada for outra — ex. provar WebAuthn antes do chrome).
|
||||
4. Após cada fase o sistema deve permanecer **compilável / testes verdes** (disciplina de `work-issue`).
|
||||
5. Checkpoint humano só quando o plano tiver >2 fases ou uma decisão cara ainda aberta — não cerimônia entre S chores.
|
||||
|
||||
## Doubt em decisão cara (ciclo curto)
|
||||
|
||||
De `doubt-driven-development` — **só** quando a decisão é não trivial **e** cara de reverter (branching de access, migration irreversível, invariante que o type system não pega, URL pública).
|
||||
|
||||
```text
|
||||
CLAIM: <1–2 linhas>
|
||||
WHY IT MATTERS: <blast radius>
|
||||
→ Adversarial self-check (ou Task fresh-context): achar furos no ARTIFACT+CONTRACT,
|
||||
não validar. Classificar: actionable | trade-off documentado | noise.
|
||||
→ Parar em 1 ciclo no planning (3 ciclos é para implementação).
|
||||
```
|
||||
|
||||
Não doubt: rename, copy, chore mecânico, “seguimos o shell de lista existente”.
|
||||
Não invocar cross-model CLI daqui — se o usuário quiser segunda opinião, ofereça no gate.
|
||||
|
||||
## Rabbit holes
|
||||
|
||||
Riscos que explodem o escopo se tocados “de passagem”. Listar ao lado de Não escopo (não são a mesma coisa):
|
||||
|
||||
| Não escopo | Rabbit hole |
|
||||
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Exclusão consciente com destino (outro plano/ID) | Armadilha se alguém “só completar” |
|
||||
| Ex.: mapa Leaflet → B3 | Ex.: layers Clean Architecture só para um feature; 2ª collection de pessoa; igualdade forçada TSE; event sourcing; helper shared antes de 3 call sites |
|
||||
|
||||
Rabbit holes Teqo recorrentes: layers/cerimônia sem volatilidade, cadastro paralelo a `Contact`, Consent hardcoded por ID, abstração DRY prematura, redesign de paleta fora de `campaign`.
|
||||
|
||||
## Depth check (módulos profundos)
|
||||
|
||||
Antes de propor arquivo/utility/componente novo na Abordagem:
|
||||
|
||||
1. Já existe módulo profundo que esconde isso? (`campaignAccess`, shells de lista, `withPayloadTransaction`, `campaignConsent`, …) → **reusar**.
|
||||
2. O novo símbolo esconde complexidade real ou é pass-through raso (classitis)? → **consolidar ou não criar**.
|
||||
3. Uma decisão de design vazaria em N módulos? → **encapsular uma vez**.
|
||||
|
||||
Não invocar a skill `software-design-philosophy` inteira — aplicar só este check no momento da decisão.
|
||||
|
||||
## Defer com gatilho
|
||||
|
||||
Adiar sem gatilho vira backlog morto. Formato:
|
||||
|
||||
`Adiar X até <evidência concreta>` — ex.: “shared `drizzleBulk` quando existir o 3º caminho bulk”; “réplicas/cache quando QPS médio > N” (raro neste produto).
|
||||
|
||||
Em `capture-review-debts`: DRY com <3 call sites → preferir **descartar** ou **defer+gatilho** a **registrar**, salvo access/LGPD/hot path.
|
||||
|
||||
## Boundaries Always / Ask / Never (por entrega)
|
||||
|
||||
Compacto no plano — reforça o que **esta** Issue carrega; não reescrever AGENTS.md.
|
||||
|
||||
| Tier | Exemplos Teqo típicos |
|
||||
| ----------- | ------------------------------------------------------------------------------------- |
|
||||
| **Always** | `overrideAccess: false` com `user`; pin de teste do parser/access; fail-closed Consent |
|
||||
| **Ask first** | Collection/migration nova; dependency nova; mudar contrato de URL pública |
|
||||
| **Never** | Neon em dev/test; Consent por document ID; pessoa fora de `Contact`; `as never` |
|
||||
|
||||
## Princípios sob demanda (método, não jornada)
|
||||
|
||||
Quando o tipo de decisão bater, aplicar o princípio — **não** abrir fases de `design-code-architecture`:
|
||||
|
||||
| Tipo de decisão | Princípio |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| Dependências de código / testabilidade do domínio | Dependency Rule: framework/ORM no anel externo; core testável sem DB/web |
|
||||
| Vocabulário / aggregate / “Customer” em dois sentidos | DDD: não unificar; invariants no aggregate; refs por ID |
|
||||
| Escopo de v1 do item | 37signals: build less, YAGNI, cortar abstração especulativa; **nunca** cortar o caro de reverter |
|
||||
| Depth / leakage na abordagem | software-design-philosophy: deep modules, um lugar por conhecimento |
|
||||
| Outbound / lista / import | Timeouts, paginação, fail-closed (já em AGENTS.md) — nomear como decisão se o item toca |
|
||||
| KPI / mapa / série / ranking na UI | [data-presentation.md](data-presentation.md): dado → decisão nomeável → forma mais pobre |
|
||||
| API de framework na Abordagem | Flag source-driven para `work-issue` (versão em package.json); não inventar da memória no plano |
|
||||
|
||||
## Self-score (gate de 30s)
|
||||
|
||||
Antes de gravar docs ou declarar o plano de implementação pronto, pontue 0–5 (1 ponto cada). **<4 → corrigir antes de escrever/seguir**:
|
||||
|
||||
1. Decisões caras têm alternativas rejeitadas (e doubt curto se migration/access/Consent/URL)?
|
||||
2. Appetite declarado; fases verticais cabem nele; Fase 1 = tracer (ou risk-first justificado)?
|
||||
3. Premissas listadas + Objetivos como aceite testável + Boundaries Always/Ask/Never?
|
||||
4. Rabbit holes nomeados (além de Não escopo) + depth check (reusa shells, sem classitis)?
|
||||
5. Consistência aplicável: tripla grafo=tabela=Dependências **ou** triage score/destino/tipo alinhados?
|
||||
|
||||
Opcional no resumo ao usuário: `Qualidade de decisão: N/5` + o item que falhou.
|
||||
89
.cursor/skills/plan-issue/intention-template.md
Normal file
89
.cursor/skills/plan-issue/intention-template.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Template de plano de intenção (`docs/plans/<slug>.md`)
|
||||
|
||||
Plano de **produto/intenção** — o que o humano quer, para quem, e como saber que deu certo. **Não** é plano de engenharia: quem executa (`work-issue` / `agent-work-issue`) cria o `docs/plans/<slug>-impl.md` depois, com liberdade de reavaliar a abordagem técnica.
|
||||
|
||||
Shaping: [shaping.md](shaping.md). Dados (só decisão de produto): [data-presentation.md](data-presentation.md).
|
||||
|
||||
````markdown
|
||||
# <Título do item em pt-BR>
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: <YYYY-MM-DD>
|
||||
Issue: #<N> (após `pnpm agent:register`; senão "—")
|
||||
Priority: <P0 | P1 | P2 | P3>
|
||||
Model: <slug model-selection>
|
||||
Impeccable: <A | B | C | D> — <N/A sem UI | encaixe em tela X | fluxo novo em Y>
|
||||
Appetite: <ex.: ~0,5–1 dia eng; um outcome verificável>
|
||||
Responsável: —
|
||||
|
||||
## Intenção
|
||||
|
||||
<Por que isso existe agora. Problema ou oportunidade em prosa curta — voz do humano, não da stack.>
|
||||
|
||||
## Persona e fluxo
|
||||
|
||||
- **Persona / contexto:** <quem usa, onde (campo/mesa), estado de espírito>
|
||||
- **Job principal:** <uma frase — o que precisa conseguir>
|
||||
- **Fluxo desejado:** <passos em linguagem de usuário; o que vê / faz / decide>
|
||||
- **Anti-goals de produto:** <o que esta entrega NÃO deve virar (ex.: spreadsheet mode, segundo cadastro de pessoa)>
|
||||
|
||||
### Esboço de fluxo (B/C/D)
|
||||
|
||||
<!-- ASCII de jornada, não layout de implementação. Omitir se A ou só controle isolado. -->
|
||||
|
||||
\```text
|
||||
[início] → … → [outcome]
|
||||
\```
|
||||
|
||||
## Objetivo e aceite
|
||||
|
||||
- <Outcome verificável em linguagem de produto, um por bullet>
|
||||
- <Guardrails de produto que valem para o item: ex. "liderança não vê estimativas", "fail-closed se faltar consentimento" — sem nomear migration/collection>
|
||||
|
||||
## Dados (intenção)
|
||||
|
||||
<!-- Sempre presente. Sem métrica: "Dados: N/A — <por quê>". -->
|
||||
|
||||
- **Vou apresentar dados?** <Não | Sim, só aggregate para outro consumidor | Sim, superfície neste item>
|
||||
- **Decisões desbloqueadas:** <ator + escolha; uma por bullet. Sem decisão nomeável → corte vaidade.>
|
||||
- **Forma:** *adiada ao plano de implementação* — aqui só restrições de produto (ex.: "sem % estadual absoluto", "leitura relativa/local").
|
||||
|
||||
## Direção no codebase (hipótese)
|
||||
|
||||
<!-- Soft. Revisável. Sem signatures, sem "criar collection X", sem mermaid de solução. -->
|
||||
|
||||
- **Áreas prováveis:** <rotas `/campanha/…`, pastas `src/components/campaign/<domínio>/`, `src/utilities/<domínio>/`, `src/lib/…`>
|
||||
- **Precedente a olhar:** <plano/Issue/arquivo análogo, se houver>
|
||||
- **Risco de acoplamento:** <uma linha — o que o executor deve respeitar (ex.: leader lockdown, lista B18)>
|
||||
|
||||
## Dependências
|
||||
|
||||
- <IDs duros/suaves ou "Nenhuma">
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- <Exclusões de produto, com destino (outro ID/plano) quando houver>
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
- **<Risco>.** Se alguém “só completar”: <explosão de escopo>. **Corte neste item:** <…>.
|
||||
|
||||
## Questões em aberto (produto)
|
||||
|
||||
<!-- Opções + Recomendação de produto. Nunca pergunta sem posição. -->
|
||||
|
||||
- **<Pergunta>?** **Opções:** A | B | C. **Recomendação:** <…>. _(assumido — validar com produto)_ quando couber.
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue #<N>
|
||||
- <arquivos/rotas úteis para o executor abrir primeiro — como pista, não contrato>
|
||||
- `AGENTS.md` / `docs/ARCHITECTURE.md` — só se o item toca convenção já travada no repo
|
||||
````
|
||||
|
||||
Notas:
|
||||
|
||||
- Alvo: ~60–100 linhas. Mais que isso costuma significar engenharia vazando para a intenção.
|
||||
- Classe **A:** `Impeccable: A — N/A`; omita esboço de fluxo.
|
||||
- Não rode `/impeccable` aqui.
|
||||
- Self-score shaping ≥4/5 antes de gravar.
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
# Template de plano (`docs/plans/<slug>.md`)
|
||||
|
||||
Estrutura extraída dos planos existentes (`overview-lista-nucleos.md`, `visitados-recentemente.md`, etc.). Manter as seções nesta ordem; omitir "Design (Impeccable)" apenas na classe **A** (só backend); **sempre** incluir "Dados → decisão → apresentação" (`N/A` se não houver superfície de dados); omitir a subseção "Referência visual (UX Pilot)" quando não houver design-ref; omitir "Wireframe (texto)" quando não houver layout a posicionar (ver skill `work-issue`).
|
||||
|
||||
Filtros de decisão (caro vs barato, appetite, rabbit holes, depth, fatias, doubt): [decision-quality.md](decision-quality.md).
|
||||
Filtro de dados (apresentar? decisão? forma?): [data-presentation.md](data-presentation.md) — obrigatório se houver KPI/mapa/série/ranking; senão `Dados: N/A`.
|
||||
Mapa skills de planejamento: [skills-map.md](skills-map.md).
|
||||
|
||||
````markdown
|
||||
# <Título do item em pt-BR>
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: <YYYY-MM-DD>
|
||||
Issue: #<N> (preencher após `pnpm agent:register`; enquanto não registrado: "—")
|
||||
Priority: <P0 | P1 | P2 | P3>
|
||||
Model: <slug sugerido por model-selection: composer-2.5 | cursor-grok-4.5-low|medium|high | kimi-k3-low>
|
||||
Impeccable: <A | B | C | D> — <uma linha: N/A sem UI | encaixe em tela X | UI nova em rota Y | ref Nome.png>
|
||||
Appetite: <ex.: ~1–2 dias eng; migration + 1 action + encaixe em lista existente>
|
||||
Responsável: —
|
||||
|
||||
## Premissas
|
||||
|
||||
<!-- Obrigatório. O que o plano assume e o gate deve confirmar. Não omita. -->
|
||||
|
||||
1. <premissa de produto / papel / schema / escopo>
|
||||
2. <…>
|
||||
→ Corrija no gate ou o implementador segue com estas.
|
||||
|
||||
## Design (Impeccable)
|
||||
|
||||
<!-- Obrigatório se Impeccable = B, C ou D. Omitir inteiro se A. -->
|
||||
|
||||
Âncoras: `PRODUCT.md` / `DESIGN.md` (register <product|brand>) · tema `data-theme='campaign'` (ou tokens do site público).
|
||||
|
||||
Na implementação (`work-issue`): <shape → craft → critique → polish | craft compacto → critique → polish | shape compacto (ref) → craft → …>. Declarar `harden`/`optimize` só se o Passo 8 do implement acionar gatilho (não pipeline fixo).
|
||||
|
||||
Brief compacto (obrigatório em C; se B ambíguo):
|
||||
|
||||
- **Persona / contexto:** <quem, onde, estado de espírito>
|
||||
- **Job principal:** <uma frase>
|
||||
- **Estratégia de cor:** Restrained (default) | <exceção justificada>
|
||||
- **Edit where you see** (só `/campanha` staff, UI B/C/D): <sim — affordance no contexto + actions existentes | não — só leitura / `/editar` justificado> — princípio 3 de `PRODUCT.md`; rabbit hole: spreadsheet mode
|
||||
- **Anti-goals:** <o que esta superfície não deve ser>
|
||||
|
||||
### Wireframe (texto)
|
||||
|
||||
<!-- Opcional no plano durável; obrigatório no plano de implementação (skill work-issue)
|
||||
quando B/C/D posiciona blocos. Caixas ASCII + rótulos pt-BR; sem cores/pixels.
|
||||
Omitir se só copy/controle isolado ou se "seguir design-ref à risca" sem adaptação. -->
|
||||
|
||||
\```text
|
||||
┌─ <rota ou superfície> ───────────────────────────────┐
|
||||
│ <bloco / região> │
|
||||
│ <…> │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
Fora do frame: <chrome compartilhado / tabs fora do item>.
|
||||
\```
|
||||
|
||||
### Referência visual (UX Pilot)
|
||||
|
||||
<!-- Só se existir design em docs/design-refs/latest/. -->
|
||||
|
||||
Design: [`<Nome>.png`](../design-refs/latest/<Nome>.png) · [`<Nome>.html`](../design-refs/latest/<Nome>.html)
|
||||
|
||||

|
||||
|
||||
Como usar:
|
||||
|
||||
- **Adotar a estrutura:** <o que do design corresponde aos objetivos deste plano>.
|
||||
- **Fora deste plano:** <partes do design que pertencem a outros planos, com links>.
|
||||
- **Ajustar cores e código:** o HTML/PNG usa a paleta antiga (vermelho escuro `#8E0E23`, navy `#1B2B4B`, dourado `#C8874B`) e Tailwind via CDN. Implementar com os componentes shadcn existentes (`src/components/ui`) e os tokens do tema `data-theme='campaign'` (`src/app/(frontend)/styles.css`): fundo branco, primário `#C51414`, superfícies neutras claras.
|
||||
|
||||
<!-- Se o item nasce de critique: cite `.impeccable/critique/<snapshot>.md` aqui; não rode critique novo neste fluxo. -->
|
||||
|
||||
## Dados → decisão → apresentação
|
||||
|
||||
<!-- Obrigatório em todo plano (também na classe A). Sem métrica/mapa/série/ranking nesta entrega: uma linha "Dados: N/A — <por quê>". Caso contrário as três perguntas. Ver data-presentation.md. -->
|
||||
|
||||
- **Vou apresentar dados?** <Não (N/A) | Sim, só aggregate para <consumidor> | Sim, superfície neste item>
|
||||
- **Decisões desbloqueadas:** <ator + escolha; uma por bullet. Sem decisão nomeável → corte vaidade.>
|
||||
- **Forma escolhida:** <degrau da escada: número+contexto | tabela/lista | série | mapa | chart | …> — **por quê.** **Rejeitado:** <chart/mapa/KPI alternativos e por quê>.
|
||||
- **Profile (se Sim):** tipo / granularidade / tamanho típico / absoluto vs relativo.
|
||||
- **Anti-goals de dado:** <ex.: sem % estadual absoluto; sem gauge SaaS — ou "N/A">.
|
||||
|
||||
## Contexto
|
||||
|
||||
<Estado atual do sistema (com caminhos de arquivo reais), o problema/oportunidade, e a decisão
|
||||
de produto que originou o item, com data. Responde "por que isso existe".>
|
||||
|
||||
## Objetivos (critérios de aceite)
|
||||
|
||||
<!-- Cada bullet = condição testável / verificável ao fim da Issue — não wish-list.
|
||||
Incluir guardrails do item: access, migration sim/não, Consent, etc. -->
|
||||
|
||||
- [ ] <resultado verificável>
|
||||
- [ ] <…>
|
||||
- Guardrails: <access / migration / Consent / sem Neon / …>
|
||||
|
||||
## Boundaries (desta entrega)
|
||||
|
||||
<!-- Compacto. Defaults do repo não precisam de ensaio — só o que esta Issue reforça ou excepciona. -->
|
||||
|
||||
- **Always:** <ex.: queries com user + overrideAccess: false; pin unit do parser>
|
||||
- **Ask first:** <ex.: collection nova; dependency nova; mudar URL pública>
|
||||
- **Never:** <ex.: Consent por ID hardcoded; cadastro paralelo a Contact; tocar Neon>
|
||||
|
||||
## Decisões travadas
|
||||
|
||||
<!-- Só decisões caras de reverter. Formato: decisão + por quê + fonte/data + alternativas rejeitadas.
|
||||
Ver decision-quality.md. Decisão silenciosa ou sem alternativas rejeitadas é defeito.
|
||||
Decisão repo-wide além deste item → marcar "candidata a doc em docs/" (não criar ADR schema novo sem precedente). -->
|
||||
|
||||
- **<Decisão em negrito>.** <Racional e fonte com data.> **Rejeitado:** <alternativa A porque …; B porque …>.
|
||||
- **i18n e naming** seguem o AGENTS.md: identificadores em inglês (<listar os principais
|
||||
nomes propostos>), strings visíveis em pt-BR.
|
||||
|
||||
## Questões em aberto
|
||||
|
||||
<!-- Formato: Opções + Recomendação. Nunca pergunta sem posição. -->
|
||||
|
||||
- **<Pergunta>?** **Opções:** A | B | C. **Recomendação:** <posição concreta e por quê>. <"Definir com
|
||||
produto" quando aplicável — mas nunca pergunta sem recomendação.>
|
||||
|
||||
## Abordagem proposta
|
||||
|
||||
\```mermaid
|
||||
flowchart LR
|
||||
<fluxo de dados/componentes da solução>
|
||||
\```
|
||||
|
||||
Componentes:
|
||||
|
||||
<!-- Depth check: reusar módulos profundos existentes; não criar pass-through raso. -->
|
||||
|
||||
- **`<NomeDoComponente/função>`** (em `src/<caminho real>`): <responsabilidade, assinatura,
|
||||
o que reusa. Queries Payload com `user` levam `overrideAccess: false`; escrita
|
||||
multi-collection é transacional; hooks propagam `req`.>
|
||||
- <um bullet por componente/arquivo novo ou alterado>
|
||||
- **<Migration>**: <se houver: nome sugerido `pnpm migrate:create <nome>`, o que adiciona,
|
||||
se tem backfill. Se não houver: "Sem migration, sem collection, sem server action.">
|
||||
- **Docs de framework (se couber):** <API Payload/Next/WebAuthn a verificar na implementação contra a versão em package.json — não citar blog/SO.>
|
||||
|
||||
## Fases verificáveis
|
||||
|
||||
<!-- Fatias VERTICAIS (não "toda DB → toda API → toda UI"). Quota do appetite.
|
||||
Fase 1 = tracer bullet. Cada fase: aceite + verify + files + tamanho S|M.
|
||||
Se só 1 fase óbvia, uma entrada basta. L/XL → partir ou Issue bipartida. -->
|
||||
|
||||
### Fase 1 — Tracer: <título curto>
|
||||
|
||||
- **Quota:** <ex.: ~0,3d do appetite>
|
||||
- **Entrega:** <path fino ponta a ponta que prova a aposta>
|
||||
- **Aceite:**
|
||||
- [ ] <condição testável>
|
||||
- **Verify:** <pnpm gate:fast | pin unit/int path | check manual>
|
||||
- **Files:** `src/…`, `tests/…`
|
||||
- **Tamanho:** S | M
|
||||
|
||||
### Fase 2 — <título>
|
||||
|
||||
- **Quota:** …
|
||||
- **Entrega:** …
|
||||
- **Aceite:** …
|
||||
- **Verify:** …
|
||||
- **Files:** …
|
||||
- **Tamanho:** S | M
|
||||
|
||||
### Checkpoint (se >2 fases)
|
||||
|
||||
- [ ] Aceites das fases 1–N verdes; sistema compilável; seguir ou cortar rabbit hole X.
|
||||
|
||||
## Dependências
|
||||
|
||||
- <Itens do roadmap dos quais depende (duras e suaves, identificadas) — ou "Nenhuma de
|
||||
outro plano." + o que reusa do código existente, com caminhos.>
|
||||
|
||||
## Não escopo
|
||||
|
||||
- <Cada exclusão explícita, citando o plano/item do roadmap para onde ela vai.>
|
||||
|
||||
## Rabbit holes
|
||||
|
||||
<!-- Armadilhas de escopo se tocadas "de passagem" — distinto de Não escopo. -->
|
||||
|
||||
- **<Risco>.** Se alguém “só completar”: <explosão>. **Mitigação neste item:** <corte / boundary / defer+gatilho>.
|
||||
|
||||
## Adiado com gatilho
|
||||
|
||||
<!-- Opcional. Barato demais para o appetite agora, mas com evidência que reabre. -->
|
||||
|
||||
- **<O quê>.** Revisitar quando: <evidência concreta — ex. 3º call site, QPS, item B3 entregue>.
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue #<N> (spec + frontmatter `id/depends/serializes/priority/model`)
|
||||
- <arquivos-fonte reais que o implementador vai abrir, um por bullet, com o porquê>
|
||||
- AGENTS.md — <quais convenções se aplicam: Campaign auth, naming, overrideAccess, etc.>
|
||||
- <!-- Se B/C/D: --> `PRODUCT.md` / `DESIGN.md` — <o que deste item herda do Field Desk / register>
|
||||
````
|
||||
|
||||
Notas:
|
||||
|
||||
- No bloco mermaid acima, remover as barras invertidas dos fences internos (`\``` → ` ``` `).
|
||||
- Nível de detalhe alvo: ~100–160 linhas (Premissas + Fases acrescentam estrutura, não prosa). Menos que ~80 costuma significar que o Passo 3 (exploração do código) foi pulado.
|
||||
- Classe **A**: omita a seção "Design (Impeccable)" e use no cabeçalho `Impeccable: A — N/A (sem superfície UI)`.
|
||||
- Seção **Dados → decisão → apresentação** é sempre presente (preenchida ou `Dados: N/A`); não omita.
|
||||
- Seções **Premissas**, **Objetivos (critérios de aceite)**, **Boundaries**, **Fases verificáveis** são sempre presentes. Chore trivial: Premissas 1 linha, Boundaries defaults, Fases = 1 entrada.
|
||||
- Não rode `/impeccable craft|critique|polish` ao criar o plano — só classifique e semeie; a skill `work-issue` executa o ciclo.
|
||||
- Self-score de qualidade de decisão (0–5) antes de gravar: ver [decision-quality.md](decision-quality.md). Se Dados ≠ N/A, self-check em [data-presentation.md](data-presentation.md) (≥3/5). Se Rabbit holes ou Adiado com gatilho estiverem vazios de propósito, escreva `Nenhum neste item.` — não omita a seção.
|
||||
56
.cursor/skills/plan-issue/shaping.md
Normal file
56
.cursor/skills/plan-issue/shaping.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Shaping de intenção (plan-issue)
|
||||
|
||||
Filtros para fatiar e descrever o que o humano quer — **sem** travar engenharia. Inspirado em Shape Up / 37signals (appetite, build less) e no caro-vs-barato de produto. Decisão silenciosa de produto é defeito; decisão silenciosa de schema aqui é **erro** (isso pertence ao plano de implementação).
|
||||
|
||||
## Fatia mínima útil
|
||||
|
||||
Cada Issue deve:
|
||||
|
||||
1. Caber num **appetite** declarado (tempo fixo, escopo flexível).
|
||||
2. Entregar **um** outcome verificável sozinho.
|
||||
3. Ser compreensível sem ler o epic-pai.
|
||||
|
||||
Se o pedido humano misturar jobs (ex.: “mapa + CSV + invite”), **separe** — a menos que um sem o outro não tenha valor.
|
||||
|
||||
| Preferir separar | Preferir manter junto |
|
||||
| ---------------- | --------------------- |
|
||||
| Outcomes distintos para personas distintas | Mesmo fluxo, mesma tela, mesmo aceite |
|
||||
| Um pedaço desbloqueia o outro depois | Separar criaria handoff inútil |
|
||||
| Um pedaço é jurídico/LGPD e o outro não | — |
|
||||
|
||||
## Appetite
|
||||
|
||||
Declare quanto o slice vale, não estimativa aberta:
|
||||
|
||||
- Exemplos: `~0,5 dia, só copy/fluxo` · `~1 dia, um encaixe em lista existente` · `~1–2 dias, fluxo novo numa rota`
|
||||
- Se a intenção não cabe → cortar rabbit holes / Fora de escopo, **não** inflar o item nem detalhar engenharia para “caber”.
|
||||
|
||||
## Caro de reverter (produto) vs barato
|
||||
|
||||
No plano de intenção, “travar” só o que é caro **de produto** e já é política do repo ou decisão humana explícita:
|
||||
|
||||
| Pode afirmar na intenção | Deixar para o plano de implementação |
|
||||
| ------------------------ | ------------------------------------ |
|
||||
| Leader lockdown / assimetria de votos | Collection nova, unicidade, shape do schema |
|
||||
| Fail-closed de consentimento (conceito) | Chave `Consent` concreta, textos versionados |
|
||||
| “Sem % estadual absoluto” | Chart vs tabela vs mapa |
|
||||
| Appetite e fora de escopo | Nomes de utilities, signatures, migration |
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
Armadilhas se alguém “só completar” o desejo humano:
|
||||
|
||||
- Segundo cadastro de pessoa paralelo a `Contact`
|
||||
- Spreadsheet mode / edição em massa sem pedido
|
||||
- Dashboard de vaidade sem decisão nomeável
|
||||
- Escopo que puxa redesign de paleta ou shell inteiro
|
||||
|
||||
## Self-score (0–5, gate ≥4)
|
||||
|
||||
1. Fatia = um outcome verificável?
|
||||
2. Appetite declarado e a intenção cabe nele?
|
||||
3. Persona + job + aceite claros (sem jargão de stack)?
|
||||
4. Direção no codebase é hipótese (não contrato técnico)?
|
||||
5. Zero decisões duras de engenharia no plano?
|
||||
|
||||
<4 → corrigir antes de gravar / registrar Issue.
|
||||
|
|
@ -203,6 +203,7 @@ Opcional e leve (se o rebase tocou schema/types): `pnpm exec tsc --noEmit` nos a
|
|||
## Posição no fluxo
|
||||
|
||||
```
|
||||
plan-issue → work-issue (claim → execução → /simplify+/impeccable
|
||||
→ rebase-on-main → capture-review-debts → PR --base stage → merge)
|
||||
plan-issue → work-issue | agent-work-issue
|
||||
(impl plan → execução → /simplify → rebase-on-main?
|
||||
→ capture-review-debts → PR --base main → merge)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,159 +1,80 @@
|
|||
---
|
||||
name: work-issue
|
||||
description: Conduz uma GitHub Issue rastreável do Teqo do claim ao merge em main — prep (pnpm i), claim (pnpm agent:claim), renomear a sessão + abrir o plano no editor, verificação do modelo declarado na Issue, freshness audit do plano, execução das fases (schema/server → UI via /impeccable → gates), /simplify (3 reviewers paralelos via Task) + capture-review-debts, PR --base main com Closes #N, acompanhamento do CI até o merge. Usar quando o usuário pedir para implementar/trabalhar uma Issue ("trabalha a issue #N", "implementa o B79", "pega a próxima issue", "vamos fazer o X", "continua a implementação").
|
||||
description: >-
|
||||
Versão humana de agent-work-issue: claim de uma Issue, Plan mode com plano
|
||||
de implementação deliberado a partir da intenção, pausa para confirmação
|
||||
humana, depois execução → /simplify → capture-review-debts → PR Ready em
|
||||
main com auto-merge. Use quando o usuário pedir /work-issue, quiser
|
||||
supervisionar a abordagem de engenharia, ou trabalhar uma Issue com gate
|
||||
humano antes do código.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Trabalhar uma Issue (claim → merge em main)
|
||||
# Work-issue (humano supervisiona)
|
||||
|
||||
Esta skill conduz UMA Issue rastreável do claim ao merge em `main`. Substitui o antigo fluxo implement-roadmap-item + close-delivery + ship-to-main. **GitHub Issues são a fonte canônica** de spec/status/deps/prio/modelo; `docs/roadmap.md` é legado congelado e nunca é editado aqui (registro de entrega vai na Issue + `docs/plans/<slug>.md` + notebook do projeto).
|
||||
Mesmo pipeline de [`agent-work-issue`](../agent-work-issue/SKILL.md), com duas diferenças:
|
||||
|
||||
**Proibido neste fluxo:** qualquer acesso a DB de prod, merge sem CI green, editar outras Issues `in-progress`.
|
||||
1. **Você claima** a Issue (`pnpm agent:claim`).
|
||||
2. **Pausa após o plano de implementação** até o humano confirmar — só então executa.
|
||||
|
||||
**Qualidade de decisão e dados:** aplique [decision-quality.md](../plan-issue/decision-quality.md) ao auditar e fatiar (caro vs barato, Opções+Recomendação+rejeitadas, appetite, rabbit holes, tracer bullet cedo) e [data-presentation.md](../plan-issue/data-presentation.md) ao auditar/fatiar superfícies com KPI/mapa/série/ranking.
|
||||
**Proibido:** DB de prod; merge sem CI green; editar outras Issues `in-progress`; pular a pausa do impl plan; Draft / sem auto-merge.
|
||||
|
||||
## Checklist do fluxo
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] 0. Prep: `pnpm i` antes do `agent:claim` (Cloud Agents já rodam via `.cursor/environment.json` → `install`; worktrees locais: obrigatório, ou deixe para o `ensure-repo-deps` do `pnpm push`). Cloud → §Prep Cloud (sem Docker; não use `db:start`)
|
||||
- [ ] 1. Claim: pnpm agent:claim (ou -- --issue <N>) — o brief do stdout é o contrato
|
||||
- [ ] 1b. Renomear a sessão (cursor-app-control rename_chat) — padrão `#<N> <id> — <título>` (linha `rename_chat:` do brief)
|
||||
- [ ] 1c. Abrir o plano no editor (cursor-app-control open_resource) para o humano acompanhar
|
||||
- [ ] 2. Verificação de modelo (best effort): comparar model: da Issue com o modelo da sessão
|
||||
- [ ] 3. Freshness audit (enxuto) do plano contra o repositório
|
||||
- [ ] 4. Executar as fases (schema/server → UI via /impeccable → gates de engenharia)
|
||||
- [ ] 5. /simplify no diff da sessão → capture-review-debts
|
||||
- [ ] 6. Fechar em main: branch → commit → **`pnpm push -u origin HEAD`** (não `git push` nu) → gh pr create --base main (Closes #N, sem --draft)
|
||||
→ gh pr merge --auto --merge → gh pr checks --watch --required até o merge → consolidar pontas soltas
|
||||
- [ ] 0. Prep: `pnpm i` se preciso
|
||||
- [ ] 1. Claim: pnpm agent:claim (ou -- --issue <N>)
|
||||
- [ ] 1b. rename_chat + open_resource (intenção)
|
||||
- [ ] 2. Verificação de modelo (assimétrica — pausa se sessão mais forte)
|
||||
- [ ] 3. Plan mode → escrever `*-impl.md` → **PARAR e confirmar com o humano**
|
||||
- [ ] 4. Após “ok”: executar como agent-work-issue Passos 4–6
|
||||
```
|
||||
|
||||
## Passo 0 — Prep (deps)
|
||||
|
||||
`pnpm agent:claim` depende de `node_modules` (scripts em `scripts/` importam pacotes do projeto). Em worktree/clone fresco, ou quando `node_modules` não existir, rode **antes** do claim:
|
||||
## Passo 0–1 — Prep e claim
|
||||
|
||||
```bash
|
||||
pnpm i
|
||||
pnpm agent:claim # topo da fila
|
||||
pnpm agent:claim -- --issue <N>
|
||||
```
|
||||
|
||||
Não pule este passo — sem deps instaladas o claim falha antes de imprimir o brief.
|
||||
O brief do stdout é o contrato de **produto** (id, prio, model, link da intenção). Claim = `ready → in-progress`.
|
||||
|
||||
### Prep Cursor Cloud (sem Docker)
|
||||
### Rename + abrir intenção
|
||||
|
||||
VMs Cloud **não têm Docker** — `pnpm db:start` (docker compose) **não funciona** aqui. O ambiente já sobe Postgres nativo via `.cursor/environment.json` (`cloud-setup.sh` no install + `ensure-postgres.sh` no start): bancos `teqo` e `teqo_test` migrados e com `db:seed:minimal`.
|
||||
Padrão: `#<N> <id> — <título>` via `cursor-app-control` `rename_chat`.
|
||||
Abra o plano de intenção com `open_resource` (`file:///…/docs/plans/<slug>.md`).
|
||||
|
||||
- **`pnpm gate:fast` e `pnpm gate:push` não precisam de Postgres** — `test:unit` usa `DATABASE_URL` inválida de propósito (sem conexão real).
|
||||
- Só `pnpm test:int` / `pnpm migrate` tocam o banco — já preparado no install; se conexão falhar: `bash ./.cursor/ensure-postgres.sh`.
|
||||
- **Proibido `git push --no-verify`** no fechamento da Issue. O pre-push roda `pnpm gate:push` (~1–2 min) — espere passar; CI não substitui o hook local.
|
||||
## Passo 2 — Modelo
|
||||
|
||||
## Passo 1 — Claim
|
||||
Regra assimétrica (`model-selection`):
|
||||
|
||||
```bash
|
||||
pnpm agent:claim # pega o topo da fila (ready, desbloqueadas, por prio)
|
||||
pnpm agent:claim -- --issue <N> # quando o usuário especifica
|
||||
```
|
||||
- Sessão **mais fraca** que `model:` → informa e segue
|
||||
- Sessão **mais forte** → **informa e pausa** (“pedir X, está em Y — seguir?”)
|
||||
- Ausente → aplique model-selection e registre na Issue
|
||||
|
||||
O brief impresso no stdout é o contrato: id, priority, **model**, spec, link do plano. O claim faz o swap de label `ready → in-progress` com lock otimista. Se falhar ("claimed by someone else"), re-rodar — nunca forçar.
|
||||
## Passo 3 — Plano de implementação + GATE humano
|
||||
|
||||
### Renomear a sessão
|
||||
Siga o **Passo 3** de `agent-work-issue` (Plan mode, engineering-brief, decision-quality, `docs/plans/<slug>-impl.md`).
|
||||
|
||||
Logo após o claim bem-sucedido, **renomeie a aba desta conversa** para o humano identificar o trabalho em curso — não espere ele pedir. Política do repo: no fluxo `work-issue` isso **não** é opcional — a descrição padrão da ferramenta MCP ("só quando o usuário pedir") não se aplica aqui.
|
||||
Depois de gravar o impl plan:
|
||||
|
||||
**Padrão canônico** (decisão travada — use sempre este formato, sem variações):
|
||||
1. Apresente no chat: abordagem recomendada, opções rejeitadas, fases, riscos, o que diverge da hipótese de direção da intenção.
|
||||
2. **Pare.** Não escreva código de feature até confirmação explícita (“ok”, “pode executar”, “aprovado”, …).
|
||||
3. Se o humano pedir mudança de abordagem → revise o `*-impl.md` e reapresente.
|
||||
4. Confirmação → marque Status `aprovado` no impl plan → `SwitchMode` `agent` → continue.
|
||||
|
||||
| Campo | Fonte no brief | Regra |
|
||||
| ----- | --------------- | ----- |
|
||||
| `#<N>` | linha `Claimed #<N> — …` | número GitHub da Issue; sempre presente |
|
||||
| `<id>` | linha `id: …` | id de roadmap (`B79`, `C11`, `FD2+`…); omita o segmento se `(none)` |
|
||||
| `<título>` | título da Issue (após `Claimed #<N> — `) | se começar com `<id> — `, remova esse prefixo para não duplicar |
|
||||
## Passos 4–6 — Execução
|
||||
|
||||
**Montagem:**
|
||||
Idênticos a `agent-work-issue`:
|
||||
|
||||
- Com `id`: `#<N> <id> — <título>` — ex.: `#456 B79 — Mapa LQ na legenda`
|
||||
- Sem `id`: `#<N> — <título>` — ex.: `#789 — Hotfix cookie path`
|
||||
- Executar fases (schema/server → UI → gates)
|
||||
- `/simplify` completo + fixes
|
||||
- `capture-review-debts` **com** gate humano (Passo 5 daquela skill) — não use o modo autônomo do pool
|
||||
- `pnpm push` → PR Ready `--base main` + `Closes #N` → auto-merge → `gh pr checks --watch --required`
|
||||
|
||||
**Truncagem:** limite da ferramenta = 200 caracteres. Preserve intactos `#<N>` e `<id>`; encurte só o `<título>` no final (reticências opcionais).
|
||||
Detalhes, Prep Cloud, invariantes e templates: leia [`agent-work-issue/SKILL.md`](../agent-work-issue/SKILL.md) e os arquivos em `.cursor/skills/work-issue/` (`engineering-brief.md`, `implementation-template.md`, `decision-quality.md`).
|
||||
|
||||
**Passos:**
|
||||
## Resumo final
|
||||
|
||||
1. Monte o título pelo padrão acima a partir do stdout do claim.
|
||||
2. Chame `cursor-app-control` → `rename_chat` com `title`.
|
||||
3. Se `rename_chat` não estiver disponível (fora da Agents Window), informe em uma linha o título exato sugerido para o humano renomear manualmente — mas tente o MCP primeiro.
|
||||
|
||||
Se a sessão continuar uma Issue já claimada (sem re-rodar claim), derive os mesmos campos do brief anterior na conversa ou de `gh issue view <N> --json number,title` + frontmatter `id:`.
|
||||
|
||||
### Abrir o plano para o humano
|
||||
|
||||
Em seguida, **abra o arquivo do plano no editor** para quem acompanha a sessão — não basta `Read` no chat.
|
||||
|
||||
1. Extraia o caminho do plano do brief (`docs/plans/<slug>.md`) ou do link `Plano:` no body da Issue.
|
||||
2. Chame `cursor-app-control` → `open_resource` com URI absoluta, ex.: `file:///…/docs/plans/foo.md` (caminho relativo resolvido a partir da raiz do workspace).
|
||||
3. Informe em uma linha qual plano foi aberto (`B79 — docs/plans/…`).
|
||||
|
||||
Se `open_resource` não estiver disponível (fora da Agents Window), diga o caminho absoluto do plano para o humano abrir manualmente — mas tente o MCP primeiro.
|
||||
|
||||
## Passo 2 — Verificação de modelo (best effort, não programática)
|
||||
|
||||
Leia a propriedade `model:` do brief e compare com o modelo da sessão atual pela tabela de capacidade de `model-selection` (Composer 2.5 ↔ Grok 4.5 ↔ Kimi K3 Low). Regra **assimétrica** (decisão travada 2026-07-30):
|
||||
|
||||
- Sessão **mais fraca** que o especificado → assume-se escolha consciente do humano: **informa em uma linha e continua, sem pausar**.
|
||||
- Sessão **mais forte** que o especificado → possível erro do humano: **informa e pausa** ("a Issue pede X, você está em Y — seguir mesmo assim?").
|
||||
- Propriedade **ausente** → aplique `model-selection` uma vez e registre a escolha na Issue (`gh issue edit <N>` no body, frontmatter `model:`).
|
||||
- Issue `{id}-exec` / `kimi-k3-low` sem a dep de plan `done` → **pare** (não execute sem plano fechado).
|
||||
|
||||
Subagentes despachados via `Task` saem **no modelo da propriedade** quando couber (`Task.model` ∈ `composer-2.5` | `cursor-grok-4.5-high` | `kimi-k3-low`; se a Issue for `-low`/`-medium` e o enum não listar, `inherit` — ver model-selection).
|
||||
|
||||
## Passo 3 — Freshness audit (enxuto)
|
||||
|
||||
O plano foi escrito no passado e o repositório andou. Cheque, afirmação por afirmação:
|
||||
|
||||
- Arquivos citados no plano existem? Utilities "a reusar" têm a assinatura que o plano assume?
|
||||
- Premissas de schema batem com `src/payload-types.ts` e `src/migrations/`?
|
||||
- Deps do frontmatter estão `done`/`in-prod` (ou fechadas)? Dependência dura não entregue → pare e proponha (fazer a dep primeiro ou corte explícito).
|
||||
- Questões em aberto já respondidas pelo código/notebook?
|
||||
|
||||
Desfechos: **divergência factual** (caminho renomeado, assinatura) → corrija o plano na mesma sessão e siga; **divergência material de produto** → pare e pergunte. Não reescreva o plano inteiro: freshness audit é enxuto, não uma re-planificação.
|
||||
|
||||
## Passo 4 — Executar as fases
|
||||
|
||||
Ordem fixa, fases pequenas e verificáveis, respeitando o appetite do plano:
|
||||
|
||||
1. **Schema e server** — migrations (`pnpm migrate:create`, seguir `payload-migrations`), collections, utilities, server actions, testes de domínio. Guardrails do repo: Local API com `user` → `overrideAccess: false`; escrita multi-collection → transação com `req: { transactionID }`; pessoa → join com `Contact`; opt-in/PII → `Consent` por chave estável falhando fechado.
|
||||
2. **UI via /impeccable** (classes B/C/D — a classe está no plano; se A, declare "Impeccable: N/A" e siga só engenharia): shape conforme a classe → craft → critique → (harden/optimize **só sob gatilho**) → polish. Paleta = tokens `data-theme='campaign'`; reusar `src/components/ui` e shells existentes; shape obrigatório em C **para** para confirmação do brief antes do craft.
|
||||
3. **Gates de engenharia** — iteração: `pnpm gate:fast`. Push: **`pnpm push -u origin HEAD`** (ensure-deps + `gate:push` no script — não depende do hook Husky). `pnpm gate:push` manual só para debug sem push. Scan Aikido dos arquivos editados. Comandos bare, nunca piped. **Nunca** `git push --no-verify` cru (pula o gate) — em Cloud não há Docker, mas `gate:fast`/`gate:push` não precisam de banco (ver §Prep Cloud).
|
||||
|
||||
Tracer bullet: se a Issue for grande, a primeira fatia vertical real (schema mínimo → uma action → uma superfície UI) vem cedo.
|
||||
|
||||
## Passo 5 — /simplify + débitos
|
||||
|
||||
Rode `/simplify` sobre o diff da sessão **antes** do Passo 6. Não pule os reviewers — o simplify deste fluxo é o comando completo, não uma leitura manual do diff.
|
||||
|
||||
### Escopo
|
||||
|
||||
1. `git diff --no-color` + `git diff --cached --no-color` (diff combinado da sessão).
|
||||
2. Se vazio, arquivos/símbolos citados na conversa; se ainda vazio, `git show --stat --patch --no-color HEAD`.
|
||||
|
||||
### Reviewers paralelos (obrigatório)
|
||||
|
||||
Lance **três** subagentes via `Task` **em paralelo** na mesma mensagem — read-only, mesmo modelo da sessão, **sem editar arquivos**. Passe o diff combinado (ou lista de arquivos + hunks relevantes se o diff for grande):
|
||||
|
||||
1. **Code quality** — comentários vazios, helpers de uso único, nullable desnecessário, try/catch amplos, abstração prematura, casts fracos, estado derivado duplicado, código morto.
|
||||
2. **Performance** — I/O bloqueante em hot path, recomputação sem cache, busy-wait, concatenação em loop, N+1, logging em loop.
|
||||
3. **Reuse** — padrões/helpers existentes no repo ou já presentes no diff que o escopo deveria reutilizar.
|
||||
|
||||
### Fixes + débitos
|
||||
|
||||
1. Agregue os achados dos três reviewers e aplique **fixes pontuais** no diff (comportamento preservado).
|
||||
2. Achados maiores que o cleanup da sessão → skill `capture-review-debts` (registra via `agent:register`/`agent:file-miss`; **nunca** edita Issue `in-progress` — nem esta; débito do mesmo pai vira Issue nova com `depends: [<id-do-pai>]`).
|
||||
3. Resuma o que corrigiu e o que ficou como recomendação/débito.
|
||||
|
||||
## Passo 6 — Fechar em main
|
||||
|
||||
1. Branch `agent/<id>-<slug>` (worktrees do Cursor são donos da criação; commits lógicos).
|
||||
2. **`pnpm push -u origin HEAD`** — canonical; roda `ensure-repo-deps` + `gate:push` + push (não depende do Husky). Não use `git push` nu.
|
||||
3. Abrir PR **Ready** (nunca draft) com `Closes #<N>` — `.cursor/rules/agent-pr-workflow.mdc` (alwaysApply). Canal: `gh pr create --base main` **ou**, em Cloud, `ManagePullRequest` com **`draft: false`**.
|
||||
4. `gh pr merge --auto --merge <PR>` **imediatamente** após o PR existir Ready (`strict=false` na proteção de `main`). Não encerre o turn com PR Draft ou sem auto-merge armado.
|
||||
5. **Acompanhe só os checks obrigatórios** (`gh pr checks <PR> --watch --required`): gate = `checks` + `migration-lock`; Vercel Git não bloqueia. Falha no ci-pr → corrige na mesma branch. **Conflito de merge** → rebase em `main` e reempurre.
|
||||
6. O flip `in-progress → done` + `in-prod` é **determinístico no CI** (`issue-done-on-main-merge.yml`). Deploy gated fica em `ci.yml` — não é passo do agente. Consolide pontas soltas após o merge.
|
||||
|
||||
## Resumo final ao usuário
|
||||
|
||||
Issue trabalhada + sessão renomeada + plano aberto no editor + verificação de modelo (declarado vs sessão, ou registro do ausente), veredito do freshness audit, o que entrou por fase, resultado do critique/polish (se UI), simplify (3 reviewers paralelos) + débitos registrados, gates (`pnpm push`, sem `--no-verify` cru), link do PR e estado do merge em main, pontas soltas consolidadas. `done`+`in-prod` no merge; deploy gated em `ci.yml`.
|
||||
Issue claimada · sessão renomeada · intenção aberta · modelo · **impl plan confirmado pelo humano** · execução · simplify/débitos · PR + merge.
|
||||
|
|
|
|||
51
.cursor/skills/work-issue/decision-quality.md
Normal file
51
.cursor/skills/work-issue/decision-quality.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Qualidade de decisão (plano de implementação)
|
||||
|
||||
Aplique ao escrever `docs/plans/<slug>-impl.md` em `work-issue` / `agent-work-issue`. O plano de **intenção** já fixou o outcome — aqui se escolhe a engenharia. Decisão silenciosa é defeito.
|
||||
|
||||
## Caro vs barato
|
||||
|
||||
Delibere e registre só o **caro de reverter**. O barato vira Não escopo, fill-in, ou “mais simples que funciona” com **gatilho de revisitação**.
|
||||
|
||||
| Caro (decidir agora + rejeitadas) | Barato (adiar / mais simples) |
|
||||
| --------------------------------- | ----------------------------- |
|
||||
| Collection nova, unicidade, access | Polish cosmético, 2º estilo de card |
|
||||
| Nova chave `Consent` / PII | Copy, motion, a11y P3 |
|
||||
| Semântica multi-collection / locks | Prefetch, ordem de colunas |
|
||||
| URL pública / slug imutável | Rename de pureza |
|
||||
| Fronteira de módulo em volatilidade real | Adapter com 1 call site |
|
||||
|
||||
## Forma obrigatória
|
||||
|
||||
Toda decisão não trivial de engenharia:
|
||||
|
||||
```text
|
||||
Opções: A | B | C
|
||||
Recomendação: B — porque …
|
||||
Alternativas rejeitadas: A porque …; C porque …
|
||||
```
|
||||
|
||||
No `*-impl.md`: **Decisões de engenharia** = decisão + por quê + rejeitadas.
|
||||
|
||||
## Appetite e tracer bullet
|
||||
|
||||
Respeite o appetite do plano de intenção. Se a abordagem estoura → cortar rabbit holes, não inflar. Preferir **tracer bullet** cedo (schema mínimo → uma action → uma superfície) antes de polish paralelo.
|
||||
|
||||
## Depth check
|
||||
|
||||
Antes de propor arquivo/utility/componente novo:
|
||||
|
||||
1. Já existe módulo profundo? (`campaignAccess`, shells de lista, `withPayloadTransaction`, …) → **reusar**
|
||||
2. Pass-through raso? → **não criar**
|
||||
3. Conhecimento vazaria em N módulos? → **encapsular uma vez**
|
||||
|
||||
## Rabbit holes Teqo
|
||||
|
||||
Layers/cerimônia sem volatilidade; cadastro paralelo a `Contact`; Consent por ID hardcoded; DRY <3 call sites; redesign de paleta fora de `campaign`.
|
||||
|
||||
## Self-score (0–5, gate ≥4)
|
||||
|
||||
1. Decisões caras têm rejeitadas?
|
||||
2. Abordagem cabe no appetite da intenção?
|
||||
3. Rabbit holes nomeados?
|
||||
4. Depth check: reusa shells/helpers existentes?
|
||||
5. Intenção (aceite de produto) permanece satisfeita — engenharia não reescreveu o outcome?
|
||||
36
.cursor/skills/work-issue/engineering-brief.md
Normal file
36
.cursor/skills/work-issue/engineering-brief.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Brief de engenharia (carregar antes do plano de implementação)
|
||||
|
||||
Leia o que for relevante **antes** de travar a abordagem no `*-impl.md`. Não invoque jornadas inteiras de skills — aplique o princípio no momento da decisão.
|
||||
|
||||
## Pinos do repo (sempre)
|
||||
|
||||
- `.cursor/rules/codebase-map.mdc` — direção `lib/` → `utilities/` → `components/` → `app/`; dono da feature
|
||||
- `.cursor/rules/engineering-standards.mdc` — gates, type honesty, client boundary, caching ladder, access
|
||||
- `.cursor/rules/security-critical.mdc` — quando tocar access/Local API/overrideAccess
|
||||
- `AGENTS.md` — auth campanha, Consent fail-closed, transactions, naming, DB local
|
||||
- `docs/ARCHITECTURE.md` — se a mudança cruza verticais ou modelo de domínio
|
||||
|
||||
## Skills sob demanda (não tour)
|
||||
|
||||
| Situação | Skill / princípio |
|
||||
| -------- | ----------------- |
|
||||
| Onde colocar lógica / dependência | `clean-architecture` — Dependency Rule; core testável |
|
||||
| Complexidade de módulo / API | `software-design-philosophy` — deep modules, anti-classitis |
|
||||
| Escopo v1 / cortar especulação | `37signals-way` / `pragmatic-programmer` — build less, tracer bullet, DRY de conhecimento |
|
||||
| Schema Payload | skill `payload-migrations` |
|
||||
| DB local / Cloud sem Docker | skill `local-database` |
|
||||
| KPI/mapa/série na UI | [data-presentation.md](../plan-issue/data-presentation.md) pergunta 3 no impl |
|
||||
| Domínio `/campanha` específico | rules `projects/*` se o item tocar aquele projeto |
|
||||
|
||||
## Invariantes que o impl plan não pode violar
|
||||
|
||||
- Local API com `user` → `overrideAccess: false`
|
||||
- Escrita multi-collection → transação + `req: { transactionID }`
|
||||
- Pessoa → join com `Contact` (não collection paralela)
|
||||
- Opt-in/PII → `Consent` por chave estável, fail-closed
|
||||
- `leader` lockdown; sem `estimatedVotes` para liderança
|
||||
- Copy pt-BR / identificadores em inglês
|
||||
|
||||
## Sistema de listas
|
||||
|
||||
Se a superfície for lista/tabela: reusar shells (`CampaignTable`, URL canônica, column visibility, pending boundary) — ver codebase-map. Não reinventar.
|
||||
65
.cursor/skills/work-issue/implementation-template.md
Normal file
65
.cursor/skills/work-issue/implementation-template.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Template de plano de implementação (`docs/plans/<slug>-impl.md`)
|
||||
|
||||
Criado em Plan mode por `work-issue` / `agent-work-issue` a partir do plano de **intenção**. Aqui a engenharia é deliberada — Opções + Recomendação + rejeitadas ([decision-quality.md](decision-quality.md)).
|
||||
|
||||
O outcome de produto do plano de intenção é **inviolável**. A forma técnica é **livre** desde que mantenha aceite, appetite e invariantes do repo ([engineering-brief.md](engineering-brief.md)).
|
||||
|
||||
````markdown
|
||||
# Impl: <mesmo título da intenção>
|
||||
|
||||
Status: rascunho | aprovado | em execução
|
||||
Atualizado em: <YYYY-MM-DD>
|
||||
Issue: #<N>
|
||||
Intenção: docs/plans/<slug>.md
|
||||
Appetite restante: <herdado / ajustado com corte explícito>
|
||||
|
||||
## Leitura da intenção
|
||||
|
||||
- **Outcome:** <1–2 frases, nas palavras do aceite de produto>
|
||||
- **O que NÃO negociar:** <lockdowns de produto / access / LGPD citados na intenção>
|
||||
- **O que reavaliar:** <hipóteses de “Direção no codebase” que podem estar erradas>
|
||||
|
||||
## Abordagem recomendada
|
||||
|
||||
\```mermaid
|
||||
flowchart LR
|
||||
…
|
||||
\```
|
||||
|
||||
**Opções consideradas:** A | B | C
|
||||
**Recomendação:** <…> — porque …
|
||||
**Rejeitadas:** …
|
||||
|
||||
### Componentes / mudanças
|
||||
|
||||
- **`<símbolo>`** (`src/…`): <responsabilidade; o que reusa>
|
||||
- **Migration:** <nome sugerido / “sem migration”>
|
||||
- **Access / Consent:** <helpers; chave se houver; fail-closed>
|
||||
- **UI:** <Impeccable A–D; shells a reusar; shape→craft→critique→polish se B/C/D>
|
||||
|
||||
### Dados → forma (se aplicável)
|
||||
|
||||
- Forma escolhida + por quê + rejeitadas (pergunta 3 de data-presentation)
|
||||
|
||||
## Fases verificáveis
|
||||
|
||||
1. **Tracer / schema+server** — <quota do appetite>
|
||||
2. **UI** — <…>
|
||||
3. **Gates** — `pnpm gate:fast`; push via `pnpm push`
|
||||
|
||||
## Rabbit holes / Não escopo (engenharia)
|
||||
|
||||
- …
|
||||
|
||||
## Riscos e mitigação
|
||||
|
||||
- …
|
||||
|
||||
## Aceite de engenharia
|
||||
|
||||
- [ ] Aceite de produto da intenção ainda coberto
|
||||
- [ ] Invariantes AGENTS/engineering-standards
|
||||
- [ ] Testes de domínio previstos (unit/int) onde access/write paths mudam
|
||||
````
|
||||
|
||||
Self-score decision-quality ≥4 antes de marcar `aprovado` ou executar.
|
||||
|
|
@ -18,7 +18,7 @@ claim → feature branch → PR --base main → CI PR green (cascade + skips)
|
|||
main → ci.yml full suite → vercel deploy --prod (se verde) → requeue se HEAD andou
|
||||
```
|
||||
|
||||
**Skills:** `plan-issue` → `work-issue` (claim → modelo → freshness → execução → /simplify → PR `--base main` → CI até o merge) → `project-status`. `docs/roadmap.md` = legado congelado; fonte canônica = GitHub Issues.
|
||||
**Skills:** `plan-issue` (intenção + Issues) → `work-issue` (humano: claim → impl plan → confirmação → execução) ou `agent-work-issue` (pool: já claimada → impl plan → execução sem pausa) → `/simplify` → `capture-review-debts` → PR `--base main` → `project-status`. `docs/roadmap.md` = legado congelado; fonte canônica = GitHub Issues.
|
||||
|
||||
- **Agente faz sozinho:** `pnpm agent:claim` → implementa → **`pnpm push`** → PR **Ready** (nunca draft) com `Closes #N` → `gh pr merge --auto --merge` → `gh pr checks --watch --required`. Regra always-on: `.cursor/rules/agent-pr-workflow.mdc`. Em Cursor Cloud: `ManagePullRequest` com `draft: false`, depois armar auto-merge via `gh pr merge --auto --merge` (o default draft da tool **não** vale neste repo).
|
||||
- **Só humano:** secrets Vercel (`VERCEL_TOKEN`, `VERCEL_ORG_ID`, `VERCEL_PROJECT_ID`), `POOL_GITHUB_TOKEN`, `pnpm configure:branch-protection`, editar envs Neon/Vercel.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente
|
|||
|
||||
---
|
||||
|
||||
**Recently resolved (2026-08-02):** **Skills plan/work reescritas** — `plan-issue` agora só gera planos de **intenção** (persona/fluxo/aceite + direção suave no código; sem decisões duras de engenharia). Execução: `agent-work-issue` (pool — Plan mode → `*-impl.md` → executa → `/simplify` → `capture-review-debts` autônomo → PR Ready + auto-merge) e `work-issue` (humano — claim + **pausa** após o impl plan). Prompt do pool aponta para `agent-work-issue`.
|
||||
|
||||
**Recently resolved (2026-08-02):** **WhatsApp interno D3–D5 descartado** — Issues #30–#32 `wontfix` (bridge Baileys/Evolution/WAHA / linked device): risco de ban do número pessoal do staff. Canal no produto = só `wa.me`. Planos `whatsapp-interno-campanha.md`, `whatsapp-canal-fundacao.md`, `whatsapp-envio-liderancas.md`, `whatsapp-sugestao-atualizacoes.md` removidos; refs em `notifications.md` / convite·email listas / fluxos-ação / regra `nucleos-eleitorais` atualizadas.
|
||||
|
||||
**Recently resolved (2026-08-02):** **Agent pool hard max → 12** — `POOL_HARD_MAX_SLOTS` de 8 → 12 (`scripts/lib/agent-pool-state.mjs`); default continua 5. Skill `agent-pool` alinhada.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* (docs/plans/agent-pool-orchestrator.md).
|
||||
*
|
||||
* The pool keeps up to POOL_MAX_SLOTS (default 5) Cursor Cloud Agents running
|
||||
* work-issue over `ready` autonomous-eligible issues. The supervisor is
|
||||
* agent-work-issue over `ready` autonomous-eligible issues. The supervisor is
|
||||
* REMOTE: a stateless GitHub Actions tick (`.github/workflows/agent-pool.yml`)
|
||||
* runs `workflow --action …` / `tick --live`; humans drive it via
|
||||
* `gh workflow run` (canonical channel). Local usage is inspection +
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
* (docs/plans/agent-pool-orchestrator.md §4/§5).
|
||||
*
|
||||
* The supervisor claims the issue BEFORE spawning (label flip + pool-worker
|
||||
* marker comment — the coordinated-claim anti-race), so the worker SKIPS the
|
||||
* claim step of work-issue and starts at step 1b. Everything else — gates, PR
|
||||
* base main with Closes #N, auto-merge + CI watch — is the standard skill
|
||||
* contract restated so the worker cannot miss it.
|
||||
* marker comment — the coordinated-claim anti-race), so the worker SKIPS
|
||||
* claim and runs `agent-work-issue` (autonomous: impl plan → execute →
|
||||
* simplify → capture-review-debts → PR). Human-supervised path is `work-issue`.
|
||||
*/
|
||||
|
||||
/** First docs/plans/*.md path in the issue body (the linked plan), if any. */
|
||||
|
|
@ -31,22 +30,24 @@ export const buildPoolWorkerPrompt = ({ issueNumber, issueTitle, issueId, planPa
|
|||
'',
|
||||
'## Fluxo',
|
||||
'',
|
||||
'Siga a skill `.cursor/skills/work-issue/SKILL.md` a partir do passo 1b, PULANDO o passo 1 (claim):',
|
||||
'Siga a skill `.cursor/skills/agent-work-issue/SKILL.md` por completo (Issue já claimada):',
|
||||
'1. Rode `pnpm i` se `node_modules` não existir.',
|
||||
planPath
|
||||
? `2. Plano: \`${planPath}\` — freshness audit enxuto (passo 3 da skill).`
|
||||
: '2. O body da Issue é a spec (não há plano linkado — avalie se ele basta para trabalhar).',
|
||||
'3. Execute as fases com os gates do repo: `pnpm gate:fast` antes do push (o pre-push roda `pnpm gate:push`). Comandos bare, nunca piped.',
|
||||
`4. PR obrigatoriamente com \`gh pr create --base main\` e "Closes #${issueNumber}" no body.`,
|
||||
'5. `gh pr merge --auto --merge <PR>` e acompanhe `gh pr checks <PR> --watch --required` até o merge. Falha de CI no seu PR é sua (docs/AGENT-OPS.md — "Dono do PR, dono do CI"): corrija na mesma branch.',
|
||||
? `2. Plano de intenção: \`${planPath}\` — abra-o; depois Plan mode e escreva \`docs/plans/<slug>-impl.md\` (engenharia deliberada; pode divergir da hipótese de direção se o aceite de produto se mantiver).`
|
||||
: '2. O body da Issue é a spec de intenção (não há plano linkado). Em Plan mode, escreva mesmo assim um `docs/plans/<id>-impl.md` a partir do body.',
|
||||
'3. Execute o impl plan. Gates: `pnpm gate:fast` na iteração; entrega com `pnpm push` (não `git push` nu). Comandos bare, nunca piped.',
|
||||
'4. Rode `/simplify` completo; `capture-review-debts` em modo autônomo (só expensive_lock ≥4).',
|
||||
`5. PR obrigatoriamente com \`gh pr create --base main\` e "Closes #${issueNumber}" no body (Ready, nunca draft).`,
|
||||
'6. `gh pr merge --auto --merge <PR>` e acompanhe `gh pr checks <PR> --watch --required` até o merge. Falha de CI no seu PR é sua (docs/AGENT-OPS.md — "Dono do PR, dono do CI"): corrija na mesma branch.',
|
||||
'',
|
||||
'## Proibido',
|
||||
'',
|
||||
'- `DATABASE_URL` de prod ou `ALLOW_REMOTE_DB` — o setup local (`.cursor/cloud-setup.sh` + seed mínimo) cobre tudo.',
|
||||
`- Editar outras Issues \`in-progress\` ou trabalhar fora da Issue #${issueNumber}.`,
|
||||
'- Tratar o plano de intenção como contrato de engenharia — ele é intenção; o `*-impl.md` é a engenharia.',
|
||||
'',
|
||||
modelSlug
|
||||
? `Modelo declarado da Issue: \`${modelSlug}\` — você foi spawnado nele (ou no fallback documentado pelo pool); a verificação assimétrica do passo 2 não se aplica.`
|
||||
? `Modelo declarado da Issue: \`${modelSlug}\` — você foi spawnado nele (ou no fallback documentado pelo pool); a verificação assimétrica de work-issue não se aplica.`
|
||||
: 'A Issue não declara `model:` — você foi spawnado no default do pool (composer-2.5).',
|
||||
'',
|
||||
`Ao terminar — merge concluído ou falha terminal — comente na Issue #${issueNumber} o desfecho em uma linha e encerre.`,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ describe('buildPoolWorkerPrompt', () => {
|
|||
expect(prompt).toContain('in-progress')
|
||||
})
|
||||
|
||||
it('points workers at agent-work-issue and forbids treating intention as engineering contract', () => {
|
||||
expect(prompt).toContain('agent-work-issue/SKILL.md')
|
||||
expect(prompt).toContain('*-impl.md')
|
||||
expect(prompt).toContain('plano de intenção como contrato de engenharia')
|
||||
})
|
||||
|
||||
it('pins the PR contract: base main, Closes #N, auto-merge, CI watch', () => {
|
||||
expect(prompt).toContain('gh pr create --base main')
|
||||
expect(prompt).toContain('Closes #42')
|
||||
|
|
|
|||
Loading…
Reference in a new issue