Artigo 2 de 12
Kiro & AWS

Kiro no dia a dia: specs, hooks e steering (guia prático com código)

Como transformar padrões de time e automação de repositório em artefatos versionados que o agente respeita — com YAML, JSON e uma rotina real de ponta a ponta.

09 de julho de 2026 · Prompt & Deploy

TL;DR

  • Steering (.kiro/steering/*.md) injeta convenções do projeto no agente. São arquivos Markdown com front matter YAML e 4 inclusion modes: always, fileMatch, manual e auto.
  • Hooks (.kiro/hooks/*.json) disparam automações por evento (PostFileSave, PreToolUse, etc.). A ação pode ser um command shell ou um prompt de agente.
  • Specs (.kiro/specs/<nome>/) estruturam a intenção em requirements.mddesign.mdtasks.md. É o assunto do artigo 1 desta série; aqui elas entram como o terceiro pilar da rotina.
  • O ganho real aparece na combinação dos três: a spec diz o que fazer, o steering diz como, e os hooks garantem que nada escape.
  • Armadilha número um: o front matter YAML precisa ser a primeira linha do arquivo, sem linha em branco antes. Se não for, o inclusion mode é ignorado.

O problema: padrões que ninguém segue e automação que ninguém dispara

Todo time tem um documento de convenções. Ele mora no Confluence, no README ou na cabeça do tech lead que entrou há três anos. E todo time sabe o que acontece na prática: o padrão é seguido nos dois primeiros dias depois do onboarding e depois vira folclore. Alguém usa any em TypeScript “só nesse caso”, outro esquece de rodar o linter, um terceiro escreve um endpoint sem o tratamento de erro que o time combinou. Não é má-fé — é atrito. Quanto mais longe o padrão está do momento em que o código é escrito, menor a chance de ele ser aplicado.

Com um agente de IA escrevendo código, esse problema não desaparece: ele escala. O agente não leu o Confluence. Ele vai gerar código idiomático genérico, não o código idiomático do seu projeto. Se você não disser que o banco é acessado via Prisma e que exceções nunca podem ser engolidas, ele vai adivinhar — e vai adivinhar de um jeito diferente a cada sessão.

O Kiro resolve isso movendo os padrões e a automação para dentro do repositório, como artefatos versionados que o agente lê automaticamente. Três mecanismos fazem esse trabalho: steering (as regras), hooks (os gatilhos) e specs (o plano). Este artigo é um guia prático dos três, com o YAML e o JSON reais que você vai colar no seu projeto.

Se o padrão não está a um arquivo de distância do código, ele não vai ser seguido — nem por humanos, nem por agentes.

Steering: ensinando as convenções do projeto ao agente

Steering são arquivos Markdown que ficam em .kiro/steering/ (no workspace) ou em ~/.kiro/steering/ (global, valendo para todos os seus projetos). Cada arquivo carrega um pedaço de contexto que o agente passa a tratar como verdade sobre o seu projeto.

Os arquivos fundacionais mais comuns são três, e vale a pena criá-los cedo:

  • product.md — o que o produto faz e para quem.
  • tech.md — stack, frameworks, convenções de código.
  • structure.md — organização de pastas e onde cada coisa mora.

Front matter e os 4 inclusion modes

O que torna o steering poderoso é o inclusion mode, declarado no front matter YAML no topo do arquivo. Ele controla quando aquele contexto é injetado. São quatro modos.

1. always — sempre incluído, em toda interação. Use para convenções universais do projeto.

---
inclusion: always
---

2. fileMatch — incluído só quando o arquivo em foco casa com um padrão glob. Ideal para regras específicas de uma camada (componentes, migrations, infra).

---
inclusion: fileMatch
fileMatchPattern: "components/**/*.tsx"
---

Precisa de mais de um padrão? Passe uma lista:

---
inclusion: fileMatch
fileMatchPattern: ["**/*.ts", "**/*.tsx"]
---

3. manual — só entra quando você chama explicitamente com #nome-do-arquivo no chat. Ele aparece como um slash command. Bom para checklists ou guias pesados que você não quer no contexto o tempo todo.

---
inclusion: manual
---

4. auto — o agente decide se o contexto é relevante, usando o name e a description que você fornece. É o modo mais inteligente para regras condicionais.

---
inclusion: auto
name: api-design
description: Padrões de design de API REST. Use ao criar ou modificar endpoints.
---

Um steering tech.md real

Teoria é fácil. Veja como fica um tech.md de verdade — curto, imperativo, sem enrolação. O agente lê isto e passa a escrever código no seu dialeto:

---
inclusion: always
---
# Stack e convenções

- Backend: Node.js 20 + TypeScript strict. Sem `any`.
- Framework HTTP: Fastify. Validação com zod.
- Banco: PostgreSQL via Prisma. Migrations versionadas.
- Testes: Vitest. Cobertura mínima 80% em `src/domain`.
- Erros: nunca engolir exceção; sempre logar com correlação (requestId).

Cinco linhas de bullets mudam radicalmente o output do agente. Sem esse arquivo, ele poderia gerar um endpoint com Express, validação manual e um catch vazio. Com ele, o código já nasce no padrão.

#[[file:...]] e AGENTS.md

Duas facilidades importantes fecham a seção:

  • Referência a arquivos vivos: dentro de um steering, você pode apontar para outro arquivo do repositório com a sintaxe #[[file:<caminho-relativo>]]. Por exemplo, #[[file:api/openapi.yaml]] traz o contrato de API atualizado para o contexto sem você copiar e colar. É uma referência viva: se o arquivo muda, o steering acompanha.

  • AGENTS.md: o Kiro suporta o padrão aberto agents.md. Esse arquivo é sempre incluído e não tem inclusion mode — é o denominador comum. Ele pode ficar na raiz do workspace ou em ~/.kiro/steering/. Se você já mantém um AGENTS.md para outras ferramentas, o Kiro o respeita sem configuração extra.

Hooks: automação disparada por evento

Se o steering é o o que fazer, os hooks são o faça isto quando acontecer aquilo. São arquivos JSON em .kiro/hooks/ (workspace) ou ~/.kiro/hooks/ (usuário). Cada hook liga um evento a uma ação.

Os campos são poucos e diretos:

CampoObrigatórioO que faz
namesimIdentificador do hook.
descriptionnãoTexto livre.
triggersimO evento que dispara (ver tabela abaixo).
matchernãoRegex que filtra por nome de tool ou por caminho de arquivo.
actionsim{type:"command", command:"..."} ou {type:"agent", prompt:"..."}.
timeoutnãoSegundos; default 60; 0 desliga. Ignorado para ações agent.
enablednãoDefault true.

Tabela de triggers

TriggerBloqueia?Quando dispara
SessionStartnãoInício da sessão.
StopnãoFim da resposta do agente.
PreToolUsesimAntes de o agente usar uma tool.
PostToolUsenãoDepois do uso de uma tool.
PreTaskExecsimAntes de executar uma task de spec.
PostTaskExecnãoDepois de executar uma task.
UserPromptSubmitsimAo enviar um prompt.
PostFileCreatenãoApós criar um arquivo.
PostFileSavenãoApós salvar um arquivo.
PostFileDeletenãoApós deletar um arquivo.

Os triggers marcados como “bloqueia” (Pre* e UserPromptSubmit) podem interromper a ação. É aí que entram os exit codes de uma ação command:

  • 0 — sucesso. Em SessionStart e UserPromptSubmit, o STDOUT é injetado no contexto do agente.
  • 2 — bloqueia a ação (só funciona nos triggers Pre*/UserPromptSubmit). O STDERR volta para o agente como explicação.
  • Qualquer outro — tratado como aviso; a execução continua.

Hook 1: lint on save (ação de comando)

O clássico: sempre que o agente salvar um arquivo .ts, roda o linter. O matcher é uma regex sobre o caminho, e timeout de 30 segundos evita travar a sessão se algo pendurar.

{
  "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
    }
  ]
}

