Skip to content

fix(exec-approval): stop misattributing Allow Always unavailability to policy#97740

Merged
vincentkoc merged 4 commits into
openclaw:mainfrom
saju01:fix/approval-allow-always-message
Jul 11, 2026
Merged

fix(exec-approval): stop misattributing Allow Always unavailability to policy#97740
vincentkoc merged 4 commits into
openclaw:mainfrom
saju01:fix/approval-allow-always-message

Conversation

@saju01

@saju01 saju01 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where users running a command with a shell redirect (e.g. openclaw --version 2>&1) under ask=on-miss saw the approval prompt claim "The effective approval policy requires approval every time, so Allow Always is unavailable." That is false: the same command without 2>&1 does offer Allow Always, so the policy is not "always". The real reason is the command is non-persistable (runtime shell payload → one-shot), but the message blamed policy, misleading operators into thinking their config required per-command approval.

Affected surface: exec approval prompts across all channels (chat reply, native forwarder, plugin reaction runtime, exec runtime, gateway server-method, Web UI) + all 20 localized Control UI bundles.

Why This Change Was Made

Allow Always is dropped in two distinct cases — policy ask=always, and the command being non-persistable/one-shot — but a single message hard-asserted the policy case. Reworded to a reason-neutral, truthful line for both: "Allow Always is unavailable for this command." No decision/behavior logic changed. English + 20 locale bundles + generated i18n meta are all updated together so localized users get the corrected copy and the i18n check stays consistent.

User Impact

Operators no longer get a misleading claim that their approval policy requires approval every time when they merely piped/redirected a command, in any language.

Evidence

Real after-fix prompt (rendered live from this branch, ask=always, redirected command):

Approval required.

Run:
/approve vers allow-once

Pending command:
openclaw --version 2>&1

Other options:
/approve vers deny

Allow Always is unavailable for this command.

Host: gateway
Full id: req-demo

Before, on origin/main (same inputs):
The effective approval policy requires approval every time, so Allow Always is unavailable.

Real setup tested: built tree, full pnpm install; rendered both via buildExecApprovalPendingReplyPayload; ran vitest + typecheck + i18n.

Commands run after this patch:

node --import tsx <render exec-approval-reply payload>   # after = neutral; main = policy-blaming
pnpm ui:i18n:check                                       # clean, 0 fallbacks
pnpm tsgo:core ; npx oxlint <changed>                    # 0/0
pnpm vitest run <6 approval suites>                      # 211 pass

Observed result after fix: neutral copy across all 6 emit-sites; 20 locales regenerated with translated neutral string (no English fallbacks); i18n meta consistent; tests/typecheck/lint green.

Not tested: no UI screenshot (string-only); translations are direct, native-equivalent rewords of the existing key.

Closes #97069

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: XS labels Jun 29, 2026
@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 11, 2026, 5:56 AM ET / 09:56 UTC.

Summary
The branch replaces misleading policy-specific Allow Always unavailability text with neutral command-scoped wording across shared exec approval renderers and localized Control UI, while adding focused UI and plugin-reaction regression tests.

PR surface: Source -22, Tests +125. Total +103 across 50 files.

Reproducibility: yes. Native Telegram before/after proof uses the same redirected command, and current-main source confirms the false explanation is emitted when Allow Always is absent.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #97069
Summary: This is the strongest complete and proof-positive candidate for the canonical reproduced bug; the open alternatives implement broader or less complete designs.

Members:

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

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

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

Risk before merge

  • [P1] The branch cannot currently merge until all 20 generated Control UI i18n metadata conflicts are regenerated from the resolved current-main locale state.
  • [P1] Several open PRs target the same canonical bug; landing more than one could create competing explanation paths and unnecessary churn.

Maintainer options:

  1. Decide the mitigation before merge
    Refresh this complete neutral-copy implementation onto current main, regenerate the conflicted i18n metadata, run exact-head shared approval and UI i18n gates, land it as the single canonical fix, and then close the overlapping candidates with merge proof.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • A maintainer should select the canonical wording design and resolve the current merge conflict; no contributor-side correctness defect remains.

Maintainer decision needed

  • Question: Should this reason-neutral renderer fix be selected as the single canonical solution for [Bug]: Approval prompt wrongly says effective policy requires approval every time for non-persistable redirected command #97069?
  • Rationale: The implementation and proof are strong, but competing open PRs encode different permanent explanation designs and only maintainers can select which wording contract should land.
  • Likely owner: vincentkoc — They introduced the current shared surface, are assigned to this PR, and maintained its latest head.
  • Options:
    • Select this PR (recommended): Refresh generated metadata, land the complete neutral-copy implementation, and close the overlapping candidates.
    • Require typed cause: Pause the candidates and first define a canonical unavailability-reason field at the approval decision boundary.
    • Select ask inference: Choose the broader competing implementation that derives policy versus persistence wording from ask state.

Security
Cleared: The patch changes copy, tests, and generated localization output without adding dependencies, permissions, secrets, workflows, downloads, or executable supply-chain paths.

Review details

Best possible solution:

