Skip to content

fix(auto-reply): deliver /compact in room_event via explicit-command bypass; notifyUser independent of internal callbacks (#87107)#87171

Merged
steipete merged 1 commit into
openclaw:mainfrom
openperf:fix/87107-compact-reply-and-notify-user
May 29, 2026
Merged

fix(auto-reply): deliver /compact in room_event via explicit-command bypass; notifyUser independent of internal callbacks (#87107)#87171
steipete merged 1 commit into
openclaw:mainfrom
openperf:fix/87107-compact-reply-and-notify-user

Conversation

@openperf

@openperf openperf commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

  • Problem: Issue /compact command reply silently dropped after upgrade to 2026.5.22 (delivered=true but no actual delivery) #87107 reports three silent-delivery failures of /compact and compaction notices on OpenClaw 2026.5.22. (a) Authorized /compact reply silently dropped on Feishu / WebChat room_event channels — reporter's logs show delivered=true but no deliver: sending text chunks and no Feishu API call. (b) Adjacent: command-handler terminal replies (/status, skill-tool blocked / error) silently dropped under messages.visibleReplies: "message_tool" configs even on DM. (c) agents.defaults.compaction.notifyUser: true notices silently skipped whenever any internal onCompactionStart / onCompactionEnd callback is registered (e.g. by Control UI).
  • Root Cause:
    • (a) room_event bypass too coarse: src/auto-reply/reply/dispatch-from-config.ts rejected deliverDespiteSourceReplySuppression for every ctx.InboundEventKind === "room_event", conflating user-initiated command terminal replies with ambient runtime failure notices. The dispatch-from-config.test.ts suppresses marked runtime failure notices for room events test was protecting ambient privacy but locked the bypass too tight, so the marker had no effect for the exact channels the reporter was using.
    • (b) command-handler terminal replies missing marker: src/auto-reply/reply/get-reply-inline-actions.ts returned { kind: "reply", reply } for six terminal paths (skill-tool not-available, blocked, success, error, inline-action terminal command reply, top-level terminal command reply) without calling markReplyPayloadForSourceSuppressionDelivery, even though peer system-meta replies (model-fallback warning in agent-runner.ts, embedded-runner errors in payloads.ts) already use the same marker. Result: even after (a), the suppress branch would still drop them.
    • (c) compaction notice gated on internal-callback absence: src/auto-reply/reply/agent-runner-execution.ts (the else if chain introduced by feat: send compaction start and completion notices #67830 to de-duplicate between internal callbacks and the default notice) gated the default notifyUser notice on the absence of onCompactionStart / onCompactionEnd. Audited every production onCompactionEnd consumer: extensions/telegram + extensions/discord + extensions/whatsapp use reaction-emoji controllers (setThinking()), extensions/feishu clears a streaming-status line, and src/agents/pi-embedded-subscribe.handlers.compaction.ts (the pi-embedded / Control UI implementation) writes a log + reconciles a counter + emits an internal agent-event. None emit user-visible chat text. The intended de-duplication had no runtime competitor; the gate suppressed the documented 🧹 Compaction complete notice (per docs/gateway/config-agents.md) without anything filling the gap. ClawSweeper review on /compact command reply silently dropped after upgrade to 2026.5.22 (delivered=true but no actual delivery) #87107 also flagged this as source-reproducible against the same doc.
  • Fix:
    • (a) Narrow the shouldDeliverDespiteSourceReplySuppression precondition in src/auto-reply/reply/dispatch-from-config.ts from "never in room_event" to "in room_event only if the current ctx is an explicit command turn" (isExplicitSourceReplyCommand(ctx, cfg) — the same helper the source-reply visibility policy uses; matches native commands, authorized text-slash, and the legacy CommandAuthorized + CommandBody fallback via isExplicitCommandTurnContext). Ambient marked notices and sendPolicy: deny stay suppressed.
    • (b) Apply markReplyPayloadForSourceSuppressionDelivery at the src/auto-reply/reply/get-reply-inline-actions.ts chokepoint via a local helper that wraps every terminal { kind: "reply" } exit. Mirrors the marker pattern already used for the model-fallback and embedded-runner notices.
    • (c) Split the else if chain in src/auto-reply/reply/agent-runner-execution.ts (start / completed-end / non-completed-end branches) so the user-channel notice fires on its documented contract while internal callbacks continue to fire on their own (non-chat-text) channels — reactions, status indicators, agent-events. hookMessages.length > 0 still suppresses the default notice in the same phase because that IS a real chat-text overlap (plugin-authored user-channel text on the same channel).
  • What changed:
    • src/auto-reply/reply/dispatch-from-config.ts — narrow the bypass predicate via the shared isExplicitSourceReplyCommand(ctx) helper from source-reply-delivery-mode.ts so the bypass and the visibility policy stay aligned.
    • src/auto-reply/reply/dispatch-from-config.test.ts — two new dispatch-level tests: delivers marked explicit command terminal replies in room events (#87107) (CommandSource: "text" shape) and delivers marked /compact reply in room event when CommandSource is undefined (#87107) (legacy CommandAuthorized: true + CommandBody: "/compact" shape that isExplicitSourceReplyCommand now resolves via the control-command-body fallback); existing ambient-failure room-event test stays as-is.
    • src/auto-reply/reply/get-reply-inline-actions.tsmarkCommandReplyForDelivery local helper around six terminal returns.
    • src/auto-reply/reply/get-reply-inline-actions.skip-when-config-empty.test.ts — new test asserting the marker.
    • src/auto-reply/reply/agent-runner-execution.ts — split the else if chain.
    • src/auto-reply/reply/agent-runner-execution.test.ts — rewrote the previously-passing test that locked in the buggy else if behavior; new assertions cover both callbacks AND both notices firing.
  • What did NOT change (scope boundary):
    • src/auto-reply/reply/source-reply-delivery-mode.ts — policy resolver untouched.
    • src/auto-reply/reply-payload.ts — marker helper unchanged.
    • The ambient room-event suppression contract (no CommandTurn → still suppressed in room_event) is preserved by the existing suppresses marked runtime failure notices for room events test, which keeps passing.
    • sendPolicy: deny continues to suppress every reply regardless of marker.
    • Config surface unchanged (no schema, defaults, doctor migrations, or docs/reference/config edits).
    • Plugin surface unchanged (no plugin SDK, manifest, extensions/api.ts / runtime-api.ts, registry, or loader edits).

Reproduction

  1. On 2026.5.22, configure agents.defaults.compaction.notifyUser: true and accumulate a long conversation (70k+ tokens) so /compact produces a non-trivial summary.
  2. Send /compact from a WebChat / Feishu room-event channel.
  3. Before this PR: no /compact summary appears in the user channel; no compaction start / end notice appears; gateway log shows command was dispatched but no channel adapter send.
  4. After this PR: /compact summary appears (room_event explicit-command bypass); both 🧹 Compacting context… and 🧹 Compaction complete notices appear (notifyUser fires independently of internal callbacks).

Real behavior proof

Behavior addressed (#87107): room_event source-suppression now honors the existing deliverDespiteSourceReplySuppression marker for explicit command turns (native or authorized text-slash), command-handler terminal replies from inline-actions now carry that marker, and the compaction notifyUser notice is no longer gated on internal-callback absence.

Real environment tested (Linux, Node 22, real-component tsx harness driving production source modules against origin/main HEAD): tsx-resolved imports of production resolveSourceReplyVisibilityPolicy, markReplyPayloadForSourceSuppressionDelivery, getReplyPayloadMetadata, and isExplicitSourceReplyCommand(ctx, cfg) (which now routes through isExplicitCommandTurnContext and covers the legacy CommandAuthorized + CommandBody shape without CommandSource). The harness mirrors the post-fix dispatch-from-config decision verbatim across six behavior-relevant scenarios.

Exact steps or command run after this patch:

  1. node_modules/.bin/tsx /tmp/qmd87107/repro.mts (real-component policy + marker + command-turn sweep)
  2. node scripts/run-vitest.mjs src/auto-reply/reply/dispatch-from-config.test.ts src/auto-reply/reply/get-reply-inline-actions.skip-when-config-empty.test.ts src/auto-reply/reply/agent-runner-execution.test.ts
  3. pnpm exec oxfmt --check --threads=1 src/auto-reply/reply/dispatch-from-config.ts src/auto-reply/reply/dispatch-from-config.test.ts src/auto-reply/reply/get-reply-inline-actions.ts src/auto-reply/reply/get-reply-inline-actions.skip-when-config-empty.test.ts src/auto-reply/reply/agent-runner-execution.ts src/auto-reply/reply/agent-runner-execution.test.ts

Evidence after fix (verbatim real-component harness output):

================ #87107 real-component scenario sweep ================

Drives production resolveSourceReplyVisibilityPolicy,
markReplyPayloadForSourceSuppressionDelivery, and
isExplicitSourceReplyCommand against dispatch-from-config decision after
the #87107 narrow-bypass fix.

--- Feishu DM, authorized /compact (text-slash, authorized=true)
    sourceReplyDeliveryMode  = automatic
    suppressDelivery         = false
    isExplicitSourceReplyCmd = true
    before fix               = delivered
    after  fix               = delivered
    fix helps?               = false  (expected: false)  OK

--- room_event, AUTHORIZED /compact, NO CommandSource (legacy fallback via isControlCommandMessage)
    sourceReplyDeliveryMode  = message_tool_only
    suppressDelivery         = true
    isExplicitSourceReplyCmd = true
    before fix               = silently-dropped
    after  fix               = delivered
    fix helps?               = true  (expected: true)  OK

--- WebChat / Feishu group room_event, AUTHORIZED /compact (text-slash)
    sourceReplyDeliveryMode  = message_tool_only
    suppressDelivery         = true
    isExplicitSourceReplyCmd = true
    before fix               = silently-dropped
    after  fix               = delivered
    fix helps?               = true  (expected: true)  OK

--- room_event AMBIENT marked reply (no CommandTurn — runtime failure notice)
    sourceReplyDeliveryMode  = message_tool_only
    suppressDelivery         = true
    isExplicitSourceReplyCmd = false
    before fix               = silently-dropped
    after  fix               = silently-dropped
    fix helps?               = false  (expected: false)  OK

--- Feishu DM, messages.visibleReplies=message_tool, NON-command reply (skill-tool blocked etc.)
    sourceReplyDeliveryMode  = message_tool_only
    suppressDelivery         = true
    isExplicitSourceReplyCmd = false
    before fix               = silently-dropped
    after  fix               = delivered
    fix helps?               = true  (expected: true)  OK

--- Feishu DM, messages.visibleReplies=message_tool, UNAUTHORIZED /compact text-slash
    sourceReplyDeliveryMode  = message_tool_only
    suppressDelivery         = true
    isExplicitSourceReplyCmd = false
    before fix               = silently-dropped
    after  fix               = delivered
    fix helps?               = true  (expected: true)  OK

================ VERDICT ================
PASS — every scenario matches expectations.

Vitest output for the three touched test files:

 RUN  v4.1.7 /root/main/openclaw/.worktrees/pr-87107

 Test Files  3 passed (3)
      Tests  336 passed (336)
   Duration  32.88s

Observed result after fix:

  • Authorized /compact in room_event (Feishu group / WebChat-as-room) moves from silently-dropped to delivered — the exact branch issue /compact command reply silently dropped after upgrade to 2026.5.22 (delivered=true but no actual delivery) #87107 hits for the reported channels.
  • Ambient marked reply (no CommandTurn) in room_event stays silently-dropped, preserving the existing privacy contract pinned by suppresses marked runtime failure notices for room events.
  • Under messages.visibleReplies: "message_tool" configs, marker recovers non-explicit / unauthorized-command paths (adjacent hygiene).
  • Authorized /compact on DM was already delivered (policy short-circuits to automatic) and stays so.
  • compaction.notifyUser: true with both internal callbacks registered now produces both callbacks AND both user-channel notices (was: 0 notices).

What was not tested:

  • End-to-end live Feishu / WebChat channel send. The real-component harness drives the production policy + marker + explicit-command-turn predicate end-to-end but does not invoke the channel adapter; touched-surface unit tests cover the dispatch-layer behavior.
  • sendPolicy: deny semantics were not re-tested in this PR (unchanged).

Regression tests:

  • dispatch-from-config.test.tsdelivers marked explicit command terminal replies in room events (#87107) (CommandSource: "text" shape) + delivers marked /compact reply in room event when CommandSource is undefined (#87107) (legacy fallback shape) + the preserved suppresses marked runtime failure notices for room events (ambient privacy contract).
  • get-reply-inline-actions.skip-when-config-empty.test.ts → marker presence on terminal command replies.
  • agent-runner-execution.test.ts → both callbacks + both notices fire when compaction.notifyUser is enabled.

Risk / Mitigation

  • Risk: Widening the bypass for explicit command turns in room_event could leak ambient runtime warnings to group chats. Mitigation: the new predicate only matches isExplicitSourceReplyCommand (native command or authorized text-slash) — the same helper already used by the source-reply visibility policy, so the bypass and the policy stay aligned; ambient notices (no CommandTurn) keep the existing suppression, pinned by suppresses marked runtime failure notices for room events which still passes.
  • Risk: Marker on command-handler replies could mask suppression elsewhere. Mitigation: marker is only consulted under suppressAutomaticSourceDelivery && !sendPolicyDenied; sendPolicy: deny still drops everything regardless of marker.
  • Risk: Independent notifyUser notice could over-notify when a plugin also sends a hookMessage for the same phase. Mitigation: hookMessages.length > 0 still suppresses the default notice in that phase (same user channel, one text per phase preserved).
  • Risk: Rewriting prefers onCompactionEnd callback over default notice when notifyUser is enabled (introduced by feat: send compaction start and completion notices #67830) could mask a legitimate de-duplication constraint. Mitigation: audited every production onCompactionEnd consumer in the repo — extensions/telegram, extensions/discord, extensions/whatsapp (reaction emoji), extensions/feishu (streaming-status-line clear), src/agents/pi-embedded-subscribe.handlers.compaction.ts (log + counter reconcile + internal agent-event). None emit user-visible chat text, so there is no chat-text source for the default notice to de-duplicate against. The original else if would have removed the only user-channel chat notice; this restores the documented docs/gateway/config-agents.md contract.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Gateway / orchestration
  • Integrations
  • Sessions / storage

Linked Issue/PR

Fixes #87107

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 29, 2026, 2:38 AM ET / 06:38 UTC.

Summary
The PR broadens the marked explicit-command reply bypass for room_event, marks command-handler terminal replies for source-suppression delivery, and decouples notifyUser compaction notices from internal compaction callbacks with targeted tests.

PR surface: Source +31, Tests +125. Total +156 across 6 files.

Reproducibility: yes. for the core paths by source inspection: current main still suppresses marked room_event final replies and gates notifyUser notices on callback absence. The exact Feishu/WebChat live transport symptom is supported by reporter logs but was not live-reproduced in this read-only review.

Review metrics: 1 noteworthy metric.

  • Message-delivery gates: 2 existing gates changed, 0 config surfaces added. The patch changes final-reply suppression and compaction notice gating without adding a new operator-facing configuration surface.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Review the current-main merge result around dispatchReplyFromConfig because nearby delivery work landed after the PR base.
  • [P2] Optionally request a redacted Feishu or WebChat /compact room-event smoke if live transport proof is required before merge.

Risk before merge

  • [P1] The PR intentionally broadens a shared final-reply delivery bypass for marked explicit command turns, so a maintainer should verify the merge result still preserves ambient room_event suppression and sendPolicy: deny.
  • [P1] The proof is strong source-level terminal output plus focused tests, but it does not include a live Feishu/WebChat transport smoke for the originally reported channels.
  • [P1] Current main has recent nearby edits in dispatchReplyFromConfig, so this branch should be reviewed against the actual merge result rather than only the original PR base.

Maintainer options:

  1. Accept the targeted delivery change (recommended)
    A maintainer can land after reviewing the merge result and accepting source-level proof for the marked explicit-command bypass and independent notifyUser notices.
  2. Require live Feishu or WebChat smoke
    If source-level proof is not enough for this channel-visible regression, ask for one redacted live /compact room-event smoke before merge.
  3. Pause for conflict coordination
    If overlapping auto-reply delivery PRs are landing first, pause this branch until the shared dispatchReplyFromConfig changes can be reviewed in one merge result.

Next step before merge

  • [P2] Member-authored PR with no blocking findings, green current-head checks, and shared message-delivery risk should get explicit maintainer review rather than an automated repair lane.

Security
Cleared: The diff only touches auto-reply source and tests; it does not change dependencies, workflows, package metadata, credentials, permissions, or code-download surfaces.

Review details

Best possible solution:

Land the focused shared auto-reply fix after maintainer review confirms the current-main merge result keeps ambient room-event privacy while restoring visible command and compaction status delivery.

Do we have a high-confidence way to reproduce the issue?

Yes for the core paths by source inspection: current main still suppresses marked room_event final replies and gates notifyUser notices on callback absence. The exact Feishu/WebChat live transport symptom is supported by reporter logs but was not live-reproduced in this read-only review.

Is this the best way to solve the issue?

Yes, the proposed direction is the narrow shared fix: mark command terminal replies, allow only explicit command room-event bypasses, and keep hook-message overlap suppression for compaction notices. A Feishu-only workaround would be less maintainable.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 4829d30cf015.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a production-module harness plus targeted Vitest and formatter commands; it does not include live Feishu/WebChat transport proof.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal output from a production-module harness plus targeted Vitest and formatter commands; it does not include live Feishu/WebChat transport proof.
  • remove rating: 🌊 off-meta tidepool: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P1: This PR targets a latest-release regression where a core /compact workflow can report success while user-visible channel feedback is silently lost.
  • merge-risk: 🚨 message-delivery: The diff changes whether marked command and compaction status replies are delivered or suppressed across shared auto-reply channel paths.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal output from a production-module harness plus targeted Vitest and formatter commands; it does not include live Feishu/WebChat transport proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a production-module harness plus targeted Vitest and formatter commands; it does not include live Feishu/WebChat transport proof.
Evidence reviewed

PR surface:

Source +31, Tests +125. Total +156 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 3 49 18 +31
Tests 3 130 5 +125
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 179 23 +156

What I checked:

  • Repository policy read: Root AGENTS.md was read fully; no scoped AGENTS.md owns src/auto-reply/reply/**, and the root policy treats channel delivery, fallback behavior, and message delivery as review-sensitive. (AGENTS.md:1, 4829d30cf015)
  • Current main suppresses marked room_event replies: The current main final delivery bypass requires ctx.InboundEventKind !== "room_event", so a marked /compact terminal reply is still suppressed in the reported room-event path before this PR. (src/auto-reply/reply/dispatch-from-config.ts:2705, 4829d30cf015)
  • Current main terminal command replies are unmarked: Current command-handler terminal replies return directly from handleInlineActions without deliverDespiteSourceReplySuppression metadata, matching the PR's second repair target. (src/auto-reply/reply/get-reply-inline-actions.ts:558, 4829d30cf015)
  • Current main gates notifyUser behind callback absence: The compaction handler only sends start/end user notices in else if branches guarded by missing onCompactionStart or onCompactionEnd, despite the config/docs contract for user notices. (src/auto-reply/reply/agent-runner-execution.ts:2436, 4829d30cf015)
  • Documented notifyUser contract: The docs say notifyUser: true sends notices when compaction starts and completes, which supports treating callback-gated suppression as a bug rather than a new feature request. Public docs: docs/gateway/config-agents.md. (docs/gateway/config-agents.md:648, 4829d30cf015)
  • PR patch scope: The downloaded PR patch changes six files: three source files and three focused tests, with no dependency, workflow, lockfile, package, config, or plugin API edits. (ae53d027c471)

Likely related people:

  • Ayaan Zaidi: Authored the current-main room-event progress-suppression commit touching dispatch-from-config immediately after this PR was opened. (role: recent dispatch area contributor; confidence: high; commits: c559776c51af; files: src/auto-reply/reply/dispatch-from-config.ts, src/auto-reply/reply/dispatch-from-config.test.ts)
  • Peter Lindsey: Authored the recent current-main change forwarding channel-owned progress callbacks through the same dispatch progress-callback gate. (role: adjacent dispatch progress contributor; confidence: high; commits: 85b6f91bd75a; files: src/auto-reply/reply/dispatch-from-config.ts)
  • feniix: Authored the merged compaction start/completion notice feature that established the notifyUser user-visible contract this PR repairs. (role: compaction notice feature contributor; confidence: medium; commits: f48d040bf523; files: src/auto-reply/reply/agent-runner-execution.ts, src/auto-reply/reply/agent-runner-execution.test.ts, docs/gateway/config-agents.md)
  • Ted Li: The central current-main lines in the checked-out grafted history blame to the recent fix(agents): enforce subagent run timeouts commit, so this is a routing hint rather than a precise introduction claim. (role: current-main blame signal; confidence: low; commits: 8a60f39221db; files: src/auto-reply/reply/dispatch-from-config.ts, src/auto-reply/reply/get-reply-inline-actions.ts, src/auto-reply/reply/agent-runner-execution.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels May 27, 2026
@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Cosmic Branchling

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: collects tiny proofs.
Image traits: location workflow harbor; accessory proof snapshot camera; palette sunrise gold and clean white; mood patient; pose stepping out of a freshly hatched shell; shell soft speckled shell; lighting cool dashboard glow; background soft code-shaped tiles.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Cosmic Branchling in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@openperf openperf changed the title fix(auto-reply): deliver /compact replies and notifyUser notices independent of source-suppression and internal callbacks fix(auto-reply): notifyUser independent of internal callbacks; mark command-handler replies (refs #87107) May 27, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels May 27, 2026
@openperf openperf changed the title fix(auto-reply): notifyUser independent of internal callbacks; mark command-handler replies (refs #87107) fix(auto-reply): deliver /compact in room_event via explicit-command bypass; notifyUser independent of internal callbacks (#87107) May 27, 2026
@openperf openperf force-pushed the fix/87107-compact-reply-and-notify-user branch from 909f696 to d92d021 Compare May 27, 2026 05:55
@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 27, 2026
@openperf openperf force-pushed the fix/87107-compact-reply-and-notify-user branch from d92d021 to 0cd11b8 Compare May 27, 2026 06:21
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels May 27, 2026
@openperf openperf force-pushed the fix/87107-compact-reply-and-notify-user branch from 0cd11b8 to d029447 Compare May 27, 2026 06:43
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 27, 2026
@openperf openperf requested a review from a team as a code owner May 27, 2026 12:49
@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label May 27, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat labels May 27, 2026
@BingqingLyu

This comment was marked as spam.

…icit command turns; deliver /compact + notifyUser independently of internal callbacks

Three distinct silent-delivery failures of /compact and compaction
notices on 2026.5.22 (openclaw#87107):

1. dispatch-from-config previously rejected the
   deliverDespiteSourceReplySuppression marker for every room_event,
   so a marked authorized /compact reply (Feishu group / WebChat
   room-event) was silently dropped. Narrow the bypass to honor the
   marker when the current ctx represents an explicit command turn
   (isExplicitCommandTurn: native or authorized text-slash); ambient
   marked runtime failure notices and sendPolicy: deny stay
   suppressed.

2. handleInlineActions terminal replies (/compact, /status, skill
   tool blocked / error replies) did not carry the marker, so the
   same suppress branch silently dropped them under
   messages.visibleReplies: "message_tool" configs. Wrap every
   { kind: "reply", reply } exit in a local helper that calls
   markReplyPayloadForSourceSuppressionDelivery.

3. The compaction-event handler in runAgentTurnWithFallback gated
   notifyUser on the absence of onCompactionStart / onCompactionEnd
   callbacks, conflating internal Control-UI callbacks with the
   opt-in user-channel notice. Drop the callback predicates from the
   gate so notifyUser fires whenever configured; keep hookMessages
   overlap suppression (same user-channel audience).

Refs openclaw#87107
@steipete

Copy link
Copy Markdown
Contributor

Maintainer verification before merge:

Behavior addressed: /compact terminal replies and opt-in compaction notices were silently suppressed on room-event/message-tool-only delivery paths.

Real environment tested: local source checkout on rebased PR head d3aaad90fcc16588103ae63d7d776f2e4229d8cf, based on origin/main d4a17477b0b5beb9737460f910538eebbea04ca6.

Exact steps or command run after this patch:

  • git rebase origin/main
  • git diff --check origin/main...HEAD
  • node scripts/run-vitest.mjs src/auto-reply/reply/dispatch-from-config.test.ts src/auto-reply/reply/get-reply-inline-actions.skip-when-config-empty.test.ts src/auto-reply/reply/agent-runner-execution.test.ts

Evidence after fix:

  • Rebase onto current origin/main completed cleanly.
  • git diff --check origin/main...HEAD passed.
  • Focused Vitest passed: 3 test files, 346 tests.

Observed result after fix: marked explicit command replies can bypass source suppression in room_event only for explicit command turns, terminal command replies are marked at the command-handler chokepoint, and notifyUser compaction notices fire independently of internal callbacks while hook messages still suppress duplicate default notices.

What was not tested: live Feishu/WebChat transport. The proof is source-level dispatch/command/compaction coverage plus CI on the exact pushed head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/compact command reply silently dropped after upgrade to 2026.5.22 (delivered=true but no actual delivery)

4 participants