Skip to content

fix: preserve allow-always unavailable reasons across approval surfaces#97345

Closed
arkyu2077 wants to merge 1 commit into
openclaw:mainfrom
arkyu2077:javis/97069-allow-always-reason
Closed

fix: preserve allow-always unavailable reasons across approval surfaces#97345
arkyu2077 wants to merge 1 commit into
openclaw:mainfrom
arkyu2077:javis/97069-allow-always-reason

Conversation

@arkyu2077

@arkyu2077 arkyu2077 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • carry a typed allowAlwaysUnavailableReason through exec approval requests, gateway transport, Control UI parsing, and approval view models
  • render reason-specific Allow Always unavailability copy in forwarded replies, reaction prompts, manual approval fallback text, and the Control UI
  • add focused coverage for policy derivation, gateway validation, node-host request plumbing, and the affected approval UI/runtime surfaces

Testing

  • node scripts/run-vitest.mjs src/plugin-sdk/approval-reaction-runtime.test.ts packages/gateway-protocol/src/exec-approvals-validators.test.ts src/gateway/server-methods/server-methods.test.ts src/infra/exec-approvals-policy.test.ts src/infra/exec-approval-forwarder.test.ts src/infra/exec-approval-reply.test.ts src/agents/bash-tools.exec-host-node.test.ts ui/src/ui/views/exec-approval.test.ts

Closes #97069

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: M triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jun 28, 2026
@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 27, 2026, 10:12 PM ET / 02:12 UTC.

Summary
The PR adds an optional typed Allow Always unavailability reason to exec approval requests and uses it for reason-specific approval copy in several gateway, forwarding, reaction, and Control UI surfaces.

PR surface: Source +137, Tests +162. Total +299 across 21 files.

Reproducibility: yes. from source with high confidence. Current main removes Allow Always for both ask=always and one-shot persistence while user-facing prompt builders still print policy-only copy when the decision is absent; I did not run a live gateway flow in this read-only review.

Review metrics: 2 noteworthy metrics.

  • Protocol reason field: 1 optional gateway request field added. The additive field is low compatibility risk, but every production approval prompt caller must propagate it for consistent user-visible copy.
  • Unwired prompt path families: 3 still missing reason plumbing. Foreground agent tool results, Telegram native handling, and Telegram forwarding still pass neither the new reason nor an equivalent fact into the shared prompt renderer.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #97069
Summary: This PR is one candidate fix for the open misleading Allow Always unavailable-copy bug, with several sibling PRs targeting the same root cause.

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: 🧂 unranked krab
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:

  • Thread the typed reason through foreground, embedded/subagent, and Telegram approval prompt paths with production-shaped regression tests.
  • Move the Control UI reason copy into i18n keys and generated locale outputs.
  • [P1] Add redacted real behavior proof showing redirected-command and ask=always approval prompts after the fix.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body lists focused tests only; it does not include after-fix terminal, log, screenshot, recording, or live prompt proof for the redirected-command behavior. 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
Telegram Desktop proof would materially verify the visible redirected-command approval prompt after the missing Telegram plumbing is fixed. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis telegram desktop proof: verify a redirected command approval shows the reason-specific Allow Always unavailable explanation and an ask=always approval keeps the policy explanation.

Risk before merge

  • [P1] Merging this as-is can close the linked bug while foreground main-agent/subagent approval-pending messages still show the stale policy-only explanation for one-shot commands.
  • [P1] Telegram native and forwarding approval prompts still do not receive the new typed reason, so Telegram-visible behavior remains unproven and likely incomplete.
  • [P1] The Control UI warning now comes from English core formatter strings instead of the UI i18n catalog, leaving non-English locales without owned translations for the new reason copy.
  • [P1] There are several overlapping open PRs for the same bug, so maintainers still need to pick one canonical implementation before closing the rest.

