fix(sync-skills): guard the pre-existing prune against an empty prefix (#1087)
prune_stale_links_in_target compared "$resolved" == "$canonical_real/"* while length-checking only $resolved. If $canonical_real were ever empty the pattern collapses to == "/"* and matches every absolute path. The failure is precisely inverted, which is what makes it worth fixing rather than noting: is_mosaic_skill_name already `continue`s for names that ARE current mosaic skills, so an empty prefix would delete exactly the FOREIGN symlinks in every target directory and preserve the mosaic ones. On this host that is 4 base installs, including codex's own .system entry. Reported by mos-claude as #1087 after I introduced the same guard in the new legacy-cleanup path in the previous commit and walked past this instance thirty lines away. Same defect class, same file, one function apart. $canonical_real is populated by readlink -f after a mkdir -p, so an empty value requires readlink to fail — unlikely, but the consequence is deleting operator symlinks across every harness, which is not a risk worth carrying for one test.
This commit is contained in:
@@ -262,7 +262,12 @@ prune_stale_links_in_target() {
|
|||||||
# -m resolves lexical dangling targets too. If resolution fails, ownership
|
# -m resolves lexical dangling targets too. If resolution fails, ownership
|
||||||
# is unproven and the link must be preserved.
|
# is unproven and the link must be preserved.
|
||||||
resolved="$(readlink -m "$link_path" 2>/dev/null || true)"
|
resolved="$(readlink -m "$link_path" 2>/dev/null || true)"
|
||||||
if [[ -n "$resolved" && "$resolved" == "$canonical_real/"* ]]; then
|
# $canonical_real must be length-checked BEFORE use as a prefix: if it were
|
||||||
|
# ever empty, "$resolved" == "$canonical_real/"* collapses to == "/"* and
|
||||||
|
# matches every absolute path. Combined with the is_mosaic_skill_name skip
|
||||||
|
# above, that inverts the function precisely — it would delete exactly the
|
||||||
|
# FOREIGN symlinks and keep the mosaic ones. (#1087, reported by mos-claude.)
|
||||||
|
if [[ -n "$resolved" && -n "$canonical_real" && "$resolved" == "$canonical_real/"* ]]; then
|
||||||
rm -f "$link_path"
|
rm -f "$link_path"
|
||||||
echo "[mosaic-skills] Removed stale retired skill link: $link_path"
|
echo "[mosaic-skills] Removed stale retired skill link: $link_path"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user