Phase B.6 audit of commits 7aee534 (Trust-3/6 main-window guard + size
cap on clipboard + paste surface), 12b413d (broaden clipboard/paste
allowlist to documented secondary windows), and f7af7b0 (Trust-4 main-
window guard on extract_content_tags_cmd).
Existing coverage is strong:
* commands/security.rs: 4 tests for ensure_main_window_label +
ensure_window_in_set_label accept/reject paths.
* commands/clipboard.rs: 3 size-cap tests via a shadow size_check
helper.
* commands/paste.rs: comprehensive — 4 backend-order, 4
clipboard-restore, 7 terminal-classification, 3 paste-size-cap, plus
paste_cap_matches_clipboard_cap that pins the
MAX_CLIPBOARD_BYTES == MAX_PASTE_BYTES invariant the commit explicitly
cared about.
* commands/llm.rs: extract_content_tags_cmd Trust-4 — unconditional
ensure_main_window guard with no surface to test beyond what's there.
One real residual.
The 12b413d commit message states:
"mirror the secondary-windows capability grant in
src-tauri/capabilities/secondary-windows.json so the IPC trust
boundary and the permission grant stay in lock-step."
But no test pins the mirror invariant. A future change could:
* add a new window to secondary-windows.json and forget to update
CLIPBOARD_ALLOWED_WINDOWS or PASTE_REPLACING_ALLOWED_WINDOWS;
* typo a label in one of the Rust consts;
* remove a window from the JSON while leaving the const intact;
* remove a window from the const while leaving the JSON intact.
Each of those silently drifts the IPC trust boundary against the
capability grant. The two halves stay in lock-step on intent — but the
intent lives only in the commit message and a docstring, not in a
runtime check.
Fix (test-only, no production behaviour change):
* Promote CLIPBOARD_ALLOWED_WINDOWS and PASTE_REPLACING_ALLOWED_WINDOWS
from private to pub(crate) so a single shared test can reference them.
* Cross-reference both consts in a new docstring back to the pinning test.
* Add commands::security::tests_capability_mirror::allowlists_match_capability_jsons.
The test reads capabilities/main.json + capabilities/secondary-windows.json
at CARGO_MANIFEST_DIR, parses with serde_json, collects every label
declared in the "windows" arrays, and asserts every label in both
Rust allowlists is in that declared set.
Asymmetric on purpose: the JSON may legitimately declare windows that
don't need clipboard/paste (e.g. tasks-float doesn't), so the test
does NOT assert const ⊇ JSON, only const ⊆ JSON. The over-restrict
direction is safe; the under-restrict direction is the IPC bypass we
care about.
Verification:
* cargo test -p lumotia --lib commands::security
→ 5/5 pass including the new allowlists_match_capability_jsons.
* cargo fmt --check → clean (applied fmt after the test edit).
* cargo clippy -p lumotia --all-targets -- -D warnings → clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rust-toolchain.toml pins to stable 1.94.1 so contributors and CI runners
share the exact rustc / rustfmt / clippy versions. Without the pin, every
machine surfaces a different lint set depending on its local install — six
pre-existing lints showed up on 1.94.1 that 1.93-era HANDOVER reported clean.
Clippy fixes (all pre-existing, not introduced by feature work):
- crates/storage/src/database.rs: std::iter::repeat().take() -> repeat_n()
- crates/llm/src/lib.rs (docs): "+ frontends" was parsed as a markdown bullet
continuation by rustdoc, breaking doc-lazy-continuation. Reworded to "and".
- crates/llm/src/lib.rs (loop): while-let-on-iterator -> for-loop.
- src-tauri/src/commands/security.rs: .iter().any(|a| *a == x) -> .contains(&x).
- src-tauri/src/lib.rs: io::Error::new(Other, e) -> io::Error::other(e).
- src-tauri/src/tauri_app_data_migration.rs: drop function-tail `return`s
inside cfg blocks; each platform's block now ends with a tail expression.
cargo fmt sweep across the workspace. Mechanical layout-only changes;
no semantics affected.
Workspace gates after this commit:
- cargo fmt --check: clean
- cargo clippy --workspace --all-targets -- -D warnings: clean
- cargo test --workspace: 405/0 (will become 409/0 with Phase A.1+A.2)
The Trust-3/Trust-6 fix in commit 7aee534 added ensure_main_window to
copy_to_clipboard, paste_text, and paste_text_replacing. That was over-
broad: the transcript-viewer and transcription-preview windows
legitimately call copy_to_clipboard (their "copy raw" / "copy
transcript" buttons), and the transcription-preview window legitimately
calls paste_text_replacing (the preview paste-to-foreground flow).
The original Trust-3/Trust-6 finding was about asymmetric exposure to
arbitrary windows, not about banning the documented secondary windows.
Fix: add ensure_window_in_set helper in commands::security, mirror the
allow-list against src-tauri/capabilities/secondary-windows.json so the
IPC trust boundary and the permission grant stay in lock-step.
copy_to_clipboard -> main + transcript-viewer + transcription-preview
paste_text_replacing -> main + transcription-preview
paste_text -> main only (unchanged; no secondary caller)
Adds two unit tests for ensure_window_in_set_label covering the
listed-label accept path and the unlisted-label reject path. The
existing Trust-3/Trust-6 tests remain in place and continue to assert
the size cap and the constants-equality invariant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>