--- name: phx-learn-from-fix description: Capture Elixir/Ecto/LiveView lessons and Hex API rules. Use after corrections or when asked to document learning… --- # Learn From Fix After fixing a bug or receiving a correction, capture the lesson to prevent future mistakes. ## Usage ``` $elixir-phoenix:phx-learn-from-fix Fixed N+1 query in user listing - was missing preload $elixir-phoenix:phx-learn-from-fix String vs atom key mismatch in params handling $elixir-phoenix:phx-learn-from-fix LiveView assign_async needs render_async in tests $elixir-phoenix:phx-learn-from-fix --library ical --scope personal ICal.to_ics output needs CRLF line endings $elixir-phoenix:phx-learn-from-fix --library ical --scope project Use method: "PUBLISH" for calendar feeds ``` ## Workflow ### Step 1: Verify the Lesson Persist only one of: - A completed fix verified by tests, reproduction, or user confirmation - An explicit rule the user taught or asked to save Stop without writing if neither condition is met. Do not save a hypothesis, unverified workaround, investigation narrative, or unsolved error. Use `$elixir-phoenix:phx-compound` for a detailed completed investigation. Capture the root cause as a concise actionable rule, not the symptom. ### Step 2: Select the Route When both `--library ` and `--scope personal|project` are present, use the [Library Route](#library-route). Require both flags; do not guess scope. For the skill directory only, trim surrounding whitespace and lowercase the package name. Preserve underscores when forming directory names (`phoenix_live_view` becomes `hex-phoenix_live_view`). Validate the normalized name against `^[a-z][a-z0-9_]+$`. If it does not match, ask for a valid Hex package identifier instead of replacing characters or inventing a name. Use the trimmed original identifier, not the normalized directory name, to look up `mix.lock`. Without `--library`, use the [General Correction Route](#general-correction-route). ### Step 3: Check Existing Knowledge Check if already documented: - Grep project CLAUDE.md and `~/.claude/CLAUDE.md` for the pattern keyword - Check auto-memory files for similar lessons - For library lessons, inspect both `~/.claude/skills/hex-/SKILL.md` and `.claude/skills/hex-/SKILL.md` - Read `references/common-mistakes.md` (read-only plugin reference) Do not duplicate the same lesson across CLAUDE.md, memory, and a package skill. If the same rule exists, merge wording or report it as already captured. ## Library Route Plugin files are read-only: files under `~/.claude/plugins/` are cached and get overwritten on updates. Package skills are user-owned files, never plugin cache files. ### Resolve Scope and Precedence | `--scope` | Canonical destination | |-----------|-----------------------| | `personal` | `~/.claude/skills/hex-/SKILL.md` | | `project` | `.claude/skills/hex-/SKILL.md` | Personal skills override same-named project skills. If a personal `hex-` skill exists, never unknowingly create or update a shadowed project skill: explain the conflict and ask whether to update personal scope or keep distinct project-only knowledge. If project scope already exists before a personal write, warn that the new skill will shadow it and offer to merge or move it. Maintain one canonical skill per package unless the user explicitly needs distinct scope-specific rules; never create one skill per lesson. ### Read the Locked Version Inspect `mix.lock` for the package. Record the exact locked version when found. If it is absent, say the lesson is not tied to a locally locked version and do not invent one. Qualify version-sensitive rules. When two verified rules conflict across versions, preserve both with explicit version ranges instead of replacing either. ### Create or Safely Update the Skill For a new package skill, create: ```markdown --- name: hex- description: user-invocable: false --- # Knowledge ## Verified Rules - **** (verified with ): ``` Make the description precise: include the Hex package, Elixir module names, important APIs/file formats, and tasks that should trigger this knowledge. Activation is model-selected from this description; package presence in `mix.lock` does not guarantee activation. Before updating an existing skill, read all of it. Preserve unrelated and hand-authored sections. Merge semantically identical rules. If safe merging is unclear, show the conflict and ask instead of overwriting content. Do not add `paths:` to a personal package skill by default: it is a file-path activation gate, not a dependency predicate. Add `paths:` only to project scope when explicitly appropriate and meaningful package-specific paths exist. ## General Correction Route Choose the narrowest non-library destination: | Scope | Write to | Example | |-------|----------|---------| | This project | Project CLAUDE.md | "Never use raw SQL in this app" | | This project across sessions | Project-keyed auto-memory | "jsonb uses string keys" | | All your projects | `~/.claude/CLAUDE.md` personal instructions | "Prefer explicit error tuples" | | Detailed completed fix | `.claude/solutions/` via `$elixir-phoenix:phx-compound` | Debugging narrative | For project or personal instructions, preserve existing content and append `**RULE NAME** — Do NOT [bad]. Instead [good]` under the relevant category. Use personal instructions only for rules that should load in every project. For auto-memory, append to the project-keyed `~/.claude/projects/{project-hash}/memory/MEMORY.md`: ```markdown ### Lesson: [Title] - **Pattern**: Do NOT [bad] — instead [good] - **Why**: [root cause explanation] ``` If the lesson is universal to the plugin rather than one project or package, suggest a plugin contribution; never write it into cached plugin files. ## Output After capturing, confirm: ```text Lesson captured in [location] Pattern: Do NOT [bad pattern] — instead [good pattern] Category: [Ecto/LiveView/OTP/Testing/etc] Version: [locked package version, not found, or not applicable] ``` For package skills, also state that description-based activation is model-selected, not guaranteed by `mix.lock`. ## Iron Laws 1. **NEVER write generated knowledge to plugin cache** — use only the user-owned destinations above 2. **DO NOT duplicate existing lessons** — always check CLAUDE.md and memory before writing 3. **NEVER overwrite hand-authored content** — read both package skill scopes and merge safely 4. **ONLY persist verified knowledge** — completed fixes or explicit user-taught rules, never hypotheses 5. **DISCLOSE scope precedence** — a global package skill shadows its project counterpart ## References (READ-ONLY — do NOT edit) - `references/common-mistakes.md` — Common Elixir mistakes reference. Consult when checking for duplicates.