Skip to content

fix: reload pending approvals after control ui reconnect#98524

Closed
haruaiclone-droid wants to merge 1 commit into
openclaw:mainfrom
haruaiclone-droid:codex/fix-control-ui-reconnect-pending-approvals
Closed

fix: reload pending approvals after control ui reconnect#98524
haruaiclone-droid wants to merge 1 commit into
openclaw:mainfrom
haruaiclone-droid:codex/fix-control-ui-reconnect-pending-approvals

Conversation

@haruaiclone-droid

Copy link
Copy Markdown
Contributor

Fixes #98523

Summary

  • refresh pending exec/plugin approval lists after a successful Control UI hello/reconnect
  • keep existing pending abort processing ahead of the refresh so reconnect abort behavior is unchanged
  • cover reconnect hydration with both exec and plugin pending approvals

Tests

  • node scripts/run-with-env.mjs OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=300000 -- node scripts/run-vitest.mjs run --config test/vitest/vitest.ui.config.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-gateway-chat-load.node.test.ts ui/src/ui/app-gateway.sessions.node.test.ts --testTimeout=30000 --reporter=dot
  • git diff --check

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: S triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 1, 2026
@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 1, 2026, 6:04 AM ET / 10:04 UTC.

Summary
The PR imports and calls refreshPendingApprovalQueue from connectGateway after hello and adds UI gateway tests/mocks covering exec and plugin approval hydration on reconnect.

PR surface: Source +2, Tests +49. Total +51 across 4 files.

Reproducibility: yes. source-reproducible but not live-run: current main's hello path applies the snapshot and handles approval events, while the approval-list RPC handlers exist separately and are not called during reconnect.

Review metrics: 1 noteworthy metric.

  • Reconnect RPC fanout: 2 approval-list RPCs after every successful hello. This adds asynchronous state hydration to a reconnect hot path, so active-client gating matters before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #98523
Summary: This PR is the linked candidate fix for the open Control UI reconnect approval hydration issue.

Members:

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

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof is added.

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

Rank-up moves:

  • Guard reconnect approval refresh results so they cannot mutate host state after host.client changes.
  • [P1] Add redacted real behavior proof for the after-fix Control UI reconnect path, such as a recording or terminal/browser output that shows pending exec and plugin approvals reappear.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR only lists tests and git diff --check; it needs redacted after-fix proof such as a short Control UI reconnect recording, terminal/browser output, or logs showing pending exec/plugin approvals reappear, and updating the PR body should trigger a fresh ClawSweeper review or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Proof path suggestion
A short visible Control UI proof would materially help show the reconnect path restores pending approval prompts in a real UI flow. Mantis is currently scoped to Telegram, Discord, and web UI chat proof, so it is not the right proof path for this surface.
Use maintainer screenshot/manual proof, browser or Playwright proof, Crabbox where appropriate, or normal local artifact proof instead.

Risk before merge

  • [P1] The new reconnect refresh can apply an approval list from a client that is no longer current if another reconnect or gateway/settings change happens before the list RPCs settle.
  • [P1] The external PR has only test-command evidence, so maintainers do not yet have after-fix proof that the real Control UI reconnect flow shows the pending approval prompts.

Maintainer options:

  1. Guard reconnect approval hydration (recommended)
    Before merge, make the reconnect-triggered refresh discard results when host.client changes, and cover that stale-client race in the UI gateway tests.
  2. Accept transient stale approval state
    Maintainers could intentionally accept the race if they decide stale approval cards across rapid reconnects are tolerable, but that should be explicit because approvals are user-visible state.
  3. Pause for contributor proof
    Because this is an external PR without real behavior proof, maintainers can keep it draft or paused until the contributor demonstrates the after-fix reconnect path.

Next step before merge

  • [P1] Needs contributor and reviewer follow-up because the patch has a stale-client state bug and no after-fix real behavior proof; automation cannot supply the contributor's real setup proof.

Security
Cleared: The diff only changes Control UI TypeScript and tests, with no dependency, workflow, credential, package, or supply-chain surface changes; the stale approval queue concern is handled as a functional state finding.

