Skip to content

Guard current browser tab exports#75731

Merged
drobison00 merged 5 commits intoopenclaw:mainfrom
eleqtrizit:549
May 4, 2026
Merged

Guard current browser tab exports#75731
drobison00 merged 5 commits intoopenclaw:mainfrom
eleqtrizit:549

Conversation

@eleqtrizit
Copy link
Copy Markdown
Contributor

Summary

  • Adds a shared current-tab URL gate for browser route handlers that inspect an already-selected tab before collecting output.
  • Applies the gate to browser debug/export endpoints so blocked current tabs return an error before collection runs.

Changes

  • Added enforceCurrentUrlAllowed to withRouteTabContext and withPlaywrightRouteContext, using the existing browser navigation result policy and proxy-mode handling.
  • Enabled the gate on console, errors, requests, trace, and response body routes.
  • Extended the browser route helper and control-server tests to cover strict current-tab blocking.

Validation

  • corepack pnpm test -- extensions/browser/src/browser/routes/agent.shared.test.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts
  • corepack pnpm check
  • corepack pnpm exec oxfmt --check extensions/browser/src/browser/routes/agent.shared.ts extensions/browser/src/browser/routes/agent.debug.ts extensions/browser/src/browser/routes/agent.act.ts extensions/browser/src/browser/routes/agent.shared.test.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts extensions/browser/src/browser/server.control-server.test-harness.ts
  • Local agentic review was attempted; the noninteractive review command did not complete with findings.

Notes

  • No behavior changes for routes that do not opt into the current-tab gate.
  • Repo-wide corepack pnpm format:check currently reports unrelated formatting drift outside this change.

@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels May 1, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 1, 2026

Codex review: needs changes before merge.

Summary
The PR adds an opt-in current-tab URL policy gate to browser route helpers, enables it for several browser debug/export/storage routes, expands tests, and adds a changelog entry.

Reproducibility: yes. Source inspection shows the latest PR head still routes GET /snapshot through direct tab resolution and CDP fallback paths without the new current-tab gate, while the guarded route matrix does not exercise /snapshot.

Next step before merge
A narrow automated repair can add the missing snapshot route guard and regression coverage without a product decision.

Security
Needs attention: The diff strengthens several browser SSRF paths but leaves a concrete snapshot read-route gap.

Review findings

  • [P2] Gate the snapshot route before claiming coverage — CHANGELOG.md:211
Review details

Best possible solution:

Keep the shared opt-in guard, apply it to GET /snapshot before any backend collection or CDP fallback, and add HTTP-level regression coverage for a blocked current-tab snapshot.

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

Yes. Source inspection shows the latest PR head still routes GET /snapshot through direct tab resolution and CDP fallback paths without the new current-tab gate, while the guarded route matrix does not exercise /snapshot.

Is this the best way to solve the issue?

No, not yet. The shared helper is the right maintainable direction, but the PR should use it for snapshot before any collection path instead of relying on backend-specific checks and a changelog claim.

Full review comments:

  • [P2] Gate the snapshot route before claiming coverage — CHANGELOG.md:211
    The new changelog says snapshot is covered by the current-tab policy gate, but the PR head still leaves GET /snapshot outside withRouteTabContext({ enforceCurrentUrlAllowed: true }). CDP fallback paths can still collect from a blocked current tab, so add the route-level guard plus regression coverage or remove snapshot from the claimed fixed surface.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.88

Security concerns:

  • [medium] Snapshot read route remains outside the new gate — extensions/browser/src/browser/routes/agent.snapshot.ts:502
    GET /snapshot can still reach snapshot collection paths without the new current-tab execution gate, including CDP fallback paths that do not receive an SSRF policy argument.
    Confidence: 0.86

Acceptance criteria:

  • pnpm test extensions/browser/src/browser/routes/agent.shared.test.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts extensions/browser/src/browser/routes/agent.snapshot.test.ts
  • pnpm exec oxfmt --check --threads=1 extensions/browser/src/browser/routes/agent.shared.ts extensions/browser/src/browser/routes/agent.snapshot.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts extensions/browser/src/browser/server.control-server.test-harness.ts CHANGELOG.md
  • pnpm check:changed

What I checked:

Likely related people:

  • steipete: Recent path history shows repeated browser route work, including CDP role snapshot fallback and safe tab URL response handling. (role: recent browser route maintainer; confidence: high; commits: ed1ac2fc4492, 7132ca5766af; files: extensions/browser/src/browser/routes/agent.snapshot.ts, extensions/browser/src/browser/routes/agent.shared.ts)
  • pgondhi987: Introduced prior snapshot/screenshot/tab SSRF enforcement work that is directly adjacent to this PR's behavior. (role: snapshot SSRF hardening contributor; confidence: medium; commits: b75ad800a590; files: extensions/browser/src/browser/routes/agent.snapshot.ts)
  • eleqtrizit: Has prior merged work on strict browser hostname navigation and interaction-driven navigation guards, in addition to authoring this PR. (role: browser navigation guard contributor; confidence: medium; commits: 121c452d666d, 049acf23cb03; files: extensions/browser/src/browser/navigation-guard.ts, extensions/browser/src/browser/routes/agent.snapshot.ts)
  • obviyus: Recent navigation-guard history includes default hostname SSRF guard changes that affect the same policy contract used by this PR. (role: adjacent navigation-policy maintainer; confidence: medium; commits: bf1d49093ae3; files: extensions/browser/src/browser/navigation-guard.ts)

Remaining risk / open question:

  • I did not run validation commands during this read-only review; the blocker is based on source and PR-head diff inspection.

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

Re-review progress:

@eleqtrizit
Copy link
Copy Markdown
Contributor Author

@clawsweeper review

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 1, 2026

🦞🦞
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.

@eleqtrizit
Copy link
Copy Markdown
Contributor Author

Standards check for the latest branch update:

  • Scope stayed inside the browser plugin route/helper/test surface: browser routes, route tests, and the control-server harness. No core, SDK, dependency, workflow, manifest, or generated surfaces were changed.
  • Rechecked the security contract around tab-scoped read/export routes. The branch uses the existing SSRF navigation-result policy as the execution gate before Playwright data collection, and the snapshot path now uses the same shared route-helper gate instead of carrying a separate inline check.
  • Extended the route-level regression matrix so the relevant guarded routes are covered through the HTTP control-server path. The tests assert both the client-visible policy failure and the important security property: the underlying Playwright/data collection mock is not invoked for a disallowed current-tab URL.
  • Kept the tests colocated, table-driven, and harness-backed with narrow mocks plus reusable SSRF policy/current-tab URL fixtures, matching the existing browser test style.
  • Rechecked formatting and whitespace on the outgoing delta.

Validation on 1a24079089b44e0a6f0a2074763cd35320b0a096:

  • corepack pnpm test extensions/browser/src/browser/routes/agent.shared.test.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts extensions/browser/src/browser/routes/agent.snapshot.test.ts — passed, 3 files / 46 tests.
  • corepack pnpm exec oxfmt --check --threads=1 extensions/browser/src/browser/routes/agent.snapshot.ts extensions/browser/src/browser/routes/agent.storage.ts extensions/browser/src/browser/server.agent-contract-form-layout-act-commands.test.ts extensions/browser/src/browser/server.control-server.test-harness.ts — passed.
  • git diff --check on the outgoing delta — passed.

CI is queued for the pushed SHA.

