Handoff
Uma sessão nova faz melhor QA e melhor revisão do que a sessão que implementou — menos contexto, sem apego ao código. Essa é uma prática deliberada, e ela vive ou morre pelo handoff. Este skill faz cada um deles ser bom.
Princípios operacionais
- Fatos são verificados, não lembrados. Cada contagem, caminho e id no bloco vem de um comando executado agora:
git rev-list --count origin/<branch>..HEAD,git worktree list,ls QA-<slug>.md, os ids de fixture obtidos do arquivo QA. Um handoff que diz "3 commits podem não estar pushados" quando a contagem é 5 leva a próxima sessão para o caminho errado. - O leitor só tem o bloco. Sem "como vimos", sem referência a este chat. Nomeie a skill a invocar, o arquivo a ler, o comando a executar.
- Chat por padrão. O bloco é renderizado no chat dentro de um bloco de código para copiar e colar. Um arquivo
HANDOFF-<slug>.md(arquivo raiz efêmero,profile.ephemeral_patterns: gitignorado, nunca commitado) só quando o usuário pedir um arquivo ou o bloco exceder ~60 linhas. - Passos que afetam produção são nomeados, com o motivo. Não "cuidado com o passo 8" mas o que ele escreve onde e por que não pode ser desfeito.
- Disciplina de PII como em todo lugar: ids e primeiros nomes; e-mails são identificadores de trabalho e podem aparecer; nunca números de documento nacional, telefone ou endereço.
Quando usar
- O encerramento do
cdv-finalize(ele mesmo imprime o handoff de QA, usando este template). - O usuário pede um prompt para continuar uma investigação, executar uma revisão ou executar QA em outra sessão.
- Uma sessão está prestes a ser abandonada porque seu contexto cresceu (compaction iminente, "está ficando longo").
Fluxo
Etapa 0 — Carregar o perfil e a extensão
- Leia
.claude/harness/profile.yamle, quando presente,.claude/harness/profile.local.yaml(suas chaves vencem). Seprofile.yamlestiver faltando, pare e diga: este skill precisa do perfil cdv-harness do repositório, e nunca adivinha os valores. - Leia
<profile.extension_dir>/cdv-handoff.mdquando existir. A extensão só adiciona ou restringe; onde ela e este skill diferirem, a extensão vence para este repositório. Abaixo,profile.<chave>é um valor do perfil. Uma chave que está faltando ou énonesignifica que o repositório não tem aquela coisa: pule a etapa que precisa dela.
Etapa 1 — Determinar o tipo e reunir fatos (tudo somente leitura)
Tipo ∈ qa | review | investigation | continue-implementation. Então execute e mantenha a saída bruta:
git branch --show-current
git worktree list --porcelain
git rev-list --count origin/<branch>..HEAD 2>/dev/null # commits não pushados ('?' se sem remote)
git rev-list --count HEAD..origin/<profile.default_branch> # atrás da branch padrão
git status --porcelain | grep -v '^??' # arquivos tracked não commitados
ls QA-<slug>.md STATE-<slug>.md <slug>-pr.md decisions-<slug>.md 2>/dev/null
grep -n 'PRODUCTION-AFFECTING' QA-<slug>.md 2>/dev/null
Para qa: as fixtures vêm dos próprios passos do arquivo QA (ids + labels de exibição, da forma que cdv-interactive-qa precisa). Para review: o id do ticket via cdv-code-review/scripts/resolve-ticket-id.sh e se um <profile.pr_review_dir_prefix><TICKET>/ já existe. Para investigation: o bloco de hipóteses e a tabela de evidências do relatório cdv-debug, ipsis litteris. Para continue-implementation: os status de fase do STATE-<slug>.md, seu ## Finalize seed e se ## Verificação existe.
Etapa 2 — Renderizar o bloco
Bloco de código, em profile.language_ui (os cabeçalhos de seção PT-BR abaixo permanecem como escritos), nesta ordem; solte uma seção apenas quando estiver verdadeiramente vazia, e diga (Sem fixtures pré-consultadas.):
<VERBO> da branch <branch> (<uma frase do que ela entrega>).
ONDE ESTÁ O CÓDIGO
- <caminho do worktree | checkout principal `profile.main_checkout`>
- <N> commits à frente de origin/<profile.default_branch>; <M> commits NÃO pushados (confira: git rev-list --count origin/<branch>..HEAD)
- <arquivos tracked não commitados, ou "árvore limpa">
ARMADILHA DO AMBIENTE (apenas quando o código está em um worktree e `profile.worktree_runner` não é `none`)
- O worktree não tem o ambiente do checkout principal (dependências, `.env`); `profile.cmd_container_exec` testa o checkout principal, não este.
- Todo gate por: <profile.worktree_runner> <worktree> <comando de teste> <filtro>
- Para QA na tela: trazer a branch com <profile.bring_branch_script> --check <branch> e depois sem --check. Se recusar, PARE e pergunte — é WIP de outra sessão. Nunca git stash.
- Baseline atual: <N passed (M assertions)>, formatador <PASS>, análise estática <OK>.
O QUE FAZER
- Invoque a skill <cdv-interactive-qa | cdv-code-review | cdv-debug | cdv-plan-feature>.
- <roteiro/arquivo a ler, com caminho> | <id do ticket> | <relatório para começar>
FIXTURES REAIS (validadas em <data>)
- <entidade> <id> (<label como a tela mostra>) — <estado que interessa>
- ...
PASSOS QUE ESCREVEM FORA DO LOCAL [PRODUCTION-AFFECTING]
- Passo <n>: escreve <o quê> em <sistema externo, de `profile.production_writing_integrations`>; irreversível porque <motivo>. Só o usuário roda, depois de confirmar <o quê>.
- (ou) Nenhum — tudo é leitura ou escrita só no banco local.
CONTEXTO QUE MUDA A EXPECTATIVA
- <o um ou dois fatos que pareceriam bugs: "o comando de exportação sai com exit 0 por decisão", "o export roda só de madrugada — testar com o comando manual é o esperado">
NÃO FAÇA
- Não troque a branch do checkout principal por cima de WIP alheio; não use git stash.
- <qualquer coisa que o usuário excluiu: "não investigar os dois registros duplicados">
<VERBO> é Rode o QA interativo, Faça o code review, Continue a investigação ou Continue a implementação.
Etapa 3 — Autoverificação antes de imprimir
- Cada número veio de um comando na Etapa 1 (reexecute se a árvore mudou).
- Cada caminho existe (
ls). - Nenhuma frase precisa deste chat para ser entendida.
- A seção PRODUCTION-AFFECTING está presente (com conteúdo ou com "Nenhum").
Composição
cdv-finalize— imprime o tipoqano seu encerramento usando este template; quando este skill é invocado sozinho após um finalize, reutilize os números do relatório de estado em vez de derivá-los novamente.cdv-interactive-qa,cdv-code-review,cdv-debug,cdv-plan-feature— os receptores. O bloco nomeia qual invocar.cdv-code-reviewmodo terceiro — um handoff de revisão para o PR de um colega diz explicitamente (branch de terceiro: sem apply-review).
Exemplo (tipo qa, condensado)
Rode o QA interativo da branch fix/export-stale-file (o export escrevia o arquivo de ontem
depois de uma nova execução manual; agora grava o arquivo do dia e remove o anterior).
ONDE ESTÁ O CÓDIGO
- worktree .claude-worktrees/export-stale-file
- 5 commits à frente de origin/<branch padrão>; 2 NÃO pushados (git rev-list --count origin/fix/export-stale-file..HEAD)
- árvore limpa
ARMADILHA DO AMBIENTE
- Worktree sem o ambiente do checkout principal: gates pelo executor de worktree; para a tela, o script de trazer a branch com --check primeiro.
- Baseline: suíte de testes verde, formatador PASS, análise estática OK.
O QUE FAZER
- Invoque cdv-interactive-qa; roteiro em QA-export-stale-file.md (6 passos).
FIXTURES REAIS (validadas na data do handoff)
- relatório 7 (Vendas — semana) — exportado ontem, o arquivo antigo ainda existe (o caso a reparar)
- relatório 8 (Estoque — semana) — nunca exportado (o caso limpo)
PASSOS QUE ESCREVEM FORA DO LOCAL
- Passo 4: o one-off LÊ a API externa real (uma chamada por item) para conferir os totais; nunca escreve nela. Se algo sugerir escrita, pare.
- Nenhum outro — o export grava só no disco local.
CONTEXTO QUE MUDA A EXPECTATIVA
- O export roda só de madrugada — testar com o comando manual é o esperado.
NÃO FAÇA
- Não troque a branch do checkout principal por cima de WIP alheio; não use git stash.