fix(cron): mirror announce delivery into destination session#80786
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. Source inspection on current main shows direct cron delivery uses params.agentSessionKey for outbound session context, and the PR body provides before/after terminal proof where the delivered WhatsApp token was absent before and present once after the patch. Real behavior proof Next step before merge Security Review detailsBest possible solution: Land this coordinated cron transcript mirror fix after CI and maintainer review, then resolve the narrower related work at #74913 and the linked cron-session issues against the merged behavior. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main shows direct cron delivery uses params.agentSessionKey for outbound session context, and the PR body provides before/after terminal proof where the delivered WhatsApp token was absent before and present once after the patch. Is this the best way to solve the issue? Yes. Resolving the destination session before send and appending a best-effort mirror only after successful delivery is the narrow maintainable fix; the duplicate guard preserves main-session awareness policy. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against daef8e73fc92. |
|
The after-fix proof is already in the body under Real behavior proof → Evidence after fix: redacted terminal output for the cron run-log JSON, |
|
Note on the latest test-only commit ( Those tests used static registry imports while mocking Happy to split or drop this test-only commit if maintainers prefer the PR to stay strictly limited to the cron/session changes. |
51c5f0b to
22b3def
Compare
|
Rebased onto current main; folded in two small cleanups (preserve media filenames in awareness-mirror text; add |
22b3def to
3e6b99e
Compare
|
Caught up to c0fe7ab (system-event authority field landed an hour ago); test assertions updated to include Re-review progress:
|
3e6b99e to
1bf70b5
Compare
1bf70b5 to
bec9d7d
Compare
|
Landed via rebase onto main.
Thanks @cavit99! |
Summary
Fixes #80468.
Cron direct announce delivery could successfully send a message to a channel while leaving the destination channel session transcript unaware of that assistant message. Later
sessions_historyreads from the channel session could therefore miss cron reports that the user had already received in chat.This PR updates isolated cron direct delivery to:
deleteAfterRuncleanup for non-cron session keysIt also tightens fallback outbound session classification for resolver-less channels: plugin-owned target parsing wins first, and core only handles explicit semantic prefixes like
user:,channel:, andgroup:.Related: #74913 covers adjacent cron transcript mirroring work for a narrower
session:<id>path. This PR covers destination channel-session mirroring for cron direct announce delivery.Real behavior proof
Behavior or issue addressed:
Cron direct announce delivery to a WhatsApp DM should be visible in that WhatsApp DM session transcript /
sessions_history.Real environment tested:
macOS mac-mini running OpenClaw installed from the PR branch tarball at SHA
97c6640688(openclaw-2026.5.10-beta.1.tgz, built viapnpm install --frozen-lockfile && pnpm run build && pnpm pack). WhatsApp channel enabled,cfg.session.dmScope = "per-channel-peer". Base release before the swap:[email protected].Exact steps or command run after this patch:
Evidence after fix:
OpenClaw version / package source:
Synthetic token used:
REPRO_TOKEN_AFTER_FIX_7a4611d7Cron run succeeded + WhatsApp delivery succeeded from
~/.openclaw/cron/runs/<job-id>.jsonl:{ "status": "ok", "delivered": true, "deliveryStatus": "delivered", "delivery": { "resolved": { "ok": true, "channel": "whatsapp", "to": "+15551234567", "accountId": "default", "source": "explicit" }, "fallbackUsed": true, "delivered": true }, "summary": "REPRO_TOKEN_AFTER_FIX_7a4611d7", "sessionKey": "agent:main:cron:<job-id>:run:<worker-id>" }sessions_history/ direct transcript grep finds the token in the resolved WhatsApp DM session:The single entry, inspected:
The DM session id corresponds to session key
agent:main:whatsapp:direct:+15551234567, the resolved destination session, not the isolated cron worker session.Observed result after fix:
The fresh token delivered by cron appears in the destination WhatsApp DM session transcript as a
role=assistantmirror entry. Hit count is 1, versus 0 hits in the same session under the before-fix stable repro on[email protected], where the identical synthetic cron token was present only in the cron run log and the auto-deleted isolated worker session.What was not tested:
Other channels (Discord, Telegram, Slack) and
dmScope: "main"/ non-per-channel-peer setups were not live-tested on this box. They are covered by targeted unit/seam tests insrc/cron/isolated-agent/delivery-dispatch.double-announce.test.tsandsrc/infra/outbound/outbound-session.test.ts.Before evidence:
Cron-delivered messages not visible in channel session context #80468 (comment) — same shape of synthetic cron on
[email protected]produceddelivered: truewith 0 hits of the unique token in the same destination DM session jsonl.Root Cause
Root cause:
Cron direct announce delivery sent outbound payloads using the cron run session context without appending the successfully delivered assistant output into the resolved destination channel session transcript.
Missing detection / guardrail:
Existing tests covered successful delivery and awareness queueing, but did not assert that explicit channel cron delivery mirrors into the destination session used by later
sessions_historyreads.Contributing context:
Main-session awareness is a separate system-event path and does not replace the destination channel transcript entry for per-channel-peer DM sessions.
Regression Test Plan
Coverage level that should have caught this:
Target test or file:
src/cron/isolated-agent/delivery-dispatch.double-announce.test.tsandsrc/infra/outbound/outbound-session.test.tsScenario the test should lock in:
Isolated cron direct announce delivery resolves the destination channel session, bootstraps the session entry when needed, and appends the delivered assistant text to that destination session only after successful delivery.
Why this is the smallest reliable guardrail:
It exercises the cron dispatch/outbound-session seam without requiring live channel credentials, while the live proof above verifies the real WhatsApp behavior end to end.
User-visible / Behavior Changes
Cron direct announce messages are now visible in the destination channel session transcript after successful delivery, so later turns on that channel can see what the cron job sent.
Security Impact
NoNoNoNoNoVerification
[email protected]: synthetic cron delivery reached WhatsApp, but the fresh token had 0 hits in the WhatsApp DM session transcript.role=assistant.pnpm test src/cron/isolated-agent/delivery-dispatch.double-announce.test.ts src/infra/outbound/outbound-session.test.ts -- --reporter=verbosepnpm exec oxfmt --check --threads=1 src/cron/isolated-agent/delivery-dispatch.ts src/cron/isolated-agent/delivery-dispatch.double-announce.test.ts src/infra/outbound/outbound-session.ts src/infra/outbound/outbound-session.test.ts src/infra/outbound/outbound-session.test-helpers.tsgit diff --checkpnpm check:changed