Skip to content

fix: keep queued approval prompts visible#98380

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

fix: keep queued approval prompts visible#98380
haruaiclone-droid wants to merge 1 commit into
openclaw:mainfrom
haruaiclone-droid:codex/fix-control-ui-queued-approvals

Conversation

@haruaiclone-droid

@haruaiclone-droid haruaiclone-droid commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Closes #98379

AI-assisted: Yes (Codex)

What Problem This Solves

Fixes an issue where users resolving one Control UI approval could lose the approval window when another exec/plugin approval was still queued. The remaining approval could stay pending but no longer be visible in the active modal flow.

Why This Change Was Made

The shared modal primitive now reopens its underlying <dialog> when the same custom element instance is reused after the dialog was closed, so queued approval content remains modal-visible after the active item changes. The approval action buttons are explicitly non-submit buttons, and the gateway hello path refreshes pending exec/plugin approval lists so reconnects recover missed approval events.

User Impact

Users can approve or deny a stack of pending Control UI approvals without the prompt disappearing after the first decision. Reconnects also repopulate pending plugin approvals from the authoritative gateway lists.

Evidence

Rebased on origin/main at 21d1e1f0f and revalidated:

  • corepack pnpm exec vitest run --config vitest.config.ts --project unit src/ui/components/modal-dialog.test.ts src/ui/app.exec-approval.test.ts src/ui/views/exec-approval.test.ts --reporter=verbose
  • corepack pnpm exec vitest run --config vitest.config.ts --project unit-node src/ui/app-gateway.node.test.ts --reporter=verbose
  • git diff --check
  • corepack pnpm ui:build
  • codex review --base origin/main was attempted but could not run in this environment because codex.exe returned Access is denied.

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 11:57 PM ET / 03:57 UTC.

Summary
The PR reopens the shared Control UI modal dialog on updates, makes exec approval action buttons non-submit buttons, refreshes pending exec/plugin approvals on gateway hello, and adds focused unit coverage.

PR surface: Source +7, Tests +103. Total +110 across 6 files.

Reproducibility: yes. source inspection gives a medium-confidence reproduction for the modal reuse subcase: current main can keep the same custom element mounted while its internal opened flag prevents reopening a closed underlying dialog. I did not run a browser repro for the full click path, so real behavior proof is still needed.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #98379
Summary: This PR is the candidate fix for the linked open Control UI queued-approval bug report.

Members:

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

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P1] Add redacted after-fix Control UI proof showing two queued approvals, resolving the active one, and the next modal staying visible.
  • Update the PR body with the proof; if a fresh review does not start automatically, ask a maintainer to comment @clawsweeper re-review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body lists unit tests and build commands only; it needs redacted real Control UI proof such as a screenshot, recording, live output, or logs showing the next queued approval remains visible after resolving the active one. 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.

Mantis proof suggestion
A visible Control UI modal regression is best confirmed with a short browser proof of the queued approval flow. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify the Control UI keeps the approval modal visible and shows the next queued exec/plugin approval after resolving the active one.

Risk before merge

  • [P1] The external PR has no after-fix real Control UI proof; tests and build commands do not show the browser-visible queued-modal flow.
  • [P1] The source/test evidence proves the modal-reopen subcase, but a real run should still demonstrate the full click path with two queued approvals.

Maintainer options:

  1. Decide the mitigation before merge
    Land a narrow Control UI fix that keeps the reused approval modal visible for queued approvals and uses the existing approval-list refresh path, after real browser proof is attached.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] The remaining blocker is contributor or maintainer real behavior proof and normal PR review, not a concrete automated code repair.

Security
Cleared: No concrete security or supply-chain concern was found; the diff changes Control UI modal/approval handling and tests, with no dependencies, workflows, secrets, or package metadata touched.

Review details

Best possible solution:

Land a narrow Control UI fix that keeps the reused approval modal visible for queued approvals and uses the existing approval-list refresh path, after real browser proof is attached.

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

Yes, source inspection gives a medium-confidence reproduction for the modal reuse subcase: current main can keep the same custom element mounted while its internal opened flag prevents reopening a closed underlying dialog. I did not run a browser repro for the full click path, so real behavior proof is still needed.

Is this the best way to solve the issue?

Yes, the proposed shape is the best observed boundary: the shared modal primitive owns reopening a reused dialog, and the gateway hello change reuses the existing approval queue refresh helper. The remaining gap is proof, not an alternate implementation path.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add status: 🛠️ actively grinding: The PR author has acted after the latest ClawSweeper review and work remains. Needs real behavior proof before merge: The PR body lists unit tests and build commands only; it needs redacted real Control UI proof such as a screenshot, recording, live output, or logs showing the next queued approval remains visible after resolving the active one. 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.
  • remove status: 📣 needs proof: Current PR status label is status: 🛠️ actively grinding.

Label justifications:

  • P2: This is a normal-priority Control UI workflow bug fix for hidden pending approvals with limited blast radius.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 🛠️ actively grinding: The PR author has acted after the latest ClawSweeper review and work remains. Needs real behavior proof before merge: The PR body lists unit tests and build commands only; it needs redacted real Control UI proof such as a screenshot, recording, live output, or logs showing the next queued approval remains visible after resolving the active one. 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 +7, Tests +103. Total +110 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 3 10 3 +7
Tests 3 114 11 +103
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 124 14 +110

What I checked:

  • Current modal behavior: Current main opens the native dialog only from firstUpdated(), and openDialog returns forever once the component's internal opened flag is set, even if the underlying dialog was later closed while the custom element instance stays mounted. (ui/src/ui/components/modal-dialog.ts:90, 21d1e1f0fc9d)
  • Current approval prompt reuse surface: The approval prompt renders a stable openclaw-modal-dialog for the active queue item, so moving from one queued approval to the next can reuse the same custom element instance. (ui/src/ui/views/exec-approval.ts:161, 21d1e1f0fc9d)
  • Shared approval refresh path: refreshPendingApprovalQueue already lists both exec and plugin approvals and merges refreshed state with approvals that arrive during the refresh, making it the right existing helper for reconnect hydration. (ui/src/ui/controllers/exec-approval.ts:327, 21d1e1f0fc9d)
  • PR implementation: The PR adds updated() reopening to the modal, imports refreshPendingApprovalQueue into connectGateway(), calls it on hello, and adds regression tests for modal reuse, queued approval state, plugin approvals, and hello-list hydration. (ui/src/ui/components/modal-dialog.ts:94, ef98bd1959a7)
  • Linked bug and candidate fix: The PR has a closing reference to the open bug report, whose body describes two queued Control UI approvals, resolving one, and the next approval becoming hidden while still pending.
  • Real behavior proof gap: The PR body lists unit/node tests, git diff --check, and ui:build, but no screenshot, recording, live Control UI output, or redacted runtime log showing the after-fix queued-approval modal behavior. (ef98bd1959a7)

Likely related people:

  • BunsDev: Authored the native dialog-backed Control UI modal migration that introduced openclaw-modal-dialog and moved exec approval prompts onto it. (role: introduced modal behavior; confidence: high; commits: e5a5ea10722e; files: ui/src/ui/components/modal-dialog.ts, ui/src/ui/views/exec-approval.ts)
  • jesse-merhi: Authored recent stale approval prompt and approval decision/controller work in the same Control UI approval queue path. (role: approval queue area contributor; confidence: high; commits: 5297eebe8837, 42f0822bfac9; files: ui/src/ui/controllers/exec-approval.ts, ui/src/ui/app.ts, ui/src/ui/views/exec-approval.ts)
  • vincentkoc: Authored recent Control UI gateway startup/reconnect work near the hello path where this PR adds approval-list refresh. (role: recent Control UI reconnect contributor; confidence: medium; commits: f49f5973b0c1, c69a8d633d45, 8c8c8c8e32e2; files: ui/src/ui/app-gateway.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: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 1, 2026
@haruaiclone-droid
haruaiclone-droid force-pushed the codex/fix-control-ui-queued-approvals branch from ef98bd1 to 869bfe3 Compare July 1, 2026 04:01
@clawsweeper clawsweeper Bot added status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 2, 2026
@steipete steipete self-assigned this Jul 5, 2026
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Closing after live verification on current main (9d2d517296996fc822acd8b6e4663e1e86f85919).

I exercised the real Control UI path with a mocked Gateway queue containing two exec approvals. The newer approval rendered first with a pending count; clicking Allow once sent exec.approval.resolve, advanced the queue to the older approval, and left that approval visibly rendered in the same still-open native dialog.

The proposed modal regression test manually calls dialog.close() before changing its content, but the actual approval decision path does not close the dialog: it resolves the request and removes the active queue item. The action button also has no form ancestor, so its default button type does not create a dialog-submit path. Reopening every reused shared modal on updated() and adding reconnect refresh behavior therefore would address an artificial state and broaden the change without a reproduced product failure.

Supported behavior already works on main. A new report would be useful if it includes a live recording or browser trace showing which real interaction closes the underlying dialog while another approval remains queued.

@steipete steipete closed this Jul 5, 2026
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 P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI approval window closes with queued approvals pending

2 participants