Bug
When the default agent's resolved provider is a CLI backend (Claude CLI, Codex CLI, Gemini CLI, or any registerCliBackend provider), the managed dreaming cron fires but the promotion sweep never runs. The dream-sentinel token is sent to the underlying LLM as a literal user prompt — wasted tokens, no MEMORY.md write, no diary entry.
Pre-existing (heartbeat path had the same gap); surfaced by #70737.
Root cause
Memory-core's promotion runs inside a before_agent_reply hook. That hook is only fired by runEmbeddedPiAgent. The CLI runner (src/agents/cli-runner/*.ts) fires before_prompt_build and before_agent_start but not before_agent_reply, so the cron's isolated agent turn skips the hook entirely (src/cron/isolated-agent/run-executor.ts:123 branches on isCliProvider).
Repro (verified 2026-04-23 against PR #70737)
Isolated OPENCLAW_HOME with default agent model: { primary: "codex-cli/gpt-5.5" } and dreaming enabled at */2 * * * *. Trigger via openclaw cron run <jobId>.
Gateway log:
[gateway] agent model: codex-cli/gpt-5.5
[gateway] ready (6 plugins: …, memory-core, …)
[agent/cli-backend] cli exec: provider=codex-cli model=gpt-5.5 promptChars=217
pgrep -af "codex exec" confirmed a codex subprocess actively talking to OpenAI with the dream-sentinel as the user prompt. No memory-core: dreaming promotion complete line ever appeared. Same config with model: { primary: "openai/gpt-5.5" } (non-CLI) routes to runEmbeddedPiAgent, fires the hook, and produces the expected promotion-complete line.
Suggested fix
Mirror the before_agent_reply block from src/agents/pi-embedded-runner/run.ts:326 into the CLI runner (gated on trigger === "cron" at minimum). Small follow-up PR.
Adjacent options if the above is too invasive: docs caveat in docs/concepts/dreaming.md, or a startup warn log when the dreaming cron is reconciled against a CLI-backed default agent.
Identified by
@chatgpt-codex-connector during PR #70737 review.
Bug
When the default agent's resolved provider is a CLI backend (Claude CLI, Codex CLI, Gemini CLI, or any
registerCliBackendprovider), the managed dreaming cron fires but the promotion sweep never runs. The dream-sentinel token is sent to the underlying LLM as a literal user prompt — wasted tokens, noMEMORY.mdwrite, no diary entry.Pre-existing (heartbeat path had the same gap); surfaced by #70737.
Root cause
Memory-core's promotion runs inside a
before_agent_replyhook. That hook is only fired byrunEmbeddedPiAgent. The CLI runner (src/agents/cli-runner/*.ts) firesbefore_prompt_buildandbefore_agent_startbut notbefore_agent_reply, so the cron's isolated agent turn skips the hook entirely (src/cron/isolated-agent/run-executor.ts:123branches onisCliProvider).Repro (verified
2026-04-23against PR #70737)Isolated
OPENCLAW_HOMEwith default agentmodel: { primary: "codex-cli/gpt-5.5" }and dreaming enabled at*/2 * * * *. Trigger viaopenclaw cron run <jobId>.Gateway log:
pgrep -af "codex exec"confirmed acodexsubprocess actively talking to OpenAI with the dream-sentinel as the user prompt. Nomemory-core: dreaming promotion completeline ever appeared. Same config withmodel: { primary: "openai/gpt-5.5" }(non-CLI) routes torunEmbeddedPiAgent, fires the hook, and produces the expected promotion-complete line.Suggested fix
Mirror the
before_agent_replyblock fromsrc/agents/pi-embedded-runner/run.ts:326into the CLI runner (gated ontrigger === "cron"at minimum). Small follow-up PR.Adjacent options if the above is too invasive: docs caveat in
docs/concepts/dreaming.md, or a startupwarnlog when the dreaming cron is reconciled against a CLI-backed default agent.Identified by
@chatgpt-codex-connector during PR #70737 review.