--- name: codify-learnings description: "Review the whole current session for failures, check each against the rules earlier runs wrote, propose up to three fixes (tools and hooks before docs) to apply with one prompt, and log the fixes and re-offenses to cla.io/. Run with /cla:codify-learnings." argument-hint: "[focus-note]" # Slash-command only (an end-of-session retro the user starts): keeps this description out of the # always-loaded skill listing. Nothing invokes it programmatically. disable-model-invocation: true --- # Codify learnings Turn this session's failures into at most three fixes that change how the next session behaves. A rule that already existed and failed again is the most important thing this skill can find. Before Step 1, read `references/routing.md` — the ladder, where each kind of lesson lives, the plugin-writability check, and the failure prompts. This repo's verification commands are in `cla.io/project-facts.md`; `cla.io/overlays/codify-learnings.md`, if present, says where memory lives and adds this skill's own rules here. If `cla.io/project-facts.md` lacks a fact this skill needs and this skill's overlay exists, the overlay may still hold it from before the move: tell the user "run /cla:cla-setup to move it". `$ARGUMENTS`, if set, narrows the focus; the review still covers the whole session. ## Step 1 — List the session's failures Review the **whole session from its first message**, not its tail: a lesson set up early is often paid for late. List every: - user correction or pushback; - reverted edit or abandoned approach; - denied tool call or permission prompt; - wasted turn — a re-diagnosis, a question already answered, a detour a tool could have avoided. Run the failure prompts in the reference over the session to catch the ones you lived through without noticing. Write each failure as one line with a short quote of what was said or done. No failures: say so, and go to Step 5 with empty lists. ## Step 2 — Check each against existing rules For each failure, search for a rule that should have prevented it: every `CLAUDE.md`, `cla.io/overlays/`, the hooks in `${CLAUDE_PLUGIN_ROOT}/hooks/` and `.claude/settings*.json`, the memory index (skip it if the overlay does not say where it is and you cannot find it), and the lessons log. Grep with the failure's keywords — never read the log whole: ```bash grep -rn -i '' cla.io/lessons-learned/ ``` This one grep also searches `cla.io/lessons-learned/lessons-learned-archive.md`, where older entries live; never read either file whole. - **A hit is a re-offense**: the rule existed and did not hold. Key it by that artifact's path or hook name (`CLAUDE.md`, `hooks/block-cd-in-bash.py`), never by a slug you made up. In the lessons log only an APPLIED line names an artifact, and that artifact is the key; any other log hit is context, not a re-offense. Its fix goes **one rung above** that artifact (reference, "The ladder"). - **No hit is a new lesson**: it enters at the lowest rung that would have prevented it. ## Step 3 — Propose at most three fixes - **Each fix cites the failure it answers, quoted.** A candidate with no session failure behind it is dropped — not deferred, softened or folded into another. Rank by payoff and cut after the third, memory included; one real lesson means one fix. - **Prefer fixes over diagnostics.** When the failure was "I had to diagnose X by hand", the first fix makes the tool handle X — a script, a config, a hook, a smoke test — and a doc or memory note is at most a second aid. Ask: could a config or script change have prevented the detour? - **Route by writability** (reference, "Is the plugin writable here?"). Read-only: a fix to a plugin file goes to `/cla:report-upstream`, and its line says so. - **Pick the home** (reference, "Which home"): repo lessons go to the repo's `CLAUDE.md`, `cla.io/project-facts.md` or `cla.io/overlays/`; memory holds only how this user personally likes to work. - **When a fix graduates a lesson**, the same fix deletes the lower-rung text it duplicates. - **Never propose edits to** a skill's bundled scripts (`**/scripts/**/*.py`), `openspec/**`, or a vendored framework directory. The repo's own tooling, configs and source are in scope. Show only the numbered list, most valuable first: ``` **1. ** (``, ) — . Failure: "". Re-offense of ``, escalated to . Benefit: . ``` Drop the re-offense clause for a new lesson. A fix going upstream names `/cla:report-upstream` as its target. ## Step 4 — One prompt, then apply ``` N fixes proposed. Apply which? (y = all / n = none / indices, e.g. 1,3) ``` - Indices apply those and mark the rest REJECTED; `y` applies all; `n` rejects all. - **Empty input is not consent.** Ask once more; a second empty answer is `n`. - Rejection is an ordinary outcome. Never argue a rejected fix back onto the list. - Nothing is written before this answer — memory included. Apply each accepted fix with the tool it needs; for one going upstream, invoke `/cla:report-upstream` with the fix and the failure it answers. ## Step 5 — Log Prepend one entry of at most 150 words to `cla.io/lessons-learned/lessons-learned.md`, above its first `## ` entry (create the file with a `# Lessons learned` title if it is missing; read only its first lines). Newest first, entries separated by `---`: ``` ## — codify-learnings - APPLIED 1. (`<target>`, <rung>) - REJECTED 2. <title> - Re-offense: `<artifact>` → <rung> ``` The log is a tracked file; include it when the applied fixes are committed. **Keep the live log under 6,000 words (`wc -w`).** When the prepend takes it over, move its oldest entries, whole and unedited, from the bottom to the top of the entries in `cla.io/lessons-learned/lessons-learned-archive.md` (create it with a `# Lessons learned — archive` title and a line saying it holds older entries moved from the live log, in log order), until the live log is under 6,000 words again. Keep one `---` line between entries in both files, none left at the end of the live log. Count `grep -c '^## '` over both files before and after; the total must match. Close with one line: fixes proposed, applied and rejected, and each re-offense with the rung it went to.