@neikyun/ciel 6.8.0 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,99 @@
1
+ #!/bin/bash
2
+ # Ciel — SessionStart hook
3
+ # Trigger: session begins or resumes
4
+ # Purpose: print Ciel banner, load overlay context, set TRACE_ID for eval logging
5
+ # Never blocks (exit 0 always). Stdout is added to Claude's context.
6
+
7
+ INPUT=$(cat 2>/dev/null || echo "{}")
8
+ CWD=$(echo "$INPUT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('cwd', ''))" 2>/dev/null || pwd)
9
+
10
+ # Detect overlay presence
11
+ OVERLAY=""
12
+ for candidate in "$CWD/ciel-overlay.md" "$CWD/.claude/ciel-overlay.md"; do
13
+ if [[ -f "$candidate" ]]; then
14
+ OVERLAY="$candidate"
15
+ break
16
+ fi
17
+ done
18
+
19
+ # Reset session-scoped edit tracker so META/RELIRE gates don't bleed across sessions
20
+ if [ -n "${CLAUDE_PROJECT_DIR:-}" ] && [ -f "$CLAUDE_PROJECT_DIR/.ciel/tracked-files.json" ]; then
21
+ echo "[]" > "$CLAUDE_PROJECT_DIR/.ciel/tracked-files.json" 2>/dev/null || true
22
+ fi
23
+
24
+ # Generate TRACE_ID for this session (used by eval logging)
25
+ TRACE_ID=$(date -u +%Y%m%dT%H%M%SZ)-$$
26
+ export CIEL_TRACE_ID="$TRACE_ID"
27
+
28
+ MSG="CIEL v6.8.0 — Skills-first deep-reasoning active. "
29
+ if [[ -n "$OVERLAY" ]]; then
30
+ MSG+="Overlay loaded: $OVERLAY. "
31
+ else
32
+ MSG+="No overlay found at $CWD/ciel-overlay.md — create one for project-specific rules. "
33
+ fi
34
+ MSG+="Trace ID: $TRACE_ID. Principle: Understand before generating. Verify before claiming done."
35
+
36
+ # ─── Cued-recall: surface relevant memories ──────────────────────────────────
37
+ # If a memory corpus exists, list active (non-stale) memories so the model
38
+ # knows what cues are available. Full content read on-demand. See ADR-0001.
39
+ MEMORY_INDEX="$CWD/.ciel/memory/index.json"
40
+ if [[ -f "$MEMORY_INDEX" ]]; then
41
+ MEMORY_SUMMARY=$(MEMORY_INDEX="$MEMORY_INDEX" python3 -c "
42
+ import json, os
43
+ try:
44
+ with open(os.environ['MEMORY_INDEX']) as f:
45
+ idx = json.load(f)
46
+ mems = idx.get('memories', {})
47
+ active = [(mid, m) for mid, m in mems.items() if not m.get('stale')]
48
+ if not active:
49
+ print('')
50
+ else:
51
+ # Sort by trigger_count desc, then by last_triggered desc
52
+ active.sort(key=lambda x: (-(x[1].get('trigger_count') or 0), x[1].get('last_triggered') or ''), reverse=False)
53
+ active.sort(key=lambda x: -(x[1].get('trigger_count') or 0))
54
+ top = active[:10]
55
+ lines = [f\" [{mid}, {m.get('trigger_count', 0)}x] {m.get('title', '?')}\" for mid, m in top]
56
+ total = len(active)
57
+ more = f' (+{total - len(top)} more)' if total > len(top) else ''
58
+ print(f'Cued-recall memory active ({total} memories{more}):\\n' + '\\n'.join(lines))
59
+ except Exception:
60
+ print('')
61
+ " 2>/dev/null || echo "")
62
+ if [[ -n "$MEMORY_SUMMARY" ]]; then
63
+ MSG+=$'\n'"$MEMORY_SUMMARY"
64
+ MSG+=$'\n'"Memories auto-inject when path/symbol/intent cues match. Read full content from .ciel/memory/{episodes,concepts,guards}/ when relevant."
65
+ fi
66
+ elif [[ -d "$CWD/.ciel" ]] || [[ -f "$CWD/.claude/settings.json" ]] || [[ -f "$CWD/opencode.json" ]] || [[ -f "$CWD/ciel-overlay.md" ]]; then
67
+ # Only suggest bootstrap if Ciel is actually installed in this project (not
68
+ # any random repo with a CLAUDE.md). Markers checked: .ciel/ dir, .claude
69
+ # settings, opencode config, or an explicit Ciel overlay.
70
+ MSG+=$'\n'"No cued-recall memory yet. Run /ciel-memory-bootstrap to scan project for ingestable tribal docs (lessons.md, ciel-overlay.md, .claude/rules/, etc.)."
71
+ fi
72
+
73
+ # ─── Update check (throttled to once per 24h, never blocks) ──────────────────
74
+ # Fetches GitHub VERSION non-blocking (max 2s). Any failure → silent skip.
75
+ MANIFEST="$HOME/.ciel/manifest.json"
76
+ LAST_CHECK="$HOME/.ciel/.last-update-check"
77
+ if [[ -f "$MANIFEST" ]]; then
78
+ STALE=false
79
+ if [[ ! -f "$LAST_CHECK" ]]; then
80
+ STALE=true
81
+ elif find "$LAST_CHECK" -mmin +1440 2>/dev/null | grep -q .; then
82
+ STALE=true
83
+ fi
84
+ if $STALE; then
85
+ LOCAL_VER=$(grep -oE '"version":[[:space:]]*"[^"]+"' "$MANIFEST" 2>/dev/null \
86
+ | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
87
+ REMOTE_VER=$(curl -fsSL --max-time 2 \
88
+ https://raw.githubusercontent.com/KaosKyun/Ciel/main/VERSION 2>/dev/null \
89
+ | tr -d '[:space:]')
90
+ if [[ -n "$LOCAL_VER" && -n "$REMOTE_VER" && "$LOCAL_VER" != "$REMOTE_VER" ]]; then
91
+ MSG+=" [UPDATE] Ciel v$LOCAL_VER → v$REMOTE_VER available. Run /ciel-update."
92
+ fi
93
+ mkdir -p "$HOME/.ciel" 2>/dev/null || true
94
+ touch "$LAST_CHECK" 2>/dev/null || true
95
+ fi
96
+ fi
97
+
98
+ echo "$MSG"
99
+ exit 0
@@ -0,0 +1,112 @@
1
+ #!/bin/bash
2
+ # Ciel — UserPromptSubmit hook
3
+ # Trigger: user submits a prompt (before Claude processes)
4
+ # Purpose: light depth pre-classification hint injected into context
5
+ # Invokes: depth-classifier skill (lightweight mode)
6
+ # Never blocks (exit 0 always)
7
+
8
+ INPUT=$(cat 2>/dev/null || echo "{}")
9
+ PROMPT=$(echo "$INPUT" | python3 -c "
10
+ import sys, json
11
+ try:
12
+ d = json.load(sys.stdin)
13
+ print(d.get('prompt', ''))
14
+ except:
15
+ print('')
16
+ " 2>/dev/null || echo "")
17
+
18
+ [ -z "$PROMPT" ] && exit 0
19
+
20
+ # Mechanical depth signals
21
+ DEPTH="Standard" # default
22
+ REASON=""
23
+
24
+ # Check for Critical signals
25
+ if echo "$PROMPT" | grep -qiE '\b(auth|authenti|author|jwt|oauth|password|secret|token|session|payment|credit.card|migration.*schema|2fa|mfa|encryption|credential|cookie.*security)\b'; then
26
+ DEPTH="Critical"
27
+ REASON="auth/security/payment keyword detected"
28
+ fi
29
+
30
+ # Check for Trivial signals (only if not Critical)
31
+ if [[ "$DEPTH" != "Critical" ]] && echo "$PROMPT" | grep -qiE '\b(rename|typo|copyright|comment|readme|1-line|one.line|fix.typo|spelling)\b'; then
32
+ DEPTH="Trivial"
33
+ REASON="rename/typo/docs keyword detected"
34
+ fi
35
+
36
+ DISPATCH_GATE=""
37
+ if [[ "$DEPTH" == "Standard" || "$DEPTH" == "Critical" ]]; then
38
+ DISPATCH_GATE=" | DISPATCH GATE: dispatch ciel-researcher + ciel-explorer in parallel BEFORE first Bash/Read/Edit."
39
+ fi
40
+
41
+ META_GATE=""
42
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
43
+ if [ -n "$PROJECT_DIR" ] && [ -f "$PROJECT_DIR/.ciel/tracked-files.json" ]; then
44
+ EDIT_COUNT=$(CIEL_PATH="$PROJECT_DIR/.ciel/tracked-files.json" python3 -c "
45
+ import json, os
46
+ try: print(len(json.load(open(os.environ['CIEL_PATH']))))
47
+ except: print(0)
48
+ " 2>/dev/null || echo "0")
49
+ if [ "${EDIT_COUNT:-0}" -gt 0 ] 2>/dev/null; then
50
+ META_GATE=" | META GATE: ${EDIT_COUNT} file(s) edited this session — complete 10-item META if previous task ended at PROUVER."
51
+ fi
52
+ fi
53
+
54
+ # ─── Cued-recall: intervention pattern detection ─────────────────────────────
55
+ # When the user message contains a clear correction/intervention pattern,
56
+ # suggest capturing it as a memory. Patterns are intentionally narrow to keep
57
+ # false-positive rate low — generic words like "wait" / "stop" / "actually"
58
+ # are NOT triggers on their own; they must combine with a negation/correction
59
+ # adjacent. Never auto-silent — the model surfaces a question to the user.
60
+ # See ADR-0001 and skill `memoire`.
61
+ INTERVENTION_GATE=""
62
+ # POSIX-ERE only (no PCRE lookahead). Patterns are intentionally high-precision
63
+ # to avoid false positives on generic words (wait/stop/actually). Each pattern
64
+ # is a clear signal of correction or "you missed something".
65
+ if echo "$PROMPT" | grep -qiE "(tu as oublié|t'as oublié|n'oublie pas (que|de)|non en fait|non,? en fait|attention que|rappelle-toi (que|de)|ici on (fait|utilise) plutôt|non on (fait|utilise) plutôt|en fait c'est pas|c'est pas comme ça|mauvaise approche|tu te trompes|you forgot (to|that)|don't forget (to|that)|that's not (right|correct|how)|that's wrong|no[,]? actually|actually,? no|wait[,—-] (no|don't|you forgot)|stop[,—-] (no|you forgot|don't))"; then
66
+ INTERVENTION_GATE=" | CAPTURE GATE: intervention pattern detected — propose AskUserQuestion to capture as memory under .ciel/memory/episodes/ (skill: memoire). Never silent-write."
67
+ fi
68
+
69
+ # ─── Cued-recall: query memory engine for matching memories ──────────────────
70
+ # Calls hooks/memory-engine.py if installed and a memory corpus exists. The
71
+ # engine handles cue extraction (paths, symbols, intents, language), scoring,
72
+ # token cap, decay, and trigger updates. See docs/adrs/0001-cued-recall-memory.md.
73
+ MEMORY_OUTPUT=""
74
+ ENGINE_PATH=""
75
+ # Resolution order: same dir as this script (most reliable, found via BASH_SOURCE)
76
+ # → project-relative paths in priority order → $HOME fallbacks. Covers local-mode
77
+ # install (top-level hooks/), curl-mode install (.claude/hooks/ or ~/.claude/plugins/ciel/),
78
+ # and OpenCode plugin layout (~/.config/opencode/...).
79
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd 2>/dev/null || echo "")"
80
+ for candidate in \
81
+ "$SCRIPT_DIR/memory-engine.py" \
82
+ "$PROJECT_DIR/.claude/hooks/memory-engine.py" \
83
+ "$PROJECT_DIR/hooks/memory-engine.py" \
84
+ "$HOME/.claude/plugins/ciel/memory-engine.py" \
85
+ "$HOME/.ciel/hooks/memory-engine.py"; do
86
+ if [[ -n "$candidate" ]] && [[ -f "$candidate" ]]; then
87
+ ENGINE_PATH="$candidate"
88
+ break
89
+ fi
90
+ done
91
+
92
+ if [[ -n "$ENGINE_PATH" ]] && [[ -n "$PROJECT_DIR" ]] && [[ -f "$PROJECT_DIR/.ciel/memory/index.json" ]]; then
93
+ DEPTH_LOWER=$(echo "$DEPTH" | tr '[:upper:]' '[:lower:]')
94
+ MEMORY_OUTPUT=$(python3 "$ENGINE_PATH" query --prompt "$PROMPT" --cwd "$PROJECT_DIR" --depth "$DEPTH_LOWER" 2>/dev/null || echo "")
95
+ fi
96
+
97
+ MSG_BASE="CIEL depth hint: $DEPTH ($REASON).$DISPATCH_GATE$META_GATE$INTERVENTION_GATE Invoke depth-classifier if ambiguous before routing pipeline."
98
+
99
+ # Emit JSON via python to handle newlines and quoting safely
100
+ MSG_BASE="$MSG_BASE" MEMORY_OUTPUT="$MEMORY_OUTPUT" python3 -c "
101
+ import os, json
102
+ base = os.environ.get('MSG_BASE', '')
103
+ mem = os.environ.get('MEMORY_OUTPUT', '').strip()
104
+ combined = base + ('\n\n' + mem if mem else '')
105
+ print(json.dumps({
106
+ 'hookSpecificOutput': {
107
+ 'hookEventName': 'UserPromptSubmit',
108
+ 'additionalContext': combined,
109
+ }
110
+ }))
111
+ "
112
+ exit 0
@@ -1,10 +1,10 @@
1
1
  ---
2
- description: Audits the current Claude Code session for Ciel paradigm violations (missed Task dispatches, inline gathering, hook inactivity, skill overlaps, intent routing misses). Produces a structured report with a Ciel Health Score (0-100). If score < 75, creates a GitHub Issue on the Ciel repository with the findings and session timeline. Hook-independent — works even when Ciel hooks are broken.
2
+ description: Audits the current Claude Code session for Ciel paradigm violations (missed Task dispatches, inline gathering, hook inactivity, skill overlaps, intent routing misses). Produces a structured report with a Ciel Health Score (0-100). If score < 90, creates a GitHub Issue on the Ciel repository with the findings and session timeline. Hook-independent — works even when Ciel hooks are broken.
3
3
  ---
4
4
 
5
5
  # /ciel-audit — Session post-mortem
6
6
 
7
- *Generates a structured report of Ciel behavior violations observed in the current session. Calculates a Ciel Health Score (0-100). If the score is below 75, creates a GitHub Issue on the Ciel repository (github.com/KaosKyun/Ciel) with the full timeline and findings — otherwise produces the report only without creating an issue.*
7
+ *Generates a structured report of Ciel behavior violations observed in the current session. Calculates a Ciel Health Score (0-100). If the score is below 90, creates a GitHub Issue on the Ciel repository (github.com/KaosKyun/Ciel) with the full timeline and findings — otherwise produces the report only without creating an issue.*
8
8
 
9
9
  Usage: `/ciel-audit`
10
10
 
@@ -85,17 +85,78 @@ If npm version > local version, include an **Update notification** in the report
85
85
 
86
86
  #### Dimension 8: Platform health — penalty up to -5
87
87
 
88
- Check which Ciel platforms are present and whether they have valid configurations:
88
+ Check that Ciel platform installations exist and are valid. Ciel currently supports two platforms: **claude** and **opencode**.
89
89
 
90
+ **Claude Code** — check for expected agent and hook files:
90
91
  ```bash
91
- ls /path/to/platforms/ 2>/dev/null
92
+ CLAUDE_AGENTS=$(ls .claude/agents/ciel-*.md 2>/dev/null | wc -l | tr -d ' ')
93
+ CLAUDE_HOOK=$(test -f .claude/hooks/session-start.sh && echo "1" || echo "0")
94
+ CLAUDE_SETTINGS=$(test -f .claude/settings.json && echo "1" || echo "0")
95
+ echo "Claude: agents=$CLAUDE_AGENTS hook=$CLAUDE_HOOK settings=$CLAUDE_SETTINGS"
96
+ if [ "$CLAUDE_AGENTS" -ge 3 ] && [ "$CLAUDE_HOOK" = "1" ] && [ "$CLAUDE_SETTINGS" = "1" ]; then
97
+ echo "Claude platform: OK"
98
+ else
99
+ echo "Claude platform: INCOMPLETE"
100
+ fi
92
101
  ```
102
+ Expected: at least 3 agent files + session-start.sh + settings.json
93
103
 
94
- Expected platforms: codex, cursor, kilocode, lmstudio, ollama, opencode, windsurf
104
+ **OpenCode** check for expected plugin, agent, and command files:
105
+ ```bash
106
+ OPENCODE_PLUGIN=$(test -f .opencode/plugins/ciel.ts && echo "1" || echo "0")
107
+ OPENCODE_AGENTS=$(ls .opencode/agents/ciel-*.md 2>/dev/null | wc -l | tr -d ' ')
108
+ OPENCODE_COMMANDS=$(ls .opencode/commands/ciel*.md 2>/dev/null | wc -l | tr -d ' ')
109
+ echo "OpenCode: plugin=$OPENCODE_PLUGIN agents=$OPENCODE_AGENTS commands=$OPENCODE_COMMANDS"
110
+ if [ "$OPENCODE_PLUGIN" = "1" ] && [ "$OPENCODE_AGENTS" -ge 3 ] && [ "$OPENCODE_COMMANDS" -ge 5 ]; then
111
+ echo "OpenCode platform: OK"
112
+ else
113
+ echo "OpenCode platform: INCOMPLETE"
114
+ fi
115
+ ```
116
+ Expected: ciel.ts plugin + at least 3 agent files + at least 5 command files
117
+
118
+ Scoring:
119
+ - Both platforms fully present and valid: **0**
120
+ - One platform missing or incomplete: **-3**
121
+ - Both platforms missing or critically incomplete: **-5**
122
+
123
+ **Important**: Do NOT check for `.claude/plugins/ciel/platforms/` or `.opencode/platforms/` directories — these are not part of the v6 architecture. Platform files are installed directly into `.claude/` and `.opencode/` respectively. Do NOT check for codex, cursor, kilocode, lmstudio, ollama, or windsurf — these platforms are not yet implemented.
124
+
125
+ #### Dimension 9: Memory health — penalty up to -10
95
126
 
96
- - All platforms present: **0**
97
- - Missing 1-2 platforms: **-3**
98
- - Missing 3+ platforms: **-5**
127
+ Check the cued-recall memory system (see `docs/adrs/0001-cued-recall-memory.md`):
128
+
129
+ - **index.json missing**: `.ciel/memory/index.json` does not exist. The memory system was never bootstrapped. **-10**
130
+ - **index.json exists but episodes/ empty**: `.ciel/memory/episodes/` has no files. Bootstrap ran but no memories were ingested, or the directory structure is incomplete. **-5**
131
+ - **Low trigger ratio**: Count memories with `trigger_count > 0` vs total. If < 30% of memories have ever been triggered, the cue-matching system may be misconfigured or the memories are not relevant to actual usage. **-3**
132
+ - **Stale memories**: Any memory with `stale: true` or with `last_triggered` older than `stale_after_days` (default 90). Stale memories waste index space and should be cleaned up by `memory-engine.py rebuild-index`. **-2**
133
+
134
+ Scoring:
135
+ - index.json missing: **-10** (blocks all other checks)
136
+ - index.json present but no episode files: **-5**
137
+ - All checks pass: **0**
138
+
139
+ Run these checks:
140
+ ```bash
141
+ # Check index.json exists
142
+ test -f .ciel/memory/index.json && echo "index: OK" || echo "index: MISSING"
143
+
144
+ # Count episodes
145
+ EPISODES=$(ls .ciel/memory/episodes/*.md 2>/dev/null | wc -l | tr -d ' ')
146
+ echo "episodes: $EPISODES"
147
+
148
+ # Count triggered vs total (requires python3)
149
+ python3 -c "
150
+ import json
151
+ with open('.ciel/memory/index.json') as f:
152
+ idx = json.load(f)
153
+ mems = idx.get('memories', {})
154
+ total = len(mems)
155
+ triggered = sum(1 for m in mems.values() if m.get('trigger_count', 0) > 0)
156
+ stale = sum(1 for m in mems.values() if m.get('stale'))
157
+ print(f'total: {total}, triggered: {triggered} ({0 if total==0 else triggered*100//total}%), stale: {stale}')
158
+ " 2>/dev/null || echo "memory check failed (no python3?)"
159
+ ```
99
160
 
100
161
  ---
101
162
 
@@ -106,9 +167,7 @@ Expected platforms: codex, cursor, kilocode, lmstudio, ollama, opencode, windsur
106
167
  | Score range | Status | Issue created? |
107
168
  |-------------|--------|----------------|
108
169
  | 90-100 | Excellent | No |
109
- | 75-89 | Good (minor issues) | No |
110
- | 50-74 | Needs improvement | **Yes** — creates issue with timeline |
111
- | 0-49 | Critical | **Yes** — creates issue with timeline |
170
+ | 0-89 | Needs improvement | **Yes** — creates issue with timeline |
112
171
 
113
172
  The score is calculated automatically from the detected violations.
114
173
 
@@ -124,7 +183,7 @@ Begin the output with the literal line `# Ciel Session Audit Report`. End with t
124
183
  **Date**: <today's date>
125
184
  **Ciel Health Score**: <N>/100 — <Excellent|Good|Needs improvement|Critical>
126
185
  **npm**: local v<X.Y.Z> | npm v<X.Y.Z> | <up-to-date|update available>
127
- **Platforms**: codexcursor ✓ kilo ✓ lmstudio ✓ ollama ✓ opencode ✓ windsurf ✓ (or ✗ if missing)
186
+ **Platforms**: claude ✓ opencode ✓ (or ✗ if missing)
128
187
  **Session summary**: <N> /ciel invocation(s), <N> total tool calls, <N> Task() dispatches, <N> inline Bash/Read/Grep/WebSearch calls in main session.
129
188
 
130
189
  **Verdict**: <PASS | VIOLATIONS FOUND>
@@ -173,6 +232,7 @@ Begin the output with the literal line `# Ciel Session Audit Report`. End with t
173
232
  | D6 — Intent routing | -<N> |
174
233
  | D7 — npm version | -<N> |
175
234
  | D8 — Platform health | -<N> |
235
+ | D9 — Memory health | -<N> |
176
236
  | **Total** | **-<N>** |
177
237
  | **Health Score** | **<N>/100** |
178
238
 
@@ -202,7 +262,7 @@ Output a single short section — **no issue is created** for PASS verdicts:
202
262
  **Date**: <today's date>
203
263
  **Ciel Health Score**: 100/100 — Excellent
204
264
  **npm**: local v<X.Y.Z> | npm v<X.Y.Z> | up-to-date
205
- **Platforms**: all 7 platforms present
265
+ **Platforms**: claude opencode
206
266
  **Session summary**: <N> /ciel invocation(s), <N> tool calls, <N> Task() dispatches.
207
267
  **Verdict**: PASS
208
268
 
@@ -213,11 +273,11 @@ Output a single short section — **no issue is created** for PASS verdicts:
213
273
 
214
274
  ---
215
275
 
216
- ### GitHub Issue creation (only if score < 75)
276
+ ### GitHub Issue creation (only if score < 90)
217
277
 
218
- If the Ciel Health Score is **below 75**, create a GitHub Issue with the report AND the session timeline.
278
+ If the Ciel Health Score is **below 90**, create a GitHub Issue with the report AND the session timeline.
219
279
 
220
- **Important**: Do NOT create an issue if score >= 75. Only create for scores < 75.
280
+ **Important**: Do NOT create an issue if score >= 90. Only create for scores < 90.
221
281
 
222
282
  1. **Check for duplicate issues first**:
223
283
  ```bash
@@ -299,6 +359,6 @@ If the Ciel Health Score is **below 75**, create a GitHub Issue with the report
299
359
  - Do NOT invoke other Ciel skills. This command is fully self-contained.
300
360
  - Do NOT dispatch `Task()` agents. Audit happens inline.
301
361
  - Do NOT ask clarifying questions. Produce the report with the information you have.
302
- - Do NOT create an issue if score >= 75. Only create for score < 75.
362
+ - Do NOT create an issue if score >= 90. Only create for score < 90.
303
363
  - Do NOT create duplicate issues — run the `gh issue list` check before creating.
304
364
  - Do NOT restart, rerun, or attempt to fix the session in-flight. The audit report is the deliverable.
@@ -0,0 +1,160 @@
1
+ ---
2
+ description: Scan project for ingestable tribal docs (lessons.md, ciel-overlay.md, .claude/rules/, etc.) and propose ingestion into the cued-recall memory under .ciel/memory/. Reports findings if no sources found. Always confirms each candidate with the user before writing.
3
+ ---
4
+
5
+ # /ciel-memory-bootstrap — Initialize Cued-Recall Memory
6
+
7
+ **Purpose:** First-run scan of an existing project to convert tribal knowledge already documented in `lessons.md`, `ciel-overlay.md`, `.claude/rules/`, and similar files into the structured cued-recall memory at `.ciel/memory/`.
8
+
9
+ **Usage:** `/ciel-memory-bootstrap` (no args)
10
+
11
+ This is **deterministic**: no agent dispatch, no pipeline, no DIVERGE/EVALUER. Just scan, propose, write on user confirmation.
12
+
13
+ ---
14
+
15
+ ## Instructions
16
+
17
+ You are bootstrapping the cued-recall memory for this project. Follow these steps in order.
18
+
19
+ ### Step 1 — Scan
20
+
21
+ Run the bootstrap script in `scan` mode:
22
+
23
+ ```bash
24
+ # Try installed location first, fallback to dev location
25
+ script="$CLAUDE_PROJECT_DIR/.claude/hooks/memory-bootstrap.sh"
26
+ [ -f "$script" ] || script="$CLAUDE_PROJECT_DIR/hooks/memory-bootstrap.sh"
27
+ bash "$script" scan
28
+ ```
29
+
30
+ Or, if running on an installed Ciel: `bash "$HOME/.ciel/hooks/memory-bootstrap.sh" scan`.
31
+
32
+ Report the output verbatim to the user.
33
+
34
+ ### Step 2 — Decide path
35
+
36
+ Based on the scan output:
37
+
38
+ - **If 0 sources found** → tell the user clearly: "No tribal docs to bootstrap from. The cued-recall memory will populate organically as you intervene with me. Nothing more to do." End here.
39
+ - **If sources found** → proceed to Step 3.
40
+
41
+ ### Step 3 — Initialize structure
42
+
43
+ Run:
44
+
45
+ ```bash
46
+ script="$CLAUDE_PROJECT_DIR/.claude/hooks/memory-bootstrap.sh"
47
+ [ -f "$script" ] || script="$CLAUDE_PROJECT_DIR/hooks/memory-bootstrap.sh"
48
+ bash "$script" ingest
49
+ ```
50
+
51
+ This creates `.ciel/memory/{episodes,concepts,guards}/` and an empty `index.json`. It does NOT auto-write memories — auto-ingestion would create cargo-cult entries from possibly-stale docs (see ADR-0001).
52
+
53
+ ### Step 4 — Read each source
54
+
55
+ For each source found in Step 1, `Read` the file fully. Identify candidate memories:
56
+
57
+ | Source format | What becomes a memory |
58
+ |---|---|
59
+ | `[YYYY-MM-DD] MISTAKE: X → RULE: Y` lines (lessons.md style) | One memory per line. Title = the rule. |
60
+ | `## Heading\n\n- rule\n- rule` (rules.md style) | One memory per rule. |
61
+ | Numbered lessons in `ciel-overlay.md` "Key Lessons" | One memory per lesson. |
62
+ | `## section` in CLAUDE.md/AGENTS.md describing a non-obvious convention | One memory per section. |
63
+
64
+ Skip:
65
+ - The pipeline / workflow descriptions (those belong in CLAUDE.md, not memory)
66
+ - General principles already in CLAUDE.md
67
+ - Anything that's just project description (READMEish)
68
+ - Code examples (those go in skills/, not memory)
69
+
70
+ ### Step 5 — Propose batch capture
71
+
72
+ Once you have N candidate memories from the sources, present them to the user **as a batch**, not one by one (avoid 50 confirmation prompts). Use a single `AskUserQuestion` with the structure:
73
+
74
+ > "Found N candidates from your tribal docs. I'll list them; you tell me which to capture, which to skip, or 'all'."
75
+
76
+ For each candidate, show:
77
+ - **Title** (one line)
78
+ - **Source** (file:line)
79
+ - **Suggested tags** (paths, symbols, intents, language inferred from the lesson content)
80
+
81
+ The user replies with: "all", "1,3,5,8" (specific indices), or "skip".
82
+
83
+ ### Step 6 — Write captured memories
84
+
85
+ For each captured candidate, create `.ciel/memory/episodes/<YYYY-MM-DD>-<slug>.md` with frontmatter:
86
+
87
+ ```yaml
88
+ ---
89
+ id: mem_<NNN>
90
+ title: <title>
91
+ languages: [<inferred>]
92
+ path_patterns:
93
+ - <pattern>
94
+ symbols: [<inferred>]
95
+ intents: [<inferred>]
96
+ captured_at: <ISO8601 now>
97
+ captured_from: bootstrap
98
+ source: <original-file:line>
99
+ trigger_count: 0
100
+ last_triggered: null
101
+ stale_after_days: 90
102
+ stale: false
103
+ ---
104
+
105
+ # <title>
106
+
107
+ <content from source, lightly cleaned>
108
+ ```
109
+
110
+ ID strategy: read existing `index.json` for max id, increment. Slug = first 5 words of title, kebab-cased.
111
+
112
+ ### Step 7 — Rebuild index
113
+
114
+ After all writes, regenerate `.ciel/memory/index.json` by parsing every frontmatter under `.ciel/memory/{episodes,concepts,guards}/`:
115
+
116
+ ```python
117
+ # pseudo — use python3 -c '...' inline
118
+ for each *.md file:
119
+ parse frontmatter
120
+ add to memories dict by id
121
+ for each path_pattern, symbol, intent, language:
122
+ append id to corresponding by_* index
123
+ write back to index.json
124
+ ```
125
+
126
+ ### Step 8 — Confirm
127
+
128
+ Report:
129
+
130
+ - N memories captured
131
+ - Sources processed
132
+ - Index rebuilt with M total entries
133
+ - Suggest: "Cued-recall memory now active. Memories will auto-inject when their cues match in future tasks. Run `/ciel-memory-bootstrap` again anytime to re-scan for new tribal docs."
134
+
135
+ ---
136
+
137
+ ## Constraints
138
+
139
+ - **Never write a memory without user confirmation.** Even on bulk confirmation ("all"), display the list first.
140
+ - **Do not delete the source files.** Bootstrap converts; the user keeps the originals as long as they want.
141
+ - **Tag conservatively.** A memory tagged with `**/*` will fire on every task and pollute. If unsure, narrow the path pattern.
142
+ - **No agent dispatch.** This command is deterministic and runs inline.
143
+ - **Idempotent.** Re-running on an already-bootstrapped project should detect existing memories (by source field) and offer to skip duplicates.
144
+
145
+ ---
146
+
147
+ ## Failure modes
148
+
149
+ | Symptom | Cause | Fix |
150
+ |---|---|---|
151
+ | Script not found | `$CLAUDE_PROJECT_DIR` not set | Try `$HOME/.ciel/hooks/memory-bootstrap.sh` instead |
152
+ | Nothing scanned | No tribal docs in this project | Working as intended; report and end |
153
+ | Memories all tagged with broad paths | Source content didn't include path hints | Ask user to refine tags after listing |
154
+ | index.json malformed after rebuild | python3 parse error | Recreate empty index, re-run rebuild step |
155
+
156
+ ## See also
157
+
158
+ - `docs/adrs/0001-cued-recall-memory.md` — full design rationale
159
+ - `skills/workflow/memoire/SKILL.md` — capture/recall flow
160
+ - `skills/workflow/memoire-consolidator/SKILL.md` — periodic maintenance
@@ -15,7 +15,7 @@ Usage: `/ciel-status [--check]`
15
15
  ```
16
16
  ## CIEL STATUS
17
17
 
18
- Version: v6.8.0
18
+ Version: v6.9.0
19
19
  Platform: Claude Code
20
20
  Config: .claude/settings.json — OK (4 hooks registered)
21
21
  Skills directory: skills/ — 43 skills loaded
@@ -6,7 +6,7 @@ temperature: 0.2
6
6
  tools:
7
7
  write: false
8
8
  edit: false
9
- bash: false
9
+ bash: true
10
10
  read: true
11
11
  glob: true
12
12
  grep: true
@@ -4,8 +4,8 @@ mode: subagent
4
4
  model: anthropic/claude-sonnet-4-6
5
5
  temperature: 0.2
6
6
  tools:
7
- write: false
8
- edit: false
7
+ write: true
8
+ edit: true
9
9
  bash: true
10
10
  read: true
11
11
  glob: true
@@ -6,7 +6,7 @@ temperature: 0.2
6
6
  tools:
7
7
  write: false
8
8
  edit: false
9
- bash: false
9
+ bash: true
10
10
  read: true
11
11
  glob: false
12
12
  grep: false