What happens
streaming.progress.narration (#103463) replaces raw tool lines in channel progress drafts with short utility-model narration. When the utility-model completion fails — observed live on a gateway where the primary model rides Codex OAuth but the derived utility model (openai/gpt-5.6-luna, #103769) resolves the openai:api-key auth profile holding a dead key — every narration call 401s, the narrator disables itself after MAX_CONSECUTIVE_FAILURES = 2, and the draft silently falls back to the old raw tool lines.
Nothing surfaces this at default log levels:
progress-narrator failures are logVerbose only (src/auto-reply/reply/progress-narrator.ts).
openclaw models status never mentions the utility model, so the operator cannot see that narration depends on a different auth profile than the primary model.
openclaw models status --probe --probe-profile openai:api-key probes the configured primary (gpt-5.6-sol) through the codex app-server harness, which never exercises the API key; the probe reports a harness startup timeout instead of the 401.
Live evidence (Molty gateway, 2026-07-11)
progress-narrator: completion failed: OpenAI API error (401): 401 Incorrect API key provided: sk-proj-…skwA
repeated at 22:25:59Z/22:26:19Z/22:27:52Z while Discord kept rendering the old-style tool lines; direct probe of the same profile via models status --probe returned timeout · codex app-server startup timed out — the dead key was invisible to every operator surface.
Fix (this issue's PR)
progress-narrator: emit one warn per turn when narration disables after consecutive failures, naming the utility model + auth profile and the last error.
openclaw models status: render the resolved utility model (explicit config / provider default / disabled / none) in human and JSON output.
Follow-up (separate issue)
models status --probe for an api_key profile should exercise the plain API path instead of the codex app-server harness; tracked separately because probe/harness routing needs the Codex-contract review gate.
What happens
streaming.progress.narration(#103463) replaces raw tool lines in channel progress drafts with short utility-model narration. When the utility-model completion fails — observed live on a gateway where the primary model rides Codex OAuth but the derived utility model (openai/gpt-5.6-luna, #103769) resolves theopenai:api-keyauth profile holding a dead key — every narration call 401s, the narrator disables itself afterMAX_CONSECUTIVE_FAILURES = 2, and the draft silently falls back to the old raw tool lines.Nothing surfaces this at default log levels:
progress-narratorfailures arelogVerboseonly (src/auto-reply/reply/progress-narrator.ts).openclaw models statusnever mentions the utility model, so the operator cannot see that narration depends on a different auth profile than the primary model.openclaw models status --probe --probe-profile openai:api-keyprobes the configured primary (gpt-5.6-sol) through the codex app-server harness, which never exercises the API key; the probe reports a harness startup timeout instead of the 401.Live evidence (Molty gateway, 2026-07-11)
repeated at 22:25:59Z/22:26:19Z/22:27:52Z while Discord kept rendering the old-style tool lines; direct probe of the same profile via
models status --probereturnedtimeout · codex app-server startup timed out— the dead key was invisible to every operator surface.Fix (this issue's PR)
progress-narrator: emit one warn per turn when narration disables after consecutive failures, naming the utility model + auth profile and the last error.openclaw models status: render the resolved utility model (explicit config / provider default / disabled / none) in human and JSON output.Follow-up (separate issue)
models status --probefor anapi_keyprofile should exercise the plain API path instead of the codex app-server harness; tracked separately because probe/harness routing needs the Codex-contract review gate.