Artigo 4 de 12
Kiro & AWS

Como desenvolvedores usam o Kiro no dia a dia (fluxo completo com código)

Um passeio honesto pela rotina de quem programa com um agente sem virar revisor de caixa-preta: spec, waves, bugfix, vibe mode e hooks — com o código de verdade.

11 de julho de 2026 · Prompt & Deploy

TL;DR

  • Spec-driven development mantém a intenção dentro do repositório: requirements.md (EARS) → design.mdtasks.md. Você aprova cada fase antes de gerar código.
  • Run all Tasks monta um grafo de dependências e agrupa tarefas independentes em waves — paralelismo com ordem garantida.
  • Bugfix specs geram um bugfix.md com current / expected / unchanged, o contrato que evita regressão.
  • Vibe mode é para exploração rápida e protótipo; spec é para o que é complexo, caro de regredir ou precisa virar documentação do time.
  • Hooks (ex.: PostFileSave com action.type: "agent") automatizam o chato — como manter o teste sincronizado com o componente.

O medo de virar revisor de caixa-preta

Todo dev que já colou 300 linhas geradas por IA num PR conhece a sensação: você não escreveu aquilo, não acompanhou o raciocínio, e agora precisa aprovar. Você virou revisor de uma caixa-preta que você mesmo pediu. Se der ruim em produção, a culpa é sua — mas o entendimento nunca foi seu.

O problema não é a IA escrever código. É a IA escrever código sem deixar rastro do porquê. Quando a intenção vive só no chat efêmero, ela evapora. O próximo dev (ou você daqui a três semanas) herda o resultado sem o contexto.

O Kiro parte de uma premissa diferente: a intenção precisa morar no repositório, versionada junto com o código, revisável em diff. É o que ele chama de spec-driven development — e é isso que mantém o dev no controle. Você não aprova um blob de código; você aprova requisitos, depois um design, depois um plano de tarefas. Cada porta tem um gate. Este artigo mostra o fluxo real, com os arquivos que ele gera e os comandos que você usa.

A diferença entre “vibe coding” e trabalhar com specs é a diferença entre aprovar código que você não entende e aprovar decisões que você tomou.

Uma feature do zero com spec

Digamos que você precise de um sistema de avaliações de produtos. Em vez de pedir “faz um CRUD de reviews”, você inicia uma spec. O Kiro cria uma pasta em .kiro/specs/<nome-da-spec>/ e conduz um fluxo de três fases: Requirements → Design → Tasks. Cada fase é um artefato de texto que você lê, edita e aprova.

Fase 1 — requirements.md (notação EARS)

A primeira fase produz user stories com critérios de aceitação em EARS (Easy Approach to Requirements Syntax). EARS força cada requisito a ter um gatilho explícito (WHEN, IF, WHILE, WHERE), o que remove a ambiguidade que normalmente só aparece na hora do bug.

# Requisitos — Sistema de Avaliações de Produtos

## User Story 1: Criar avaliação
Como cliente autenticado, quero avaliar um produto que comprei,
para ajudar outros compradores.

### Critérios de aceitação (EARS)
- WHEN um cliente autenticado envia uma avaliação com nota de 1 a 5,
  THE SYSTEM SHALL persistir a avaliação e associá-la ao produto e ao usuário.
- IF o usuário não comprou o produto,
  THEN THE SYSTEM SHALL rejeitar a avaliação com HTTP 403.
- WHILE o texto da avaliação exceder 2.000 caracteres,
  THE SYSTEM SHALL bloquear o envio e exibir mensagem de validação.
- WHERE a avaliação contém linguagem sinalizada pelo filtro,
  THE SYSTEM SHALL marcá-la como "pendente de moderação".

Repare que aqui você já está decidindo comportamento: 403 para quem não comprou, moderação para conteúdo sinalizado. É onde você quer gastar seu cérebro — não revisando if (!user) return.

Fase 2 — design.md

Aprovados os requisitos, o Kiro propõe a arquitetura: diagramas de sequência, fluxo de dados, tratamento de erros, estratégia de testes e modelo de dados. É o momento de discordar antes de existir uma linha de código.

## Arquitetura

```mermaid
sequenceDiagram
    participant U as Cliente
    participant API as Review API
    participant DB as PostgreSQL
    U->>API: POST /products/{id}/reviews
    API->>DB: verifica compra (orders)
    DB-->>API: compra confirmada
    API->>DB: INSERT review (status=published)
    API-->>U: 201 Created

Modelo de dados

CampoTipoNota
iduuidPK
product_iduuidFK products
user_iduuidFK users
ratingint1..5
bodytext<= 2000 chars
statusenumpublished | pending | rejected

```mermaid
flowchart LR
    D["🏗️ design.md<br/>em revisão"] --> A["Arquitetura"]
    D --> S["Diagrama de sequência"]
    D --> M["Modelo de dados"]
    D --> T["Estratégia de testes"]

Fase 3 — tasks.md

Só então vem o plano de implementação: tarefas discretas, rastreáveis, cada uma ligada a um requisito. Você pode rodar uma tarefa por vez ou disparar todas.

# Plano de implementação

