Skip to content

feat: desktop vault settings integration - phase 40#424

Merged
FSM1 merged 17 commits into
mainfrom
feat/desktop-vault-settings-integration
Mar 31, 2026
Merged

feat: desktop vault settings integration - phase 40#424
FSM1 merged 17 commits into
mainfrom
feat/desktop-vault-settings-integration

Conversation

@FSM1

@FSM1 FSM1 commented Mar 31, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add HKDF-derived IPNS keypair for vault settings with cross-language test vectors
  • Add VaultSettings type with validation, clamping, and serde round-trip support to cipherbox-core
  • Load encrypted vault settings from IPNS during desktop auth flow with graceful fallback to defaults
  • Replace hardcoded FUSE versioning constants with user-configurable values from vault settings
  • Extract shared apply_versioning() helper to eliminate platform-specific code duplication (macOS + Windows)
  • Code cleanup: use u32::clamp() from std, remove dead constants, strip redundant comments

Test plan

  • cipherbox-core vault_settings unit tests (13 tests: defaults, validation, clamping, serde round-trip, unknown version guard)
  • cipherbox-crypto HKDF derivation tests (determinism, domain separation, cross-language vectors)
  • cipherbox-fuse compiles with removed constants (no dead code references)
  • Manual: verify FUSE mount respects custom vault settings when set via web app
  • Manual: verify default settings used when no vault settings IPNS entry exists

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Desktop app now loads user-configured vault settings during login, enabling personalized file versioning behavior (max versions per file and version cooldown periods) instead of using fixed defaults.
  • Chores

    • Updated project planning and roadmap documentation for Phase 40: Desktop vault settings integration.
    • Expanded test infrastructure with new cross-language derivation vectors.

FSM1 and others added 15 commits March 31, 2026 14:38
Propagate user-configurable vault settings (Phase 39) to Rust SDK
and desktop app. Replaces hardcoded MAX_VERSIONS_PER_FILE and
VERSION_COOLDOWN_MS with values from encrypted IPNS settings blob.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 4da251897fc5
Entire-Checkpoint: b14b14455de5
- Add cross-language test vector for cipherbox-vault-settings-v1
- Add unit tests for derive_vault_settings_ipns_keypair
- Add match arm in cross_language.rs for vault-settings info string
- Tests fail because function not yet implemented (TDD RED)
- Add VAULT_SETTINGS_HKDF_INFO constant with info "cipherbox-vault-settings-v1"
- Add derive_vault_settings_ipns_keypair() following existing derivation pattern
- Re-export new function from crates/crypto/src/lib.rs
- Cross-language parity verified via shared test vector with TypeScript
- Add VaultSettings struct with serde camelCase serialization
- Add DeleteBehavior enum (Bin, Permanent)
- Add default_vault_settings() returning v1 defaults
- Add validate_vault_settings() with clamping and unknown-version guard
- 13 unit tests covering all validation scenarios
- Add 40-01-SUMMARY.md with execution results
- Update STATE.md with metrics
- Update ROADMAP.md with plan progress
… flow

- Add vault_settings: RwLock<VaultSettings> field to KeyState (defaults on init)
- Add load_vault_settings() helper: derive IPNS -> resolve -> fetch -> ECIES unwrap -> validate
- Call load_vault_settings in complete_auth_setup with graceful fallback to defaults
- Update SDK state tests to assert vault_settings initialization and clear behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… settings

- Add max_versions_per_file and version_cooldown_ms fields to CipherBoxFS
- Rename constants to DEFAULT_MAX_VERSIONS_PER_FILE and DEFAULT_VERSION_COOLDOWN_MS
- Update macOS read_ops.rs to use fs.max_versions_per_file and fs.version_cooldown_ms
- Update Windows write_ops.rs to use CipherBoxFS fields for versioning
- Add new params to mount_filesystem on both macOS and Windows
- Pass vault settings from KeyState to FUSE mount with minutes-to-ms conversion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 40-02-SUMMARY.md with execution results and self-check
- Update STATE.md progress (90/96 plans, 94%)
- Update ROADMAP.md phase 40 progress (2/2 complete)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: a4ee52a12edc
…c code

The version cooldown check, version entry creation, and pruning logic
was duplicated between read_ops.rs (macOS/Linux) and
platform/windows/write_ops.rs. Extract into helpers::apply_versioning()
so all platforms share identical behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 0d8a9827e403
…nt helpers

