3 İşlemeler 3756391f7d ... cff445651f

Yazar SHA1 Mesaj Tarih
  bastien cff445651f fix(prune-memory): STEP 4 verify — prefix mapping bug (TDD RED→GREEN) 5 gün önce
  bastien c85c1f742b fix(memory): BDR-011 body status — superseded by BDR-013 5 gün önce
  bastien 4e6ef5a329 feat(skills): add /prune-memory — curate .claude/memory/ registries 5 gün önce
2 değiştirilmiş dosya ile 257 ekleme ve 1 silme
  1. 1 1
      .claude/memory/decisions.md
  2. 256 0
      skills/prune-memory/SKILL.md

+ 1 - 1
.claude/memory/decisions.md

@@ -198,7 +198,7 @@ rules:
 ## BDR-011 — Client handover deliverable: 4-chapter structure + ZenQuality branded HTML/PDF
 
 - **Date**: 2026-05-07
-- **Status**: accepted
+- **Status**: superseded by BDR-013
 - **Decision**: client handover doc restructured to 4 chapters — §1 *Ce qu'il fallait faire (et pourquoi)* (briefing+motivation, 100–180 words), §2 *Ce qui a été fait* (lay summary, **≤300 words hard cap, zero jargon, no internal tool/skill names**), §3 *Ce qui vous reste à faire* (action-only checklist with cadences), §4 *Détails techniques (pour les curieux)* (scores, key choices, phases, optional glossary — internal labels allowed here only). Plus optional §5 (external platforms, web), §6 (build & deploy). Replaces old 9-section structure. Output now triple: `LIVRAISON.md` (editable source) + `LIVRAISON.html` (always, branded) + `LIVRAISON.pdf` (when PDF engine on host). HTML/PDF use ZenQuality identity — green palette `#1A3A25 / #2D5A3D / #4A7C59 / #87A878`, cream BG `#F5F0EB`, fonts Inter (body) + Playfair Display (headings), cover page with logo + tagline "La sérénité numérique, la qualité en plus", running header (project name) + footer (page N/M, `ZenQuality — zenquality.fr`). Renderer cascade: MD→HTML via pandoc > python markdown > `npx marked`; HTML→PDF via weasyprint > wkhtmltopdf > chromium > headless Chrome. STEP 15 enforces gates before render: chapter 2 word count ≤300 (`wc -w`) AND forbidden-token grep on chapters 1–3 (no `/seo`, `/harden`, `/validate`, `/cso`, `seo-analyzer`, `SEO.md`, `SCORE_*`, etc.).
 - **Why**: client reads top-down, may stop after §2 — old 9 sections diluted the read. Bare markdown unreadable by non-tech client. Branded PDF = professional deliverable matching company identity (ZenQuality), suitable to email/print/sign. Per-section gates prevent regression to skill-name leaks or jargon bloat.
 - **Alternatives rejected**:

+ 256 - 0
skills/prune-memory/SKILL.md

