Skip to content

Python: [BREAKING] Treat nested SKILL.md content as part of the parent skill#6849

Merged
giles17 merged 2 commits into
microsoft:mainfrom
giles17:python/stop-skill-discovery-at-boundary
Jul 1, 2026
Merged

Python: [BREAKING] Treat nested SKILL.md content as part of the parent skill#6849
giles17 merged 2 commits into
microsoft:mainfrom
giles17:python/stop-skill-discovery-at-boundary

Conversation

@giles17

@giles17 giles17 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

File-based skill discovery kept descending past a SKILL.md, so a SKILL.md nested inside another skill's directory was treated as an independent skill root, and content beneath a skill boundary was split away from its skill. Discovery should stop at the first skill boundary, and everything beneath that boundary should belong to that skill.

Description & Review Guide

  • What are the major changes?
    • _discover_skill_directories: stop recursing once a SKILL.md is found, so a nested SKILL.md is no longer discovered as a separate skill.
    • _scan_directory_for_resources / _scan_directory_for_scripts: no longer skip subdirectories that contain their own SKILL.md, so resources and scripts beneath a skill boundary are attached to that skill (the SKILL.md file itself is still excluded as a resource).
    • Updated the discovery docstring, reworked the nested-skill test to assert the new behavior, and added a discovery-level regression test.
  • What is the impact of these changes?
    • Standard flat skill layouts are unchanged. For nested layouts, a directory that previously produced a separate child skill now contributes its content to the enclosing skill instead. This is a [BREAKING — experimental] change to the skills feature (ExperimentalFeature.SKILLS).
  • What do you want reviewers to focus on? The boundary behavior in _discover_skill_directories and the recursion in the resource/script scans.

Related Issue

Fixes #6682

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.

File-based skill discovery kept descending after finding a SKILL.md, which treated content nested beneath a skill boundary as an independent skill root. Return immediately after recording a directory that contains SKILL.md so everything below it stays part of that skill, and add a regression test with a nested SKILL.md.

Fixes microsoft#6682
Copilot AI review requested due to automatic review settings July 1, 2026 06:01
@giles17 giles17 added the python Usage: [Issues, PRs], Target: Python label Jul 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Python file-based skill discovery to treat a directory containing SKILL.md as a hard “skill boundary” and stop recursing into its subdirectories, preventing nested directories from being discovered as separate skill roots.

Changes:

  • Update FileSkillsSource._discover_skill_directories to return immediately after finding a SKILL.md in the current directory.
  • Add a regression test ensuring discovery does not descend into a nested directory that also contains a SKILL.md.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/packages/core/agent_framework/_skills.py Stops recursion once a SKILL.md is found, enforcing a skill boundary during discovery.
python/packages/core/tests/core/test_skills.py Adds a regression test for “do not discover nested skills under an existing skill boundary”.

Comment thread python/packages/core/agent_framework/_skills.py
Comment thread python/packages/core/tests/core/test_skills.py
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Flagged issue

The PR changes nested SKILL.md handling from 'discover both skills, but keep their files separate' to 'ignore the nested skill entirely'. That contradicts the existing contract in python/packages/core/tests/core/test_skills.py:1810-1845, where test_nested_skill_directory_not_crossed explicitly asserts both parent and child skills are discovered, and FileSkillsSource.get_skills() still sources its candidates from _discover_skill_directories() at python/packages/core/agent_framework/_skills.py:2706.


Source: automated DevFlow PR review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 5 | Confidence: 93%

✓ Correctness

The change adds a single return statement in _search after recording a directory that contains SKILL.md. This correctly stops recursion into subdirectories of an already-discovered skill boundary while preserving discovery of sibling skill directories. The logic is sound: the return exits only the current recursive call, so the parent's iteration over other entries continues normally. The new test properly validates the boundary behavior.

✓ Security Reliability

Clean, minimal change that adds a single return to stop recursive skill discovery below an already-found SKILL.md boundary. No security or reliability concerns: the existing OSError handling, depth limit, and input validation remain intact. The change actually improves reliability by preventing unintended discovery of nested skill content as independent skills.

✓ Test Coverage

The PR adds a single return statement to stop recursion after discovering a skill boundary, with a well-structured regression test that directly validates the new behavior. Test coverage is adequate: the new test verifies that nested SKILL.md directories below an already-discovered skill boundary are not treated as independent skills. Existing tests cover sibling skill discovery (via the parent loop), root-level skills, depth limits, and edge cases. One minor suggestion for additional coverage.

✓ Failure Modes

The change is a minimal, correct one-line addition of return after recording a skill directory in _discover_skill_directories._search. This stops recursion below skill boundaries, aligning discovery behavior with the sibling _scan_directory_for_scripts method (which already skips subdirectories containing their own SKILL.md at line 3112). No silent failure modes, lost errors, or operational issues are introduced. The existing test_finds_nested_skill test remains valid because it tests a case where only the child has SKILL.md (not the parent). The new regression test correctly validates the boundary behavior.

✗ Design Approach

The new boundary rule changes more than file attachment: it suppresses discovery of nested skills entirely. Existing tests already establish that a nested SKILL.md defines a separate child skill whose files must not be attached to the parent, so the new test is asserting behavior that contradicts the current contract and would hide a real regression in get_skills().

Flagged Issues

  • The PR changes nested SKILL.md handling from 'discover both skills, but keep their files separate' to 'ignore the nested skill entirely'. That contradicts the existing contract in python/packages/core/tests/core/test_skills.py:1810-1845, where test_nested_skill_directory_not_crossed explicitly asserts both parent and child skills are discovered, and FileSkillsSource.get_skills() still sources its candidates from _discover_skill_directories() at python/packages/core/agent_framework/_skills.py:2706.

Automated review by giles17's agents

@giles17 giles17 closed this Jul 1, 2026
Removing the SKILL.md subdirectory skip in resource and script scanning so that content beneath a skill boundary is attached to that skill, and update the discovery docstring and the nested-skill test to match. Complements the discovery early-return so a nested SKILL.md is never treated as an independent skill root.
@giles17 giles17 reopened this Jul 1, 2026
@giles17 giles17 marked this pull request as draft July 1, 2026 06:39
@giles17 giles17 marked this pull request as ready for review July 1, 2026 06:39
@giles17 giles17 requested a review from Copilot July 1, 2026 06:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _skills.py10383896%313, 586, 1106, 1121, 1123–1124, 1491–1492, 1736, 1765, 2319, 2782–2783, 2880, 2888, 2893, 2896, 2901, 2921, 2933, 2938, 3033, 3041, 3046, 3049, 3054, 3074, 3083, 3088, 3354–3355, 3704, 3931–3932, 3959–3960, 3967–3968
TOTAL43138514488% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
8519 37 💤 0 ❌ 0 🔥 2m 11s ⏱️

@giles17 giles17 changed the title Python: Stop skill discovery below skill boundaries Python: Treat nested SKILL.md content as part of the parent skill Jul 1, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 5 | Confidence: 94% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Failure Modes, Design Approach


Automated review by giles17's agents

@giles17 giles17 added the breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible label Jul 1, 2026
@giles17 giles17 changed the title Python: Treat nested SKILL.md content as part of the parent skill Python: [BREAKING] Treat nested SKILL.md content as part of the parent skill Jul 1, 2026
@giles17 giles17 added this pull request to the merge queue Jul 1, 2026
Merged via the queue into microsoft:main with commit effbd17 Jul 1, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Skill directory search should stop recursing after finding SKILL.md

4 participants