skills/meta/retro/SKILL.md
Learning system interface: stats, search, graduate, clear learnings. Backed by learning.db (SQLite + FTS5).
npx skillsauth add notque/claude-code-toolkit retroInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill wraps scripts/learning-db.py into a user-friendly interface for the learning system. The learning database is the single source of truth—all queries go through the Python CLI, never maintaining a parallel file store.
Parse the user's argument to determine the subcommand. Default to status if no argument given.
| Argument | Subcommand | |----------|------------| | (none), status | status | | list | list | | search TERM | search | | graduate | graduate | | what-didnt-work | what-didnt-work | | clear | clear |
Key constraint: Always present results in readable tables/sections, not raw JSON. When showing stats, suggest next actions (search, graduate).
Show learning system health summary.
Step 1: Get stats.
python3 ~/.claude/scripts/learning-db.py stats
Step 2: Present status report. Present high-confidence counts with the category breakdown; error spam inflates per-row confidence (pruning 5119 noise rows dropped high-conf 4201→564, 2026-06-12).
LEARNING SYSTEM STATUS
======================
Entries: [total] ([high-conf] high confidence)
Categories: [breakdown by category]
Graduated: [N] entries embedded in agents/skills
Injection:
Hook: session-context.py (SessionStart, ADR-147 dream system)
Method: pre-built payload from nightly auto-dream cycle + learning.db high-confidence patterns
Next actions:
/retro list — see all entries
/retro search TERM — find specific knowledge
/retro graduate — embed mature entries into agents
Display all accumulated knowledge.
Key constraint: Output must use the Python CLI as the single source of truth. Do not maintain parallel markdown files. Present results in readable grouped format, not raw JSON.
Step 1: Query all entries.
python3 ~/.claude/scripts/learning-db.py query
Step 2: Present grouped by category:
LEARNING DATABASE
=================
## [Category] ([N] entries)
- [topic/key] (conf: [N], [Nx] observations): [first line of value]
...
Optional flags:
--category design — filter to one category--min-confidence 0.7 — only high-confidence entriesFull-text search across all learnings.
Step 1: Run FTS5 search.
python3 ~/.claude/scripts/learning-db.py search "TERM"
Step 2: Present results ranked by relevance:
SEARCH: "TERM"
==============
[N] results:
1. [topic/key] (conf: [N], category: [cat])
[value excerpt]
2. ...
Evaluate learning.db entries and embed mature ones into agents/skills.
Key constraints:
--auto flag, confirm intent).error and effectiveness—those are injection-only (useful in context but not suitable as permanent agent instructions).Step 1: Get graduation candidates from the DB.
python3 ~/.claude/scripts/learning-db.py query --category design --category gotcha
Step 2: For each entry, evaluate graduation readiness.
For each candidate, the LLM:
| Question | Pass | Fail | |----------|------|------| | Is this specific and actionable? | "sync.Mutex for multi-field state machines" | "Use proper concurrency" | | Is this universally applicable? | Applies across the domain | Only applied in one feature | | Would it be wrong as a prescriptive rule? | Safe as default | Has important exceptions | | Does the target already contain this? | Not present | Already equivalent |
Step 3: Present graduation plan to user.
GRADUATION CANDIDATES (N of M entries)
1. [topic/key] → [target file] (add anti-pattern)
Proposed: "### AP-N: [title]\n[description]"
ALREADY APPLIED (N entries — mark graduated only)
- [topic/key] — already in [file]
NOT READY (N entries — keep injecting)
- [topic/key] — [reason]
Approve? (y/n/pick numbers)
Step 4: On user approval, apply changes.
Use the Edit tool to insert graduated content into target agent/skill files.
After embedding, mark the entry as graduated:
python3 ~/.claude/scripts/learning-db.py graduate TOPIC KEY "target:file/path"
Graduated entries stop being injected (the injector filters graduated_to IS NULL).
Step 5: Report.
GRADUATED:
[key] → [target file] (section: [section])
Entries marked. They will no longer be injected via the hook
since they are now part of the agent's permanent knowledge.
Remove noise from learning.db: cross-domain rows (via filtered prune) or
old low-confidence rows (via stale-prune). Wraps the existing
learning-db.py prune / stale-prune CLI — no new deletion code path.
Key constraints:
--apply/--confirm on the first invocation of a session, regardless of how the user phrased the request ("clear the voice noise", "prune this", "clean up learnings").--apply or --confirm.learning.db. Do not use it to satisfy a code-level bug fix task that explicitly excludes data mutation — check the task's constraints before running --apply/--confirm.Step 1: Determine the clear mode from the user's argument.
| User intent | Mode | Underlying command |
|---|---|---|
| "clear category X" / "clear topic X" / has --category, --topic, --max-confidence, or --older-than | filtered | learning-db.py prune |
| "clear stale" / "clear old" / no filter given | stale | learning-db.py stale-prune |
Step 2: Run the dry-run (always, unconditionally, first).
# Filtered mode
python3 ~/.claude/scripts/learning-db.py prune --category CATEGORY [--topic TOPIC] [--max-confidence N] [--older-than DAYS] --dry-run
# Stale mode
python3 ~/.claude/scripts/learning-db.py stale-prune --dry-run [--min-age-days DAYS]
Step 3: Present the dry-run result and stop.
RETRO CLEAR — DRY RUN
======================
Mode: [filtered | stale]
Filter: [category=X, topic=Y, ...] or [min-age-days=N]
Matched: [N] entries
- [topic/key] (conf: [N], age: [N]d)
...
This is a preview — nothing was deleted. Reply "apply" (or "confirm") to
actually remove these entries, or refine the filter and re-run.
Step 4: Only after the user explicitly confirms in this turn, re-run with --apply (filtered) or --confirm (stale):
python3 ~/.claude/scripts/learning-db.py prune --category CATEGORY ... --apply
# or
python3 ~/.claude/scripts/learning-db.py stale-prune --confirm [--min-age-days DAYS]
Step 5: Report the outcome.
CLEARED: [N] entries removed ([mode] mode, filter: [...])
Total learnings: [before] -> [after]
Graduated entries and routing/effectiveness rows are always protected from prune (see scripts/tests/test_learning_db_prune.py). stale-prune archives to learning_archive rather than hard-deleting, and likewise skips graduated rows.
Print the negative-results registry, the list of experiments that lost. Read it before re-running an experiment so a known-dead path is not retried.
The registry is a doc, not a DB table: docs/what-didnt-work.md is capture, store, and query target. This subcommand reads and prints it, then offers an optional one-line mirror into learning.db for FTS search.
Step 1: Read and print the registry.
Use the Read tool on docs/what-didnt-work.md and present it. Group by the dated ## YYYY-MM-DD headings; show each entry's Decision verdict (rejected / deferred / revisit-if) up front so a scan answers "did we already reject this?".
NEGATIVE RESULTS (docs/what-didnt-work.md)
==========================================
## [date] [experiment]
Decision: [rejected | deferred | revisit-if <condition>]
What happened: [one line]
...
If the file is missing, report that no negative results are recorded yet and point the user at the format in CONTRIBUTING.md.
Step 2 (optional): Mirror one line into learning.db for full-text search.
The doc stays canonical. The mirror is one pointer row, not a parallel store. Run only when the user wants the entry FTS-searchable via /retro search:
python3 ~/.claude/scripts/learning-db.py learn --topic negative-results \
"YYYY-MM-DD <experiment>: <decision> - see docs/what-didnt-work.md"
Batching learn calls: run learning-db.py learn calls individually or chained with &&, then confirm via learning-db.py search. A single failing command in a plain multi-line Bash batch silently drops the rest (observed 2026-06-12).
This reuses the existing learn command (no new code). Confirm with either:
# Topic listing (exact, includes the hyphen):
python3 ~/.claude/scripts/learning-db.py query --topic negative-results
# Or FTS (use a space, not the hyphen; the tokenizer splits hyphens):
python3 ~/.claude/scripts/learning-db.py search "negative results"
User says: "/retro"
Actions: Run learning-db.py stats, show entry counts, injection health.
User says: "/retro list"
Actions: Run learning-db.py query, display grouped by category.
User says: "/retro search routing"
Actions: Run learning-db.py search "routing", display ranked results.
User says: "/retro graduate" Actions: Query design/gotcha entries, evaluate each against graduation criteria, propose edits to target agents/skills, apply approved changes, mark graduated.
User says: "/retro clear category voice"
Actions: Run learning-db.py prune --category voice --dry-run, present the matched count and sample rows, stop and wait for explicit confirmation. Only on "apply"/"confirm" from the user, re-run with --apply and report before/after totals.
Cause: Database not initialized yet Solution: Report that no learnings exist yet. Hooks auto-populate during normal work.
Cause: No design/gotcha entries, or all already graduated Solution: Report the stats and suggest recording more learnings via normal work.
~/.claude/scripts/learning-db.py — Python CLI for all database operations, including prune and stale-prune (wrapped by the clear subcommand)hooks/session-context.py — Hook that injects the pre-built dream payload and high-confidence patterns at session start (ADR-147, supersedes retro-knowledge-injector.py)hooks/pretool-learning-injector.py — PreToolUse hook that queries learning.db for tool-error hints; scoped to error/gotcha/debug categories (ADR: pretool-injector-scoping)scripts/learning.db — SQLite database with FTS5 search indexdocs/what-didnt-work.md: Negative-results registry. Printed by the what-didnt-work subcommand; the doc is the canonical store.tools
Shell configuration: Fish and Zsh setup, PATH, completions, plugins.
tools
Kubernetes operations: debugging, security, RBAC, and infrastructure tooling.
development
Swift development: concurrency patterns, async/await, actors, testing with XCTest and Swift Testing framework.
development
PHP development: code quality, PSR standards, testing with PHPUnit.