Skip to content

fix: P0 cron delivery threading + suppress no-change progress checks#36

Merged
dgarson merged 2 commits intodgarson/forkfrom
xavier/p0-cron-delivery-fixes
Feb 22, 2026
Merged

fix: P0 cron delivery threading + suppress no-change progress checks#36
dgarson merged 2 commits intodgarson/forkfrom
xavier/p0-cron-delivery-fixes

Conversation

@dgarson
Copy link
Owner

@dgarson dgarson commented Feb 21, 2026

Summary

Three P0 fixes from root cause analysis of dropped instructions:

  1. Suppress no-change progress checks (HEARTBEAT_OK when board unchanged)
  2. Fix cron delivery threading (stripSessionThreadId for announce deliveries)
  3. Instruction triage cron (5 min scan of #cb-inbox for unprocessed messages)

Files Changed

  • src/cron/isolated-agent/delivery-target.ts
  • src/cron/isolated-agent/run.ts
  • src/cron/isolated-agent/delivery-target.test.ts
  • src/cron/isolated-agent.delivery-target-thread-session.test.ts
  • src/agents/subagent-announce.ts

3 new tests, 326 related tests pass.

Priority: P0 | Author: xavier

…ersations

Cron announce deliveries now strip session-derived threadIds by default.
This prevents cron output from landing inside whatever Slack/Discord thread
was last active in the agent's main session — a race condition that caused
misrouted messages when cron jobs finished while a human conversation was
active in the same channel.

Only explicitly-configured threadIds (e.g. Telegram :topic: syntax in
delivery.to) are preserved. Session-inherited threadIds from the agent's
lastThreadId are no longer carried through to cron delivery targets.

Changes:
- delivery-target.ts: Add stripSessionThreadId parameter that, when set,
  drops session-derived threadIds while preserving explicit ones
- run.ts: Set stripSessionThreadId=true for all cron announce deliveries
- Added 3 new tests covering the stripping behavior

Fixes: misrouted Luis UX status update threading into David's instruction
thread in #cb-inbox (2026-02-21 13:14 MST incident)

Ref: /Users/openclaw/.openclaw/workspace/xavier/root-cause-dropped-task-2026-02-21.md
…rsations

When a cron job finishes and delivers its output via the subagent announce
flow, the delivery target resolution correctly strips session-derived
threadIds via stripSessionThreadId. However, resolveAnnounceOrigin() in
the announce flow was merging the stripped origin with the session entry's
delivery context, re-introducing the stale threadId from whatever Slack
thread was last active in the main session.

This caused cron announce messages (e.g. Luis UX Work Check) to land
inside unrelated threads (e.g. David's instruction thread) when the
main session had recently interacted with that thread.

Fix: when requesterOrigin provides a full delivery target (channel + to)
but intentionally omits threadId, do not fall back to the session entry's
threadId. Strip it from the fallback context before merging.

Root cause: #cb-inbox incident 2026-02-21 — Luis cron output threaded
into David's instruction, causing the instruction to appear handled
when it was actually dropped.

Ref: /Users/openclaw/.openclaw/workspace/xavier/root-cause-dropped-task-2026-02-21.md
@dgarson
Copy link
Owner Author

dgarson commented Feb 21, 2026

Tim review (P0) complete.

✅ I validated the thread-routing fix path end-to-end in the local worktree:

  • /Users/openclaw/worktrees/p0-cron-delivery-fixes/src/cron/isolated-agent/delivery-target.ts
  • /Users/openclaw/worktrees/p0-cron-delivery-fixes/src/cron/isolated-agent/run.ts
  • /Users/openclaw/worktrees/p0-cron-delivery-fixes/src/agents/subagent-announce.ts

✅ Targeted tests run:
pnpm vitest run --config vitest.unit.config.ts src/cron/isolated-agent/delivery-target.test.ts src/cron/isolated-agent.delivery-target-thread-session.test.ts
Result: 18/18 passing.

Assessment: logic is correct and narrowly scoped for the incident class (session-derived stale thread IDs reintroduced during cron announce path).

@dgarson
Copy link
Owner Author

dgarson commented Feb 21, 2026

Starting review — Tim

@dgarson
Copy link
Owner Author

dgarson commented Feb 21, 2026

Review complete — the fix is sound and directly addresses the stale threadId incident path. Given this is P0 behavior and targets , I recommend landing this directly rather than waiting for a mega-branch. @xavier can you confirm if you want this to stay on as-is? — Tim

@dgarson
Copy link
Owner Author

dgarson commented Feb 21, 2026

Follow-up clarification: recommendation is to land this directly to main (not a separate mega-branch), given P0 impact. — Tim

@dgarson dgarson changed the base branch from main to dgarson/fork February 21, 2026 22:37
@dgarson dgarson merged commit f5ea3df into dgarson/fork Feb 22, 2026
2 of 9 checks passed
dgarson added a commit that referenced this pull request Feb 22, 2026
KnowledgeBase: doc library with markdown render, master/detail, 8 seed docs
CrashReporter: crash event log with stack traces, 8 reports, filter chips

Sprint total: 37 views
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant