From 4f3d078d9950b3a4e66ad95a2732d21dcb7ace9b Mon Sep 17 00:00:00 2001 From: Roni Fabio Banaszewski Date: Tue, 1 Sep 2026 17:24:02 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20revis=C3=A3o=20de=20consist=C3=AAncia=20?= =?UTF-8?q?=E2=80=94=20Gitflow=20completo,=20port=C3=A3o=20de=20400,=20res?= =?UTF-8?q?tos=20de=20NestJS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - branch da história nasce no entendimento (main/develop bloqueadas exigem um lugar para o commit de aprovação da spec); guia, workflow e tutorial contam a mesma ordem: rascunho -> aprovação -> plano -> código - diffs do tutor (prova) e do auditor final passam a apontar para develop - diagrama do guia migrado para Gitflow (branch da develop, merge na develop) - CONTRIBUTING alinhado aos 400 caracteres; CI descarta comentários HTML do modelo antes de contar; proteção de branch exige o check explicacao - tutor e revisor-codigo sem restos de NestJS (Nest, controller, banco) - setup sem 'framework do backend'; casca apps/ agora vem no template - design-tokens ganha seções de breakpoints e identidade PWA; PRD define Draft -> Ready -> Live; /utf-tutor no Claude Code usa $ARGUMENTS Co-Authored-By: Claude Fable 5 --- .agents/agents/auditor-final.md | 4 +- .agents/agents/revisor-codigo.md | 4 +- .agents/agents/tutor.md | 10 +-- .agents/workflows/ciclo-tarefa.md | 4 +- .agents/workflows/setup.md | 23 +++--- .agents/workflows/tutor.md | 2 +- .agents/workflows/utf-workflow.md | 11 +-- .claude/commands/utf-tutor.md | 2 +- .github/workflows/portao-de-entendimento.yml | 3 +- CONTRIBUTING.md | 2 +- apps/api/README.md | 1 + apps/web/.gitkeep | 0 docs/architecture.md | 2 +- docs/design-tokens.md | 24 +++++++ docs/guia-sdd.md | 73 ++++++++++++-------- docs/prd.md | 7 +- docs/tutorial-sdd.md | 18 ++--- 17 files changed, 122 insertions(+), 68 deletions(-) create mode 100644 apps/api/README.md create mode 100644 apps/web/.gitkeep diff --git a/.agents/agents/auditor-final.md b/.agents/agents/auditor-final.md index 9c6aeac..04d7f32 100644 --- a/.agents/agents/auditor-final.md +++ b/.agents/agents/auditor-final.md @@ -1,6 +1,6 @@ --- name: auditor-final -description: Passo 6 do ciclo. Compara o diff INTEIRO da branch contra a spec.md original, não contra o plano. Somente leitura. +description: Passo 6 do guia (§4). Compara o diff INTEIRO da branch contra a spec.md original, não contra o plano. Somente leitura. mainAgent: false subagent: true tools: @@ -29,7 +29,7 @@ Você não altera nenhum arquivo. 1. Leia o `spec.md` **original**, incluindo as seções *fora de escopo*, *abandono no meio* e *assume que*. 2. **Ignore o `plan.md`.** Ele é meio, não fim — se o plano omitiu um critério, comparar contra ele esconde exatamente o defeito que você procura. -3. Leia o diff completo da branch contra a `main` (comando vem no despacho). +3. Leia o diff completo da branch contra a `develop` (comando vem no despacho — no Gitflow a feature branch nasce da `develop`). 4. Rode a suíte de testes inteira, não só os testes novos. 5. Confira, um a um, **todos** os critérios de aceite da spec. diff --git a/.agents/agents/revisor-codigo.md b/.agents/agents/revisor-codigo.md index 7aa26f7..dbefc69 100644 --- a/.agents/agents/revisor-codigo.md +++ b/.agents/agents/revisor-codigo.md @@ -33,8 +33,8 @@ Caminho do `spec.md`, número e texto da tarefa, e o comando de diff vêm no des ## O que reprova -- violação de camada declarada no `architecture.md` (ex.: controller acessando o banco direto) -- resposta de API fora do formato global (envelope, `statusCode`, `message`) +- violação de camada declarada no `architecture.md` (ex.: componente chamando o `HttpClient` direto, sem passar pelo Service) +- sintaxe fora dos padrões declarados no `architecture.md` (ex.: `*ngIf` no lugar de `@if`, injeção por construtor no lugar de `inject()`, estado fora de signals) - segredo, chave ou URL de ambiente escrita no código - tratamento de erro que engole a falha silenciosamente - abstração criada para um caso só — indireção sem ganho diff --git a/.agents/agents/tutor.md b/.agents/agents/tutor.md index 7a4dda0..77eccb4 100644 --- a/.agents/agents/tutor.md +++ b/.agents/agents/tutor.md @@ -24,8 +24,8 @@ Você não implementa, não corrige e não avalia qualidade — quem aponta prob ## Regras didáticas (valem para todos os modos) - **Português simples, um conceito por vez.** Frases curtas. Nada de jargão sem definição na primeira aparição. -- **Nomeie o termo oficial** (em inglês, como aparece na documentação) para o aluno conseguir pesquisar sozinho: "isso se chama *dependency injection*", "esse decorator é um *Guard*". -- **Explique o porquê do framework, não só o quê.** Não "criei um service", mas *por que o Nest injeta o service em vez de dar `new`, e o que quebraria sem isso*. +- **Nomeie o termo oficial** (em inglês, como aparece na documentação) para o aluno conseguir pesquisar sozinho: "isso se chama *dependency injection*", "essa função passada à rota é um *Functional Guard*". +- **Explique o porquê do framework, não só o quê.** Não "criei um service", mas *por que o Angular injeta o service via `inject()` em vez de dar `new`, e o que quebraria sem isso*. - **Use analogia do dia a dia** quando ela tornar o mecanismo visível (ex.: o Guard é a portaria do prédio: decide se a visita sobe antes de o morador atender). - **Ancore no projeto do aluno**, não em exemplos genéricos: cite os arquivos, entidades e rotas reais dele. - **Ligue aos Indicadores da disciplina** quando pertinente — os IDs estão em `docs/checklist.md`; cite o número e o que a tarefa evidencia dele. @@ -78,9 +78,9 @@ Devolva: ``` # Tutor — Tarefa explicada -## O caminho da requisição - +## O caminho do dado + ## Por que o framework faz assim diff --git a/.agents/workflows/ciclo-tarefa.md b/.agents/workflows/ciclo-tarefa.md index faeeac9..6e9d6eb 100644 --- a/.agents/workflows/ciclo-tarefa.md +++ b/.agents/workflows/ciclo-tarefa.md @@ -1,5 +1,5 @@ --- -description: Executa UMA tarefa do plan.md com o ciclo completo do Passo 5 — tutor explica antes e o usuário aceita, implementador com contexto limpo, dois revisores distintos e somente-leitura, máximo de 2 rodadas de revisão. Recebe o número da tarefa; sem número, resolve a próxima pendente do plan.md. +description: Executa UMA tarefa do plan.md com o ciclo completo do Passo 5 do guia (§4) — tutor explica antes e o usuário aceita, implementador com contexto limpo, dois revisores distintos e somente-leitura, máximo de 2 rodadas de revisão. Recebe o número da tarefa; sem número, resolve a próxima pendente do plan.md. --- # Ciclo de uma tarefa @@ -13,7 +13,7 @@ Tarefa a executar: **$1** ## Passo 0 — Localizar e travar 1. Descubra a pasta `specs/-/` da branch atual. -2. Abra o `spec.md` e confira `status: aprovada` no frontmatter. **Se não estiver, PARE** e diga: *"A spec ainda não foi aprovada por você. O portão do Passo 3 não passou."* +2. Abra o `spec.md` e confira `status: aprovada` no frontmatter. **Se não estiver, PARE** e diga: *"A spec ainda não foi aprovada por você. O portão de aprovação da spec (Passo 3 do guia) não passou."* 3. **Se o comando veio sem número**, resolva-o pelo `plan.md`: a tarefa é a **primeira ainda não marcada como feita**, na ordem do plano. Anuncie ao usuário qual número foi resolvido (ex.: *"Próxima pendente: tarefa 3 — "*) antes de seguir — daqui em diante, esse número é o `$1` em tudo (pareceres, decisões, commit). **Se não houver nenhuma pendente, PARE** e diga: *"Não há mais tarefas pendentes no `plan.md`. O próximo passo é o auditor final e o Pull Request, pelo fluxo da Issue."* Não invente tarefa nova. 4. Extraia do `plan.md` o **texto literal** da tarefa `$1`. 5. Guarde o ponto de partida: `git rev-parse HEAD`. Ele é a base de todos os diffs desta tarefa. diff --git a/.agents/workflows/setup.md b/.agents/workflows/setup.md index 38cacaf..f01ea9e 100644 --- a/.agents/workflows/setup.md +++ b/.agents/workflows/setup.md @@ -14,12 +14,15 @@ que foi decidida. O que não estiver escrito lá, você pergunta; não escolhe. ## Passo 0 — Pré-condições (PARE se qualquer uma falhar) -1. `docs/prd.md` e `docs/architecture.md` existem e declaram: o framework do backend, - o framework do frontend, a fonte de dados, a estrutura de pastas e como rodar os testes. +1. `docs/prd.md` e `docs/architecture.md` existem e declaram: o framework do + frontend (versão e padrões), a fonte de dados de cada fase, a estrutura de + pastas e como rodar os testes. Se algum desses quatro estiver ausente ou ambíguo, **PARE** e diga o que falta — setup com stack adivinhada é retrabalho garantido. 2. As pastas de app previstas no `architecture.md` (ex.: `apps/web`) - **não existem** ou estão vazias. Se já existirem com conteúdo, **PARE**: o setup + **não existem** ou estão vazias — o `.gitkeep` de `apps/web/` e o `README.md` + de reserva de `apps/api/`, que vêm do template, não contam como conteúdo. + Se já existirem com conteúdo de verdade, **PARE**: o setup roda uma vez, e rodá-lo de novo por cima é destrutivo. 3. Você está na `develop`, limpa e atualizada (se a `develop` ainda não existe, crie-a a partir da `main` e publique: `git switch -c develop && git push -u origin develop` — o Gitflow da ficha exige as duas). 4. O `gh` está autenticado (`gh auth status`) **ou** o MCP do GitHub está @@ -42,9 +45,10 @@ Gere o app com o gerador oficial da stack declarada no `architecture.md` dentro da estrutura de pastas que o documento descreve. - **A casca do monorepo é só estrutura.** Se o documento prevê `apps/web` e - `apps/api`, gere o app em `apps/web` e **crie `apps/api/` vazia**, com um - `README.md` de uma linha dizendo que ela está reservada para uma API própria, - se um dia existir. **Não gere backend nenhum** — nem scaffold, nem + `apps/api`, gere o app em `apps/web` (o `.gitkeep` que veio do template pode + ser removido junto) e **confira `apps/api/`**: ela vem do template com um + `README.md` de uma linha dizendo que está reservada para uma API própria, + se um dia existir — crie-a assim se faltar. **Não gere backend nenhum** — nem scaffold, nem `package.json`, nem dependência. Pasta reservada é lugar guardado; scaffold morto é código que ninguém mantém e que o agente lê como se existisse. @@ -114,7 +118,7 @@ do guia é exatamente como o Portão nasce parafraseado e sem efeito. ``` gh api -X PUT repos/{owner}/{repo}/branches/main/protection --input - <<'JSON' { - "required_status_checks": null, + "required_status_checks": { "strict": false, "checks": [ { "context": "explicacao" } ] }, "enforce_admins": true, "required_pull_request_reviews": { "required_approving_review_count": 1 }, "restrictions": null, @@ -127,7 +131,10 @@ do guia é exatamente como o Portão nasce parafraseado e sem efeito. `required_approving_review_count: 1` exige **Pull Request aprovado por um colega** — nesta disciplina o projeto é em equipe (2–3), e a revisão entre colegas com resolução de conflitos é cobrada pelo ID27: quem abre a story - não mergeia o próprio PR. `enforce_admins: true` faz a regra valer também para o + não mergeia o próprio PR. O bloco `required_status_checks` exige que o check + `explicacao` (o job do Portão de Entendimento) **passe antes do merge** — sem + ele, o Portão reprovaria mas não bloquearia nada. + `enforce_admins: true` faz a regra valer também para o dono do repositório: sem isso, o aluno é justamente quem fura a regra sem perceber. Para destravar uma emergência ele desliga a proteção conscientemente, e isso fica registrado no log do repositório. diff --git a/.agents/workflows/tutor.md b/.agents/workflows/tutor.md index 9ee0da7..67c86b9 100644 --- a/.agents/workflows/tutor.md +++ b/.agents/workflows/tutor.md @@ -26,7 +26,7 @@ Sem argumento, pergunte ao usuário qual modo ele quer. 3. Conforme o modo, acrescente: - **`depois`**: número e texto literal da tarefa, e o comando de diff. Encontre o commit da tarefa com `git log --oneline --grep "tarefa "` (convenção de commit do ciclo-tarefa) e monte `git diff ^..`. Se a tarefa tiver mais de um commit ou o commit não for encontrado, monte o intervalo à mão e confirme com o usuário antes de despachar. - **`antes`**: número e texto literal da tarefa, e os critérios de aceite ligados a ela, transcritos. - - **`prova`**: o comando do diff completo da branch: `git diff main..HEAD`. + - **`prova`**: o comando do diff completo da branch: `git diff develop..HEAD` (no Gitflow a feature branch nasce da `develop` — diff contra a `main` traria trabalho de outras histórias já integradas). ## Entregar diff --git a/.agents/workflows/utf-workflow.md b/.agents/workflows/utf-workflow.md index 42b8ac0..8099810 100644 --- a/.agents/workflows/utf-workflow.md +++ b/.agents/workflows/utf-workflow.md @@ -13,7 +13,8 @@ Sempre que o usuário pedir para trabalhar em uma Issue (Feature), você atuará **Passo 1: Entendimento e Brainstorming** - Leia a Issue apontada e busque no `docs/prd.md` os critérios e o Glossário Ubíquo. - Faça perguntas ao usuário de forma proativa. Questione sobre casos de borda, caminhos tristes (ex: falhas de rede, dados inválidos) e como validar os critérios de aceite. -- Após sanar as dúvidas, redija o documento e salve no caminho `specs/-/spec.md`, com este frontmatter: +- Após sanar as dúvidas, **crie a branch da história a partir da `develop`** (`git switch develop && git pull && git switch -c -`). Ela nasce agora, antes da aprovação, porque no Gitflow `main` e `develop` são bloqueadas — e o commit de aprovação do usuário precisa de um lugar para viver. +- Redija o documento e salve no caminho `specs/-/spec.md`, commitando o rascunho na branch, com este frontmatter: ```yaml --- @@ -22,17 +23,17 @@ status: rascunho # rascunho | aprovada --- ``` -- **PAUSA OBRIGATÓRIA:** Pare de gerar respostas e exija que o usuário leia e aprove o `spec.md`. Ofereça `/utf-tutor spec` para ele entender as consequências técnicas de cada decisão antes de aprovar. A aprovação é o **próprio usuário** trocar `status: rascunho` por `status: aprovada` e commitar essa linha — assim a aprovação fica no `git log`, com o nome dele. Você não altera esse campo em hipótese nenhuma. +- **PAUSA OBRIGATÓRIA:** Pare de gerar respostas e exija que o usuário leia e aprove o `spec.md`. Ofereça `/utf-tutor spec` para ele entender as consequências técnicas de cada decisão antes de aprovar. A aprovação é o **próprio usuário** trocar `status: rascunho` por `status: aprovada` e commitar essa linha **na branch da história** — assim a aprovação fica no `git log`, com o nome dele. Você não altera esse campo em hipótese nenhuma. **Passo 2: Planejamento** -- Com o `spec.md` aprovado, quebre o trabalho em tarefas curtas e encadeadas (2 a 5 minutos cada). +- Com o `spec.md` aprovado, quebre o trabalho em tarefas curtas e encadeadas — cada uma prova **um critério de aceite inteiro**, ou é um passo técnico que sozinho não prova nada mas destrava o próximo. - Cada tarefa deve prever a criação de testes primeiro (TDD). - Se o plano passar de **10 tarefas**, pare: a história é grande demais. Proponha dividi-la em duas Issues antes de continuar. - Salve o resultado no caminho `specs/-/plan.md`. -- **PAUSA OBRIGATÓRIA:** Peça a aprovação do usuário para o plano. +- **PAUSA OBRIGATÓRIA:** Peça a aprovação do usuário para o plano. Com o OK, commite o `plan.md` na branch da história. **Passo 3: Execução (uma tarefa por vez)** -- Crie a branch da Issue a partir da `develop` (Gitflow — ver a ficha). +- A branch da história existe desde o Passo 1. Antes do primeiro código, confira que o `spec.md` (aprovado) e o `plan.md` estão commitados nela — é esse `git log` que prova que a especificação veio antes do código. - Execute **uma tarefa por vez** através do fluxo `ciclo-tarefa` (`.agents/workflows/ciclo-tarefa.md`), que despacha o subagente **implementador** com contexto limpo e, depois dele, dois revisores distintos e somente-leitura: **revisor-conformidade** (diff × critérios de aceite da `spec.md`) e **revisor-codigo** (diff × `docs/architecture.md`). - **Você nunca revisa o código que você mesmo despachou.** Revisor é sempre outro agente, sem permissão de escrita. Auto-auditoria não conta como revisão: quem escreveu carrega os mesmos pontos cegos. - Ao fim de cada tarefa, pare e devolva o controle ao usuário. Ele pede a próxima. diff --git a/.claude/commands/utf-tutor.md b/.claude/commands/utf-tutor.md index d1dbafa..2ccbfac 100644 --- a/.claude/commands/utf-tutor.md +++ b/.claude/commands/utf-tutor.md @@ -5,4 +5,4 @@ argument-hint: | spec | prova> Leia `.agents/workflows/tutor.md` e execute-o integralmente. -Argumento: $1 +Argumento: $ARGUMENTS diff --git a/.github/workflows/portao-de-entendimento.yml b/.github/workflows/portao-de-entendimento.yml index 0b8c169..10582a7 100644 --- a/.github/workflows/portao-de-entendimento.yml +++ b/.github/workflows/portao-de-entendimento.yml @@ -15,7 +15,8 @@ jobs: TEXTO=$(printf '%s' "$CORPO" \ | sed -n '/O que este PR faz e por quê/,$p' \ | tail -n +2 \ - | sed '/^##/,$d') + | sed '/^##/,$d' \ + | perl -0pe 's///gs') TAMANHO=$(printf '%s' "$TEXTO" | tr -d '[:space:]' | wc -c) echo "Caracteres na explicação: $TAMANHO (mínimo 400)" if [ "$TAMANHO" -lt 400 ]; then diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0bea89..25437ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,7 +64,7 @@ Se o Pull Request for a primeira vez que você olha o código, o método falhou. **O PR será REPROVADO se:** 1. Não atualizar nenhum arquivo em `docs/` ou `specs/`. -2. A descrição não contiver a seção _"O que este PR faz e por quê"_ preenchida por você com pelo menos 200 caracteres (Não cole o _diff_ nem a saída da IA; explique com suas palavras). +2. A descrição não contiver a seção _"O que este PR faz e por quê"_ preenchida por você com pelo menos 400 caracteres (Não cole o _diff_ nem a saída da IA; explique com suas palavras). **Exceção (Manutenção puramente técnica):** Se a mudança não afeta o produto (ex: atualizar versão, refatorar código, arrumar formatação), você não precisa criar um `spec.md`. Abra o PR direto e aplique a etiqueta `manutencao`. diff --git a/apps/api/README.md b/apps/api/README.md new file mode 100644 index 0000000..d3eb46b --- /dev/null +++ b/apps/api/README.md @@ -0,0 +1 @@ +Reservada para uma API própria, se um dia existir — o `/utf-setup` não gera nada aqui (ver `docs/architecture.md` §3). diff --git a/apps/web/.gitkeep b/apps/web/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture.md b/docs/architecture.md index bba6eec..3b905d6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -24,7 +24,7 @@ | Fonte | Onde configurar | Serve para | | :---- | :-------------- | :--------- | | Constituição da IA | `.agents/rules/utf-rules.md` (via `CLAUDE.md`) | Regras inegociáveis: fases do SDD, 2 rodadas, revisores distintos, Gitflow | -| Fluxos da IA | `.agents/workflows/` | PRD, flows, architecture, setup, ciclo por Issue, ciclo por tarefa, tutor | +| Fluxos da IA | `.agents/workflows/` | PRD, backlog, design, architecture, setup, ciclo por Issue, ciclo por tarefa, tutor | | Agentes (subagentes) | `.agents/agents/` (cascas em `.claude/`, `.cursor/`, `.opencode/`) | Implementador, revisores, auditor final e tutor | | Ficha da disciplina | `docs/checklist.md` | Regras do projeto, IDs e entregas | | Protótipo (Stitch/Figma) | [link público] | Telas, jornadas e hierarquia visual (ID1) | diff --git a/docs/design-tokens.md b/docs/design-tokens.md index 10c4045..dfada83 100644 --- a/docs/design-tokens.md +++ b/docs/design-tokens.md @@ -49,6 +49,30 @@ Uma progressão só, usada em tudo. | desabilitado | | | carregando | | +## Breakpoints (Mobile-First) + +O design nasce para a menor tela e cresce (ID2). Toda tela do protótipo tem +versão mobile antes da versão desktop. + +| Token | Largura mínima | Vale para | +| --- | --- | --- | +| `sm` | | | +| `md` | | | +| `lg` | | | + +## Identidade PWA + +Os valores abaixo alimentam o `manifest.webmanifest` no `/utf-setup` (ID3). + +| Campo | Valor | +| --- | --- | +| Nome curto (`short_name`) | | +| Cor de tema (`theme_color`) | | +| Cor de fundo (`background_color`) | | +| Ícone | | +| Modo de exibição (`display`) | `standalone` | +| Comportamento visual offline | [o que a pessoa vê sem rede] | + ## Protótipo **Link:** [Figma / Stitch / equivalente] diff --git a/docs/guia-sdd.md b/docs/guia-sdd.md index adc13e1..71353c1 100644 --- a/docs/guia-sdd.md +++ b/docs/guia-sdd.md @@ -370,7 +370,17 @@ Você conversa com o agente sobre a história. Um bom agente vai fazer perguntas escrever qualquer coisa: o que acontece se a carona lotar enquanto a pessoa preenche? Ela pode solicitar duas vezes a mesma carona? O motorista precisa aprovar? -Dessa conversa sai o `spec.md`, em `specs/-/`, contendo: +Antes de salvar qualquer coisa, o agente cria a **branch da história** — a partir da +`develop`, porque no Gitflow as duas branches permanentes são bloqueadas e todo commit +deste ciclo (inclusive o da sua aprovação, no Passo 3) precisa de um lugar para viver: + +```bash +git switch develop && git pull +git switch -c 27-solicitar-vaga +``` + +Dessa conversa sai o `spec.md`, em `specs/-/`, commitado como +rascunho na branch, contendo: ```yaml --- @@ -411,7 +421,10 @@ que você define o que conta como "certo" — e tudo depois disso obedece a essa A aprovação tem uma forma concreta, e é só ela que vale: > **Você — não o agente — troca `status: rascunho` por `status: aprovada` e faz um -> commit dessa linha.** +> commit dessa linha, na branch da história.** + +É por isso que a branch nasce no Passo 2, antes da aprovação: `main` e `develop` são +bloqueadas, e este commit — que é **seu** — precisa de um lugar para viver. Isso não é cerimônia. É o que dá **data, autor e diff** para a decisão mais importante do ciclo. Sem esse commit, no fim do semestre não existe nenhuma diferença observável @@ -422,7 +435,7 @@ circunstância. Se você aprovar sem ler, perdeu a disciplina. Todo o resto do ciclo vai construir, com perfeição, uma ideia errada. -### Passo 4 — Do plano à branch +### Passo 4 — O plano entra na branch Aprovada a spec, o agente deriva o `plan.md`: decisões técnicas (componentes, Services, rotas e modelos afetados) e as tarefas em ordem. @@ -447,23 +460,22 @@ você usa a palavra "e" duas vezes, são duas tarefas. **PAUSA OBRIGATÓRIA:** peça a aprovação do plano. -Aprovado, **crie a branch a partir da `main`** e faça o primeiro commit: +Aprovado, o plano entra na **branch da história** — a mesma que existe desde o Passo 2: ```bash -git switch main && git pull -git switch -c 27-solicitar-vaga -git add specs/027-solicitar-vaga/ -git commit -m "spec: solicitar vaga na carona (#27)" +git add specs/27-solicitar-vaga/plan.md +git commit -m "plan: solicitar vaga na carona (#27)" ``` -> **Por que a spec e o plano são o primeiro commit da branch.** Porque é isso que prova -> que a especificação veio antes do código. Se eles forem commitados junto com a -> implementação, no fim, o `git log` não sustenta a afirmação central do método — e é o -> `git log` que você vai mostrar na defesa. Dois minutos aqui economizam uma discussão -> inteira depois. +> **Por que a spec e o plano entram na branch antes de qualquer código.** Porque é isso +> que prova que a especificação veio antes do código. O `git log` da branch conta a +> história na ordem: rascunho da spec → aprovação (um commit **seu**) → plano → só então +> implementação. Se tudo fosse commitado junto no fim, o log não sustentaria a afirmação +> central do método — e é o `git log` que você vai mostrar na defesa. Dois minutos aqui +> economizam uma discussão inteira depois. -> **A `main` é bloqueada.** Nenhum commit vai direto para ela. Toda implementação nasce -> em branch própria e entra por Pull Request. +> **A `main` e a `develop` são bloqueadas.** Nenhum commit vai direto para elas. Toda +> implementação nasce em branch própria a partir da `develop` e entra por Pull Request. ### Passo 5 — Execução, tarefa por tarefa @@ -488,7 +500,7 @@ quem conduz o ciclo é um **orquestrador**, que não implementa e não revisa: #### Os pareceres vão para o disco ``` -specs/027-solicitar-vaga/reviews/ +specs/27-solicitar-vaga/reviews/ ├── tarefa-03-conformidade-r1.md ├── tarefa-03-codigo-r1.md ├── tarefa-03-decisoes-r1.md ← sua triagem: aceitos e recusados, com motivo @@ -593,8 +605,9 @@ No corpo do PR vão os **apontamentos aceitos e recusados**, com o motivo de cad Eles estão em `specs//reviews/` — você não precisa lembrar de nada. O merge acontece depois que o Portão de Entendimento (§9) passa. **Você não mescla o -próprio PR sem que ele tenha passado**; a `main` é protegida justamente para que essa -regra não dependa da sua disciplina no dia. +próprio PR sem que ele tenha passado**; a `develop` (destino do PR de história) e a +`main` são protegidas justamente para que essa regra não dependa da sua disciplina no +dia. ### Quando o ciclo não é linear @@ -681,7 +694,7 @@ primeira. Aí você tem duas saídas: 2. **Pause a Issue atual.** Mova o card para *Blocked* no GitHub Projects. 3. **Rode o ciclo SDD completo na história bloqueadora** — ela tem spec e PR próprios, porque é uma história de verdade. -4. Com o código dela na `main`, **volte para a Issue bloqueada**. +4. Com o código dela na `develop`, **volte para a Issue bloqueada**. **O que é "seguir com substituto".** É fazer o código funcionar com uma peça de mentira, no lugar da peça que ainda não existe. @@ -784,8 +797,8 @@ Com quinze pastas em `specs/`, ninguém sabe o que está vivo. Mantenha um | Issue | Spec | Estado | Observação | | --- | --- | --- | --- | -| #12 | `012-concluir-carona` | implementada | — | -| #27 | `027-solicitar-vaga` | bloqueada | espera #31 | +| #12 | `12-concluir-carona` | implementada | — | +| #27 | `27-solicitar-vaga` | bloqueada | espera #31 | | #31 | `031-vaga-concorrente` | aberta | descoberta durante #27 | --- @@ -795,12 +808,12 @@ Com quinze pastas em `specs/`, ninguém sabe o que está vivo. Mantenha um ```mermaid flowchart TD A["Issue no GitHub Projects"] --> B["Conversa com a IA
perguntas antes do código"] - B --> C["spec.md
status: rascunho"] + B --> F["Branch a partir da develop
spec e plano antes do código"] + F --> C["spec.md
status: rascunho"] C --> D{"🚪 Você lê e aprova
commit trocando para aprovada"} D -->|"ajustar"| B D -->|"aprovada"| E["plan.md
todo critério vira tarefa"] - E --> F["Branch a partir da main
spec e plano no 1º commit"] - F --> T["Tutor explica a tarefa
bem mastigado, antes do código"] + E --> T["Tutor explica a tarefa
bem mastigado, antes do código"] T --> U{"🚪 Você aceita?"} U -->|"dúvidas"| T U -->|"aceito"| G["Implementador novo
uma tarefa — TDD"] @@ -815,7 +828,7 @@ flowchart TD L --> M{"🚪 Você lê, escreve
e abre o PR"} M --> N["Portão de Entendimento"] N -->|"reprovado"| M - N -->|"aprovado"| O["Merge na main"] + N -->|"aprovado"| O["Merge na develop
(release: PR develop → main)"] style I fill:#ffe0e0,stroke:#c62828 ``` @@ -902,7 +915,7 @@ uma. **1. Regras sempre ativas.** Um arquivo carregado em toda mensagem, com as regras inegociáveis do projeto: não codificar antes da spec aprovada, TDD obrigatório, a `main` -é bloqueada, os nomes vêm do glossário. Sem isso, você repete as mesmas instruções todo +e a `develop` são bloqueadas, os nomes vêm do glossário. Sem isso, você repete as mesmas instruções todo dia e o agente esquece na terceira mensagem. **2. Um comando de fluxo.** Um arquivo de instruções que você dispara com uma linha — @@ -965,7 +978,7 @@ Não existe arquivo de estado, e não se pergunta ao agente em que rodada ele es perde a conta. A contagem **é** a listagem do diretório: ```bash -ls specs/027-solicitar-vaga/reviews/tarefa-03-* +ls specs/27-solicitar-vaga/reviews/tarefa-03-* ``` Nenhum arquivo → rodada 1. Um par de arquivos `-r1` → você está na rodada 2. Um par @@ -1190,7 +1203,8 @@ Você não escreve nem altera nenhum arquivo. Aponta; não corrige. Salve como `.github/workflows/portao-de-entendimento.yml`. São vinte linhas e não há nada escondido nelas: o passo recorta o texto entre o título da seção e o próximo título, -conta os caracteres que não são espaço, e reprova se for pouco. +descarta os comentários HTML herdados do modelo de PR (para eles não contarem como +explicação), conta os caracteres que não são espaço, e reprova se for pouco. ```yaml name: Portão de Entendimento @@ -1210,7 +1224,8 @@ jobs: TEXTO=$(printf '%s' "$CORPO" \ | sed -n '/O que este PR faz e por quê/,$p' \ | tail -n +2 \ - | sed '/^##/,$d') + | sed '/^##/,$d' \ + | perl -0pe 's///gs') TAMANHO=$(printf '%s' "$TEXTO" | tr -d '[:space:]' | wc -c) echo "Caracteres na explicação: $TAMANHO (mínimo 400)" if [ "$TAMANHO" -lt 400 ]; then diff --git a/docs/prd.md b/docs/prd.md index 3ff144d..c63523e 100644 --- a/docs/prd.md +++ b/docs/prd.md @@ -37,7 +37,8 @@ ## 👤 3. Atores e Permissões -> ⚠️ A coluna **"Não pode"** vira Guard e controle de role na API. +> ⚠️ A coluna **"Não pode"** vira Guard na rota e regra de acesso no BaaS +> (ex.: RLS no Supabase). | Ator | Quem é | Pode | Não pode | | :--- | :----- | :--- | :------- | @@ -53,7 +54,9 @@ > entram se sobrar tempo, mas ficam documentadas — nada se perde; o > `Won't Have` vira item da seção *Fora de Escopo* — e **Tamanho (esforço)** — > `S` cabe numa sessão, `M` vira algumas tarefas no plano, `L` pede divisão. -> Toda story nasce `Draft` — **só você promove a `Ready`**. +> O status percorre `Draft` → `Ready` → `Live`: toda story nasce `Draft` — +> **só você promove a `Ready`** — e vira `Live` quando o PR dela é mesclado +> (o auditor final cobra essa atualização; o commit é seu). ### US01 — [título] · `Must|Should|Could Have` · `S|M|L` · Status: `Draft` diff --git a/docs/tutorial-sdd.md b/docs/tutorial-sdd.md index 1c6e1d2..76ad371 100644 --- a/docs/tutorial-sdd.md +++ b/docs/tutorial-sdd.md @@ -14,7 +14,7 @@ Git e de PR estão no [CONTRIBUTING](../CONTRIBUTING.md). ## Fase 0 — Iniciar o projeto (uma vez por projeto) -Quatro comandos, nesta ordem, cada um fechando num portão seu: +Cinco comandos, nesta ordem, cada um fechando num portão seu: | # | Comando | O que sai | 🚪 Você faz o quê | | --- | --- | --- | --- | @@ -45,8 +45,9 @@ pode rodar de novo mais tarde, a cada leva de stories promovidas a `Ready`. ``` O agente vira orquestrador: lê a Issue e o PRD e **faz perguntas** sobre casos de -borda e caminhos tristes (brainstorming). Da conversa sai -`specs/012-/spec.md` com `status: rascunho` — e ele **para**. +borda e caminhos tristes (brainstorming). Ele cria a branch da história a partir +da `develop` (Gitflow) e da conversa sai +`specs/12-/spec.md` com `status: rascunho`, commitado na branch — e ele **para**. ## Passo 2 — 🚪 Aprovar a spec (fora do chat) @@ -54,14 +55,15 @@ Leia o arquivo **inteiro**. Em dúvida sobre alguma decisão técnica, rode `/utf-tutor spec` antes. A aprovação é **você** trocar `status: rascunho` por `status: aprovada` no -frontmatter e **commitar essa linha** — ela fica no `git log`, com o seu nome. -Nenhum agente altera esse campo. +frontmatter e **commitar essa linha na branch da história** — ela fica no +`git log`, com o seu nome. Nenhum agente altera esse campo. ## Passo 3 — Aprovar o plano -Avise que aprovou; o agente gera o `plan.md` (tarefas de 2–5 minutos — mais de -10, a história é grande demais e ele propõe dividir). Você lê, dá o OK na -conversa, e ele cria a branch a partir da `develop` (Gitflow). +Avise que aprovou; o agente gera o `plan.md` (uma tarefa por critério de aceite, +ou um passo técnico que destrava o próximo — mais de 10, a história é grande +demais e ele propõe dividir). Você lê, dá o OK na conversa, e ele commita o +plano na branch da história (criada no Passo 1). ## Passo 4 — Implementar, uma tarefa por vez