Two-Tier Learning
Psi's self-improvement mechanism. Two speeds of learning, both injected into prompts.
Tier 1: LEARNINGS.md (Fast, Unvalidated)
Managed by src/psi/learning_tracker.py.
Format: --- delimited blocks in a markdown file.
markdown
# Learned Patterns Rules extracted from experience. Apply relevant rules to avoid repeating mistakes. --- Always use `type: "module"` in package.json when using ESM imports. --- Filter all database queries by userId to prevent data leaks. ---
How it works:
- •Claude appends rules during work (it writes directly to LEARNINGS.md)
- •Orchestrator reads last 20 rules and injects them into the next iteration prompt
- •Parser skips the header block (everything before first
---) and blocks < 10 chars
Key implementation detail: get_all() splits on ---, skips blocks[0] (header), normalizes whitespace.
Tier 2: expertise.yaml (Validated, Promoted)
Managed by src/psi/skill_sync.py. Runs between phases, not during.
Flow:
- •Read all LEARNINGS.md entries
- •Extract search terms from each (backtick code, quoted strings, significant words)
- •Search codebase with ripgrep (excludes yaml, md, node_modules, .git, .psi)
- •3+ occurrences → promote to
.claude/skills/learned/resources/expertise.yaml - •Remove promoted entries from LEARNINGS.md
Confidence thresholds:
- •High: 5+ file matches
- •Medium: 3-4 file matches
- •Low: <3 (stays in LEARNINGS.md only)
expertise.yaml schema (written via yaml.safe_dump()):
yaml
version: "0.2.0"
patterns:
- pattern: "Always extend tsconfig from @tsconfig/node20"
confidence: high
occurrences: 7
evidence: "tsconfig.json, packages/*/tsconfig.json"
learned_from: skill_sync
promoted_at: "2026-01-31T14:23:00"
evolution_log:
- date: "2026-01-31"
change: "Promoted 3 patterns from Tier 1"
patterns_added: 3
All YAML operations use yaml.safe_load()/yaml.safe_dump() per PyYAML best practices — prevents arbitrary object construction on load and restricts serialization to safe Python types on dump.
Prompt Injection Order
In prompt_generator.py:augment_with_learnings():
- •Tier 2 patterns first (validated, higher priority), capped at 20
- •Tier 1 learnings second (unvalidated, lower priority), capped at 20
- •Separated by
---from base prompt
Troubleshooting
No patterns promoted after skill sync
- •Search terms may be too generic. Check
_extract_search_terms()output. - •ripgrep excludes yaml/md files — patterns about config won't match code files.
LEARNINGS.md entries duplicating
- •Claude may write duplicate rules. No dedup currently — accepted limitation.
- •Promoted entries are removed, which helps keep the file clean.
Related Files
- •
src/psi/learning_tracker.py— Tier 1 read/write - •
src/psi/skill_sync.py— Tier 2 validation + promotion - •
src/psi/prompt_generator.py— Injection into prompts