fix(core): guard reconcile skill deletion paths#216
Conversation
|
Warning Review limit reached
More reviews will be available in 27 minutes and 9 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6425c27b4d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if !metadata.is_dir() || metadata.file_type().is_symlink() { | ||
| return None; |
There was a problem hiding this comment.
Allow deleting symlinked skill entries
When the skills root itself is a real directory but skills/<safe-name> is a symlink, this check filters the location out before reconcile_skill can remove anything. That layout is supported elsewhere in the repo: skill discovery follows symlinked skill directories and records canonical_path, and ConfigManager::remove_skill removes just the symlink parent rather than the target. In that supported setup, removing an agent through reconcile returns no delete result and leaves the symlinked skill installed.
Useful? React with 👍 / 👎.
| return None; | ||
| } | ||
|
|
||
| if has_symlink_component(skills_dir) { |
There was a problem hiding this comment.
Do not reject symlinked project ancestors
This rejects any symlink in the entire skills_dir path, not just a symlinked skills root. When a project is opened through a symlinked checkout path, or a home/tmp ancestor is a symlink, a normal .claude/skills/<skill> directory is skipped before the later canonical containment check can prove it is still inside the real skills directory, so reconcile leaves the skill installed and reports no delete result for that agent.
Useful? React with 👍 / 👎.
Motivation
skillsdirectories and deleteddir/sanitize_name(skill)unconditionally, which allowed deletions via symlinked skills roots and could remove directories outside intended skill roots.remove_dir_all()to remove arbitrary user-writable directories.Description
has_symlink_component()to detect symlinked path components andvalid_skill_delete_location()to validate candidate deletion targets with multiple checks (safe name, non-symlink directory, presence ofSKILL.md, parse name match, canonical containment, and canonical-path deduplication).find_skill_locations_in_agents()to only return validated, deduplicated deletion candidates instead of trusting every adapter-provided skills directory.fs::remove_dir_all()and refuse deletion when a candidate becomes unsafe.reconcile_skill_skips_symlinked_skills_root_delete()that asserts a symlinked.claude/skillspointing outside the project is skipped and the outside directory is not removed.Testing
cargo fmt -p aghub-core, which completed successfully.git diff --check, which reported no whitespace issues.cargo test -p aghub-core reconcile_skill_skips_symlinked_skills_root_deleteand variants, but test execution was blocked by the environment (missingsccachewrapper and network crate-download failures), so the test could not be executed here.just fmtwas not available in the execution environment, so frontend/monorepo format steps were not run.Codex Task