Skip to content

feat: scope learned rules by path_glob — filter before Actor context and personal-rules injection#293

Merged
azalio merged 1 commit into
mainfrom
feat/280-scoped-learned-rules
Jun 26, 2026
Merged

feat: scope learned rules by path_glob — filter before Actor context and personal-rules injection#293
azalio merged 1 commit into
mainfrom
feat/280-scoped-learned-rules

Conversation

@azalio

@azalio azalio commented Jun 26, 2026

Copy link
Copy Markdown
Owner

What changed

Path-scoped filtering for learned rules — rules with paths: frontmatter are now only loaded when the agent is working on matching files. This saves context budget and prevents irrelevant rules from leaking into unrelated modules.

1. build_context_block() in map_step_runner.py

  • Added _filter_learned_rules_by_files() — rules with paths: frontmatter are only included when the subtask affected_files match at least one path glob. Rules without paths: are always included (unconditional).
  • Added _format_learned_rules_block() — compact <learned_rules> XML block injected into <map_context> for Actor consumption.
  • Empty affected_files → all rules included (cannot safely exclude without file context).

2. workflow-context-injector.py (personal rules)

  • Added _parse_rule_paths() + _paths_match_file() + _extract_target_file() — personal rules from .map/personal/rules/learned/ are filtered by paths: frontmatter against the current tool target file (Edit/Write/MultiEdit).
  • Unconditional rules (no paths:) are always loaded. Bash commands skip filtering (cannot reliably determine target files).

Why

Aligns MAP with Claude Code .claude/rules/ path-scoped behavior and the industry-standard hierarchical rule loading pattern (Stripe, Anthropic, IBM).

How tested

  • make check: pyright 0, ruff clean, mypy clean, hook lint clean, render check passes
  • 2843 tests passed, 0 failures

Closes #280

🤖 Generated with Claude Code

…and personal-rules injection (#280)

- Added _filter_learned_rules_by_files() to map_step_runner.py:
  rules with paths: frontmatter are only included in build_context_block()
  when the subtask affected_files match at least one path glob. Rules
  without paths: are always included (unconditional).

- Added _format_learned_rules_block() to format applicable rules as a
  compact <learned_rules> XML block inside <map_context>.

- Added _parse_rule_paths() + _paths_match_file() + _extract_target_file()
  to workflow-context-injector.py: personal rules from
  .map/personal/rules/learned/ are now filtered by paths: frontmatter
  against the current tool target file (Edit/Write/MultiEdit). Files
  without paths: are always loaded; Bash commands skip filtering.

- Aligns MAP with Claude Code .claude/rules/ path-scoped behavior
  and the industry-standard hierarchical rule loading pattern (Stripe,
  Anthropic, IBM). Saves context budget by not loading irrelevant rules.

Closes #280
@azalio azalio merged commit 7fa1a11 into main Jun 26, 2026
6 checks passed
@azalio azalio deleted the feat/280-scoped-learned-rules branch June 26, 2026 20:16
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.

Scope learned rules by module/path — hierarchical rule loading from agentic engineering model

1 participant