Commit Graph

4 Commits

Author SHA1 Message Date
7f0e1b0375 agent: lumotia — Phase B.6 pin IPC-allowlist vs capability-JSON mirror invariant
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>
2026-05-14 19:37:39 +01:00
27661c816e agent: lumotia — pin rust toolchain + workspace clippy/fmt sweep
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)
2026-05-14 07:19:59 +01:00
12b413d645 agent: code-atomiser-fix — broaden clipboard/paste guards to documented secondary windows
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>
2026-05-13 18:09:26 +01:00
b333c6229e chore(hardening): tighten security and footprint defaults 2026-04-24 19:03:57 +01:00