| name | opi |
| description | Extract learnings from recent git commits, current conversation, and security reviews.
Captures both reactive fixes (what went wrong) and preventive patterns (what to always do).
Routes AND fans out each learning to EVERY relevant skill — one canonical entry plus
lightweight pointers in each affected skill's learnings.md — so the learning surfaces no
matter which skill a future Claude session triggers.
Use for: "/opi" or "opi", "what did we learn?", extract/update learnings,
end-of-session reflection, after a security review/audit, or after creating
reusable components/patterns other skills should know about.
Triggers: "opi", "learn", "oppia", "mitä opittiin", "extract learnings", "add learning"
|
Opi - Learning Extractor
Extract learnings from recent work to improve future Claude sessions. Captures two types:
- Reactive — What went wrong and how it was fixed (bugs, corrections, failed attempts)
- Preventive — Reusable patterns that prevent future problems (safe components, conventions, security defaults)
Workflow
Step 1: Gather Sources
git log --oneline -20
git log --since="midnight" --format="%h %s"
git log --oneline -50 | grep -iE "(fix|korja|refactor|bugfix|secur|safe|harden)"
Also check:
- Current conversation for corrections, discoveries, new patterns
- Recent security reviews or audit results
- New reusable components or utilities created this session
Step 2: Classify Each Finding
For each potential learning, determine the type:
| Type | Signal | Example |
|---|
| Reactive fix | Bug fixed, user corrected, test failed | "useEffect infinite loop — wrap in useCallback" |
| Preventive pattern | New convention, safe default, reusable component | "Use SafeTextarea for user-facing text inputs" |
| Security hardening | Vulnerability found, RLS gap, input validation | "Always enforce maxLength on text inputs" |
| Anti-pattern | Repeatedly wrong approach discovered | "Don't use bare Textarea without maxLength" |
Step 3: Route AND Fan Out
A learning is useless if it only lives where the bug happened — a future
session usually triggers a different skill. So every learning gets one
canonical home plus lightweight pointers in every other skill it touches.
See references/learnings-router.md for the
full routing table and the fan-out procedure.
Step 3a — Pick the canonical home. One destination, where the full
wrong/right detail lives:
| Learning Domain | Canonical Home |
|---|
| React/TypeScript, Supabase/DB, CSS, i18n | .claude/LEARNINGS.md |
| Security patterns, input validation | .claude/LEARNINGS.md (Security section) |
| CI/CD | ci-doctor/references/learnings.md |
| Lint/formatting | lint-fixer/references/learnings.md |
| Tests | test-writer/references/learnings.md |
| Security audits, RLS | security-auditor/references/learnings.md |
| Supabase migrations | supabase-migration-writer/references/learnings.md |
| Other skill-specific | [skill]/references/learnings.md |
Prefer global .claude/LEARNINGS.md when the learning is cross-cutting —
it's better visible everywhere than hidden in one skill.
Step 3b — Fan out pointers. Identify every other skill a future
session might be in when this learning matters:
- Open
Docs/context/skills-map.md and scan the Trigger Keywords table.
Any skill whose triggers overlap the learning's domain is a fan-out target
(e.g. a lazy-load bug → performance-auditor, cinema-voice-architect,
any skill that renders summaries).
- In each target skill's
references/learnings.md, add one line under a
## Pointers section — never duplicate the full entry (duplication drifts):
- **[Short title]:** see canonical entry in `.claude/LEARNINGS.md#anchor`
- Create a missing
references/learnings.md from
skill-creator/assets/learnings-template.md, then verify the receiving
skill's SKILL.md actually links it (add a line if not — an unreferenced
learnings.md is never read).
Step 4: Format Learnings
Reactive fix format:
### [Issue Title]
- **Pattern:** What triggers this mistake
- **Wrong:** ❌ The incorrect approach
- **Right:** ✅ The correct approach
- **Why:** Root cause
Preventive pattern format:
### [Convention Title]
- **Rule:** Always do X when Y
- **Wrong:** ❌ The old/unsafe way
- **Right:** ✅ The new/safe way
- **Why:** What this prevents
- **Since:** date or commit ref
Recent Corrections table row:
| Date | Issue | Fix | Applies To |
Step 5: Propose & Write
- Present each proposed learning with its canonical home and the list of
fan-out skills (from Step 3b)
- User approves/rejects each
- Write the full entry to the canonical file, then add one-line pointers to
each fan-out skill's
references/learnings.md
- Commit changes
Learning Quality Criteria
Only propose learnings that are:
- Non-obvious — Claude wouldn't know without being told
- Actionable — Concrete wrong/right examples, not vague advice
- Recurring — Likely to come up again in this codebase
- Preventive OR Corrective — Either prevents future bugs or fixes repeated mistakes
Skip: Typo fixes, one-off configs, project-specific constants, things Claude already knows.
Preventive Patterns to Watch For
When analyzing commits, specifically look for these signals that indicate a preventive learning:
| Signal in Commit | Learning Type |
|---|
| New reusable component created | "Always use X instead of Y" convention |
| Security hardening (maxLength, validation, RLS) | Security default rule |
feat(security): or fix(security): prefix | Security learning |
| Wrapper/helper replacing bare primitive | Anti-pattern (bare primitive) + convention (use wrapper) |
| Migration adding constraints/checks | DB convention |
| New utility extracted from repeated code | "Use X utility" convention |
Commands Reference
git log --since="2025-01-10" --oneline
git log --all --oneline | grep -i "fix"
git show <hash> --name-only
git diff <hash>^..<hash>
git log --oneline -50 | grep -iE "(secur|rls|grant|xss|valid|sanitiz|safe|harden)"