diff --git a/.cursor/skills/capture-review-debts/SKILL.md b/.cursor/skills/capture-review-debts/SKILL.md index 33978cc0..a11c31dc 100644 --- a/.cursor/skills/capture-review-debts/SKILL.md +++ b/.cursor/skills/capture-review-debts/SKILL.md @@ -143,6 +143,8 @@ Para cada lote com destino **registrar** ou **absorver**: Não implemente as fases aqui. Apontar `implement-roadmap-item` só se o usuário pedir em seguida. +**Próximo no fluxo de entrega:** após a triage confirmada (ou no-op sem débitos), o passo natural é `ship-to-main` (commit all → push → merge main → apagar worktree). Para fechar rebase + debts + ship numa tacada (com auto-confirm desta triage), use `close-delivery`. + ## Anti-padrões (baseline) | Desculpa | Realidade | diff --git a/.cursor/skills/close-delivery/SKILL.md b/.cursor/skills/close-delivery/SKILL.md new file mode 100644 index 00000000..33f64eee --- /dev/null +++ b/.cursor/skills/close-delivery/SKILL.md @@ -0,0 +1,90 @@ +--- +name: close-delivery +description: >- + Runs the full post-simplify delivery closeout in one flow: rebase-on-main, + capture-review-debts (auto-confirm triage recommendations), then ship-to-main + (commit, push, merge to main, delete session worktree). Use after /simplify + and /impeccable when the user says "close delivery", "fecha a entrega", + "rebase + debts + ship", "fecha o ciclo", or wants the three closeout steps + without pausing for debt-triage confirmation. +--- + +# Close delivery + +Orquestra o fechamento da entrega em worktree numa única invocação: + +1. **`rebase-on-main`** — sync com `origin/main` + conflitos +2. **`capture-review-debts`** — triage de débitos **com auto-confirmação** da recomendação +3. **`ship-to-main`** — commit all → push → merge main → apagar worktree + +**Announce at start:** "Using close-delivery: rebase → capture debts (auto-confirm) → ship." + +**REQUIRED SUB-SKILLS:** Leia e execute integralmente, nesta ordem: + +- `.cursor/skills/rebase-on-main/SKILL.md` +- `.cursor/skills/capture-review-debts/SKILL.md` (com override abaixo) +- `.cursor/skills/ship-to-main/SKILL.md` + +Não reimplemente a lógica delas aqui — só orquestre + aplique o override de confirmação. + +## Checklist + +``` +- [ ] 1. rebase-on-main (completo; pare se abortar/perguntar) +- [ ] 2. capture-review-debts com auto-confirm (override do Passo 5) +- [ ] 3. ship-to-main (completo) +- [ ] 4. Resumo unificado do ciclo +``` + +## Override: auto-confirm em `capture-review-debts` + +A skill filha exige **Pare e confirme** no Passo 5 antes de editar docs. **Neste fluxo, esse gate está dispensado.** + +Comportamento: + +1. Execute Passos 1–4 de `capture-review-debts` normalmente (colher, deduplicar, pontuar, mesclar). +2. Mostre a tabela de triage no resumo (transparência). +3. **Trate a recomendação da tabela como aprovada** e avance ao Passo 6 sem esperar o usuário. +4. Se não houver candidatos / só `já_resolvido`+`descartar`+`defer` sem registro: no-op de docs; siga para `ship-to-main`. +5. `defer` continua sem criar ID; anote gatilho no plano-pai se a skill filha mandar. + +**Ainda pare e pergunte** (não auto-confirm) se: + +- A triage ficar ambígua entre dois destinos sem regra clara na skill filha +- Um candidato `expensive_lock` (access/LGPD/schema/unicidade) não tiver destino seguro sem decisão de produto +- `roadmap-item` falharia por falta de dado que só o usuário pode dar + +Nesses casos: reporte o bloqueio, **não** rode `ship-to-main` ainda (working tree pode ter só o rebase). + +## Regras de orquestração + +| Situação | Ação | +| ------------------------------------ | ------------------------------------------------------------------------- | +| Rebase no-op (já sync) | Siga para debts | +| Rebase com conflitos resolvidos | Siga para debts | +| Rebase abortado / precisa decisão | **Pare** — não debts, não ship | +| Debts auto-confirm OK (ou no-op) | Siga para ship | +| Debts bloqueado (lock / ambiguidade) | **Pare** — não ship | +| Ship: feature atrás de main | Não deve ocorrer se Passo 1 OK; se ocorrer, re-rode rebase antes de merge | +| Ship: branch é `main` | Pare (guard da filha) | + +Commit das mudanças de roadmap/planos feitas no Passo 2 entra no **mesmo** `ship-to-main` (Passo 2 da filha — commit all). + +## Resumo unificado (final) + +Um bloco só, curto: + +1. **Rebase:** no-op / N commits / conflitos (paths) / abort +2. **Debts:** contagem (colhidos / registrados / absorvidos / defer / descartados) + IDs/slugs se houver + nota “auto-confirm” +3. **Ship:** SHA de main, branch/worktree removidos, aviso Cursor se path morto +4. **Próximo:** `suggest-next-roadmap-items` + +## Posição no fluxo + +``` +suggest-next → implement-roadmap-item → /simplify+/impeccable + → close-delivery + (= rebase-on-main → capture-review-debts[auto] → ship-to-main) +``` + +As três skills filhas continuam invocáveis à parte quando o usuário quiser pausar entre etapas. diff --git a/.cursor/skills/compile-roadmap/SKILL.md b/.cursor/skills/compile-roadmap/SKILL.md index a55a6adb..ab5323fb 100644 --- a/.cursor/skills/compile-roadmap/SKILL.md +++ b/.cursor/skills/compile-roadmap/SKILL.md @@ -24,7 +24,10 @@ Esta skill **reescreve** `docs/roadmap.md` para voltar a ser um documento de **p | `suggest-next-roadmap-items` | Escolher candidatos entre o que o roadmap já lista | | `roadmap-item` | Registrar ideia nova / criar plano | | `implement-roadmap-item` | Auditar plano + implementar o ID escolhido | +| `rebase-on-main` | Após simplify: fetch + rebase em main + conflitos | | `capture-review-debts` | Triagear débitos de `/simplify` / critique | +| `ship-to-main` | Commit + push + merge main + apagar worktree | +| `close-delivery` | Orquestra rebase + debts (auto-confirm) + ship | **Escopo padrão:** só `docs/roadmap.md`. Planos em `docs/plans/` **não** são movidos nem apagados. Só atualize/arquive planos se o usuário pedir explicitamente. diff --git a/.cursor/skills/implement-roadmap-item/SKILL.md b/.cursor/skills/implement-roadmap-item/SKILL.md index c94bd541..5673d71c 100644 --- a/.cursor/skills/implement-roadmap-item/SKILL.md +++ b/.cursor/skills/implement-roadmap-item/SKILL.md @@ -247,3 +247,5 @@ Não declare a implementação completa sem 10d. **Após implementação (Passo 10):** o que entrou em cada fase, resultado do critique/polish (score/P0–P1 se houver), checklist AGENTS.md + Aikido, superfícies de doc atualizadas no 10d, e o que ficou de fora. Se `/simplify` ou `/impeccable critique` deixaram follow-ups **maiores que o cleanup da sessão**, ofereça a skill `capture-review-debts` (triage → confirmação → `roadmap-item`) em vez de registrar débitos ad hoc ou abandoná-los no chat. + +**Fluxo de fechamento em worktree:** após simplify/impeccable → `rebase-on-main` → `capture-review-debts` → `ship-to-main` (atalho único: `close-delivery`). diff --git a/.cursor/skills/rebase-on-main/SKILL.md b/.cursor/skills/rebase-on-main/SKILL.md new file mode 100644 index 00000000..0e5bc7ac --- /dev/null +++ b/.cursor/skills/rebase-on-main/SKILL.md @@ -0,0 +1,147 @@ +--- +name: rebase-on-main +description: >- + Sync the current feature branch with latest origin/main via fetch + rebase, + then resolve conflicts intelligently. Use after /simplify & /impeccable and + before capture-review-debts when the user says "pull main, rebase on main, + resolve conflicts", "rebase on main", "atualiza com main", "sincroniza com + main", or asks to bring the worktree branch up to date with main. +--- + +# Rebase on main + +Etapa do fluxo de entrega Teqo (worktree) **depois** de `/simplify` + `/impeccable` e **antes** de `capture-review-debts`: trazer `origin/main` e rebasear a branch da sessão, resolvendo conflitos com critério. + +**Inspiração:** `superpowers:using-git-worktrees` (detecção de worktree), `babysit` (resolver conflitos preservando intent), regras de git do usuário (sem force-push, sem `--no-verify`). + +**Announce at start:** "Using rebase-on-main to sync this branch with main." + +## Checklist + +``` +- [ ] 1. Detectar ambiente (branch, worktree, dirty tree) +- [ ] 2. Fetch origin/main +- [ ] 3. Rebase da branch atual em cima de origin/main +- [ ] 4. Resolver conflitos (ou abortar e perguntar se intents colidem) +- [ ] 5. Verificar resultado e reportar +``` + +## Passo 1 — Detectar ambiente + +Rode em paralelo: + +```bash +git status -sb +git branch --show-current +git rev-parse --show-toplevel +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +git log --oneline -5 HEAD +git log --oneline -3 origin/main 2>/dev/null || true +``` + +**Guards (pare e explique se verdadeiros):** + +| Condição | Ação | +| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Branch é `main` / `master` | Não rebasear main em si. Pare. | +| Detached HEAD | Pare; peça branch nomeada ou checkout. | +| Working tree dirty (uncommitted) | Stash **só** se o usuário autorizar; preferência: commit primeiro via `ship-to-main` parcial, ou stash com mensagem `rebase-on-main:`. Sem dirty tree limpa → não invente stash. | +| Rebase / merge / cherry-pick já em andamento | Continue ou `git rebase --abort` **só** com confirmação explícita. | + +Se `GIT_DIR != GIT_COMMON` (e não é submodule): está em worktree — OK; rebase acontece **aqui**, na feature branch. + +## Passo 2 — Fetch + +```bash +git fetch origin main +``` + +Se `origin/main` não existir, tente `master`. Confirme o tip: + +```bash +git rev-parse origin/main +git merge-base HEAD origin/main +git log --oneline --left-right HEAD...origin/main | head -40 +``` + +Se já está up-to-date (`HEAD` contém `origin/main` e não há commits de main à frente): reporte "já sincronizado" e pare (sucesso no-op). + +## Passo 3 — Rebase + +```bash +git rebase origin/main +``` + +**Não** use `git pull --rebase` no main checkout para “atualizar a feature” — o rebase é da **feature atual** sobre `origin/main`. + +**Não** force-push aqui. Se a branch já tinha sido pushed e o rebase reescreveu commits, o push (com `--force-with-lease` se necessário) fica para `ship-to-main` ou pedido explícito do usuário. + +## Passo 4 — Resolver conflitos + +Quando o rebase parar com conflitos: + +1. Liste arquivos: `git status` / `git diff --name-only --diff-filter=U` +2. Para **cada** arquivo, leia ambos os lados e o contexto do projeto antes de editar. +3. **Gotcha do rebase:** durante `git rebase`, `ours` = branch base (`origin/main`) e `theirs` = o commit que está sendo reaplicado (sua feature). Não inverta mentalmente com merge. +4. Preserve **intent e correção** dos dois lados. Se os intents forem incompatíveis (ex.: main removeu a API que a feature estende), **`git rebase --abort`**, explique o conflito de produto, e pergunte — não “ganhe” um lado no escuro. +5. Após editar: `git add ` → `git rebase --continue` (editor: `GIT_EDITOR=true` ou `-c core.editor=true` se precisar não abrir editor interativo para a mensagem do commit). +6. Repita até o rebase terminar ou abortar com pergunta. + +### Heurísticas Teqo (quando o arquivo conflitar) + +| Superfície | Como resolver | +| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `src/migrations/index.ts` | Unir **ambos** os exports/imports na ordem cronológica; nunca dropar migration de um dos lados. | +| `src/migrations/*.ts` / `*.json` | Arquivos novos de lados diferentes → manter os dois. Mesmo timestamp/nome → pare e pergunte (não fundir SQL no escuro). | +| `src/payload-types.ts` | Prefira regenerar (`pnpm generate:types`) **depois** do rebase limpo em vez de merge manual gigante, se o schema dos dois lados for coerente. | +| `docs/roadmap.md` / `docs/plans/*` | Preserve entregas `✓` de main **e** itens/planos novos da feature; não apague marca de entregue de main. | +| Snapshots/fixtures (`plaza-catalog`, municipality codes) | Se main e feature divergiram o gerador, rode o rebuild/seed canônico do plano; não edite snapshot “no feeling”. | +| Lockfiles (`pnpm-lock.yaml`) | Aceite um lado e rode `pnpm install` para regenerar; não mescle lockfile à mão. | + +### Quando abortar e perguntar + +- Conflito em access control / Consent / uniqueness / migration destrutiva sem regra clara +- Main reverteu ou redesenhou a mesma feature +- Mais de ~5 arquivos com conflito sem padrão óbvio de união + +```bash +git rebase --abort # só neste caso, após explicar +``` + +## Passo 5 — Verificar e reportar + +```bash +git status -sb +git log --oneline origin/main..HEAD +git diff --stat origin/main...HEAD +``` + +Opcional e leve (se o rebase tocou schema/types): `pnpm exec tsc --noEmit` nos arquivos relevantes — **não** rode a suíte inteira salvo pedido. + +**Resumo ao usuário (curto):** + +1. Branch + worktree path +2. Quantos commits rebased / se no-op +3. Conflitos resolvidos (paths + uma linha de racional cada) **ou** “nenhum” +4. Se abortou: por quê + o que precisa de decisão +5. Próximo passo natural: `capture-review-debts` (se ainda não rodou), `ship-to-main`, ou o atalho `close-delivery` (rebase+debts+ship) + +## Anti-padrões + +| Nunca | Em vez disso | +| -------------------------------------------- | ------------------------------------------------------------- | +| `git push --force` sem pedido | Deixe force-with-lease para `ship-to-main` / pedido explícito | +| Resolver conflito sem ler os dois lados | Abra o arquivo + `git show :1/:2/:3:` se precisar | +| Continuar rebase com markers `<<<<<<<` | Grep por `^<<<<<<<` antes de `--continue` | +| Rebasear em cima de `main` local stale | Sempre `fetch` + `origin/main` | +| `reset --hard` para “limpar” conflito | Abort ou resolve; hard reset só com pedido explícito | +| Expandir escopo (refatorar além do conflito) | Só o necessário para o rebase passar | + +## Posição no fluxo + +``` +suggest-next → implement-roadmap-item → /simplify+/impeccable + → rebase-on-main → capture-review-debts → ship-to-main + # ou atalho: close-delivery +``` diff --git a/.cursor/skills/ship-to-main/SKILL.md b/.cursor/skills/ship-to-main/SKILL.md new file mode 100644 index 00000000..bbae93e6 --- /dev/null +++ b/.cursor/skills/ship-to-main/SKILL.md @@ -0,0 +1,193 @@ +--- +name: ship-to-main +description: >- + Commit all session work, push the feature branch, merge into main, push main, + then remove the session git worktree and delete the feature branch. Use after + capture-review-debts when the user says "commit all, push, merge to main", + "ship", "merge to main", "fecha a entrega", "sobe pro main", or asks to finish + the worktree session and land on main. +--- + +# Ship to main + +Etapa final do fluxo de entrega Teqo em worktree: **commit all → push feature → merge em main → push main → apagar worktree da sessão**. + +**Inspiração:** `superpowers:finishing-a-development-branch` (merge local + cleanup de worktree com `cd` no repo principal), regras de commit/PR do usuário, `gh` quando houver PR aberto. + +**Announce at start:** "Using ship-to-main to land this branch on main and clean up the worktree." + +**Pré-condição típica:** `rebase-on-main` já rodou (branch em dia com `origin/main`). Se estiver atrás de main, rode `rebase-on-main` antes de mergear — não mergeie feature stale. + +## Checklist + +``` +- [ ] 1. Detectar ambiente (branch, MAIN_ROOT, worktree path) +- [ ] 2. Commit all (se houver mudanças; seguir protocolo de commit) +- [ ] 3. Push da feature branch +- [ ] 4. Merge da feature em main (no checkout principal) + push main +- [ ] 5. Remover worktree da sessão + deletar feature branch +- [ ] 6. Reportar URLs/SHAs e avisar se a sessão Cursor ficou em path morto +``` + +## Passo 1 — Detectar ambiente + +```bash +git status -sb +FEATURE_BRANCH=$(git branch --show-current) +WORKTREE_PATH=$(git rev-parse --show-toplevel) +GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) +GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) +# Primary checkout (safe even when CWD is a linked worktree): +MAIN_ROOT=$(git worktree list --porcelain | awk '/^worktree / {print $2; exit}') +git worktree list +git -C "$MAIN_ROOT" branch --show-current +git fetch origin main +git merge-base --is-ancestor origin/main HEAD && echo "in-sync-or-ahead" || echo "behind-main" +``` + +Se `GIT_DIR == GIT_COMMON`, você já está no checkout principal: `MAIN_ROOT="$WORKTREE_PATH"` e o Passo 5a vira no-op. + +**Guards:** + +| Condição | Ação | +| ----------------------------------------- | ----------------------------------------------------- | +| `FEATURE_BRANCH` é `main`/`master` | Pare — não “ship” de main para main. | +| Detached HEAD | Pare — precisa de branch nomeada. | +| Rebase/merge em andamento | Termine ou aborte antes. | +| Feature atrás de `origin/main` | Rode `rebase-on-main` primeiro. | +| Usuário pediu só commit / só push / só PR | Não execute o fluxo completo; honre o pedido parcial. | + +Capture `WORKTREE_PATH` **antes** de qualquer `cd` — é o path a remover no Passo 5. + +## Passo 2 — Commit all + +Siga o protocolo de commit do usuário (status + diff staged/unstaged + log recente **em paralelo**; mensagem via HEREDOC; sem `--no-verify`; sem amend salvo regras dele). + +```bash +git status -sb +git diff --stat && git diff --cached --stat +git log -5 --oneline +``` + +- Inclua arquivos relevantes da entrega (código + docs de roadmap/planos da sessão). +- **Não** commite segredos (`.env`, credenciais). +- Se working tree limpa e já há commits na feature: pule o commit, siga. +- Mensagem: 1–2 frases no estilo do repo, foco no **porquê** da entrega (item do roadmap se conhecido). + +## Passo 3 — Push da feature + +```bash +git push -u origin HEAD +``` + +Se o rebase reescreveu commits já pushed e o push for rejeitado: + +```bash +git push --force-with-lease origin HEAD +``` + +Use `--force-with-lease` **somente** neste caso (feature branch própria, nunca `main`). Sem lease cego (`--force`). + +## Passo 4 — Merge em main e push main + +Tudo a partir do **checkout principal**, nunca de dentro do worktree da feature: + +```bash +cd "$MAIN_ROOT" +git checkout main +git pull --ff-only origin main +git merge --no-ff "$FEATURE_BRANCH" -m "Merge branch '$FEATURE_BRANCH'" +``` + +Preferência Teqo (solo / worktree): merge local. Se `git pull --ff-only` falhar, pare e diagnostique — não force main. + +**Alternativa só se o usuário pedir PR em vez de merge local:** + +```bash +gh pr create --title "…" --body "…" # ou merge de PR existente +gh pr merge --merge # ou --squash se o usuário pedir +``` + +Após merge local bem-sucedido: + +```bash +git push origin main +``` + +Verifique: + +```bash +git status -sb +git log -3 --oneline +git -C "$MAIN_ROOT" merge-base --is-ancestor "$FEATURE_BRANCH" main && echo "feature ⊆ main" +``` + +**Só avance ao Passo 5 se main contém a feature e o push de main OK.** + +Se testes/CI forem gate explícito do usuário neste momento, espere; caso contrário não rode a suíte completa de AGENTS.md de novo (já veio de simplify/implement). + +## Passo 5 — Apagar worktree + branch + +Ordem obrigatória (igual Superpowers): **merge OK → remove worktree → delete branch**. Nunca delete a branch enquanto o worktree ainda a referencia. + +```bash +cd "$MAIN_ROOT" +``` + +### 5a. Remover worktree da sessão + +Se `WORKTREE_PATH` == `MAIN_ROOT`: **não remova** — não há worktree extra. + +Se `WORKTREE_PATH` ≠ `MAIN_ROOT`: + +```bash +git worktree remove "$WORKTREE_PATH" +# Se dirty residual após merge (raro): +# git worktree remove --force "$WORKTREE_PATH" +git worktree prune +``` + +**Cursor / harness (`~/.cursor/worktrees/...`):** esta skill **é** o consentimento explícito para remover o worktree da sessão após o merge — diferente do default cauteloso de `finishing-a-development-branch`. Ainda assim: + +- Remova **somente** o `WORKTREE_PATH` da sessão atual, nunca outros worktrees listados. +- Remova sempre com CWD em `$MAIN_ROOT`. +- Avise que a janela/agente Cursor pode estar apontando para um diretório já apagado — o usuário deve reabrir o checkout principal (`$MAIN_ROOT`). + +Se existir ferramenta nativa de exit/cleanup de worktree do harness, prefira-a; senão `git worktree remove` como acima. + +### 5b. Deletar feature branch + +```bash +git branch -d "$FEATURE_BRANCH" +git push origin --delete "$FEATURE_BRANCH" 2>/dev/null || true +``` + +Use `-d` (safe). Só `-D` se o merge foi confirmado mas o Git ainda reclama e você verificou `feature ⊆ main`. + +## Passo 6 — Resumo + +1. SHA de `main` após o merge + mensagem do merge/commit +2. Feature branch deleted? remote deleted? +3. Worktree removido: path (ou “n/a — já era main”) +4. Aviso Cursor se aplicável: reabrir `$MAIN_ROOT` +5. Próximo passo natural: `suggest-next-roadmap-items` + +## Anti-padrões + +| Nunca | Em vez disso | +| ------------------------------------------------------------ | ----------------------------------------- | +| Mergear de dentro do worktree feature com checkout bagunçado | `cd "$MAIN_ROOT"` → checkout main → merge | +| `git worktree remove` com CWD dentro do worktree | Sempre a partir de `$MAIN_ROOT` | +| Apagar worktree **antes** do merge/push de main OK | Passo 4 completo primeiro | +| Remover _outros_ worktrees do `git worktree list` | Só `WORKTREE_PATH` da sessão | +| `push --force` em `main` | Só ff / merge commit normal | +| `git clean -fdx` / `reset --hard` no main | Fora de escopo | +| Pular commit com mudanças uncommitted | Commit no Passo 2 ou pergunte | + +## Posição no fluxo + +``` +suggest-next → implement-roadmap-item → /simplify+/impeccable + → rebase-on-main → capture-review-debts → ship-to-main + # ou atalho: close-delivery +``` diff --git a/.cursor/skills/suggest-next-roadmap-items/SKILL.md b/.cursor/skills/suggest-next-roadmap-items/SKILL.md index 09da8d41..2b461907 100644 --- a/.cursor/skills/suggest-next-roadmap-items/SKILL.md +++ b/.cursor/skills/suggest-next-roadmap-items/SKILL.md @@ -21,7 +21,10 @@ Esta skill **só recomenda** — não implementa, não edita o roadmap e não cr | `suggest-next-roadmap-items` | **Escolher candidatos** entre o que o roadmap já lista | | `roadmap-item` | Registrar ideia nova / criar plano | | `implement-roadmap-item` | Auditar plano + implementar o ID escolhido | +| `rebase-on-main` | Após simplify: fetch + rebase em main + conflitos | | `capture-review-debts` | Triagear débitos de `/simplify` / critique | +| `ship-to-main` | Commit + push + merge main + apagar worktree | +| `close-delivery` | Orquestra rebase + debts (auto-confirm) + ship | ## Checklist