drobison00 added a commit to eleqtrizit/openclaw that referenced this pull request May 4, 2026
drobison00 added a commit to eleqtrizit/openclaw that referenced this pull request May 4, 2026
@drobison00 drobison00 merged commit ef0dbcf into openclaw:main May 4, 2026
78 checks passed
arieldiego73 pushed a commit to arieldiego73/openclaw that referenced this pull request May 5, 2026
* fix(browser): guard current tab exports

* fix(browser): expand tab guard coverage

* fix(browser): guard tab reads

* fix(browser): guard screenshot route

* changelog: PR openclaw#75731

---------

Co-authored-by: Devin Robison <[email protected]>
cbeltrao added a commit to stationzeroai/openclaw-updated-from-original-repository that referenced this pull request May 5, 2026
* feat(models): list auth profiles

* fix(gateway): clarify systemd service scope

* fix(types): wire plugin package metadata

* test(agents): update model auth fixture shape

* test: harden plugin and UI isolation checks

* docs(changelog): credit recent plugin fixes

* fix: proxy direct APNs HTTP2 sessions (#74905)

Summary:
- This PR routes direct APNs HTTP/2 sends through an APNs allowlisted managed-proxy CONNECT wrapper, adds APNs proxy validation/docs/guardrails, and expands regression and live-test coverage.
- Reproducibility: yes. source-reproducible: current main `sendApnsRequest()` still uses raw `http2.connect(au ... nly covers HTTP/global-agent/Undici hooks. I did not run a live APNs reproduction in this read-only review.

Automerge notes:
- PR branch already contained follow-up commit before automerge: test: guard raw HTTP2 APNs connections
- PR branch already contained follow-up commit before automerge: test: guard raw HTTP2 with OpenGrep
- PR branch already contained follow-up commit before automerge: lint: ban raw HTTP2 imports
- PR branch already contained follow-up commit before automerge: fix: use managed proxy state for APNs
- PR branch already contained follow-up commit before automerge: test: exercise APNs active proxy state
- PR branch already contained follow-up commit before automerge: fix: reject conflicting managed proxy activation

Validation:
- ClawSweeper review passed for head dab7c86a7595a01b09c32395578e7c26a03f938d.
- Required merge gates passed before the squash merge.

Prepared head SHA: dab7c86a7595a01b09c32395578e7c26a03f938d
Review: https://github.com/openclaw/openclaw/pull/74905#issuecomment-4350181159

Co-authored-by: jesse-merhi <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>

* test: stabilize full crabbox sweep

* fix: refresh stale codex auth profile routing

Summary:
- Promotes fresh Codex OAuth relogin profiles ahead of stale per-agent auth order entries.
- Repairs invalidated per-agent Codex order and session overrides toward healthy relogin profiles.
- Adds focused regression coverage for auth order, invalidated profile repair, and session override re-resolution.

Verification:
- pnpm test src/agents/auth-profiles/profiles.test.ts src/agents/auth-profiles.ensureauthprofilestore.test.ts src/agents/auth-profiles/session-override.test.ts src/commands/models/auth.test.ts -- --reporter=verbose
- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/agents/auth-profiles.ensureauthprofilestore.test.ts src/agents/auth-profiles/persisted.ts src/agents/auth-profiles/profiles.test.ts src/agents/auth-profiles/profiles.ts src/agents/auth-profiles/session-override.test.ts src/agents/auth-profiles/session-override.ts src/commands/models/auth.test.ts src/commands/models/auth.ts
- git diff --check origin/main...HEAD
- pnpm check:changed via Blacksmith Testbox tbx_01kqscwvkywnt72qx1t8a07tp8
- GitHub CI on 1a6f93a3723236efb8132dec3f2bc8be505c7364, with checks-node-core-runtime-infra-state rerun passing after an unrelated stale-lock timing failure

* test(release): leave Windows updater timeout headroom

* Control UI explicit action feedback

Add explicit Control UI feedback for repeated actions: session switches now announce through the chat controls live-status path and flash the active session selector, config actions show inline busy state, and session list empty states distinguish filtered results with a Show all reset. Also refresh generated Control UI locale metadata and fallback markers.

* chore(ui): refresh zh-CN control ui locale

* chore(ui): refresh de control ui locale

* chore(ui): refresh zh-TW control ui locale

* chore(ui): refresh pt-BR control ui locale

* chore(ui): refresh es control ui locale

* chore(ui): refresh ja-JP control ui locale

* chore(ui): refresh ko control ui locale

* chore(ui): refresh fr control ui locale

* chore(ui): refresh ar control ui locale

* chore(ui): refresh tr control ui locale

* chore(ui): refresh it control ui locale

* chore(ui): refresh uk control ui locale

* chore(ui): refresh id control ui locale

* chore(ui): refresh pl control ui locale

* chore(ui): refresh vi control ui locale

* chore(ui): refresh th control ui locale

* chore(ui): refresh nl control ui locale

* chore(ui): refresh fa control ui locale

* test: repair current main checks

* fix(tui): abort run during pre-event waiting gap (#77199)

* fix(tui): abort run during pre-event waiting gap

Track the runId returned from chat.send so pressing Esc while `activeChatRunId` is still null aborts the in-flight run instead of repeatedly printing "no active run". Identified in #1296.

* fix(tui): drop redundant comment on pendingChatRunId set

* docs(changelog): restore 2026.5.3 release notes

* fix(tui): preserve code spans, code blocks, and dotted/hyphenated identifiers from long-token sanitizer (#77335)

The display sanitizer's long-token chunker (`\S{33,}` -> 32-char chunks
joined by spaces) was injecting literal spaces inside inline code spans,
fenced code blocks, and bare identifiers it didn't recognize. Tokens like
`requireConfirmationForMutatingActions`, `ubuntu-budgie-desktop-environment`,
and `binary_sensor.sense_energy_monitor_power` rendered with mid-word
spaces, contaminating copy/paste of package names, entity IDs, and shell
line-continuations.

Fix:

- Make sanitizer code-aware: split text into fenced/inline-code segments
  and prose, and only run the chunker on prose segments. Code regions
  pass through verbatim.
- Widen `isCopySensitiveToken` to use the punctuation-stripped candidate
  for all classification, and accept any `FILE_LIKE_RE` token that
  contains `_`, `-`, or `.` (covers package names, dotted IDs, kebab
  flags). Picks up the goals of #69340 and #39565.
- Skip chunking for symbol-only runs (box-drawing rows, dashes, equals)
  so table borders aren't corrupted.
- Preserve the original goal of narrow-terminal protection: long
  unidentifiable prose tokens (e.g. accidental base64 dumps) are still
  chunked so they don't blow out terminal layout.

Security ordering preserved: ANSI strip / control-char strip / binary
redaction still run on the whole string before segmentation, so code
regions cannot smuggle escapes, control characters, or binary garbage
past the sanitizer.

16 new regression tests cover: camelCase config keys in inline code,
hyphenated package names (bare and in code), dotted entity IDs (bare
and in code), backtick and tilde fenced blocks, base64-like blobs in
code, prose-token chunking unchanged, prose-around-code mixed content,
box-drawing horizontal rules, multi-line shell `\\` continuations,
plus three explicit security-ordering tests asserting ANSI/control/
binary stripping still runs inside code segments.

Fixes #48432, #39505.
Supersedes #69340, #39565 (carries forward both ideas in a more
general fix). Carries forward the code-fence-aware approach from the
closed #48445.

* fix(telegram): clean up tool-only previews

* [plugin sdk] Harden finalize retry and run context cleanup (#75600)

Merged via squash.

Prepared head SHA: ec58a6212b0aa239bf23d339d825eeff0777b611
Co-authored-by: 100yenadmin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* feat(cron): surface run diagnostics in status (#75928)

* feat(cron): surface run diagnostics in status

* docs: add cron diagnostics changelog

* fix(cron): preserve latest run diagnostics

* test(cron): update diagnostics regression deps

* fix(memory): prevent memory-hit starvation in corpus=all by capping per-corpus results (#77337) (#77356)

Summary:
- The PR adds balanced, backfilled all-corpus result merging for `memory_search` and `wiki_search`, regression tests, and a changelog entry for #77337.
- Reproducibility: yes. Current main is source-reproducible: both affected paths fetch both corpora for `corpus=all`, raw-sort wiki integer scores against memory similarity scores, and slice to `maxResults`.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix(memory): prevent all-corpus memory hit starvation

Validation:
- ClawSweeper review passed for head a5b4f6a93210e748c40e64160848dac5c5fa94f1.
- Required merge gates passed before the squash merge.

Prepared head SHA: a5b4f6a93210e748c40e64160848dac5c5fa94f1
Review: https://github.com/openclaw/openclaw/pull/77356#issuecomment-4371767658

Co-authored-by: HCL <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>

* fix(qqbot): keep private commands off framework surface [AI] (#77212)

* fix: keep private qqbot commands off framework surface

* addressing codex review

* docs: add changelog entry for PR merge

* [plugin sdk] Project session extension slots (#75609)

Merged via squash.

Prepared head SHA: d9b670a8676d7ecc638568c9713a103dc58a2868
Co-authored-by: 100yenadmin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix #77296: [Bug]: Plugin manifest `skills` field not published to agent skill discovery paths (#77328)

Summary:
- The PR publishes enabled plugin-declared skill directories into a generated `~/.openclaw/plugin-skills` syml ... plugin-skill precedence, cleans stale generated links, adds regression coverage, and updates the changelog.
- Reproducibility: yes. source-based. Current main resolves plugin-declared skill directories for prompt loadi ... ble generated discovery path, and the linked issue provides a concrete ENOENT path for a plugin `SKILL.md`.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: fix: resolve issue #77296
- Included post-review commit in the final squash: fix: publish plugin manifest skills for agent discovery
- Included post-review commit in the final squash: fix(clawsweeper): address review for automerge-openclaw-openclaw-7732…

Validation:
- ClawSweeper review passed for head 0f52865ee3a9b268bf33ab012a787b2b32fdd050.
- Required merge gates passed before the squash merge.

Prepared head SHA: 0f52865ee3a9b268bf33ab012a787b2b32fdd050
Review: https://github.com/openclaw/openclaw/pull/77328#issuecomment-4371415857

Co-authored-by: zhang-guiping <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>

* fix(security): block workspace env from overriding Windows system root paths [AI] (#74458)

* fix: address issue

* fix: address PR review feedback

* fix: address PR review feedback

* fix: address PR review feedback

* fix: address codex review feedback

* fix: address codex review feedback

* changelog: PR #74458

---------

Co-authored-by: Devin Robison <[email protected]>

* test(acpx): cover Windows extension test paths

* test(bluebubbles): accept native contact database paths

* test(diffs): use native viewer asset file URLs

* test(discord): accept native voice temp paths

* test(feishu): cover native Windows webhook and workspace paths

* test(feishu): accept native oversized body resets

* test(matrix): cover native Windows file semantics

* test(memory): cover native Windows paths and locks

* test(telegram): accept native Windows session file paths

* test(whatsapp): accept native Windows auth paths

* test(openshell): accept native symlink targets

* test(anthropic-vertex): accept native ADC home paths

* fix(qa-channel): settle aborted bus polls

* test(qa-lab): accept native Windows paths

* fix(device-pair): require pairing scope for pair command [AI] (#76377)

* fix: restrict device pairing command access

* addressing review-skill

* addressing review-skill

* addressing codex review

* address codex review feedback

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* docs: add changelog entry for PR merge

* Gate zalouser startup name matching [AI] (#77411)

* fix: gate zalouser startup name matching

* addressing codex review

* docs: add changelog entry for PR merge

* fix: block SystemRoot/WINDIR in workspace .env and harden reg.exe path resolution [AI-assisted] (#74454)

* fix: address issue

* fix: address PR review feedback

* Add changelog entry for PR #74454

---------

Co-authored-by: Devin Robison <[email protected]>

* Feat/main session durable delivery pr (#75280)

* feat: generalize pending-final-delivery for subagents and main session

(cherry picked from commit 677fcbfaf87c8cd6de8b5bd02099b29b7d49e916)

* feat(agents): implement Phase 2 durable final delivery for main sessions

(cherry picked from commit b4e39f0ddf6dbd3f0d3b9226df8e714ad722f751)

* fix(agents): narrow heartbeat deferral to pending final delivery

* fix(agents): clear final delivery after dispatch

* fix(agents): gate durable delivery retry capture

---------

Co-authored-by: Mert Basar <[email protected]>

* fix(gateway): clamp unbound websocket auth scopes [AI] (#77413)

* fix: clamp unapproved trusted proxy websocket scopes

* addressing claude review

* addressing claude review

* addressing ci

* addressing ci

* docs: add changelog entry for PR merge

* fix(gateway): add safe restart coordinator (#76923)

Add a safe restart coordinator that preflights active Gateway work before restart.

- expose gateway.restart.preflight and gateway.restart.request RPC methods
- add explicit openclaw gateway restart --safe / openclaw daemon restart --safe path
- narrow restart blockers to running non-ended tasks so queued records no longer block indefinitely
- keep existing restart behavior unchanged; --force remains the immediate override

Co-authored-by: NikolaFC <[email protected]>
Co-authored-by: galiniliev <[email protected]>

* fix: pass claude cli thinking effort (#77410)

Summary:
- Adds a plugin-owned CLI backend argument rewrite hook and wires Anthropic `claude-cli` to translate non-off `/think` levels into Claude Code `--effort`, with docs, changelog, API baseline, and tests.
- Reproducibility: yes. Current main has a high-confidence source reproduction: choose `claude-cli`, set a non ... builds argv from backend args that contain no `--effort` even though `thinkLevel` exists on the run params.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head be17754009e5651ec9df6472f46fbffdfe3346e7.
- Required merge gates passed before the squash merge.

Prepared head SHA: be17754009e5651ec9df6472f46fbffdfe3346e7
Review: https://github.com/openclaw/openclaw/pull/77410#issuecomment-4372812685

Co-authored-by: stainlu <[email protected]>

* test(release): skip restart in package upgrade lane

* fix(plugins): reserve pending delivery session slots

* chore: better explicit message on whatsapp

* chore: ignore crabbox artifacts

* fix(plugins): trust catalog package installs

* docs(plugins): explain catalog install trust

* fix(active-memory): skip colon-containing session-store channels to prevent crash with QQ c2c agent IDs (#77402)

Summary:
- The PR filters colon-containing store-derived Active Memory channel values before embedded recall resolution, adds a QQ c2c regression test, and records the user-facing changelog entry.
- Reproducibility: yes. Source inspection on current main shows a stored colon-containing `lastChannel` or `ch ... come the strong embedded recall channel, and the downstream bundled-plugin directory validator rejects `:`.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fixup! fix(active-memory): add changelog contributor credit (clawswee…
- PR branch already contained follow-up commit before automerge: fix(active-memory): skip colon-containing session-store channels

Validation:
- ClawSweeper review passed for head 4bf00dd6acfc95d861779ec1fdd1ae36cab93797.
- Required merge gates passed before the squash merge.

Prepared head SHA: 4bf00dd6acfc95d861779ec1fdd1ae36cab93797
Review: https://github.com/openclaw/openclaw/pull/77402#issuecomment-4372618783

Co-authored-by: HCL <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>

* fix(qqbot): preserve framework command authorization (#77453)

* fix(qqbot): preserve framework command authorization

* Add changelog entry for PR #77453

* docs(changelog): credit @NikolaFC and @MertBasar0 for gateway and main-session fixes

#76923 (Satoshi F. / @NikolaFC) added user-facing `gateway.restart.safe`
preflight alignment and #75280 (Mert Başar / @MertBasar0) added
user-facing main-session pending-delivery marker preservation, but both
entries landed without contributor attribution. Add the merging PR refs
and credit the human contributors per CLAUDE.md changelog-attribution
rules.

* Use trusted Windows browser helper root (#77469)

* fix(agents): refresh deferred subagent delivery text

* fix(doctor): restore group config drift migrations (#77465)

* docs(changelog): credit group config migration fix

Credit @scoootscooob for #77465.

* ci: gate slack live qa credentials

* fix(process): kill Windows command trees on timeout

(cherry picked from commit 9cc3ae100b846437dd3dcbcfaf20b242d9f6f6a2)

* test(release): recover known Windows packaged upgrade timeout

(cherry picked from commit 8f7399e9e9decbb6e2125278a7ffb6327e9f0088)

* test(release): match versioned Windows upgrade tarballs

(cherry picked from commit b70dbe32d0311808e95448e0f78dee8931e09664)

* ci(release): fix ClawHub runtime preflight command

(cherry picked from commit 954b25e129f3d42a69d495a250c0f6c87bcf47f2)

* fix codex thread continuity

* docs: credit Codex context PR (#76824)

* Harden update environment path resolution (#77470)

* Harden update environment path resolution

* docs(changelog): credit windows update env path hardening

Adds the user-facing Unreleased Fixes entry for the workspace LOCALAPPDATA
blocklist + portable Git path-prepend hardening change in this PR.

* Fix Active Memory memory-only recall latency (#75200)

Summary:
- The PR adds a bounded latest-message search-query section to Active Memory recall prompts, regression coverage for metadata stripping, a changelog entry, and pending-final-delivery session slot reservations.
- Reproducibility: yes. for a source-level reproduction path: an eligible interactive turn reaches Active Memo ... om current releases, but I did not run a live gateway/provider reproduction under the read-only constraint.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(plugins): reserve final delivery session slots

Validation:
- ClawSweeper review passed for head 24bf408e75d87081c8736f1df7fd06bc3b4f887e.
- Required merge gates passed before the squash merge.

Prepared head SHA: 24bf408e75d87081c8736f1df7fd06bc3b4f887e
Review: https://github.com/openclaw/openclaw/pull/75200#issuecomment-4354978044

Co-authored-by: SYU8384 <[email protected]>

* Guard current browser tab exports (#75731)

* fix(browser): guard current tab exports

* fix(browser): expand tab guard coverage

* fix(browser): guard tab reads

* fix(browser): guard screenshot route

* changelog: PR #75731

---------

Co-authored-by: Devin Robison <[email protected]>

* fix(update): finish post-core package updates

* fix(update): exit post-core package child

* docs(changelog): note update and slack fixes

* Harden Windows command wrapper resolution (#77472)

* Harden Windows command wrapper resolution

* clawsweeper: route Windows cmd.exe wrapper through getWindowsInstallRoots

Replace the local SystemRoot/windir/SYSTEMROOT/WINDIR scan in
resolveTrustedWindowsCmdExe with the shared getWindowsInstallRoots()
resolver from src/infra/windows-install-roots.ts. The shared resolver
already rejects UNC paths, root-relative values, semicolon-delimited
path-lists, and missing-drive-letter roots, and prefers registry-derived
roots over env, so the wrapper-launch trust boundary now matches the
existing Windows install-root boundary on main.

Tests:
- _resetWindowsInstallRootsForTests in beforeEach so cached roots track
  per-test process.env mutations
- expectedTrustedCmdExe helper now joins the resolved systemRoot, so the
  expected wrapper executable matches the production resolver on Linux
  CI (where it falls back to DEFAULT_WINDOWS_SYSTEM_ROOT)
- new "rejects unsafe Windows root values" test covers UNC,
  semicolon-delimited path-list, root-relative, and bare-relative
  SystemRoot inputs

* Add CHANGELOG entry for #77472 Windows command wrapper hardening

* clawsweeper: stub registry probe in Windows wrapper tests

On real Windows CI runners getWindowsInstallRoots() reads the canonical
SystemRoot from the registry (e.g. C:\WINDOWS) before falling back to
process.env, which shadowed the env-only setup in the ComSpec-poisoning
and unsafe-root tests and produced casing mismatches like
"C:\WINDOWS\System32\cmd.exe" vs the expected "C:\Windows\...". Pass a
queryRegistryValue stub returning null in beforeEach (and inside the
unsafe-root loop) so install-root resolution is fully driven by the
test's process.env setup on every platform.

* clawsweeper: overwrite WINDIR alongside SystemRoot in unsafe-root test

Real Windows runners did not honor `delete process.env.windir`, so the
unsafe-root iteration's WINDIR fallback still resolved to the canonical
`C:\WINDOWS` and produced a casing mismatch against the expected default
`C:\Windows\System32\cmd.exe`. Set both `SystemRoot` and `WINDIR` to the
unsafe payload so every install-root env source is rejected by
`normalizeWindowsInstallRoot` and the resolver falls through to
`DEFAULT_WINDOWS_SYSTEM_ROOT`.

* ci(release): recover Windows packaged update no-restart timeout

* fix(plugins): trust official diagnostics installs (#77516)

* fix(plugins): trust chat catalog installs

* fix(agents): honor hook bootstrap content (#77501)

* Problem: `agent:bootstrap` hooks can inject `BOOTSTRAP.md` content, but embedded-runner bootstrap routing decided whether bootstrap was pending before hook-adjusted files were considered.
* Fix: preload hook-adjusted bootstrap files before routing, treat non-empty hook-provided `BOOTSTRAP.md` as pending and accessible bootstrap content, and reuse the preloaded files when building Project Context.
* Tests: added routing + context-engine regression coverage for hook-injected bootstrap content.

Co-authored-by: ificator <[email protected]>
Co-authored-by: galiniliev <[email protected]>

* fix(update): stage npm-prefix package updates cleanly

Co-authored-by: Josh Lehman <[email protected]>

* fix(update): keep plugin install runtime aliases stable

* test(package): cover stale source plugin shadows

Co-authored-by: Vincent Koc <[email protected]>

* fix(plugins): fall back from invalid beta npm updates

* fix(active-memory): stabilize timeout partial recovery

* fix(browser): guard existing-session screenshots

* test(plugins): harden kitchen sink live gauntlet

* fix(gateway): clear reply run before followup drain

* fix(openrouter): keep DeepSeek V4 reasoning effort valid (#77423)

Summary:
- The PR removes `max` from OpenRouter DeepSeek V4 thinking profiles, maps stale OpenRouter `max` overrides to `xhigh`, preserves direct DeepSeek behavior, and updates docs, tests, and changelog.
- Reproducibility: yes. Source inspection on current main shows OpenRouter DeepSeek V4 advertises `max` and se ... ffort: "max"`, matching the linked 400 logs; I did not need a live OpenRouter request for this assist pass.

Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Addressed earlier ClawSweeper review findings before merge.
- Included post-review commit in the final squash: docs(changelog): credit OpenRouter duplicate fix
- Included post-review commit in the final squash: fix(openrouter): keep DeepSeek V4 reasoning effort valid

Validation:
- ClawSweeper review passed for head becdea4223be0cbb6806d92d11ca4307d19bfc3f.
- Required merge gates passed before the squash merge.

Prepared head SHA: becdea4223be0cbb6806d92d11ca4307d19bfc3f
Review: https://github.com/openclaw/openclaw/pull/77423#issuecomment-4372880583

Co-authored-by: sallyom <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>

* fix(update): exit post-core resume without result path

* fix(update): isolate plugin sync failures

Disable and skip plugins that fail package-update plugin sync so broken plugin packages do not fail an otherwise successful OpenClaw update.

* test(plugins): source Testbox auth for kitchen sink live

* fix(agents): avoid duplicate generated media attachments

* fix(cli): bound sessions list output

* fix(update): use absolute npm script shell

* refactor: centralize reply followup drain lifecycle

* test(browser): mirror route URL guard in existing-session helper

* docs(changelog): note npm script shell update fix

* fix(openai): default direct responses to sse

* fix(plugins): treat CalVer correction versions as compatible with plugin API ranges (#77450)

* fix(plugins): accept CalVer correction plugin API hosts

Fixes #77293

* docs(changelog): credit plugin api calver fix pr

---------

Co-authored-by: pingu <[email protected]>

* fix(active-memory): skip sub-agent gracefully when no memory tools registered (#77506) (#77515)

* fix(active-memory): skip sub-agent gracefully when no memory tools registered (#77506)

When memory-core and memory-lancedb are both absent, the embedded
memory sub-agent would throw 'No callable tools remain after resolving
explicit tool allowlist', which propagated as a noisy warning through
the before_prompt_build hook. Catch this specific error in
runActiveMemorySubAgent and return an empty NONE result so the
gateway log stays clean and the sub-agent run is skipped without
disrupting the parent session.

* fix(active-memory): skip missing memory-tool subagent runs

* fix(active-memory): match inherited missing memory tool errors

* fix(active-memory): preserve policy-filtered memory errors

---------

Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(telegram): honor topic requireMention precedence

Telegram forum-topic requireMention config now takes precedence over persisted activation state, with focused regression coverage.\n\nFixes #49864.\nThanks @Panniantong.

* fix(secretrefs): resolve external channel contracts in dist/ sidecars (#77421)

* fix(secretrefs): resolve external channel contracts in dist/ sidecars

Externalized channel plugins published to npm (e.g. @openclaw/discord
since 2026.5.2) keep their compiled secret-contract-api artifact under
<rootDir>/dist/, per the package.json `openclaw.runtimeExtensions`
convention. The runtime contract loader added in #76449 only searched
the rootDir, so npm-installed plugins silently dropped their channel
SecretRef contracts: the runtime snapshot left `channels.<id>.token`
as an unresolved SecretRef, the plugin's `isConfigured` check then
returned false, and the gateway recorded `error: not configured`
without firing the usual channel startup logs.

Look in `<rootDir>/dist/` as well as `<rootDir>/`, preferring dist
when running from a built openclaw artifact and rootDir when running
from source. The new `loads dist/ secret-contract-api sidecars …`
test in channel-contract-api.external.test.ts mirrors the real
npm-package layout and fails without this change.

Refs #76371. Fixes #77416.

* docs: credit changelog contributor

---------

Co-authored-by: Magpie <magpie@local>
Co-authored-by: joshavant <[email protected]>

* chore: update dependencies

* fix(docker): prune external plugin dist (#77547)

* fix: harden startup readiness and discord replies

(cherry picked from commit 3956672106b3387d42427a485a9ca01e77f3b78f)

* fix(discord): preserve non-text payloads in reply scrub

* fix: clean up startup readiness PR docs

* fix: preserve visible Discord labeled replies

* fix(agents): preserve workspace metadata reuse

Pass the resolved agent workspace through hot model refresh paths so workspace-scoped plugin metadata snapshots can be reused.

Refs #77519.
Refs #77532.

* test: make global install shell test portable

* fix(config): prefer plugin ids for built-in channel claims

Prefer the manifest plugin id when auto-allowlisting configured built-in channel aliases, with regression coverage for alias/id split plugins and same-name official channel plugins.

* fix(model): guide runtime allowlist repairs

* fix(telegram): clarify model picker runtime scope

* docs(changelog): note model runtime switch repair UX

* fix(docker): normalize plugin build args

* fix(doctor): preserve active auth profile metadata

* fix(codex/app-server): stable mirror idempotency to prevent transcript loss (#77046)

* fix(codex/app-server): stable mirror idempotency to prevent transcript loss

* Changelog: note codex/app-server transcript mirror dedupe stabilization (#77046)

* fix(plugins): emit actionable install hint for externalized channel plugins (#77502)

Fixes #77483.\n\n- Suggest catalog-backed install commands for missing official external plugins in config validation.\n- Preserve stale/remove wording for non-catalog missing plugins.\n- Add regression coverage for plugins.entries and plugins.allow warnings.\n\nVerification:\n- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/config/validation.ts src/config/config.plugin-validation.test.ts\n- pnpm test src/config/config.plugin-validation.test.ts src/commands/doctor/shared/missing-configured-plugin-install.test.ts\n- pnpm crabbox:run -- --provider blacksmith-testbox ... pnpm check:changed\n- GitHub CI green on d1b1b1044403a2072fe10631a70fb13438990440

* Harden Codex harness control surfaces (#77459)

* fix(scripts): find codex protocol source from worktrees

* fix(test): keep codex harness docker caches writable

* fix(test): relax live codex cache mount permissions

* test(codex): add live docker harness debug output

* fix(test): detect numeric ci env in codex docker harness

* fix(codex): skip duplicate agent-command telemetry

* fix(tooling): skip sparse-missing oxlint tsconfig

* fix(tooling): route changed checks through testbox

* fix(qa): keep coverage json source-clean

* fix(test): preflight codex docker auth

* fix(codex): validate bind option values

* fix(codex): parse quoted command arguments

* fix(codex): reject extra control args

* fix(codex): use content for blank bound prompts

* fix(codex): decode local image file urls

* fix(codex): treat local media urls as images

* fix(codex): keep windows media paths local

* fix(codex): reject malformed diagnostics confirmations

* fix(codex): reject malformed resume commands

* fix(codex): reject malformed thread actions

* fix(codex): reject malformed turn controls

* fix(codex): reject malformed model controls

* fix(codex): resolve empty user input prompts

* fix(codex): enforce user input options

* fix(codex): reject ambiguous computer-use actions

* fix(codex): ignore stale bound turn notifications

* test(gateway): close task registries in gateway harness

* test(gateway): route cleanup through task seams

* fix(codex): describe current permission approvals

* fix(codex): disclose command approval amendments

* fix(codex): preserve approval detail under truncation

* fix(codex): propagate dynamic tool failures

* test(codex): align dynamic tool block contract

* fix(codex): reject extra read-only command operands

* fix(codex): escape command readout fields

* fix(codex): escape status probe errors

* fix(codex): narrow formatted thread details

* fix(codex): escape successful status summaries

* fix(codex): escape bound control replies

* fix(codex): escape user input prompts

* fix(codex): escape control failure replies

* fix(codex): escape approval prompt text

* test(codex): narrow escaped reply assertions

* test(codex): complete strict reply fixtures

* test(codex): preserve account fixture literals

* test(codex): align status probe fixtures

* fix(codex): satisfy sanitizer regex lint

* fix(codex): harden command readouts

* fix(codex): harden bound image inputs

* fix(codex): sanitize command failure replies

* test(codex): complete rate limit fixture

* test(tooling): isolate postinstall compile cache fixture

* fix(codex): keep app-server event ownership explicit

---------

Co-authored-by: pashpashpash <[email protected]>

* ci(release): split release soak validation

* feat: add gateway stall diagnostics

* fix: enable sync io tracing in gateway watch

* fix: preserve gateway watch trace overrides

* docs: add gateway diagnostics changelog

* fix: clarify slack socket retry errors

* fix: clean up orphaned child processes (#77481)

* fix: forward launcher respawn signals

* docs: explain respawn signal exit timer

* fix: centralize launcher respawn supervision

* fix: include respawn helper in duplicate scan

* fix: keep launcher respawn bridge local

* fix(channels): preserve channel aliases in plugin probes

Key package-state probes, env/config presence, and read-only command defaults by channel id instead of manifest plugin id so alias-owned channel plugins keep setup/native-command detection working.

* fix(gateway): quiet benchmark watch output

* fix(mattermost): clarify model picker runtime behavior

* fix: repair release validation checks

* fix(lint): cover diagnostic phase events

* fix(gateway): route watch trace spam to artifacts

* test(doctor): mock bundled channel ids

* fix(config): register bundledMode in zod schema and help text

Addresses review feedback: adds bundledMode to the strict plugins zod
object so the config option passes validation, and adds schema.help
documentation for the field.

* fix(plugins): add bundledMode to gate runtime provider discovery by allowlist

When plugins.bundledMode is set to "respect-allow", runtime provider
discovery paths honor plugins.allow for bundled plugins instead of
force-loading all providers. Default "compat" preserves existing behavior.

Closes #75575

* fix(plugins): respect allowlist for web provider fallback

* test(plugins): type bundled public artifact mock

* fix(plugins): rename bundled allowlist discovery policy

* docs(config): refresh bundled discovery baseline

* fix(plugins): default bundled discovery to allowlist

* test(doctor): preserve bundled discovery literal type

* test(plugins): make loader compat contract explicit

* fix(plugins): preserve bundled allowlist edges

* fix(plugins): normalize compat allowlist aliases

* fix(discord): prefer IPv4 for gateway startup

* fix: log gateway model mode defaults

* fix(docker): pin container-side workspace and config dirs in compose

Fixes #77436

* fix: simplify gateway model startup modes

* test(extensions): refresh dependency-backed assertions

* test(docker): align published upgrade timeout

* fix(plugins): recover managed-npm external plugins after package-manager upgrade

Co-authored-by: pingu <[email protected]>

* fix(doctor): repair allow-only official plugins

* fix(plugins): include json5 in memory runtime deps

* fix(plugins): include json5 in memory runtime deps

* chore(ci): allow bundled runtime json5 dep

* fix(openai-codex): avoid stale Responses replay state

* fix(openai-codex): match codex replay identity

* docs(changelog): credit codex replay fix

* fix(dashboard): guide manual token auth fallback

Summary:
- Add a redaction-safe dashboard fallback hint when tokenized URL delivery fails.
- Document the manual auth path and update the changelog.

Verification:
- PR CI exact head 48ccb97c0843c8b2e9640ac68adab6d311605705 green for relevant CI/security checks.
- pnpm test src/commands/dashboard.links.test.ts src/commands/dashboard.test.ts
- pnpm exec oxfmt --check --threads=1 src/commands/dashboard.ts src/commands/dashboard.links.test.ts
- pnpm format:docs:check
- pnpm docs:check-mdx
- pnpm docs:check-i18n-glossary
- targeted markdownlint for docs/cli/dashboard.md and docs/web/dashboard.md

* fix: sync Codex app-server protocol (#77578)

* fix: sync codex app-server protocol

* docs: add codex protocol changelog

* fix: refresh codex protocol schemas

* fix(telegram): derive media placeholders from MIME

Fixes #69793.

Verification:
- repro before fix: `pnpm test:serial extensions/telegram/src/bot-message-context.body.test.ts -- --reporter=verbose` failed 3 new cases with `<media:image>` returned for non-image/mixed saved media
- `pnpm test:serial extensions/telegram/src/bot-message-context.body.test.ts -- --reporter=verbose` passed 9 tests after fix
- `pnpm exec oxfmt --check --threads=1 extensions/telegram/src/bot-message-context.body.ts extensions/telegram/src/bot-message-context.body.test.ts`
- `git diff --check`
- `OPENCLAW_TESTBOX=1 pnpm testbox:run --id tbx_01kqtnnhpg6rk1225tbb7109kf -- "pnpm check:changed"` passed

* test(plugins): add kitchen sink rpc walk

* test: add slack onboarding channel smoke (#77575)

* fix: keep runtime prompt context out of system prompt (#77521)

* fix(plugins): keep explicit web providers on fast path

* test(agents): remove redundant payload casts

* Surface Codex usage-limit reset details in chat replies (#77557)

* fix(codex): surface usage limit reset details

* fix(codex): satisfy extension lint

* fix: surface codex runtime failures in tool-only replies

* fix(release): refresh plugin sdk api gate

Refresh release baseline hashes and raise the Plugin SDK API baseline heap cap so release preflight reports real drift instead of OOMing.

* fix(openai): route Codex audio to transcription model

* test(plugins): refresh kitchen sink docker fixture

* test(live): run cache probe with node

* fix(acpx): resolve plugin manifest from bundled runtime

* docs(changelog): credit @pashpashpash for Codex usage-limit reset surfacing

#77557 added user-facing surfacing of Codex app-server usage-limit reset
details and OpenClaw-owned runtime failure notices through tool-only
source-reply mode, but the entry landed without contributor attribution.
Add the merging PR ref and credit the human contributor @pashpashpash
per CLAUDE.md changelog-attribution rules.

* test(plugins): update kitchen sink prerelease canary version

* fix(discord): fail dropped final reply delivery

* docs: thank Discord reply fix contributor (#77596)

* Add instructions for how to setup slack for QA tests (#77606)

* docs(cli): document gateway restart --safe in command options

The `gateway restart` Command-options accordion only listed `--force`,
`--wait`, and `--json` even though `--safe` is a fully-supported flag
(documented in the prose at line 112 and rejected by lifecycle.ts when
combined with --force/--wait). Add --safe to the option list and a
Lifecycle-behavior bullet that explains the preflight-defer behavior
plus its mutual exclusion with --force and --wait, matching
src/cli/daemon-cli/lifecycle.ts:153-156.

* perf(plugins): reuse compatible metadata snapshots

Reuse compatible workspace-scoped plugin metadata snapshots for unscoped model catalog and manifest-contract readers while preserving env/config/workspace compatibility checks.

Also updates the stale kitchen-sink prerelease canary assertion to the current script default.

Fixes #77519.
Related #77532.

* fix(agents): mediate async media completions

* docs(help,security): cross-reference auth list and trusted-env-proxy

Two missing cross-references uncovered by the 24-hour doc audit:

- docs/help/faq-models.md: link to `openclaw models auth list` from the
  "What is an auth profile?" accordion. The command was added in
  23eb44b045 but the FAQ never pointed users at it.
- docs/security/network-proxy.md: list `tools.web.fetch.useTrustedEnvProxy`
  in Related Proxy Terms. The opt-in is fully documented in
  docs/tools/web-fetch.md but the proxy reference page omitted the
  cross-reference, leaving the page incomplete for proxy-state triage.

* test(live): retry cache probe text misses

* fix(secrets): preserve auth profile key refs during provider scrub (#77489)

* fix(secrets): preserve auth profile key refs during provider scrub

* Add changelog for secrets apply fix

* Seed auth profile ref for scrub regression

* fix(secrets): guard auth profile ref scrub

---------

Co-authored-by: Vincent Koc <[email protected]>

* fix: repair stale session route state in doctor

* test: use latest kitchen sink canary

* build: bump axios override

* docs: require live proof before landing

* fix(media): use r+ for Windows media fsync (#76593)

Fix Windows media offload failures by opening saved attachment temp files read/write before fsync, preserving the non-truncating temp-file write path while allowing Windows FlushFileBuffers to succeed.

Also adds the required changelog entry.

Tests:
- pnpm test src/media/store.test.ts src/gateway/chat-attachments.test.ts
- pnpm check:changed

Thanks @qq230849622-a11y.

Co-authored-by: 李claw <[email protected]>
Co-authored-by: Brad Groux <[email protected]>

* fix(lsp): resolve Windows .cmd shims (#75343)

Resolve Windows npm .cmd shim startup failures for bundled LSP servers by routing LSP process spawning through the shared Windows spawn resolver with a sanitized child environment.

The change reuses existing PATH/PATHEXT and .cmd shim handling, keeps non-Windows behavior unchanged, and adds focused regression coverage for resolver wiring, env sanitization, and spawn materialization.

Fixes #75352.

Tests:
- pnpm test src/agents/pi-bundle-lsp-runtime.windows-spawn.test.ts src/agents/pi-bundle-lsp-runtime.test.ts
- pnpm check:changed

Thanks @ElliotDrel.

Co-authored-by: Elliot Drel <[email protected]>
Co-authored-by: Brad Groux <[email protected]>

* test(plugins): align metadata snapshot policy fixtures

* test(live): scale gateway profile timeout

* test(live): use low reasoning for cache probes

* feat(agents): add post-compaction loop guard module + config

Pure module with unit tests; not yet wired into runner. The guard arms
after auto-compaction-retry and aborts when the same (tool, args, result)
triple repeats within the configured window.

Refs #77474

* fix(agents): address review feedback on post-compaction loop guard

- Add PostCompactionLoopPersistedError.fromVerdict factory.
- Add unit tests for the error class + fromVerdict adapter.
- Disabled guard is now truly dormant (no state mutation when enabled=false).
- Tighten help text for postCompactionGuard.enabled.

Refs #77474

* feat(agents): wire post-compaction loop guard into pi-embedded-runner

Arms the guard at each of the three compaction-success points in
run.ts and observes tool-call outcomes from the diagnostic session
state's toolCallHistory after each attempt. Aborts with
PostCompactionLoopPersistedError when the same (tool, args, result)
triple repeats windowSize times within the post-compaction window.

Refs #77474

* fix(agents): make post-compaction guard config valid + observation trim-resilient

Two correctness fixes from code review.

1. Zod schema (src/config/zod-schema.agent-runtime.ts) was strict and
   rejected tools.loopDetection.postCompactionGuard.* keys at validation
   time, making the guard's documented configurability inaccessible at
   gateway startup. Adds ToolLoopPostCompactionGuardSchema with both
   optional fields and wires it into ToolLoopDetectionSchema.

2. The runner observation cursor in pi-embedded-runner/run.ts used
   absolute indices into state.toolCallHistory, but that array is
   trimmed at historySize (default 30). Once the buffer was full, new
   records shifted out from under the cursor and the guard silently
   missed every loop in long-running sessions. Replaces the index
   cursor with a monotonic toolOutcomeSeq on SessionState that
   recordToolCallOutcome bumps on each observable push (unmatched
   branch only, mirroring the prior cursor's effective semantics).
   The runner now reads the most recent (currentSeq - lastSeq) entries
   from the tail of toolCallHistory, which is trim-resilient.

Adds zod parse tests for the new config keys (valid, empty, unknown
key, non-positive, non-integer) and a runner regression test that
seeds toolCallHistory at the trim cap before triggering a
post-compaction loop, asserting the abort still fires.

Refs #77474

* fix(agents): observe matched post-compaction tool outcomes

* test(agents): avoid redundant guard scope spread

* fix(agents): observe post-compaction guard live

* refactor(agents): thread post-compaction guard observer

* fix(agents): honor scoped post-compaction guard config

* chore(config): refresh post-compaction guard labels

* refactor(agents): use loop detection switch for post-compaction guard

* fix(agents): abort post-compaction loops out-of-band

* chore(config): refresh merged baseline hash

* docs(channels): inline Slack manifest into Quick Setup with Recommended/Minimal variants

The Quick Setup steps in docs/channels/slack.md previously sent users to
the `#manifest-and-scope-checklist` anchor lower on the page to copy the
manifest, breaking the copy-paste flow. Pull the manifest inline as a
Mintlify <CodeGroup> for both Socket Mode and HTTP Request URLs tabs and
add a Minimal variant for workspaces that restrict scopes (drops
files:*, reactions:*, pins:*, mpim:*, emoji:read, usergroups:read while
keeping DMs, channel/group history, mentions, App Home, and slash
commands). Recommended matches extensions/slack/src/setup-shared.ts.
Existing Manifest and scope checklist section stays as the canonical
per-scope reference.

Cross-link from docs/concepts/qa-e2e-automation.md so QA maintainers see
the production manifest reference, while keeping the QA Driver/SUT pair
of manifests inline (the lane intentionally needs two distinct apps so
its shape is different from a single-app production install).

* docs(doctor): clarify configured plugin repair (#77613)

* ci(release): speed up focused release reruns

* fix: honor embedded runtime tool allowlists (#77609)

* fix: honor embedded runtime tool allowlists

* fix: preserve plugin allowlist filtering

* fix: gate bundled lsp allowlists

* docs(channels): add Socket vs HTTP comparison and explain shared URL fields

The Slack docs jumped straight from intro into the Quick Setup tabs
without telling readers when to pick each transport. Add a Choosing
Socket Mode or HTTP Request URLs section above Quick Setup with a
concern-by-concern table (public URL, outbound network, tokens, dev
laptops, scaling, multi-account, slash command transport, signing,
recovery) plus a Note pointing at the right default for each shape.

Also add an Info block under the HTTP Quick Setup manifest explaining
why the manifest carries three url fields (slash_commands[].url,
event_subscriptions.request_url, interactivity.request_url) — Slack's
manifest schema requires them spelled out separately even though
OpenClaw routes by payload type, and slash commands silently no-op
without their url field in HTTP mode.

* fix(infra): skip POSIX tmp path on Windows (#73533)

Skip the POSIX `/tmp/openclaw` preferred path on Windows so temp files land under the trusted `os.tmpdir()`/`%TEMP%`-based `openclaw-<uid>` path instead of `C:\tmp\openclaw`.

Add regression coverage for Windows path selection and the WhatsApp media temp directory integration, plus a changelog entry.

Fixes #60713.

Tests:
- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/infra/tmp-openclaw-dir.ts src/infra/tmp-openclaw-dir.test.ts extensions/whatsapp/src/media.test.ts
- pnpm test src/infra/tmp-openclaw-dir.test.ts extensions/whatsapp/src/media.test.ts
- pnpm check:changed

Thanks @juan-flores077.

Co-authored-by: Juan Flores <[email protected]>
Co-authored-by: Brad Groux <[email protected]>

* chore(release): prepare 2026.5.4 beta 2

* fix(release): prune externalized plugin chunks

* fix(build): route externalized plugin chunks

* fix(build): route externalized plugin entry chunks

* fix: recover missing Codex bound threads

(cherry picked from commit a373468d825224c92051dc2e50b717fbe75c401c)

* fix(plugins): repair missing openclaw peer links on update

(cherry picked from commit 2e8761c5c1541496667201ba02716ab90eb24ee3)

* docs: note plugin peer-link update repair

(cherry picked from commit 712aa96a8fb3589bd39ab0c2e071395bc612ad1d)

* fix: start configured generation providers

(cherry picked from commit 0eb06caae3807679b23d2c20a5b464fa46fdc556)

* fix: slack mention-gating thread participation

(cherry picked from commit cf3ce08b910ee13f84ec04970f2d852dbbd36a32)

* fix: explain missing git during plugin install

(cherry picked from commit a91c17c426f9bf5c0e201f0da99064e088e251fa)

* fix(update): authenticate restart health probes

(cherry picked from commit b546aa91e19b3411ccdbc7c4189c2fdac9415869)

* fix(whatsapp): normalize onboarding allowlist numbers

Normalize WhatsApp onboarding allowlist entries to digit-only WhatsApp IDs and reject invalid owner-phone inputs during prompt validation.

(cherry picked from commit 68a500c465cc2a44561c46d8ee14a01e471097f7)

* fix(telegram): reuse preview for long text finals (#77658)

* fix(telegram): reuse preview for long text finals

* test(qa): cover long telegram finals

* fix(qa): satisfy extension lint

* fix(qa): keep telegram long final fixture to two chunks

* test(telegram): cover three chunk finals

* fix(telegram): force long final preview boundary

(cherry picked from commit e03fe1e28965c5edbf8735620757c2f5d28b29e7)

* fix(plugins): honor beta channel for auto installs

(cherry picked from commit b0f841ef37dbf3313487a3068a51c2751ddf4fb3)

* test: align beta plugin repair expectations

* fix(gateway): skip IPv6 loopback binding on Windows (#69701)

Bind the default loopback gateway listener only to `127.0.0.1` on Windows so libuv dual-stack `::1` behavior cannot wedge localhost HTTP requests.

Also keeps non-Windows dual-loopback behavior covered, replaces the redundant Windows passthrough test with guard coverage, and adds the required changelog entry.

Fixes #69674.

Tests:
- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/gateway/net.ts src/gateway/net.test.ts
- pnpm test src/gateway/net.test.ts
- pnpm check:changed
- GitHub required checks: green

Thanks @SARAMALI15792.

Co-authored-by: saram ali <[email protected]>
Co-authored-by: Brad Groux <[email protected]>
(cherry picked from commit 978bc53e80cccdc23d42324b18c4d20cd4749315)

* fix(agents): enforce exact skill path from <available_skills> [AI-assisted] (#74161)

Summary:
- The PR updates agents skill prompt guidance to require exact `<location>` paths for single- and multi-skill selection, adds prompt assertions, and records the fix in the changelog.
- Reproducibility: yes. Static source reproduction is enough: current main lacks the exact-`<location>` guard  ... illsSection()`, while the PR diff adds it to both selection branches and asserts the resulting prompt text.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: enforce exact skill paths for all skill matches

Validation:
- ClawSweeper review passed for head 743c9840c117312646ff6065ce4939f6555c5c0b.
- Required merge gates passed before the squash merge.

Prepared head SHA: 743c9840c117312646ff6065ce4939f6555c5c0b
Review: https://github.com/openclaw/openclaw/pull/74161#issuecomment-4341488109

Co-authored-by: tianguicheng <[email protected]>
Co-authored-by: sallyom <[email protected]>
(cherry picked from commit c739088d62b9e3589f6a5f9bb31cdc73688ca20f)

* fix(sandbox): support Windows drive-letter bind sources

Accept drive-absolute Windows sandbox Docker bind sources in config and runtime validation while keeping blocked-path and allowed-root comparisons case-insensitive for Windows drive paths.

Also remove a stale WhatsApp setup import that blocked extension lint after the rebase.

Co-authored-by: 6607changchun <[email protected]>
Co-authored-by: Brad Groux <[email protected]>
(cherry picked from commit d02fbc6116ed9cbd501ad6a1e4d08f3fc71c1dd8)

* chore(release): bump to 2026.5.4-beta.3

* chore(release): refresh plugin SDK API baseline

* fix(diagnostics): drop stale session recovery event cases

* ci: parallelize release publish workflows

* chore(release): bump to 2026.5.4

---------

Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Jesse Merhi <[email protected]>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Val Alexander <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dallin Romney <[email protected]>
Co-authored-by: Josh Lehman <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
Co-authored-by: Eva <[email protected]>
Co-authored-by: 100yenadmin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Co-authored-by: Kevin Lin <[email protected]>
Co-authored-by: hcl <[email protected]>
Co-authored-by: Pavan Kumar Gondhi <[email protected]>
Co-authored-by: zhang-guiping <[email protected]>
Co-authored-by: Michael Appel <[email protected]>
Co-authored-by: Devin Robison <[email protected]>
Co-authored-by: Mert Başar <[email protected]>
Co-authored-by: Mert Basar <[email protected]>
Co-authored-by: Satoshi F. <[email protected]>
Co-authored-by: galiniliev <[email protected]>
Co-authored-by: stain lu <[email protected]>
Co-authored-by: stainlu <[email protected]>
Co-authored-by: Devin Robison <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: VACInc <[email protected]>
Co-authored-by: Syu <[email protected]>
Co-authored-by: SYU8384 <[email protected]>
Co-authored-by: Agustin Rivera <[email protected]>
Co-authored-by: Brad <[email protected]>
Co-authored-by: ificator <[email protected]>
Co-authored-by: galiniliev <[email protected]>
Co-authored-by: Sally O'Malley <[email protected]>
Co-authored-by: Penchan <[email protected]>
Co-authored-by: pingu <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Pnant <[email protected]>
Co-authored-by: Mogglemoss <[email protected]>
Co-authored-by: Magpie <magpie@local>
Co-authored-by: joshavant <[email protected]>
Co-authored-by: Satoshi <[email protected]>
Co-authored-by: Brandon <[email protected]>
Co-authored-by: Chunyue Wang <[email protected]>
Co-authored-by: pashpashpash <[email protected]>
Co-authored-by: dougbtv <[email protected]>
Co-authored-by: Shubhankar Tripathy <[email protected]>
Co-authored-by: mkdev11 <[email protected]>
Co-authored-by: praveen9354 <[email protected]>
Co-authored-by: Patrick Erichsen <[email protected]>
Co-authored-by: Sarah Fortune <[email protected]>
Co-authored-by: 李claw <[email protected]>
Co-authored-by: 李claw <[email protected]>
Co-authored-by: Brad Groux <[email protected]>
Co-authored-by: Elliot Drel <[email protected]>
Co-authored-by: Eduardo Piva <[email protected]>
Co-authored-by: Juan Flores <[email protected]>
Co-authored-by: Kelaw - Keshav's Agent <[email protected]>
Co-authored-by: pickaxe <[email protected]>
Co-authored-by: Bek <[email protected]>
Co-authored-by: saram ali <[email protected]>
Co-authored-by: 兰之 <[email protected]>
Co-authored-by: tianguicheng <[email protected]>
Co-authored-by: 6607changchun <[email protected]>
lxe pushed a commit to lxe/openclaw that referenced this pull request May 6, 2026
* fix(browser): guard current tab exports

* fix(browser): expand tab guard coverage

* fix(browser): guard tab reads

* fix(browser): guard screenshot route

* changelog: PR openclaw#75731

---------

Co-authored-by: Devin Robison <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants