Lição 4 de 6: Atualizar o Starter
- Remote
upstreamconfigurado apontando pro starter público - Pelo menos 1 ciclo completo de
fetch + inspect + merge ou rejeitarrealizado - Pelo menos 1 conflito resolvido (real ou simulado): você sabe o gesto
- Commit
chore(starter): upstream synced (or rejected — reason X)
O que você vai conseguir ao fim desta lição
Você vai conectar seu projeto ao starter original pra receber fixes e melhorias sem perder o que você customizou. Vai:
- Configurar o
upstream(apelido pro repo do Starter) - Baixar mudanças do Starter sem aplicar, pra você inspecionar antes
- Decidir caso a caso: aceita esse fix? rejeita aquela mudança? aplica essa skill nova?
- Resolver pelo menos 1 conflito (real ou simulado), pra você ter o gesto pronto quando precisar
- Registrar a decisão num log de sincronizações
Em termos técnicos: você vai git remote add upstream, git fetch upstream, git log upstream/main ^HEAD pra inspeção, decidir merge total ou cherry-pick seletivo, resolver pelo menos 1 conflito de merge, e documentar em docs/starter-sync-log.md.
Você clonou o Builder OS Starter em alguma data passada e foi adicionando coisa em cima. Enquanto isso, o upstream (o Starter público) continuou se atualizando: CLI fix, edge case BR novo, skill atualizada. Você fica preso na versão que clonou, e os fixes não chegam.
Esta lição configura o remote upstream apontando pro starter, e te mostra o workflow de inspecionar antes de merge. Por que inspeção primeiro? Porque você modificou o Starter: seu Personal Pack vive lá dentro. Aceitar mudança no escuro pode sobrescrever o seu trabalho. Inspecionando primeiro, você decide arquivo por arquivo.
Vocabulário rápido:
origin= seu fork ou clone do Starter. É pra onde você faz push.upstream= o starter público, mantido pelo autor (jpvss/builder-os ou onde for). Você só lê dele; nunca dá push.git fetch upstream= baixa as mudanças do upstream sem aplicar. Você inspeciona comgit log upstream/main ^HEAD(commits que estão no upstream e não no seu repo), depois decide se mergeia.git merge upstream/main= aplica as mudanças. Se há conflitos (você modificou arquivo que upstream também modificou), git pausa pra você resolver.
Por que git remote add upstream (não gh repo sync)
gh repo sync é o comando "fácil" do GitHub CLI: sincroniza seu fork com upstream automaticamente. Para repos não-modificados, é OK. Para Builder OS Starter, não serve: você modificou o .claude/, criou rules, possivelmente alterou skills. gh repo sync pode aceitar mudanças que sobrescrevem o seu trabalho sem te perguntar.
git remote add upstream é o pattern explícito: você baixa, olha o diff e decide arquivo por arquivo.
Passo 1 — Adicione o upstream
Cole no Claude:
Configura o remote upstream do starter. Comandos:
1. `git remote -v`: checa o que existe agora (deve aparecer só `origin`)
2. `git remote add upstream https://github.com/jpvss/builder-os.git` (ou repo equivalente; confirma o URL real do Starter que cloneei)
3. `git fetch upstream`
4. `git remote -v` de novo: agora deve aparecer `origin` + `upstream`
Mostra cada passo do output.Aprove. Você agora tem 2 remotes:
origin= seu repo no GitHubupstream= starter público (você só lê)
Passo 2 — Liste as mudanças disponíveis
Quero ver o que mudou no starter desde que clonei. Comandos:
1. `git log --oneline upstream/main ^HEAD --first-parent | head -30`: commits que tem no upstream mas não no meu repo
2. `git diff --stat upstream/main`: quais arquivos têm diferença
Mostra o output dos dois. Não merge nada ainda, só listagem.Aprove. Resultado típico (depende de quanto tempo passou):
- Talvez 5-30 commits novos no upstream
- Talvez 10-40 arquivos com diferença
- Mistura de "arquivo novo no upstream" (skill nova, etc.) e "arquivo modificado nos dois lados" (conflito potencial)
Passo 3 — Inspecione 3 arquivos específicos antes de decidir
Não aplique tudo de uma vez. Pega 3 arquivos do diff e olha caso a caso:
Lista os 3 arquivos com maior diff entre meu repo e upstream (ordenado por # de linhas mudadas). Para cada um:
1. `git diff HEAD..upstream/main -- <arquivo>`: mostra o diff
2. Avalia: é mudança que eu quero (fix, melhoria)? É mudança que conflita com algo meu? É arquivo do canônico (Starter) ou do Personal Pack?
Mostra cada um e sua avaliação. Eu vou decidir o que fazer com cada.Aprove. Pra cada arquivo, decide:
- "Quero a mudança do upstream e não tenho mudança minha em conflito" → vai aplicar
- "Quero a mudança, mas tem coisa minha em cima" → vai mergear com cuidado (resolver conflito)
- "Não quero a mudança" → ignora (não vai mergear esse arquivo)
Passo 4 — Aplique seletivamente (ou mergeia tudo, se for seguro)
Duas opções, dependendo do que você viu no Passo 3:
Opção A — Merge completo (recomendado se 0 conflitos)
git merge upstream/mainSe git não reclama, você está bom. Confere com git log que o merge entrou, e roda npm run check pra confirmar que nada quebrou. Aprove e commita (o merge gera commit automático com mensagem "Merge upstream").
Opção B — Cherry-pick seletivo (recomendado se conflitos)
git log --oneline upstream/main ^HEAD
# Identifica os commits específicos que você quer
git cherry-pick <commit-hash>
# Repete pros que você quer; ignora os que nãoAprove cada cherry-pick. Se quebra, resolve o conflito (Passo 5).
Passo 5 — Resolva pelo menos 1 conflito (real ou simulado)
Se você teve conflito real no Passo 4, perfeito: resolve agora. Se não teve, simula um pra aprender o gesto:
Quero praticar resolver conflito de merge. Como simular:
1. Cria uma branch temporária: `git checkout -b practice-conflict`
2. Edita um arquivo do Starter (ex: `.claude/skills/getting-started/SKILL.md`): muda 1 linha. Commit.
3. Tenta merge a versão upstream: `git merge upstream/main -- .claude/skills/getting-started/SKILL.md` (vai gerar conflito)
4. Mostra o estado do arquivo conflituoso (com os `<<<<<<<` markers)
5. Me ensina o gesto pra resolver: identifica a versão minha (`<<<<<<<` até `=======`), a versão upstream (`=======` até `>>>>>>>`), decide qual ficar, salva, `git add`, `git commit`.
Depois desfaz tudo: `git checkout main && git branch -D practice-conflict`.Aprove. O gesto é simples mas a primeira vez assusta. Praticar simulado deixa pronto pra fazer no real.
Passo 6 — Documente o ciclo e commite
Atualiza `docs/decisions.md` (criado no M4/L03) ou cria `docs/starter-sync-log.md` com 1 entry:
# Starter sync log
## YYYY-MM-DD
- Commits inspecionados: <N>
- Aceitos: <lista de commit hashes / fixes que entraram>
- Rejeitados: <lista + razão> (ex: "feat(skill): change to commit-and-pr SKILL.md; meu pack tem versão customizada, não quero perder")
- Próximo sync planejado: <data ou trigger>
Mostre o diff antes de criar.Aprove. Commit:
Faça commit das mudanças. Mensagem: `chore(starter): upstream synced — <data>` (ou `chore(starter): upstream rejected — <razão>` se você decidiu não mergear nada). Mostra os comandos antes.Aprove.
Build Diary — o CEAP usa CHANGELOG.md pra registrar mudanças do dashboard
O CEAP tem um CHANGELOG.md (formato Keep a Changelog) que registra cada mudança significativa entre versões. Trecho:
[3.1] - 2026-01-05
Changed
- CNAE mapping: added 84/85/94 to Category 1
Fixed
- False positives in Office Maintenance category
O CHANGELOG.md cumpre função análoga ao docs/starter-sync-log.md que você acabou de criar: memória das mudanças intencionais entre versões. Quem chega no projeto 6 meses depois lê o changelog e entende o porquê das decisões em ordem cronológica, sem precisar abrir o git log e cruzar com PRs.
Quando o changelog vale a pena: projetos com >1 release ao mês. Pra fatia 1 inicial, é overhead. Mas a partir do M4 (você lança em produção), criar CHANGELOG.md no estilo do CEAP é boa ideia: vira o complemento natural do runbook.md (do M4/L07).
Takeaways
- Sync com upstream a cada 1-2 meses. Mais frequente é overhead; menos frequente acumula divergência.
- Inspeção primeiro, merge depois.
git fetch upstreambaixa; você decide antes de aplicar.gh repo syncé o "fácil": perigoso pra repo modificado. - Cherry-pick seletivo quando há mudança específica que você quer; merge completo quando 0 conflito + 0 dúvida.
docs/starter-sync-log.mdregistra a memória das decisões. Sem ele, você re-avalia o mesmo upstream commit 3 meses depois.
Você terminou quando
Quatro coisas:
git remote -vmostraorigin+upstreamconfiguradosgit fetch upstreamrodou, você viu o que tem disponível- Pelo menos 1 ciclo: inspecionou → decidiu (merge OU rejeitou) → documentou
- Pelo menos 1 conflito resolvido (real ou simulado): você sabe o gesto