Referência de Hooks

Um hook é um comando que o Claude Code dispara em torno de eventos da sessão (PreToolUse, PostToolUse, SessionStart, …), registrado em .claude/settings.json. O ai-core-kit oferece um único hook como payload CHILD: o contract-gate, um guarda PreToolUse que impõe edição design-contract-first.

Restrição rígida. Os hooks do Claude Code recebem apenas session_id, transcript_path, cwd, permission_mode e hook_event_namenenhum campo de token ou custo (anthropics/claude-code#11008). Por isso nenhum hook do kit pode medir custo ao vivo; a telemetria de custo é sempre offline. Veja Telemetria de Custo Offline.


O hook contract-gate

PropriedadeValor
TipoPreToolUse (comando)
MatcherEdit|Write|MultiEdit|NotebookEdit
CamadaCHILD (renderizado em um fork pelo /ack-init)
Renderizado quandofeatures.sdd_gate == true
Localização no fork.claude/hooks/contract-gate
Runtimepython3 (dialeto de glob: fnmatch com **)

O hook é oferecido nos conjuntos de arquétipo backend-api e fullstack:

ArquétipoCaminho do hook (no kit)
backend-apitemplates/archetypes/backend-api/.claude/hooks/contract-gate
fullstacktemplates/archetypes/fullstack/.claude/hooks/contract-gate

Os dois arquivos compartilham comportamento idêntico — eles diferem apenas nos padrões de protected_paths por arquétipo que o /ack-init congela no manifesto.


O que o gate faz

Um matcher PreToolUse só pode filtrar por nome de ferramenta, nunca por caminho de arquivo. Então o hook recebe toda chamada Edit/Write/MultiEdit/NotebookEdit, lê o tool_input.file_path do JSON em stdin e escopa no próprio script:

  1. exempt vence tudo — uma edição que corresponde é sempre permitida.
  2. protected_paths (obrigatório, minItems 1, para que o gate nunca seja vacuoso) — edições aqui exigem um contrato approved em contracts[].
  3. scope (opcional; por padrão igual a protected_paths) — o subconjunto que também exige um contrato aprovado.
  4. Qualquer arquivo que não corresponda a nenhum acima é PERMITIDO.

O “oráculo de aprovados” é contracts[]: uma edição sob um caminho protegido só é permitida se alguma entrada de contracts[] cujo scope o cubra estiver com status: approved (um draft não libera seu escopo). Os padrões de protected_paths por arquétipo são resolvidos pelo /ack-init a partir do arquétipo escolhido e congelados no manifesto:

ArquétipoCaminhos protegidos padrão
backend-apisrc/**, migrations/**, openapi/**
fullstackapp/**, api/**, src/**
infra-iacfornecidos via o campo do manifesto (sem src/** hardcoded, que seria vacuoso para infra)

Os três modos (contract_gate.mode) são mecanismos distintos:

ModoExitSaídaEfeito
block2define hookSpecificOutput.permissionDecision: "deny"Para a chamada da ferramenta.
warn0mensagem em stderr / additionalContextRegistra e continua — não bloqueia.
off0nenhuma; retorno antecipadoNo-op silencioso.

Fail-open em runtime. Se o manifesto estiver ausente ou não-analisável quando o hook roda, o gate se comporta como off mais um aviso em stderr — ele nunca sai com 2 e nunca trava a sessão. A análise de manifesto é deliberadamente fail-open.

Status. O contrato do manifesto e o formato de dados do gate estão CONGELADOS e entregues (contract_gate.* e contracts[] no schema, o matcher do settings.json, a localização do hook e o comportamento fail-open). O runtime profundo (escopo via fnmatch no próprio script, percurso do oráculo de aprovados, os três mecanismos de modo distintos) é P5 / roadmap. O hook entregue é um stub fail-open coerente que sai com 0.


Registro no settings.json

O matcher renderizado em .claude/settings.json está congelado:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit|NotebookEdit",
        "hooks": [
          { "type": "command", "command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/contract-gate" }
        ]
      }
    ]
  }
}

Quando features.sdd_gate: false, o /ack-init não renderiza nem o hook nem o matcher PreToolUse, e contract_gate.mode torna-se irrelevante.

O tratamento completo — chave-mestra, padrões de caminho por arquétipo, o oráculo de contratos aprovados e o que está entregue vs. roadmap — está em Gate de Contrato de Design.

Veja também: Gate de Contrato de Design (spec completa), Manifesto e Entrevista para os campos contract_gate e contracts[] que o hook lê.