Maintainer options:

  1. Complete typed-reason plumbing (recommended)
    Carry allowAlwaysUnavailableReason through ExecToolDetails, buildExecApprovalPendingToolResult, embedded/subagent handling, Telegram native and forwarding callers, and add production-shaped tests for one-shot and ask=always prompts.
  2. Choose an existing canonical branch
    Maintainers can pause this PR and land a better-proven sibling such as fix(approval): distinguish policy vs non-persistable reason for missing allow-always (fixes #97069) (AI-assisted) #97077 if they prefer the ask-threading approach over a new typed protocol field.
  3. Accept partial surface coverage
    Maintainers could intentionally accept the narrower typed-reason coverage, but the linked bug should remain open because reported main-agent/subagent and Telegram paths are not fully repaired.

Next step before merge

  • [P1] The PR needs author or maintainer changes plus real behavior proof, and maintainers should choose one canonical fix among the overlapping candidates before merge.

Security
Cleared: The diff changes approval metadata propagation, prompt copy, UI rendering, and tests; no dependency, workflow, secret, permission, install, or package-resolution concern was found.

Review findings

  • [P1] Thread the reason into production prompt callers — src/infra/exec-approval-reply.ts:382-385
  • [P2] Keep Control UI warning text in i18n — ui/src/ui/views/exec-approval.ts:159-166
Review details

Best possible solution:

Thread the typed unavailable reason through all production approval prompt data paths, keep Control UI copy in the i18n catalog, prove redirected-command and ask=always behavior in a real prompt, then choose one canonical PR for the linked bug.

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

Yes, from source with high confidence. Current main removes Allow Always for both ask=always and one-shot persistence while user-facing prompt builders still print policy-only copy when the decision is absent; I did not run a live gateway flow in this read-only review.

Is this the best way to solve the issue?

No. The typed reason approach is plausible, but this branch stops short of the foreground/embedded/Telegram production call sites and bypasses Control UI i18n, so it is not yet the narrow complete fix.

Full review comments:

  • [P1] Thread the reason into production prompt callers — src/infra/exec-approval-reply.ts:382-385
    The new reply formatter can only show reason-specific text when callers pass allowAlwaysUnavailableReason, but the foreground tool result and Telegram native/forwarding paths still pass neither that field nor an equivalent fact. That means the reported main-agent/subagent and Telegram approval prompts can keep stale policy-only or generic copy for redirected one-shot commands, so please carry the typed reason through ExecToolDetails, embedded/Telegram callers, and production-shaped tests.
    Confidence: 0.92
  • [P2] Keep Control UI warning text in i18n — ui/src/ui/views/exec-approval.ts:159-166
    This replaces the localized t("execApproval.allowAlwaysUnavailable") warning with English strings from a core formatter. Non-English Control UI locales cannot translate the new reason-specific warnings, so add UI i18n keys and generated locale metadata instead of rendering hardcoded core copy here.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.91

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a bounded approval prompt regression that misleads users and adds repeated approval friction without blocking all exec usage.
  • merge-risk: 🚨 other: Merging this incomplete prompt-copy fix could leave different approval surfaces showing conflicting or stale explanations for the same one-shot command.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body lists focused tests only; it does not include after-fix terminal, log, screenshot, recording, or live prompt proof for the redirected-command behavior. 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: telegram-visible-proof: Mantis should capture Telegram visible proof. The linked bug and approval prompt copy are Telegram-visible, and a short Telegram Desktop recording can directly show whether the final native prompt text is correct.
Evidence reviewed

PR surface:

Source +137, Tests +162. Total +299 across 21 files.

View PR surface stats
Area Files Added Removed Net
Source 13 147 10 +137
Tests 8 168 6 +162
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 21 315 16 +299

What I checked:

  • Repository policy read: Root AGENTS.md plus scoped agent, gateway, server-methods, plugin SDK, UI, and Telegram maintainer notes were read; the review applied the whole-surface approval and i18n guidance. (AGENTS.md:1, d1b917120a47)
  • Linked bug scope: The linked open bug reports the misleading Allow Always text from main agent, subagent, and Telegram approval prompts for redirected commands under ask=on-miss.
  • Current-main cause collapse: Current main removes allow-always for both ask=always and one-shot persistence, so downstream renderers need a separate reason to distinguish policy from non-persistable command state. (src/infra/exec-approvals.ts:1819, d1b917120a47)
  • Foreground tool-result prompt still policy-only: The current foreground approval-pending message still prints the policy explanation whenever allow-always is absent; this PR does not modify this file or thread the new reason into this call path. (src/agents/bash-tools.exec-runtime.ts:403, d1b917120a47)
  • ExecToolDetails lacks reason plumbing: The approval-pending tool details carry allowed decisions but no ask or allow-always unavailable reason, so embedded/subagent renderers cannot recover the new typed reason from production details. (src/agents/bash-tools.exec-types.ts:133, d1b917120a47)
  • Telegram native prompt caller lacks reason: The Telegram native approval handler calls buildExecApprovalPendingReplyPayload without ask or allowAlwaysUnavailableReason, so the PR's new reply helper cannot show the specific one-shot reason there. (extensions/telegram/src/approval-handler.runtime.ts:75, d1b917120a47)

Likely related people:

  • jesse-merhi: Authored the Tree-sitter command authorization planner work that introduced one-shot persistence and unavailable-decision handling for Allow Always. (role: feature-history owner; confidence: high; commits: c9707ab635b9, 42f0822bfac9; files: src/infra/exec-approvals.ts, src/agents/bash-tools.exec-host-gateway.ts, src/agents/bash-tools.exec-host-node.ts)
  • gumadeiras: Authored the effective exec approval reporting/actions PR that added generic unavailable Allow Always copy across shared approval surfaces. (role: introduced effective-policy reporting path; confidence: high; commits: ba735d015809; files: src/infra/exec-approval-reply.ts, src/infra/exec-approval-forwarder.ts, src/agents/bash-tools.exec-runtime.ts)
  • ooiuuii: Recent merged history touches the Control UI i18n formatter pipeline, which is relevant to the PR's hardcoded Control UI warning copy. (role: adjacent UI i18n contributor; confidence: medium; commits: 9d800b71c060; files: scripts/control-ui-i18n.ts, ui/src/i18n/locales/en.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.

@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closing this in favor of #97145 as the stronger canonical fix for #97069.

This branch introduces a typed unavailable-reason field, but the current head still leaves three production path families unwired: foreground agent tool results, Telegram native approvals, and Telegram forwarding. #97145 carries the existing ask cause through agent, gateway, Telegram, reaction, and Control UI renderers, has redacted real prompt/screenshot proof for both the redirected-command and ask=always cases, and its current exact head is 01b37c45bb0a0adb656e1e54b08ee6f5e3bd11ef. Keeping the fully covered branch avoids landing a partial fix that would leave the reported prompt wrong on some surfaces.

Thank you for the careful protocol, renderer, and test work, @arkyu2077.

@steipete steipete closed this Jul 9, 2026
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. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M 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]: Approval prompt wrongly says effective policy requires approval every time for non-persistable redirected command

2 participants