From cd375dd74a529447645e1121df7993e6005be9ae Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sat, 27 Jun 2026 12:26:20 +0200 Subject: [PATCH] =?UTF-8?q?feat(capitalize):=20wire=20commit=20include=20(?= =?UTF-8?q?STEP=205B)=20=E2=80=94=20completes=20BDR-034=20rollout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /capitalize + /close predated lib/capitalize-commit.md and never called it, so a standalone flush left memory written but uncommitted (BDR-037). Add STEP 5B: after the content gate (STEP 3) approves entries and STEP 5 writes the journal, commit them surgically via memory-commit.sh — same one-liner as the 6 dev flows. /close is a thin alias, inherits it for free. Journal always writes => memory always pending at 5B => hash non-empty by construction (only rc 3 skips). --- skills/capitalize/SKILL.md | 58 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/skills/capitalize/SKILL.md b/skills/capitalize/SKILL.md index 73fda22..5dcd111 100644 --- a/skills/capitalize/SKILL.md +++ b/skills/capitalize/SKILL.md @@ -263,6 +263,48 @@ candidate was skipped or already captured. Reference any IDs written this run AND the TODO ops: `BDR-019 + LRN-026 capitalized; checked 1 done, added 1 task.` +## STEP 5B — COMMIT THE CAPITALIZED MEMORY (coupled) + +Once the approved entries (STEP 4) and the journal line (STEP 5) are written, +commit them — surgically, via the shared include, exactly like the 6 dev flows. +This closes a wiring gap: `/capitalize` and `/close` predate +`lib/capitalize-commit.md` and never called it, so a flush left memory written +but **uncommitted** (BDR-037). STEP 3 already approved the CONTENT; only the +COMMIT of those approved entries is automated here (the BDR-034 contract). + +Follow `~/.claude/lib/capitalize-commit.md`: + +1. Compose the message from the IDs just written + the mode: + - `chore(memory): — capitalize` (pre-wipe flush) + - `chore(memory): — close ritual` (ritual mode, via /close) + - `chore(memory): journal — capitalize` (journal-only — see note) + +2. Commit via the helper, capturing the hash: + + mem_hash=$(bash "$HOME/.claude/lib/memory-commit.sh" commit "") + rc=$? + +3. Report by (rc, mem_hash): + - **rc 0, hash non-empty** → committed; surface `` in STEP 6. This + is the only success path here (see the invariant below). + - **rc 3** → unsafe git state (detached / merge / rebase) or not a git repo: + memory stays in the working tree, surface the helper's stderr, do NOT retry. + The flush is safe on disk; STEP 6 must say NOT committed, not ✅-all. + - **rc 0, hash EMPTY → must NOT happen from this step.** STEP 5 always writes + the journal line, so memory is ALWAYS pending at 5B → the helper always has + ≥1 change → the hash is non-empty by construction. An empty hash here means + the STEP 5 journal write silently failed upstream — treat it as a bug to + investigate, not a normal "nothing to commit" branch. + +**Journal-only commit is DESIRED, not a side effect.** On `skip-all` (no registry +entries approved) STEP 5 still writes the journal line, so 5B commits +`chore(memory): journal — capitalize`. The journal IS memory; a session-timeline +line is worth committing on its own — intended, mirroring the include's own +journal-only example. + +Surgical scope is the helper's (stages ONLY `.claude/memory` + `.claude/tasks`, +changed-paths-filtered, never `git add -A`). Do NOT hand-roll git here. + ## STEP 6 — FINAL OUTPUT + HANDOFF ``` @@ -273,17 +315,23 @@ CAPITALIZE COMPLETE — () evals.md : + (EVAL-003) | 0 TODO.md : checked , added journal.md : +1 line under ## + committed : (chore(memory): …) | ⚠️ NOT committed (rc 3 — see closing line) dropped as already-captured: LRN-023, BLK-006 ignored as noise: push/tag release ``` 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.` +- **pre-wipe flush** → `✅ Context flushed + committed . Safe to /clear or /compact now.` +- **session-close ritual** → `✅ Session closed + committed . Next session: read .claude/memory/ at startup.` +- **commit skipped (rc 3)** → keep the ✅ on the FLUSH but make the gap loud, never + buried: `✅ Context flushed — ⚠️ NOT committed (); entries safe on disk, commit manually.` + The ✅ covers the write (entries on disk); the ⚠️ marks the commit gap so it is + not read as "all committed". The closing line matters — confirm the wipe is safe (default) or the session is -checkpointed (ritual). +checkpointed (ritual), AND whether the memory was committed (5B) or left for a +manual commit (rc 3). ## Rules @@ -303,6 +351,10 @@ checkpointed (ritual). - **Anti-noise**: never track commit / deploy / push / release / tag. - **Orientation directive → decisions.md (BDR)**, not the TODO. - **Journal always writes**, even on `skip-all`. +- **Commit the flush (STEP 5B)** — content gate (STEP 3) first, then the commit of + approved entries is automated via `lib/capitalize-commit.md` (BDR-034 contract). + The journal always writes → memory is always pending at 5B, so a successful run + always produces a commit; only an unsafe git state (rc 3) skips it. - **Skip trivial** for the 4 ID registries; journal excepted. - `.claude/memory/` missing → STOP at STEP 0, do not create the structure here.