@@ -231,10 +231,10 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
231231
232232 A directory is considered multi-skill when it has no root ``SKILL.md`` and
233233 at least two immediate child directories contain a manifest or supported
234- structured skill bundle. Any discovery limit or filesystem ambiguity
235- discards all partial classifications and returns ``complete == False``.
236- Callers can then fall back to a bounded monolithic scan and propagate the
237- supplied limitation to their public completeness surfaces .
234+ structured skill bundle. Discovery limits and filesystem ambiguities return
235+ ``complete == False``. A symlinked immediate child is the narrow exception:
236+ it is never traversed, but already classified non-link siblings remain
237+ available for a bounded recursive scan with the supplied limitation .
238238 """
239239 absolute_directory = Path (os .path .abspath (directory ))
240240 try :
@@ -273,12 +273,19 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
273273 return MultiSkillDetectionResult (is_multi_skill = False , has_root_skill = True )
274274
275275 skills : list [SkillDirectory ] = []
276+ limitations : list [MultiSkillDetectionLimitation ] = []
276277 for entry in _bounded_scandir (directory , budget = budget ):
277278 budget .check_runtime ()
278279 child = Path (entry .path )
279280 try :
280281 if entry .is_symlink () or _is_link_or_junction (child ):
281- raise _read_error ("multi_skill_symlinked_entry" )
282+ limitations .append (
283+ MultiSkillDetectionLimitation (
284+ reason_code = "read_error" ,
285+ resource = "multi_skill_symlinked_entry" ,
286+ )
287+ )
288+ continue
282289 if not entry .is_dir (follow_symlinks = False ):
283290 continue
284291 except OSError as exc :
@@ -310,6 +317,7 @@ def detect_skills(directory: Path) -> MultiSkillDetectionResult:
310317 is_multi_skill = len (skills ) >= 2 ,
311318 skills = skills ,
312319 has_root_skill = False ,
320+ limitations = tuple (limitations ),
313321 entries_examined = budget .entries ,
314322 structured_candidates_examined = budget .structured_candidates ,
315323 structured_input_bytes_examined = budget .structured_bytes ,
0 commit comments