Skip to content

fix(voice): require admin for voice set#97874

Merged
eleqtrizit merged 1 commit into
openclaw:mainfrom
eleqtrizit:791
Jun 29, 2026
Merged

fix(voice): require admin for voice set#97874
eleqtrizit merged 1 commit into
openclaw:mainfrom
eleqtrizit:791

Conversation

@eleqtrizit

@eleqtrizit eleqtrizit commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Require admin or explicit owner authority before Talk Voice persists a new voice selection.

Changes

  • Gate the mutating voice set command on operator.admin when gateway scopes are present.
  • Expose and honor owner status for absent-scope channel command contexts.
  • Cover external-channel denial, owner/admin success, and read-only command behavior in Talk Voice tests.

Validation

  • corepack pnpm test extensions/talk-voice/index.test.ts
  • git diff --check -- extensions/talk-voice/index.ts extensions/talk-voice/index.test.ts
  • .agents/skills/autoreview/scripts/autoreview --mode local

What Problem This Solves

Fixes an issue where authorized non-owner channel command senders could persist a gateway-wide Talk voice change when no gateway scope metadata was present.

Why This Change Was Made

Persistent Talk voice selection is a gateway configuration write, so the mutating command now requires the same admin or owner authority used by adjacent config-writing command handlers. Read-only voice status and list commands remain available.

User Impact

Operators get consistent admin-only behavior for persistent Talk voice changes. Non-owner command senders can still inspect voice status or list voices when otherwise authorized, but cannot persist a new voice selection.

Evidence

The focused Talk Voice test file passes with 17 tests, including external Telegram/Discord denial without admin, admin success, owner success, and read-only command coverage.

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 29, 2026, 4:19 PM ET / 20:19 UTC.

Summary
The PR changes Talk Voice so /voice set requires operator.admin or explicit owner authority before persisting a voice selection, while adding denial, owner/admin success, and read-only command tests.

PR surface: Source +7, Tests +57. Total +64 across 2 files.

Reproducibility: yes. Current main’s Talk Voice handler and existing test show no-scope Telegram /voice set mutates config; I did not run tests because this cleanup review is read-only.

Review metrics: 1 noteworthy metric.

  • Config-writing authorization boundary: 1 mutating subcommand tightened. The diff changes who can persist Talk Voice config, which is the key upgrade behavior maintainers need to evaluate.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
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:

  • none.

Risk before merge

  • [P1] Existing authorized non-owner Telegram or Discord senders without operator.admin or explicit owner status will no longer be able to persist /voice set; this appears intentional but needs maintainer sign-off before merge.

Maintainer options:

  1. Land With Permission Sign-Off (recommended)
    Maintainers can accept that non-owner authorized channel senders without operator.admin may no longer persist Talk Voice changes, then merge after exact-head checks remain green.
  2. Pause For A Separate Permission Model
    If non-owner channel operators should retain Talk Voice write authority, pause this PR and define that permission explicitly instead of preserving the no-scope fallback.

Next step before merge

  • [P2] The protected maintainer label and intentional compatibility-visible authorization change make this a maintainer sign-off item, not an automated repair candidate.

Security
Cleared: The diff tightens an existing command authorization boundary and adds tests without new dependencies, workflows, secrets handling, downloads, or code-execution surfaces.

Review details

Best possible solution:

Land the narrow subcommand-level owner/admin gate after maintainers explicitly accept the compatibility-visible permission tightening and exact-head checks remain green.

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

Yes. Current main’s Talk Voice handler and existing test show no-scope Telegram /voice set mutates config; I did not run tests because this cleanup review is read-only.

Is this the best way to solve the issue?

Yes. Subcommand-level gating is the narrowest maintainable fix because it protects the config write while preserving /voice status and /voice list; a whole-command requiredScopes gate would over-block read-only behavior.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a bounded bundled-plugin authorization bug fix with limited blast radius.
  • merge-risk: 🚨 compatibility: Merging intentionally blocks existing non-owner external-channel /voice set writers who previously only needed normal command authorization.
  • 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 (recording): The author posted after-fix production-path live output, and Mantis posted successful Telegram Desktop before/after visual proof for the PR head.
  • proof: sufficient: Contributor real behavior proof is sufficient. The author posted after-fix production-path live output, and Mantis posted successful Telegram Desktop before/after visual proof for the PR head.
  • proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The author posted after-fix production-path live output, and Mantis posted successful Telegram Desktop before/after visual proof for the PR head.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. This PR changes visible Telegram /voice set authorization behavior, and the existing Mantis proof demonstrates that path.
Evidence reviewed

PR surface:

Source +7, Tests +57. Total +64 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 15 8 +7
Tests 1 63 6 +57
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 78 14 +64

