Sensors (feedback determinístico)
Um sensor lê o artefato depois que o agent o escreve e devolve pass ou fail. Um sensor que falha bloqueia a aprovação, e o agent regenera as partes que falharam até passar.
Todo sensor declara como é aplicado:
Execution: |
Aplicado por | Pode reportar pass |
|---|---|---|
computational |
sensor-runner.py, mesmo veredito toda vez |
sim |
inferential |
um modelo ou uma pessoa aplicando julgamento | nunca; fica registrado como inferential |
Essa é a divisão de Böckeler. Três sensors do harness-kit já se declararam gates rígidos enquanto escreviam checks em prosa que o runner não conseguia ler; o log registrava passed em toda execução para checks que nunca rodaram. python3 .claude/scripts/check-sensors.py imprime cada sensor, seu tipo de execução e os checks que ele liga.
O que é um sensor
Um sensor é uma spec em markdown; um runner Python a aplica com regex.
# Sensor: PRD Structure
Type: deterministic
Execution: computational
Mode: hard gate
## Required sections
- Problem and Hypothesis
- Customers
## Forbidden tokens
- lorem, TODO, FIXME, placeholder
## Markdown rules
- exactly 1 H1 heading
- no em-dash
Como o runner funciona
.claude/runtime/scripts/{agent}/sensor-runner.py lê cinco seções: Required sections, Forbidden sections, Required tokens, Forbidden tokens (ou Forbidden patterns), Markdown rules. As seções obrigatórias viram regexes de heading que toleram prefixos como ## 3) .... Qualquer outra coisa no arquivo é documentação e não é aplicada.
| Saída | Significado |
|---|---|
0 |
todos os checks passaram |
1 |
um check falhou; o agent corrige só as partes que falharam |
2 |
spec quebrada: computational sem nenhum check que o runner entenda |
3 |
inferential; o runner recusa e quem chama registra inferential, nunca pass |
Um hook PostToolUse roda o runner ao salvar e devolve o feedback ao agent. A comparação de headings ignora um parêntese no final, então ## Design doc, required sections (all present, in order) resolve para Required sections. O bug original: o runner só aceitava (all must be present, in order), três sensors escreviam (all present, in order), e cerca de 30 asserções não faziam nada.
Por que determinístico
Um sensor não custa tokens, dá a mesma resposta toda vez e deixa para o eval só o que precisa de julgamento semântico. Torne determinístico o que puder, infira só o que precisar.
Sensors por stage
| Stage | Sensors |
|---|---|
prd |
prd-structure, prd-acceptance-criteria |
prp |
prp-structure, prp-context-quality, prp-links (roda link-validator.py) |
plan |
plan-structure |
dev |
dev-structure, code-maintainability, code-conventions e test-coverage (ambos inferential) |
test |
test-structure |
pr |
pr-structure |
entrada do sdd |
prp-has-acceptance-criteria (inferential) |
| system design | design-structure, review-structure, design-rigor (inferential) |
code-maintainability checa código. Ele roda o que o repo configura (npm lint e typecheck, ruff, ktlint, checkstyle, gitleaks), nunca uma config imposta, e sai com 4 (não checado) quando não encontra nada que conheça. design-rigor quer metas numéricas, contas de back-of-envelope, três trade-offs e uma fase de vertical slice; isso exige julgamento, então ele é inferential.
Escrevendo um sensor
Declare Execution: com honestidade: se o runner não consegue checar, é inferential. Coloque os checks computacionais nas cinco seções lidas pelo runner, mantenha-os objetivos e use forbidden tokens para pegar placeholders como {N} e TBD. Escreva a mensagem de falha como uma instrução, por exemplo "missing required section: 'Success Metrics'".
Rode python3 .claude/scripts/check-sensors.py antes de commitar. O CI também roda, e um teste garante que todo sensor computacional rejeita um artefato vazio.
Veja também
Evals, Harness Engineering, Referências. Fonte: Böckeler, Maintainability sensors for coding agents.
Tradução manual de Sensors (feedback determinístico), a página original em inglês na wiki.