feat: add explicit RDP clipboard output - #24
Merged
Merged
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a new clipboard delivery path plus systemd sandboxing and data-schema changes that warrant careful human security and end-to-end behavioral review.
Pull request overview
This PR adds an explicit, default-off “clipboard final delivery” output target intended for RDP canvases (e.g., Remmina) that cannot consume native IBus preedit/commit, while keeping caret/IBus delivery as the default path.
Changes:
- Introduces
output-target.json(caret/clipboard) that is hot-loaded and frozen per utterance; adds a bounded, preflighted clipboard writer that only copies authoritative finals. - Extends GTK settings with a new “remote desktop” page, new actionable service status codes, and user-facing privacy/safety boundaries for clipboard mode.
- Advances opted-in dataset
record.jsonto schema v4 by recordingdelivery.target(caret/clipboard), and updates CLI/systemd/packaging/docs/tests accordingly.
File summaries
| File | Description |
|---|---|
| voice/tests/test_settings_controller.py | Adds tests for allowlisted clipboard/output-target status codes and output-target save/load privacy. |
| voice/tests/test_settings_app.py | Adds remote-desktop UI tests and clipboard status messaging expectations; updates page count. |
| voice/tests/test_session.py | Adds extensive session-level coverage for clipboard target behavior, freezing, and failure modes. |
| voice/tests/test_output_target.py | New unit tests for strict output-target config I/O and clipboard helper preflight/write boundaries. |
| voice/tests/test_data_collection.py | Updates to schema v4 expectations and validates delivery.target recording and immutability rules. |
| voice/tests/test_cli.py | Wires new --output-target option into CLI run path and hot-reload expectations. |
| voice/README.md | Documents explicit remote-desktop clipboard target, helper requirements, and schema v4 semantics. |
| voice/pyproject.toml | Bumps voice package version to 0.1.0a8. |
| voice/murmur_voice/settings_controller.py | Adds output-target config path handling, save/load APIs, and allowlists new status codes. |
| voice/murmur_voice/settings_app.py | Adds “远程桌面” settings page, new status/outcome labels, and output-target save/load UI. |
| voice/murmur_voice/session.py | Implements output target freezing, clipboard preflight before mic/provider, clipboard final-only delivery, and new status/outcome behavior. |
| voice/murmur_voice/output_target.py | New module implementing strict output-target config and a bounded clipboard helper writer with socket preflight. |
| voice/murmur_voice/output_style.py | Adjusts delivery record docstring to avoid hard-coding schema version wording. |
| voice/murmur_voice/data_collection.py | Advances record schema to v4 and records frozen delivery target in record.json. |
| voice/murmur_voice/cli.py | Adds --output-target CLI argument and wires output_target_reader + ClipboardWriter into VoiceSession. |
| voice/murmur_voice/init.py | Bumps package __version__ to 0.1.0a8. |
| voice/.gitignore | Ignores local output-target.json. |
| settings/README.md | Documents new output target option and clipboard-mode boundaries in settings app README. |
| SECURITY.md | Clarifies caret-mode secret-field protections vs clipboard-mode limitations; forbids auto-paste and late switching. |
| scripts/verify_preview_bundle.py | Adds output-target.json to the “must not ship” private config filename set. |
| scripts/uninstall-user.sh | Updates messaging to include output-target among preserved private settings. |
| scripts/tests/test_user_install.py | Updates wheel/version expectations and asserts systemd unit includes --output-target; verifies retention on uninstall. |
| scripts/tests/test_systemd_units.py | Asserts unit includes VOICE_OUTPUT_TARGET, --output-target, and X11 socket bind with PrivateTmp. |
| scripts/tests/test_preview_sbom.py | Updates versioned wheel/dist-info expectations for 0.1.0a8. |
| scripts/tests/test_preview_bundle.py | Adds output-target.json to forbidden private config artifacts and updates wheel filename. |
| scripts/tests/test_deb_packaging.py | Updates version expectations, unit assertions, and checks helper dependencies are rendered. |
| scripts/install-user.sh | Adds VOICE_OUTPUT_TARGET wiring into rendered user units. |
| scripts/build-deb.sh | Extends forbidden-owned-config filename checks to include output-target.json. |
| README.md | Updates Chinese top-level README messaging and architecture diagram for explicit remote-desktop clipboard mode. |
| README.en.md | Updates English README to describe explicit final-only clipboard mode for remote desktop. |
| packaging/systemd/murmur-ime-voice.service.in | Adds --output-target to ExecStart and bind-mounts /tmp/.X11-unix read-only under PrivateTmp. |
| packaging/debian/README.md | Updates statement of preserved user configuration to include final-delivery target. |
| packaging/debian/murmur-ime-voice.service | Adds --output-target and BindReadOnlyPaths=-/tmp/.X11-unix in Debian unit. |
| packaging/debian/io.github.SidUParis.OpenVoiceInputLinux.metainfo.xml | Adds release notes entry for 0.1.0-alpha.8 and describes remote-desktop clipboard mode. |
| packaging/debian/control.in | Declares xclip, wl-clipboard dependencies and updates package description for explicit remote mode. |
| engine/murmur_ime_engine/constants.py | Bumps engine VERSION to 0.1.0-alpha.8. |
| docs/user-service.md | Documents output-target config file and clipboard preflight behavior under user service. |
| docs/threat-model.md | Extends threat model to include explicit remote-desktop clipboard target boundaries. |
| docs/security.md | Adds explicit security constraints for clipboard delivery mode. |
| docs/remote-desktop.md | Rewrites remote-desktop guide in Chinese, documenting explicit final-copy workflow and privacy boundaries. |
| docs/remote-dataset-storage.md | Updates delivery semantics wording to schema v4 and records delivery.target. |
| docs/release-process.md | Updates release checklist language for schema v4 and target recording. |
| docs/recognition-accuracy.md | Updates references from schema v3 to v4 in delivery replay/audit discussion. |
| docs/README.zh-CN.md | Updates Chinese docs index to include explicit remote-desktop clipboard mode. |
| docs/privacy.md | Documents output-target storage and clipboard-mode privacy boundaries and non-observation behavior. |
| docs/personal-asr-data-plan.md | Updates data plan to schema v4 and migration policy including v3->v4. |
| docs/dependencies.md | Documents optional helpers for source installs and packaged deterministic helper deps. |
| docs/architecture.md | Updates architecture and text lifecycle to include frozen output target and clipboard path. |
| CHANGELOG.md | Adds 0.1.0-alpha.8 changelog entry describing clipboard target and schema v4. |
| .gitignore | Ignores repo-root output-target.json. |
| .github/workflows/ci.yml | Adds output-target.json to CI checks for forbidden private configuration artifacts. |
Review details
- Files reviewed: 50/51 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目标
为 Remmina RDP 等没有 GTK/IBus 文本提交接口的画布增加一个明确、默认关闭的终稿剪贴板目标,同时保持原生 IBus 光标输出为默认路径。
实现
output-target.json:caret(缺省)或clipboard,每条听写开始时冻结。Ctrl+V或模拟按键。/usr/bin/xclip//usr/bin/wl-copy,终稿只经 stdin;预检严格验证本地 X11/Wayland Unix socket,并在打开麦克风或连接 provider 前失败关闭。caret/clipboardtarget;v1/v2/v3 不重写。PrivateTmp=yes,仅将/tmp/.X11-unix只读绑定进 voice service namespace;Debian 包同时依赖 X11/Wayland 两个小型 helper。隐私边界
RDP clipboard 会让终稿对本机、远端会话及其剪贴板历史可见。UI 明确禁止密码、API Key、验证码等秘密。
clipboard-ready只是“上一条曾成功复制”的历史事实,不保证剪贴板未被其他应用覆盖。验证
xclip中文、emoji、换行往返通过;未触碰真实桌面剪贴板。PrivateTmp=yes+BindReadOnlyPaths=-/tmp/.X11-unixtransient user-service namespace smoke 通过。