O harness confiável
O harness é o motor do Okami: um loop ReAct com invariantes de confiabilidade. Ele não confia na prosa do modelo — decide pelo estado e por efeitos observáveis. É o…
A máquina de estados
Toda tarefa percorre estados explícitos. Ela nunca fica IN_PROGRESS para sempre: max_steps (default 24), o relógio de parede e o detector de stall garantem terminação.
PENDING ─► IN_PROGRESS ─► COMPLETE (exitCriteria verificados)
├─► BLOCKED (razão estruturada)
├─► NEEDS_INPUT (falta um dado seu)
└─► FAILED (orçamento estourado)Action-or-Terminate
Todo turno termina em tool-call OU num sinal terminal (task_complete · task_blocked · need_input). Texto em futuro (“vou”, “let me”, “I'll”) sem ação é pego por um reconciler intent–ação (PT/EN), rejeitado e re-promptado: “você disse que faria X mas não agiu — execute agora ou declare bloqueio”. Não existe “tô pensando” infinito.
exitCriteria verificados
task_complete só vale se os critérios baterem mecanicamente. Se o modelo declara conclusão mas o critério falha, o harness emite complete_rejected com a lista exata do que falta — e o agente retoma.
| critério | verifica |
|---|---|
| file_exists:<path> | o arquivo existe no workspace |
| file_contains:<path>:<txt> | o arquivo existe E contém o texto |
| shell_ok:<cmd> | o comando sai com código 0 (ex.: pytest -q) |
| ui_gate | o gate de contrato de design passa (§ Skills) |
Anti-loop
Modelo fraco adora repetir a mesma tool e oscilar entre dois estados. O harness quebra isso sem depender de o modelo “perceber”:
- Fingerprint + dedup — cada chamada vira hash (tool + args normalizados); repetiu N vezes → bloqueia com nudge.
- Detecção de ciclo — padrões A,B,A,B / A,B,C,A,B,C na janela recente → quebra.
- Circuit breaker — mesmo comando falhando N vezes com o mesmo erro → aquela abordagem é proibida.
- Orçamento por progresso — muito efeito e zero avanço contra os exitCriteria → quebra.
- Tetos duros —
max_stepspor tarefa + cap por-tool. - Escada de escalonamento — nudge → re-decompõe → escala p/ modelo mais forte (
--escalate) →BLOCKEDcom diagnóstico.
Anti-alucinação
- Grounding obrigatório — afirmação sobre o código precisa estar lastreada numa observação real (read-before-edit). O tool result é a verdade, não a memória do modelo.
- Checagem de existência de símbolo/import/pacote antes de usar (anti-slopsquatting).
- Abstenção é first-class — “não sei / preciso checar” é mais barato que chutar.
- Gates como filtro — build/typecheck pegam API/import alucinado na hora.
Dual-mode (paridade entre LLMs)
O capability.tool_mode define como o modelo emite ações:
params json_text modo Ação como bloco ``json`` no texto — funciona em qualquer modelo. json_constrained modo Força JSON válido via grammar/response_format (locais/fracos) — tool-call malformado deixa de ser fatal. native modo Tool-calling nativo do provider (forte); o transport converte de volta pro protocolo de ação.
Checkpoints & rollback
Toda escrita registra o estado anterior num journal append-only com lock + HMAC encadeado — adulterar ou inserir uma entrada quebra a cadeia, e o rollback ignora a entrada forjada. okami rollback N desfaz as últimas N escritas.
Orçamento e auto-compaction
Há teto de passos/tokens por turno. Quando o contexto enche (~72% da janela do modelo), turnos antigos viram nós de summary e os fatos duráveis são promovidos para a memória de longo prazo — comprimir é promover + apontar, nunca esquecer.
Eventos do turno
O harness emite um stream de eventos (consumido pela CLI, pela TUI e pelo event log). Cada um aparece ao vivo no okami task/chat:
| evento | significa |
|---|---|
| start · step | início da tarefa · cada tool-call com ✓/✗ |
| violation | turno sem ação (futuro vazio) → rejeitado |
| loop | repetição/ciclo detectado |
| escalate | subindo p/ um modelo mais forte |
| compact | auto-compaction (n fatos → memória) |
| complete_rejected | conclusão negada: faltou um exitCriteria |