What I checked:

  • Repository policy applied: Read root AGENTS.md plus the scoped extension/plugin guidance and Telegram maintainer note; this review applied the compatibility-risk and Telegram proof requirements. (AGENTS.md:1, 29f787f10ed4)
  • Current-main behavior: Current main only requires admin when gateway scopes are present or the channel is webchat, so no-scope Telegram/Discord command contexts can currently reach the config write path. (extensions/talk-voice/index.ts:116, 29f787f10ed4)
  • Current-main test expectation: The existing Talk Voice test expects no-scope Telegram /voice set to mutate config, which confirms the compatibility-visible behavior changed by this PR. (extensions/talk-voice/index.test.ts:310, 29f787f10ed4)
  • PR patch shape: The patch adds exposeSenderIsOwner, changes the mutating subcommand guard to require admin or owner authority, and keeps read-only status/list paths outside that guard. (extensions/talk-voice/index.ts:136, 488bab495f3c)
  • Trusted owner-status seam: Command execution forwards senderIsOwner only through the existing trusted exposure path, and registry activation grants that exposure to bundled plugin records. (src/plugins/commands.ts:310, 29f787f10ed4)
  • External plugin exposure guard: Existing command tests show normal and external plugin commands cannot expose owner status merely by setting exposeSenderIsOwner, while trusted bundled commands can opt in. (src/plugins/commands.test.ts:680, 29f787f10ed4)

Likely related people:

  • jacobtomlinson: Live path history shows PR work that enforced operator.admin for /voice set config writes on the same Talk Voice files. (role: earlier Talk Voice admin-gate contributor; confidence: high; commits: e34694733fc6, aa66ae1fc797; files: extensions/talk-voice/index.ts, extensions/talk-voice/index.test.ts)
  • hydro13: Live history shows hardening of Talk Voice config persistence scope checks on the same command surface. (role: Talk Voice hardening contributor; confidence: high; commits: a4e447a16e37; files: extensions/talk-voice/index.ts, extensions/talk-voice/index.test.ts)
  • pgondhi987: Recent Phone Control work added the same trusted owner/admin mutation pattern and command owner-status seam that this PR mirrors for Talk Voice. (role: adjacent authorization contributor; confidence: high; commits: 91a4635bdca9; files: extensions/phone-control/index.ts, extensions/phone-control/index.test.ts, src/plugins/commands.ts)
  • steipete: Live path history shows several recent Talk Voice parsing, config-write, and docs-related touches around this plugin surface. (role: recent Talk Voice area contributor; confidence: medium; commits: 7a803c113d71, 2fe39ce94957, 4fa5092cdc39; files: extensions/talk-voice/index.ts, extensions/talk-voice/index.test.ts, docs/tools/slash-commands.md)
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.

@eleqtrizit

Copy link
Copy Markdown
Contributor Author

Behavioral proof at head 488bab495f3cd08278edd7d0e741a40800113eb3:

I exercised the real command path, not a reduced authorization model:

bundled plugin registration -> matchPluginCommand -> executePluginCommand -> Talk Voice handler -> config mutation callback

Observed with an authorized Telegram command sender and a configured voice provider:

Caller context Command Response Config writes Persisted voice
non-owner, no gateway scopes /voice set Claudia requires operator.admin 0 unchanged
non-owner, operator.write /voice set Claudia requires operator.admin 0 unchanged
non-owner, operator.admin /voice set Claudia success 1 voice-a
owner, no gateway scopes /voice set Claudia success 1 voice-a
non-owner, no gateway scopes /voice status status returned 0 unchanged
non-owner, no gateway scopes /voice list voice list returned 0 unchanged

This proves the mutation boundary itself: denied callers never reach mutateConfigFile; permitted callers reach it once and persist the selected voice. It also proves bundled registration exposes owner status through the production command executor, while explicit gateway scope context remains authoritative.

Fresh focused validation:

  • node scripts/run-vitest.mjs extensions/talk-voice/index.test.ts -- --reporter=verbose — 17/17 passed, including Telegram and Discord denial, admin success, owner success, read-only status/list, and canonical config persistence.
  • node scripts/run-vitest.mjs extensions/talk-voice/index.test.ts src/plugins/commands.test.ts — 66/66 passed across 2 shards, covering the plugin behavior plus command registration, scope enforcement, and trusted owner-status exposure.
  • git diff --check origin/main...HEAD -- extensions/talk-voice/index.ts extensions/talk-voice/index.test.ts — passed.
  • The latest repository “Real behavior proof” check also passed: https://github.com/openclaw/openclaw/actions/runs/28387742622

@eleqtrizit

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@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. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels Jun 29, 2026
@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared June 29, 2026 16:46 Inactive
@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. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. 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
@openclaw-mantis

Copy link
Copy Markdown
Contributor

Mantis Telegram Desktop Proof

Summary: Mantis captured native Telegram Desktop before/after GIFs for /voice set authorization: Main sets the voice, while this PR requires operator.admin.

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-97874/run-28388096959-1/index.json

@clawsweeper clawsweeper Bot added the proof: 🎥 video Contributor real behavior proof includes video or recording evidence. label Jun 29, 2026
@eleqtrizit
eleqtrizit merged commit cbdbb22 into openclaw:main Jun 29, 2026
189 of 205 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 30, 2026
@eleqtrizit
eleqtrizit deleted the 791 branch June 30, 2026 19:27
QiuYuang pushed a commit to QiuYuang/openclaw that referenced this pull request Jul 1, 2026
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
Rorqualx pushed a commit to Rorqualx/cortex that referenced this pull request Jul 6, 2026
Rorqualx pushed a commit to Rorqualx/cortex that referenced this pull request Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: talk-voice maintainer Maintainer-authored PR mantis: telegram-visible-proof Mantis should capture Telegram visible proof. 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: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S 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.

1 participant