Fix: compilation.exclude does not filter primitive discovery#477
Conversation
Agent-Logs-Url: https://github.com/microsoft/apm/sessions/6aae940e-6c6a-40f5-9f06-994570e01fa7 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
Propagate exclude patterns from CompilationConfig to the primitive discovery phase so that .instructions.md files (and other primitives) inside excluded directories are never discovered or compiled. Fixes #464 Agent-Logs-Url: https://github.com/microsoft/apm/sessions/6aae940e-6c6a-40f5-9f06-994570e01fa7 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
|
Tested, and it works :). Thank you. |
There was a problem hiding this comment.
Pull request overview
Fixes a gap where compilation.exclude patterns were only applied during context optimization, not during primitive discovery, allowing excluded .instructions.md files to be discovered and compiled.
Changes:
- Thread
exclude_patternsthrough primitive discovery entry points and apply filtering before parsing discovered files. - Propagate
CompilationConfig.excludeinto both discovery paths inAgentsCompiler. - Add unit tests to cover exclusion behavior for local scanning and both discovery entry points.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Updates editable project version metadata to 0.8.6. |
| src/apm_cli/primitives/discovery.py | Adds exclude-aware discovery helpers and wires exclude filtering into discovery/scan flows. |
| src/apm_cli/compilation/agents_compiler.py | Passes config.exclude into discovery functions for both local-only and dependency-aware compilation. |
| tests/unit/primitives/test_discovery_parser.py | Adds tests validating exclusion behavior across discovery APIs. |
| tests/unit/compilation/test_agents_compiler_coverage.py | Updates mock assertion for the new discovery call signature. |
| CHANGELOG.md | Adds an Unreleased fix entry for exclude filtering during discovery. |
Copilot's findings
- Files reviewed: 5/6 changed files
- Comments generated: 4
| ### Fixed | ||
|
|
||
| - `compilation.exclude` patterns now filter primitive discovery, preventing `.instructions.md` files in excluded directories from leaking into compiled output (#464) |
There was a problem hiding this comment.
| try: | ||
| rel_path = file_path.resolve().relative_to(base_dir.resolve()) | ||
| except ValueError: | ||
| return False | ||
|
|
||
| rel_path_str = rel_path.as_posix() | ||
|
|
There was a problem hiding this comment.
_should_exclude_file() uses Path.resolve().relative_to() but only catches ValueError. On Windows (and some CI setups) resolve()/relative_to() can also raise OSError/RuntimeError (e.g., 8.3 short-name mismatches). Consider using utils.paths.portable_relpath() or expanding the exception handling so exclude filtering does not crash discovery.
| # Find and parse files for each primitive type | ||
| for primitive_type, patterns in LOCAL_PRIMITIVE_PATTERNS.items(): | ||
| files = find_primitive_files(base_dir, patterns) | ||
|
|
||
| for file_path in files: | ||
| if _should_exclude_file(file_path, base_path, exclude_patterns): | ||
| continue |
There was a problem hiding this comment.
discover_primitives() is used for --local-only ("Ignore dependencies"), but it does not filter out files under apm_modules/. Because LOCAL_PRIMITIVE_PATTERNS includes recursive "/.apm/..." and "/*.instructions.md" patterns, primitives from installed dependencies can still be discovered in local-only mode. Consider applying the same apm_modules exclusion used in scan_local_primitives(), or refactoring local-only discovery to reuse scan_local_primitives().
…erage - Extract duplicated glob matcher from discovery.py and context_optimizer.py into shared src/apm_cli/utils/exclude.py - Add validate_exclude_patterns() with consecutive ** collapse and segment cap (max 5 non-consecutive) to prevent exponential recursion DoS - Cover _discover_local_skill() with exclusion filtering (was bypassed) - Add debug logging for excluded files - Add 34 tests for shared exclude util (validation, matching, DoS guard) - Add SKILL.md exclusion and DoS validation tests to discovery tests - Revert uv.lock version bump artifact - Net -160 lines from deduplication Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial plan * Initial plan for compilation.exclude primitive discovery fix Agent-Logs-Url: https://github.com/microsoft/apm/sessions/6aae940e-6c6a-40f5-9f06-994570e01fa7 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * fix: compilation.exclude patterns now filter primitive discovery Propagate exclude patterns from CompilationConfig to the primitive discovery phase so that .instructions.md files (and other primitives) inside excluded directories are never discovered or compiled. Fixes #464 Agent-Logs-Url: https://github.com/microsoft/apm/sessions/6aae940e-6c6a-40f5-9f06-994570e01fa7 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * refactor: extract shared exclude matcher, add DoS guard, complete coverage - Extract duplicated glob matcher from discovery.py and context_optimizer.py into shared src/apm_cli/utils/exclude.py - Add validate_exclude_patterns() with consecutive ** collapse and segment cap (max 5 non-consecutive) to prevent exponential recursion DoS - Cover _discover_local_skill() with exclusion filtering (was bypassed) - Add debug logging for excluded files - Add 34 tests for shared exclude util (validation, matching, DoS guard) - Add SKILL.md exclusion and DoS validation tests to discovery tests - Revert uv.lock version bump artifact - Net -160 lines from deduplication Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> Co-authored-by: danielmeppiel <dmeppiel@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
compilation.excludepatterns were only applied during context optimization (directory scanning/placement), not during primitive discovery. This caused.instructions.mdfiles in excluded directories to leak into compiled output.Files under
docs/were still discovered, parsed, and compiled into AGENTS.md/CLAUDE.md.Changes:
discovery.py: Addedexclude_patternsparameter todiscover_primitives(),discover_primitives_with_dependencies(), andscan_local_primitives()with glob matching helpers (**support, cross-platform path normalization)agents_compiler.py: Passesconfig.excludeto both discovery code pathsType of change
Testing
⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.