🧱 As três peças e quem chama quem
Nas trilhas 2 a 4 você construiu o cérebro do mentor: acervo, wiki e regras. Agora entra o comportamento: um agente que segue o método, skills que o acionam e um portão que impede o turno de terminar com código que ninguém rodou. Tudo isso fica dentro da pasta oculta .claude/ do projeto do mentor.
🆕 Novo aqui?
- Hook é um script que o Claude Code roda sozinho quando algo acontece (o modelo editou um arquivo, o turno vai terminar). O hook não é IA: é um programa comum que lê um JSON e responde.
- Subagente é um segundo Claude, com instruções próprias, que a sessão principal chama para uma tarefa e que devolve o resultado.
- Skill é uma receita salva em arquivo que você dispara com /nome. Ela diz ao Claude o passo a passo de uma tarefa.
Como ler: a linha de cima é o caminho do pedido (você → skill → subagente). A caixa de baixo não está nesse caminho: o hook registrado no settings.json observa de fora, pelas setas tracejadas. É por isso que ele consegue barrar o fim do turno mesmo quando o agente "esquece" a instrução.
settings.json
Registra os hooks
agents/
O mentor e seu loop
skills/
As 6 receitas com /
hooks/
O script do portão
⚙️ settings.json: hook só roda se estiver registrado
Colocar um script em .claude/hooks/ não faz nada sozinho. O Claude Code só executa o que estiver listado em .claude/settings.json, debaixo do nome do evento. O kit registra um único script em três eventos. Este é o arquivo real:
.claude/settings.json (kit 1.2, igual no mentor-nei)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit|Bash",
"hooks": [
{ "type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/portao-execucao.py\"", "timeout": 10 }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/portao-execucao.py\"", "timeout": 10 }
]
}
],
"SubagentStop": [
{
"hooks": [
{ "type": "command", "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/portao-execucao.py\"", "timeout": 10 }
]
}
]
}
}
🆕 O que é cada campo?
- Evento é o momento em que o hook dispara. PostToolUse = logo depois de o Claude usar uma ferramenta. Stop = quando a sessão principal vai encerrar o turno. SubagentStop = quando um subagente vai encerrar o dele.
- matcher filtra por nome de ferramenta, como expressão regular: aqui, só Write, Edit, MultiEdit e Bash. Os eventos de parada não têm ferramenta, por isso não levam matcher.
- $CLAUDE_PROJECT_DIR é uma variável que o Claude Code preenche com a raiz do projeto. Com ela, o caminho funciona de qualquer subpasta.
- timeout (em segundos) é o teto: se o script travar, o Claude Code segue em frente depois de 10 s.
✓ Registrado do jeito certo
- ✓Script em .claude/hooks/ e listado no settings.json
- ✓Caminho com $CLAUDE_PROJECT_DIR entre aspas
- ✓Um script, vários eventos: a lógica fica num lugar só
✗ Por que "o hook não faz nada"
- ✗Script copiado para hooks/, mas sem entrada no settings.json
- ✗JSON com vírgula sobrando: o arquivo inteiro é ignorado
- ✗Caminho relativo que só funciona quando você está na raiz
🧪 Copie e rode: o registro está válido?
Objetivo: confirmar que o settings.json do seu mentor é JSON válido e lista os três eventos.
cd <pasta do seu mentor>
python3 -c 'import json; d = json.load(open(".claude/settings.json")); print(sorted(d["hooks"]))'
Como verificar: a saída deve ser ['PostToolUse', 'Stop', 'SubagentStop']. Se aparecer JSONDecodeError, o Claude Code também não está lendo o arquivo: conserte antes de seguir.
🤖 Subagente: .claude/agents/*.md e o frontmatter
O mentor é um subagente: um arquivo Markdown em .claude/agents/. O topo do arquivo, entre duas linhas ---, é o frontmatter: um cabeçalho com campos que o Claude Code lê para saber o nome do agente e quando chamá-lo. O resto do arquivo é a instrução que o subagente recebe.
.claude/agents/nei-mentor.md (início; no arquivo, a description ocupa uma linha só)
--- name: nei-mentor description: "Mentor que ensina e revisa no método de Nei Maldaner (INEMA) (ensinar a usar Claude Code e agentes de IA na prática, construindo junto). Use quando o usuário quiser APRENDER algo construindo junto, entender um código, ou revisar um trabalho antes de entregar. Segue as regras de regras.md, consulta a wiki e só afirma o que rodou." --- Você é um mentor que ensina **no método** de Nei Maldaner (INEMA), em … Você NÃO é Nei Maldaner (INEMA): não fala em nome da pessoa, não imita voz nem bordões, não inventa opiniões dela. Copia o **método**: como explica, constrói, depura e verifica.
| Parte | Para que serve | Erro comum |
|---|---|---|
| name | Identificador que a skill usa para chamar o agente | Nome diferente do que a skill chama |
| description | Diz quando usar. É o gatilho, não um enfeite | Descrever o que ele "é" em vez de quando chamar |
| corpo | Antes de responder, loop obrigatório, revisão, proibido | Imitar a voz do especialista (persona, não método) |
✓ Frontmatter que funciona
- ✓description diz quando chamar: "Use quando o usuário quiser APRENDER algo construindo junto…"
- ✓name igual ao que a skill chama (nei-mentor)
- ✓Corpo descreve o método: como explica, constrói, depura e verifica
✗ Frontmatter que atrapalha
- ✗description que só diz o que o agente "é" ("um mentor experiente")
- ✗name diferente do que a skill referencia: a chamada falha
- ✗Corpo que imita a voz e os bordões do especialista
🧭 Por que o mentor é subagente e não a sessão principal
O subagente começa com contexto limpo e com as instruções do arquivo. A sessão principal fica livre para orquestrar e conferir: ela salva a resposta e roda o validador de fora. Quem ensina não é quem dá a nota. Esse corte é o mesmo da trilha 1: autoavaliação não vale como prova.
Arquivo .md
Em .claude/agents/
Frontmatter
name + description
Contexto limpo
Só o método
Método
Não persona
🧩 Skill: .claude/skills/<nome>/SKILL.md
Cada skill é uma pasta com um arquivo SKILL.md dentro. O nome da pasta vira o comando: skills/nei-ensina/ responde a /nei-ensina. Assim como o agente, ela tem frontmatter com name e description. A diferença é o papel: a skill é a receita que a sessão principal segue; o agente é quem executa a parte que exige o método.
Como ler: as três skills da esquerda montam o cérebro e você já as usou nas trilhas anteriores. As três da direita são as de uso. Repare nas setas: só ensina e revisa passam pelo subagente mentor; ingere mexe no acervo, na wiki e nas regras e não precisa dele.
Skill
- • Disparada por você com /nome
- • Roda na sessão principal
- • Passos, comandos e "pronto quando"
- • Pode chamar um subagente
Subagente
- • Chamado pela sessão (ou por uma skill)
- • Roda com contexto próprio
- • Método, loop e proibições
- • Devolve uma resposta, não confere a si mesmo
🛑 Stop × SubagentStop: por que registrar os dois
Quem escreve código no kit é o mentor, e ele roda como subagente. Quando ele termina, o evento que dispara é SubagentStop, não Stop. Se o portão escutasse só o Stop, o mentor poderia entregar código sem rodar e a barreira só apareceria depois, na sessão principal. Registrar os dois fecha as duas portas de saída.
Você chama /nei-ensina
A sessão principal segue a skill e passa a dúvida ao subagente nei-mentor.
O mentor escreve e roda código
Cada Write/Edit e cada Bash disparam o PostToolUse, que anota o que está pendente.
O mentor tenta terminar → SubagentStop
Se ficou código sem rodar, o portão devolve o turno ao mentor, que ainda tem o contexto para rodar.
A sessão principal tenta terminar → Stop
Mesma checagem, para o código que a própria sessão principal tenha escrito sem rodar.
🆕 Novo aqui? stop_hook_active
Quando um hook de parada já bloqueou uma vez, o Claude Code manda no JSON do evento seguinte o campo "stop_hook_active": true. É o aviso "você já insistiu". Um hook bem escrito usa esse sinal para não prender a sessão num laço sem fim. O módulo 5.2 mostra o que acontece quando ele é ignorado, e o 5.4 mostra como o portão o usa.
🌳 Projeto × global, e a árvore real do mentor-nei
A pasta .claude/ existe em dois lugares. A do projeto vale só quando você abre o Claude Code naquela pasta. A global (~/.claude/, na sua pasta de usuário) vale em todos os projetos. O mentor mora inteiro no projeto: o portão só vigia o mentor e não atrapalha seus outros trabalhos.
| Peça | No projeto (mentor) | Global |
|---|---|---|
| Hooks | .claude/settings.json | ~/.claude/settings.json |
| Subagentes | .claude/agents/ | ~/.claude/agents/ |
| Skills | .claude/skills/ | ~/.claude/skills/ |
| Quando vale | Só dentro da pasta do mentor | Em toda sessão |
Árvore real de .claude/ no piloto mentor-nei (9 arquivos):
.claude/
├── settings.json ← registra o portão em 3 eventos
├── hooks/
│ └── portao-execucao.py ← o portão (módulo 5.4)
├── agents/
│ └── nei-mentor.md ← o mentor e o loop (módulo 5.2)
└── skills/
├── nei-coletar/SKILL.md ← fase 1
├── nei-compilar/SKILL.md ← fase 2
├── nei-regras/SKILL.md ← fase 3
├── nei-ensina/SKILL.md ← uso (módulo 5.3)
├── nei-revisa/SKILL.md ← uso
└── nei-ingere/SKILL.md ← evolução
🧪 Copie e rode: conferir a árvore do seu mentor
Objetivo: ver que o novo-mentor.py gerou as peças com o seu slug no lugar de {{SLUG}}.
cd <pasta do seu mentor> find .claude -type f | sort grep -h '^name:' .claude/agents/*.md .claude/skills/*/SKILL.md
Como verificar: 9 arquivos, como na árvore acima, e 7 linhas name: (1 agente + 6 skills), todas com o seu slug. Se aparecer {{SLUG}} em algum nome, a pasta foi copiada à mão em vez de gerada.
💡 Do piloto: testar hook novo longe do portão
No teste 1 do piloto, o mentor criou um hook de Stop novo numa pasta separada, exemplos/hook-todo-stop/, com o próprio .claude/settings.json. O motivo, nas palavras da resposta: assim ele "não se empilha no portão que este projeto já usa". Dois hooks de Stop no mesmo projeto rodam juntos, e basta um bloquear para o turno continuar.
Checagem rápida: você copiou portao-execucao.py para .claude/hooks/ de outro projeto e o portão não bloqueia nada. Qual é a causa mais provável?
📌 Resumo do Módulo
Próximo Módulo:
5.2 - O loop obrigatório do mentor: Pronto, Menor versão, Previsão, Saída real, Versão quebrada e Relatório.