diff --git a/skills/continuous-learning/SKILL.md b/skills/continuous-learning/SKILL.md index 3b37e30..a7190d8 100644 --- a/skills/continuous-learning/SKILL.md +++ b/skills/continuous-learning/SKILL.md @@ -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. @@ -184,7 +184,7 @@ Edit(file_path: "/.claude/memories/.md", old_string: " 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__`) @@ -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 @@ -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. @@ -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.:142` --- @@ -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 | diff --git a/skills/memory-audit/SKILL.md b/skills/memory-audit/SKILL.md index c7aa983..e43f7f8 100644 --- a/skills/memory-audit/SKILL.md +++ b/skills/memory-audit/SKILL.md @@ -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. @@ -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 `: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. @@ -123,14 +124,14 @@ 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 @@ -138,7 +139,7 @@ The categories below are the recurring concrete shapes of B.1 (forcing-function) - 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 @@ -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. @@ -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.