learn-from-fix
Capture Elixir/Ecto/LiveView lessons and Hex API rules. Use after corrections or when asked to document learning, record a lesson, prevent a fixed mistake, or remember package guidance with --library.
git clone --depth 1 https://github.com/oliver-kriska/claude-elixir-phoenix /tmp/learn-from-fix && cp -r /tmp/learn-from-fix/plugins/elixir-phoenix/skills/learn-from-fix ~/.claude/skills/learn-from-fixSKILL.md
# Learn From Fix
After fixing a bug or receiving a correction, capture the lesson
to prevent future mistakes.
## Usage
```
/phx:learn-from-fix Fixed N+1 query in user listing - was missing preload
/phx:learn-from-fix String vs atom key mismatch in params handling
/phx:learn-from-fix LiveView assign_async needs render_async in tests
/phx:learn-from-fix --library ical --scope personal ICal.to_ics output needs CRLF line endings
/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 `/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 <package>` 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-<package>/SKILL.md` and
`.claude/skills/hex-<package>/SKILL.md`
- Read `${CLAUDE_SKILL_DIR}/references/common-mistakes.md` (READ-ONLY plugin
reference — do NOT edit this file)
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
**CRITICAL: NEVER edit plugin files.** 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-<package>/SKILL.md` |
| `project` | `.claude/skills/hex-<package>/SKILL.md` |
Personal skills override same-named project skills. If a personal
`hex-<package>` 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-<package>
description: <Package/module/API/task trigger terms for this knowledge>
user-invocable: false
---
# <Package> Knowledge
## Verified Rules
- **<Rule>** (verified with <package> <version>): <actionable guidance>
```
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 `/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]
```|
|
Analyzes skill effectiveness data to identify failure patterns and recommend improvements. Use after /skill-monitor flags underperforming skills.
Run ad-hoc PostgreSQL analytics queries against dev/test database
Analyze Elixir/Phoenix technical debt — duplicates, refactoring opportunities, credo issues. Use when asked about code quality, cleanup, or what to improve.
|
|
Guide plugin development workflow — editing skills, agents, hooks, or eval framework in this repo. Use when modifying files in plugins/elixir-phoenix/, lab/eval/, or lab/autoresearch/. Ensures changes pass eval, lint, and tests before committing.