Skip to content

fix(gateway): hot-reload browser profile config#93827

Merged
steipete merged 3 commits into
openclaw:mainfrom
goutamadwant:fix/43803-browser-profiles-hot-reload
Jul 6, 2026
Merged

fix(gateway): hot-reload browser profile config#93827
steipete merged 3 commits into
openclaw:mainfrom
goutamadwant:fix/43803-browser-profiles-hot-reload

Conversation

@goutamadwant

@goutamadwant goutamadwant commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

What problem does this PR solve?

  • Fixes browser profile config reload classification so browser.profiles.* changes can hot-reload instead of forcing a gateway restart.
  • Keeps broader browser config changes, such as browser.enabled and browser.defaultProfile, restart-scoped.

Why does this matter now?

What is the intended outcome?

  • Browser profile fields resolve as hot-reloadable config paths.
  • Broader browser settings still require restart where appropriate.
  • Config reload rules prefer the most specific matching prefix, so narrow hot rules can override broad restart rules.

What is intentionally out of scope?

  • No changes to browser runtime connection behavior beyond reload classification.
  • No changes to auth, pairing, plugin loading, or browser profile schema fields.

What does success look like?

  • browser.profiles.sandbox.cdpUrl resolves to hot.
  • browser.enabled and browser.defaultProfile continue resolving to restart.
  • Focused gateway/browser tests and the full build pass.

What should reviewers focus on?

  • Whether longest-prefix reload rule matching is the right project-native behavior.
  • Whether browser.profiles is the correct narrow hot-reload boundary.
  • Whether the regression coverage protects both direct reload planning and authenticated config.patch behavior.

Linked context

Which issue does this close?

Closes #43803

Which issues, PRs, or discussions are related?

Related #64204

Was this requested by a maintainer or owner?

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: browser profile config paths were classified under the broad browser restart rule, so profile-only changes could schedule a gateway restart instead of hot reload.
  • Real environment tested: local OpenClaw checkout using Node v24, built gateway artifacts, temporary config/state directories, loopback gateway, browser plugin enabled, and gateway.reload.mode: "hot".
  • Exact steps or command run after this patch:
    • Built the project with node scripts/build-all.mjs.
    • Started the built gateway with a temporary config containing browser.profiles.sandbox.
    • Queried live schema metadata through the gateway for browser.profiles.sandbox.cdpUrl and browser.enabled.
    • Queried gateway health after startup.
  • Evidence after fix: copied live output from the running gateway: config.schema.lookup browser.profiles.sandbox.cdpUrl -> {"path":"browser.profiles.sandbox.cdpUrl","reloadKind":"hot"}; config.schema.lookup browser.enabled -> {"path":"browser.enabled","reloadKind":"restart"}; health -> {"ok":true,"loadedPlugins":["browser"]}.
  • Observed result after fix: the live gateway exposes browser profile connection fields as hot-reloadable while preserving restart classification for broader browser settings.
  • What was not tested: a live write-scoped config.patch through a fully paired external client was not completed.
  • Proof limitations or environment constraints: the local CLI client could read schema/health successfully, but write-scoped config.patch was blocked by the gateway pairing/scope-upgrade flow. The patch path is covered by the authenticated server-method regression test.
  • Before evidence: browser.profiles.sandbox.cdpUrl reproduced as restart-scoped in the focused reload-plan regression before this patch. The authenticated config.patch regression also reproduced a scheduled gateway restart for the same profile-only path before this patch.

Tests and validation

Which commands did you run?

  • node scripts/test-projects.mjs src/gateway/config-reload.test.ts -- --testNamePattern "browser profile" --reporter=verbose
  • node scripts/test-projects.mjs src/gateway/server-methods/config.shared-auth.test.ts -- --testNamePattern "browser profile" --reporter=verbose
  • node scripts/test-projects.mjs extensions/browser/index.test.ts -- --testNamePattern "static browser metadata" --reporter=verbose
  • node scripts/test-projects.mjs src/gateway/config-reload.test.ts extensions/browser/index.test.ts src/gateway/server-methods/config.shared-auth.test.ts
  • node_modules/.bin/oxfmt --check src/gateway/config-reload-plan.ts src/gateway/config-reload.test.ts src/gateway/server-methods/config.shared-auth.test.ts extensions/browser/plugin-registration.ts extensions/browser/index.test.ts
  • node_modules/.bin/oxlint src/gateway/config-reload-plan.ts src/gateway/config-reload.test.ts src/gateway/server-methods/config.shared-auth.test.ts extensions/browser/plugin-registration.ts extensions/browser/index.test.ts
  • git diff --check
  • node scripts/build-all.mjs

What regression coverage was added or updated?

  • Added coverage that browser.profiles.sandbox.cdpUrl plans as hot reload even when a broader browser restart rule exists.
  • Updated browser plugin metadata coverage to assert hotPrefixes: ["browser.profiles"].
  • Added authenticated config.patch coverage proving a browser profile-only change does not schedule a gateway SIGUSR1 restart in hot mode.

What failed before this fix, if known?

  • The focused reload-plan test failed because browser.profiles.sandbox.cdpUrl still produced restartGateway: true.
  • The authenticated server-method regression failed because scheduleGatewaySigusr1Restart was called for a browser profile-only patch.

If no test was added, why not?

  • Tests were added and updated.

Risk checklist

Did user-visible behavior change? (Yes/No)

Yes

Did config, environment, or migration behavior change? (Yes/No)

Yes

Did security, auth, secrets, network, or tool execution behavior change? (Yes/No)

No

What is the highest-risk area?

  • Reload classification precedence now uses the longest matching prefix instead of the first matching rule.

How is that risk mitigated?

  • The behavior is covered by focused reload-plan tests, browser metadata tests, and authenticated config patch tests.
  • Existing broader browser config paths are explicitly checked to remain restart-scoped.

Current review state

What is the next action?

  • Ready for maintainer review after the refreshed CI run completes.

What is still waiting on author, maintainer, CI, or external proof?

  • Waiting on refreshed CI and maintainer review.
  • External write-scoped runtime proof through a paired client was not completed locally; the server-method regression covers the same restart scheduling behavior.

Which bot or reviewer comments were addressed?

  • Addressed Barnacle's real-behavior-proof parsing requirement by making the after-fix evidence explicit as copied live output from the running gateway.

@goutamadwant
goutamadwant requested a review from a team as a code owner June 17, 2026 00:48
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 17, 2026
@goutamadwant
goutamadwant force-pushed the fix/43803-browser-profiles-hot-reload branch from f432504 to a0e0f44 Compare June 17, 2026 01:16
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 17, 2026
@clawsweeper

clawsweeper Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed July 6, 2026, 11:32 AM ET / 15:32 UTC.

Summary
This PR adds a browser profile hot-reload prefix, makes reload-rule matching prefer the most specific prefix, pins gateway reload policy to the gateway plugin registry, and adds focused gateway/browser regression tests.

PR surface: Source +8, Tests +80. Total +88 across 5 files.

Reproducibility: yes. Current main maps browser.profiles.* through the broad browser restart prefix, and the config write path schedules SIGUSR1 when hot mode still sees a restart-required plan.

Review metrics: 1 noteworthy metric.

  • Reload policy changes: 1 hot prefix added, 1 precedence rule changed. This changes config reload classification, so maintainers should review upgrade expectations beyond ordinary test pass/fail.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #43803
Summary: This PR is the active candidate fix for the canonical browser profile config.patch restart issue; older reports cover the same or broader restart behavior.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

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

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

Rank-up moves:

  • Update the Gateway reload documentation for the new browser.profiles.* hot-reload boundary.

Risk before merge

  • [P1] Public docs still say browser config changes require a Gateway restart, so users may not discover the new hot-reload profile boundary unless the docs are updated before merge.
  • [P1] Reload-rule precedence is compatibility-sensitive: longest-prefix matching intentionally changes outcomes for overlapping plugin reload prefixes, and maintainers should accept that rule with the existing browser, WhatsApp, and pinned-registry coverage.

Maintainer options:

  1. Document the new reload boundary (recommended)
    Update the Gateway reload docs so browser profile edits are documented as hot-reloadable while broader browser settings stay restart-scoped.
  2. Accept code-only behavior change
    Maintainers may choose to land with the current code and tests, but the public docs will temporarily describe the old restart behavior.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Update the Gateway configuration reload docs for this PR so the reload table or note reflects that `browser.profiles.*` hot-reloads while `browser.enabled` and `browser.defaultProfile` remain restart-scoped; do not edit `CHANGELOG.md`.

Next step before merge

  • [P2] A narrow docs repair can address the remaining P3 finding without changing the reviewed runtime behavior.

Security
Cleared: No concrete security or supply-chain regression was found; the diff changes reload classification and tests without adding dependencies, secrets handling, CI execution, or new code-download paths.

Review findings

  • [P3] Update reload docs for browser profiles — extensions/browser/plugin-registration.ts:146
Review details

Best possible solution:

Merge the reload-policy fix with docs that distinguish browser.profiles.* hot reload from restart-scoped browser settings such as browser.enabled and browser.defaultProfile.

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

Yes. Current main maps browser.profiles.* through the broad browser restart prefix, and the config write path schedules SIGUSR1 when hot mode still sees a restart-required plan.

Is this the best way to solve the issue?

Yes, with a docs follow-up. The PR fixes the owner boundary by adding plugin reload metadata plus specific-prefix matching, while preserving restart behavior for broader browser settings.

Full review comments:

  • [P3] Update reload docs for browser profiles — extensions/browser/plugin-registration.ts:146
    This adds browser.profiles as hot-reloadable, but docs/gateway/configuration.md still lists all browser config under Infrastructure as requiring a Gateway restart. Users following the public reload table will see the old behavior, so update the docs to call out that browser.profiles.* hot-reloads while broader browser settings remain restart-scoped.
    Confidence: 0.9

Overall correctness: patch is correct
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 9606fe43231b.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: The PR changes config reload precedence and browser profile restart behavior, which can affect existing upgrade/runtime expectations even though the change is intended.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied live gateway output showing browser.profiles.sandbox.cdpUrl resolves as hot while browser.enabled remains restart-scoped, plus focused regression tests for the write path.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied live gateway output showing browser.profiles.sandbox.cdpUrl resolves as hot while browser.enabled remains restart-scoped, plus focused regression tests for the write path.

Label justifications:

  • P2: This is a normal-priority gateway/browser bug fix for unnecessary restarts that can disrupt sessions, with a focused code path and linked source-repro issue.
  • merge-risk: 🚨 compatibility: The PR changes config reload precedence and browser profile restart behavior, which can affect existing upgrade/runtime expectations even though the change is intended.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied live gateway output showing browser.profiles.sandbox.cdpUrl resolves as hot while browser.enabled remains restart-scoped, plus focused regression tests for the write path.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied live gateway output showing browser.profiles.sandbox.cdpUrl resolves as hot while browser.enabled remains restart-scoped, plus focused regression tests for the write path.
Evidence reviewed

PR surface:

Source +8, Tests +80. Total +88 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 2 17 9 +8
Tests 3 82 2 +80
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 99 11 +88

Acceptance criteria:

  • [P1] pnpm docs:list.
  • [P1] git diff --check.

What I checked:

  • Current main still treats all browser config as restart-scoped: Current main exports the Browser plugin reload metadata as only restartPrefixes: ["browser"], so browser.profiles.* has no hot reload override before this PR. (extensions/browser/plugin-registration.ts:144, 9606fe43231b)
  • Current main uses first matching reload rule: The current reload planner converts plugin restart and hot prefixes to rules, then matchRule() returns the first prefix match; without a more specific browser profile rule, profile paths fall under the broad browser restart rule. (src/gateway/config-reload-plan.ts:202, 9606fe43231b)
  • Config patch restart scheduling is reload-plan driven: resolveConfigRestartRequirement() calls buildGatewayReloadPlan() and schedules a direct restart in hot mode when the plan still requires a gateway restart, which explains the linked issue's SIGUSR1 behavior on current main. (src/gateway/server-methods/config-write-flow.ts:150, 9606fe43231b)
  • PR adds the intended hot browser profile boundary: At the reviewed head, Browser reload metadata keeps the broad browser restart prefix but adds hotPrefixes: ["browser.profiles"]. (extensions/browser/plugin-registration.ts:144, 33e261fb2eeb)
  • PR makes narrower reload rules win: The reviewed head sorts reload rules by descending prefix length before first-match lookup, so browser.profiles can override the broad browser restart rule. (src/gateway/config-reload-plan.ts:234, 33e261fb2eeb)
  • PR covers direct planner and config.patch behavior: The reviewed head adds tests that browser.profiles.sandbox.cdpUrl plans as hot, broader browser settings remain restart-scoped, and hot-mode config.patch for a browser profile does not schedule SIGUSR1. (src/gateway/server-methods/config.shared-auth.test.ts:401, 33e261fb2eeb)

