Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 8 additions & 24 deletions skills/continuous-learning/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ After completing any task, evaluate in two stages.
- Did this require non-obvious investigation or debugging?
- Was a choice made about architecture, patterns, or approach?
- Is there an established project convention worth documenting?
- **Forcing-function (hard gate):** without this memory, would a future session act differently in the project? If the code, `git log`, lint, or the formatter already drives the behavior → skip. The "Do Not Save" table cites this as `[Forcing-function]`.
- **Forcing-function (hard gate):** without this memory, would a future session act differently in the project? If the current code or a mechanical check already drives the behavior → skip. The "Do Not Save" table cites this as `[Forcing-function]`.

If the forcing-function gate fails, or no other prompt answers yes → skip. Otherwise continue to Stage B.

Expand Down Expand Up @@ -184,7 +184,7 @@ Edit(file_path: "<project>/.claude/memories/<existing_name>.md", old_string: "<s

## Quality Gates

> Capture Rules are gated in **Stage B** above; do not re-evaluate them here. This checklist covers formatting, quality, staleness, and security only — different concerns.
> Capture Rules are gated in **Stage B** above; do not re-evaluate them here. This checklist covers formatting, quality, and security only — different concerns.

Before saving any memory, verify:
- [ ] Name follows the correct pattern (`learning_` or `decision_<domain>_`)
Expand All @@ -193,9 +193,7 @@ Before saving any memory, verify:
- [ ] Content is specific enough to be actionable
- [ ] Content is general enough to be reusable
- [ ] No sensitive information (credentials, internal URLs)
- [ ] Does not duplicate existing memories
- [ ] References included if external sources were consulted
- [ ] No brittle references that rot quickly (see Staleness Prevention below)

### Do Not Save

Expand All @@ -209,11 +207,11 @@ Anti-examples, generalized — do not create memories like these:
| Public API reference | "Public Git hosting API rate limit is N/hr authenticated" | **[Rule 1]** Public API docs cover this — no project-specific twist. |
| Personal identifier | Problem section narrates a specific engineer hitting a cache bug | **[Rule 2]** Names an engineer. |
| Personal preference without project evidence | "Prefer early returns" with no lint rule, consistent codebase usage, or team agreement | **[Rule 3]** Taste, not pattern. |
| Historical record of a one-time shipped change | "We renamed folder `Install/` to `Sync/` after the command rename" | **[Forcing-function]** Once shipped, `git log` answers this. Future sessions read the current code, not the migration story. The memory drives no future behavior. |
| Historical record of a one-time shipped change | "We renamed folder `Install/` to `Sync/` after the command rename" | **[Forcing-function]** Once shipped, `git log` answers this. Future sessions read the current code, not the migration story. Assumes version control holds the history — without it nothing else records the change. |
| Generic engineering wisdom with a token project example | "Extract methods over condensing for lint compliance" with one PR cited | **[Rule 1]** Strip the example — what is left is universal advice that fits any project. Belongs in a coding-style doc, not a per-project KB. |
| One-line rule that belongs in CLAUDE.md | A single-sentence convention with no Context / Options / Consequences | **[Scope]** If it fits in one bullet under "Conventions" in CLAUDE.md, put it there. A standalone memory file is overhead for content that cannot grow. |
| Naming/prefix decision once enforced | "We kept the `External` prefix on adapter types" | **[Forcing-function]** Once the type system, lint, or formatter enforces it, the decision lives in the code. Future sessions read the code, not the memory. |
| One-time bug fix self-evident in current code | "Bug X used `dropFirst()`; we changed to a guarded check" | **[Forcing-function]** The fix is a small diff; the code reads correctly today. Save only if the bug class is recurring and the memory teaches the *avoidance pattern*, not the one fix. |
| One-time bug fix self-evident in current code | "Bug X skipped the first element instead of the matching one; we changed the filter to compare identity" | **[Forcing-function]** The fix is a small diff; the code reads correctly today. Save only if the bug class is recurring and the memory teaches the *avoidance pattern*, not the one fix. |
| Research artifact for deferred or dormant work | "Cross-platform audit / options-considered for feature X (deferred indefinitely)" | **[Forcing-function]** Useful when the work resumes — but it belongs in a planning doc or `docs/`, not the memory KB. The KB is for things that change how a session works on the active codebase today. |

**Internal docs are fair game.** A memory summarizing a Confluence page, ADR, RFC, or team-wiki entry is project knowledge — those sources aren't "documentation anyone can look up." Always include the source URL in `References:` so the memory points at the canonical version and readers can check for drift.
Expand All @@ -235,11 +233,11 @@ Before saving, check memory content against these rules:

- **No line numbers.** Reference symbols (types, functions, methods) instead — they survive refactors.
- **Prefer module-level paths** over deep file paths. Use full paths only for stable, well-known files.
- **Use semantic anchors** — method signatures, protocol names, and architectural concepts are durable.
- **Use semantic anchors** — method signatures, interface and type names, and architectural concepts are durable.
- **Omit transient details** — feature flags being removed, in-progress PR numbers, temporary workarounds.

**Good:** `SessionManager.refreshToken(forceExpiry:)` in the `Auth` module
**Bad:** `SessionManager.swift:142` at `Sources/Features/Auth/Session/SessionManager.swift`
**Good:** `SessionManager.refreshToken` in the `Auth` module
**Bad:** `src/features/auth/session/SessionManager.<ext>:142`

---

Expand All @@ -252,20 +250,6 @@ When the user asks to "run a retrospective", "extract learnings from this sessio
1. Review conversation history for extractable knowledge.
2. Search existing memories following Step 2 of the Extraction Workflow.
3. Filter candidates through the Capture Rules. Drop anything that fails Rule 1 (no project tie), Rule 2 (names an engineer), or Rule 3 (preference without project evidence).
4. Save the top 1–3 highest-value candidates that pass, following Step 4's pre-`Write` checks.
4. Save the top 1–3 highest-value candidates that pass, following Step 4's pre-`Write` checks. The cap is deliberate: a long session can yield many qualifying memories, and three is the most worth adding at once — the gates decide what is eligible, the cap decides how many land per session. Note any you set aside.
5. Report what was created and why in a brief summary.

---

## Tool Reference

| Tool | Purpose |
|------|---------|
| `mcp__docs-mcp-server__search_docs` | **Primary:** Semantic search across docs and memories |
| `mcp__docs-mcp-server__list_libraries` | List indexed libraries |
| `Glob` | **Fallback:** List all memory files (`.claude/memories/*.md`) |
| `Read` | Read a specific memory file |
| `Write` | Create new memory file |
| `Edit` | Update existing memory file |
| `Bash` | Resolve git repo name for `Applies to:` (`git remote get-url origin`) |
| `WebSearch` | Built-in web search for general topics |
16 changes: 9 additions & 7 deletions skills/memory-audit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ If the test fails, recommend DROP — or UPDATE only if a rewrite around the act
### Group B — The audit's own gate

#### B.1 Actionability — the forcing-function test
- **Primary test:** *"Would a future session act differently in this codebase because this memory exists?"* If the answer is "no, the code itself or `git log` already conveys it" → DROP.
- **Primary test:** *"Would a future session act differently in this codebase because this memory exists?"* If the answer is "no, the current code already conveys it" → DROP.
- Can a future session **act on** this memory to avoid a mistake or follow a convention? Or is it purely descriptive/documentary with no clear "do this, not that" takeaway?
- **Fact-check ≠ actionability.** A claim being *true* and *project-specific* is not enough. Many memories pass A.1 (real anchors) and C.4 (claims still verifiable) but still fail this one — historical records, shipped naming decisions, one-time bug fixes whose fix is self-evident in the code. Apply both passes; do not conflate them.
- **Bias check.** If you find yourself defending KEEP with "it's project-specific and still accurate" without identifying the *behavior change* it drives, that's the leniency trap. KEEP requires a positive answer to the forcing-function test, not just absence of a reason to drop.
Expand All @@ -108,11 +108,12 @@ If the test fails, recommend DROP — or UPDATE only if a rewrite around the act
- **Verify key claims against the codebase.** If a memory says "we use pattern X in module Y," search the code to confirm that pattern still exists.
- Use `Grep` to check for symbol names, type names, or patterns referenced in the memory.
- Use `Glob` to verify that referenced files or modules still exist.
- If a memory describes a convention (e.g., "all repositories conform to protocol X"), spot-check a few cases to confirm it holds.
- If a memory describes a convention (e.g., "all data-access modules implement interface X"), spot-check a few cases to confirm it holds.
- Do not audit every single line — focus on the **central claim** of the memory. If the core assertion is wrong, recommend DROP or UPDATE.
- **An empty grep is not proof the symbol never existed.** It may live on an unmerged branch, or the grep may have matched only the memory's own text. Where you cannot confirm a symbol in current source, that is the UPDATE-uncertain verdict, not DROP: say in the rationale what you could not confirm, and let the user decide.

#### C.5 Staleness Signals
- **Line number references** — e.g., `lines 266-296` or `FileName.swift:142`. These break after any edit. Recommend UPDATE to replace with symbol names.
- **Line number references** — e.g., `lines 266-296` or `<file>:142`. These break after any edit. Recommend UPDATE to replace with symbol names.
- **Deep file paths** — full nested paths are fragile. Recommend UPDATE to use module-level references unless the path is stable and well-known.
- **Transient details** — feature flag names being removed, in-progress PR numbers, temporary workarounds with known expiry.
- References to features or files that may have been removed or heavily refactored.
Expand All @@ -123,22 +124,22 @@ If the test fails, recommend DROP — or UPDATE only if a rewrite around the act

## DROP Categories — recurring patterns that should not need user pushback

The categories below are the recurring concrete shapes of B.1 (forcing-function) failure. When a memory matches one, the analysis is already done — call DROP without hedging. None of these are "in doubt" cases.
The categories below are the recurring concrete shapes of B.1 (forcing-function) failure. When a memory matches one, the analysis is already done — call DROP without hedging beyond a category's own "Exception" or "Keep only when" clause, which you should apply.

### A. Self-marked superseded / deferred / abandoned
- The memory itself says **SUPERSEDED**, **deferred indefinitely**, **closed without implementation**, **path abandoned**, or points at another memory as the current decision.
- The "historical context" argument is rarely worth a file. If the superseder cross-links back, that's enough provenance. DROP the older one.

### B. Pure historical records of shipped one-time changes
- Folder renames, file renames, identifier migrations, org migrations *that are done*. Once shipped, `git log` answers "why is this named X?" The memory adds nothing actionable.
- Folder renames, file renames, identifier migrations, org migrations *that are done*. Once shipped, `git log` answers "why is this named X?" The memory adds nothing actionable. This assumes version control holds the history — without it nothing else records the change, so judge on behavior alone.
- Exception: when the historical change still imposes an ongoing constraint future code must honor — then the memory is about the constraint, not the change.

### C. Shipped naming or style decisions
- "We named the prefix X" / "we kept type Y suffixed" / "we use this enum case style." Once enforced by the type system, lint, or formatter, the decision is in the code. Future sessions read the code, not the memory.
- Keep only when the rule has *no* enforcer (no lint, no formatter, no compiler check) and the codebase actually depends on humans following it.

### D. One-time bug fixes whose fix is self-evident in the code now
- "Bug X used `dropFirst()`; we changed to `where index != firstIndex`." The fix is a 2-line diff, the code reads correctly today. A future regressor would not consult the memory; the existing code is the documentation.
- "Bug X skipped the first element instead of the matching one; we changed the filter to compare identity." The fix is a two-line diff and the code reads correctly today. A future regressor would not consult the memory; the existing code is the documentation.
- Keep only when the bug class is *recurring* (same pattern in multiple places, or a footgun future code might re-introduce) and the memory teaches the *avoidance pattern*, not the one fix.

### E. Generic engineering wisdom dressed up with one project example
Expand Down Expand Up @@ -231,6 +232,7 @@ Run only after Step 3 has produced an explicit approval (or per-item decisions)
- **UPDATE (content)**: Use `Edit` or `Write` to update the file
- **UPDATE (merge)**: Create the merged file, then delete the originals
- **UPDATE (uncertain)**: If the correct replacement isn't obvious (e.g., a referenced symbol was removed and the new equivalent is unclear), ask the user what the updated content should be rather than guessing.
- **Stop at the filesystem.** Never `git add`, commit, or push memory changes — a KB may be tracked in the project's own repo, kept in a separate repo with its own propagation rules, or gitignored and purely local.

Report what was done after each batch.

Expand Down Expand Up @@ -259,7 +261,7 @@ Knowledge base reduced from 42 → 34 files.
- **Never delete or edit without explicit per-batch approval.** Print the verdict table, then stop. Do not run any tool until the user replies for *this* batch — silence is not consent, and approval of an earlier batch does not carry forward.
- **Explain the "why" clearly.** The user should understand the reasoning behind every DROP and UPDATE recommendation, not just see the label.
- **Apply criteria with teeth, not deference.** Past audits drifted into KEEP-by-default because each memory had *some* tie to the project. The forcing-function test (B.1) is the correction: KEEP requires identifying behavior the memory drives, not just absence of error. When the DROP categories above match, call DROP — don't soften it to UPDATE or stash in KEEP "to be safe."
- **In genuine doubt, prefer DROP with rationale over silent KEEP.** The user can always override. A KEEP that should have been DROP rarely gets revisited; a proposed DROP gets debated and resolved in seconds. **DROP is not a failure** — moving content to `CLAUDE.local.md`, to a planning doc, or simply deleting it because the code now documents itself is the audit doing its job.
- **In genuine doubt, prefer DROP with rationale over silent KEEP.** The user can always override. A KEEP that should have been DROP rarely gets revisited; a proposed DROP gets debated and resolved in seconds. **DROP is not a failure** — moving content to `CLAUDE.local.md`, to a planning doc, or simply deleting it because the code now documents itself is the audit doing its job. This is about doubt over a memory's *value*. Doubt over a *fact you could not check* is different — an unverified claim is a reason to ask, not to delete.
- **Watch for the "but it's true and project-specific" trap.** That sentence is A.1 and C.4 passing — it says nothing about B.1. Two-pass thinking: first verify, then ask "does this change behavior?"
- **Batch size matters.** 10-15 per batch keeps the review manageable.
- **End-of-audit check for broken cross-links.** After DROPs land, grep `Related:` / `References:` lines for any pointer to a deleted filename and clean those up — broken refs accumulate silently otherwise.