* fix(gateway): guard dangerous config alias
* fix(gateway): ignore reordered dangerous flags
* fix(gateway): use id-based mapping identity and honor legacy alias baseline
* fix(gateway): tighten dangerous config matching
* fix(gateway): strip IPv6 brackets in isRemoteGatewayTarget hostname check
* fix(gateway): detect tunneled remote targets
* fix(gateway): match id-less hook mappings by fingerprint, not index
* fix(gateway): detect env-selected remote targets
* fix(gateway): resolve remote-target guard from live config, not captured opts
* fix(gateway): resolve remote-target guard from live config, not captured opts
* fix(gateway): treat loopback OPENCLAW_GATEWAY_URL as local when mode is not remote
* fix(gateway): preserve legacy dangerous hook edits
* fix(gateway): block dangerous plugin reactivation
* fix(gateway): handle dotted plugin IDs in dangerous-flag checks
* fix(gateway): honor plugin policy activation
* fix(gateway): block remote plugin activation changes via allow/deny/enabled
* fix(gateway): broaden loopback url detection
* fix(gateway): resolve plugin IDs by longest-prefix match
* fix(gateway): block remote slot activation
* fix(gateway): preserve legacy mapping identity during id+field transitions
* fix(gateway): block remote load-path and channel activation changes
* test(gateway): fix remote config mock typing
* fix(gateway): guard auto-enabled dangerous plugins
* fix(gateway): address P1 review comments on remote gateway mutation guards
- Treat all OPENCLAW_GATEWAY_URL targets as remote for mutation guards to prevent SSH tunnel bypasses
- Always load config fresh in isRemoteGatewayTargetForAgentTools to detect session changes
- Expand remote activation guard to cover auto-enable paths (auth.profiles, models.providers, agents.defaults, agents.list, tools.web.fetch.provider)
- Respect plugins.deny in manifest-missing fallback to prevent false negatives
- Fix hook mapping identity matching to properly handle id-less mappings by fingerprint
- Update tests to reflect new secure behavior for env-sourced gateway URLs
* fix(gateway): prevent hook mapping swap attacks via fingerprint-only matching
When both current and next tokens have fingerprints, match ONLY by fingerprint.
This prevents replacing one dangerous hook mapping with a different one at the
same array index from being incorrectly treated as 'already present'.
The previous fallback to index-based matching allowed bypasses where an attacker
could swap dangerous mappings at the same index without triggering the guard.
* fix(gateway): honor allowlist in fallback guard
* fix(gateway): treat empty plugin allowlist as unrestricted in manifest-missing fallback
* docs: update USER.md worklog for empty-allowlist fix
* fix(gateway): resolve review comments — type safety, auto-enable resilience, remote hardening edits
* docs: update USER.md worklog for review comment resolution
* fix(gateway): block remaining remote setup auto-enable paths
* fix(gateway): simplify dangerous config mutation guard to set-diff approach
Replace 400+ lines of hook fingerprinting, remote gateway detection,
plugin activation tracking, and auto-enable enumeration with a simple
set-diff against collectEnabledInsecureOrDangerousFlags — the same
enumeration openclaw security audit already uses.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove USER.md audit log from PR
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* changelog: note gateway-tool dangerous config mutation guard (#62006)
---------
Co-authored-by: Devin Robison <drobison@nvidia.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(hooks): pass workspaceDir in gateway session reset internal hook context
The gateway path (performGatewaySessionReset) omitted workspaceDir when
creating the internal hook event, while the plugin hook path
(emitGatewayBeforeResetPluginHook) in the same file correctly resolved and
passed it. This caused the session-memory handler to fall back to
resolveAgentWorkspaceDir from the session key, which for default-agent
keys resolves to the shared default workspace instead of the per-agent
workspace. Daily notes and memory files were written to the wrong
workspace in multi-agent setups.
Closes#64528
* docs(changelog): add session-memory workspace reset note
* fix(changelog): remove conflict markers
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* openclaw-11f.1: retry reasoning-only OpenAI turns
Regeneration-Prompt: |
Patch the embedded runner so a signed reasoning-only assistant turn with no user-visible text is treated as recoverable instead of silently ending the run. Keep the change focused on the active OpenAI GPT-style path, retry the turn with an explicit visible-answer continuation instruction, and fall back to the existing incomplete-turn error handling only after retries are exhausted. Add regression coverage for the helper classification and for the outer run loop retry behavior, and keep unrelated provider behavior unchanged.
* openclaw-11f.1: address reasoning-only review feedback
Regeneration-Prompt: |
Follow up on PR review feedback for the reasoning-only retry patch. Keep the fix narrow: move the retry limit into a named constant alongside the other retry-policy values, document why the limit is 2, and prevent reasoning-only auto-retries after any side effects so the runner falls back to the existing caution path instead of risking duplicate actions. Add regression coverage for the side-effect guard and the named limit behavior.
* openclaw-11f.1: drop local pebbles artifacts
Regeneration-Prompt: |
Remove accidentally committed local pebbles tracker artifacts from the PR branch without changing runtime code. Keep the cleanup limited to deleting the tracked .pebbles files from version control, and rely on local git excludes for future pebbles activity so these files stay out of diffs.
* openclaw-11f.1: tighten reasoning-only retry guards
Regeneration-Prompt: |
Follow up on the remaining review feedback for the reasoning-only retry path. Keep the fix narrow: do not auto-retry a reasoning-only turn when the assistant already terminated with stopReason error, and evaluate the OpenAI-specific retry guard against the provider/model metadata of the assistant turn that actually produced the partial output rather than the outer run configuration. Add regression coverage for both behaviors in the incomplete-turn runner tests.
* openclaw-11f.1: retry empty GPT turns once
Regeneration-Prompt: |
Extend the embedded runner's GPT-style incomplete-turn recovery with a separate generic empty-response retry path. Keep it narrower than the existing reasoning-only recovery: one retry only, replay-safe only, no side effects, no assistant error turns, and scoped to the active assistant provider/model metadata. Add explicit warning logs when the empty-response retry triggers and when its single retry budget is exhausted, and add regression coverage for the success and exhaustion cases without changing broader provider fallback behavior.
* openclaw-11f.1: harden reasoning-only retry completion checks
Regeneration-Prompt: |
Follow up on the remaining review feedback for the GPT-style recovery path. Keep the change narrow: only retry reasoning-only turns when there is no visible assistant answer yet, and if the reasoning-only retry budget is exhausted without any visible answer, surface the existing incomplete-turn error instead of treating reasoning-only payloads as a successful completion. Add focused regression coverage for both scenarios and preserve the adjacent empty-response retry behavior.
* openclaw-11f.1: preserve profile cooldown on retry exhaustion
Regeneration-Prompt: |
Follow up on the final review comment for the GPT-style recovery path. Keep the change narrow: when the reasoning-only retry budget is exhausted and the run returns the incomplete-turn error early, preserve the same auth-profile cooldown behavior that the normal incomplete-turn branch already applies so multi-profile failover continues to work consistently. Verify the touched runner suites still pass.
* fix: recover GPT-style empty turns
Regeneration-Prompt: |
Add the required changelog entry for the PR that hardens embedded GPT-style recovery of reasoning-only and empty-response turns. Keep the changelog update under ## Unreleased > ### Fixes, append-only, and include the PR number plus author attribution on the same line.