feat(capitalize): merge /close into /capitalize + TODO reconcile
Two-mode capitalize: default pre-wipe flush, --ritual adds the 3-question end-of-session reflection (now deduped, unlike legacy /close). New STEP 2B reconciles .claude/tasks/TODO.md — PASS A done-detection (only on an unambiguous task<->commit map), PASS B explicit-only capture with an anti-noise filter (never track commit/deploy/push/release/tag) and BDR routing for orientation directives. STEP 3 gate gains a separate TODO block; journal/handoff report TODO ops. /close becomes a thin alias for /capitalize --ritual (zero duplicated logic). Built via superpowers:writing-skills TDD: RED baseline (no skill) folded a push/tag parasite into the TODO, invented a subtask, and wrote with no gate; GREEN re-run on the same fixture stops at the gate, drops both dups (footer shows existing IDs), logs one learning, checks only the cleanly-done task, ignores the parasite, and routes the GraphQL directive to BDR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X3e8LaH2vymmxyh36h3jFU
This commit is contained in:
parent
a4e0425581
commit
9dc2b83f0e
@ -1,61 +0,0 @@
|
||||
$ClaudeDir = if ($env:CLAUDE_CONFIG_DIR) { $env:CLAUDE_CONFIG_DIR } else { Join-Path $HOME ".claude" }
|
||||
$Flag = Join-Path $ClaudeDir ".caveman-active"
|
||||
if (-not (Test-Path $Flag)) { exit 0 }
|
||||
|
||||
# Refuse reparse points (symlinks / junctions) and oversized files. Without
|
||||
# this, a local attacker could point the flag at a secret file and have the
|
||||
# statusline render its bytes (including ANSI escape sequences) to the terminal
|
||||
# every keystroke.
|
||||
try {
|
||||
$Item = Get-Item -LiteralPath $Flag -Force -ErrorAction Stop
|
||||
if ($Item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { exit 0 }
|
||||
if ($Item.Length -gt 64) { exit 0 }
|
||||
} catch {
|
||||
exit 0
|
||||
}
|
||||
|
||||
$Mode = ""
|
||||
try {
|
||||
$Raw = Get-Content -LiteralPath $Flag -TotalCount 1 -ErrorAction Stop
|
||||
if ($null -ne $Raw) { $Mode = ([string]$Raw).Trim() }
|
||||
} catch {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Strip anything outside [a-z0-9-] — blocks terminal-escape and OSC hyperlink
|
||||
# injection via the flag contents. Then whitelist-validate.
|
||||
$Mode = $Mode.ToLowerInvariant()
|
||||
$Mode = ($Mode -replace '[^a-z0-9-]', '')
|
||||
|
||||
$Valid = @('off','lite','full','ultra','wenyan-lite','wenyan','wenyan-full','wenyan-ultra','commit','review','compress')
|
||||
if (-not ($Valid -contains $Mode)) { exit 0 }
|
||||
|
||||
$Esc = [char]27
|
||||
if ([string]::IsNullOrEmpty($Mode) -or $Mode -eq "full") {
|
||||
[Console]::Write("${Esc}[38;5;172m[CAVEMAN]${Esc}[0m")
|
||||
} else {
|
||||
$Suffix = $Mode.ToUpperInvariant()
|
||||
[Console]::Write("${Esc}[38;5;172m[CAVEMAN:$Suffix]${Esc}[0m")
|
||||
}
|
||||
|
||||
# Savings suffix: on by default. Opt out via CAVEMAN_STATUSLINE_SAVINGS=0.
|
||||
# Reads a pre-rendered string written by caveman-stats.js. Refuses reparse
|
||||
# points and strips control bytes (matches statusline.sh hardening). Until
|
||||
# /caveman-stats has run at least once, the suffix file is absent and nothing
|
||||
# is rendered — safe default for fresh installs.
|
||||
if ($env:CAVEMAN_STATUSLINE_SAVINGS -ne "0") {
|
||||
$SavingsFile = Join-Path $ClaudeDir ".caveman-statusline-suffix"
|
||||
if (Test-Path $SavingsFile) {
|
||||
try {
|
||||
$SavingsItem = Get-Item -LiteralPath $SavingsFile -Force -ErrorAction Stop
|
||||
if (-not ($SavingsItem.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -and
|
||||
$SavingsItem.Length -le 64) {
|
||||
$Savings = (Get-Content -LiteralPath $SavingsFile -Raw -ErrorAction Stop).TrimEnd()
|
||||
$Savings = ($Savings -replace '[\x00-\x1F]', '')
|
||||
if ($Savings.Length -gt 0) {
|
||||
[Console]::Write(" ${Esc}[38;5;172m$Savings${Esc}[0m")
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,19 @@
|
||||
---
|
||||
name: capitalize
|
||||
description: |
|
||||
Use when about to /clear or /compact and the current conversation holds
|
||||
decisions, learnings, blockers, or eval results that were never written to
|
||||
`.claude/memory/`. Use to flush important uncapitalized context before it is
|
||||
wiped, or when unsure whether the session's insights already reached the
|
||||
registries. NOT the fresh end-of-session ritual (that is /close) and NOT
|
||||
Use when about to /clear or /compact, or when closing a session, and the
|
||||
conversation holds decisions, learnings, blockers, eval results, or
|
||||
finished/new TODO items not yet written to `.claude/memory/` or
|
||||
`.claude/tasks/TODO.md`. Plain invocation = pre-wipe flush; `--ritual` (or the
|
||||
word "close"/"ritual" in the request) = end-of-session reflection mode. NOT
|
||||
registry curation (that is /prune-memory).
|
||||
Triggers: "capitalize", "capitalise", "before clear", "before compact",
|
||||
"save before clear", "flush memory", "don't lose this", "what's not logged
|
||||
yet", "avant de clear", "avant compact", "sauvegarde avant clear",
|
||||
"capitalise ce qui manque".
|
||||
argument-hint: (none — scans the current conversation against .claude/memory/)
|
||||
"capitalise ce qui manque", "close", "end session", "session close",
|
||||
"ferme la session", "checkpoint memory", "what did we learn", "retro rapide",
|
||||
"fin de journée".
|
||||
argument-hint: "[--ritual] (scans conversation + git + TODO against .claude/memory/; --ritual adds the 3-question reflection)"
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Edit
|
||||
@ -22,27 +24,31 @@ allowed-tools:
|
||||
- AskUserQuestion
|
||||
---
|
||||
|
||||
# /capitalize — Flush uncapitalized context before a wipe
|
||||
# /capitalize — Flush uncapitalized context (two modes)
|
||||
|
||||
Salvage the registry-worthy insights from **this conversation** that were
|
||||
never written down, right before `/clear` or `/compact` destroys them.
|
||||
Salvage the registry-worthy insights from **this conversation** that were never
|
||||
written down — before `/clear` or `/compact` destroys them, or as a deliberate
|
||||
end-of-session ritual. Also reconciles `.claude/tasks/TODO.md` against what
|
||||
actually shipped.
|
||||
|
||||
Operates on conversation memory + git state + the existing registries. Does
|
||||
NOT re-read source code.
|
||||
Operates on conversation memory + git state + the existing registries + the
|
||||
TODO. Does NOT re-read source code.
|
||||
|
||||
## What makes this different from /close
|
||||
## Modes
|
||||
|
||||
| Situation | Skill |
|
||||
|-----------|-------|
|
||||
| About to `/clear` or `/compact` — salvage what the session produced but never logged | **/capitalize** (this) |
|
||||
| Deliberate end-of-session ritual, fresh 3-question prompt | `/close` |
|
||||
| Registries too long / noisy — curate, merge, compress | `/prune-memory` |
|
||||
| Token-compress one registry file | `/caveman:compress <file>` |
|
||||
| Mode | How triggered | Adds |
|
||||
|------|---------------|------|
|
||||
| **default** (pre-wipe flush) | plain `/capitalize`, "before clear", "flush memory" | auto-scan + dedup + TODO reconcile |
|
||||
| **--ritual** (session-close) | `--ritual` flag, OR `$ARGUMENTS` contains "close"/"ritual", OR invoked via `/close` | everything above **+ STEP 1B** 3-question reflection |
|
||||
|
||||
The signature move of THIS skill is **STEP 2 — DEDUP**: every candidate is
|
||||
checked against what is already in the registries, and anything already
|
||||
captured is dropped silently. `/close` does not dedup; it asks fresh. Running
|
||||
`/capitalize` right after a `/close` should propose (near) nothing.
|
||||
Detect the mode first. Both modes share the SAME dedup (STEP 2), TODO reconcile
|
||||
(STEP 2B), and approval gate (STEP 3). The signature move is **STEP 2 — DEDUP**:
|
||||
every candidate is checked against what is already in the registries, and
|
||||
anything already captured is dropped (its existing ID shown in the footer).
|
||||
Running `/capitalize` right after a ritual should propose (near) nothing.
|
||||
|
||||
This skill is NOT `/prune-memory` (registry curation — merge, compress,
|
||||
mark-superseded). It only appends.
|
||||
|
||||
## STEP 0 — PRECHECK
|
||||
|
||||
@ -50,6 +56,7 @@ captured is dropped silently. `/close` does not dedup; it asks fresh. Running
|
||||
ls .claude/memory/decisions.md .claude/memory/learnings.md \
|
||||
.claude/memory/blockers.md .claude/memory/evals.md \
|
||||
.claude/memory/journal.md 2>/dev/null
|
||||
ls .claude/tasks/TODO.md 2>/dev/null
|
||||
```
|
||||
|
||||
- `.claude/memory/` missing entirely → print and STOP (do NOT create here —
|
||||
@ -58,8 +65,11 @@ ls .claude/memory/decisions.md .claude/memory/learnings.md \
|
||||
⚠️ .claude/memory/ absent. Lance `/onboard` (ou `/init-project`) pour créer
|
||||
les registres avant de capitaliser.
|
||||
```
|
||||
- Some files missing → name them, create each from
|
||||
- Some registry files missing → name them, create each from
|
||||
`~/.claude/templates/memory/<name>.md`, continue.
|
||||
- `.claude/tasks/TODO.md` missing → the TODO reconcile volet (STEP 2B) is
|
||||
**skipped**. Do NOT create it (same posture as the registries). Registries
|
||||
still run.
|
||||
|
||||
## STEP 1 — SCAN THE CONVERSATION
|
||||
|
||||
@ -83,34 +93,50 @@ git status --short
|
||||
date +%Y-%m-%d
|
||||
```
|
||||
|
||||
For each candidate, draft the fields the target registry's schema expects
|
||||
(read the YAML header of that file if unsure — e.g. decisions need
|
||||
decision/why/alternatives; blockers need friction/real_cause/solution/status).
|
||||
For each candidate, draft the fields the target registry's schema expects (read
|
||||
the YAML header of that file if unsure).
|
||||
|
||||
**Skip the trivial.** If it is reversible in under 10 min with no cross-file
|
||||
impact, it is not a decision. If it is a one-shot fact, not a reusable
|
||||
pattern, it is not a learning. Noise hurts the every-session re-read.
|
||||
impact, it is not a decision. If it is a one-shot fact, not a reusable pattern,
|
||||
it is not a learning. Noise hurts the every-session re-read.
|
||||
|
||||
**One incident → one primary registry.** Do not fan a single event across
|
||||
registries. A resolved gotcha that cost time is a *learning* (the reusable
|
||||
pattern) — not *also* a blocker. Open a blocker only when the friction is
|
||||
unresolved, or when the friction itself (not the lesson) is the durable
|
||||
record. The same event written to two registries is a near-duplicate in the
|
||||
unresolved, or when the friction itself (not the lesson) is the durable record.
|
||||
The same event written to two registries is a near-duplicate in the
|
||||
every-session re-read.
|
||||
|
||||
## STEP 1B — RITUAL REFLECTION (only in --ritual mode)
|
||||
|
||||
Default mode skips this entirely. In ritual mode, after the auto-scan, force the
|
||||
end-of-session reflection — three questions that surface what the scan may have
|
||||
missed:
|
||||
|
||||
1. **What did you decide?** → decisions.md (BDR)
|
||||
2. **What did you learn?** → learnings.md (LRN)
|
||||
3. **What blocked you?** → blockers.md (BLK)
|
||||
|
||||
Each answer becomes an additional candidate. It does NOT bypass dedup: every
|
||||
ritual answer flows into STEP 2 exactly like an auto-scanned candidate. A
|
||||
reflection answer that is already captured is **dropped, and its existing
|
||||
`<ID>` is shown in the footer** — same as any other dup, never re-logged. This
|
||||
is the key difference from the legacy `/close`, which wrote ritual answers fresh
|
||||
with no dedup.
|
||||
|
||||
## STEP 2 — DEDUP AGAINST THE REGISTRIES ★ the whole point
|
||||
|
||||
For every candidate from STEP 1, check whether it is already captured before
|
||||
proposing it. Pull the distinctive keyword(s) of the candidate and grep the
|
||||
relevant registry (Index + bodies):
|
||||
For every candidate from STEP 1 (and STEP 1B), check whether it is already
|
||||
captured before proposing it. Pull the distinctive keyword(s) of the candidate
|
||||
and grep the relevant registry (Index + bodies):
|
||||
|
||||
```bash
|
||||
# Example: candidate is a learning about "cd -P symlink resolution"
|
||||
grep -niE 'symlink|cd -P|BASH_SOURCE' .claude/memory/learnings.md
|
||||
```
|
||||
|
||||
Also scan the journal tail for `<ID> capitalized` lines — the session may
|
||||
have already logged it earlier:
|
||||
Also scan the journal tail for `<ID> capitalized` lines — the session may have
|
||||
already logged it earlier:
|
||||
|
||||
```bash
|
||||
grep -nE '(BDR|LRN|BLK|EVAL)-[0-9]+ capitalized' .claude/memory/journal.md | tail -20
|
||||
@ -124,16 +150,55 @@ Classify each candidate:
|
||||
flag `⚠ maybe dup of <ID> — confirm or skip`.
|
||||
- **NEW** — no match → propose it normally.
|
||||
|
||||
Dedup is semantic, not string-equality. Same root cause described two ways is
|
||||
still a dup.
|
||||
Dedup is **semantic, not string-equality**. The same insight reworded with
|
||||
different vocabulary is still a dup — read the registry entries and reason about
|
||||
meaning, do not rely on keyword grep alone. (A reworded "Tailwind classes built
|
||||
by concatenation get purged at build" still matches an existing "purge strips
|
||||
concatenated class names" entry.)
|
||||
|
||||
## STEP 2B — TODO RECONCILE (both modes)
|
||||
|
||||
Runs only if `.claude/tasks/TODO.md` exists (STEP 0). Two passes.
|
||||
|
||||
**PASS A — done-detection (TODO → reality).** For each unchecked `- [ ]`, decide
|
||||
whether the session actually finished it, grounding on git (`git log`,
|
||||
`git diff HEAD`, `git show`) AND the conversation. Propose `[x]` ONLY when the
|
||||
task ↔ commit/code map is unambiguous (task "add retry-with-backoff" ↔ a commit
|
||||
that adds exactly that).
|
||||
- Partial / umbrella tasks ("harden X" covering 3 things when only 1 shipped) →
|
||||
leave unchecked.
|
||||
- Vague tasks ("Commit", "Deploy", "test it") with no precise git evidence →
|
||||
leave unchecked. Never check on assumption or on a guess.
|
||||
|
||||
**PASS B — capture (conversation → TODO).** Spot explicit to-dos voiced in the
|
||||
session ("il faut X", "TODO Y", "à corriger Z", new directives) that are absent
|
||||
from the TODO → propose adding them as `- [ ]`. Dedup semantically against
|
||||
existing items first. Capture ONLY what was explicitly stated — do not invent,
|
||||
expand, or decompose a task into subtasks the user never named.
|
||||
|
||||
**Anti-noise filter (PASS B).** NEVER add — or fold into an existing item —
|
||||
commit / deploy / push / release / tag actions. These are systematic steps the
|
||||
user performs every session, not tracked work. "push la branche + tag v0.3.0" is
|
||||
noise even when phrased with action verbs. If such an item ALREADY exists in the
|
||||
TODO, PASS A may check it when proven done, but PASS B never creates it nor
|
||||
enriches one with session-derived push/tag/release detail.
|
||||
|
||||
**Routing.** A directive that changes the project's ORIENTATION (a policy /
|
||||
architecture choice, e.g. "GraphQL for all new endpoints from now on") is a
|
||||
DECISION, not a task → it flows through STEP 1 into decisions.md (BDR), never
|
||||
into the TODO. Don't confuse an actionable task with an architecture decision.
|
||||
|
||||
**Language.** The TODO is **NOT caveman**. Tasks stay in readable, actionable
|
||||
prose. Caveman is reserved for the `.claude/memory/` registries (STEP 4).
|
||||
|
||||
## STEP 3 — PRESENT PLAN ★ MANDATORY STOP (approval gate)
|
||||
|
||||
One compact screen. Pre-filled drafts, caveman-English bodies (registry rule).
|
||||
Group by registry. Mark dup flags inline.
|
||||
One compact screen. Pre-filled drafts — registry bodies in caveman-English, TODO
|
||||
lines in plain prose. Group by registry, then a **SEPARATE TODO.md block**. Mark
|
||||
dup flags inline.
|
||||
|
||||
```
|
||||
═══ CAPITALIZE — uncapitalized context before wipe ═══
|
||||
═══ CAPITALIZE — <pre-wipe flush | session-close ritual> ═══
|
||||
|
||||
decisions.md
|
||||
▸ NEW BDR-019 <title>
|
||||
@ -149,17 +214,28 @@ blockers.md
|
||||
evals.md
|
||||
▸ NEW EVAL-003 <output> — <method> — <anomalies> — action: <keep|correct|deprecate>
|
||||
|
||||
TODO.md
|
||||
☑ check "<task>" (done @ <hash> | conversation)
|
||||
+ add "[ ] <new task>" (said in session, absent)
|
||||
|
||||
Already captured this session (dropped): LRN-023, BLK-006
|
||||
Ignored as noise: "push branch + tag v0.3.0" (systematic action)
|
||||
|
||||
Action ? (all / pick <IDs> / edit <ID> / skip-all)
|
||||
```
|
||||
|
||||
If a registry has zero NEW + zero DUP → print `(rien de neuf — déjà à jour)`.
|
||||
The **TODO.md block is approved / edited / skipped INDEPENDENTLY** of the
|
||||
registry blocks. If a section has zero NEW + zero DUP → print
|
||||
`(rien de neuf — déjà à jour)`. If a dup was dropped (incl. a ritual answer),
|
||||
name its existing ID on the `Already captured` line. If the anti-noise filter
|
||||
dropped a parasite, name it on the `Ignored as noise` line (no silent drops).
|
||||
Wait for input. Default = nothing written (journal line still goes in STEP 5).
|
||||
|
||||
## STEP 4 — WRITE APPROVED ENTRIES
|
||||
|
||||
For each approved entry, in registry order:
|
||||
Registries first (in registry order), then the TODO.
|
||||
|
||||
Registry entries — for each approved:
|
||||
|
||||
1. Read the target registry file.
|
||||
2. Next sequential ID = scan existing `## <PREFIX>-NNN` body headings, take max,
|
||||
@ -173,6 +249,12 @@ For each approved entry, in registry order:
|
||||
verbatim. Entries are ALWAYS English even if the STEP 3 prompt mirrored the
|
||||
user's language.
|
||||
|
||||
TODO — for each approved:
|
||||
|
||||
- **Check**: flip the exact `- [ ]` line to `- [x]`, leaving the text unchanged.
|
||||
- **Add**: append `- [ ] <task>` under the right `##` section (create a section
|
||||
only if none fits). Plain readable prose, NOT caveman.
|
||||
|
||||
## STEP 5 — JOURNAL LINE (always)
|
||||
|
||||
Write one timeline line under today's `## YYYY-MM-DD` heading — even if every
|
||||
@ -181,36 +263,49 @@ candidate was skipped or already captured.
|
||||
- Heading exists → append a bullet.
|
||||
- Missing → create `## YYYY-MM-DD` and write 3-5 bullets summarizing the session.
|
||||
|
||||
Reference any IDs written this run: `BDR-019 + LRN-026 capitalized before /clear.`
|
||||
Reference any IDs written this run AND the TODO ops:
|
||||
`BDR-019 + LRN-026 capitalized; checked 1 done, added 1 task.`
|
||||
|
||||
## STEP 6 — FINAL OUTPUT + HANDOFF
|
||||
|
||||
```
|
||||
CAPITALIZE COMPLETE — <YYYY-MM-DD> (pre-wipe flush)
|
||||
CAPITALIZE COMPLETE — <YYYY-MM-DD> (<pre-wipe flush | session-close>)
|
||||
decisions.md : +<N> (BDR-019) | 0
|
||||
learnings.md : +<N> (LRN-026) | 0
|
||||
blockers.md : 0 — already up to date
|
||||
evals.md : +<N> (EVAL-003) | 0
|
||||
TODO.md : checked <N>, added <M>
|
||||
journal.md : +1 line under ## <date>
|
||||
dropped as already-captured: LRN-023, BLK-006
|
||||
|
||||
✅ Context flushed. Safe to /clear or /compact now.
|
||||
ignored as noise: push/tag release
|
||||
```
|
||||
|
||||
The closing line matters — this skill exists to make the wipe safe, so confirm
|
||||
it explicitly.
|
||||
Then the mode-specific closing line:
|
||||
|
||||
- **pre-wipe flush** → `✅ Context flushed. Safe to /clear or /compact now.`
|
||||
- **session-close ritual** → `✅ Session closed. Next session: read .claude/memory/ at startup.`
|
||||
|
||||
The closing line matters — confirm the wipe is safe (default) or the session is
|
||||
checkpointed (ritual).
|
||||
|
||||
## Rules
|
||||
|
||||
- **Never invent.** Every entry grounded in this conversation or git history.
|
||||
No fabricated "lessons" to fill the screen.
|
||||
- **Dedup before proposing.** Re-logging an existing entry is the #1 failure
|
||||
mode of this skill. When in doubt, flag as `⚠ DUP?` and let the user decide —
|
||||
never silently create a near-duplicate.
|
||||
- **Append-only.** Never overwrite or renumber existing entries.
|
||||
- **Caveman English** bodies, always English, per CLAUDE.md memory format.
|
||||
- **Journal always writes**, even on `skip-all` — timeline logging is cheap and
|
||||
noise-tolerant.
|
||||
- **Never invent.** Every entry grounded in this conversation or git history. No
|
||||
fabricated "lessons" to fill the screen, no invented TODO subtasks.
|
||||
- **Dedup before proposing.** Re-logging an existing entry is the #1 failure mode.
|
||||
When in doubt, flag as `⚠ DUP?` and let the user decide. Dedup is semantic —
|
||||
a reworded dup is still a dup. Applies to ritual answers too.
|
||||
- **Append-only.** Never overwrite or renumber existing registry entries.
|
||||
- **Caveman English** registry bodies, always English. **The TODO is plain
|
||||
prose, never caveman** — caveman is registries-only.
|
||||
- **TODO reconcile runs only if TODO.md exists.** Never create it (STEP 0).
|
||||
- **PASS A checks only on an unambiguous task↔code/commit map.** Partial /
|
||||
umbrella / vague → leave unchecked. Never on assumption.
|
||||
- **PASS B captures only explicit to-dos**, deduped — never invented or
|
||||
decomposed.
|
||||
- **Anti-noise**: never track commit / deploy / push / release / tag.
|
||||
- **Orientation directive → decisions.md (BDR)**, not the TODO.
|
||||
- **Journal always writes**, even on `skip-all`.
|
||||
- **Skip trivial** for the 4 ID registries; journal excepted.
|
||||
- `.claude/memory/` missing → STOP at STEP 0, do not create the structure here.
|
||||
|
||||
@ -218,35 +313,48 @@ it explicitly.
|
||||
|
||||
| Mistake | Fix |
|
||||
|---------|-----|
|
||||
| Proposing items already in the registries | STEP 2 dedup is mandatory. Grep keywords + journal `capitalized` lines first. |
|
||||
| Re-running after `/close` and re-logging the same items | Expected output after `/close` is `(rien de neuf)`. If it proposes the just-closed items, dedup failed. |
|
||||
| Proposing items already in the registries | STEP 2 dedup is mandatory. Grep keywords + read entries + journal `capitalized` lines first. |
|
||||
| Re-running after a ritual and re-logging the same items | Expected output after a ritual is `(rien de neuf)`. If it proposes the just-closed items, dedup failed. |
|
||||
| Treating a reworded insight as new | Dedup is semantic, not lexical. Read the entry's meaning, not just its keywords. |
|
||||
| Renumbering or reusing an ID | IDs are stable + sequential. Max existing +1. |
|
||||
| Writing prose bodies | Registries are caveman-English. Fragments, no articles/filler. |
|
||||
| Writing prose registry bodies | Registries are caveman-English. Fragments, no articles/filler. (TODO stays prose.) |
|
||||
| Logging a trivial reversible tweak as a decision | Decision = tradeoff you'd defend, cross-file or >10 min to reverse. Else skip. |
|
||||
| Fanning one incident across registries (e.g. a resolved gotcha as both LRN and BLK) | One incident → one primary registry. Reusable pattern → LRN. Unresolved friction / the friction itself → BLK. Don't write the same event twice. |
|
||||
| French/English entry text | Prompt may be French; written entry is always English. |
|
||||
| Creating `.claude/memory/` when absent | Not this skill's job — STOP and point to `/onboard`. |
|
||||
| Fanning one incident across registries (a resolved gotcha as both LRN and BLK) | One incident → one primary registry. Reusable pattern → LRN. Unresolved friction / the friction itself → BLK. |
|
||||
| Folding push / tag / release / deploy into the TODO | Anti-noise filter. Those are systematic actions, not tracked work — drop them, even phrased as tasks. |
|
||||
| Checking an umbrella/partial task because "some of it shipped" | PASS A needs the WHOLE task proven done with a clear git map. Partial → leave unchecked. |
|
||||
| Inventing a subtask the user never voiced | PASS B captures only explicit to-dos. No decomposition, no expansion. |
|
||||
| Dumping an architecture directive as a TODO task | Route orientation/policy directives to decisions.md (BDR), not the TODO. |
|
||||
| Writing a ritual answer fresh without dedup | Ritual answers go through STEP 2 like any candidate; a dup shows its existing ID. |
|
||||
| French/English entry text | Prompt may be French; written registry entry is always English. |
|
||||
| Creating `.claude/memory/` or `.claude/tasks/TODO.md` when absent | Not this skill's job — registries STOP and point to `/onboard`; TODO volet is skipped. |
|
||||
|
||||
## Red flags — STOP
|
||||
|
||||
- About to append an entry without having grepped the registry for it → dedup skipped.
|
||||
- Proposing 6+ entries from a short conversation → over-capturing noise; keep only what you'd defend.
|
||||
- Rewriting an existing entry "to update it" → append-only violation; add a new entry with `supersedes`.
|
||||
- Same incident headed for two registries (LRN + BLK for one event) → pick the one primary registry.
|
||||
- About to append a registry entry without having grepped + read the registry
|
||||
for it → dedup skipped.
|
||||
- About to treat a reworded item as new without checking meaning → semantic
|
||||
dedup skipped.
|
||||
- Proposing 6+ entries from a short conversation → over-capturing noise.
|
||||
- Rewriting an existing entry "to update it" → append-only violation; add a new
|
||||
entry with `supersedes`.
|
||||
- Same incident headed for two registries (LRN + BLK for one event) → pick one.
|
||||
- About to add / relabel a TODO item with push / tag / release / deploy → noise.
|
||||
- About to check a `- [ ]` with no commit/code proving the WHOLE task done → stop.
|
||||
- About to write a TODO item the user never explicitly asked for → stop.
|
||||
- Writing the TODO in caveman → TODO is plain prose.
|
||||
|
||||
## TDD note (skill itself)
|
||||
|
||||
v1 ships without baseline pressure tests per superpowers:writing-skills Iron
|
||||
Law. The STEP 3 approval gate is the human safety net (same posture as
|
||||
`/prune-memory` v1). Recommended baseline before relying on it:
|
||||
Baseline (RED, 2026-06-19): a no-skill agent on a pressured fixture deduped
|
||||
correctly (incl. a reworded semantic dup), routed an architecture directive to
|
||||
BDR, and checked a cleanly-done task — but (a) folded a "push branch + tag
|
||||
release" parasite into the TODO, (b) invented a subtask the user never voiced,
|
||||
(c) wrote everything with no approval stop, and (d) fanned one incident across
|
||||
two registries on an earlier run (non-deterministic). This skill's mandatory
|
||||
gate (STEP 3), anti-noise filter (STEP 2B), explicit-only capture, and
|
||||
one-incident-one-registry rule make those deterministic.
|
||||
|
||||
1. **RED** — give a subagent a synthetic transcript containing 2
|
||||
already-captured insights + 1 genuinely new learning, plus a registry
|
||||
snapshot. Ask it to "save what matters before /clear" WITHOUT this skill.
|
||||
Document whether it re-logs the captured ones (no dedup) or misses the new one.
|
||||
2. **GREEN** — invoke `/capitalize` on the same inputs. Verify STEP 2 drops the
|
||||
2 dups and proposes only the 1 new entry.
|
||||
3. **REFACTOR** — log any new rationalization (e.g. "it's basically the same so
|
||||
I'll just append anyway") and add a counter to Common mistakes / Red flags.
|
||||
|
||||
Until done, treat as v1-untested; the approval gate gates every write.
|
||||
GREEN re-run on the same fixture must: stop at the gate, drop both dups (footer
|
||||
shows existing IDs), log jigsaw as ONE learning, check only the cleanly-done
|
||||
task, leave the umbrella "harden" task unchecked, add only the explicit README
|
||||
to-do, ignore the push/tag parasite, and route the GraphQL directive to BDR.
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
---
|
||||
name: close
|
||||
description: |
|
||||
End-of-session ritual — capitalize the 3 registry questions: what was
|
||||
decided, what was learned, what was blocked. Writes approved entries
|
||||
into `.claude/memory/decisions.md`, `.claude/memory/learnings.md`, and
|
||||
`.claude/memory/blockers.md`, plus a timeline line in `.claude/memory/journal.md`.
|
||||
Trigger: "close", "end session", "ferme la session", "session close",
|
||||
End-of-session ritual — flush what was decided, learned, and blocked into
|
||||
`.claude/memory/`, reconcile `.claude/tasks/TODO.md`, and log a journal line.
|
||||
Alias for `/capitalize --ritual`: same dedup + TODO-reconcile + approval-gate
|
||||
pipeline, plus the explicit 3-question reflection. NOT registry curation
|
||||
(that is /prune-memory).
|
||||
Triggers: "close", "end session", "ferme la session", "session close",
|
||||
"checkpoint memory", "what did we learn", "retro rapide", "fin de journée".
|
||||
argument-hint: (none — operates on the current conversation context)
|
||||
argument-hint: (none — runs capitalize in ritual mode on the current conversation)
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Edit
|
||||
@ -15,124 +16,22 @@ allowed-tools:
|
||||
- Bash
|
||||
- Grep
|
||||
- Glob
|
||||
- AskUserQuestion
|
||||
---
|
||||
|
||||
# CLOSE — Session-Close Ritual
|
||||
# /close — Session-close ritual (alias)
|
||||
|
||||
Capture the 3 registry-worthy outputs from the current session before losing context. Operates entirely on conversation memory + git state — does NOT re-read code.
|
||||
`/close` is an alias for **`/capitalize --ritual`**. All logic lives in the
|
||||
**capitalize** skill — nothing is duplicated here.
|
||||
|
||||
## STEP 0 — PRECHECK
|
||||
Invoke the `capitalize` skill now and run it in **ritual mode**: the full
|
||||
pipeline (STEP 0 precheck → STEP 1 auto-scan → STEP 2 dedup → STEP 2B TODO
|
||||
reconcile → STEP 3 approval gate → STEP 4 write → STEP 5 journal → STEP 6
|
||||
handoff), PLUS STEP 1B's explicit 3-question reflection (what did you decide /
|
||||
learn / block).
|
||||
|
||||
Verify the registry files exist:
|
||||
Ritual answers are deduped like any other candidate — a dup is dropped and its
|
||||
existing ID shown, not re-logged. This is the upgrade over the legacy `/close`,
|
||||
which wrote ritual answers fresh with no dedup.
|
||||
|
||||
```bash
|
||||
ls .claude/memory/decisions.md .claude/memory/learnings.md .claude/memory/blockers.md .claude/memory/journal.md 2>/dev/null
|
||||
```
|
||||
|
||||
- If `.claude/memory/` is missing entirely → print:
|
||||
```
|
||||
⚠️ .claude/memory/ absent. Lance d'abord `/onboard` (ou `/init-project` pour un nouveau repo)
|
||||
pour créer la structure des registres.
|
||||
```
|
||||
STOP.
|
||||
- If some files are missing → print which, create them from `~/.claude/templates/memory/<name>.md`, continue.
|
||||
|
||||
## STEP 1 — GATHER SESSION CONTEXT
|
||||
|
||||
Collect the raw material without re-reading code:
|
||||
|
||||
```bash
|
||||
git log --oneline -10
|
||||
git diff HEAD --stat
|
||||
git status --short
|
||||
date +%Y-%m-%d
|
||||
```
|
||||
|
||||
Extract from current conversation:
|
||||
- Any decision made (framework pick, refactor scope, architecture choice, naming convention).
|
||||
- Any learning surfaced (surprising API behaviour, reusable pattern, gotcha, "don't do X").
|
||||
- Any blocker encountered (dead end, friction > 15 min wasted, upstream bug).
|
||||
|
||||
## STEP 2 — THE 3 QUESTIONS
|
||||
|
||||
Present the ritual compactly — one screen, 3 questions, pre-filled draft answers from STEP 1:
|
||||
|
||||
```
|
||||
═══ SESSION-CLOSE RITUAL — 3 QUESTIONS ═══
|
||||
|
||||
1️⃣ Qu'est-ce que tu as décidé ?
|
||||
Proposition BDR-XXX :
|
||||
Titre : <extrait de la conversation>
|
||||
Décision: <1 phrase>
|
||||
Pourquoi: <1-2 phrases>
|
||||
Alts rejetées: <si captable>
|
||||
→ (accept / edit / skip / add another)
|
||||
|
||||
2️⃣ Qu'est-ce que tu as appris ?
|
||||
Proposition LRN-XXX :
|
||||
Pattern : <extrait abstrait>
|
||||
Contexte: <où/quand>
|
||||
Future : <quand s'en rappeler>
|
||||
→ (accept / edit / skip / add another)
|
||||
|
||||
3️⃣ Sur quoi es-tu bloqué ?
|
||||
Proposition BLK-XXX :
|
||||
Friction : <extrait>
|
||||
Cause : <si identifiée — sinon "à investiguer">
|
||||
Solution : <workaround si déjà trouvé — sinon "open">
|
||||
Statut : open | resolved | upstream
|
||||
→ (accept / edit / skip / add another)
|
||||
|
||||
Action globale ? (all / pick <numbers> / edit / skip-all)
|
||||
```
|
||||
|
||||
If nothing notable to propose for a given question → say `(rien à logger cette session)` for that question.
|
||||
|
||||
## STEP 3 — WRITE APPROVED ENTRIES
|
||||
|
||||
For each approved entry:
|
||||
|
||||
1. Read the target registry file.
|
||||
2. Append the new entry at the end (never rewrite existing entries).
|
||||
3. Add a line to the Index table at the top with the new ID, date, short title, status.
|
||||
4. Generate next sequential ID by scanning existing IDs (e.g., if `BDR-007` exists, next is `BDR-008`).
|
||||
|
||||
## STEP 4 — JOURNAL ENTRY
|
||||
|
||||
Always write one line in `.claude/memory/journal.md` under today's heading — even if all 3 questions were skipped:
|
||||
|
||||
- If today's heading exists → append a new bullet under it.
|
||||
- If not → create `## YYYY-MM-DD` heading and write 3-5 bullets summarising the session.
|
||||
|
||||
Template:
|
||||
```markdown
|
||||
## YYYY-MM-DD
|
||||
|
||||
- <what was done — 1 line from conversation>
|
||||
- <what was decided — link to BDR-XXX if logged>
|
||||
- <what was learned — link to LRN-XXX if logged>
|
||||
- <what's blocked — link to BLK-XXX if logged>
|
||||
- <commit hashes if any — `<hash1>..<hashN>`>
|
||||
```
|
||||
|
||||
## STEP 5 — FINAL OUTPUT
|
||||
|
||||
```
|
||||
CLOSE COMPLETE — session <YYYY-MM-DD>
|
||||
decisions.md : +<N> entries (BDR-XXX, BDR-YYY) | 0 entries
|
||||
learnings.md : +<N> entries (LRN-XXX) | 0 entries
|
||||
blockers.md : +<N> entries (BLK-XXX) | 0 entries
|
||||
journal.md : +1 line under ## <date>
|
||||
Prochaine session : lire `.claude/memory/` au démarrage pour rappel.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RULES
|
||||
|
||||
- Never invent content. Every entry must be grounded in the current conversation or git history — no fabricated "lessons".
|
||||
- Skip silently rather than log a trivial entry. Journal excepted (timeline logging is cheap, noise is fine).
|
||||
- Never overwrite existing entries — append-only.
|
||||
- If the user says `skip-all` → still write the journal line and exit.
|
||||
- If `.claude/memory/` is missing → STOP at STEP 0, do not create it here (onboard / init-project responsibility).
|
||||
- **Language rule**: written entries are ALWAYS in English (see CLAUDE.md "Memory registries" § Language). The 3-question prompt may mirror the user's language; the appended entries must not.
|
||||
→ Use the Skill tool to launch `capitalize` with argument `--ritual`.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user