Refresh this complete neutral-copy implementation onto current main, regenerate the conflicted i18n metadata, run exact-head shared approval and UI i18n gates, land it as the single canonical fix, and then close the overlapping candidates with merge proof.

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

Yes. Native Telegram before/after proof uses the same redirected command, and current-main source confirms the false explanation is emitted when Allow Always is absent.

Is this the best way to solve the issue?

Yes. Neutral wording is the narrowest truthful fix because the shared renderer inputs do not carry a canonical cause; it covers all existing callers without new API, configuration, or protocol surface.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: The PR fixes misleading approval guidance with bounded workflow impact and does not change approval decisions or command execution.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): Published Mantis Telegram Desktop screenshots directly show the false baseline and corrected after-fix wording for the same redirected command; linked recordings provide additional evidence.
  • proof: sufficient: Contributor real behavior proof is sufficient. Published Mantis Telegram Desktop screenshots directly show the false baseline and corrected after-fix wording for the same redirected command; linked recordings provide additional evidence.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Published Mantis Telegram Desktop screenshots directly show the false baseline and corrected after-fix wording for the same redirected command; linked recordings provide additional evidence.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. The approval wording is directly visible in Telegram, and the existing native before/after screenshots satisfy this proof need.
Evidence reviewed

PR surface:

Source -22, Tests +125. Total +103 across 50 files.

View PR surface stats
Area Files Added Removed Net
Source 46 70 92 -22
Tests 4 133 8 +125
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 50 203 100 +103

What I checked:

  • Current main remains affected: Current main still emits the policy-specific explanation from the agent, shared reply, forwarder, plugin reaction, gateway error, and English Control UI paths whenever allow-always is absent. (src/infra/exec-approval-reply.ts:387, d8bf51b4625d)
  • Patch covers shared owner surfaces: The branch changes the central agent, reply, forwarder, reaction, gateway, and UI copy surfaces; shared callers include Telegram, Signal, Matrix, iMessage, WhatsApp, and embedded agent delivery paths. (src/infra/exec-approval-reply.ts:357, 4eab04b445de)
  • Best-fix boundary: The affected renderers receive the allowed decision set but do not consistently receive a canonical reason for allow-always being absent, so the neutral wording is truthful without adding protocol state or inferring a cause from ask. (ui/src/components/exec-approval.ts:159, d8bf51b4625d)
  • Native real-behavior proof: The published Mantis baseline screenshot shows openclaw --version 2>&1 with the false policy explanation, while the candidate screenshot shows the same command with neutral command-scoped wording. (4eab04b445de)
  • Merge conflict scope: A three-way merge with current main conflicts only in the 20 generated Control UI i18n metadata files; runtime code, tests, English source, and locale bundles merge automatically. (ui/src/i18n/.i18n/ar.meta.json:1, 4eab04b445de)
  • Feature provenance: Current-main blame attributes the recently unified approval-renderer surface and misleading strings to Vincent Koc's approval-surface work; they are also the live assignee and maintained this PR's latest UI/i18n commits. (src/agents/bash-tools.exec-runtime.ts:405, 1667654caa)

Likely related people:

  • vincentkoc: Current-main blame connects them to the unified approval renderers, and they authored the latest UI test and generated-i18n maintenance commits on this branch. (role: introduced current shared approval surface, recent branch contributor, and assignee; confidence: high; commits: 1667654caa, d70b06ecdb02, 4eab04b445de; files: src/agents/bash-tools.exec-runtime.ts, src/infra/exec-approval-reply.ts, src/infra/exec-approval-forwarder.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 (4 earlier review cycles)
  • reviewed 2026-06-29T11:26:28.626Z sha 8aa5b6f :: needs changes before merge. :: [P2] Avoid command-specific copy for plugin approvals
  • reviewed 2026-07-11T04:47:18.459Z sha 6922240 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T05:07:28.512Z sha bbb3886 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T06:20:03.881Z sha 4b85e7b :: needs maintainer review before merge. :: none

@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. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P2 Normal backlog priority with limited blast radius. labels Jun 29, 2026
@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared June 29, 2026 10:03 Inactive
@saju01

saju01 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

Heads up: the only red check (build-artifacts → Check Control UI i18n) is pre-existing drift on main, not from this PR. It flags ui/src/ui/views/chat.ts "Cancel reply" aria-label/title missing from the raw-copy baseline — chat.ts is untouched by this diff (string-only reword in exec-approval surfaces + en.ts). Everything else, incl. Real behavior proof, is green. Happy to add the baseline sync here if you'd prefer it bundled, otherwise it'll clear once main is reconciled.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 29, 2026
@openclaw-mantis

Copy link
Copy Markdown
Contributor

Mantis Telegram Desktop Proof

Summary: Mantis captured Telegram Desktop before/after proof for the exec approval prompt wording.

Main screenshot This PR screenshot
Baseline native Telegram Desktop screenshot Candidate native Telegram Desktop screenshot
Main This PR
Baseline native Telegram Desktop proof GIF Candidate native Telegram Desktop proof GIF

Motion-trimmed clips:

Raw QA files: https://artifacts.openclaw.ai/mantis/telegram-desktop/pr-97740/run-28364061567-1/index.json

@saju01
saju01 force-pushed the fix/approval-allow-always-message branch from 012c66f to 8aa5b6f Compare June 29, 2026 11:13
@saju01

saju01 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both review blockers: (1) the i18n defect is fixed — all 20 locale bundles now carry the translated neutral string and meta hashes legitimately match regenerated bundles (no more stale-but-marked-current); (2) added a real after-fix approval prompt render in the PR body with the main-vs-branch contrast for openclaw --version 2>&1. Squashed to one clean commit. @clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed 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. labels Jun 29, 2026
@vincentkoc
vincentkoc force-pushed the fix/approval-allow-always-message branch from 8aa5b6f to 1396383 Compare July 11, 2026 04:30
@clawsweeper clawsweeper Bot added 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. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 11, 2026
@vincentkoc
vincentkoc force-pushed the fix/approval-allow-always-message branch from 6922240 to bbb3886 Compare July 11, 2026 04:55
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 11, 2026
@vincentkoc
vincentkoc force-pushed the fix/approval-allow-always-message branch from bbb3886 to 4b85e7b Compare July 11, 2026 06:06
@vincentkoc vincentkoc self-assigned this Jul 11, 2026
@vincentkoc
vincentkoc force-pushed the fix/approval-allow-always-message branch from 4b85e7b to 4eab04b Compare July 11, 2026 09:41
saju01 and others added 4 commits July 11, 2026 17:56
…o policy

Allow Always is dropped both when policy ask=always AND when a command is
non-persistable (e.g. shell redirect `2>&1` -> one-shot), but the prompt always
claimed 'effective approval policy requires approval every time'. That's
misleading for the non-persistable case (openclaw#97069). Reword to reason-neutral
'Allow Always is unavailable for this command.' across all approval surfaces,
update en + 20 locale bundles, refresh i18n meta, and the matching tests.

Closes openclaw#97069
@vincentkoc
vincentkoc force-pushed the fix/approval-allow-always-message branch from 4eab04b to a53668a Compare July 11, 2026 10:00
@vincentkoc
vincentkoc merged commit cbc8476 into openclaw:main Jul 11, 2026
98 checks passed
vincentkoc added a commit that referenced this pull request Jul 11, 2026
* origin/main:
  fix(cron): abort superseded reconciliation hooks (#104368)
  ci(release): expose Telegram runtime preflight stage (#104387)
  fix(status): avoid false shell-wrapper audit warnings (#81778)
  fix: retry live Gateway readiness proof (#104374)
  fix(exec-approval): stop misattributing Allow Always unavailability to policy (#97740)
  fix: preserve Mac bundle during live builds (#104376)
  chore(docs): translate with GPT-5.6 xhigh
  test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (#104361)
  fix(ui): hide group submenu separator when New group is the only entry (#104370)
  fix(discord): reset progress drafts across queued turns (#102341)
  docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (#94999)
  fix(discord): single-source thread-binding default placement and guard artifact parity (#104342)
  fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (#95536)
  fix(maint): reuse recent same-PR hosted gates (#104355)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 12, 2026
…o policy (openclaw#97740)

* fix(exec-approval): stop misattributing Allow Always unavailability to policy

Allow Always is dropped both when policy ask=always AND when a command is
non-persistable (e.g. shell redirect `2>&1` -> one-shot), but the prompt always
claimed 'effective approval policy requires approval every time'. That's
misleading for the non-persistable case (openclaw#97069). Reword to reason-neutral
'Allow Always is unavailable for this command.' across all approval surfaces,
update en + 20 locale bundles, refresh i18n meta, and the matching tests.

Closes openclaw#97069

* fix(exec-approval): stop misattributing Allow Always unavailability to policy

* test(ui): await exec approval render updates

* chore(ui): sync approval i18n metadata

---------

Co-authored-by: saju01 <[email protected]>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 12, 2026
* origin/main:
  fix(cron): abort superseded reconciliation hooks (openclaw#104368)
  ci(release): expose Telegram runtime preflight stage (openclaw#104387)
  fix(status): avoid false shell-wrapper audit warnings (openclaw#81778)
  fix: retry live Gateway readiness proof (openclaw#104374)
  fix(exec-approval): stop misattributing Allow Always unavailability to policy (openclaw#97740)
  fix: preserve Mac bundle during live builds (openclaw#104376)
  chore(docs): translate with GPT-5.6 xhigh
  test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (openclaw#104361)
  fix(ui): hide group submenu separator when New group is the only entry (openclaw#104370)
  fix(discord): reset progress drafts across queued turns (openclaw#102341)
  docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (openclaw#94999)
  fix(discord): single-source thread-binding default placement and guard artifact parity (openclaw#104342)
  fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (openclaw#95536)
  fix(maint): reuse recent same-PR hosted gates (openclaw#104355)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui gateway Gateway runtime mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: M 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]: Approval prompt wrongly says effective policy requires approval every time for non-persistable redirected command

2 participants