Compare commits
2 Commits
e4f7d3e82a
...
cd375dd74a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd375dd74a | ||
|
|
77aac2c890 |
@ -47,6 +47,7 @@ rules:
|
||||
| BDR-034 | 2026-06-26 | Coupled-capitalize invariant v1 — memory commit auto per dev flow (Frame 2) | accepted |
|
||||
| BDR-035 | 2026-06-26 | Analyze-before-plan invariant v1 — read-before bookend of coupled-capitalize | accepted |
|
||||
| BDR-036 | 2026-06-27 | Doc-sync coupled invariant — commit docs doc-syncer patches (twin of BDR-034, BUILT not reordered) | accepted |
|
||||
| BDR-037 | 2026-06-27 | v2 capitalize Stop-hook rejected → wire /capitalize+/close to the include | accepted |
|
||||
|
||||
---
|
||||
|
||||
@ -582,3 +583,15 @@ rules:
|
||||
- Static-glob scope (`*.md`/`docs/`) — over-reach onto a user-edited doc / `MIGRATION.md`; chose touched-files argv (in-thread list already in hand).
|
||||
- Silent-filter the forbidden path — masks an upstream BDR-022 bug; guard must REFUSE-ALL loudly ([[LRN-060]]).
|
||||
- **Reference**: commits `ae1f218` (helper+tests) · `4a54a65` (include) · `fb1f359` (doc-syncer PATCHED_FILES) · `636b491` (ship-feature reorder) · `e81f629` (init-project reorder) · `1b01b95` (3 inline flows). See [[BDR-034]], [[LRN-058]], [[LRN-059]], [[LRN-060]], [[BLK-010]], [[BLK-011]], [[EVAL-008]].
|
||||
|
||||
## BDR-037 — v2 capitalize Stop-hook REJECTED → wire /capitalize+/close to the include
|
||||
|
||||
- **Date**: 2026-06-27
|
||||
- **Status**: accepted
|
||||
- **Decision**: Deferred "v2 hook" ([[BDR-033]]-style non-blocking stateless Stop-hook nagging dirty `.claude/memory`) REJECTED — no code written. No Claude Code event supports an end-of-session nag: `Stop` fires PER-TURN (self-defeating — would nag during /capitalize's own write→commit window, [[LRN-047]]); `SessionEnd` is debug-log-only (can't nag) + would bypass the content gate (half-written entries). Real gap ≠ forgetting → CÂBLAGE manquant: `/capitalize` + `/close` never call `lib/capitalize-commit.md`. Redirect: wire the include into `/capitalize` STEP 5B (`/close` = thin alias, follows free), same one-liner as the 6 dev flows. Content gate (STEP 3) first → commit of approved entries automated ([[BDR-034]] contract). Deterministic, zero-noise, at source.
|
||||
- **Why**: 3 git proofs — (1) memory already committed by hand 35× as pure `chore(memory)` (zero code mixed); (2) orphans self-heal — `commit_memory` stages whole `.claude/memory` dir, next flow sweeps up; (3) cost on common path (per-turn noise / non-gated commit), benefit marginal (residual self-healing) → a hook polices a discipline already in evidence. OUBLI not choice: include + helper born 2026-06-26; `/capitalize` last edit 2026-06-19 (created 2026-06-09), `/close` 2026-04-23 — skills predate the machinery 7-60d; wiring commits (`2763678`/`e8eff7e`/`df60df6`) touched neither. No control removed: the commit was never gated, just done by hand in the exact `chore(memory): <IDs> — <ctx>` style the include reproduces.
|
||||
- **Alternatives rejected**:
|
||||
- (a) Stop per-turn memory-only wrapper — fires during the very flush it nags about → [[LRN-047]] self-defeat (frequent ignored nag = risk, not annoyance).
|
||||
- (b) SessionEnd auto-commit (FAIT) — bypasses STEP 3 content gate, embarks half-written entries, can't report actionably.
|
||||
- (c) abandon with no redirect — leaves the real wiring gap open; fix for an unwired skill = wire it.
|
||||
- **Reference**: read-phase analysis (no hook code ever written); wiring commit (capitalize STEP 5B) follows. Completes [[BDR-034]] rollout; applies [[BDR-033]] doctrine to REJECT (not all nudges — the determinism split is [[LRN-061]]). See [[LRN-061]], [[LRN-047]], [[LRN-049]], [[LRN-054]].
|
||||
|
||||
@ -211,3 +211,4 @@ rules:
|
||||
## 2026-06-27
|
||||
- Doc-sync coupled invariant (twin of BDR-034, BUILT not reordered): new `lib/doc-commit.sh` (inverse-scope surgical, fail-closed exit 4 on `.claude/`) + `lib/doc-commit.md` include; doc-syncer emits `PATCHED_FILES` (one path/line) → agent → distinct argv (space-safe). 2 orchestrators reordered DOC SYNC before FINISH (ship-feature 9→8, init-project 12→10c, GSD 13→12), 3 inline flows wired (feat/bugfix/hotfix). 6 commits `ae1f218` · `4a54a65` · `fb1f359` · `636b491` · `e81f629` · `1b01b95`. 28/28 real-exec, shellcheck clean. BDR-036, LRN-058/059/060, EVAL-008.
|
||||
- Sweep caught PRIOR-chantier debt (README:153 stale since e8eff7e's swap) + expanded scope to 3 inline flows (asymmetry vs memory was decider). Swap flips meanings ≠ letter-insertion (LRN-059). Deferred note "reorder only" refuted in read-phase — doc-syncer commits nothing (LRN-058). BLK-010 (scaffold/unborn HEAD + worktree) + BLK-011 (GSD ROADMAP post-FINISH) deferred = new work.
|
||||
- v2 capitalize Stop-hook REJECTED on facts: `Stop`=per-turn (self-defeat, nags mid-flush, LRN-047), `SessionEnd`=debug-log-only (can't nag) + gate-bypass. Real gap = OUBLI de câblage: `/capitalize`+`/close` never call `capitalize-commit.md` (predate it 7-60d; wiring commits never touched them; commit done by hand 35×, orphans self-heal). Redirect = wire the include (STEP 5B); `/close` alias follows. BDR-037 + LRN-061 (capstone: runtime net for an unwired skill → check wiring first; deterministic gap = fix structurally, non-det aléa = net OK cf BDR-033). Next: câblage + dogfood (5B commits future capitalizations).
|
||||
|
||||
@ -59,6 +59,7 @@ rules:
|
||||
| LRN-058 | 2026-06-27 | Same bug-class ≠ same fix — verify the twin shares the fix's PRECONDITION before replicating | porting a fix to a "same bug" twin |
|
||||
| LRN-059 | 2026-06-27 | Step-number SWAP flips meanings (sweep refs) ≠ letter-suffix insertion (shifts nothing) | any pipeline renumber |
|
||||
| LRN-060 | 2026-06-27 | Fail-closed guard proven by what it REFUSES (loudly); pass dynamic lists as argv not separator-string | automated scoped-commit / destructive guards |
|
||||
| LRN-061 | 2026-06-27 | Runtime net for an unwired skill → check the wiring first (deterministic gap = fix structurally; non-det aléa = net OK, cf BDR-033) | "build a hook/watcher to catch when X isn't done" |
|
||||
|
||||
---
|
||||
|
||||
@ -733,3 +734,11 @@ rules:
|
||||
- **Context**: doc-commit.sh ([[BDR-036]]), T1a/b/c (refuse paths) + T7 (argv space-safe), all real-exec.
|
||||
- **Future application**: any automated scoped-commit / destructive guard — test the REFUSAL path + refuse loud; pass lists as argv. Same family as [[LRN-046]] (deterministic oracle for a destructive guard).
|
||||
- **Reference**: [[BDR-036]], [[LRN-051]] (changed-paths filter), [[LRN-046]].
|
||||
|
||||
## LRN-061 — Runtime net proposed for an unwired skill → check the wiring first
|
||||
|
||||
- **Date**: 2026-06-27
|
||||
- **Pattern**: Tempted to build a runtime guard/hook/monitor that watches for a bad OUTCOME (memory written but uncommitted)? First ask if the outcome is a MISSING WIRING, not a behavioral lapse. A per-turn Stop-hook was proposed to catch "dirty memory" — but the cause was `/capitalize`+`/close` not calling the commit include (they predate it). Fix for an unwired skill = WIRE it (deterministic, zero-noise, at source); a monitor over a wiring hole pays RECURRING cost to detect a ONE-TIME omission, and a frequent ignored nag is itself a risk ([[LRN-047]]). **NOT "runtime nets are bad"** — the split is by DETERMINISM: a MISSING WIRING is deterministic → repair structurally; a genuinely NON-DETERMINISTIC aléa → a runtime net IS the right tool. Good counter-example: [[BDR-033]] anim-lib nudge — "will the user want motion?" is unknowable statically → a stateless 1-line suggestion is correct. Same determinism test as [[LRN-046]]/[[LRN-049]], applied to the build-or-not question.
|
||||
- **Context**: deferred "v2 capitalize hook" ([[BDR-037]]). Read-phase killed it before code: git proved skills predate the include (oubli), memory already committed by hand 35×, orphans self-heal via `commit_memory`. The hook would've been disabled within an hour (frequent ignored nag).
|
||||
- **Future application**: any "build a hook/watcher/lint to catch when X isn't done" — first grep whether X is even WIRED at its source. Deterministic/structural gap (missing include/call) → fix structurally; reserve runtime nets for non-deterministic lapses, never to complete a rollout. Classify by determinism BEFORE building.
|
||||
- **Reference**: [[BDR-037]], [[BDR-034]] (rollout this completes), [[BDR-033]] (the GOOD net — contrast). Conditions [[LRN-047]], [[LRN-049]], [[LRN-054]].
|
||||
|
||||
@ -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): <IDs> — capitalize` (pre-wipe flush)
|
||||
- `chore(memory): <IDs> — 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 "<message>")
|
||||
rc=$?
|
||||
|
||||
3. Report by (rc, mem_hash):
|
||||
- **rc 0, hash non-empty** → committed; surface `<mem_hash>` 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 — <YYYY-MM-DD> (<pre-wipe flush | session-close>)
|
||||
evals.md : +<N> (EVAL-003) | 0
|
||||
TODO.md : checked <N>, added <M>
|
||||
journal.md : +1 line under ## <date>
|
||||
committed : <mem_hash> (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 <mem_hash>. Safe to /clear or /compact now.`
|
||||
- **session-close ritual** → `✅ Session closed + committed <mem_hash>. 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 (<reason: detached/merge/non-git>); 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.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user