{"type":"system","subtype":"init","cwd":"./bench/results/mcp-no-toolsearch/weekly_catchup/run1/workspace","session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","tools":["Task","TaskOutput","Bash","Glob","Grep","ExitPlanMode","Read","Edit","Write","NotebookEdit","WebFetch","TodoWrite","WebSearch","TaskStop","AskUserQuestion","Skill","EnterPlanMode","EnterWorktree","ExitWorktree","CronCreate","CronDelete","CronList","mcp__chrome-devtools__click","mcp__chrome-devtools__close_page","mcp__chrome-devtools__drag","mcp__chrome-devtools__emulate","mcp__chrome-devtools__evaluate_script","mcp__chrome-devtools__fill","mcp__chrome-devtools__fill_form","mcp__chrome-devtools__get_console_message","mcp__chrome-devtools__get_network_request","mcp__chrome-devtools__handle_dialog","mcp__chrome-devtools__hover","mcp__chrome-devtools__lighthouse_audit","mcp__chrome-devtools__list_console_messages","mcp__chrome-devtools__list_network_requests","mcp__chrome-devtools__list_pages","mcp__chrome-devtools__navigate_page","mcp__chrome-devtools__new_page","mcp__chrome-devtools__performance_analyze_insight","mcp__chrome-devtools__performance_start_trace","mcp__chrome-devtools__performance_stop_trace","mcp__chrome-devtools__press_key","mcp__chrome-devtools__resize_page","mcp__chrome-devtools__select_page","mcp__chrome-devtools__take_memory_snapshot","mcp__chrome-devtools__take_screenshot","mcp__chrome-devtools__take_snapshot","mcp__chrome-devtools__type_text","mcp__chrome-devtools__upload_file","mcp__chrome-devtools__wait_for","mcp__github__add_comment_to_pending_review","mcp__github__add_issue_comment","mcp__github__add_reply_to_pull_request_comment","mcp__github__assign_copilot_to_issue","mcp__github__create_branch","mcp__github__create_or_update_file","mcp__github__create_pull_request","mcp__github__create_pull_request_with_copilot","mcp__github__create_repository","mcp__github__delete_file","mcp__github__fork_repository","mcp__github__get_commit","mcp__github__get_copilot_job_status","mcp__github__get_file_contents","mcp__github__get_label","mcp__github__get_latest_release","mcp__github__get_me","mcp__github__get_release_by_tag","mcp__github__get_tag","mcp__github__get_team_members","mcp__github__get_teams","mcp__github__issue_read","mcp__github__issue_write","mcp__github__list_branches","mcp__github__list_commits","mcp__github__list_issue_types","mcp__github__list_issues","mcp__github__list_pull_requests","mcp__github__list_releases","mcp__github__list_tags","mcp__github__merge_pull_request","mcp__github__pull_request_read","mcp__github__pull_request_review_write","mcp__github__push_files","mcp__github__request_copilot_review","mcp__github__run_secret_scanning","mcp__github__search_code","mcp__github__search_issues","mcp__github__search_pull_requests","mcp__github__search_repositories","mcp__github__search_users","mcp__github__sub_issue_write","mcp__github__update_pull_request","mcp__github__update_pull_request_branch","ListMcpResourcesTool","ReadMcpResourceTool","LSP"],"mcp_servers":[{"name":"chrome-devtools","status":"connected"},{"name":"github","status":"connected"},{"name":"claude.ai Google Calendar","status":"needs-auth"},{"name":"claude.ai Gmail","status":"needs-auth"}],"model":"claude-sonnet-4-6","permissionMode":"bypassPermissions","slash_commands":["update-config","debug","simplify","batch","loop","claude-api","test-driven-development","app-installer","release-notify-issues","cli-demo-recorder","readme-generator","compact","context","cost","heapdump","init","pr-comments","release-notes","review","security-review","extra-usage","insights","mcp__github__AssignCodingAgent","mcp__github__issue_to_fix_workflow"],"apiKeySource":"none","claude_code_version":"2.1.77","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan","claude-code-guide"],"skills":["update-config","debug","simplify","batch","loop","claude-api","test-driven-development","app-installer","release-notify-issues","cli-demo-recorder","readme-generator"],"plugins":[{"name":"rust-analyzer-lsp","path":"~/.claude/plugins/rust-analyzer-lsp/1.0.0"}],"uuid":"2e91620a-4245-47cb-a508-176798eadcd5","fast_mode_state":"off"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01DocAfUmrQg5Ef2qRKAph14","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Let me fetch all three pieces of information in parallel.","signature":"EuEBCkYICxgCKkC2tgFKQLhg/DLEw1nkVuEDY9+etWRUygaFerbhmn9gvVrKqfqWBYC9wqHufRkn15T+ABoa6mG3xfspHAeRu5dTEgwLtkGe0UNWFR9fp5YaDGIzxML+QgA3bjQQmCIwRYp+LMvL8+ezZf7SJ/6FtN1SWKy8eINKq0V1ZceMTEAqMzXi/TWaOjdw0ao4bsIdKkm0BKoR3CX9ipfK6f+E20tMoK/B1PZ7DZb/n7G1LX93ZfJF4Mjjb/glU/Tw5lTKSA8zAezfGfpcZMDqr0mLrsHuCVoYdH25axSxGAE="}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":6898,"cache_read_input_tokens":34648,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6898},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"823db1ae-a1f8-4b13-bae5-f7c7d7a9f623"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01DocAfUmrQg5Ef2qRKAph14","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01Qo2edY8wyNw8TYr6WK68eH","name":"mcp__github__list_issues","input":{"owner":"openclaw","repo":"openclaw","state":"OPEN","perPage":1},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":6898,"cache_read_input_tokens":34648,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6898},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"1578bc27-4b4d-4098-978a-9befa7e681aa"}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01Qo2edY8wyNw8TYr6WK68eH","type":"tool_result","content":[{"type":"text","text":"{\"issues\":[{\"number\":51832,\"title\":\"[Bug]: Multi-agent error cascade when gateway posts error messages to shared Slack channels\",\"body\":\"# [Bug]: Multi-agent error cascade when gateway posts error messages to shared Slack channels\\n\\n## Summary\\n\\nWhen multiple agents share a Slack channel with `allowBots: true`, gateway-posted error messages (e.g., OAuth failures) trigger a cascade loop. Each agent\\u0026#39;s error message triggers the other agent to attempt a response, which also fails and posts another error, creating a feedback loop of 1000+ messages in minutes.\\n\\nCritically, **no tokens are consumed** since the agents fail before any LLM call, but the Slack channel gets flooded with identical error messages and becomes unusable.\\n\\n## Steps to Reproduce\\n\\n1. Configure two agents with separate Slack bot accounts\\n2. Both agents listen in the same channel with `allowBots: true` (needed for inter-agent coordination)\\n3. Trigger an auth failure that affects both agents (e.g., OAuth token expiration)\\n4. Agent A receives any message (or heartbeat) in the shared channel\\n5. Gateway attempts to start Agent A\\u0026#39;s session, fails with auth error\\n6. Gateway posts error message to the channel: \\u0026#34;:warning: Agent failed before reply: OAuth token refresh failed...\\u0026#34;\\n7. Agent B sees the error message (it\\u0026#39;s from a bot, but `allowBots: true`)\\n8. Gateway attempts to start Agent B\\u0026#39;s session, also fails with same auth error\\n9. Gateway posts another error message\\n10. Agent A sees Agent B\\u0026#39;s error message, repeat from step 5\\n\\n## Actual Behavior\\n\\n~1000 error messages posted to a shared channel in under 2 minutes. Both agents were completely non-functional (OAuth expired), so no tokens were burned, but the channel was trashed. Required manual cleanup.\\n\\n## Expected Behavior\\n\\nThe gateway should detect and suppress error cascades. Some possible approaches:\\n\\n### Option A: Error message deduplication (simplest)\\nIf the same error message has been posted N times (e.g., 3) to the same channel within X minutes (e.g., 5), suppress further posts and log locally instead. Post a single summary message like \\u0026#34;Suppressed N identical errors. Check logs.\\u0026#34;\\n\\n### Option B: Don\\u0026#39;t trigger agent sessions on gateway error messages\\nGateway-generated error messages (`:warning: Agent failed before reply:`) should not be treated as inbound messages that trigger new agent sessions. The gateway knows it posted these itself - it could tag them and skip processing.\\n\\n### Option C: Auth failure cooldown\\nWhen an auth/OAuth error occurs, enter a cooldown period (e.g., 5 minutes) before retrying that agent. Don\\u0026#39;t attempt to start new sessions for that agent until the cooldown expires.\\n\\n### Option D: Cross-agent error awareness\\nIf Agent A just failed with an error in a channel, and Agent B is about to be triggered by that error message in the same channel, skip it. The gateway has enough context to know that the \\u0026#34;inbound message\\u0026#34; is actually an error from a sibling agent on the same gateway.\\n\\n## Relationship to Existing Issues\\n\\nRelated to #37842 (graph-aware loop detection for sessions_send), but different mechanism:\\n- #37842: agents actively sending messages to each other via `sessions_send`\\n- This issue: gateway error handler passively posting to channels, triggering other agents\\n\\nAlso related to #29745 (config validation infinite retry loop) and #3181 (runaway heartbeat loop) - all are variants of the same class: insufficient backoff/suppression on repeated failures.\\n\\n## Environment\\n\\n- OpenClaw 2026.3.13\\n- Two Slack bot accounts sharing a channel\\n- Both using `allowBots: true` for inter-agent coordination\\n- Auth: OAuth (shared account)\\n- Trigger: OAuth token expiration\\n\\n## Workaround\\n\\nCurrently no good workaround. Options considered:\\n- `allowBots: false` - breaks inter-agent coordination\\n- `allowBots: \\u0026#34;mentions\\u0026#34;` - would work but prevents agents from seeing each other\\u0026#39;s non-mention messages\\n- Adding rules to AGENTS.md - agents never start (auth fails before prompt is loaded), so behavioral rules can\\u0026#39;t help\\n\",\"state\":\"OPEN\",\"user\":{\"login\":\"scottyallen\"},\"created_at\":\"2026-03-21T19:11:59Z\",\"updated_at\":\"2026-03-21T19:11:59Z\"}],\"totalCount\":8779,\"pageInfo\":{\"hasNextPage\":true,\"hasPreviousPage\":false,\"startCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoxMTo1OS0wNzowMM71LrED\",\"endCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoxMTo1OS0wNzowMM71LrED\"}}"}]}]},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"75e97ba2-d95f-49b9-867f-1e069e8d88a7","timestamp":"2026-03-21T19:18:21.608Z","tool_use_result":[{"type":"text","text":"{\"issues\":[{\"number\":51832,\"title\":\"[Bug]: Multi-agent error cascade when gateway posts error messages to shared Slack channels\",\"body\":\"# [Bug]: Multi-agent error cascade when gateway posts error messages to shared Slack channels\\n\\n## Summary\\n\\nWhen multiple agents share a Slack channel with `allowBots: true`, gateway-posted error messages (e.g., OAuth failures) trigger a cascade loop. Each agent\\u0026#39;s error message triggers the other agent to attempt a response, which also fails and posts another error, creating a feedback loop of 1000+ messages in minutes.\\n\\nCritically, **no tokens are consumed** since the agents fail before any LLM call, but the Slack channel gets flooded with identical error messages and becomes unusable.\\n\\n## Steps to Reproduce\\n\\n1. Configure two agents with separate Slack bot accounts\\n2. Both agents listen in the same channel with `allowBots: true` (needed for inter-agent coordination)\\n3. Trigger an auth failure that affects both agents (e.g., OAuth token expiration)\\n4. Agent A receives any message (or heartbeat) in the shared channel\\n5. Gateway attempts to start Agent A\\u0026#39;s session, fails with auth error\\n6. Gateway posts error message to the channel: \\u0026#34;:warning: Agent failed before reply: OAuth token refresh failed...\\u0026#34;\\n7. Agent B sees the error message (it\\u0026#39;s from a bot, but `allowBots: true`)\\n8. Gateway attempts to start Agent B\\u0026#39;s session, also fails with same auth error\\n9. Gateway posts another error message\\n10. Agent A sees Agent B\\u0026#39;s error message, repeat from step 5\\n\\n## Actual Behavior\\n\\n~1000 error messages posted to a shared channel in under 2 minutes. Both agents were completely non-functional (OAuth expired), so no tokens were burned, but the channel was trashed. Required manual cleanup.\\n\\n## Expected Behavior\\n\\nThe gateway should detect and suppress error cascades. Some possible approaches:\\n\\n### Option A: Error message deduplication (simplest)\\nIf the same error message has been posted N times (e.g., 3) to the same channel within X minutes (e.g., 5), suppress further posts and log locally instead. Post a single summary message like \\u0026#34;Suppressed N identical errors. Check logs.\\u0026#34;\\n\\n### Option B: Don\\u0026#39;t trigger agent sessions on gateway error messages\\nGateway-generated error messages (`:warning: Agent failed before reply:`) should not be treated as inbound messages that trigger new agent sessions. The gateway knows it posted these itself - it could tag them and skip processing.\\n\\n### Option C: Auth failure cooldown\\nWhen an auth/OAuth error occurs, enter a cooldown period (e.g., 5 minutes) before retrying that agent. Don\\u0026#39;t attempt to start new sessions for that agent until the cooldown expires.\\n\\n### Option D: Cross-agent error awareness\\nIf Agent A just failed with an error in a channel, and Agent B is about to be triggered by that error message in the same channel, skip it. The gateway has enough context to know that the \\u0026#34;inbound message\\u0026#34; is actually an error from a sibling agent on the same gateway.\\n\\n## Relationship to Existing Issues\\n\\nRelated to #37842 (graph-aware loop detection for sessions_send), but different mechanism:\\n- #37842: agents actively sending messages to each other via `sessions_send`\\n- This issue: gateway error handler passively posting to channels, triggering other agents\\n\\nAlso related to #29745 (config validation infinite retry loop) and #3181 (runaway heartbeat loop) - all are variants of the same class: insufficient backoff/suppression on repeated failures.\\n\\n## Environment\\n\\n- OpenClaw 2026.3.13\\n- Two Slack bot accounts sharing a channel\\n- Both using `allowBots: true` for inter-agent coordination\\n- Auth: OAuth (shared account)\\n- Trigger: OAuth token expiration\\n\\n## Workaround\\n\\nCurrently no good workaround. Options considered:\\n- `allowBots: false` - breaks inter-agent coordination\\n- `allowBots: \\u0026#34;mentions\\u0026#34;` - would work but prevents agents from seeing each other\\u0026#39;s non-mention messages\\n- Adding rules to AGENTS.md - agents never start (auth fails before prompt is loaded), so behavioral rules can\\u0026#39;t help\\n\",\"state\":\"OPEN\",\"user\":{\"login\":\"scottyallen\"},\"created_at\":\"2026-03-21T19:11:59Z\",\"updated_at\":\"2026-03-21T19:11:59Z\"}],\"totalCount\":8779,\"pageInfo\":{\"hasNextPage\":true,\"hasPreviousPage\":false,\"startCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoxMTo1OS0wNzowMM71LrED\",\"endCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoxMTo1OS0wNzowMM71LrED\"}}"}]}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01DocAfUmrQg5Ef2qRKAph14","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01SPP9UyfvcVoCNfdF5M3CAV","name":"mcp__github__search_pull_requests","input":{"query":"repo:openclaw/openclaw is:pr is:merged sort:updated","perPage":5},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":6898,"cache_read_input_tokens":34648,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6898},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"aaeef7eb-825a-4f7d-be3d-1bd798b44c4b"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01DocAfUmrQg5Ef2qRKAph14","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_014CkqbGQj4fxbLJTC57M9qj","name":"mcp__github__get_latest_release","input":{"owner":"openclaw","repo":"openclaw"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":6898,"cache_read_input_tokens":34648,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":6898},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"04866775-909c-4a6d-81fa-8ca9df28e38d"}
{"type":"rate_limit_event","rate_limit_info":{"status":"allowed","resetsAt":1774126800,"rateLimitType":"five_hour","overageStatus":"rejected","overageDisabledReason":"org_level_disabled","isUsingOverage":false},"uuid":"b5676829-282b-461e-a419-b0ec9d82f8fe","session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253"}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_014CkqbGQj4fxbLJTC57M9qj","type":"tool_result","content":[{"type":"text","text":"{\"tag_name\":\"v2026.3.13-1\",\"target_commitish\":\"61d171ab0b2fe4abc9afe89c518586274b4b76c2\",\"name\":\"openclaw 2026.3.13\",\"body\":\"This recovery release uses `v2026.3.13-1` because GitHub immutable releases do not allow reusing `v2026.3.13` after publication.\\r\\n\\r\\nImportant:\\r\\n- This release exists to recover the broken `v2026.3.13` tag/release path.\\r\\n- The corresponding npm version is still `2026.3.13`, not `2026.3.13-1`.\\r\\n- The `-1` suffix is for the Git tag and GitHub Release only.\\r\\n\\r\\n\\r\\n## What's Changed\\r\\n* fix(compaction): use full-session token count for post-compaction sanity check by @efe-arv in https://github.com/openclaw/openclaw/pull/28347\\r\\n* fix(telegram): thread media transport policy into SSRF by @obviyus in https://github.com/openclaw/openclaw/pull/44639\\r\\n* fix: handle Discord gateway metadata fetch failures by @jalehman in https://github.com/openclaw/openclaw/pull/44397\\r\\n* docs: move post-release changelog entries to Unreleased by @jalehman in https://github.com/openclaw/openclaw/pull/44691\\r\\n* fix(session): preserve `lastAccountId ` and `lastThreadId` on session reset by @Lanfei in https://github.com/openclaw/openclaw/pull/44773\\r\\n* Updated default model from openai-codex/gpt-5.3-codex to openai-codex/gpt-5.4 in tests. by @jrrcdev in https://github.com/openclaw/openclaw/pull/44367\\r\\n* fix: address delivery dedupe review follow-ups by @frankekn in https://github.com/openclaw/openclaw/pull/44666\\r\\n* CLI: align xhigh thinking help text by @frankekn in https://github.com/openclaw/openclaw/pull/44819\\r\\n* docs: fix changelog credit for xhigh help by @frankekn in https://github.com/openclaw/openclaw/pull/44874\\r\\n* fix(agents): drop Anthropic thinking blocks on replay by @frankekn in https://github.com/openclaw/openclaw/pull/44843\\r\\n* docs: fix session key :dm: → :direct: by @Lanfei in https://github.com/openclaw/openclaw/pull/26506\\r\\n* feat(android): redesign chat settings UI by @obviyus in https://github.com/openclaw/openclaw/pull/44894\\r\\n* fix(agents): avoid injecting memory file twice on case-insensitive mounts by @Lanfei in https://github.com/openclaw/openclaw/pull/26054\\r\\n* Docker: add OPENCLAW_TZ timezone support by @Lanfei in https://github.com/openclaw/openclaw/pull/34119\\r\\n* Android: fix HttpURLConnection leak in TalkModeVoiceResolver by @Kaneki-x in https://github.com/openclaw/openclaw/pull/43780\\r\\n* fix(agents): respect explicit user compat overrides for non-native openai-completions by @cheapestinference in https://github.com/openclaw/openclaw/pull/44432\\r\\n* test(config): cover requiresOpenAiAnthropicToolPayload in compat schema fixture by @xingsy97 in https://github.com/openclaw/openclaw/pull/43438\\r\\n* fix(agents): rephrase session reset prompt to avoid Azure content filter by @xingsy97 in https://github.com/openclaw/openclaw/pull/43403\\r\\n* fix(config): add missing params field to agents.list[] validation schema by @atian8179 in https://github.com/openclaw/openclaw/pull/41171\\r\\n* fix(android): use Google Code Scanner for onboarding QR by @obviyus in https://github.com/openclaw/openclaw/pull/45021\\r\\n* fix: restore web fetch firecrawl config in runtime zod schema by @stim64045-spec in https://github.com/openclaw/openclaw/pull/42583\\r\\n* fix(signal): add groups config to Signal channel schema by @unisone in https://github.com/openclaw/openclaw/pull/27199\\r\\n* feat(ios): add onboarding welcome pager by @ngutman in https://github.com/openclaw/openclaw/pull/45054\\r\\n* small addition to .gitignore  by @Sovtoshi-SC in https://github.com/openclaw/openclaw/pull/42879\\r\\n* fix(discovery): add missing domain to wideArea Zod config schema by @ingyukoh in https://github.com/openclaw/openclaw/pull/35615\\r\\n* fix(ui): keep shared auth on insecure control-ui connects by @velvet-shark in https://github.com/openclaw/openclaw/pull/45088\\r\\n* fix: preserve persona and language continuity in compaction summaries by @keepitmello in https://github.com/openclaw/openclaw/pull/10456\\r\\n* ui: mobile navigation drawer \\u0026 theme variant refinements by @BunsDev in https://github.com/openclaw/openclaw/pull/45107\\r\\n* fix: resolve target agent workspace for cross-agent subagent spawns by @moshehbenavraham in https://github.com/openclaw/openclaw/pull/40176\\r\\n* fix(ollama): hide native reasoning-only output by @frankekn in https://github.com/openclaw/openclaw/pull/45330\\r\\n* test: annotate chat abort helper exports by @frankekn in https://github.com/openclaw/openclaw/pull/45346\\r\\n* Fix incorrect rendering of brave costs in docs by @keelanfh in https://github.com/openclaw/openclaw/pull/44989\\r\\n* security(docker): prevent gateway token leak in Docker build context by @xingsy97 in https://github.com/openclaw/openclaw/pull/44956\\r\\n* refactor: remove redundant ?? undefined in Slack probe by @Cafexss in https://github.com/openclaw/openclaw/pull/44775\\r\\n* fix(ui): restore chat-new-messages class on scroll pill button by @Astro-Han in https://github.com/openclaw/openclaw/pull/44856\\r\\n* fix(windows): suppress visible console windows during restart and process cleanup by @MoerAI in https://github.com/openclaw/openclaw/pull/44842\\r\\n* Slack: add opt-in interactive reply directives by @vincentkoc in https://github.com/openclaw/openclaw/pull/44607\\r\\n* Docs: describe Slack interactive replies by @vincentkoc in https://github.com/openclaw/openclaw/pull/45463\\r\\n* fix(cron): prevent isolated cron nested lane deadlocks by @vincentkoc in https://github.com/openclaw/openclaw/pull/45459\\r\\n* Fix updater refresh cwd for service reinstall by @vincentkoc in https://github.com/openclaw/openclaw/pull/45452\\r\\n* [codex] Polish sidebar status, agent skills, and chat rendering by @BunsDev in https://github.com/openclaw/openclaw/pull/45451\\r\\n* perf(build): deduplicate plugin-sdk chunks to fix ~2x memory regression by @TarasShyn in https://github.com/openclaw/openclaw/pull/45426\\r\\n* Guard updater service refresh against missing invocation cwd by @vincentkoc in https://github.com/openclaw/openclaw/pull/45486\\r\\n* fix(browser): normalize batch act dispatch for selector and batch support by @vincentkoc in https://github.com/openclaw/openclaw/pull/45457\\r\\n* docs(android): note that app is not publicly released yet by @eengad in https://github.com/openclaw/openclaw/pull/23051\\r\\n* fix(browser): follow up batch failure and limit handling by @vincentkoc in https://github.com/openclaw/openclaw/pull/45506\\r\\n* docker: add apt-get upgrade to all Dockerfiles by @jacobtomlinson in https://github.com/openclaw/openclaw/pull/45384\\r\\n* fix(config): avoid Anthropic startup crash by @BunsDev in https://github.com/openclaw/openclaw/pull/45520\\r\\n* test: preserve wrapper behavior for targeted runs by @Takhoffman in https://github.com/openclaw/openclaw/pull/45518\\r\\n* UI: fix chat context notice icon sizing by @BunsDev in https://github.com/openclaw/openclaw/pull/45533\\r\\n* fix(ui): stop dashboard chat history reload storm by @BunsDev in https://github.com/openclaw/openclaw/pull/45541\\r\\n* fix: retry Telegram inbound media downloads over IPv4 fallback by @frankekn in https://github.com/openclaw/openclaw/pull/45327\\r\\n* fix(feishu): preserve non-ASCII filenames in file uploads (#33912) by @fabiaodemianyang in https://github.com/openclaw/openclaw/pull/34262\\r\\n* macOS: respect exec-approvals.json settings in gateway prompter by @sliekens in https://github.com/openclaw/openclaw/pull/13707\\r\\n* fix(ui): keep oversized chat replies readable by @BunsDev in https://github.com/openclaw/openclaw/pull/45559\\r\\n* fix(gateway/ui): restore control-ui auth bypass and classify connect failures by @sallyom in https://github.com/openclaw/openclaw/pull/45512\\r\\n* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode by @teslamint in https://github.com/openclaw/openclaw/pull/13798\\r\\n* fix(sessions): create transcript file on chat.inject when missing by @2233admin in https://github.com/openclaw/openclaw/pull/36645\\r\\n* Plugins: fail fast on channel and binding collisions by @vincentkoc in https://github.com/openclaw/openclaw/pull/45628\\r\\n* fix(macos): align minimum Node.js version with runtime guard (22.16.0) by @ImLukeF in https://github.com/openclaw/openclaw/pull/45640\\r\\n* fix(agents): preserve blank local custom-provider API keys after onboarding by @frankekn in https://github.com/openclaw/openclaw/pull/45631\\r\\n* fix(browser): harden existing-session driver validation and session lifecycle by @odysseus0 in https://github.com/openclaw/openclaw/pull/45682\\r\\n* fix(feishu): add early event-level dedup to prevent duplicate replies by @yunweibang in https://github.com/openclaw/openclaw/pull/43762\\r\\n* fix(models): apply Gemini model-id normalization to google-vertex provider by @scoootscooob in https://github.com/openclaw/openclaw/pull/42435\\r\\n* Gateway: treat scope-limited probe RPC as degraded reachability by @joshavant in https://github.com/openclaw/openclaw/pull/45622\\r\\n* fix(gateway): bound unanswered client requests by @Takhoffman in https://github.com/openclaw/openclaw/pull/45689\\r\\n\\r\\n## New Contributors\\r\\n* @jrrcdev made their first contribution in https://github.com/openclaw/openclaw/pull/44367\\r\\n* @Kaneki-x made their first contribution in https://github.com/openclaw/openclaw/pull/43780\\r\\n* @cheapestinference made their first contribution in https://github.com/openclaw/openclaw/pull/44432\\r\\n* @xingsy97 made their first contribution in https://github.com/openclaw/openclaw/pull/43438\\r\\n* @atian8179 made their first contribution in https://github.com/openclaw/openclaw/pull/41171\\r\\n* @stim64045-spec made their first contribution in https://github.com/openclaw/openclaw/pull/42583\\r\\n* @Sovtoshi-SC made their first contribution in https://github.com/openclaw/openclaw/pull/42879\\r\\n* @keepitmello made their first contribution in https://github.com/openclaw/openclaw/pull/10456\\r\\n* @moshehbenavraham made their first contribution in https://github.com/openclaw/openclaw/pull/40176\\r\\n* @keelanfh made their first contribution in https://github.com/openclaw/openclaw/pull/44989\\r\\n* @Cafexss made their first contribution in https://github.com/openclaw/openclaw/pull/44775\\r\\n* @Astro-Han made their first contribution in https://github.com/openclaw/openclaw/pull/44856\\r\\n* @eengad made their first contribution in https://github.com/openclaw/openclaw/pull/23051\\r\\n* @jacobtomlinson made their first contribution in https://github.com/openclaw/openclaw/pull/45384\\r\\n* @fabiaodemianyang made their first contribution in https://github.com/openclaw/openclaw/pull/34262\\r\\n* @sliekens made their first contribution in https://github.com/openclaw/openclaw/pull/13707\\r\\n* @teslamint made their first contribution in https://github.com/openclaw/openclaw/pull/13798\\r\\n* @yunweibang made their first contribution in https://github.com/openclaw/openclaw/pull/43762\\r\\n\\r\\n**Full Changelog**: https://github.com/openclaw/openclaw/compare/v2026.3.12...v2026.3.13-1\",\"draft\":false,\"prerelease\":false,\"id\":297041210,\"created_at\":\"2026-03-14T18:03:51Z\",\"published_at\":\"2026-03-14T18:04:28Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210\",\"html_url\":\"https://github.com/openclaw/openclaw/releases/tag/v2026.3.13-1\",\"assets_url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210/assets\",\"upload_url\":\"https://uploads.github.com/repos/openclaw/openclaw/releases/297041210/assets{?name,label}\",\"zipball_url\":\"https://api.github.com/repos/openclaw/openclaw/zipball/v2026.3.13-1\",\"tarball_url\":\"https://api.github.com/repos/openclaw/openclaw/tarball/v2026.3.13-1\",\"author\":{\"login\":\"onutc\",\"id\":152018508,\"node_id\":\"U_kgDOCQ-eTA\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/152018508?v=4\",\"html_url\":\"https://github.com/onutc\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/onutc\",\"events_url\":\"https://api.github.com/users/onutc/events{/privacy}\",\"following_url\":\"https://api.github.com/users/onutc/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/onutc/followers\",\"gists_url\":\"https://api.github.com/users/onutc/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/onutc/orgs\",\"received_events_url\":\"https://api.github.com/users/onutc/received_events\",\"repos_url\":\"https://api.github.com/users/onutc/repos\",\"starred_url\":\"https://api.github.com/users/onutc/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/onutc/subscriptions\"},\"node_id\":\"RE_kwDOQb6kR84RtH06\",\"immutable\":true}"}]}]},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"e3c7e69f-de18-4f48-b87e-c349576ad75a","timestamp":"2026-03-21T19:18:22.461Z","tool_use_result":[{"type":"text","text":"{\"tag_name\":\"v2026.3.13-1\",\"target_commitish\":\"61d171ab0b2fe4abc9afe89c518586274b4b76c2\",\"name\":\"openclaw 2026.3.13\",\"body\":\"This recovery release uses `v2026.3.13-1` because GitHub immutable releases do not allow reusing `v2026.3.13` after publication.\\r\\n\\r\\nImportant:\\r\\n- This release exists to recover the broken `v2026.3.13` tag/release path.\\r\\n- The corresponding npm version is still `2026.3.13`, not `2026.3.13-1`.\\r\\n- The `-1` suffix is for the Git tag and GitHub Release only.\\r\\n\\r\\n\\r\\n## What's Changed\\r\\n* fix(compaction): use full-session token count for post-compaction sanity check by @efe-arv in https://github.com/openclaw/openclaw/pull/28347\\r\\n* fix(telegram): thread media transport policy into SSRF by @obviyus in https://github.com/openclaw/openclaw/pull/44639\\r\\n* fix: handle Discord gateway metadata fetch failures by @jalehman in https://github.com/openclaw/openclaw/pull/44397\\r\\n* docs: move post-release changelog entries to Unreleased by @jalehman in https://github.com/openclaw/openclaw/pull/44691\\r\\n* fix(session): preserve `lastAccountId ` and `lastThreadId` on session reset by @Lanfei in https://github.com/openclaw/openclaw/pull/44773\\r\\n* Updated default model from openai-codex/gpt-5.3-codex to openai-codex/gpt-5.4 in tests. by @jrrcdev in https://github.com/openclaw/openclaw/pull/44367\\r\\n* fix: address delivery dedupe review follow-ups by @frankekn in https://github.com/openclaw/openclaw/pull/44666\\r\\n* CLI: align xhigh thinking help text by @frankekn in https://github.com/openclaw/openclaw/pull/44819\\r\\n* docs: fix changelog credit for xhigh help by @frankekn in https://github.com/openclaw/openclaw/pull/44874\\r\\n* fix(agents): drop Anthropic thinking blocks on replay by @frankekn in https://github.com/openclaw/openclaw/pull/44843\\r\\n* docs: fix session key :dm: → :direct: by @Lanfei in https://github.com/openclaw/openclaw/pull/26506\\r\\n* feat(android): redesign chat settings UI by @obviyus in https://github.com/openclaw/openclaw/pull/44894\\r\\n* fix(agents): avoid injecting memory file twice on case-insensitive mounts by @Lanfei in https://github.com/openclaw/openclaw/pull/26054\\r\\n* Docker: add OPENCLAW_TZ timezone support by @Lanfei in https://github.com/openclaw/openclaw/pull/34119\\r\\n* Android: fix HttpURLConnection leak in TalkModeVoiceResolver by @Kaneki-x in https://github.com/openclaw/openclaw/pull/43780\\r\\n* fix(agents): respect explicit user compat overrides for non-native openai-completions by @cheapestinference in https://github.com/openclaw/openclaw/pull/44432\\r\\n* test(config): cover requiresOpenAiAnthropicToolPayload in compat schema fixture by @xingsy97 in https://github.com/openclaw/openclaw/pull/43438\\r\\n* fix(agents): rephrase session reset prompt to avoid Azure content filter by @xingsy97 in https://github.com/openclaw/openclaw/pull/43403\\r\\n* fix(config): add missing params field to agents.list[] validation schema by @atian8179 in https://github.com/openclaw/openclaw/pull/41171\\r\\n* fix(android): use Google Code Scanner for onboarding QR by @obviyus in https://github.com/openclaw/openclaw/pull/45021\\r\\n* fix: restore web fetch firecrawl config in runtime zod schema by @stim64045-spec in https://github.com/openclaw/openclaw/pull/42583\\r\\n* fix(signal): add groups config to Signal channel schema by @unisone in https://github.com/openclaw/openclaw/pull/27199\\r\\n* feat(ios): add onboarding welcome pager by @ngutman in https://github.com/openclaw/openclaw/pull/45054\\r\\n* small addition to .gitignore  by @Sovtoshi-SC in https://github.com/openclaw/openclaw/pull/42879\\r\\n* fix(discovery): add missing domain to wideArea Zod config schema by @ingyukoh in https://github.com/openclaw/openclaw/pull/35615\\r\\n* fix(ui): keep shared auth on insecure control-ui connects by @velvet-shark in https://github.com/openclaw/openclaw/pull/45088\\r\\n* fix: preserve persona and language continuity in compaction summaries by @keepitmello in https://github.com/openclaw/openclaw/pull/10456\\r\\n* ui: mobile navigation drawer \\u0026 theme variant refinements by @BunsDev in https://github.com/openclaw/openclaw/pull/45107\\r\\n* fix: resolve target agent workspace for cross-agent subagent spawns by @moshehbenavraham in https://github.com/openclaw/openclaw/pull/40176\\r\\n* fix(ollama): hide native reasoning-only output by @frankekn in https://github.com/openclaw/openclaw/pull/45330\\r\\n* test: annotate chat abort helper exports by @frankekn in https://github.com/openclaw/openclaw/pull/45346\\r\\n* Fix incorrect rendering of brave costs in docs by @keelanfh in https://github.com/openclaw/openclaw/pull/44989\\r\\n* security(docker): prevent gateway token leak in Docker build context by @xingsy97 in https://github.com/openclaw/openclaw/pull/44956\\r\\n* refactor: remove redundant ?? undefined in Slack probe by @Cafexss in https://github.com/openclaw/openclaw/pull/44775\\r\\n* fix(ui): restore chat-new-messages class on scroll pill button by @Astro-Han in https://github.com/openclaw/openclaw/pull/44856\\r\\n* fix(windows): suppress visible console windows during restart and process cleanup by @MoerAI in https://github.com/openclaw/openclaw/pull/44842\\r\\n* Slack: add opt-in interactive reply directives by @vincentkoc in https://github.com/openclaw/openclaw/pull/44607\\r\\n* Docs: describe Slack interactive replies by @vincentkoc in https://github.com/openclaw/openclaw/pull/45463\\r\\n* fix(cron): prevent isolated cron nested lane deadlocks by @vincentkoc in https://github.com/openclaw/openclaw/pull/45459\\r\\n* Fix updater refresh cwd for service reinstall by @vincentkoc in https://github.com/openclaw/openclaw/pull/45452\\r\\n* [codex] Polish sidebar status, agent skills, and chat rendering by @BunsDev in https://github.com/openclaw/openclaw/pull/45451\\r\\n* perf(build): deduplicate plugin-sdk chunks to fix ~2x memory regression by @TarasShyn in https://github.com/openclaw/openclaw/pull/45426\\r\\n* Guard updater service refresh against missing invocation cwd by @vincentkoc in https://github.com/openclaw/openclaw/pull/45486\\r\\n* fix(browser): normalize batch act dispatch for selector and batch support by @vincentkoc in https://github.com/openclaw/openclaw/pull/45457\\r\\n* docs(android): note that app is not publicly released yet by @eengad in https://github.com/openclaw/openclaw/pull/23051\\r\\n* fix(browser): follow up batch failure and limit handling by @vincentkoc in https://github.com/openclaw/openclaw/pull/45506\\r\\n* docker: add apt-get upgrade to all Dockerfiles by @jacobtomlinson in https://github.com/openclaw/openclaw/pull/45384\\r\\n* fix(config): avoid Anthropic startup crash by @BunsDev in https://github.com/openclaw/openclaw/pull/45520\\r\\n* test: preserve wrapper behavior for targeted runs by @Takhoffman in https://github.com/openclaw/openclaw/pull/45518\\r\\n* UI: fix chat context notice icon sizing by @BunsDev in https://github.com/openclaw/openclaw/pull/45533\\r\\n* fix(ui): stop dashboard chat history reload storm by @BunsDev in https://github.com/openclaw/openclaw/pull/45541\\r\\n* fix: retry Telegram inbound media downloads over IPv4 fallback by @frankekn in https://github.com/openclaw/openclaw/pull/45327\\r\\n* fix(feishu): preserve non-ASCII filenames in file uploads (#33912) by @fabiaodemianyang in https://github.com/openclaw/openclaw/pull/34262\\r\\n* macOS: respect exec-approvals.json settings in gateway prompter by @sliekens in https://github.com/openclaw/openclaw/pull/13707\\r\\n* fix(ui): keep oversized chat replies readable by @BunsDev in https://github.com/openclaw/openclaw/pull/45559\\r\\n* fix(gateway/ui): restore control-ui auth bypass and classify connect failures by @sallyom in https://github.com/openclaw/openclaw/pull/45512\\r\\n* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode by @teslamint in https://github.com/openclaw/openclaw/pull/13798\\r\\n* fix(sessions): create transcript file on chat.inject when missing by @2233admin in https://github.com/openclaw/openclaw/pull/36645\\r\\n* Plugins: fail fast on channel and binding collisions by @vincentkoc in https://github.com/openclaw/openclaw/pull/45628\\r\\n* fix(macos): align minimum Node.js version with runtime guard (22.16.0) by @ImLukeF in https://github.com/openclaw/openclaw/pull/45640\\r\\n* fix(agents): preserve blank local custom-provider API keys after onboarding by @frankekn in https://github.com/openclaw/openclaw/pull/45631\\r\\n* fix(browser): harden existing-session driver validation and session lifecycle by @odysseus0 in https://github.com/openclaw/openclaw/pull/45682\\r\\n* fix(feishu): add early event-level dedup to prevent duplicate replies by @yunweibang in https://github.com/openclaw/openclaw/pull/43762\\r\\n* fix(models): apply Gemini model-id normalization to google-vertex provider by @scoootscooob in https://github.com/openclaw/openclaw/pull/42435\\r\\n* Gateway: treat scope-limited probe RPC as degraded reachability by @joshavant in https://github.com/openclaw/openclaw/pull/45622\\r\\n* fix(gateway): bound unanswered client requests by @Takhoffman in https://github.com/openclaw/openclaw/pull/45689\\r\\n\\r\\n## New Contributors\\r\\n* @jrrcdev made their first contribution in https://github.com/openclaw/openclaw/pull/44367\\r\\n* @Kaneki-x made their first contribution in https://github.com/openclaw/openclaw/pull/43780\\r\\n* @cheapestinference made their first contribution in https://github.com/openclaw/openclaw/pull/44432\\r\\n* @xingsy97 made their first contribution in https://github.com/openclaw/openclaw/pull/43438\\r\\n* @atian8179 made their first contribution in https://github.com/openclaw/openclaw/pull/41171\\r\\n* @stim64045-spec made their first contribution in https://github.com/openclaw/openclaw/pull/42583\\r\\n* @Sovtoshi-SC made their first contribution in https://github.com/openclaw/openclaw/pull/42879\\r\\n* @keepitmello made their first contribution in https://github.com/openclaw/openclaw/pull/10456\\r\\n* @moshehbenavraham made their first contribution in https://github.com/openclaw/openclaw/pull/40176\\r\\n* @keelanfh made their first contribution in https://github.com/openclaw/openclaw/pull/44989\\r\\n* @Cafexss made their first contribution in https://github.com/openclaw/openclaw/pull/44775\\r\\n* @Astro-Han made their first contribution in https://github.com/openclaw/openclaw/pull/44856\\r\\n* @eengad made their first contribution in https://github.com/openclaw/openclaw/pull/23051\\r\\n* @jacobtomlinson made their first contribution in https://github.com/openclaw/openclaw/pull/45384\\r\\n* @fabiaodemianyang made their first contribution in https://github.com/openclaw/openclaw/pull/34262\\r\\n* @sliekens made their first contribution in https://github.com/openclaw/openclaw/pull/13707\\r\\n* @teslamint made their first contribution in https://github.com/openclaw/openclaw/pull/13798\\r\\n* @yunweibang made their first contribution in https://github.com/openclaw/openclaw/pull/43762\\r\\n\\r\\n**Full Changelog**: https://github.com/openclaw/openclaw/compare/v2026.3.12...v2026.3.13-1\",\"draft\":false,\"prerelease\":false,\"id\":297041210,\"created_at\":\"2026-03-14T18:03:51Z\",\"published_at\":\"2026-03-14T18:04:28Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210\",\"html_url\":\"https://github.com/openclaw/openclaw/releases/tag/v2026.3.13-1\",\"assets_url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210/assets\",\"upload_url\":\"https://uploads.github.com/repos/openclaw/openclaw/releases/297041210/assets{?name,label}\",\"zipball_url\":\"https://api.github.com/repos/openclaw/openclaw/zipball/v2026.3.13-1\",\"tarball_url\":\"https://api.github.com/repos/openclaw/openclaw/tarball/v2026.3.13-1\",\"author\":{\"login\":\"onutc\",\"id\":152018508,\"node_id\":\"U_kgDOCQ-eTA\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/152018508?v=4\",\"html_url\":\"https://github.com/onutc\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/onutc\",\"events_url\":\"https://api.github.com/users/onutc/events{/privacy}\",\"following_url\":\"https://api.github.com/users/onutc/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/onutc/followers\",\"gists_url\":\"https://api.github.com/users/onutc/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/onutc/orgs\",\"received_events_url\":\"https://api.github.com/users/onutc/received_events\",\"repos_url\":\"https://api.github.com/users/onutc/repos\",\"starred_url\":\"https://api.github.com/users/onutc/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/onutc/subscriptions\"},\"node_id\":\"RE_kwDOQb6kR84RtH06\",\"immutable\":true}"}]}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01SPP9UyfvcVoCNfdF5M3CAV","type":"tool_result","content":[{"type":"text","text":"{\"total_count\":3550,\"incomplete_results\":false,\"items\":[{\"id\":4020929744,\"number\":34222,\"state\":\"closed\",\"locked\":false,\"title\":\"fix: use content hash for memory flush dedup instead of compactionCount (#30115)\",\"body\":\"## What\\nReplace event-based memory flush deduplication (`compactionCount`) with state-based deduplication (content hash) to prevent duplicate MEMORY.md writes when compaction aborts.\\n\\n## Why\\nFixes #30115 — Compaction abort triggers duplicate memory flushes in MEMORY.md.\\n\\nThe existing dedup uses `compactionCount` (an event counter) to decide whether to skip a flush. When compaction aborts and retries, the counter increments but the session context stays the same, causing the same content to be flushed repeatedly (4-7x duplicate entries reported).\\n\\nRoot cause: `compactionCount` conflates \\\"compaction cycle count\\\" with \\\"content has changed\\\" — these are independent concerns. Two different compaction cycles can see identical context (abort → retry scenario), so event-based dedup is fundamentally wrong for this use case.\\n\\n## How\\n- **State-based dedup**: compute a SHA-256 hash (truncated to 16 hex chars) of `messages.length + last 3 user/assistant message contents` before each flush. If the hash matches the stored `memoryFlushContextHash`, skip the flush.\\n- **Two-layer design**: `shouldRunMemoryFlush()` unchanged (token threshold gate), hash check added as second gate in `runMemoryFlushIfNeeded()`.\\n- **`willRetry` fix**: `onAgentEvent` now checks `!evt.data?.willRetry` before marking `memoryCompactionCompleted = true`, preventing retry-in-progress compaction from being incorrectly treated as completed.\\n- **Performance**: `readTranscriptTailMessages()` reads only the last 64KB of the transcript file (not the full file).\\n- **Hash timing**: stores the hash computed *before* the flush run (not after), since the flush turn itself writes to the transcript and would change the hash.\\n\\n### Scenario behavior\\n| Scenario | Behavior |\\n|----------|----------|\\n| Compaction abort | messages unchanged → hash unchanged → skip ✅ |\\n| Compaction success | messages compressed → hash changed → allow flush ✅ |\\n| New messages | tail content changed → hash changed → allow flush ✅ |\\n| Persistence failure | `contextHashBeforeFlush` used in-memory → no re-flush within session ✅ |\\n\\n## Files changed (3 + 1 test)\\n- `src/auto-reply/reply/memory-flush.ts` — new `computeContextHash()` function\\n- `src/auto-reply/reply/agent-runner-memory.ts` — hash check gate + willRetry fix + tail reader\\n- `src/config/sessions/types.ts` — add `memoryFlushContextHash` field to `SessionEntry`\\n- `src/auto-reply/reply/memory-flush.test.ts` — 8 unit tests for `computeContextHash`\\n\\n## Testing\\n- [x] `pnpm build` passes\\n- [x] `pnpm check` passes (lint + format)\\n- [x] `pnpm test` — 811/812 pass (1 pre-existing failure in `process-respawn.test.ts`)\\n- [x] 8 new unit tests for `computeContextHash` (empty input, object content, undefined content, system message filtering, length differentiation, tail behavior)\\n- [x] AI-assisted (OpenClaw agents 李飞飞/陈皮皮/毛豆豆, cross-reviewed, fully tested)\\n\\n## Backward compatibility\\n- `memoryFlushContextHash` undefined → falls back to existing `compactionCount` logic\\n- `memoryFlushCompactionCount` field preserved (not removed)\\n- First flush after upgrade runs normally (hash is empty = allow), subsequent flushes use hash dedup\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"lml2468\",\"id\":39320777,\"node_id\":\"MDQ6VXNlcjM5MzIwNzc3\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/39320777?v=4\",\"html_url\":\"https://github.com/lml2468\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/lml2468\",\"events_url\":\"https://api.github.com/users/lml2468/events{/privacy}\",\"following_url\":\"https://api.github.com/users/lml2468/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/lml2468/followers\",\"gists_url\":\"https://api.github.com/users/lml2468/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/lml2468/orgs\",\"received_events_url\":\"https://api.github.com/users/lml2468/received_events\",\"repos_url\":\"https://api.github.com/users/lml2468/repos\",\"starred_url\":\"https://api.github.com/users/lml2468/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/lml2468/subscriptions\"},\"labels\":[{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10190106720,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20M\",\"name\":\"size: M\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwYA\"}],\"assignee\":{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"},\"comments\":4,\"closed_at\":\"2026-03-21T19:06:26Z\",\"created_at\":\"2026-03-04T09:13:16Z\",\"updated_at\":\"2026-03-21T19:06:26Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/34222\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/34222.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/34222.patch\",\"merged_at\":\"2026-03-21T19:06:26Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/reactions\"},\"assignees\":[{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87H0sGg\",\"draft\":false},{\"id\":4031938020,\"number\":37080,\"state\":\"closed\",\"locked\":false,\"title\":\"fix(tts): add matrix to VOICE_BUBBLE_CHANNELS\",\"body\":\"## Summary\\n\\n- Matrix TTS replies were sent as generic audio file attachments\\n- Missing from VOICE_BUBBLE_CHANNELS set in src/tts/tts.ts\\n- Enables native MSC3245 voice bubble support\\n\\n## Impact\\n\\nMatrix users configured with `messages.tts.auto: \\\"inbound\\\"` will now receive TTS replies as native voice message bubbles with:\\n- Waveform visualization\\n- Duration display\\n- Inline playback controls\\n\\nThis improves user experience for ~1500+ active Matrix users in the open-source community.\\n\\n## Root Cause\\n\\nMatrix channel was missing from VOICE_BUBBLE_CHANNELS, causing resolveOutputFormat() to skip voice-compatible settings. Although extensions/matrix/src/matrix/send.ts fully supports audioAsVoice and MSC3245 metadata, the TTS pipeline never set the flag.\\n\\n## Change\\n\\nAdded \\\"matrix\\\" to VOICE_BUBBLE_CHANNELS set:\\n- Before: [\\\"telegram\\\", \\\"feishu\\\", \\\"whatsapp\\\"]\\n- After: [\\\"telegram\\\", \\\"feishu\\\", \\\"whatsapp\\\", \\\"matrix\\\"]\\n\\n## Test plan\\n\\n- [ ] Send voice message to bot on Matrix (Element)\\n- [ ] Verify TTS reply is sent as MSC3245 voice bubble, not generic file attachment\\n- [ ] Verify waveform, duration, and inline playback metadata present\\n\\nFixes #37061\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"Matthew19990919\",\"id\":97017241,\"node_id\":\"U_kgDOBchdmQ\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/97017241?v=4\",\"html_url\":\"https://github.com/Matthew19990919\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/Matthew19990919\",\"events_url\":\"https://api.github.com/users/Matthew19990919/events{/privacy}\",\"following_url\":\"https://api.github.com/users/Matthew19990919/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/Matthew19990919/followers\",\"gists_url\":\"https://api.github.com/users/Matthew19990919/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/Matthew19990919/orgs\",\"received_events_url\":\"https://api.github.com/users/Matthew19990919/received_events\",\"repos_url\":\"https://api.github.com/users/Matthew19990919/repos\",\"starred_url\":\"https://api.github.com/users/Matthew19990919/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/Matthew19990919/subscriptions\"},\"labels\":[{\"id\":10064298237,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/channel:%20matrix\",\"name\":\"channel: matrix\",\"color\":\"1d76db\",\"description\":\"Channel integration: matrix\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EA_Q\"},{\"id\":10190106648,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20S\",\"name\":\"size: S\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwGA\"}],\"assignee\":{\"login\":\"gumadeiras\",\"id\":5599352,\"node_id\":\"MDQ6VXNlcjU1OTkzNTI=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5599352?v=4\",\"html_url\":\"https://github.com/gumadeiras\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/gumadeiras\",\"events_url\":\"https://api.github.com/users/gumadeiras/events{/privacy}\",\"following_url\":\"https://api.github.com/users/gumadeiras/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/gumadeiras/followers\",\"gists_url\":\"https://api.github.com/users/gumadeiras/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/gumadeiras/orgs\",\"received_events_url\":\"https://api.github.com/users/gumadeiras/received_events\",\"repos_url\":\"https://api.github.com/users/gumadeiras/repos\",\"starred_url\":\"https://api.github.com/users/gumadeiras/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gumadeiras/subscriptions\"},\"comments\":3,\"closed_at\":\"2026-03-21T18:29:53Z\",\"created_at\":\"2026-03-06T03:06:45Z\",\"updated_at\":\"2026-03-21T18:36:56Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/37080\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/37080.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/37080.patch\",\"merged_at\":\"2026-03-21T18:29:53Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/reactions\"},\"assignees\":[{\"login\":\"gumadeiras\",\"id\":5599352,\"node_id\":\"MDQ6VXNlcjU1OTkzNTI=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5599352?v=4\",\"html_url\":\"https://github.com/gumadeiras\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/gumadeiras\",\"events_url\":\"https://api.github.com/users/gumadeiras/events{/privacy}\",\"following_url\":\"https://api.github.com/users/gumadeiras/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/gumadeiras/followers\",\"gists_url\":\"https://api.github.com/users/gumadeiras/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/gumadeiras/orgs\",\"received_events_url\":\"https://api.github.com/users/gumadeiras/received_events\",\"repos_url\":\"https://api.github.com/users/gumadeiras/repos\",\"starred_url\":\"https://api.github.com/users/gumadeiras/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gumadeiras/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87IYpNR\",\"draft\":false},{\"id\":4109978591,\"number\":51260,\"state\":\"closed\",\"locked\":false,\"title\":\"Fix Discord `/codex_resume` picker expiration\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: Discord `/codex_resume` picker buttons could immediately fail with `This component has expired.` even though the picker message had just been sent.\\n- Why it matters: resume-by-picker worked in Telegram but was broken in Discord, including the thread-in-channel-in-server flow used for real Codex resume.\\n- What changed: I kept the Discord fallback path from discarding explicit callback payloads, and I moved the Discord component registry onto process-global singleton maps so senders and listeners share the same component state across duplicate module instances.\\n- What did NOT change (scope boundary): I did not change the Codex app server picker generation logic; it was already emitting the expected `codexapp:\\u003ctoken\\u003e` callbacks.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [x] Integrations\\n- [ ] API / contracts\\n- [x] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes #\\n- Related #\\n\\n## User-visible / Behavior Changes\\n\\nDiscord Codex resume pickers now stay clickable and can successfully resume a session instead of immediately showing `This component has expired.`\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`No`)\\n- Secrets/tokens handling changed? (`No`)\\n- New/changed network calls? (`No`)\\n- Command/tool execution surface changed? (`No`)\\n- Data access scope changed? (`No`)\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: local dev checkout\\n- Model/provider: Codex app server integration\\n- Integration/channel (if any): Discord thread inside a channel inside a server\\n- Relevant config (redacted): Discord slash command flow with `/codex_resume`\\n\\n### Steps\\n\\n1. Run `/codex_resume` in a Discord thread.\\n2. Click `Browse Projects` or one of the recent-session buttons from the picker.\\n3. Repeat the interaction in the same Discord conversation.\\n\\n### Expected\\n\\n- The picker action is accepted and the selected Codex session view continues normally.\\n\\n### Actual\\n\\n- Before this fix, Discord responded with `This component has expired.` immediately after clicking the picker button.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [x] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: I verified the Discord end-to-end `/codex_resume` flow, including clicking the picker in a Discord thread and successfully resuming a session.\\n- Edge cases checked: I also verified the focused Discord component tests covering callback fallback behavior and duplicate-module registry sharing.\\n- What you did **not** verify: I did not run the full `pnpm test` suite.\\n\\n## Review Conversations\\n\\n- [ ] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes`)\\n- Config/env changes? (`No`)\\n- Migration needed? (`No`)\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert the two Discord component commits on this branch\\n- Files/config to restore: `extensions/discord/src/components-registry.ts`, `extensions/discord/src/monitor/agent-components.ts`\\n- Known bad symptoms reviewers should watch for: Discord component clicks failing to resolve, or plugin-owned pickers regressing to immediate `expired` responses\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: sharing the registry globally could make stale component state survive duplicate module loads longer than before.\\n- Mitigation: the existing TTL and explicit clear/consume paths are unchanged, and I added a regression test for cross-module sharing.\\n\",\"author_association\":\"MEMBER\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"},\"labels\":[{\"id\":10064298117,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/channel:%20discord\",\"name\":\"channel: discord\",\"color\":\"1d76db\",\"description\":\"Channel integration: discord\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EAhQ\"},{\"id\":10069934037,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/scripts\",\"name\":\"scripts\",\"color\":\"5319e7\",\"description\":\"Repository scripts\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDb_1Q\"},{\"id\":10118530218,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/maintainer\",\"name\":\"maintainer\",\"color\":\"FFD700\",\"description\":\"Maintainer-authored PR\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWxyEqg\"},{\"id\":10190106760,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20L\",\"name\":\"size: L\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwiA\"}],\"assignee\":{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"},\"comments\":2,\"closed_at\":\"2026-03-21T16:59:22Z\",\"created_at\":\"2026-03-20T20:30:04Z\",\"updated_at\":\"2026-03-21T18:30:22Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/51260\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/51260.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/51260.patch\",\"merged_at\":\"2026-03-21T16:59:21Z\"},\"reactions\":{\"total_count\":2,\"+1\":2,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/reactions\"},\"assignees\":[{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87MP4LF\",\"draft\":false},{\"id\":4041794311,\"number\":40126,\"state\":\"closed\",\"locked\":false,\"title\":\"feat(memory): pluggable system prompt section for memory plugins\",\"body\":\"## Summary\\n\\n- Problem: The system prompt \\\"Memory Recall\\\" section is hardcoded in `system-prompt.ts`, providing memory-core-specific instructions. When a third-party memory plugin is active (via the exclusive memory slot), these instructions are misleading.\\n- Why it matters: Third-party memory plugins need to provide their own system prompt guidance for their tools instead of the hardcoded memory-core instructions.\\n- What changed: Added `registerMemoryPromptSection(builder)` to the plugin API. The active memory plugin registers its own system prompt builder callback. Moved the existing \\\"Memory Recall\\\" logic into `memory-core` as its registration. `buildMemorySection()` delegates to the registered callback.\\n- What did NOT change (scope boundary): Default behavior is identical — memory-core registers the same prompt content. No changes to memory tools, compaction, or other plugin APIs.\\n\\n## Change Type (select all)\\n\\n- [ ] Bug fix\\n- [x] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [x] Memory / storage\\n- [ ] Integrations\\n- [x] API / contracts\\n- [ ] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\nNone\\n\\n## User-visible / Behavior Changes\\n\\nNone for default memory-core users. Memory plugins with `kind: \\\"memory\\\"` can now register a custom system prompt section via `api.registerMemoryPromptSection(builder)`.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? No\\n- Secrets/tokens handling changed? No\\n- New/changed network calls? No\\n- Command/tool execution surface changed? No\\n- Data access scope changed? No\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: Bun\\n- Model/provider: N/A (system prompt wiring)\\n- Integration/channel (if any): Telegram (for human test)\\n\\n### Steps\\n\\n1. Install a memory plugin that calls `api.registerMemoryPromptSection(builder)`\\n2. Start a session\\n3. Observe that the system prompt contains the plugin's memory section instead of the hardcoded one\\n\\n### Expected\\n\\n- With memory-core (default): system prompt contains \\\"Memory Recall\\\" section as before\\n- With custom memory plugin: system prompt contains the plugin's custom section\\n- With no memory plugin: memory section is omitted\\n\\n### Actual (before fix)\\n\\n- Hardcoded \\\"Memory Recall\\\" section always present regardless of active memory plugin\\n\\n## Evidence\\n\\n- [x] Failing test/log before + passing after\\n- [ ] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\nNew unit tests in `prompt-section.test.ts`: delegation, citationsMode passthrough, no-builder returns empty, last-registration-wins. All 43 existing `system-prompt.test.ts` tests pass.\\n\\n## Human Verification (required)\\n\\n- Verified scenarios: Tested on two separate OpenClaw bots (Telegram) with memory-core active — memory instructions present as expected, no regression observed\\n- Edge cases checked: None\\n- What you did **not** verify: No memory plugin active (section omitted), custom third-party memory plugin providing its own section\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? Yes\\n- Config/env changes? No\\n- Migration needed? No\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: Revert the commit; hardcoded prompt returns\\n- Files/config to restore: N/A\\n- Known bad symptoms reviewers should watch for: Missing \\\"Memory Recall\\\" section in system prompt when memory-core is active\\n\\n## Risks and Mitigations\\n\\nNone. Additive API change. Default behavior is identical — memory-core registers the same prompt content it previously hardcoded.\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"jarimustonen\",\"id\":1272053,\"node_id\":\"MDQ6VXNlcjEyNzIwNTM=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/1272053?v=4\",\"html_url\":\"https://github.com/jarimustonen\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jarimustonen\",\"events_url\":\"https://api.github.com/users/jarimustonen/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jarimustonen/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jarimustonen/followers\",\"gists_url\":\"https://api.github.com/users/jarimustonen/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jarimustonen/orgs\",\"received_events_url\":\"https://api.github.com/users/jarimustonen/received_events\",\"repos_url\":\"https://api.github.com/users/jarimustonen/repos\",\"starred_url\":\"https://api.github.com/users/jarimustonen/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jarimustonen/subscriptions\"},\"labels\":[{\"id\":10064299210,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/extensions:%20lobster\",\"name\":\"extensions: lobster\",\"color\":\"0e8a16\",\"description\":\"Extension: lobster\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EEyg\"},{\"id\":10064299264,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/extensions:%20memory-core\",\"name\":\"extensions: memory-core\",\"color\":\"0e8a16\",\"description\":\"Extension: memory-core\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EFAA\"},{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10069934037,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/scripts\",\"name\":\"scripts\",\"color\":\"5319e7\",\"description\":\"Repository scripts\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDb_1Q\"},{\"id\":10069976942,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/agents\",\"name\":\"agents\",\"color\":\"5319e7\",\"description\":\"Agent runtime and tooling\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDenbg\"},{\"id\":10190106720,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20M\",\"name\":\"size: M\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwYA\"}],\"assignee\":{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"},\"comments\":2,\"closed_at\":\"2026-03-21T18:20:45Z\",\"created_at\":\"2026-03-08T17:38:46Z\",\"updated_at\":\"2026-03-21T18:20:45Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/40126\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/40126.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/40126.patch\",\"merged_at\":\"2026-03-21T18:20:45Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/reactions\"},\"assignees\":[{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87I4a8x\",\"draft\":false},{\"id\":4108957490,\"number\":51146,\"state\":\"closed\",\"locked\":false,\"title\":\"fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux)\",\"body\":\"## Summary\\n\\n- Detect nvm-installed Node.js on Linux (via `NVM_DIR` env var or `process.execPath` containing `/.nvm/`)\\n- Auto-set `NODE_EXTRA_CA_CERTS` to the system CA bundle in the systemd service environment when nvm is detected on Linux (same pattern as the existing macOS default)\\n- Probe multiple distro-specific CA bundle paths (`/etc/ssl/certs/ca-certificates.crt` for Debian/Ubuntu/Alpine, `/etc/pki/tls/certs/ca-bundle.crt` for RHEL/Fedora/CentOS, `/etc/ssl/ca-bundle.pem` for openSUSE) — returns `undefined` when none exists, so `NODE_EXTRA_CA_CERTS` is never set to a missing path\\n- Write `NODE_EXTRA_CA_CERTS` to `~/.openclaw/.env` during `openclaw gateway install` so manual `gateway run` also picks up the system CA bundle via dotenv\\n- Backfill `.env` on the `already-installed` path so upgrading users get the entry without `--force`\\n- Injectable `platform`/`execPath` params throughout for testability\\n- Add documentation for nvm/VPS users with the manual workaround\\n\\nFixes #49088\\n\\n## Test plan\\n\\n- [x] `isNvmNode()` unit tests: NVM_DIR env detection, execPath detection, negative cases\\n- [x] `resolveLinuxSystemCaBundle()` probes multiple distro paths, returns undefined when none exists\\n- [x] Service env tests: NODE_EXTRA_CA_CERTS defaults on Linux with/without nvm, user override respected\\n- [x] `execPath` injectable in both `buildServiceEnvironment` and `buildNodeServiceEnvironment`\\n- [x] All 65 service-env tests pass\\n- [x] TypeScript typecheck passes (0 errors)\\n- [x] Lint/format passes\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"GodsBoy\",\"id\":5792287,\"node_id\":\"MDQ6VXNlcjU3OTIyODc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5792287?v=4\",\"html_url\":\"https://github.com/GodsBoy\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/GodsBoy\",\"events_url\":\"https://api.github.com/users/GodsBoy/events{/privacy}\",\"following_url\":\"https://api.github.com/users/GodsBoy/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/GodsBoy/followers\",\"gists_url\":\"https://api.github.com/users/GodsBoy/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/GodsBoy/orgs\",\"received_events_url\":\"https://api.github.com/users/GodsBoy/received_events\",\"repos_url\":\"https://api.github.com/users/GodsBoy/repos\",\"starred_url\":\"https://api.github.com/users/GodsBoy/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/GodsBoy/subscriptions\"},\"labels\":[{\"id\":9706244975,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/docs\",\"name\":\"docs\",\"color\":\"0075ca\",\"description\":\"Improvements or additions to documentation\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACQomLbw\"},{\"id\":10064298857,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/gateway\",\"name\":\"gateway\",\"color\":\"d4c5f9\",\"description\":\"Gateway runtime\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EDaQ\"},{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10190106760,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20L\",\"name\":\"size: L\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwiA\"}],\"comments\":4,\"closed_at\":\"2026-03-21T18:06:32Z\",\"created_at\":\"2026-03-20T16:54:00Z\",\"updated_at\":\"2026-03-21T18:07:18Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/51146\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/51146.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/51146.patch\",\"merged_at\":\"2026-03-21T18:06:32Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/reactions\"},\"node_id\":\"PR_kwDOQb6kR87MMvoa\",\"draft\":false}]}"}]}]},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"083a2f0b-dd21-45c6-913b-bdd9eba1016e","timestamp":"2026-03-21T19:18:22.512Z","tool_use_result":[{"type":"text","text":"{\"total_count\":3550,\"incomplete_results\":false,\"items\":[{\"id\":4020929744,\"number\":34222,\"state\":\"closed\",\"locked\":false,\"title\":\"fix: use content hash for memory flush dedup instead of compactionCount (#30115)\",\"body\":\"## What\\nReplace event-based memory flush deduplication (`compactionCount`) with state-based deduplication (content hash) to prevent duplicate MEMORY.md writes when compaction aborts.\\n\\n## Why\\nFixes #30115 — Compaction abort triggers duplicate memory flushes in MEMORY.md.\\n\\nThe existing dedup uses `compactionCount` (an event counter) to decide whether to skip a flush. When compaction aborts and retries, the counter increments but the session context stays the same, causing the same content to be flushed repeatedly (4-7x duplicate entries reported).\\n\\nRoot cause: `compactionCount` conflates \\\"compaction cycle count\\\" with \\\"content has changed\\\" — these are independent concerns. Two different compaction cycles can see identical context (abort → retry scenario), so event-based dedup is fundamentally wrong for this use case.\\n\\n## How\\n- **State-based dedup**: compute a SHA-256 hash (truncated to 16 hex chars) of `messages.length + last 3 user/assistant message contents` before each flush. If the hash matches the stored `memoryFlushContextHash`, skip the flush.\\n- **Two-layer design**: `shouldRunMemoryFlush()` unchanged (token threshold gate), hash check added as second gate in `runMemoryFlushIfNeeded()`.\\n- **`willRetry` fix**: `onAgentEvent` now checks `!evt.data?.willRetry` before marking `memoryCompactionCompleted = true`, preventing retry-in-progress compaction from being incorrectly treated as completed.\\n- **Performance**: `readTranscriptTailMessages()` reads only the last 64KB of the transcript file (not the full file).\\n- **Hash timing**: stores the hash computed *before* the flush run (not after), since the flush turn itself writes to the transcript and would change the hash.\\n\\n### Scenario behavior\\n| Scenario | Behavior |\\n|----------|----------|\\n| Compaction abort | messages unchanged → hash unchanged → skip ✅ |\\n| Compaction success | messages compressed → hash changed → allow flush ✅ |\\n| New messages | tail content changed → hash changed → allow flush ✅ |\\n| Persistence failure | `contextHashBeforeFlush` used in-memory → no re-flush within session ✅ |\\n\\n## Files changed (3 + 1 test)\\n- `src/auto-reply/reply/memory-flush.ts` — new `computeContextHash()` function\\n- `src/auto-reply/reply/agent-runner-memory.ts` — hash check gate + willRetry fix + tail reader\\n- `src/config/sessions/types.ts` — add `memoryFlushContextHash` field to `SessionEntry`\\n- `src/auto-reply/reply/memory-flush.test.ts` — 8 unit tests for `computeContextHash`\\n\\n## Testing\\n- [x] `pnpm build` passes\\n- [x] `pnpm check` passes (lint + format)\\n- [x] `pnpm test` — 811/812 pass (1 pre-existing failure in `process-respawn.test.ts`)\\n- [x] 8 new unit tests for `computeContextHash` (empty input, object content, undefined content, system message filtering, length differentiation, tail behavior)\\n- [x] AI-assisted (OpenClaw agents 李飞飞/陈皮皮/毛豆豆, cross-reviewed, fully tested)\\n\\n## Backward compatibility\\n- `memoryFlushContextHash` undefined → falls back to existing `compactionCount` logic\\n- `memoryFlushCompactionCount` field preserved (not removed)\\n- First flush after upgrade runs normally (hash is empty = allow), subsequent flushes use hash dedup\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"lml2468\",\"id\":39320777,\"node_id\":\"MDQ6VXNlcjM5MzIwNzc3\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/39320777?v=4\",\"html_url\":\"https://github.com/lml2468\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/lml2468\",\"events_url\":\"https://api.github.com/users/lml2468/events{/privacy}\",\"following_url\":\"https://api.github.com/users/lml2468/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/lml2468/followers\",\"gists_url\":\"https://api.github.com/users/lml2468/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/lml2468/orgs\",\"received_events_url\":\"https://api.github.com/users/lml2468/received_events\",\"repos_url\":\"https://api.github.com/users/lml2468/repos\",\"starred_url\":\"https://api.github.com/users/lml2468/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/lml2468/subscriptions\"},\"labels\":[{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10190106720,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20M\",\"name\":\"size: M\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwYA\"}],\"assignee\":{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"},\"comments\":4,\"closed_at\":\"2026-03-21T19:06:26Z\",\"created_at\":\"2026-03-04T09:13:16Z\",\"updated_at\":\"2026-03-21T19:06:26Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/34222\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/34222.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/34222.patch\",\"merged_at\":\"2026-03-21T19:06:26Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/34222/reactions\"},\"assignees\":[{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87H0sGg\",\"draft\":false},{\"id\":4031938020,\"number\":37080,\"state\":\"closed\",\"locked\":false,\"title\":\"fix(tts): add matrix to VOICE_BUBBLE_CHANNELS\",\"body\":\"## Summary\\n\\n- Matrix TTS replies were sent as generic audio file attachments\\n- Missing from VOICE_BUBBLE_CHANNELS set in src/tts/tts.ts\\n- Enables native MSC3245 voice bubble support\\n\\n## Impact\\n\\nMatrix users configured with `messages.tts.auto: \\\"inbound\\\"` will now receive TTS replies as native voice message bubbles with:\\n- Waveform visualization\\n- Duration display\\n- Inline playback controls\\n\\nThis improves user experience for ~1500+ active Matrix users in the open-source community.\\n\\n## Root Cause\\n\\nMatrix channel was missing from VOICE_BUBBLE_CHANNELS, causing resolveOutputFormat() to skip voice-compatible settings. Although extensions/matrix/src/matrix/send.ts fully supports audioAsVoice and MSC3245 metadata, the TTS pipeline never set the flag.\\n\\n## Change\\n\\nAdded \\\"matrix\\\" to VOICE_BUBBLE_CHANNELS set:\\n- Before: [\\\"telegram\\\", \\\"feishu\\\", \\\"whatsapp\\\"]\\n- After: [\\\"telegram\\\", \\\"feishu\\\", \\\"whatsapp\\\", \\\"matrix\\\"]\\n\\n## Test plan\\n\\n- [ ] Send voice message to bot on Matrix (Element)\\n- [ ] Verify TTS reply is sent as MSC3245 voice bubble, not generic file attachment\\n- [ ] Verify waveform, duration, and inline playback metadata present\\n\\nFixes #37061\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"Matthew19990919\",\"id\":97017241,\"node_id\":\"U_kgDOBchdmQ\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/97017241?v=4\",\"html_url\":\"https://github.com/Matthew19990919\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/Matthew19990919\",\"events_url\":\"https://api.github.com/users/Matthew19990919/events{/privacy}\",\"following_url\":\"https://api.github.com/users/Matthew19990919/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/Matthew19990919/followers\",\"gists_url\":\"https://api.github.com/users/Matthew19990919/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/Matthew19990919/orgs\",\"received_events_url\":\"https://api.github.com/users/Matthew19990919/received_events\",\"repos_url\":\"https://api.github.com/users/Matthew19990919/repos\",\"starred_url\":\"https://api.github.com/users/Matthew19990919/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/Matthew19990919/subscriptions\"},\"labels\":[{\"id\":10064298237,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/channel:%20matrix\",\"name\":\"channel: matrix\",\"color\":\"1d76db\",\"description\":\"Channel integration: matrix\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EA_Q\"},{\"id\":10190106648,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20S\",\"name\":\"size: S\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwGA\"}],\"assignee\":{\"login\":\"gumadeiras\",\"id\":5599352,\"node_id\":\"MDQ6VXNlcjU1OTkzNTI=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5599352?v=4\",\"html_url\":\"https://github.com/gumadeiras\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/gumadeiras\",\"events_url\":\"https://api.github.com/users/gumadeiras/events{/privacy}\",\"following_url\":\"https://api.github.com/users/gumadeiras/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/gumadeiras/followers\",\"gists_url\":\"https://api.github.com/users/gumadeiras/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/gumadeiras/orgs\",\"received_events_url\":\"https://api.github.com/users/gumadeiras/received_events\",\"repos_url\":\"https://api.github.com/users/gumadeiras/repos\",\"starred_url\":\"https://api.github.com/users/gumadeiras/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gumadeiras/subscriptions\"},\"comments\":3,\"closed_at\":\"2026-03-21T18:29:53Z\",\"created_at\":\"2026-03-06T03:06:45Z\",\"updated_at\":\"2026-03-21T18:36:56Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/37080\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/37080.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/37080.patch\",\"merged_at\":\"2026-03-21T18:29:53Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/37080/reactions\"},\"assignees\":[{\"login\":\"gumadeiras\",\"id\":5599352,\"node_id\":\"MDQ6VXNlcjU1OTkzNTI=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5599352?v=4\",\"html_url\":\"https://github.com/gumadeiras\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/gumadeiras\",\"events_url\":\"https://api.github.com/users/gumadeiras/events{/privacy}\",\"following_url\":\"https://api.github.com/users/gumadeiras/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/gumadeiras/followers\",\"gists_url\":\"https://api.github.com/users/gumadeiras/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/gumadeiras/orgs\",\"received_events_url\":\"https://api.github.com/users/gumadeiras/received_events\",\"repos_url\":\"https://api.github.com/users/gumadeiras/repos\",\"starred_url\":\"https://api.github.com/users/gumadeiras/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gumadeiras/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87IYpNR\",\"draft\":false},{\"id\":4109978591,\"number\":51260,\"state\":\"closed\",\"locked\":false,\"title\":\"Fix Discord `/codex_resume` picker expiration\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: Discord `/codex_resume` picker buttons could immediately fail with `This component has expired.` even though the picker message had just been sent.\\n- Why it matters: resume-by-picker worked in Telegram but was broken in Discord, including the thread-in-channel-in-server flow used for real Codex resume.\\n- What changed: I kept the Discord fallback path from discarding explicit callback payloads, and I moved the Discord component registry onto process-global singleton maps so senders and listeners share the same component state across duplicate module instances.\\n- What did NOT change (scope boundary): I did not change the Codex app server picker generation logic; it was already emitting the expected `codexapp:\\u003ctoken\\u003e` callbacks.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [x] Integrations\\n- [ ] API / contracts\\n- [x] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes #\\n- Related #\\n\\n## User-visible / Behavior Changes\\n\\nDiscord Codex resume pickers now stay clickable and can successfully resume a session instead of immediately showing `This component has expired.`\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`No`)\\n- Secrets/tokens handling changed? (`No`)\\n- New/changed network calls? (`No`)\\n- Command/tool execution surface changed? (`No`)\\n- Data access scope changed? (`No`)\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: local dev checkout\\n- Model/provider: Codex app server integration\\n- Integration/channel (if any): Discord thread inside a channel inside a server\\n- Relevant config (redacted): Discord slash command flow with `/codex_resume`\\n\\n### Steps\\n\\n1. Run `/codex_resume` in a Discord thread.\\n2. Click `Browse Projects` or one of the recent-session buttons from the picker.\\n3. Repeat the interaction in the same Discord conversation.\\n\\n### Expected\\n\\n- The picker action is accepted and the selected Codex session view continues normally.\\n\\n### Actual\\n\\n- Before this fix, Discord responded with `This component has expired.` immediately after clicking the picker button.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [x] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: I verified the Discord end-to-end `/codex_resume` flow, including clicking the picker in a Discord thread and successfully resuming a session.\\n- Edge cases checked: I also verified the focused Discord component tests covering callback fallback behavior and duplicate-module registry sharing.\\n- What you did **not** verify: I did not run the full `pnpm test` suite.\\n\\n## Review Conversations\\n\\n- [ ] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes`)\\n- Config/env changes? (`No`)\\n- Migration needed? (`No`)\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert the two Discord component commits on this branch\\n- Files/config to restore: `extensions/discord/src/components-registry.ts`, `extensions/discord/src/monitor/agent-components.ts`\\n- Known bad symptoms reviewers should watch for: Discord component clicks failing to resolve, or plugin-owned pickers regressing to immediate `expired` responses\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: sharing the registry globally could make stale component state survive duplicate module loads longer than before.\\n- Mitigation: the existing TTL and explicit clear/consume paths are unchanged, and I added a regression test for cross-module sharing.\\n\",\"author_association\":\"MEMBER\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"},\"labels\":[{\"id\":10064298117,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/channel:%20discord\",\"name\":\"channel: discord\",\"color\":\"1d76db\",\"description\":\"Channel integration: discord\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EAhQ\"},{\"id\":10069934037,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/scripts\",\"name\":\"scripts\",\"color\":\"5319e7\",\"description\":\"Repository scripts\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDb_1Q\"},{\"id\":10118530218,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/maintainer\",\"name\":\"maintainer\",\"color\":\"FFD700\",\"description\":\"Maintainer-authored PR\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWxyEqg\"},{\"id\":10190106760,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20L\",\"name\":\"size: L\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwiA\"}],\"assignee\":{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"},\"comments\":2,\"closed_at\":\"2026-03-21T16:59:22Z\",\"created_at\":\"2026-03-20T20:30:04Z\",\"updated_at\":\"2026-03-21T18:30:22Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/51260\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/51260.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/51260.patch\",\"merged_at\":\"2026-03-21T16:59:21Z\"},\"reactions\":{\"total_count\":2,\"+1\":2,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51260/reactions\"},\"assignees\":[{\"login\":\"huntharo\",\"id\":5617868,\"node_id\":\"MDQ6VXNlcjU2MTc4Njg=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\",\"html_url\":\"https://github.com/huntharo\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/huntharo\",\"events_url\":\"https://api.github.com/users/huntharo/events{/privacy}\",\"following_url\":\"https://api.github.com/users/huntharo/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/huntharo/followers\",\"gists_url\":\"https://api.github.com/users/huntharo/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/huntharo/orgs\",\"received_events_url\":\"https://api.github.com/users/huntharo/received_events\",\"repos_url\":\"https://api.github.com/users/huntharo/repos\",\"starred_url\":\"https://api.github.com/users/huntharo/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/huntharo/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87MP4LF\",\"draft\":false},{\"id\":4041794311,\"number\":40126,\"state\":\"closed\",\"locked\":false,\"title\":\"feat(memory): pluggable system prompt section for memory plugins\",\"body\":\"## Summary\\n\\n- Problem: The system prompt \\\"Memory Recall\\\" section is hardcoded in `system-prompt.ts`, providing memory-core-specific instructions. When a third-party memory plugin is active (via the exclusive memory slot), these instructions are misleading.\\n- Why it matters: Third-party memory plugins need to provide their own system prompt guidance for their tools instead of the hardcoded memory-core instructions.\\n- What changed: Added `registerMemoryPromptSection(builder)` to the plugin API. The active memory plugin registers its own system prompt builder callback. Moved the existing \\\"Memory Recall\\\" logic into `memory-core` as its registration. `buildMemorySection()` delegates to the registered callback.\\n- What did NOT change (scope boundary): Default behavior is identical — memory-core registers the same prompt content. No changes to memory tools, compaction, or other plugin APIs.\\n\\n## Change Type (select all)\\n\\n- [ ] Bug fix\\n- [x] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [x] Memory / storage\\n- [ ] Integrations\\n- [x] API / contracts\\n- [ ] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\nNone\\n\\n## User-visible / Behavior Changes\\n\\nNone for default memory-core users. Memory plugins with `kind: \\\"memory\\\"` can now register a custom system prompt section via `api.registerMemoryPromptSection(builder)`.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? No\\n- Secrets/tokens handling changed? No\\n- New/changed network calls? No\\n- Command/tool execution surface changed? No\\n- Data access scope changed? No\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: Bun\\n- Model/provider: N/A (system prompt wiring)\\n- Integration/channel (if any): Telegram (for human test)\\n\\n### Steps\\n\\n1. Install a memory plugin that calls `api.registerMemoryPromptSection(builder)`\\n2. Start a session\\n3. Observe that the system prompt contains the plugin's memory section instead of the hardcoded one\\n\\n### Expected\\n\\n- With memory-core (default): system prompt contains \\\"Memory Recall\\\" section as before\\n- With custom memory plugin: system prompt contains the plugin's custom section\\n- With no memory plugin: memory section is omitted\\n\\n### Actual (before fix)\\n\\n- Hardcoded \\\"Memory Recall\\\" section always present regardless of active memory plugin\\n\\n## Evidence\\n\\n- [x] Failing test/log before + passing after\\n- [ ] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\nNew unit tests in `prompt-section.test.ts`: delegation, citationsMode passthrough, no-builder returns empty, last-registration-wins. All 43 existing `system-prompt.test.ts` tests pass.\\n\\n## Human Verification (required)\\n\\n- Verified scenarios: Tested on two separate OpenClaw bots (Telegram) with memory-core active — memory instructions present as expected, no regression observed\\n- Edge cases checked: None\\n- What you did **not** verify: No memory plugin active (section omitted), custom third-party memory plugin providing its own section\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? Yes\\n- Config/env changes? No\\n- Migration needed? No\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: Revert the commit; hardcoded prompt returns\\n- Files/config to restore: N/A\\n- Known bad symptoms reviewers should watch for: Missing \\\"Memory Recall\\\" section in system prompt when memory-core is active\\n\\n## Risks and Mitigations\\n\\nNone. Additive API change. Default behavior is identical — memory-core registers the same prompt content it previously hardcoded.\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"jarimustonen\",\"id\":1272053,\"node_id\":\"MDQ6VXNlcjEyNzIwNTM=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/1272053?v=4\",\"html_url\":\"https://github.com/jarimustonen\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jarimustonen\",\"events_url\":\"https://api.github.com/users/jarimustonen/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jarimustonen/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jarimustonen/followers\",\"gists_url\":\"https://api.github.com/users/jarimustonen/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jarimustonen/orgs\",\"received_events_url\":\"https://api.github.com/users/jarimustonen/received_events\",\"repos_url\":\"https://api.github.com/users/jarimustonen/repos\",\"starred_url\":\"https://api.github.com/users/jarimustonen/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jarimustonen/subscriptions\"},\"labels\":[{\"id\":10064299210,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/extensions:%20lobster\",\"name\":\"extensions: lobster\",\"color\":\"0e8a16\",\"description\":\"Extension: lobster\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EEyg\"},{\"id\":10064299264,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/extensions:%20memory-core\",\"name\":\"extensions: memory-core\",\"color\":\"0e8a16\",\"description\":\"Extension: memory-core\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EFAA\"},{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10069934037,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/scripts\",\"name\":\"scripts\",\"color\":\"5319e7\",\"description\":\"Repository scripts\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDb_1Q\"},{\"id\":10069976942,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/agents\",\"name\":\"agents\",\"color\":\"5319e7\",\"description\":\"Agent runtime and tooling\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWDenbg\"},{\"id\":10190106720,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20M\",\"name\":\"size: M\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwYA\"}],\"assignee\":{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"},\"comments\":2,\"closed_at\":\"2026-03-21T18:20:45Z\",\"created_at\":\"2026-03-08T17:38:46Z\",\"updated_at\":\"2026-03-21T18:20:45Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/40126\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/40126.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/40126.patch\",\"merged_at\":\"2026-03-21T18:20:45Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/40126/reactions\"},\"assignees\":[{\"login\":\"jalehman\",\"id\":550978,\"node_id\":\"MDQ6VXNlcjU1MDk3OA==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/550978?v=4\",\"html_url\":\"https://github.com/jalehman\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/jalehman\",\"events_url\":\"https://api.github.com/users/jalehman/events{/privacy}\",\"following_url\":\"https://api.github.com/users/jalehman/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/jalehman/followers\",\"gists_url\":\"https://api.github.com/users/jalehman/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/jalehman/orgs\",\"received_events_url\":\"https://api.github.com/users/jalehman/received_events\",\"repos_url\":\"https://api.github.com/users/jalehman/repos\",\"starred_url\":\"https://api.github.com/users/jalehman/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/jalehman/subscriptions\"}],\"node_id\":\"PR_kwDOQb6kR87I4a8x\",\"draft\":false},{\"id\":4108957490,\"number\":51146,\"state\":\"closed\",\"locked\":false,\"title\":\"fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux)\",\"body\":\"## Summary\\n\\n- Detect nvm-installed Node.js on Linux (via `NVM_DIR` env var or `process.execPath` containing `/.nvm/`)\\n- Auto-set `NODE_EXTRA_CA_CERTS` to the system CA bundle in the systemd service environment when nvm is detected on Linux (same pattern as the existing macOS default)\\n- Probe multiple distro-specific CA bundle paths (`/etc/ssl/certs/ca-certificates.crt` for Debian/Ubuntu/Alpine, `/etc/pki/tls/certs/ca-bundle.crt` for RHEL/Fedora/CentOS, `/etc/ssl/ca-bundle.pem` for openSUSE) — returns `undefined` when none exists, so `NODE_EXTRA_CA_CERTS` is never set to a missing path\\n- Write `NODE_EXTRA_CA_CERTS` to `~/.openclaw/.env` during `openclaw gateway install` so manual `gateway run` also picks up the system CA bundle via dotenv\\n- Backfill `.env` on the `already-installed` path so upgrading users get the entry without `--force`\\n- Injectable `platform`/`execPath` params throughout for testability\\n- Add documentation for nvm/VPS users with the manual workaround\\n\\nFixes #49088\\n\\n## Test plan\\n\\n- [x] `isNvmNode()` unit tests: NVM_DIR env detection, execPath detection, negative cases\\n- [x] `resolveLinuxSystemCaBundle()` probes multiple distro paths, returns undefined when none exists\\n- [x] Service env tests: NODE_EXTRA_CA_CERTS defaults on Linux with/without nvm, user override respected\\n- [x] `execPath` injectable in both `buildServiceEnvironment` and `buildNodeServiceEnvironment`\\n- [x] All 65 service-env tests pass\\n- [x] TypeScript typecheck passes (0 errors)\\n- [x] Lint/format passes\",\"author_association\":\"CONTRIBUTOR\",\"user\":{\"login\":\"GodsBoy\",\"id\":5792287,\"node_id\":\"MDQ6VXNlcjU3OTIyODc=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5792287?v=4\",\"html_url\":\"https://github.com/GodsBoy\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/GodsBoy\",\"events_url\":\"https://api.github.com/users/GodsBoy/events{/privacy}\",\"following_url\":\"https://api.github.com/users/GodsBoy/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/GodsBoy/followers\",\"gists_url\":\"https://api.github.com/users/GodsBoy/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/GodsBoy/orgs\",\"received_events_url\":\"https://api.github.com/users/GodsBoy/received_events\",\"repos_url\":\"https://api.github.com/users/GodsBoy/repos\",\"starred_url\":\"https://api.github.com/users/GodsBoy/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/GodsBoy/subscriptions\"},\"labels\":[{\"id\":9706244975,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/docs\",\"name\":\"docs\",\"color\":\"0075ca\",\"description\":\"Improvements or additions to documentation\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACQomLbw\"},{\"id\":10064298857,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/gateway\",\"name\":\"gateway\",\"color\":\"d4c5f9\",\"description\":\"Gateway runtime\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACV-EDaQ\"},{\"id\":10068150099,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/cli\",\"name\":\"cli\",\"color\":\"0052cc\",\"description\":\"CLI command changes\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACWBvHUw\"},{\"id\":10190106760,\"url\":\"https://api.github.com/repos/openclaw/openclaw/labels/size:%20L\",\"name\":\"size: L\",\"color\":\"b76e79\",\"default\":false,\"node_id\":\"LA_kwDOQb6kR88AAAACX2CwiA\"}],\"comments\":4,\"closed_at\":\"2026-03-21T18:06:32Z\",\"created_at\":\"2026-03-20T16:54:00Z\",\"updated_at\":\"2026-03-21T18:07:18Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"comments_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/comments\",\"events_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/events\",\"labels_url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/labels{/name}\",\"repository_url\":\"https://api.github.com/repos/openclaw/openclaw\",\"pull_request\":{\"url\":\"https://api.github.com/repos/openclaw/openclaw/pulls/51146\",\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"diff_url\":\"https://github.com/openclaw/openclaw/pull/51146.diff\",\"patch_url\":\"https://github.com/openclaw/openclaw/pull/51146.patch\",\"merged_at\":\"2026-03-21T18:06:32Z\"},\"reactions\":{\"total_count\":1,\"+1\":1,\"-1\":0,\"laugh\":0,\"confused\":0,\"heart\":0,\"hooray\":0,\"rocket\":0,\"eyes\":0,\"url\":\"https://api.github.com/repos/openclaw/openclaw/issues/51146/reactions\"},\"node_id\":\"PR_kwDOQb6kR87MMvoa\",\"draft\":false}]}"}]}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_012cSvUTohi7FCkbbBBT42eN","type":"message","role":"assistant","content":[{"type":"text","text":"Here's your catchup on **openclaw/openclaw**:\n\n---\n\n**Open Issues:** 8,779\n\n---\n\n**5 Most Recently Merged PRs** (merged today, 2026-03-21):\n\n| # | Title | Author |\n|---|-------|--------|\n| #34222 | fix: use content hash for memory flush dedup instead of compactionCount | @lml2468 |\n| #37080 | fix(tts): add matrix to VOICE_BUBBLE_CHANNELS | @Matthew19990919 |\n| #40126 | feat(memory): pluggable system prompt section for memory plugins | @jarimustonen |\n| #51146 | fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux) | @GodsBoy |\n| #51260 | Fix Discord `/codex_resume` picker expiration | @huntharo |\n\n---\n\n**Latest Release:** `v2026.3.13-1` (openclaw 2026.3.13, published 2026-03-14)\n\n> Note: The `-1` suffix on the tag is a recovery tag — the npm version is still `2026.3.13`. The release includes a broad mix of fixes across agents, UI, Android/iOS, Docker, and channel integrations."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":4181,"cache_creation_input_tokens":13709,"cache_read_input_tokens":41546,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":13709},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","uuid":"c2ac1184-ef12-4e46-88f5-0b42e3902867"}
{"type":"result","subtype":"success","is_error":false,"duration_ms":16449,"duration_api_ms":16069,"num_turns":4,"result":"Here's your catchup on **openclaw/openclaw**:\n\n---\n\n**Open Issues:** 8,779\n\n---\n\n**5 Most Recently Merged PRs** (merged today, 2026-03-21):\n\n| # | Title | Author |\n|---|-------|--------|\n| #34222 | fix: use content hash for memory flush dedup instead of compactionCount | @lml2468 |\n| #37080 | fix(tts): add matrix to VOICE_BUBBLE_CHANNELS | @Matthew19990919 |\n| #40126 | feat(memory): pluggable system prompt section for memory plugins | @jarimustonen |\n| #51146 | fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux) | @GodsBoy |\n| #51260 | Fix Discord `/codex_resume` picker expiration | @huntharo |\n\n---\n\n**Latest Release:** `v2026.3.13-1` (openclaw 2026.3.13, published 2026-03-14)\n\n> Note: The `-1` suffix on the tag is a recovery tag — the npm version is still `2026.3.13`. The release includes a broad mix of fixes across agents, UI, Android/iOS, Docker, and channel integrations.","stop_reason":"end_turn","session_id":"48c93971-26ec-4c21-9e9d-e2d7e921e253","total_cost_usd":0.12159645000000001,"usage":{"input_tokens":4184,"cache_creation_input_tokens":20607,"cache_read_input_tokens":76194,"output_tokens":594,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":20607,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":4184,"outputTokens":594,"cacheReadInputTokens":76194,"cacheCreationInputTokens":20607,"webSearchRequests":0,"costUSD":0.12159645000000001,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"fast_mode_state":"off","uuid":"2effd280-94e8-4211-be76-122f74183cdf"}
