Entry/Exit
- Entry: Learning entries added manually or collected automatically by skills
- Exit:
.claude/learnings.jsonl - Points to: Other skills call this skill at key points to record learnings
- Preload: CANON.md
- Output path: After recording a learning, return to
maintain-workflow-using-unifiedor the original calling skill
When not to use
- It is only a one-off task detail with no cross-session reuse value
- The information is unverified, or is only a temporary guess
- The user explicitly requests not to write to memory or project learning records
Storage
File:.claude/learnings.jsonl(project-level, must be added to .gitignore)
One JSON object per line, appended:
{"type":"pitfall","key":"orm-n+1-query","insight":"User.list() 默认加载关联,列表接口必须用 .select() 限制字段","confidence":8,"files":["src/services/user.service.ts"],"source":"manual","ts":"2026-04-24T14:30:52+08:00"}
Format
| Field | Type | Description |
|---|---|---|
type |
Enum | pattern / pitfall / preference / architecture |
key |
String | Unique identifier, kebab-case. For the same key, later writes overwrite earlier writes (last-write-wins) |
insight |
String | One-sentence insight. Specific and actionable, not a vague description |
confidence |
Integer | 1-10. 10 = solid evidence, 1 = preliminary observation |
files |
List | Related file paths (may be an empty list) |
source |
Enum | auto(collected automatically by skills) / manual(added manually) |
ts |
ISO-8601 | Record time |
The four type types
| type | Purpose | Example |
|---|---|---|
pattern |
Verified pattern | "Use the Result type uniformly for error handling, not try/catch" |
pitfall |
Pitfall already hit | "Internal network services cannot be accessed in CI, so tests need mocks" |
preference |
Team preference | "Use the conventional commits format for commit messages" |
architecture |
Architectural constraint | "The event bus only allows async communication; synchronous calls are forbidden" |
Deduplication
For the same key, later writes overwrite earlier writes (last-write-wins).
# 去重方法:按 key 保留最后一条
tac .claude/learnings.jsonl | awk -F'"key":"' '!seen[$2]++' | tac > .claude/learnings.jsonl.tmp && mv .claude/learnings.jsonl.tmp .claude/learnings.jsonl
Subcommands
/learn (default)
Show the most recent 20 learnings, grouped by type:
Patterns (8):
[conf:9] api-error-handling → 统一用 Result 类型
[conf:7] pagination-cursor → 列表接口用游标分页
Pitfalls (5):
[conf:8] orm-n+1-query → User.list() 默认加载关联
[conf:6] ci-internal-access → CI 中不能访问内网服务
Preferences (4):
[conf:9] commit-convention → conventional commits 格式
Architecture (3):
[conf:10] event-bus-async-only → 事件总线只允许 async 通信
conf is the abbreviation for confidence. One line per entry.
/learn search <query>
Full-text search learnings.jsonl:
/learn search auth
Search for matches in the key and insight fields, highlighting matching lines.
/learn prune
Interactive cleanup:
- Staleness detection — Mark entries as stale if the referenced
filesno longer exists - Contradiction detection — Mark entries with the same key but different insights as contradictory
- Interactive confirmation — Display entries one by one, and the user chooses keep/delete/update
- Deduplication — Perform last-write-wins deduplication
/learn export
Export as markdown (grouped by type):
# Learnings
## Patterns
- **api-error-handling** (conf:9) — 统一用 Result 类型
Files: src/utils/result.ts
- **pagination-cursor** (conf:7) — 列表接口用游标分页
Files: src/middleware/pagination.ts
## Pitfalls
- **orm-n+1-query** (conf:8) — User.list() 默认加载关联
Files: src/services/user.service.ts
## Preferences
- **commit-convention** (conf:9) — conventional commits 格式
## Architecture
- **event-bus-async-only** (conf:10) — 事件总线只允许 async 通信
/learn add
Manual addition. Must specify type, key, insight, and confidence:
/learn add type:pitfall key:env-var-case insight:"环境变量用 UPPER_SNAKE_CASE,不用 camelCase" confidence:7 files:"config/env.ts"
If required fields are missing, refuse to write and show a prompt.files and ts are optional (ts defaults to the current time).
Automatic learning
Other skills call this skill at key moments to record learnings. Trigger scenarios:
| Scenario | Record type | Source skill |
|---|---|---|
| Debugging reveals root cause | pitfall |
verify-workflow-debug |
| Adopt a new implementation pattern | pattern |
build-workflow-execute |
| Confirm team preference | preference |
verify-workflow-review |
| Make an architecture decision | architecture |
build-cognitive-decision-record |
Automatically recorded source is auto, confidence defaults to 5 (pending verification). After manual review, confidence can be raised.
Common excuses
| Excuse | Reality | Consequence |
|---|---|---|
| "Recording learnings is useless" | The cost of repeatedly falling into the same pitfall far exceeds the recording cost. One pitfall that avoids one rework pays for itself. | Repeated pitfall ×3 times ×2 hours = 6 hours wasted; recording cost = 5 minutes |
| "Let the AI record it itself" | Automated collection is a supplement, not a replacement. Human judgment is more valuable—auto records need manual filtering and promotion. | auto all confidence=5 → low signal-to-noise ratio → valuable learnings get drowned out → prune cost ×3 |
| "JSONL format is too primitive" | Primitive = greppable, appendable, dependency-free. No database needed. | Introducing a database = new dependency + migration cost + maintenance burden; JSONL has zero dependencies |
| "confidence is subjective and unreliable" | Subjective but valuable. The difference between confidence 7 and 3 conveys the degree of certainty. Marking everything 10 is the real problem. | All marked 10 → cannot distinguish confirmed vs preliminary → high-confidence learnings have no priority → misleads decisions |
| "prune is too troublesome" | Not pruning is more troublesome—outdated and contradictory learnings are more dangerous than no learnings. | Outdated learnings mislead → implement according to a deprecated pattern → 2-4 hours of rework; prune only takes 10 minutes |
Red flags — STOP
learnings.jsonlexceeds 1000 entries — prune needed. 1000+ entries means outdated entries have not been cleaned up, and the signal-to-noise ratio declines.- confidence is all 10 — lack of self-doubt. All insights are "conclusive evidence"? Impossible. Check whether downweighting is needed.
- Large amount of
autosource, fewmanual— lack of manual filtering. The confidence of auto records defaults to 5 and needs manual review. - insight exceeds two sentences — too long. insight is a one-sentence insight, not a paragraph. Put long text in documents, with key pointing to the document.
- Missing files field — it is an empty list, but the field must exist. Learnings that reference files are 10 times more valuable than vague descriptions.
- key not in kebab-case — inconsistent naming causes deduplication to fail, and multiple variants of the same insight appear.
Validation failure handling
| Validation item | Failure manifestation | Handling method |
|---|---|---|
| JSONL format error | Invalid JSON or multi-line object | Validate line by line; fix the format or delete the corrupted line |
| type not within the enumeration range | A non-standard type was used | Map to the closest standard type; if it cannot be mapped, reject the write |
| confidence out of range | < 1 or > 10 | Truncate to 1-10; entries all marked 10 need manual downweighting |
| key not in kebab-case | Use camelCase or include spaces | Convert to kebab-case; keep the latest entry after deduplication |
| More than 1000 entries | learnings.jsonl is too long | Run prune: clean up outdated, contradictory, low confidence entries |
Good and bad examples
Good: one-sentence insight + kebab-case key + has files + reasonable confidence
{"type":"pitfall","key":"orm-n+1-query","insight":"User.list() 默认加载关联,列表接口必须用 .select() 限制字段","confidence":8,"files":["src/services/user.service.ts"],"source":"manual","ts":"2026-04-24T14:30:52+08:00"}
Bad: vague description + non-kebab-case + no files + all marked 10
{"type":"pitfall","key":"ORM Problem","insight":"ORM sometimes has performance issues when loading too much data and this can cause slow queries in production environments especially on list endpoints","confidence":10,"files":[],"source":"auto","ts":"2026-04-24T14:30:52+08:00"}
Output template
学习记录完成:
操作: [add / list / search / prune / export]
条目数: [N] (add 时 = 1)
新增条目 (add):
type: [pattern/pitfall/preference/architecture]
key: [kebab-case]
insight: [一句话]
confidence: [1-10]
files: [相关路径列表]
source: [auto/manual]
列表摘要 (list):
Patterns: [N] 条 (avg conf: [X])
Pitfalls: [N] 条 (avg conf: [X])
Preferences: [N] 条 (avg conf: [X])
Architecture: [N] 条 (avg conf: [X])
修剪结果 (prune):
已删除: [N] 条 (过时/矛盾/低 conf)
保留: [N] 条
Validation checklist
- JSONL format is correct (one valid JSON object per line)
- type is one of four (pattern / pitfall / preference / architecture)
- confidence is within the 1-10 range
- key is kebab-case and unique (or has a clear reason for update)
- insight is one sentence (no more than two sentences)
- files field exists (may be an empty list)
- source is auto or manual
- ts is in valid ISO-8601 format