- [ ] 1. Criar migration da tabela reviews (Req 1)
- [ ] 2. Implementar ReviewRepository com verificação de compra (Req 1)
  - [ ] 2.1 Testes unitários do repositório
- [ ] 3. Endpoint POST /products/{id}/reviews (Req 1)
  - [ ] 3.1 Teste de integração (403 sem compra)
- [ ] 4. Filtro de moderação (Req 1 - WHERE)

O ganho prático: quando o Kiro implementa a tarefa 3, você não revisa um monólito. Você revisa o diff daquela tarefa contra o critério de aceitação que você aprovou na fase 1. A rastreabilidade (Req 1) no fim de cada linha não é decoração — é o fio que liga o código à decisão. Auditar um diff assim é revisar uma decisão sua, não uma caixa-preta.

Vale notar as variantes: Feature Specs vêm em modo Requirements-First ou Design-First, e existe o Quick Plan, que gera os três artefatos de uma vez, sem os approval gates — útil quando você já sabe o que quer e só precisa do esqueleto. E, importante: as specs ficam sincronizadas com o código conforme ele evolui, então não viram documentação morta.

Rodando tarefas em paralelo (waves)

O tasks.md acima tem dependências implícitas: não dá para escrever o endpoint (tarefa 3) antes do repositório (tarefa 2), que por sua vez depende da migration (tarefa 1). Mas a tarefa 4 (filtro de moderação) talvez não dependa de nenhuma delas.

Quando você aciona “Run all Tasks”, o Kiro constrói um grafo de dependências entre as tarefas e agrupa as independentes em waves:

  • Wave 1 = todas as tarefas sem dependências. Rodam em paralelo.
  • Wave 2 = tarefas cujas dependências foram satisfeitas na Wave 1.
  • E assim por diante, até o grafo esvaziar.

Pense no grafo assim: cada aresta é um “precisa de”. A Wave 1 são os nós sem aresta de entrada; conforme eles concluem, liberam os nós seguintes. É topological sort aplicado ao seu plano de implementação — você ganha paralelismo sem perder a ordem correta. Na prática, migration e filtro de moderação podem sair juntos, enquanto repositório e endpoint esperam suas dependências, tudo sem você orquestrar nada à mão.

Waves são o oposto de “roda tudo e reza”: o paralelismo respeita o grafo, então a ordem que importa é preservada e o resto acelera.

Bugfix specs: corrigir sem regredir

Feature nova é um caso. Bug em código que já roda em produção é outro — e é onde o medo de regressão é legítimo. Para isso o Kiro tem Bugfix Specs, que trocam a fase de requisitos por uma Bug Analysis e geram um bugfix.md estruturado em torno de três seções:

  • current — o comportamento atual, errado. O que acontece hoje.
  • expected — o comportamento correto que você espera depois do fix.
  • unchanged — o que não pode mudar. Este é o contrato anti-regressão.
# Bugfix — Avaliação duplicada ao reenviar formulário

## current
Ao clicar duas vezes em "Enviar", o endpoint POST /products/{id}/reviews
cria duas avaliações idênticas para o mesmo par (user_id, product_id).

## expected
A segunda submissão idêntica deve ser idempotente: retornar 200 com a
avaliação já existente, sem criar um novo registro.

## unchanged
- O fluxo de moderação (status=pending para conteúdo sinalizado) continua igual.
- A regra de 403 para quem não comprou o produto não muda.
- O formato da resposta 201 na primeira submissão permanece idêntico.

A seção unchanged é o que faz a diferença. Ela é a lista explícita do que o agente não tem permissão de tocar — e vira a base natural dos testes que provam que nada mais quebrou. Você corrige a duplicação sem descobrir, dias depois, que o filtro de moderação parou de funcionar de tabela.

Vibe mode para tarefas pontuais (e quando NÃO usar spec)

Nem tudo merece três fases de aprovação. Se você está explorando uma API que nunca usou, montando um protótipo descartável ou fazendo um ajuste de uma linha, spec é burocracia. Para isso existe o vibe mode: você conversa, o agente faz, você itera. Direto.

A regra prática que uso:

SituaçãoUse SpecUse Vibe
Feature complexa, várias tarefas
Bug onde regressão sai caro
Precisa virar documentação para o time
Requisitos/design que vão iterar
Exploração rápida de uma lib
Protótipo sem meta clara
Ajuste pontual de baixo risco

O erro comum é o inverso dos dois: usar vibe numa feature crítica (e depois herdar a caixa-preta) ou abrir uma spec de três fases para renomear uma variável (e afogar em cerimônia). Escolha pela complexidade e pelo custo do erro, não por hábito.

Spec não é sobre burocracia; é sobre onde o custo de errar é alto. Vibe não é sobre pressa; é sobre onde errar é barato e reversível.

Testes automáticos com hooks

Uma das coisas que mais quebra na correria é o teste ficar defasado do código. Você mexe no componente, esquece do .test.tsx, e o CI só reclama depois. Hooks resolvem isso automatizando reações a eventos do editor.