- Replace custom clamp() with std u32::clamp() in vault_settings.rs
- Remove unnecessary numbered comments in load_vault_settings()
- Flatten redundant scope block in complete_auth_setup()
- Delete unused DEFAULT_MAX_VERSIONS_PER_FILE and DEFAULT_VERSION_COOLDOWN_MS constants

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: ed8cad6e6741
@coderabbitai

coderabbitai Bot commented Mar 31, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@FSM1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 24 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 24 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2681ceb9-0263-407d-879e-46ecb50d551a

📥 Commits

Reviewing files that changed from the base of the PR and between 2153edc and e7ba6f1.

📒 Files selected for processing (3)
  • .planning/phases/40-desktop-vault-settings-integration/40-VERIFICATION.md
  • apps/desktop/src-tauri/src/commands/auth.rs
  • crates/fuse/src/helpers.rs

Walkthrough

This implementation introduces user-configurable vault settings to the desktop application. It adds HKDF domain-separated IPNS keypair derivation for vault settings, a new VaultSettings struct with validation and defaults, loads encrypted settings during desktop authentication, wires them into FUSE filesystem operations, and replaces hardcoded versioning constants with configurable values from loaded settings.

Changes

Cohort / File(s) Summary
Planning & Project Management
.planning/PROJECT.md, .planning/ROADMAP.md, .planning/STATE.md, .planning/phases/40-desktop-vault-settings-integration/*
Updated project status to reflect Phase 40 completion; added roadmap entry and planning documents (context, research, validation, verification, two implementation plans, and summary) defining vault settings integration architecture, cross-language parity via HKDF vectors, desktop login flow, and FUSE wiring strategy.
Rust Crypto: HKDF & IPNS Derivation
crates/crypto/src/hkdf.rs, crates/crypto/src/lib.rs
Added VAULT_SETTINGS_HKDF_INFO constant for domain-separated derivation; introduced derive_vault_settings_ipns_keypair() function that derives Ed25519 keypairs for vault settings IPNS records; re-exported the new function from crate root.
Rust Core: VaultSettings Type
crates/core/src/vault_settings.rs, crates/core/src/lib.rs
Introduced VaultSettings struct with serde camelCase serialization and DeleteBehavior enum; implemented default_vault_settings() returning baseline configuration; added validate_vault_settings() with numeric field clamping (retention 0–365 days, versions 0–100, cooldown 0–1440 minutes) and unknown-version guard; included comprehensive unit tests.
Rust SDK: KeyState Integration
crates/sdk/src/state.rs
Added vault_settings: RwLock<VaultSettings> field to KeyState; initialized with defaults in new() and reset in clear(); extended tests to validate default and cleared states.
Rust FUSE: Refactoring to Configurable Parameters
crates/fuse/src/constants.rs, crates/fuse/src/lib.rs, crates/fuse/src/helpers.rs
Removed hardcoded MAX_VERSIONS_PER_FILE and VERSION_COOLDOWN_MS constants; added max_versions_per_file and version_cooldown_ms fields to CipherBoxFS struct; introduced new apply_versioning() helper that encapsulates version entry creation, pruning, and cooldown logic (accepting max_versions and cooldown_ms as parameters).
Rust FUSE: Platform-Specific Operations
crates/fuse/src/platform/windows/write_ops.rs, crates/fuse/src/read_ops.rs
Replaced inline versioning decision and pruning logic with calls to apply_versioning() helper; removed hardcoded constant imports; now use fs.max_versions_per_file and fs.version_cooldown_ms via CipherBoxFS instance.
Desktop/Tauri: Auth & FUSE Integration
apps/desktop/src-tauri/src/commands/auth.rs
Added load_vault_settings() helper that derives IPNS keypair, resolves IPNS, fetches IPFS content, decrypts via ECIES, validates, and returns settings (with graceful fallback to defaults on any error); integrated loading into complete_auth_setup() and stored result in state.sdk.vault_settings; updated FUSE mount call to pass max_versions_per_file and converted version_cooldown_minutes to milliseconds.
Desktop/Tauri: FUSE Mount Configuration
apps/desktop/src-tauri/src/fuse/mod.rs, apps/desktop/src-tauri/src/fuse/windows/mod.rs
Extended mount_filesystem signatures to accept max_versions_per_file: usize and version_cooldown_ms: u64 parameters; propagated parameters into CipherBoxFS construction.
Git Hooks & Test Vectors
.husky/commit-msg, crates/crypto/tests/cross_language.rs, tests/vectors/crypto/hkdf.json
Updated commit-msg hook to call cipherbox git commit-msg with fallback to optional pre-existing hook; extended HKDF cross-language test dispatcher to recognize "cipherbox-vault-settings-v1" info string; added new HKDF test vector for vault settings derivation.

Sequence Diagram(s)

sequenceDiagram
    participant Desktop as Desktop App
    participant Auth as Auth Handler
    participant Crypto as Crypto Crate
    participant IPNS as IPNS Resolver
    participant IPFS as IPFS Client
    participant Decryption as ECIES Decrypt
    participant Validation as VaultSettings<br/>Validator
    participant SDK as SDK State
    participant FUSE as FUSE Mount

    Desktop->>Auth: complete_auth_setup()
    Auth->>Crypto: derive_vault_settings_ipns_keypair(private_key)
    Crypto-->>Auth: (ed25519_priv, ed25519_pub, ipns_name)
    
    Auth->>IPNS: resolve(ipns_name)
    IPNS-->>Auth: ipfs_cid
    
    Auth->>IPFS: fetch(ipfs_cid)
    IPFS-->>Auth: encrypted_content
    
    Auth->>Decryption: ecies_unwrap(encrypted_content, private_key)
    Decryption-->>Auth: json_payload
    
    Auth->>Validation: validate_vault_settings(json_payload)
    Validation-->>Auth: VaultSettings (validated & clamped)
    
    Auth->>SDK: store vault_settings in KeyState
    SDK-->>Auth: ✓
    
    Auth->>FUSE: mount_filesystem(...,<br/>max_versions_per_file,<br/>version_cooldown_ms)
    FUSE-->>Auth: ✓
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • feat(web): user-configurable vault parameters #423: Implements the same "vault settings" feature on the web/TypeScript side; directly precedes this PR's Rust/desktop integration of the same HKDF derivation and VaultSettings validation APIs.
  • feat: Linux desktop app with FUSE mount #220: Modifies desktop FUSE implementation (same modules: apps/desktop/src-tauri/src/fuse/*); changes to FUSE orchestration and mount parameters overlap in scope.
  • feat(12.3.1): Pre-wipe identity cleanup #127: Introduces domain-separated HKDF-based IPNS derivation helpers and corresponding test-vector updates in the crypto crate; shares the same pattern of new derive_*_ipns_keypair functions and cross-language test dispatch extensions.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: introducing desktop vault settings integration for Phase 40 of the project.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/desktop-vault-settings-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@FSM1 FSM1 changed the title feat: desktop vault settings integration (Phase 40) feat: desktop vault settings integration - phase 40 Mar 31, 2026
@codecov

codecov Bot commented Mar 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.84%. Comparing base (fa7b443) to head (e7ba6f1).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
apps/desktop/src-tauri/src/commands/auth.rs 0.00% 42 Missing ⚠️
apps/desktop/src-tauri/src/fuse/mod.rs 0.00% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #424      +/-   ##
==========================================
+ Coverage   62.27%   71.84%   +9.56%     
==========================================
  Files         134      113      -21     
  Lines       10082     7160    -2922     
  Branches     1050     1050              
==========================================
- Hits         6279     5144    -1135     
+ Misses       3587     1800    -1787     
  Partials      216      216              
Flag Coverage Δ
api 84.92% <ø> (ø)
api-client 84.92% <ø> (ø)
core 84.92% <ø> (ø)
crypto 84.92% <ø> (ø)
desktop 14.44% <0.00%> (-16.77%) ⬇️
sdk 84.92% <ø> (ø)
sdk-core 84.92% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
apps/desktop/src-tauri/src/fuse/mod.rs 14.20% <0.00%> (+14.20%) ⬆️
apps/desktop/src-tauri/src/commands/auth.rs 0.00% <0.00%> (ø)

... and 32 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.planning/phases/40-desktop-vault-settings-integration/40-VERIFICATION.md:
- Around line 90-96: Update the "Human Verification Required" and "Gaps Summary"
sections in the 40-VERIFICATION.md report to reflect the two remaining runtime
checks still open: "FUSE mount respects custom settings" and "defaults used if
no IPNS entry"; specifically, change the "None" under "Human Verification
Required" to list those two checks as pending and adjust "Gaps Summary" from "No
gaps" to note that these runtime verifications are outstanding (so the report
doesn't claim full completion) and keep the existing statements about static
verification and graceful fallback intact.

In `@apps/desktop/src-tauri/src/commands/auth.rs`:
- Around line 95-138: Wrap the entire resolve→fetch→decrypt chain in
load_vault_settings with a tokio timeout so a slow/hung IPNS/IPFS call will
return an error and fall back to defaults; specifically, use
tokio::time::timeout(...) around the async block in load_vault_settings (the
block that calls cipherbox_api_client::ipns::resolve_ipns and
cipherbox_api_client::ipfs::fetch_content and
cipherbox_crypto::ecies::unwrap_key) and map a tokio::time::error::Elapsed into
a descriptive Err (e.g., "vault settings load timed out") so the existing match
on result uses cipherbox_core::default_vault_settings() on timeout. Ensure the
duration is reasonable (or configurable) and keep the function signature and
existing error-to-log behavior.

In `@crates/fuse/src/helpers.rs`:
- Around line 122-150: The early return when should_version is false skips
pruning existing_versions; change the logic in the function (around the
should_version check) to always enforce max_versions_per_file by trimming
existing_versions when its length > max_versions and returning the trimmed
Some(versions) plus the pruned CIDs, even if no new version is created. Use the
same pruning approach as in the later branch (build pruned: Vec<String> from
versions.split_off(max_versions).map(|v| v.cid)), log the pruning with ino and
max_versions, and then return (Some(trimmed_versions), pruned) when
should_version is false; preserve the existing debug/info messages and keep the
branch that creates a new version unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 809ef0e0-251e-4f99-9e13-148fae1167cd

📥 Commits

Reviewing files that changed from the base of the PR and between fa7b443 and 2153edc.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (27)
  • .husky/commit-msg
  • .planning/PROJECT.md
  • .planning/ROADMAP.md
  • .planning/STATE.md
  • .planning/phases/40-desktop-vault-settings-integration/40-01-PLAN.md
  • .planning/phases/40-desktop-vault-settings-integration/40-01-SUMMARY.md
  • .planning/phases/40-desktop-vault-settings-integration/40-02-PLAN.md
  • .planning/phases/40-desktop-vault-settings-integration/40-02-SUMMARY.md
  • .planning/phases/40-desktop-vault-settings-integration/40-CONTEXT.md
  • .planning/phases/40-desktop-vault-settings-integration/40-RESEARCH.md
  • .planning/phases/40-desktop-vault-settings-integration/40-VALIDATION.md
  • .planning/phases/40-desktop-vault-settings-integration/40-VERIFICATION.md
  • apps/desktop/src-tauri/src/commands/auth.rs
  • apps/desktop/src-tauri/src/fuse/mod.rs
  • apps/desktop/src-tauri/src/fuse/windows/mod.rs
  • crates/core/src/lib.rs
  • crates/core/src/vault_settings.rs
  • crates/crypto/src/hkdf.rs
  • crates/crypto/src/lib.rs
  • crates/crypto/tests/cross_language.rs
  • crates/fuse/src/constants.rs
  • crates/fuse/src/helpers.rs
  • crates/fuse/src/lib.rs
  • crates/fuse/src/platform/windows/write_ops.rs
  • crates/fuse/src/read_ops.rs
  • crates/sdk/src/state.rs
  • tests/vectors/crypto/hkdf.json
💤 Files with no reviewable changes (1)
  • crates/fuse/src/constants.rs

Comment thread .planning/phases/40-desktop-vault-settings-integration/40-VERIFICATION.md Outdated
Comment thread apps/desktop/src-tauri/src/commands/auth.rs
Comment thread crates/fuse/src/helpers.rs Outdated
FSM1 and others added 2 commits March 31, 2026 16:27
Cover cooldown logic, version creation, pruning, and edge cases
(empty CID, zero max versions, empty version list).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: c7e74621b1ab
- Add 10s tokio::timeout to load_vault_settings() so hung IPNS/IPFS
  calls fall back to defaults instead of stalling login
- Always enforce max_versions pruning in apply_versioning(), even when
  cooldown skips version creation (handles lowered max_versions)
- Update VERIFICATION.md to list two pending runtime checks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01a69d909db0
@FSM1 FSM1 merged commit 0d37d71 into main Mar 31, 2026
25 checks passed
This was referenced Mar 31, 2026
@FSM1 FSM1 deleted the feat/desktop-vault-settings-integration branch April 14, 2026 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant