Skip to content

fix: fail closed on cwd-relative organize targets - #225

Closed
seonghobae wants to merge 11 commits into
mainfrom
fix/organize-rooted-target-20260816
Closed

fix: fail closed on cwd-relative organize targets#225
seonghobae wants to merge 11 commits into
mainfrom
fix/organize-rooted-target-20260816

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Purpose

Prevent user-editable ontology dm:targetFolder values from producing process-working-directory-relative move plans. DiskSage preview/execute destinations must be rooted and stable rather than depending on whichever CWD launched the desktop process.

Exact current state

  • Exact source head: 9580804a9c1df6d2ba01d564fb1f1aa684636c6e.
  • Independently resolved live protected main: be418bac9bfbdc8aa41b1a698713833e3dbccfdc.
  • PR is open, Draft, and GitHub reports it mergeable. Draft/mergeable is not merge authorization.
  • Semantic delta is src-tauri/src/organize.rs plus the dedicated Windows organize-path test job in .github/workflows/test.yml.
  • Exact-head Release 31942644718, Security Scan 31942644683, and SAST Semgrep 31942644737 completed success.
  • Exact-head Test 31942644656 also completed success, including the dedicated Windows organize-path job, but this older Test workflow still used the predecessor Rust-cache contract that may restore src-tauri/target. Canonical exact-evidence owner ci: require exact-head production coverage evidence #156 has since proven stale compiled-target contamination and repaired it with cache-targets: false; therefore this earlier Test success is not treated as final trustworthy exact-head evidence for integration.
  • The prior CodeRabbit finding about absolute home resolution and Windows proof is resolved. Root-cause owner feat: persist provider sync goals and runtime ADRs #213 removed the relative resolve_home fallback and provided Windows absolute-home evidence; this branch independently provided Windows organize-path evidence.

Test-first repair

The original RED proved dm:targetFolder "relative/{class}" could produce a CWD-relative move destination. The current implementation adds resolve_target_folder and fails closed unless an ontology target is either:

  • an absolute platform path; or
  • an exact ~ / ~/... home-relative target whose supplied home is itself absolute and whose suffix contains only normal path components.

The branch also rejects parent traversal in home-relative targets and named-user-like ~other/... values, preserves literal tildes inside absolute targets, uses platform-appropriate absolute fixtures, and keeps existing {class} substitution behavior. No filesystem mutation authority was added or broadened.

Ownership / dependency order

Required before merge

Keep Draft until the unchanged integration head has trustworthy current Test evidence under the non-stale target-cache contract, Release/Security/SAST and every applicable central workflow pass, every valid current-head finding/thread is resolved, fresh protected-main ancestry remains current, repository-wide exact 100% owned-production region/statement-equivalent, branch, function, and line coverage is satisfied without exclusions or threshold weakening, and live independent-review governance is satisfied. Pending, queued, skipped-required, neutral-required, failed, stale, predecessor, synthetic, diagnostic-only, status-only, model-only, author-only, cached-target, or infrastructure-only evidence is non-passing.


Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b1d3057-691f-4fce-a563-0985a946fc11

📥 Commits

Reviewing files that changed from the base of the PR and between ef88bc8 and 9580804.

📒 Files selected for processing (2)
  • .github/workflows/test.yml
  • src-tauri/src/organize.rs

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

plan_moves_withtargetFolder를 전용 resolver로 처리합니다. {class} 치환 후 절대 경로만 허용합니다. 정확한 ~~/만 홈 경로로 확장하고, 위험한 상대 경로 형식은 거부합니다. 플랫폼별 경로 테스트와 Windows 테스트 잡을 추가합니다.

Changes

대상 폴더 경로 검증

Layer / File(s) Summary
대상 폴더 경로 검증 및 테스트
src-tauri/src/organize.rs
targetFolder를 검증된 PathBuf로 해석합니다. {class} 치환과 홈 경로 확장을 지원합니다. 상대 경로, 부모 디렉터리 탐색, 명명된 사용자 틸드, 상대 home을 거부합니다. 절대 경로 내부의 리터럴 ~는 보존합니다.
Windows 경로 동작 검증
.github/workflows/test.yml
windows-latest 환경에서 organize::tests 라이브러리 테스트를 실행하는 잡을 추가합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 95808

The change makes relative organize targets fail closed while preserving supported rooted targets; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 CWD 기준 상대 경로 대상에 대한 fail-closed 동작 변경을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/organize-rooted-target-20260816

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.

@seonghobae
seonghobae marked this pull request as ready for review August 15, 2026 18:04
coderabbitai[bot]

This comment was marked as resolved.

@seonghobae
seonghobae marked this pull request as draft August 15, 2026 18:10
@seonghobae
seonghobae marked this pull request as ready for review August 16, 2026 21:12
@cursor

cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@seonghobae
seonghobae marked this pull request as draft August 17, 2026 09:02
@seonghobae
seonghobae marked this pull request as ready for review August 18, 2026 00:05
@seonghobae
seonghobae marked this pull request as draft August 18, 2026 00:14
@opencode-agent opencode-agent Bot added priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior labels Aug 22, 2026
@seonghobae
seonghobae marked this pull request as ready for review August 24, 2026 05:25

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 potential issues.

Open in Devin Review

Comment thread src-tauri/src/organize.rs
Comment on lines +27 to +48
fn resolve_target_folder(template: &str, home: &Path, local: &str) -> Option<PathBuf> {
let resolved_template = template.replace("{class}", local);
if resolved_template == "~" {
return home.is_absolute().then(|| home.to_path_buf());
}
if let Some(relative) = resolved_template.strip_prefix("~/") {
if !home.is_absolute() {
return None;
}
let mut folder_path = home.to_path_buf();
for component in Path::new(relative).components() {
match component {
Component::Normal(segment) => folder_path.push(segment),
_ => return None,
}
}
return Some(folder_path);
}

let folder_path = PathBuf::from(resolved_template);
folder_path.is_absolute().then_some(folder_path)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Old tilde substitution replaced first tilde anywhere

The prior template.replacen('~', ...) expanded the first tilde anywhere in the template, so an absolute target like /opt/~archive/{class} was corrupted. The new resolve_target_folder only expands an exact ~ or leading ~/ and preserves literal tildes in absolute targets, fixing this.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread .github/workflows/test.yml Outdated
Comment on lines +45 to +56
windows-organize-paths:
runs-on: windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: src-tauri
- name: Windows organize absolute-path regressions
run: cargo test --manifest-path src-tauri/Cargo.toml --lib organize::tests

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Windows CI job installs no system deps

The new windows-organize-paths job runs cargo test --lib organize::tests on windows-latest with no system-dep install step, unlike the ubuntu job. Building the src-tauri lib pulls in tauri build dependencies; confirm it compiles on a bare windows-latest runner or the job fails before the organize tests run.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@seonghobae
seonghobae marked this pull request as draft August 24, 2026 06:11
@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head update: pushed merge commit ea6f82d9 after resolving the stale origin/main conflict.

  • Preserved lineage-aware MovePlan metadata and source drift validation from current main.
  • Preserved the PR's fail-closed ontology target resolver: only ~/~/... expands from an absolute home; cwd-relative, named-user tilde, parent traversal, and relative-home targets are rejected.
  • Combined the Windows job so both the home-resolution contract and organize path regressions execute.
  • Local evidence: cargo test --lib organize::tests (21 passed), cargo test --test home_resolution_windows_ci_contract (1 passed), actionlint .github/workflows/test.yml, and git diff --check passed.

Hosted checks are now invalidated/restarted for exact head ea6f82d9; the PR remains draft and protected review gates are still required.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head update: 06d1d2e (style-only rustfmt for touched src-tauri/src/organize.rs after main merge).

Local evidence at this head: rustfmt --check and git diff --check passed; focused organize tests 21 passed; Windows home-resolution contract 1 passed; actionlint passed. Hosted checks are queued/in progress with no failures observed. PR remains draft and protected review gates are still required; no merge claimed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head update: 3715a5a (test: use platform absolute homes in organize regressions). Hosted Windows failed only because two organize tests supplied POSIX /home/u; the new fail-closed resolver correctly rejects that as non-absolute on Windows. Tests now use the existing platform_home() helper. Local pinned Rust organize suite: 21 passed; rustfmt --check and git diff --check pass. Protected review/check gates remain; no merge claimed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Superseded by current-main successor PR #260 (69f88d2caaebca934735176f0f1c832b8694555f). The feature is preserved with a smaller diff, a rooted-destination ADR/Changelog record, and a Windows public-boundary contract. The old draft was based on stale main and its hosted test failure was an unrelated concurrent projection test; no force push or bypass was used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant