Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Versionamento independente do OpenClaw — kit segue semver próprio.
## [Unreleased]

### Adicionado
- **Lesson** [`lessons/2026-05-24-upgrade-5.22-harness-restart-latency-and-plugin-config-env.md`](lessons/2026-05-24-upgrade-5.22-harness-restart-latency-and-plugin-config-env.md) — (sem TL;DR — ver lesson para detalhes)
- **Lesson** [`lessons/2026-05-08-09-invariant-upgrade-and-health-probe-race.md`](lessons/2026-05-08-09-invariant-upgrade-and-health-probe-race.md) — (sem TL;DR — ver lesson para detalhes)
- **Lesson** [`lessons/2026-05-09-upgrade-5.7-and-f18-f17-mitigation.md`](lessons/2026-05-09-upgrade-5.7-and-f18-f17-mitigation.md) — | Item | Estado |
- **Lesson** [`lessons/2026-05-17-launchagent-mac-stale-openclaw-version.md`](lessons/2026-05-17-launchagent-mac-stale-openclaw-version.md) — (sem TL;DR — ver lesson para detalhes)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ openclaw-update-toolkit/
│ ├── upgrade-from-v24-to-v29.md
│ ├── recovery-from-fratricide-loop.md
│ └── recovery-from-cost-explosion.md
└── lessons/ # 22 lições por incident — fonte de truth
└── lessons/ # 23 lições por incident — fonte de truth
```

---
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Lesson 2026-05-24 — Upgrade 5.20→5.22: harness pós-update, latência = trabalho, e `${VAR}` não resolve em config de plugin

Upgrade 5.20→5.22. Logo após, Nox (WhatsApp) e Forge (Discord) pararam de responder. Três problemas distintos numa cadeia — diagnosticados e resolvidos em sequência.

## 1. Canais mudos: harness `claude-cli` not registered (causa = restart in-process)

**Sintoma:** transporte conectado (WhatsApp `connected/healthy`, Discord reconectando), mas TODO dispatch de canal falha com `MissingAgentHarnessError: Requested agent harness "claude-cli" is not registered`.

**Diagnóstico:** o `openclaw update` reinicia o gateway via `[restart-sentinel]` (restart **in-process**), visível no journal como `Gateway restart restart ok (gateway.restart)`. Restart in-process **NÃO re-registra o harness** (o plugin `anthropic` lazy não re-ativa). É diferente de um cold start do systemd.

**Fix:** `systemctl restart openclaw-gateway` (cold). Confirma no journal: `http server listening (N plugins: ...anthropic...whatsapp...)`.

**Resíduo de boot (NÃO confundir com falha):** 1-2 `MissingAgentHarnessError` nos primeiros ~50s pós-cold-restart são a fila de retry do restart-sentinel reprocessando mensagens antigas ANTES do harness subir (`channel=webchat source=replyResolver messageId=restart-sentinel:...`). Validação correta: contar erros numa janela DEPOIS do boot (`journalctl -u openclaw-gateway --since "<restart+60s>"` deve dar 0), e procurar um `claude live session turn` de sucesso.

**Fonte de log:** `journalctl -u openclaw-gateway` (o wrapper `openclaw-gateway-wrapper` loga tudo lá) — tão válido quanto `/tmp/openclaw/*.log`.

## 2. Latência alta = trabalho do turn, não overhead de prompt

**Sintoma:** "responde mas demora uma eternidade", intermitente.

**Diagnóstico:** a latência de um turn escala com `rawLines` (tool calls em cadeia + tamanho da resposta), NÃO com o tamanho do system prompt:

| rawLines (trabalho) | tempo (sonnet) |
|---|---|
| ~17 | 2-4s |
| 51-56 | 14-15s |
| 157-199 | 60-67s |

Turns leves já respondem em 2-4s mesmo no modelo grande; os de 60s fazem 150-200 rawLines (muita ferramenta). **Enxugar prompt/skills dá ganho modesto** (custo fixo de prefill já é ~2-7s). Alavancas reais pros turns longos: modelo mais leve no chat casual, ou instrução de concisão (menos tool calls).

**Falso suspeito:** fetch-timeout de 120s pro provider de embedding logo após restart = **event-loop starvation** (`eventLoopDelayMax ~9s` durante o boot pesado), não rede nem chave.

**Cortar skills do prompt:** skills em `skills.load.extraDirs` SEM entry em `skills.entries` são auto-ativadas e injetadas no prompt. Desativar = adicionar `{"enabled": false}` em `skills.entries.<nome>`. Cada skill ≈ 1 linha na seção `## Skills`. Sempre backup + `openclaw config validate` + restart.

## 3. `${VAR}` NÃO resolve em `plugins.entries.<plugin>.config`

**Sintoma:** o plugin de memória (graph-memory) falha o embedding com `Embedding API 400: API key expired` — apesar da chave do `.env` estar **válida** (HTTP 200 nos endpoints).

**Causa raiz:** o openclaw interpola `${VAR}` no config CORE (`models.providers.*`, `channels.*`, `gateway.auth.token`) mas passa `plugins.entries.<plugin>.config` **cru** pro plugin, sem interpolar. O plugin recebia a string literal `${...}` e a mandava como credencial → o provider respondia "expired"/inválido.

**Pegadinha de diagnóstico:** `openclaw config get` redacta TODO campo `apiKey` como `__OPENCLAW_REDACTED__` — isso **NÃO prova** que o `${VAR}` resolveu; mascara a string crua. Confirmar lendo o valor real (começa com `${` = ref não-resolvida vs credencial real).

**Fix aplicado:** chave literal no `embedding.apiKey` + `llm.apiKey` do plugin config (lida do `.env` no host, sem expor). Pós-restart: `[graph-memory] vector search ready`. **Alternativa limpa** (não usada — exige projeto dedicado): ativar o sistema SecretRef formal do 5.22 (`openclaw secrets configure` + `secrets.providers`), que re-resolve refs no runtime snapshot e cobriria config de plugin.

**Trade-off de segurança:** a chave literal vira a única exceção ao padrão `.env`+`${VAR}`. Mitigar: `openclaw.json` (e seus backups) não devem ser commitados; na rotação da credencial, atualizar o `openclaw.json` ALÉM do `.env`.

## Lições

1. **Pós `openclaw update`: SEMPRE `systemctl restart openclaw-gateway` (cold).** Restart in-process não re-registra o harness. Reincidência do tema de 2026-05-22, agora com a mecânica (`restart-sentinel`) isolada.
2. **Latência de chat: diagnosticar por `rawLines`, não por tamanho de prompt.** Enxugar overhead é ganho marginal; os turns longos são trabalho real.
3. **Secrets em config de PLUGIN não aceitam `${VAR}`** — só literal ou o sistema SecretRef formal. O `${VAR}`→`.env` funciona em todo o config core, só não dentro de `plugins.entries.*.config`.
Loading