From 096418c3e7c80e5ed6fa2f4076ab10eee9a3aa35 Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Thu, 16 Jul 2026 13:51:15 +0200 Subject: [PATCH] feat(capitalize): auto-persist memory to develop on /close + /capitalize (STEP 5C, BDR-068) --- .claude/memory/decisions.md | 8 ++++++ .claude/tasks/TODO.md | 6 ++++ lib/gitflow-aiguillage.md | 7 +++-- skills/capitalize/SKILL.md | 57 +++++++++++++++++++++++++++++++------ 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/.claude/memory/decisions.md b/.claude/memory/decisions.md index 228113c..4038bfc 100644 --- a/.claude/memory/decisions.md +++ b/.claude/memory/decisions.md @@ -1000,3 +1000,11 @@ rules: - **Safety (git cherry)**: found a STALE abandoned `release/1.0.0` (July-4 prep, 227 commits behind develop, pushed to origin). `git cherry develop release/1.0.0` + content checks confirmed all its real changes (rtk PATH fix, drop-AI-attribution settings backstop, find-skills drop, BLK-016/LRN-098/LRN-101/EVAL-015, all features) ALREADY in develop → nothing orphaned → deleted it (local+origin). Cut fresh v1.0.0 from CURRENT develop, not the stale branch. - **Method**: release-candidate skill gates honored (when-to-release, push) but PREP done manually — backward version (4.0.0→1.0.0) + CHANGELOG restructure exceed the sonnet release-executor's forward-bump assumption (reflection, stays big). LRN candidate: a version RESET is editorial, not mechanical — don't dispatch the forward-only executor for it. - **Status**: SHIPPED. origin main=dc4f78b, develop=6c23d6f, tag v1.0.0 sole tag; v4.0.0 + stale release/1.0.0 removed from origin. + +## BDR-068 — /capitalize + /close auto-persist memory (finish→develop + push); scoped LRN-069 exception — 2026-07-16 +- **Decision**: when /capitalize (or /close = --ritual) writes entries AND the aiguillage branched a `chore/` off develop THIS run, new STEP 5C auto-finishes that branch → develop + pushes origin/develop. Default ON. `--no-push` holds it on the chore branch (pre-BDR-068 behavior). WORKING branch (memory rides feature/bugfix) or rc-3 commit-fail → 5C skips. push-fail → merge already local, report + manual push (no retry/reset). +- **Why**: memory's value = cross-session persistence; a ritual commit stranded on an unmerged chore branch is INVISIBLE to the next session on develop → the ritual defeats itself (user-identified gap). Memory = append-only/low-risk; the human-gated MERGE (aiguillage) is a CODE safeguard, and LRN-069's push-gate guards surprise CODE/release pushes — neither applies to an end-of-session memory persist. +- **Scope**: /capitalize + /close ONLY. /prune-memory + /reconcile stay fully human-gated (curation/report may want review before landing). NEVER auto-finish a branch the run did not create. +- **Amends**: [[LRN-069]] (push needs explicit go) — scoped exception for memory-only ritual persist; `gitflow-aiguillage.md` "never gitflow finish" — carved for capitalize/close. +- **Files**: skills/capitalize/SKILL.md (STEP 5C + aiguillage branch-capture + STEP 6 outcomes + Rules + arg-hint `--no-push`), lib/gitflow-aiguillage.md (exception note). Tests unaffected (run-deterministic covers memory-commit.sh surgical scope, not the persist step). +- **Status**: implemented on feature/close-auto-persist, UNMERGED (human gate). diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index bd3ceb5..feee292 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -1,5 +1,11 @@ # TODO +## 2026-07-16 — /close auto-persist memory (feature/close-auto-persist, BDR-068) +- [x] STEP 5C: auto-finish chore→develop + push when capitalize/close branched off develop +- [x] --no-push escape hatch; WORKING-branch + rc-3 skip; graceful push-fail +- [x] aiguillage exception note + BDR-068 +- [ ] merge feature/close-auto-persist → develop (human gate) + ## 2026-07-16 — SHIPPED v1.0.0 first public release (BDR-067) - [x] versioning reset 4.0.0→1.0.0, CHANGELOG pre-release-history banner - [x] deleted v4.0.0 tag + stale release/1.0.0 branch (git-cherry: nothing orphaned) diff --git a/lib/gitflow-aiguillage.md b/lib/gitflow-aiguillage.md index 617bd1d..a51f0d8 100644 --- a/lib/gitflow-aiguillage.md +++ b/lib/gitflow-aiguillage.md @@ -33,8 +33,11 @@ with no code branch to follow. That is the leak it closes: the `.claude/**` hook exemption still lets a *manual* memory commit through on a protected base, but a skill-driven one now branches to `chore/*` first. -**Never run `gitflow finish`** — these flows commit, they do not merge. Integration -is a separate, human-gated step (the `gitflow` skill). +**Integration is human-gated by default** — these flows commit, they do not merge. +EXCEPTION: `/capitalize` + `/close` auto-persist their memory-only commit (finish → +develop + push) when THEY branched a `chore/*` off develop this run (BDR-068 — a +scoped [[LRN-069]] exception; see the capitalize skill's STEP 5C). `/prune-memory` ++ `/reconcile` stay fully human-gated: never run `gitflow finish` from them. Note: `hotfix` branches off **main** (prod) even when invoked from `develop` — that is the gitflow definition of a hotfix. For a dev-scoped small fix, use `/bugfix` diff --git a/skills/capitalize/SKILL.md b/skills/capitalize/SKILL.md index e2352b0..547e91b 100644 --- a/skills/capitalize/SKILL.md +++ b/skills/capitalize/SKILL.md @@ -9,7 +9,7 @@ description: | Triggers: "capitalize", "before clear/compact", "flush memory", "don't lose this", "avant de clear/compact", "capitalise ce qui manque", "close", "fin de journée", "checkpoint memory". -argument-hint: "[--ritual] (scans conversation + git + TODO against .claude/memory/; --ritual adds the 3-question reflection)" +argument-hint: "[--ritual] [--no-push] (scans conversation + git + TODO against .claude/memory/; --ritual adds the 3-question reflection; --no-push holds memory on the chore branch instead of the default auto-merge+push)" allowed-tools: - Read - Edit @@ -51,7 +51,10 @@ mark-superseded). It only appends. Before STEP 4 writes anything, follow `$HOME/.claude/lib/gitflow-aiguillage.md` — this skill's TYPE = `chore`. On `main`/`develop` it branches to `chore/` off develop, so the memory commit lands on a branch, never direct on a protected -base; on a working branch it proceeds in place. Never `gitflow finish` (human-gated). +base; on a working branch it proceeds in place. **Record whether it branched this +run** (PROTECTED → a fresh `chore/` was created off develop; remember +``) — STEP 5C uses that to auto-persist. Do NOT `gitflow finish` here; the +finish is STEP 5C's job, after the commit, and only for a branch THIS run created. ## STEP 0 — PRECHECK @@ -308,6 +311,33 @@ 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 5C — AUTO-PERSIST THE MEMORY (finish + push) + +Memory's value is cross-session persistence — a commit stranded on an unmerged +`chore/` branch is invisible to the next session sitting on develop, so the +skill closes the loop itself. This is a SCOPED exception to the human-gated merge ++ [[LRN-069]] push rule: it fires ONLY for this memory-only commit, ONLY on a +`chore/` branch THIS run created off develop (BDR-068). + +Fire only when ALL hold — else SKIP (STEP 6 prints the manual-merge note, the +pre-BDR-068 behavior): +- STEP 5B committed cleanly (`rc 0`), AND +- the aiguillage BRANCHED this run (PROTECTED → `chore/`; on a WORKING + branch the memory already rides feature/bugfix — never auto-merge it), AND +- `--no-push` was NOT passed (the hold escape hatch). + +Then, from the `chore/` branch: + + bash "$HOME/.claude/lib/gitflow.sh" finish chore # merge → develop, delete branch + git push origin develop + +- **finish + push OK** → surface `develop pushed` in STEP 6. +- **push fails** (offline / rejected) → the merge to develop ALREADY happened + locally; report `merged to develop, push FAILED — push manually`. Do NOT retry + or reset the merge. +- **`--no-push` / WORKING branch / rc 3** → skip this step; the commit stays where + it is. STEP 6 prints the manual-merge note. + ## STEP 6 — FINAL OUTPUT + HANDOFF ``` @@ -319,18 +349,22 @@ CAPITALIZE COMPLETE — () TODO.md : checked , added journal.md : +1 line under ## committed : (chore(memory): …) | ⚠️ NOT committed (rc 3 — see closing line) + persisted : develop pushed | on chore/, not merged (--no-push) | merged, push FAILED dropped as already-captured: LRN-023, BLK-006 ignored as noise: push/tag release ``` -Then the mode-specific closing line: +Then the closing line — pick by the STEP 5C persist result (`` = `Context +flushed` for pre-wipe, `Session closed` for ritual): -- **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". +- **auto-persisted (default — branched off develop, pushed)** → `✅ + persisted to origin/develop (). Next session: read .claude/memory/ at startup.` +- **--no-push (held on branch)** → `✅ + committed on chore/, NOT pushed (--no-push). Merge + push when ready.` +- **push failed after merge** → `✅ + merged to develop — ⚠️ push FAILED (); merged locally, push manually.` +- **WORKING branch (rode a feature branch)** → `✅ + committed on . Integrates when the branch merges.` +- **commit skipped (rc 3)** → keep the ✅ on the WRITE but make the gap loud, never + buried: `✅ — ⚠️ NOT committed (); entries safe on disk, commit manually.` + The ✅ covers the write (entries on disk); the ⚠️ marks the gap so it is not read + as "all done". The closing line matters — confirm the wipe is safe (default) or the session is checkpointed (ritual), AND whether the memory was committed (5B) or left for a @@ -358,6 +392,11 @@ manual commit (rc 3). 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. +- **Auto-persist the flush (STEP 5C, BDR-068)** — a memory-only commit on a + `chore/` branch THIS run created off develop auto-finishes → develop + + pushes; a scoped exception to LRN-069. `--no-push` holds it on the branch; a + WORKING branch (memory rides feature/bugfix) or rc 3 skips it. NEVER auto-finish + a branch the run did not create. - **Skip trivial** for the 4 ID registries; journal excepted. - `.claude/memory/` missing → STOP at STEP 0, do not create the structure here.