* feat(ops): auto-promote stage→main e merge em stage sem exigir head Substitui o promote manual por workflow disparado no ci-stage green, relaxa strict na proteção de stage (script configure:branch-protection) e documenta o novo paradigma em AGENT-OPS e work-issue. * style: format AGENT-OPS and configure-branch-protection for ci-pr * feat(ops): pnpm push com ensure-repo-deps determinístico Bootstrap install + Husky antes de todo push (pnpm push e pre-push). Documenta fluxo canônico em work-issue, agent-pr-workflow e AGENT-OPS. * fix(ops): pnpm push roda gate no script, sem depender do Husky Cloud environment.json chama prepare explicitamente após install. * test(int): isolate advisor portfolio search from shared cairu slug Parallel int specs were stomping municipality.advisors on the fixed cairu row; allocate per-test municipalities instead.
12 KiB
| name | description |
|---|---|
| work-issue | Conduz uma GitHub Issue rastreável do Teqo do claim ao merge em stage — 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 stage com Closes |
Trabalhar uma Issue (claim → merge em stage)
Esta skill conduz UMA Issue rastreável do claim ao merge em stage. 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).
Proibido neste fluxo: qualquer acesso a DB de stage/prod, merge sem CI green, editar outras Issues in-progress. pnpm agent:promote é só override manual — o promote normal é automático após CI stage green.
Qualidade de decisão e dados: aplique 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 ao auditar/fatiar superfícies com KPI/mapa/série/ranking.
Checklist do fluxo
- [ ] 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`)
- [ ] 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>`
- [ ] 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 stage: branch → commit → **`pnpm push -u origin HEAD`** (não `git push` nu) → gh pr create --base stage (Closes #N, sem --draft)
→ gh pr merge --auto --merge → gh pr checks --watch --required até o merge → consolidar pontas soltas
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:
pnpm i
Não pule este passo — sem deps instaladas o claim falha antes de imprimir o brief.
Passo 1 — Claim
pnpm agent:claim # pega o topo da fila (ready, desbloqueadas, por prio)
pnpm agent:claim -- --issue <N> # quando o usuário especifica
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.
Renomear a sessão
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.
Padrão canônico (decisão travada — use sempre este formato, sem variações):
| 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 |
Montagem:
- Com
id:#<N> <id> — <título>— ex.:#456 B79 — Mapa LQ na legenda - Sem
id:#<N> — <título>— ex.:#789 — Hotfix cookie path
Truncagem: limite da ferramenta = 200 caracteres. Preserve intactos #<N> e <id>; encurte só o <título> no final (reticências opcionais).
Passos:
- Monte o título pelo padrão acima a partir do stdout do claim.
- Chame
cursor-app-control→rename_chatcomtitle. - Se
rename_chatnã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.
- Extraia o caminho do plano do brief (
docs/plans/<slug>.md) ou do linkPlano:no body da Issue. - Chame
cursor-app-control→open_resourcecom URI absoluta, ex.:file:///…/docs/plans/foo.md(caminho relativo resolvido a partir da raiz do workspace). - 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. 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-selectionuma vez e registre a escolha na Issue (gh issue edit <N>no body, frontmattermodel:).
Subagentes despachados via Task saem no modelo da propriedade quando couber (Task.model).
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.tsesrc/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:
- Schema e server — migrations (
pnpm migrate:create, seguirpayload-migrations), collections, utilities, server actions, testes de domínio. Guardrails do repo: Local API comuser→overrideAccess: false; escrita multi-collection → transação comreq: { transactionID }; pessoa → join comContact; opt-in/PII →Consentpor chave estável falhando fechado. - 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'; reusarsrc/components/uie shells existentes; shape obrigatório em C para para confirmação do brief antes do craft. - Gates de engenharia — iteração:
pnpm gate:fast. Push:pnpm push(ensure-deps +gate:pushno script — não depende do hook Husky).pnpm gate:pushmanual só para debug sem push. Scan Aikido dos arquivos editados. Comandos bare, nunca piped. Escape WIP:git push --no-verifysem passar porpnpm push.
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
git diff --no-color+git diff --cached --no-color(diff combinado da sessão).- 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):
- 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.
- Performance — I/O bloqueante em hot path, recomputação sem cache, busy-wait, concatenação em loop, N+1, logging em loop.
- Reuse — padrões/helpers existentes no repo ou já presentes no diff que o escopo deveria reutilizar.
Fixes + débitos
- Agregue os achados dos três reviewers e aplique fixes pontuais no diff (comportamento preservado).
- Achados maiores que o cleanup da sessão → skill
capture-review-debts(registra viaagent:register/agent:file-miss; nunca edita Issuein-progress— nem esta; débito do mesmo pai vira Issue nova comdepends: [<id-do-pai>]). - Resuma o que corrigiu e o que ficou como recomendação/débito.
Passo 6 — Fechar em stage
- Branch
agent/<id>-<slug>(worktrees do Cursor são donos da criação; commits lógicos). pnpm push -u origin HEAD— canonical; rodaensure-repo-deps+gate:push+ push (não depende do Husky). Não usegit pushnu.gh pr create --base stagecomCloses #<N>no body — nunca--draft(.cursor/rules/agent-pr-workflow.mdc).gh pr merge --auto --merge <PR>imediatamente após criar o PR (não precisa rebasear na head destagese não houver conflito —strict=falsena proteção destage).- Acompanhe só os checks obrigatórios (
gh pr checks <PR> --watch --required): gate =checks+migration-lock; Vercel não bloqueia. Falha no ci-pr → corrige na mesma branch. Conflito de merge → rebase emstagee reempurre; não force-push salvo para destravar CI após rebase. - O flip
in-progress → doneé determinístico no CI (workflowissue-done-on-stage-merge.ymllê oCloses #Nno merge em stage). O agente espera o merge apenas para verificar e consolidar pontas soltas: débitos não registrados, doc da sessão pendente (notebook do projeto +docs/plans/<slug>.mdcom Status/Atualizado em), comentário de fechamento na Issue com o que entrou. Se o agente falhar depois do merge, o status já está correto.
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, link do PR e estado do merge em stage, pontas soltas consolidadas. in-prod entra no auto-promote (promote-stage-to-main.yml) após CI stage green — não é passo do agente.