Add delivery closeout skills and wire them into the roadmap workflow.

Introduces rebase-on-main, ship-to-main, and close-delivery for the post-simplify worktree flow, with cross-references in existing roadmap skills.
This commit is contained in:
Francisco Ignácio Fontoura Solla 2026-07-21 16:25:58 -03:00
parent c0bf440c76
commit f3302d5dca
7 changed files with 440 additions and 0 deletions

View file

@ -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 |

View file

@ -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.

View file

@ -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.

View file

@ -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`).

View file

@ -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:<branch>`. 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 <files>` → `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
```

View file

@ -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
```

View file

@ -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