Review findings

  • [P2] Guard approval refreshes against stale reconnect clients — ui/src/ui/app-gateway.ts:849
Review details

Best possible solution:

Keep the existing approval refresh helper as the owner, but invoke it from reconnect with an active-client guard and add redacted real behavior proof for the Control UI reconnect flow.

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

Yes, source-reproducible but not live-run: current main's hello path applies the snapshot and handles approval events, while the approval-list RPC handlers exist separately and are not called during reconnect.

Is this the best way to solve the issue?

No as submitted. Calling the existing approval refresh helper on hello is the right boundary, but the PR needs an active-client guard before applying refreshed state.

Full review comments:

  • [P2] Guard approval refreshes against stale reconnect clients — ui/src/ui/app-gateway.ts:849
    The new fire-and-forget refresh captures the current state.client, awaits the approval-list RPCs, and then writes state.execApprovalQueue. If another reconnect or gateway URL change replaces host.client before those RPCs settle, the older client can overwrite the new connection's approval queue; the neighboring reconnect work guards this by checking host.client !== client before async mutations, so this refresh needs the same protection before applying results.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a normal-priority Control UI approval bug fix with limited blast radius, but it affects whether pending approvals reappear after reconnect.
  • merge-risk: 🚨 session-state: The patch can stale or mis-associate the Control UI approval queue if an older reconnect refresh finishes after a newer client becomes active.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR only lists tests and git diff --check; it needs redacted after-fix proof such as a short Control UI reconnect recording, terminal/browser output, or logs showing pending exec/plugin approvals reappear, and updating the PR body should trigger a fresh ClawSweeper review or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +2, Tests +49. Total +51 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 1 2 0 +2
Tests 3 49 0 +49
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 51 0 +51

What I checked:

  • Current reconnect path: On current main, connectGateway handles onHello, applies the hello snapshot, processes pending aborts, and continues into reconnect startup work without refreshing pending approval lists. (ui/src/ui/app-gateway.ts:807, aa91c9d4a950)
  • Approval refresh helper mutates after async RPCs: refreshPendingApprovalQueue captures state.client, awaits both approval-list RPCs, then assigns state.execApprovalQueue; it has no active-client check before applying the result. (ui/src/ui/controllers/exec-approval.ts:327, aa91c9d4a950)
  • Sibling reconnect work guards active client: Nearby reconnect startup work passes the expected client into loadAgentsThenRefreshActiveTabForClient and deferred startup work returns when host.client !== client, showing the local invariant this new async refresh should preserve. (ui/src/ui/app-gateway.ts:753, aa91c9d4a950)
  • Linked issue context: The linked issue reports that server-side exec.approval.list and plugin.approval.list still expose pending approvals after disconnect, but Control UI does not reload them after a fresh hello.
  • PR diff: The patch adds void refreshPendingApprovalQueue(host) directly inside the hello handler and adds a reconnect hydration test for both exec and plugin approvals. (ui/src/ui/app-gateway.ts:849, 4c74aa6301a5)
  • Proof gate: The PR body lists focused Vitest and git diff --check commands, but no screenshot, recording, terminal output, live log, or linked artifact demonstrating the after-fix Control UI reconnect behavior; the Real behavior proof check is failing. (4c74aa6301a5)

Likely related people:

  • RomneyDa: Recent merged work in https://github.com/openclaw/openclaw/pull/98146 introduced or carried forward the current Control UI reconnect handler and approval refresh helper touched by this PR. (role: recent area contributor; confidence: high; commits: 9003042c5fa0; files: ui/src/ui/app-gateway.ts, ui/src/ui/controllers/exec-approval.ts, ui/src/ui/app.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.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jul 1, 2026
@steipete-oai

Copy link
Copy Markdown
Contributor

Superseded by #102745 in deb7faf.

The old ui/src/ui/app-gateway.ts path has been replaced. Current main owns reconnect hydration in ui/src/app/overlays.ts, reloads both approval lists for each connected epoch, and guards results by client plus epoch, addressing the stale-client concern raised on this PR.

Thanks @haruaiclone-droid for identifying the missing reconnect hydration and contributing the initial fix. Closing as superseded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI reconnect does not reload pending approvals

2 participants