Hook 2: sync-tests (ação de agente)

Este é mais interessante e mostra o poder da ação agent. Em vez de rodar um comando, ele dispara outro prompt de agente: quando um componente .tsx muda, o Kiro atualiza o arquivo de teste correspondente. Note que ações agent ignoram o timeout.

{
  "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 conceitual é enorme: o hook command executa algo determinístico; o hook agent delega uma tarefa cognitiva ao Kiro. Você automatiza não só a checagem, mas o próprio trabalho de manter os testes em dia.

Um hook command valida. Um hook agent trabalha. Escolher entre os dois é escolher entre um portão e um colega de par.

Specs: o plano que amarra tudo (recapitulando o artigo 1)

Cobri specs em profundidade no primeiro artigo desta série, então aqui vai o resumo funcional. Specs vivem em .kiro/specs/<nome-da-spec>/ e geram três arquivos, seguindo um fluxo de três fases: Requirements → Design → Tasks.

  • requirements.md — user stories com critérios de aceitação em notação EARS (WHEN... THE SYSTEM SHALL...).
  • design.md — arquitetura, diagramas de sequência, modelo de dados, estratégia de testes.
  • tasks.md — tarefas discretas e rastreáveis, que você roda uma a uma ou todas de uma vez.

O detalhe que importa para a rotina de hoje: ao rodar “Run all Tasks”, o Kiro monta um grafo de dependências e agrupa tarefas independentes em waves (Wave 1 = sem dependências), executando em paralelo o que pode ser paralelizado. E as specs ficam sincronizadas com o código conforme ele evolui. Use specs para features complexas e bugs onde regressão é cara; use o modo vibe para exploração rápida sem meta definida.

Mão na massa: os três pilares em uma rotina só

Vamos juntar tudo em um cenário real. Você vai adicionar um sistema de avaliações de produtos a uma API Node/TypeScript. Veja como os três mecanismos se encaixam.

Passo 1 — Steering define o terreno. Você já tem .kiro/steering/tech.md com inclusion: always (o exemplo lá de cima). Toda geração de código já respeita Fastify + zod + Prisma + Vitest. Você adiciona um steering auto só para endpoints:

---
inclusion: auto
name: api-design
description: Padrões de design de API REST. Use ao criar ou modificar endpoints.
---
# Padrões de endpoint

- Toda rota valida input com zod antes do handler.
- Respostas de erro seguem { error: { code, message } }.
- Status codes: 201 na criação, 403 sem autorização, 422 em validação.

Passo 2 — Spec define o plano. Você cria a spec reviews. O requirements.md sai em EARS (“WHEN um cliente autenticado envia uma avaliação… THE SYSTEM SHALL persistir…”; “IF o usuário não comprou… THEN… HTTP 403”). O design.md traz o diagrama de sequência e o modelo de dados. O tasks.md lista as tarefas:

# 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)

Passo 3 — Hooks garantem a disciplina. Com o lint-on-save ativo, cada arquivo .ts que o Kiro salvar ao executar as tasks passa pelo linter automaticamente. Se você trabalha com componentes de front-end para exibir as avaliações, o sync-tests mantém os .test.tsx alinhados a cada mudança. Você não precisa lembrar de nada disso — os gatilhos disparam sozinhos.

O resultado: você aprova o plano da spec, manda executar, e enquanto o Kiro implementa a Wave 1, o steering mantém o código no padrão e os hooks fazem o policiamento. Cada peça cobre um buraco que as outras deixariam.

Armadilhas comuns

Alguns tropeços que custam tempo e são fáceis de evitar:

  • Front matter tem que ser a primeira linha. No steering, o bloco --- do YAML precisa ser literalmente a primeira coisa do arquivo, sem linha em branco ou comentário antes. Se houver qualquer coisa acima, o inclusion mode é ignorado e o arquivo pode virar um always silencioso — ou nem ser lido como esperado.
  • matcher é regex, não glob. No hook, o matcher é uma expressão regular. \\.ts$ casa arquivos .ts; *.ts não faz o que você imagina. Escape os pontos (\\.) e ancore com $ quando quiser casar a extensão no fim do caminho. Isso é diferente do fileMatchPattern do steering, que é glob.
  • timeout só vale para ação command. Se sua ação é do tipo agent, o timeout é ignorado — a tarefa cognitiva roda até concluir. Não conte com ele para limitar um hook de agente.
  • Exit code 2 só bloqueia em triggers Pre*. Fazer um script sair com código 2 em um PostFileSave não impede nada; ali o evento já aconteceu. O bloqueio só existe em PreToolUse, PreTaskExec e UserPromptSubmit.
  • Steering demais polui o contexto. Cada arquivo always entra em toda interação e consome contexto (e créditos). Reserve o always para o essencial e prefira fileMatch/auto para regras específicas.

Principais aprendizados

  • Steering, hooks e specs movem padrões, automação e planejamento para dentro do repositório, onde o agente os lê sem depender da sua memória.
  • Steering usa front matter YAML com 4 inclusion modes; escolha entre always, fileMatch, manual e auto conforme a regra seja universal, contextual, sob demanda ou condicional.
  • Hooks ligam eventos a ações; uma ação command valida de forma determinística, uma ação agent delega trabalho cognitivo ao Kiro.
  • Specs dão o plano rastreável (EARS → design → tasks) e executam em waves paralelas.
  • Comece pequeno: um tech.md com always, um lint-on-save, e cresça a partir daí. O valor composto aparece quando os três operam juntos.

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, aws, steering, automation, devtools

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