---
name: map-learn
description: >-
  Capture reusable lessons after a completed MAP workflow. Use when a MAP
  run has finished and you want rules written to
  `.claude/rules/learned/` from a workflow summary or handoff. Do NOT use
  during active implementation.
effort: medium
disable-model-invocation: true
argument-hint: "[workflow-summary]"
---

# MAP Learn - Post-Workflow Learning with Persistence

**Purpose:** Extract lessons AFTER completing any MAP workflow and persist them to `.claude/rules/learned/` so Claude Code loads them automatically in future sessions.

**When to use:**
- After `/map-efficient` completes (to preserve patterns from the workflow)
- After `/map-debug` completes (to preserve debugging patterns)
- After `/map-review` or `/map-check` completes (to preserve review/verification patterns)
- After `/map-fast` completes (to retroactively add learning when learning was skipped)

**What it does:**
1. Reads existing learned rules (for deduplication)
2. Calls Reflector agent to analyze workflow outputs and extract patterns
3. Writes new lessons to `.claude/rules/learned/*.md` files
4. Outputs a structured learning summary

**Workflow Summary Input:** $ARGUMENTS

**Zero-argument mode:** If `$ARGUMENTS` is empty and `.map/<branch>/learning-handoff.md` exists, load that artifact automatically. If `$ARGUMENTS` is a readable file path, load the file contents and treat them as the workflow summary. Inline summary text still works when you want to override the artifact.

## Effort and Parallelism Policy

```yaml
thinking_policy: medium/adaptive
parallel_tool_policy: sequential_learning_write
```

- Use enough reasoning to distinguish reusable lessons from one-off noise, but do not re-review or re-implement the completed workflow.
- Keep Reflector analysis, rule-file updates, and learning-metrics recording sequential so deduplication and persistence stay coherent.
- Parallelize only independent reads of existing handoff, metrics, and learned-rule files before deciding what to write.

## Templates

Reference templates for the rules file format are bundled with this skill:
- [rules-unconditional.md](templates/rules-unconditional.md) — format for cross-cutting rules (security, architecture, errors) that load in every session
- [rules-with-paths.md](templates/rules-with-paths.md) — format for language-specific rules with `paths:` frontmatter scoping
- [example-rules.md](templates/example-rules.md) — real-world example showing Go controller lessons with code snippets

Use these templates when creating new rules files in Step 3. Copy the appropriate template structure, replace placeholders, and append bullets.

---

## IMPORTANT: This is an OPTIONAL step

**You are NOT required to run this command.** No MAP workflow includes automatic learning — learning is always a separate step via this command.

Use /map-learn when:
- You completed /map-efficient, /map-debug, /map-review, /map-check, or /map-fast and want to extract lessons
- You want to batch-learn from multiple workflows at once
- You want to manually trigger learning for custom workflows

**Do NOT use this command:**
- During active workflow execution (run after workflow completes)
- If no meaningful patterns emerged from the workflow

---

## Step 1: Validate Input

Resolve the workflow summary before validating input:

1. If `$ARGUMENTS` is empty, look for `.map/<branch>/learning-handoff.md`
2. If `$ARGUMENTS` looks like a file path, read that file
3. Otherwise treat `$ARGUMENTS` as inline workflow summary text

If a branch-scoped learning handoff exists, prefer it over asking the user to reconstruct the workflow from memory.

Track the resolved summary source for Step 4:

- `auto-handoff` if zero-argument mode loaded `.map/<branch>/learning-handoff.md`
- `file-handoff` if `$ARGUMENTS` resolved by reading a file path
- `inline-summary` if the user supplied summary text directly

Do not record consumption yet. Only record it after `/map-learn` finishes successfully.

Check that the resolved workflow summary contains:

**Required information:**
- Workflow type (feature, debug, refactor, review, custom)
- Subtask outputs (Actor implementations)
- Validation results (Monitor feedback)
- Analysis results (Predictor/Evaluator outputs, if available)
- Workflow metrics (total subtasks, iterations, files changed)

**If no summary can be resolved:** Ask the user for a workflow summary before proceeding.

---

## Step 2: Read Existing Rules and Call Reflector

### Step 2a: Gather existing lessons for deduplication

Before calling the Reflector, read all existing `.claude/rules/learned/*.md` files (excluding README.md). Extract the bullet points from each file.

```bash
ls .claude/rules/learned/*.md 2>/dev/null || echo "NO_EXISTING_RULES"
```

If files exist, read each one and collect all lines starting with `- **`. These are existing lessons that the Reflector should NOT duplicate.

### Step 2b: Call Reflector

**MUST use subagent_type="reflector"** (NOT general-purpose):

```
Task(
  subagent_type="reflector",
  description="Extract lessons from completed workflow",
  prompt="Extract structured lessons from this workflow:

**Workflow Summary:**
[resolved workflow summary from Step 1]

**Existing learned rules (do NOT duplicate these):**
[paste extracted bullets from Step 2a, or 'None — first learning session' if no files exist]

**Analysis Instructions:**

Analyze holistically across ALL subtasks:
- What patterns emerged consistently?
- What worked well that should be repeated?
- What could be improved for future similar tasks?
- What knowledge should be preserved?
- What trade-offs were made and why?

**Focus areas:**
- Implementation patterns (code structure, design decisions)
- Security patterns (auth, validation, error handling)
- Testing patterns (edge cases, test structure)
- Performance patterns (optimization, resource usage)
- Error patterns (what went wrong, how it was fixed)
- Architecture patterns (system design, component boundaries)

**IMPORTANT:** Do NOT repeat any pattern from the 'Existing learned rules' list above.
Only suggest genuinely new patterns not already captured.

JSON contract reference: [Learning Summary](../../references/map-json-output-contracts.md#learning-summary).

**Output JSON with:**
- key_insight: string (one sentence takeaway in 'When X, always Y because Z' format)
- patterns_used: array of strings (existing patterns applied successfully)
- patterns_discovered: array of strings (new patterns worth preserving)
- suggested_new_bullets: array of {section, title, content, code_example, rationale}
  where section is one of: SECURITY_PATTERNS, IMPLEMENTATION_PATTERNS, PERFORMANCE_PATTERNS,
  ERROR_PATTERNS, ARCHITECTURE_PATTERNS, TESTING_STRATEGIES
- workflow_efficiency: {total_iterations, avg_per_subtask, bottlenecks: array of strings}"
)
```

---

## Step 3: Write Rules Files

Transform Reflector output into `.claude/rules/learned/` markdown files.

**Use the bundled templates** from `${CLAUDE_SKILL_DIR}/templates/` as the format reference:
- `rules-unconditional.md` for sections without `paths:` frontmatter
- `rules-with-paths.md` for language-scoped sections
- `example-rules.md` for bullet format with code snippets

### Section-to-file mapping

| Reflector section | File | `paths:` frontmatter |
|---|---|---|
| `SECURITY_PATTERNS` | `security-patterns.md` | None (loads always) |
| `IMPLEMENTATION_PATTERNS` | `implementation-patterns.md` | Derived from file extensions in workflow |
| `PERFORMANCE_PATTERNS` | `performance-patterns.md` | Derived from file extensions in workflow |
| `ERROR_PATTERNS` | `error-patterns.md` | None (loads always) |
| `ARCHITECTURE_PATTERNS` | `architecture-patterns.md` | None (loads always) |
| `TESTING_STRATEGIES` | `testing-strategies.md` | `["**/test_*", "**/tests/**", "**/*_test.*", "**/*.test.*"]` |

### Deriving `paths:` frontmatter

For `IMPLEMENTATION_PATTERNS` and `PERFORMANCE_PATTERNS`:
1. Extract file extensions from the workflow summary (e.g., `.py`, `.go`, `.ts`)
2. Generate glob patterns: `.py` → `["**/*.py"]`, `.go` → `["**/*.go"]`
3. If no extensions found or multiple languages, omit `paths:` (unconditional loading)

### Writing each file

For each `suggested_new_bullet` from the Reflector:

1. **Determine target file** from the section mapping above.

2. **If file does NOT exist**, create it using the template from `${CLAUDE_SKILL_DIR}/templates/`:
   - Use `rules-with-paths.md` template for sections with path scoping
   - Use `rules-unconditional.md` template for cross-cutting sections
   - Replace `{SECTION_TITLE}` with the human-readable section name
   - Replace `{EXT}` with the derived extension glob

3. **Append the bullet** to the file:

```markdown
- **{title}** ({YYYY-MM-DD}): {content} [workflow: {workflow_type}]
```

If `code_example` is present, add it indented below (see `example-rules.md` for format):

```markdown
- **{title}** ({YYYY-MM-DD}): {content} [workflow: {workflow_type}]
  ```{language}
  {code_example}
  ```
```

4. **Also write `key_insight`** from the top-level Reflector output as a bullet in the most relevant section file. Use section `IMPLEMENTATION_PATTERNS` as default if no better match.

### File size check

After writing, count bullets in each modified file. If any file exceeds 50 bullets, print a warning:

```
⚠ {filename} has {N} rules (recommended max: 50). Consider pruning old or low-value rules.
```

### Personal vs public write-time choice

When writing a NEW rule, choose the target layer at write time:

| Layer | Directory | Loaded by |
|---|---|---|
| **Public** (team-shared) | `.claude/rules/learned/<category>.md` | Claude Code on every session |
| **Personal** (user-local) | `.map/personal/rules/learned/<category>.md` | Active MAP workflows only (see D2 note below) |

Both layers use the **same 6-category → file mapping** from the table above and the **same bullet format**:

```markdown
- **{title}** ({YYYY-MM-DD}): {content} [workflow: {workflow_type}]
```

Only the directory prefix differs. Create the personal directory if it does not exist:

```bash
mkdir -p .map/personal/rules/learned
```

The `.map/personal/` tree is repo-global but gitignored (HC-1), keeping personal rules off version control.

**D2 limitation — personal rules inject only during active MAP workflows:** Unlike `.claude/rules/` files which Claude Code auto-loads on every session, personal rules under `.map/personal/rules/learned/` are injected only when an active MAP workflow is running (i.e., when `.map/<branch>/step_state.json` is present in the branch workspace). They are NOT available on every prompt outside a MAP workflow. This is an informed trade-off (E5): personal rules stay scoped to the workflow context where they are most relevant, but you will not see them in ad-hoc sessions.

### Promoting a personal rule to public

To share a personal rule with the team, **move** it from the personal layer to the public layer:

1. **Locate** the bullet in `.map/personal/rules/learned/<category>.md` (same category → file mapping).
2. **Check idempotency** — a rule is already present iff a bullet with the same exact bold-title token (the text between the leading `**...**` markers) exists in the target public file.
   - If the bold-title token is **not** found in the public file: insert the bullet into `.claude/rules/learned/<category>.md`.
   - If the bold-title token **is already** found in the public file: skip insertion (do not duplicate).
   - In **both** cases: remove the bullet from the personal file. Re-running promote never duplicates and always cleans up the personal copy.
3. **Result:** the rule is now in `.claude/rules/learned/<category>.md` and no longer in `.map/personal/rules/learned/<category>.md`.

---

## Step 4: Summary Report

Before printing the completion summary, record learning-usage metrics with the source you resolved in Step 1:

- Zero-argument handoff: `python .map/scripts/map_step_runner.py record_learning_consumption auto-handoff`
- File-backed summary: `python .map/scripts/map_step_runner.py record_learning_consumption file-handoff`
- Inline summary text: `python .map/scripts/map_step_runner.py record_learning_consumption inline-summary "<workflow-type-if-known>"`

Use the exact source that produced the resolved workflow summary. Do not downgrade an auto-loaded handoff to `inline-summary` just because the content is now in memory.

Print the learning summary:

```markdown
## /map-learn Completion Summary

**Workflow Analyzed:** [workflow type from input]
**Total Subtasks:** [N]

### Rules Written to .claude/rules/learned/
[For each file written:]
- {filename}: +{N} rules ({action: 'new file created' | 'appended'})
[If duplicates were skipped:]
- Duplicates skipped: {N}

### Reflector Insights
- **Key Insight:** [key_insight]
- **Patterns Applied:** [count] existing patterns used successfully
- **Patterns Discovered:** [count] new patterns identified

### Workflow Efficiency
- **Total Iterations:** [total_iterations]
- **Average per Subtask:** [avg_per_subtask]
- **Bottlenecks:** [list bottlenecks]

### Next Steps
- Review written rules: open `.claude/rules/learned/` files
- Rules will auto-load in next Claude Code session
- Commit to share with team: `git add .claude/rules/`

**Learning extraction and persistence complete.**
```

---

## Token Budget Estimate

**Typical /map-learn execution:**
- Read existing rules: ~500 tokens
- Reflector: ~3K tokens (depends on workflow size)
- Write rules + summary: ~1K tokens
- **Total:** 4-5K tokens for standard workflow

**Large workflow (8+ subtasks):**
- Read existing rules: ~1K tokens
- Reflector: ~6K tokens
- Write rules + summary: ~2K tokens
- **Total:** 8-9K tokens

---

## Examples

### Example 1: First learning session (no existing rules)

```
User: /map-learn "Workflow: /map-efficient 'Add user authentication'
Subtasks: 3 (JWT setup, middleware, tests)
Files: api/auth.py, middleware/jwt.py, tests/test_auth.py
Iterations: 5

Key decisions:
- Used PyJWT with RS256
- Middleware validates on every request
- Refresh token rotation implemented"
```

Result: Creates `.claude/rules/learned/security-patterns.md` and `implementation-patterns.md` with new rules.

### Example 2: Second learning session (deduplication)

```
User: /map-learn "Workflow: /map-efficient 'Add API rate limiting'
Subtasks: 2 (rate limiter, tests)
Files: middleware/rate_limit.py, tests/test_rate_limit.py
Iterations: 3"
```

Reflector sees existing JWT/auth patterns in `security-patterns.md`, does NOT duplicate them, only adds new rate-limiting patterns.

### Example 3: Batched learning

```
User: /map-learn "Workflows: 3 debugging sessions this week
Session 1: Race condition in payment processing → DB transaction locks
Session 2: Memory leak in WebSocket → connection pooling
Session 3: Timezone bug in scheduler → always UTC internally"
```

Result: Appends patterns across multiple topic files.

---

## Integration with Other Commands

### After /map-efficient (recommended)
/map-efficient prints: "Optional: Run /map-learn to preserve patterns."

### After /map-debug (recommended)
Preserves debugging patterns and root cause analysis approaches.

### After /map-fast (optional)
Only if the work revealed patterns worth preserving.

---

## Troubleshooting

**No `.claude/rules/learned/` directory:** Run `mapify init` or create it manually: `mkdir -p .claude/rules/learned`

**Rules not loading in next session:** Verify files are `.md` format in `.claude/rules/learned/`. Check that `paths:` frontmatter globs match your file structure. Run `/memory` to see loaded rules.

**Too many rules (>50 per file):** Prune outdated lessons. Remove rules that no longer apply or are too project-specific. Keep only patterns that prevent real mistakes.

**Duplicate rules appearing:** Ensure Step 2a reads existing rules before calling Reflector. If duplicates persist, manually remove them — the deduplication is LLM-based and not perfect.

**Reflector returns empty results:** Provide more detail in the workflow summary. Include specific files changed, iterations, and key decisions.

---

## Final Notes

**This command is OPTIONAL.** You are not required to run it after every workflow.

**Where rules are stored:** `.claude/rules/learned/` — committed with the project, shared with team, auto-loaded by Claude Code.

**Rules are yours to edit.** Add context, fix inaccuracies, prune outdated patterns. They are project knowledge, not framework artifacts.

**Goal:** Each `/map-learn` invocation makes the next session stronger. If you're still explaining the same gotchas to Claude after running `/map-learn`, the rules need to be more specific.