Um hook vive em .kiro/hooks/*.json (workspace) ou ~/.kiro/hooks/ (usuário). Ele tem um trigger (o evento), um matcher (regex que filtra por nome de tool ou caminho de arquivo) e uma action. A action pode ser um comando shell (type: "command") ou — o que interessa aqui — um prompt de agente (type: "agent").

O exemplo abaixo dispara sempre que o agente salva um componente em src/components/ e pede para o próprio Kiro atualizar o teste correspondente:

{
  "version": "v1",
  "hooks": [
    {
      "name": "sync-tests",
      "trigger": "PostFileSave",
      "matcher": "src/components/.*\\.tsx$",
      "action": {
        "type": "agent",
        "prompt": "O componente foi alterado. Atualize o arquivo de teste correspondente (.test.tsx) cobrindo os novos casos e mantendo os existentes."
      }
    }
  ]
}

A diferença entre uma action de comando e uma de agente é importante: command roda um script determinístico (rápido, previsível); agent delega o raciocínio ao Kiro (flexível, entende o que mudou). Para “rodar o linter”, comando basta. Para “atualizar os testes cobrindo os novos casos”, você precisa de um agente.

Se o que você quer é apenas garantir que o lint rode a cada save de .ts, o hook fica assim — note o timeout e o enabled:

{
  "version": "v1",
  "hooks": [
    {
      "name": "lint-on-save",
      "description": "Roda o linter quando um .ts é salvo pelo agente",
      "trigger": "PostFileSave",
      "matcher": "\\.ts$",
      "action": { "type": "command", "command": "npm run lint" },
      "timeout": 30,
      "enabled": true
    }
  ]
}

Vale conhecer o leque de triggers, porque alguns bloqueiam a ação enquanto outros só reagem depois: SessionStart, Stop, PreToolUse (bloqueia), PostToolUse, PreTaskExec (bloqueia), PostTaskExec, UserPromptSubmit (bloqueia), PostFileCreate, PostFileSave, PostFileDelete. Nos triggers que bloqueiam, uma action de comando que sai com exit code 2 interrompe a operação e devolve o STDERR ao agente — é assim que você monta, por exemplo, um scanner de segredos que veta um commit antes de ele acontecer.

Um dia típico

Para aterrissar tudo isso, aqui vai uma rotina concreta de um dia trabalhando com o Kiro:

  1. Manhã — feature nova. Abro uma spec para o recurso da sprint. Passo 20 minutos revisando o requirements.md em EARS, corto dois critérios ambíguos, aprovo. Reviso o design.md, troco o cache de in-memory para Redis no diagrama, aprovo. O tasks.md sai com sete tarefas.
  2. Meio da manhã — waves. Aciono “Run all Tasks”. A Wave 1 roda migration e scaffolding em paralelo; enquanto isso, pego um café. Volto, audito os diffs tarefa por tarefa contra os critérios de aceitação. Duas tarefas eu aprovo direto; numa eu peço ajuste no tratamento de erro.
  3. Almoço — hooks trabalhando por mim. O hook sync-tests já atualizou os .test.tsx de cada componente que o agente tocou. O lint-on-save manteve o código limpo. Não precisei lembrar de nada disso.
  4. Tarde — um bug urgente. Chega um relato de avaliação duplicada. Abro uma bugfix spec, preencho current/expected/unchanged. A seção unchanged garante que o fix de idempotência não encoste na moderação nem na regra de 403. Reviso o diff, os testes de regressão passam, mergeio.
  5. Fim do dia — exploração. Quero testar uma lib de rate limiting que nunca usei. Nada de spec: entro em vibe mode, faço três perguntas, monto um protótipo de 40 linhas, confirmo que a lib serve. Amanhã, se for pra valer, isso vira uma spec.

O padrão que emerge: spec para o que importa, vibe para o que é barato, hooks para o que é repetitivo. Em nenhum momento eu aprovei código que não entendia — aprovei decisões, diffs pequenos e contratos explícitos.

Principais aprendizados

  • A intenção mora no repositório. Specs versionam requisitos, design e plano junto com o código — o contexto não evapora com o chat.
  • Você aprova decisões, não caixas-pretas. Os três gates (requirements → design → tasks) e a rastreabilidade (Req N) fazem cada diff ser revisável contra algo que você decidiu.
  • Waves dão paralelismo com ordem. O grafo de dependências roda o que é independente em paralelo e respeita o que precisa esperar.
  • unchanged é seu contrato anti-regressão. Em bugfix specs, é a linha que o agente não pode cruzar.
  • Escolha spec vs. vibe pelo custo do erro, não por hábito.
  • Hooks tiram o trabalho chato do caminhotype: "agent" quando precisa de raciocínio, type: "command" quando basta um script.

Referências


Este artigo foi publicado originalmente no Medium. Preços, nomes de modelos e detalhes de produto refletem o estado do Kiro em meados de 2026 e podem mudar — confirme em kiro.dev antes de tomar decisões. Este é um conteúdo educacional independente, sem vínculo oficial com a AWS.

Tags: kiro, spec-driven-development, aws, produtividade, testes

Publicado originalmente em prompt.victorbatistax.com. Se você chegou por outra plataforma, esta é a versão canônica.