Skip to content

Fix: compilation.exclude does not filter primitive discovery#477

Merged
danielmeppiel merged 5 commits intomainfrom
copilot/fix-primitive-discovery-exclusion
Apr 6, 2026
Merged

Fix: compilation.exclude does not filter primitive discovery#477
danielmeppiel merged 5 commits intomainfrom
copilot/fix-primitive-discovery-exclusion

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 27, 2026

Description

compilation.exclude patterns were only applied during context optimization (directory scanning/placement), not during primitive discovery. This caused .instructions.md files in excluded directories to leak into compiled output.

# apm.yml
compilation:
  exclude:
    - "docs/**"

Files under docs/ were still discovered, parsed, and compiled into AGENTS.md/CLAUDE.md.

Changes:

  • discovery.py: Added exclude_patterns parameter to discover_primitives(), discover_primitives_with_dependencies(), and scan_local_primitives() with glob matching helpers (** support, cross-platform path normalization)
  • agents_compiler.py: Passes config.exclude to both discovery code paths
  • 5 new tests covering single/multiple exclude patterns across both discovery entry points

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality (if applicable)

⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

Copilot AI and others added 2 commits March 27, 2026 11:54
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>
Copilot AI changed the title [WIP] Fix compilation.exclude to filter primitive discovery Fix: compilation.exclude does not filter primitive discovery Mar 27, 2026
Copilot AI requested a review from danielmeppiel March 27, 2026 12:01
@Coolomina
Copy link
Copy Markdown
Contributor

Tested, and it works :). Thank you.

@danielmeppiel danielmeppiel marked this pull request as ready for review April 6, 2026 20:14
Copilot AI review requested due to automatic review settings April 6, 2026 20:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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_patterns through primitive discovery entry points and apply filtering before parsing discovered files.
  • Propagate CompilationConfig.exclude into both discovery paths in AgentsCompiler.
  • 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

CHANGELOG.md Outdated
Comment on lines +11 to +13
### Fixed

- `compilation.exclude` patterns now filter primitive discovery, preventing `.instructions.md` files in excluded directories from leaking into compiled output (#464)
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

CHANGELOG entry ends with (#464), but this PR is #477 (per PR metadata). Keep-a-Changelog convention in this repo is one line per PR ending with the PR number; please update the reference to the correct PR number (or include the correct set if intentionally grouped).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +201 to +207
try:
rel_path = file_path.resolve().relative_to(base_dir.resolve())
except ValueError:
return False

rel_path_str = rel_path.as_posix()

Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

_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.

Copilot uses AI. Check for mistakes.
Comment on lines 75 to +81
# 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
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

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().

Copilot uses AI. Check for mistakes.
danielmeppiel and others added 2 commits April 6, 2026 22:26
…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>
@danielmeppiel danielmeppiel merged commit 3203104 into main Apr 6, 2026
6 checks passed
@danielmeppiel danielmeppiel deleted the copilot/fix-primitive-discovery-exclusion branch April 6, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] compilation.exclude does not filter primitive discovery

4 participants