Skip to content

fix(paths): support HPC symlinks + drop home/project gate for read-only ops#38

Merged
RealZST merged 1 commit intomainfrom
fix/hpc-symlink-home-canonicalize
May 4, 2026
Merged

fix(paths): support HPC symlinks + drop home/project gate for read-only ops#38
RealZST merged 1 commit intomainfrom
fix/hpc-symlink-home-canonicalize

Conversation

@RealZST
Copy link
Copy Markdown
Owner

@RealZST RealZST commented May 4, 2026

Summary

Custom config paths (preview, add) and several desktop-side read/UX operations were rejecting valid paths in two scenarios:

  1. Symlinked $HOME (e.g. Lumi's /users/<user> β†’ /pfs/lustrep*/users/<user>): is_path_allowed compared canonical file paths against the symlink-form home, never matching the prefix.
  2. Work outside $HOME (HPC scratch dirs, external volumes, network shares): the home/project gate forced users to register a project just to track a single config file β€” unnecessary friction since the OS already gates reads via filesystem permissions.

Backend

  • is_path_allowed: canonicalize both sides before prefix comparison; reject non-existent paths (mirrors desktop semantics). Remains in use only as the deploy/write gate.
  • resolve_and_validate_config_path: extracted to hk_core::sanitize as the single authority for both web and desktop. Drops the home/project gate; keeps .. rejection, exists() check, and home-itself rejection (now via canonicalize so trailing slashes / symlinks all reject correctly).
  • Desktop is_path_within_allowed_dirs: deleted entirely (was the equivalent gate for read-only ops; same trust-model justification).

Frontend

  • humanizeError accepts unknown (Tauri IPC rejects with reified HkError objects, not strings β€” String() wrapping produced "[object Object]").
  • Preserve specific message for PathNotAllowed / PermissionDenied (previous git-flavored "repository may be private" wording was misleading for fs-perm errors).
  • IME composition guard with e.keyCode !== 229 fallback (macOS WebKit isComposing is unreliable).

Test plan

  • 365 unit + integration tests pass (`cargo test --workspace` + `npx vitest run`)
  • clippy clean across workspace (`cargo clippy --workspace -- -D warnings`)
  • tsc + biome clean
  • End-to-end on Lumi (web mode): opening `.claude.json` preview no longer shows "Access denied"; adding paths under `/pfs/lustrep3/scratch/` works without registering a project
  • End-to-end on macOS desktop (`cargo tauri dev`): D behavior verified for `/etc/hosts`, `/usr/share/dict/words`, `/etc/master.passwd`; error toasts now show real cause; IME confirm-on-Enter no longer triggers form submit; `/etc/../etc/hosts` and `~` show specific errors

πŸ€– Generated with Claude Code

…ly ops

Custom config paths (preview, add) and several desktop-side read/UX
operations were rejecting valid paths in two scenarios:

1. Symlinked $HOME (e.g. Lumi's /users/<user> -> /pfs/lustrep*/users/<user>):
   is_path_allowed compared canonical file paths against the symlink-form
   home, never matching the prefix.

2. Work outside $HOME (HPC scratch dirs, external volumes, network shares):
   the home/project gate forced users to register a project just to track
   a single config file β€” unnecessary friction since the OS already gates
   reads via filesystem permissions.

Changes:

- is_path_allowed: canonicalize both sides before prefix comparison; reject
  non-existent paths (mirrors desktop semantics). Remains in use only as
  the deploy/write gate.
- resolve_and_validate_config_path: extracted to hk_core::sanitize as the
  single authority for both web and desktop. Drops the home/project gate;
  keeps '..' rejection, exists() check, and home-itself rejection (now
  via canonicalize so trailing slashes / symlinks all reject correctly).
- Desktop is_path_within_allowed_dirs: deleted entirely (was the
  equivalent gate for read-only ops; same trust-model justification).
- Frontend: humanizeError accepts unknown (Tauri IPC rejects with reified
  HkError objects, not strings β€” String() wrapping produced
  "[object Object]"); preserve specific message for PathNotAllowed and
  PermissionDenied (previous git-flavored "repository may be private"
  wording was misleading for fs-perm errors); IME composition guard with
  e.keyCode !== 229 fallback (macOS WebKit isComposing is unreliable).

Tested: 365 unit + integration tests, manual end-to-end on Lumi (web mode)
and macOS desktop (cargo tauri dev).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@RealZST RealZST merged commit 5bcbece into main May 4, 2026
3 checks passed
@RealZST RealZST deleted the fix/hpc-symlink-home-canonicalize branch May 4, 2026 18:43
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