fix(agents): drop stale exec approval followups after session rebind#85679
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 8, 2026, 12:03 PM ET / 16:03 UTC. Summary PR surface: Source +172, Tests +231, Other +4. Total +407 across 15 files. Reproducibility: yes. Source inspection shows current main rotates sessionId on reset while exec approval follow-ups carry only sessionKey/idempotency, and the PR body supplies live before/after gateway logs for that path. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the focused session-id guard after exact-head checks and merge coordination, keeping the optional protocol field and direct/denied fallback checks covered by regression tests. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main rotates sessionId on reset while exec approval follow-ups carry only sessionKey/idempotency, and the PR body supplies live before/after gateway logs for that path. Is this the best way to solve the issue? Yes. Pinning the approval-time sessionId and checking it at the gateway preflight plus direct fallback is the narrow owner-boundary fix; changing session-key semantics globally would be broader and riskier. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 57633c42b647. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +172, Tests +231, Other +4. Total +407 across 15 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg ✨ Hatched: 🥚 common Brave Test Hopper Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
ecd3182 to
10d3060
Compare
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
10d3060 to
03311e4
Compare
5b44e01 to
a082367
Compare
This comment was marked as spam.
This comment was marked as spam.
a082367 to
b77003e
Compare
460860b to
8ac9521
Compare
Exec approval followups were dispatched by sessionKey only. When /new or /reset rotates the sessionId under that key while an approval is pending, the resolved followup landed in the new session, surfacing stale approval output (or 'Exec denied' / continuation text) in a fresh conversation. Capture the session UUID active when the approval is requested and drop the followup once the key has been rebound to a different sessionId: - agent-run followups: carry the expected id on the agent request and drop it at the gateway as an early preflight, before the handler touches the rebound session (session-store write, chat/agent run + active-run registration, dedupe, accepted ack) — not just before model dispatch. Covers elevated and non-elevated. - denied / direct fallback followups: resolve the key's current sessionId from the session store and drop before the channel send. Fixes openclaw#59349.
8ac9521 to
f021633
Compare
|
Maintainer review: the stale-follow-up behavior in this PR is intentional and accepted. After The additive optional gateway protocol field and Swift mirror are acceptable here. CI is green on the rebased head, and the local/Testbox verification covered the touched agent/gateway paths. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Maintainer pre-merge verification for rebase merge:
Verification run before push/landing:
Known proof gap: no extra live end-to-end channel run was performed by me after the rebase; this landing relies on the PR's supplied real-behavior proof, the focused agent/gateway Testbox tests, the changed gate, and the green PR CI. Proceeding with rebase merge. |
…26.6.6) (#1040) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.6.5` → `2026.6.6` | --- ### Release Notes <details> <summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary> ### [`v2026.6.6`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#202666) [Compare Source](openclaw/openclaw@v2026.6.5...v2026.6.6) ##### Highlights - Security boundaries are substantially tighter across transcripts, sandbox binds, host environment inheritance, MCP stdio, Codex HTTP access, native search policy, elevated sender checks, deleted-agent ACP bypasses, loopback tools, Discord moderation, and Teams group actions; exec approvals now fail closed on timeout. ([#​91529](openclaw/openclaw#91529), [#​91618](openclaw/openclaw#91618), [#​91615](openclaw/openclaw#91615), [#​91619](openclaw/openclaw#91619), [#​91741](openclaw/openclaw#91741), [#​91745](openclaw/openclaw#91745), [#​91746](openclaw/openclaw#91746), [#​91748](openclaw/openclaw#91748), [#​91749](openclaw/openclaw#91749), [#​91750](openclaw/openclaw#91750), [#​91751](openclaw/openclaw#91751), [#​91752](openclaw/openclaw#91752), [#​91763](openclaw/openclaw#91763), [#​89938](openclaw/openclaw#89938)) Thanks [@​joshavant](https://github.com/joshavant), [@​pgondhi987](https://github.com/pgondhi987), [@​mmaps](https://github.com/mmaps), [@​eleqtrizit](https://github.com/eleqtrizit), [@​shakkernerd](https://github.com/shakkernerd), and [@​drobison00](https://github.com/drobison00). - Telegram delivery is safer and more coherent: account-scoped topics route to the right agent, streamed text survives tool calls, `/compact` works on generic ingress, callback handling uses concrete APIs, draft chunking is shared, durable dispatch dedupe moved into the SDK, and unauthorized DM text stays out of cache and prompt context. ([#​91189](openclaw/openclaw#91189), [#​88682](openclaw/openclaw#88682), [#​89588](openclaw/openclaw#89588), [#​90212](openclaw/openclaw#90212), [#​91876](openclaw/openclaw#91876), [#​91874](openclaw/openclaw#91874), [#​91904](openclaw/openclaw#91904), [#​91478](openclaw/openclaw#91478), [#​91915](openclaw/openclaw#91915)) Thanks [@​codysai001](https://github.com/codysai001), [@​alexzhu0](https://github.com/alexzhu0), [@​joelnishanth](https://github.com/joelnishanth), [@​snowzlm](https://github.com/snowzlm), [@​obviyus](https://github.com/obviyus), and [@​sallyom](https://github.com/sallyom). - iMessage recovery and delivery now cover always-on inbound restart, durable echo markers, block streaming, idle approval discovery, hardened outbound transport, and actionable inbound startup diagnostics. ([#​91335](openclaw/openclaw#91335), [#​91449](openclaw/openclaw#91449), [#​88969](openclaw/openclaw#88969), [#​88530](openclaw/openclaw#88530), [#​91783](openclaw/openclaw#91783), [#​91785](openclaw/openclaw#91785)) Thanks [@​omarshahine](https://github.com/omarshahine), [@​jmissig](https://github.com/jmissig), and [@​colmbrogan](https://github.com/colmbrogan). - Browser and MCP connectivity gained existing-session CDP support, discovered WebSocket validation, default-profile `cdpUrl` handling, safer browser-output boundaries, Streamable HTTP loopback transport, corrected OAuth/SSE authorization handling, and broader schema compatibility. ([#​91422](openclaw/openclaw#91422), [#​89851](openclaw/openclaw#89851), [#​91736](openclaw/openclaw#91736), [#​91747](openclaw/openclaw#91747), [#​91451](openclaw/openclaw#91451), [#​80143](openclaw/openclaw#80143)) Thanks [@​pgondhi987](https://github.com/pgondhi987), [@​anagnorisis2peripeteia](https://github.com/anagnorisis2peripeteia), [@​lifuyue](https://github.com/lifuyue), [@​eleqtrizit](https://github.com/eleqtrizit), [@​LiuwqGit](https://github.com/LiuwqGit), and [@​HemantSudarshan](https://github.com/HemantSudarshan). - Control UI startup and first-reply latency are lower through cached model metadata, removal of the startup catalog wait, lazy slash-command loading, and first-event tracing with slow-reply diagnostics. ([#​91531](openclaw/openclaw#91531), [#​91538](openclaw/openclaw#91538), [#​91568](openclaw/openclaw#91568), [#​91583](openclaw/openclaw#91583), [#​91598](openclaw/openclaw#91598)) - Provider support expands with OpenRouter OAuth onboarding and Claude Fable 5 adaptive thinking, while Codex sessions keep correct compaction ownership, local models skip guardian review, dynamic tool progress normalizes cleanly, and Gemma 4 reasoning replay is preserved. ([#​91830](openclaw/openclaw#91830), [#​91882](openclaw/openclaw#91882), [#​91590](openclaw/openclaw#91590), [#​88630](openclaw/openclaw#88630), [#​88768](openclaw/openclaw#88768), [#​91696](openclaw/openclaw#91696)) Thanks [@​Patrick-Erichsen](https://github.com/Patrick-Erichsen), [@​joshavant](https://github.com/joshavant), [@​bdjben](https://github.com/bdjben), and [@​Coder-Wangyankun](https://github.com/Coder-Wangyankun). ##### Changes - CLI progress: emit Claude CLI commentary progress events and bridge inter-tool commentary into channel progress without exposing internal protocol scaffolding. ([#​89834](openclaw/openclaw#89834), [#​90883](openclaw/openclaw#90883)) Thanks [@​anagnorisis2peripeteia](https://github.com/anagnorisis2peripeteia). - Observability: allow trusted diagnostics channels to capture tool input/output content, add first-assistant-event traces, and warn on slow initial replies. ([#​91256](openclaw/openclaw#91256), [#​91568](openclaw/openclaw#91568), [#​91583](openclaw/openclaw#91583)) Thanks [@​amknight](https://github.com/amknight). - Plugins/ClawHub: dogfood reusable package publishing, let dry runs skip publish approval, allow declared installed trusted hooks, report managed plugin version drift, and warn instead of failing on retired Skill Workshop configuration. ([#​91574](openclaw/openclaw#91574), [#​91591](openclaw/openclaw#91591), [#​90004](openclaw/openclaw#90004), [#​90927](openclaw/openclaw#90927), [#​90838](openclaw/openclaw#90838)) Thanks [@​Patrick-Erichsen](https://github.com/Patrick-Erichsen), [@​brokemac79](https://github.com/brokemac79), and [@​lonexreb](https://github.com/lonexreb). - Memory/providers: move the local llama.cpp runtime into its provider plugin, batch embeddings across files, persist the agent model catalog cache, and keep QMD JSON search one-shot while filtering stale REM recall previews. ([#​91324](openclaw/openclaw#91324), [#​89138](openclaw/openclaw#89138), [#​90457](openclaw/openclaw#90457), [#​91837](openclaw/openclaw#91837), [#​91851](openclaw/openclaw#91851)) Thanks [@​osolmaz](https://github.com/osolmaz), [@​mushuiyu886](https://github.com/mushuiyu886), [@​ai-hpc](https://github.com/ai-hpc), and [@​TurboTheTurtle](https://github.com/TurboTheTurtle). - Channels/mobile: add the QQBot group mention toggle, improve iPad and iPhone control surfaces, and expose the active connection host in the TUI footer. ([#​91423](openclaw/openclaw#91423), [#​91557](openclaw/openclaw#91557), [#​89909](openclaw/openclaw#89909)) Thanks [@​cxyhhhhh](https://github.com/cxyhhhhh), [@​Solvely-Colin](https://github.com/Solvely-Colin), and [@​baskduf](https://github.com/baskduf). - Performance: prewarm TUI runtime plugins, deduplicate plugin auto-enable fanout, trim dense text-delta snapshots, and reuse prepared startup model metadata. ([#​90782](openclaw/openclaw#90782), [#​89978](openclaw/openclaw#89978), [#​91580](openclaw/openclaw#91580), [#​91531](openclaw/openclaw#91531)) Thanks [@​RomneyDa](https://github.com/RomneyDa) and [@​ai-hpc](https://github.com/ai-hpc). ##### Fixes - Agent/session recovery: drop stale approval follow-ups after session rebind, remove drained reply-queue items by identity, recover stale main and visible replies, preserve Codex context-engine compaction ownership, lower the default compaction timeout to 180 seconds while respecting explicit configuration, and keep provider-failure terminal lifecycle state correct. ([#​85679](openclaw/openclaw#85679), [#​91450](openclaw/openclaw#91450), [#​91566](openclaw/openclaw#91566), [#​91840](openclaw/openclaw#91840), [#​91590](openclaw/openclaw#91590), [#​91361](openclaw/openclaw#91361), [#​91895](openclaw/openclaw#91895)) Thanks [@​openperf](https://github.com/openperf), [@​yetval](https://github.com/yetval), [@​joshavant](https://github.com/joshavant), [@​wangmiao0668000666](https://github.com/wangmiao0668000666), and [@​TurboTheTurtle](https://github.com/TurboTheTurtle). - User-visible content boundaries: suppress Codex/Harmony protocol artifacts, neutralize browser and LanceDB memory media directives, redact transcript images, and preserve native `/compact` replies through source suppression. ([#​89151](openclaw/openclaw#89151), [#​91422](openclaw/openclaw#91422), [#​91425](openclaw/openclaw#91425), [#​91529](openclaw/openclaw#91529), [#​90212](openclaw/openclaw#90212)) Thanks [@​joelnishanth](https://github.com/joelnishanth), [@​pgondhi987](https://github.com/pgondhi987), [@​joshavant](https://github.com/joshavant), and [@​snowzlm](https://github.com/snowzlm). - Channel delivery: keep WhatsApp captured replies attached to the successor controller after restart, retry Feishu rate limits, preserve Mattermost thread replies, canonicalize LINE webhook paths, restore Discord reply hydration and runtime timeout exports, and show OpenAI Realtime WebRTC assistant transcripts. ([#​85823](openclaw/openclaw#85823), [#​89659](openclaw/openclaw#89659), [#​91684](openclaw/openclaw#91684), [#​91649](openclaw/openclaw#91649), [#​90263](openclaw/openclaw#90263), [#​91686](openclaw/openclaw#91686), [#​90426](openclaw/openclaw#90426)) Thanks [@​itsuzef](https://github.com/itsuzef), [@​ladygege](https://github.com/ladygege), [@​jacobtomlinson](https://github.com/jacobtomlinson), [@​fuller-stack-dev](https://github.com/fuller-stack-dev), and [@​shushushv](https://github.com/shushushv). - Cron: cancel active task runs cleanly, preserve terminal timeout/cancel state, and recover no-deliver tool warnings instead of silently losing the outcome. ([#​90666](openclaw/openclaw#90666), [#​90678](openclaw/openclaw#90678)) Thanks [@​ai-hpc](https://github.com/ai-hpc). - Gateway/config/auth: share the approval runtime socket token, replace arrays explicitly in `config.patch`, skip the deleted-agent guard only for valid ACP harness sessions, surface headless LaunchAgent state, verify SQLite auth migration before cleanup, and arm QMD startup maintenance. ([#​87105](openclaw/openclaw#87105), [#​91551](openclaw/openclaw#91551), [#​91219](openclaw/openclaw#91219), [#​91614](openclaw/openclaw#91614), [#​91740](openclaw/openclaw#91740), [#​91978](openclaw/openclaw#91978)) Thanks [@​fuller-stack-dev](https://github.com/fuller-stack-dev) and [@​scotthuang](https://github.com/scotthuang). - Providers/Codex: clarify quota errors, restore the Codex synthetic usage line, canonicalize Codex protocol assets, require API-key auth for realtime voice, normalize ACP model refs, preserve Gemma 4 `reasoning_content`, and avoid guardian review for local models. ([#​91390](openclaw/openclaw#91390), [#​91709](openclaw/openclaw#91709), [#​91507](openclaw/openclaw#91507), [#​91567](openclaw/openclaw#91567), [#​88630](openclaw/openclaw#88630), [#​91696](openclaw/openclaw#91696)) Thanks [@​hxy91819](https://github.com/hxy91819), [@​brokemac79](https://github.com/brokemac79), [@​RomneyDa](https://github.com/RomneyDa), [@​joshavant](https://github.com/joshavant), and [@​Coder-Wangyankun](https://github.com/Coder-Wangyankun). - Updates/builds: recover package Gateway restarts after refresh failure, expose plugin convergence repair, fall back to Corepack in PATH-less pnpm environments, seed the correct Docker store packages, and keep ClawHub dry-run and publish paths reusable. ([#​91581](openclaw/openclaw#91581), [#​91599](openclaw/openclaw#91599), [#​91547](openclaw/openclaw#91547), [#​91591](openclaw/openclaw#91591)) Thanks [@​fuller-stack-dev](https://github.com/fuller-stack-dev), [@​sallyom](https://github.com/sallyom), and [@​Patrick-Erichsen](https://github.com/Patrick-Erichsen). - UI: require explicit user intent before opening chat sessions and drain restored chat queues after session switches. ([#​91480](openclaw/openclaw#91480)) Thanks [@​TurboTheTurtle](https://github.com/TurboTheTurtle). - Android: avoid the `dataSync` foreground-service type for persistent nodes. ([#​80082](openclaw/openclaw#80082)) Thanks [@​davelutztx](https://github.com/davelutztx). - Native hooks: bound relay lifetimes so abandoned native hook connections cannot linger indefinitely. ([#​91550](openclaw/openclaw#91550)) Thanks [@​joshavant](https://github.com/joshavant). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/1040
Summary
/newor/resetbefore resolving it, the eventual approval follow-up can be delivered into the new session. It surfaces as stale approval messages,Exec denied, or continuation text appearing in an unrelated fresh conversation. The bug is observed across elevated and non-elevated approvals on every channel that routes through/v1/chat/completionsor the agent-command pipeline.sessionKeyonly (the agent follow-up request carries the key, not the originating session instance). The gateway resolves that key to whateversessionIdit currently maps to at follow-up time./newand/resetrotate thesessionIdunder the same key, so a follow-up created while the original session was active resolves to the new session and lands there. The session instance active when the approval was requested was never captured or compared, so there was nothing to detect the rebind. CWE-200 information leak: old approval output reaches a fresh user-facing conversation.sessionId, regenerated on/newand/reset) and thread it from the exec tool through the exec hosts onto the follow-up target. Drop the follow-up once that key has been rebound to a different session id, on both delivery paths:execApprovalFollowupExpectedSessionId, and drop it at the gateway as an early preflight — before the handler touches the rebound session at all (session-store write, chat/agent run + active-run registration, dedupe, accepted ack), not just before model dispatch. So a stale follow-up leaves the rebound session completely untouched. Because the id rides on the request (not only on the elevated runtime handoff), it covers both elevated and non-elevated approvals.Exec deniedand direct-send path, which never reaches the gateway): resolve the key's current session id from the session store and drop the follow-up before the channel send. Thesession.storetemplate is threaded through so custom store locations resolve correctly.src/agents/bash-tools.exec-types.ts: addsessionIdand thesession.storetemplate toExecToolDefaults.src/agents/agent-tools.ts: forward the run's session id and store template into the exec tool defaults.src/agents/bash-tools.exec.ts,bash-tools.exec-host-gateway.ts,bash-tools.exec-host-node.ts,bash-tools.exec-host-node.types.ts: thread the session id and store template tobuildExecApprovalFollowupTarget.src/agents/bash-tools.exec-host-shared.ts: carryexpectedSessionIdand the store template on the follow-up target and forward them to the dispatch.src/agents/bash-tools.exec-approval-followup.ts: includeexecApprovalFollowupExpectedSessionIdon the follow-up agent request, and drop denied/direct fallback sends when the key resolves to a different session id.src/agents/bash-tools.exec-approval-followup-state.ts: add theisExecApprovalFollowupSessionRebounddecision helper.packages/gateway-protocol/src/schema/agent.ts: add the optional request field (additive only).src/gateway/server-methods/agent.ts: drop the follow-up as an early preflight when the session key was rebound — before any session-store write, run/context/active-run registration, dedupe, or accepted ack.apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift: protocol model mirror for the new optional field.src/agents/bash-tools.exec-host-shared.test.ts,bash-tools.exec-approval-followup.test.ts: regression coverage for both delivery paths (rebound / unchanged / missing-id).src/gateway/server-methods/agent.test.ts: focused gateway integration test asserting that a stale exec-approval followup is dropped at preflight without any side effect on the rebound session — response is{status: "ok", summary: "exec approval followup dropped: ..."}, dedupe entry is seeded with that payload, and neithermocks.updateSessionStorenormocks.agentCommandis invoked.agentRequest); no key is retired, no version bump required, existing clients unaffected.package.json/pnpm-lock.yaml/npm-shrinkwrap.json/pnpm-workspace.yamledits; Dependency Guard not applicable.CHANGELOG.mdedit (release-owned).Reproduction
/newor/reset, creating a newsessionIdunder the same key.Exec denied, or continuation text surfaces in an unrelated fresh conversation.Real behavior proof
/newor/resetwhile the approval was pending must be dropped at the gateway (resume path) or in the agents layer (denied/direct path) instead of being delivered into the new session.startGatewayServeron loopback (bundled plugins disabled for fast startup; channels/providers/cron skipped), driven over a real operator WebSocket connection. Linux x64, Node 22. RealperformGatewaySessionReset+ realexec.approval.resolveoperator RPC + real on-disk session-store JSON.agent:main:mainto session id11111111-...-111111111111; start the gateway and connect an operator; build the gateway exec tool for that session (agent follow-up mode,ask: always) and run a command requiring approval, leaving it pending; call the real reset pathperformGatewaySessionReset({ key, reason: "reset" })to rotate the key to a new session id; resolve the pending approval via theexec.approval.resolveoperator RPC; observe the gateway log + re-read the session store. Unit-level regression:node scripts/run-vitest.mjs src/agents/bash-tools.exec-approval-followup.test.ts src/agents/bash-tools.exec-host-shared.test.ts.[REPRO]= harness script markers,[gateway]/[agents/exec-approval-followup]= OpenClaw runtime logs):updatedAtunchanged), proving no run/store/dedupe/ack side effects on the rebound session. The denied/direct path equivalent is dropped one layer earlier in the agents code so no channel send occurs. The pre-fix baseline shows the same scenario unconditionally dispatching a follow-up agent run (runId=exec-approval-followup:0fb830d1-...) into the rebound session.node scripts/run-vitest.mjs src/agents/bash-tools.exec-approval-followup.test.ts src/agents/bash-tools.exec-host-shared.test.ts(86 passed across 4 files) covers rebound / unchanged / missing-id branches on the predicate, the followup-target thread-through, and the denied/direct fallback path.node scripts/run-vitest.mjs src/gateway/server-methods/agent.test.ts -t 'drops a stale exec approval followup at preflight'(2 passed) locks the gateway preflight invariant — drop response shape, dedupe seed, and the absence ofupdateSessionStore/agentCommandcalls — in regression tests. Bite check confirmed: temporarily disabling the preflight makes the new gateway test fail withstatus: "accepted"(followup dispatched into the rebound session), which is exactly the pre-fix behavior the predicate is supposed to prevent.pnpm exec oxfmt --checkandpnpm exec oxlinton the touched TypeScript files are clean.origin/mainwith the single import-merge conflict resolved.Risk / Mitigation
agentRequest; no key is retired, no version bump required. Existing clients that do not send the field hit the existing delivery path. The SwiftOpenClawProtocolmirror is updated in lockstep so iOS clients deserialize cleanly.updatedAtis unchanged across the drop.src/agents/agent-command.tsandbash-tools.*. Mitigation: this branch rebases cleanly onto currentorigin/mainafter resolving one import-merge inbash-tools.exec-approval-followup.ts(combine the newisExecApprovalFollowupSessionReboundimport with main's renamedembedded-agent-helpers/sanitize-user-facing-textpath). Merge order with the sibling PRs is independent.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Fixes #59349