Likely related people:

  • steipete: Peter Steinberger's merged history moved browser runtime seams behind plugin metadata and split/pinned gateway plugin registry surfaces; he also authored the latest two commits on this PR branch. (role: feature owner and recent PR branch contributor; confidence: high; commits: 471d056e2f0d, 46d3617d25e4, a69f6190ab56; files: extensions/browser/plugin-registration.ts, src/gateway/config-reload-plan.ts, src/plugins/runtime.ts)
  • vincentkoc: Git history shows Vincent Koc on recent release/main snapshots touching the affected browser/gateway files, and the PR author explicitly requested review from this handle. (role: recent area contributor and requested reviewer; confidence: medium; commits: e085fa1a3ffd; files: extensions/browser/plugin-registration.ts, src/gateway/config-reload-plan.ts, src/gateway/server-methods/config-write-flow.ts)
  • Momo: Current-main blame for the affected files points at a grafted July 6 commit that reintroduced these files in the local history, but the broader provenance is less specific than the targeted feature commits. (role: recent area contributor; confidence: low; commits: 17605c57df26; files: extensions/browser/plugin-registration.ts, src/gateway/config-reload-plan.ts, src/gateway/server-methods/config-write-flow.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed June 21, 2026, 9:18 PM ET / 01:18 UTC sha a0e0f44 :: needs changes before merge. :: [P3] Update browser docs for profile hot reload

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jun 17, 2026
@goutamadwant

Copy link
Copy Markdown
Contributor Author

@vincentkoc can you review when you get a chance? thanks!

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 22, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 6, 2026
@steipete
steipete force-pushed the fix/43803-browser-profiles-hot-reload branch from a0e0f44 to c4a504e Compare July 6, 2026 14:51
@openclaw-barnacle openclaw-barnacle Bot removed the agents Agent runtime and tooling label Jul 6, 2026
@clawsweeper clawsweeper Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jul 6, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 6, 2026
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Land-ready proof for 33e261fb2eebfc2aac0cd050377dc1955a4d9247:

  • I kept the contributor's profile-only hot-reload direction, then made the reload rule ordering explicit so the narrower browser.profiles rule wins over the broad browser restart rule.
  • Live verification exposed one additional trust-boundary bug: an agent turn activates an agent-scoped plugin registry, so reading the generic active registry made Gateway reload policy disappear after the first turn. Reload policy now reads the Gateway-pinned registry. Agent-scoped registry isolation remains intact; it can no longer silently replace Gateway restart policy.
  • Sanitized AWS Crabbox focused run run_ebb11446c36b passed 393 assertions: 370 Gateway reload/config tests plus 23 Browser plugin registration tests, including the scoped-registry regression.
  • Source-blind live run run_eacf4be11888 on public, role-free AWS lease cbx_ffe26dc8618d passed with a real Dev Gateway, two concurrent Chromium CDP endpoints, and real OpenAI agent turns. Schema reported profile cdpUrl hot and broad Browser settings restart-scoped. Agent A saw endpoint A; authenticated config.patch moved only the profile to B with requiresRestart=false; agent B then saw B and not A. Gateway PID stayed 6252, both CDPs remained alive, and both persisted transcripts contained Browser tool calls over Gateway transport.
  • Fresh branch autoreview: clean, no accepted/actionable findings.
  • Exact-head hosted CI run 28802653503: successful, including lint, production/test types, plugin contracts, Gateway-related test shards, security scans, and the real-behavior-proof check. PR is mergeable/clean.

Known proof gaps: none.

@steipete
steipete merged commit b82e3c1 into openclaw:main Jul 6, 2026
132 of 143 checks passed
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
* fix(gateway): hot-reload browser profile config

* refactor(gateway): cache reload rule specificity

* fix(gateway): pin reload policy to gateway registry

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix(gateway): hot-reload browser profile config

* refactor(gateway): cache reload rule specificity

* fix(gateway): pin reload policy to gateway registry

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S stale Marked as stale due to inactivity status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] config.patch still sends SIGUSR1 for hot-reloadable paths (browser.profiles.*), bypassing reload mode

2 participants