@@ -0,0 +1,256 @@
+---
+name: prune-memory
+description: |
+  Use when .claude/memory/ registries grow too large or noisy — superseded
+  entries verbose, similar entries cluttering, journal stale, caveman style
+  drifted. Curates the 5 registries via mark-superseded + merge + inline
+  caveman compression. Append-only safe (no hard delete). Git is the backup.
+  Triggers: "prune memory", "compact memory", "clean memory", "memory
+  hygiene", "trier memoire", "nettoyer memoire", "registres trop longs",
+  "compresse les memoires".
+argument-hint: [optional: decisions|learnings|blockers|journal|evals — default all 5]
+disable-model-invocation: false
+allowed-tools:
+  - Read
+  - Edit
+  - Write
+  - Bash
+  - Grep
+  - Glob
+  - AskUserQuestion
+---
+
+# /prune-memory — Memory registry curation
+
+Operates on `.claude/memory/` in the current project (CWD). Curates the
+5 registries: `decisions.md`, `learnings.md`, `blockers.md`, `journal.md`,
+`evals.md`.
+
+## Core principles
+
+- **Git is the backup.** Skill writes in-place. PRECHECK refuses to run
+  if working tree dirty on registry files.
+- **Append-only friendly.** Marks entries `status: superseded by <new-ID>`
+  or `status: deprecated` instead of deleting. Body of old entry stays
+  for history.
+- **IDs stable.** Never renumber. Merges create a new ID; sources keep
+  their ID with superseded status.
+- **Caveman style enforced.** Per CLAUDE.md memory rule, all writes are
+  caveman-style English. Compression rewrites prose to fragments.
+- **User approves every category.** No silent changes.
+
+## Quick reference
+
+| When | Use |
+|------|-----|
+| Add new entry this session | `/close` |
+| Token-compress one file (not curating) | `/caveman:compress <file>` |
+| Curate: obsolete + merge + caveman | `/prune-memory` (this skill) |
+
+## STEP 0 — PRECHECK
+
+```bash
+test -d .claude/memory/ || { echo "no .claude/memory/ in $(pwd)"; exit 1; }
+git status --short .claude/memory/ 2>/dev/null
+```
+
+If working tree is dirty on any registry file → STOP with: "Commit or
+stash pending changes in `.claude/memory/` first. Skill writes in-place.
+Git is the only backup."
+
+## STEP 1 — AUDIT (per registry)
+
+For each target registry (filter by `$ARGUMENTS` or all 5):
+
+Read file. Classify candidates into A/B/C/D below. Use today's date for
+age comparisons. Today's date is in the system context.
+
+### A. Obsolete — mark-superseded candidates
+- Decisions `status: proposed` older than 90 days → propose
+  `status: deprecated` (no follow-up).
+- Decisions whose body contains "superseded by <ID>" but Index row still
+  says `accepted` → propose Index row fix to
+  `superseded by <that-ID>`.
+- Blockers `status: open` whose root cause matches a commit in last 30
+  days (grep `git log --since=30.days --grep=<keyword>`) → propose
+  `status: resolved` with commit ref.
+- Journal entries older than 180 days with zero cross-reference from
+  later entries → propose collapse into 1-line month summary
+  (`## YYYY-MM` heading replaces detail).
+
+### B. Similar — merge candidates
+- Two+ entries sharing root keyword in title (e.g. `pandoc`,
+  `client-handover`, `CSS overlay`).
+- Shared file paths in `**Reference**:` lines.
+- Same week + adjacent IDs + same domain.
+- Use semantic judgment on overlap; don't merge complementary entries
+  that cover different angles of one concept.
+
+### C. Bloated — inline caveman-rewrite candidates
+- Body > 150 words AND prose-heavy.
+- Detect filler density: count `\b(the|a|an|just|really|basically|actually|simply)\b`
+  matches; if > 5% of word count → bloated.
+
+### D. Index drift
+- Body `## (BDR|LRN|BLK|EVAL)-NNN` heading exists but no matching row
+  in `## Index` table → propose Index backfill.
+- Index row exists but body entry missing → propose `status: deleted
+  (orphaned)` tombstone or removal of Index row (user decides).
+
+## STEP 2 — PRESENT PLAN ★ MANDATORY STOP
+
+Print one block per registry. Example:
+
+```
+PRUNE PLAN — decisions.md (N entries → M after if approved)
+
+[A. Obsolete — mark superseded]
+  BDR-003 — Gitignore wildcard pattern — status: proposed since 2026-03-12
+            → mark: status: deprecated (no follow-up after 90 days)
+  BDR-011 — Client handover 4-chapter — body says superseded by BDR-013
+            → fix Index: status = "superseded by BDR-013"
+
+[B. Similar — merge]
+  LRN-014 + LRN-016 — both pandoc rendering quirks
+            → propose: merge into NEW LRN-017 ("Pandoc rendering quirks")
+              with both bodies appended + caveman pass; sources marked
+              status: superseded by LRN-017
+
+[C. Bloated — inline caveman rewrite]
+  BDR-011 — body 612 words, filler density 7.2% → ~380 expected (-38%)
+
+[D. Index drift]
+  (none)
+
+Approve per category? (all / a / b / c / d / edit <ID> / skip)
+```
+
+Wait for user input. Default = nothing applied.
+
+## STEP 3 — APPLY APPROVED CHANGES
+
+Order: safe → destructive.
+
+1. **Index drift fixes** — no body changes. Backfill missing rows, mark
+   orphans.
+2. **Status flag updates** — Index row status field only. Body untouched.
+3. **Merges** — write new merged entry (next-free ID); source IDs marked
+   `status: superseded by <new-ID>` in Index (body kept verbatim for
+   history). Merged body:
+   - Preserves all `**Reference**:` lines (dedupe identical paths).
+   - Caveman pass on prose during merge.
+   - Keeps frontmatter fields: id (new), date (today), title, status
+     (accepted), references (union).
+4. **Inline caveman compression** — preserve frontmatter exactly (id,
+   date, title, status, references). Rewrite prose body to fragments:
+   - Drop articles (`a`, `an`, `the`).
+   - Drop filler (`just`, `really`, `basically`, `actually`, `simply`).
+   - Short synonyms (`big` not `extensive`, `fix` not `implement a solution for`).
+   - Keep code blocks, URLs, error messages, file paths VERBATIM.
+   - Keep IDs (BDR-XXX, LRN-XXX, commit hashes) verbatim.
+
+After each write, regenerate Index from body when rows changed.
+
+## STEP 4 — VERIFY
+
+```bash
+# Filename → ID-prefix map. Hard-mapped because filenames don't share
+# their first 3 chars with the prefix (decisions → BDR, not DEC).
+# v1 bug: derived prefix via `basename | cut -c1-3` → never matched,
+# verify printed false-clean signal. Fixed in v1.1 (TDD found it).
+declare -A PREFIX_MAP=(
+  [decisions]=BDR
+  [learnings]=LRN
+  [blockers]=BLK
+  [evals]=EVAL
+)
+
+# All body entries have Index rows; no orphans
+for fname in decisions learnings blockers evals; do
+  f=".claude/memory/${fname}.md"
+  [ -f "$f" ] || continue
+  prefix="${PREFIX_MAP[$fname]}"
+
+  /usr/bin/grep -oE "^## (${prefix})-[0-9]+" "$f" | while read marker; do
+    id="${marker##\#\# }"
+    /usr/bin/grep -q "^| ${id} " "$f" || echo "MISSING INDEX: $id in $f"
+  done
+  /usr/bin/grep -oE "^\| (${prefix})-[0-9]+ " "$f" | while read row; do
+    id=$(echo "$row" | awk '{print $2}')
+    /usr/bin/grep -q "^## ${id} " "$f" || echo "ORPHAN INDEX: $id in $f"
+  done
+done
+echo "(blank above = OK)"
+
+wc -l .claude/memory/*.md | grep -v "\.original\.md"
+```
+
+Report:
+
+```
+PRUNE COMPLETE
+  decisions.md : 226 → 184 lines (-19%)
+  learnings.md : 190 → 165 lines (-13%)
+  blockers.md  : no candidates
+  journal.md   :  88 → 62 lines (-30%)
+  evals.md     : no candidates
+
+INDEX SANITY: OK
+NEXT: review `git diff .claude/memory/`, then `/commit-change`
+```
+
+## What NOT to prune
+
+- Journal entries < 30 days old.
+- Decisions / learnings with commit references < 14 days old.
+- Entries the user marked `status: accepted` in the current session.
+- The current session's just-capitalized entries (read `journal.md`
+  tail to identify them).
+
+## Common mistakes
+
+| Mistake | Fix |
+|---------|-----|
+| Renumbering IDs after a merge | IDs are stable. Sources keep their ID + `status: superseded`. New merged entry gets next-free ID. |
+| Hard-deleting "obsolete" entries | Forbidden by append-only rule. Use `status: deprecated`. Body stays. |
+| Compressing code blocks / URLs / error messages | Caveman compression touches PROSE only. Code, URLs, IDs, error quotes stay verbatim. |
+| Running on a dirty working tree | PRECHECK blocks this. Commit first. |
+| Compressing the current session's journal entry | Excluded by "What NOT to prune" — current session capitalization is still useful. |
+| Merging complementary entries that cover different angles | Merge only when same concept, same scope. Different angles = keep separate. |
+
+## Failure paths
+
+| Situation | Behavior |
+|---|---|
+| `.claude/memory/` missing | STOP: `no .claude/memory/ in current directory; run from project root` |
+| Working tree dirty on registry files | STOP per PRECHECK; tell user to commit/stash first |
+| User says `skip` at STEP 2 | Exit cleanly, no writes |
+| Merge produces an entry > 600 words | Re-split — merge was too greedy. Re-prompt user to keep separate. |
+| Index sanity FAILED at STEP 4 | Print exact missing/orphan IDs. Do NOT auto-fix — user re-runs or hand-edits. |
+| Caveman compression result < 20% of original AND original had code blocks | Revert that entry's compression — flag as needing manual rewrite (likely stripped technical detail). |
+| Same file already compressed in same session (e.g. via `/caveman:compress`) | Skip C-category for that file; warn user that double-pass risks technical drift. |
+
+## Rules
+
+- No silent writes — every change goes through STEP 2 approval gate.
+- No renumbering — IDs are stable across all operations.
+- No hard delete in v1 — only mark superseded. (Hard delete opt-in may
+  arrive in v2 if explicit demand surfaces.)
+- Working tree must be clean before any write — git is the only backup.
+- Caveman compression touches prose only; code/URLs/error quotes
+  verbatim per CLAUDE.md memory format rule.
+
+## TDD note (skill itself)
+
+v1 ships without baseline test scenarios per superpowers:writing-skills
+Iron Law. Recommended before relying on the skill in production:
+
+1. RED: spawn subagent, give it a real `.claude/memory/` snapshot, ask
+   "prune obsolete entries". Document what it does naturally.
+2. GREEN: invoke `/prune-memory` on the same snapshot. Verify it
+   follows STEP 0–4 + respects append-only rule.
+3. REFACTOR: log any new rationalizations the subagent finds; add
+   counters to the "Common mistakes" / "Failure paths" tables.
+
+Until TDD is done, the skill is v1-untested. STEP 2 approval gate is
+the human safety net.