19 — `init.sh` e Definition of Done
19 — init.sh e Definition of Done
Um script que verifica o baseline do projeto antes e depois de cada sessão, em dois modos. E a definição de quando uma tarefa está de fato concluída. Um
init.shque não roda é pior que nenhum. Execute-o antes de dizer que terminou.
Por que existe
Sem baseline verificado, uma sessão começa sobre terreno já quebrado e o dev gasta uma hora
depurando um erro que não era dele. O init.sh responde a uma pergunta em segundos: o projeto está
são agora?
Roda no início da sessão (o terreno está limpo?) e no fim (eu quebrei algo?).
FAST e FULL
A distinção é o que faz o script ser usado de fato, em vez de pulado por demorar.
| Modo | Invocação | O que roda | Quando |
|---|---|---|---|
| FAST | ./init.sh |
Lint + type-check | Toda hora, várias vezes ao dia |
| FULL | FULL=1 ./init.sh |
+ format:check + build completo |
Antes de considerar pronto |
FAST precisa terminar em segundos. Se passar de ~30s, algo está no modo errado.
O script
#!/usr/bin/env bash
# init.sh — verifica o baseline do projeto antes/depois de uma sessao.
#
# Uso:
# ./init.sh # rapido (padrao): lint + type-check
# FULL=1 ./init.sh # completo: + format:check + build
#
# Pre-requisitos:
# - Node >= 24 no PATH (gerenciado via fnm — ver harness/guides/dev-environment.md)
# - npm install ja rodado
set -euo pipefail
FULL="${FULL:-0}"
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "== {{NOME_DO_PROJETO}} — init.sh (modo $([ "$FULL" = "1" ] && echo FULL || echo FAST)) =="
echo ""
echo "--- [1/4] Node ---"
node_expected=$(tr -d '[:space:]' < "$ROOT_DIR/.node-version")
node_actual=$(node -v 2>/dev/null | sed 's/^v//')
if [ -z "$node_actual" ]; then
echo "ERRO: 'node' nao encontrado no PATH. Rode 'fnm use'."
exit 1
fi
lower=$(printf '%s\n%s\n' "$node_expected" "$node_actual" | sort -V | head -n1)
if [ "$lower" != "$node_expected" ]; then
echo "ERRO: Node v$node_actual encontrado, necessario >= v$node_expected."
exit 1
fi
echo "Node v$node_actual OK"
echo ""
echo "--- [2/4] Lint ---"
(cd "$ROOT_DIR" && npm run lint)
echo ""
echo "--- [3/4] Type-check ---"
(cd "$ROOT_DIR" && npx tsc --noEmit)
if [ "$FULL" = "1" ]; then
echo ""
echo "--- [4/4] Formatacao + build ---"
(cd "$ROOT_DIR" && npm run format:check)
(cd "$ROOT_DIR" && npm run build)
else
echo ""
echo "--- [4/4] Build — PULADO (rode com FULL=1 para incluir) ---"
fi
echo ""
echo "== init.sh OK =="
Projeto web dentro de um monorepo
Se o web for submódulo de um monorepo, o init.sh fica na raiz do repositório e entra na pasta do
módulo:
WEB_DIR="$ROOT_DIR/caminho/do/modulo"
echo "--- [2/4] Lint ---"
(cd "$WEB_DIR" && npm run lint)
Decisões do script
| Item | Razão |
|---|---|
set -euo pipefail |
Aborta no primeiro erro; variável indefinida vira falha, não string vazia |
| Checagem de Node primeiro | Erro claro em vez de falha incompreensível do npm |
npx tsc --noEmit no FAST |
Barato e pega o que o checker do dev não viu |
build só no FULL |
Demora demais para rodar a toda hora |
format:check, não format
|
Verificação não deve reescrever arquivo |
Não copie comandos de outro projeto (ex.: ./mvnw compile, mvn test de um projeto fullstack
Java+React). Os comandos precisam ser os reais deste projeto.
Rodar o script
chmod +x init.sh
./init.sh
No Windows, execute pelo Git Bash. Se o time for todo Windows, considere um init.ps1 equivalente —
mas mantenha um só como fonte de verdade, para não divergirem.
Execute o script depois de gerá-lo. Isso não é sugestão: um init.sh que nunca rodou tem
probabilidade alta de estar quebrado (caminho errado, script npm inexistente, set -e derrubando num
comando que retorna não-zero legitimamente).
Startup Workflow
Antes de escrever código:
-
pwd— confirme o diretório. - Resolva a branch atual (
git rev-parse --abbrev-ref HEAD). Seharness/<branch>/state/não existir, crie a partir deharness/_examples/(scaffolding mecânico, não preenchimento de conteúdo). - Leia
harness/user_preferences.md(se existir). - Leia
harness/<branch>/state/feature_list.jsoneprogress.md(se existirem). -
git log --oneline -5. -
./init.sh.
Se o baseline já estiver quebrado, corrija antes de implementar feature nova. Misturar correção de baseline com feature nova produz um diff que ninguém consegue revisar.
Definition of Done
Uma tarefa só está concluída quando:
O item do browser não é opcional
Não há suíte de testes (14). lint e tsc provam que o código
compila, não que funciona. A única evidência funcional que existe neste padrão é abrir a tela e
verificar o fluxo. Ver o checklist de 17.
Evidência é texto, não adjetivo
// RUIM — nao e' evidencia
"evidence": "Implementado e testado."
// BOM — verificavel
"evidence": "Implementado em 2026-08-18. ./init.sh FULL verde. Tela cadastro/fornecedor aberta em dev:
busca com filtro 'ACME' retornou 3 registros; salvar com CNPJ invalido bloqueou no zod; salvar valido
mostrou notificacao verde e o registro apareceu na tabela apos rebusca. Sem erro no console."
Não marque como passing só porque o código foi escrito. É o erro mais comum, e o que torna o
feature_list.json inútil.
Fim de sessão
- Atualizar
harness/<branch>/state/feature_list.json(status + evidência): se algo chegou apassing, mover a entrada defeaturesparacompletedno mesmo arquivo — sem cópia para nenhum arquivo global, não existe mais (ver 18). - Atualizar
harness/<branch>/state/progress.md. - Atualizar
harness/<branch>/state/session-handoff.mdcom o resultado da verificação. - Commit descritivo com o repositório em estado seguro — inclui
state/,plans/,specs/ehandoffs/da branch, tudo versionado. - A próxima sessão deve conseguir rodar
./init.shimediatamente.
O passo 5 é o teste do fim de sessão: se a próxima pessoa não consegue verificar o baseline sem antes consertar algo, a sessão não fechou.
Se o projeto adotar testes
Se 14 for revisto e o projeto passar a ter suíte:
- Adicione
npm testao bloco FULL doinit.sh. - Adicione "testes passando" à Definition of Done.
- Mantenha o item da verificação no browser — teste unitário não prova integração com o Curio.