create-claude-cabinet 0.9.0 → 0.10.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.
- package/lib/cli.js +2 -3
- package/lib/copy.js +1 -0
- package/lib/omega-setup.js +44 -0
- package/lib/settings-merge.js +17 -34
- package/package.json +1 -1
- package/templates/rules/memory-capture.md +32 -39
- package/templates/scripts/cabinet-memory-adapter.py +23 -110
- package/templates/skills/cabinet-cc-health/SKILL.md +7 -8
- package/templates/skills/cabinet-historian/SKILL.md +84 -9
- package/templates/skills/cc-upgrade/SKILL.md +29 -0
- package/templates/skills/debrief/SKILL.md +39 -4
- package/templates/skills/debrief/phases/record-lessons.md +30 -1
- package/templates/skills/memory/SKILL.md +79 -15
- package/templates/skills/onboard/SKILL.md +1 -1
- package/templates/skills/onboard/phases/detect-state.md +1 -1
- package/templates/skills/orient/SKILL.md +12 -9
- package/templates/skills/orient/phases/auto-maintenance.md +67 -23
- package/templates/skills/orient/phases/context.md +6 -13
package/lib/cli.js
CHANGED
|
@@ -103,7 +103,7 @@ const MODULES = {
|
|
|
103
103
|
default: true,
|
|
104
104
|
lean: false,
|
|
105
105
|
needsOmega: true,
|
|
106
|
-
templates: ['skills/memory', '
|
|
106
|
+
templates: ['skills/memory', 'scripts/cabinet-memory-adapter.py', 'rules/memory-capture.md'],
|
|
107
107
|
},
|
|
108
108
|
};
|
|
109
109
|
|
|
@@ -558,8 +558,7 @@ async function run() {
|
|
|
558
558
|
|
|
559
559
|
// --- Merge hooks into settings.json ---
|
|
560
560
|
if (selectedModules.includes('hooks') && !flags.dryRun) {
|
|
561
|
-
const
|
|
562
|
-
const settingsPath = mergeSettings(projectDir, { includeDb, includeMemory });
|
|
561
|
+
const settingsPath = mergeSettings(projectDir, { includeDb });
|
|
563
562
|
console.log(` ⚙️ Merged hooks into ${path.relative(projectDir, settingsPath)}`);
|
|
564
563
|
}
|
|
565
564
|
|
package/lib/copy.js
CHANGED
|
@@ -75,6 +75,7 @@ async function walkAndCopy(srcRoot, destRoot, currentSrc, results, dryRun, skipC
|
|
|
75
75
|
if (!dryRun) fs.copyFileSync(srcPath, destPath);
|
|
76
76
|
results.overwritten.push(relPath);
|
|
77
77
|
results.manifest[relPath] = incomingHash;
|
|
78
|
+
console.log(` Updated: ${displayPath}`);
|
|
78
79
|
} else {
|
|
79
80
|
results.skipped.push(relPath);
|
|
80
81
|
// Record the hash of what's actually on disk, not the template —
|
package/lib/omega-setup.js
CHANGED
|
@@ -106,6 +106,21 @@ function setupOmega() {
|
|
|
106
106
|
try {
|
|
107
107
|
execSync(`"${VENV_PYTHON}" -c "import omega"`, { stdio: 'pipe' });
|
|
108
108
|
results.push('Existing omega venv is valid');
|
|
109
|
+
// Ensure cross-encoder model is downloaded (added in v0.9.1)
|
|
110
|
+
try {
|
|
111
|
+
const hasReranker = execSync(
|
|
112
|
+
`"${VENV_PYTHON}" -c "from omega.reranker import _get_model_dir; print('yes' if _get_model_dir() else 'no')"`,
|
|
113
|
+
{ encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }
|
|
114
|
+
).trim();
|
|
115
|
+
if (hasReranker === 'no') {
|
|
116
|
+
console.log(' Downloading cross-encoder model...');
|
|
117
|
+
execSync(`"${VENV_PYTHON}" -c "from omega.reranker import download_model; download_model()"`, {
|
|
118
|
+
stdio: 'pipe',
|
|
119
|
+
timeout: 120000,
|
|
120
|
+
});
|
|
121
|
+
results.push('Downloaded cross-encoder reranker model');
|
|
122
|
+
}
|
|
123
|
+
} catch { /* non-fatal */ }
|
|
109
124
|
return results;
|
|
110
125
|
} catch {
|
|
111
126
|
// Venv is broken — nuke and rebuild (D5)
|
|
@@ -135,6 +150,35 @@ function setupOmega() {
|
|
|
135
150
|
});
|
|
136
151
|
results.push('Downloaded ONNX embedding model (bge-small-en-v1.5)');
|
|
137
152
|
|
|
153
|
+
// 6. Download cross-encoder reranker model (improves query result ranking)
|
|
154
|
+
console.log(' Downloading cross-encoder model...');
|
|
155
|
+
try {
|
|
156
|
+
execSync(`"${VENV_PYTHON}" -c "from omega.reranker import download_model; download_model()"`, {
|
|
157
|
+
stdio: 'pipe',
|
|
158
|
+
timeout: 120000,
|
|
159
|
+
});
|
|
160
|
+
results.push('Downloaded cross-encoder reranker model');
|
|
161
|
+
} catch {
|
|
162
|
+
// Non-fatal — queries work without it, just less accurate ranking
|
|
163
|
+
results.push('Cross-encoder model download skipped (optional)');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 7. Configure omega native hooks in global settings
|
|
167
|
+
// Omega hooks live in ~/.claude/settings.json (global) — they run for all
|
|
168
|
+
// projects and handle memory capture/recall natively. This is idempotent:
|
|
169
|
+
// omega checks if hooks already exist before adding them.
|
|
170
|
+
console.log(' Configuring omega hooks...');
|
|
171
|
+
try {
|
|
172
|
+
execSync(`"${VENV_PYTHON}" -m omega.cli hooks setup`, {
|
|
173
|
+
stdio: 'pipe',
|
|
174
|
+
timeout: 30000,
|
|
175
|
+
});
|
|
176
|
+
results.push('Configured omega native hooks (global settings)');
|
|
177
|
+
} catch {
|
|
178
|
+
// Non-fatal — hooks can be set up manually with `omega hooks setup`
|
|
179
|
+
results.push('Omega hooks setup skipped (run `omega hooks setup` manually)');
|
|
180
|
+
}
|
|
181
|
+
|
|
138
182
|
return results;
|
|
139
183
|
}
|
|
140
184
|
|
package/lib/settings-merge.js
CHANGED
|
@@ -1,31 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
const MEMORY_HOOKS = {
|
|
5
|
-
SessionStart: [
|
|
6
|
-
{
|
|
7
|
-
matcher: 'startup|resume|compact',
|
|
8
|
-
hooks: [
|
|
9
|
-
{
|
|
10
|
-
type: 'command',
|
|
11
|
-
command: '.claude/hooks/memory-session-start.sh',
|
|
12
|
-
},
|
|
13
|
-
],
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
PostCompact: [
|
|
17
|
-
{
|
|
18
|
-
matcher: '',
|
|
19
|
-
hooks: [
|
|
20
|
-
{
|
|
21
|
-
type: 'command',
|
|
22
|
-
command: '.claude/hooks/memory-post-compact.sh',
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
};
|
|
28
|
-
|
|
29
4
|
const DEFAULT_HOOKS = {
|
|
30
5
|
PreToolUse: [
|
|
31
6
|
{
|
|
@@ -75,7 +50,7 @@ const DEFAULT_HOOKS = {
|
|
|
75
50
|
* Merge PIB hooks into the project's .claude/settings.json.
|
|
76
51
|
* Creates the file if it doesn't exist. Preserves existing hooks.
|
|
77
52
|
*/
|
|
78
|
-
function mergeSettings(projectDir, { includeDb = true
|
|
53
|
+
function mergeSettings(projectDir, { includeDb = true } = {}) {
|
|
79
54
|
const settingsDir = path.join(projectDir, '.claude');
|
|
80
55
|
const settingsPath = path.join(settingsDir, 'settings.json');
|
|
81
56
|
|
|
@@ -90,16 +65,24 @@ function mergeSettings(projectDir, { includeDb = true, includeMemory = false } =
|
|
|
90
65
|
|
|
91
66
|
if (!settings.hooks) settings.hooks = {};
|
|
92
67
|
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
68
|
+
// Remove legacy CC memory hooks (v0.9.x and earlier).
|
|
69
|
+
// These are now handled by omega's native hooks in global settings.
|
|
70
|
+
const LEGACY_MEMORY_COMMANDS = [
|
|
71
|
+
'memory-session-start.sh',
|
|
72
|
+
'memory-post-compact.sh',
|
|
73
|
+
];
|
|
74
|
+
for (const [event, entries] of Object.entries(settings.hooks)) {
|
|
75
|
+
if (!Array.isArray(entries)) continue;
|
|
76
|
+
settings.hooks[event] = entries.filter(entry => {
|
|
77
|
+
if (!entry.hooks || !Array.isArray(entry.hooks)) return true;
|
|
78
|
+
return !entry.hooks.some(h =>
|
|
79
|
+
LEGACY_MEMORY_COMMANDS.some(cmd => (h.command || '').includes(cmd))
|
|
80
|
+
);
|
|
81
|
+
});
|
|
99
82
|
}
|
|
100
83
|
|
|
101
84
|
// Merge each hook event type
|
|
102
|
-
for (const [event, newHooks] of Object.entries(
|
|
85
|
+
for (const [event, newHooks] of Object.entries(DEFAULT_HOOKS)) {
|
|
103
86
|
if (!settings.hooks[event]) {
|
|
104
87
|
settings.hooks[event] = newHooks;
|
|
105
88
|
} else {
|
|
@@ -123,4 +106,4 @@ function mergeSettings(projectDir, { includeDb = true, includeMemory = false } =
|
|
|
123
106
|
return settingsPath;
|
|
124
107
|
}
|
|
125
108
|
|
|
126
|
-
module.exports = { mergeSettings, DEFAULT_HOOKS
|
|
109
|
+
module.exports = { mergeSettings, DEFAULT_HOOKS };
|
package/package.json
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
1
|
# Memory Capture Rules
|
|
2
2
|
|
|
3
|
-
When omega memory is active (check:
|
|
4
|
-
|
|
5
|
-
what gets captured and when.
|
|
3
|
+
When omega memory is active (check: `omega hooks doctor` reports OK),
|
|
4
|
+
these rules govern what gets captured and when.
|
|
6
5
|
|
|
7
|
-
##
|
|
6
|
+
## How Capture Works
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
Omega handles memory capture natively through its hooks in
|
|
9
|
+
`~/.claude/settings.json` (global). No project-level hook scripts needed.
|
|
10
10
|
|
|
11
|
-
**
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
**Automatic capture (omega native hooks):**
|
|
12
|
+
- `auto_capture` (UserPromptSubmit) — detects decisions/lessons from user messages in real time
|
|
13
|
+
- `assistant_capture` (Stop) — extracts insights from assistant responses at session end
|
|
14
|
+
- `session_stop` (Stop) — session summary, activity report, auto-reflection
|
|
15
|
+
- `surface_memories` (PostToolUse) — surfaces relevant memories before file edits
|
|
15
16
|
|
|
16
|
-
**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
**Manual capture (adapter or omega MCP tools):**
|
|
18
|
+
- Use `omega_store()` MCP tool directly, or
|
|
19
|
+
- Use the adapter for project-scoped storage:
|
|
20
|
+
```bash
|
|
21
|
+
echo '{"text": "the memory", "type": "decision"}' | \
|
|
22
|
+
~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
|
|
23
|
+
```
|
|
20
24
|
|
|
21
|
-
**
|
|
22
|
-
"no, not like that" or redirects your approach, capture what they
|
|
23
|
-
actually want. "User prefers single bundled PRs for refactors, not
|
|
24
|
-
many small ones."
|
|
25
|
+
**Memory types:** `decision`, `lesson_learned`, `user_preference`, `constraint`, `error_pattern`
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
first time — naming pattern, file organization, workflow step. Not
|
|
28
|
-
the convention itself (that's in the code), but that it was a
|
|
29
|
-
deliberate choice.
|
|
27
|
+
## What to Capture Manually
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
Omega's auto_capture hook catches many decisions and lessons from
|
|
30
|
+
conversation flow. Manual capture is for things the hooks miss:
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
**Decisions with reasoning.** Non-obvious architectural choices where
|
|
33
|
+
the "why" matters as much as the "what."
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
|
|
38
|
-
```
|
|
35
|
+
**Discovered constraints.** Limitations or gotchas that waste time
|
|
36
|
+
if you don't know them in advance.
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
**User preferences revealed through correction.** When the user
|
|
39
|
+
redirects your approach — capture what they actually want.
|
|
41
40
|
|
|
42
41
|
## What NOT to Capture
|
|
43
42
|
|
|
@@ -49,17 +48,11 @@ Memory types: `decision`, `lesson`, `preference`, `constraint`, `pattern`
|
|
|
49
48
|
|
|
50
49
|
## Capture Cadence
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Cadence scales with session length and discovery density. A short
|
|
57
|
-
focused session might produce 0-1 memories. A long session with
|
|
58
|
-
multiple discoveries, corrections, and decisions could produce 5-10+.
|
|
59
|
-
The right number is however many genuinely worth-remembering things
|
|
60
|
-
happened — no artificial cap.
|
|
51
|
+
Omega's native hooks handle most capture automatically. Manual capture
|
|
52
|
+
should be rare — only when something important happened that the hooks
|
|
53
|
+
wouldn't detect (e.g., a nuanced architectural decision discussed
|
|
54
|
+
verbally, or a constraint discovered through external research).
|
|
61
55
|
|
|
62
56
|
Over-capturing degrades retrieval quality. The test: *"Would a future
|
|
63
57
|
session benefit from knowing this?"* If yes, capture it. If it's just
|
|
64
|
-
noise or ephemera, skip it.
|
|
65
|
-
important that was missed during the session.
|
|
58
|
+
noise or ephemera, skip it.
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
Cabinet Memory Adapter — single Python file wrapping
|
|
3
|
+
Cabinet Memory Adapter — single Python file wrapping omega interaction.
|
|
4
4
|
|
|
5
|
-
Called by
|
|
5
|
+
Called by skills and scripts via the venv Python. Provides project-scoped
|
|
6
|
+
tiered retrieval (omega's main gap) and a stable JSON-in/JSON-out interface.
|
|
6
7
|
Designed for D2 (never block Claude Code) and D3 (graceful degradation).
|
|
7
8
|
|
|
9
|
+
Note: Session-level hooks (welcome, capture, session start/stop) are handled
|
|
10
|
+
by omega's native hooks configured in ~/.claude/settings.json (global).
|
|
11
|
+
This adapter handles skill-invoked operations only.
|
|
12
|
+
|
|
8
13
|
Usage:
|
|
9
14
|
cabinet-memory-adapter.py <command> [options]
|
|
10
15
|
|
|
11
16
|
Commands:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
store Store a memory directly (called by debrief)
|
|
15
|
-
query Query memories by text
|
|
17
|
+
store Store a memory directly (called by debrief, /memory)
|
|
18
|
+
query Query memories by text (with project-scoped tiering)
|
|
16
19
|
delete Delete a memory by full node_id
|
|
17
20
|
list List all memories with full node_ids
|
|
18
|
-
status Check omega health
|
|
19
21
|
|
|
20
22
|
All commands read JSON from stdin when applicable.
|
|
21
23
|
All commands output JSON to stdout.
|
|
@@ -59,87 +61,15 @@ def _import_omega():
|
|
|
59
61
|
return None
|
|
60
62
|
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if not omega:
|
|
72
|
-
_error("omega not available")
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
try:
|
|
76
|
-
cwd = data.get("cwd", os.getcwd())
|
|
77
|
-
project_name = os.path.basename(cwd)
|
|
78
|
-
|
|
79
|
-
result = omega.welcome(project=project_name)
|
|
80
|
-
if not result:
|
|
81
|
-
_output({"ok": True, "context": ""})
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
# welcome() returns a dict with memory count, recent memories, etc.
|
|
85
|
-
if isinstance(result, dict):
|
|
86
|
-
context = (
|
|
87
|
-
result.get("observation_prefix", "")
|
|
88
|
-
or result.get("summary", "")
|
|
89
|
-
or result.get("context", "")
|
|
90
|
-
)
|
|
91
|
-
if not context and result.get("memory_count", 0) == 0:
|
|
92
|
-
_output({"ok": True, "context": ""})
|
|
93
|
-
return
|
|
94
|
-
if not context:
|
|
95
|
-
context = json.dumps(result, indent=2)
|
|
96
|
-
_output({"ok": True, "context": context})
|
|
97
|
-
elif isinstance(result, str):
|
|
98
|
-
_output({"ok": True, "context": result})
|
|
99
|
-
else:
|
|
100
|
-
_output({"ok": True, "context": str(result)})
|
|
101
|
-
except Exception as e:
|
|
102
|
-
_error(f"welcome failed: {e}")
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def cmd_capture():
|
|
106
|
-
"""Capture context from PostCompact summary.
|
|
107
|
-
|
|
108
|
-
Reads compact_summary from stdin.
|
|
109
|
-
Extracts key decisions, lessons, and reasoning chains.
|
|
110
|
-
Stores them in omega.
|
|
111
|
-
"""
|
|
112
|
-
data = _read_stdin()
|
|
113
|
-
omega = _import_omega()
|
|
114
|
-
if not omega:
|
|
115
|
-
_error("omega not available")
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
summary = data.get("compact_summary", "")
|
|
119
|
-
if not summary:
|
|
120
|
-
_output({"ok": True, "stored": 0, "reason": "no summary"})
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
session_id = data.get("session_id", "unknown")
|
|
124
|
-
cwd = data.get("cwd", os.getcwd())
|
|
125
|
-
project_name = os.path.basename(cwd)
|
|
126
|
-
|
|
127
|
-
try:
|
|
128
|
-
result = omega.auto_capture(
|
|
129
|
-
summary,
|
|
130
|
-
event_type="compaction",
|
|
131
|
-
session_id=session_id,
|
|
132
|
-
project=project_name,
|
|
133
|
-
)
|
|
134
|
-
count = 0
|
|
135
|
-
if isinstance(result, dict):
|
|
136
|
-
count = result.get("stored", 0)
|
|
137
|
-
elif isinstance(result, (list, tuple)):
|
|
138
|
-
count = len(result)
|
|
139
|
-
|
|
140
|
-
_output({"ok": True, "stored": count})
|
|
141
|
-
except Exception as e:
|
|
142
|
-
_error(f"capture failed: {e}")
|
|
64
|
+
# Map friendly type names to omega's native event_type values.
|
|
65
|
+
# This ensures permanent TTL for types that should never expire.
|
|
66
|
+
_TYPE_MAP = {
|
|
67
|
+
"lesson": "lesson_learned",
|
|
68
|
+
"preference": "user_preference",
|
|
69
|
+
"error": "error_pattern",
|
|
70
|
+
# These already match omega's native types:
|
|
71
|
+
# "decision", "constraint", "error_pattern", "lesson_learned", "user_preference"
|
|
72
|
+
}
|
|
143
73
|
|
|
144
74
|
|
|
145
75
|
def cmd_store():
|
|
@@ -147,7 +77,9 @@ def cmd_store():
|
|
|
147
77
|
|
|
148
78
|
Reads JSON from stdin with fields:
|
|
149
79
|
text: the memory content (required)
|
|
150
|
-
type: event_type for omega (default: "
|
|
80
|
+
type: event_type for omega (default: "lesson_learned")
|
|
81
|
+
Accepts friendly names: lesson, preference, error
|
|
82
|
+
which are mapped to omega native types.
|
|
151
83
|
tags: list of tags (stored in metadata, optional)
|
|
152
84
|
project: project name (default: basename of cwd)
|
|
153
85
|
"""
|
|
@@ -163,7 +95,8 @@ def cmd_store():
|
|
|
163
95
|
return
|
|
164
96
|
|
|
165
97
|
try:
|
|
166
|
-
|
|
98
|
+
raw_type = data.get("type", "lesson")
|
|
99
|
+
event_type = _TYPE_MAP.get(raw_type, raw_type)
|
|
167
100
|
project = data.get("project", os.path.basename(os.getcwd()))
|
|
168
101
|
metadata = {}
|
|
169
102
|
if data.get("tags"):
|
|
@@ -335,23 +268,6 @@ def cmd_query():
|
|
|
335
268
|
_error(f"query failed: {e}")
|
|
336
269
|
|
|
337
270
|
|
|
338
|
-
def cmd_status():
|
|
339
|
-
"""Check omega health status."""
|
|
340
|
-
omega = _import_omega()
|
|
341
|
-
if not omega:
|
|
342
|
-
_output({"ok": False, "status": "omega not available"})
|
|
343
|
-
return
|
|
344
|
-
|
|
345
|
-
try:
|
|
346
|
-
result = omega.status()
|
|
347
|
-
if isinstance(result, dict):
|
|
348
|
-
_output({"ok": True, **result})
|
|
349
|
-
else:
|
|
350
|
-
_output({"ok": True, "status": str(result)})
|
|
351
|
-
except Exception as e:
|
|
352
|
-
_error(f"status failed: {e}")
|
|
353
|
-
|
|
354
|
-
|
|
355
271
|
def cmd_delete():
|
|
356
272
|
"""Delete a memory by its full node_id.
|
|
357
273
|
|
|
@@ -433,13 +349,10 @@ def cmd_list():
|
|
|
433
349
|
|
|
434
350
|
|
|
435
351
|
COMMANDS = {
|
|
436
|
-
"welcome": cmd_welcome,
|
|
437
|
-
"capture": cmd_capture,
|
|
438
352
|
"store": cmd_store,
|
|
439
353
|
"query": cmd_query,
|
|
440
354
|
"delete": cmd_delete,
|
|
441
355
|
"list": cmd_list,
|
|
442
|
-
"status": cmd_status,
|
|
443
356
|
}
|
|
444
357
|
|
|
445
358
|
if __name__ == "__main__":
|
|
@@ -397,17 +397,16 @@ If the memory module is installed (check `.ccrc.json` modules list for
|
|
|
397
397
|
A broken venv means all memory hooks silently degrade.
|
|
398
398
|
|
|
399
399
|
- **Adapter availability.** Does `scripts/cabinet-memory-adapter.py`
|
|
400
|
-
exist in the project?
|
|
400
|
+
exist in the project? Skills use it for project-scoped queries.
|
|
401
401
|
|
|
402
|
-
- **Hook registration.** Check
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
402
|
+
- **Hook registration.** Check `~/.claude/settings.json` (global) for
|
|
403
|
+
omega native hooks (`fast_hook.py session_start`, etc.). Run
|
|
404
|
+
`omega hooks doctor` to verify. Missing hooks mean omega was installed
|
|
405
|
+
but `omega hooks setup` was never run.
|
|
406
406
|
|
|
407
|
-
- **Omega database.** Run
|
|
407
|
+
- **Omega database.** Run `omega status` to check health:
|
|
408
408
|
```bash
|
|
409
|
-
|
|
410
|
-
scripts/cabinet-memory-adapter.py status
|
|
409
|
+
~/.claude-cabinet/omega-venv/bin/omega status
|
|
411
410
|
```
|
|
412
411
|
Check: is the database growing? Zero memories after multiple sessions
|
|
413
412
|
suggests capture isn't working.
|
|
@@ -105,6 +105,28 @@ to help you do your job.
|
|
|
105
105
|
Omega data lives at `~/.omega/omega.db` (SQLite). The `/memory` skill
|
|
106
106
|
gives users self-serve access to browse, search, and manage memories.
|
|
107
107
|
|
|
108
|
+
**Graph traversal** (follow connections from a memory):
|
|
109
|
+
```bash
|
|
110
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
111
|
+
from omega import traverse
|
|
112
|
+
result = traverse('MEM_ID', max_hops=2)
|
|
113
|
+
print(result)
|
|
114
|
+
"
|
|
115
|
+
```
|
|
116
|
+
After finding a relevant memory, traverse its graph connections to
|
|
117
|
+
discover related decisions, contradictions, or how understanding evolved.
|
|
118
|
+
Edge types: `related`, `evolution`, `contradicts`, `temporal_cluster`.
|
|
119
|
+
|
|
120
|
+
**Contradiction detection** (find conflicting memories):
|
|
121
|
+
```bash
|
|
122
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
123
|
+
from omega import SQLiteStore
|
|
124
|
+
s = SQLiteStore()
|
|
125
|
+
edges = s.get_edges_by_type('contradicts')
|
|
126
|
+
for e in edges: print(f\"{e['source_id']} <-> {e['target_id']} ({e['weight']:.2f})\")
|
|
127
|
+
"
|
|
128
|
+
```
|
|
129
|
+
|
|
108
130
|
Omega returns memories ranked by relevance. This is the richest source
|
|
109
131
|
of institutional memory when available. If omega queries return nothing
|
|
110
132
|
or fail, fall through to source 1 (flat memory files).
|
|
@@ -190,10 +212,10 @@ what was about to happen next. This is the historian's moment.
|
|
|
190
212
|
in a session should survive compaction because it's been written
|
|
191
213
|
down *during* the session, not just summarized after truncation.
|
|
192
214
|
|
|
193
|
-
**Omega and compaction:** If omega memory is active,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
preserved:
|
|
215
|
+
**Omega and compaction:** If omega memory is active, omega's native hooks
|
|
216
|
+
automatically capture key context at session boundaries (session_stop,
|
|
217
|
+
auto_capture, assistant_capture). After compaction, query omega to see
|
|
218
|
+
what was preserved:
|
|
197
219
|
|
|
198
220
|
```bash
|
|
199
221
|
echo '{"text": "session context before compaction", "limit": 5}' | \
|
|
@@ -229,11 +251,64 @@ You are responsible for the health of the memory system:
|
|
|
229
251
|
they can be catalogued — if the team keeps re-deriving solutions, if
|
|
230
252
|
memory files are growing too large to scan, if conversation history
|
|
231
253
|
search isn't surfacing what it should — advocate for better tooling.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
254
|
+
|
|
255
|
+
### Memory Health Measurement
|
|
256
|
+
|
|
257
|
+
When activated during audit or review, evaluate omega memory health:
|
|
258
|
+
|
|
259
|
+
**Growth & Coverage:**
|
|
260
|
+
```bash
|
|
261
|
+
~/.claude-cabinet/omega-venv/bin/omega stats --json 2>&1
|
|
262
|
+
```
|
|
263
|
+
Check: Is the memory count growing session over session? Are all
|
|
264
|
+
permanent types represented (decision, lesson_learned, user_preference,
|
|
265
|
+
constraint, error_pattern)? Gaps suggest capture isn't working for
|
|
266
|
+
certain categories.
|
|
267
|
+
|
|
268
|
+
**Graph Connectivity:**
|
|
269
|
+
```bash
|
|
270
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
271
|
+
from omega import SQLiteStore
|
|
272
|
+
s = SQLiteStore()
|
|
273
|
+
import sqlite3
|
|
274
|
+
conn = sqlite3.connect(s.db_path)
|
|
275
|
+
total = conn.execute('SELECT COUNT(*) FROM memories').fetchone()[0]
|
|
276
|
+
edges = s.edge_count()
|
|
277
|
+
connected = conn.execute('SELECT COUNT(DISTINCT source_id) + COUNT(DISTINCT target_id) FROM memory_relationships').fetchone()[0]
|
|
278
|
+
print(f'Memories: {total}, Edges: {edges}, Connected: {connected}/{total} ({100*connected//max(total,1)}%)')
|
|
279
|
+
"
|
|
280
|
+
```
|
|
281
|
+
Target: >50% of memories should participate in at least one edge.
|
|
282
|
+
Below 30% means discover_connections isn't running or memories are
|
|
283
|
+
too diverse to auto-relate.
|
|
284
|
+
|
|
285
|
+
**Contradiction Health:**
|
|
286
|
+
```bash
|
|
287
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
288
|
+
from omega import SQLiteStore
|
|
289
|
+
s = SQLiteStore()
|
|
290
|
+
contradictions = s.get_edges_by_type('contradicts')
|
|
291
|
+
print(f'{len(contradictions)} contradiction(s) detected')
|
|
292
|
+
for c in contradictions:
|
|
293
|
+
print(f' {c[\"source_id\"]} <-> {c[\"target_id\"]} (confidence: {c[\"weight\"]:.2f})')
|
|
294
|
+
"
|
|
295
|
+
```
|
|
296
|
+
Unresolved contradictions are technical debt in the knowledge graph.
|
|
297
|
+
Surface them and recommend resolution.
|
|
298
|
+
|
|
299
|
+
**Consolidation Effectiveness:**
|
|
300
|
+
```bash
|
|
301
|
+
~/.claude-cabinet/omega-venv/bin/omega consolidate --prune-days 30 2>&1
|
|
302
|
+
```
|
|
303
|
+
Check: Are duplicates accumulating? Are zero-access memories growing?
|
|
304
|
+
If consolidation consistently prunes many entries, capture quality
|
|
305
|
+
may need improvement (storing noise instead of signal).
|
|
306
|
+
|
|
307
|
+
**Retrieval Quality (spot check):**
|
|
308
|
+
Pick 2-3 recent decisions or lessons from the session. Query omega
|
|
309
|
+
for each one. Does the query return the correct memory in the top 3
|
|
310
|
+
results? If not, embeddings may be degraded or the memory text may
|
|
311
|
+
be too generic to differentiate.
|
|
237
312
|
|
|
238
313
|
## Output Format
|
|
239
314
|
|
|
@@ -129,6 +129,35 @@ the upstream guard hook because it runs as a separate process using
|
|
|
129
129
|
the filesystem directly. This is by design — the installer is the
|
|
130
130
|
authorized update path for manifest-tracked files.
|
|
131
131
|
|
|
132
|
+
### 2.4. Memory Hook Migration (v0.9.x → v0.10+)
|
|
133
|
+
|
|
134
|
+
**This step runs when upgrading from v0.9.x or earlier** (detected by
|
|
135
|
+
the presence of `memory-session-start.sh` or `memory-post-compact.sh`
|
|
136
|
+
in `.claude/settings.json`).
|
|
137
|
+
|
|
138
|
+
Starting in v0.10, omega's native hooks handle memory capture/recall
|
|
139
|
+
directly (configured in global `~/.claude/settings.json`). The old
|
|
140
|
+
project-level CC memory hooks are now redundant and cause double
|
|
141
|
+
context injection if left in place.
|
|
142
|
+
|
|
143
|
+
**Check and clean:**
|
|
144
|
+
1. Read `.claude/settings.json` — look for `memory-session-start.sh`
|
|
145
|
+
in `SessionStart` hooks and `memory-post-compact.sh` in `PostCompact`
|
|
146
|
+
2. If found, remove those entries. Keep other hooks (git-guardrails,
|
|
147
|
+
cc-upstream-guard, telemetry) untouched.
|
|
148
|
+
3. Verify omega native hooks are configured: run `omega hooks doctor`.
|
|
149
|
+
If not configured, the installer's omega-setup already ran
|
|
150
|
+
`omega hooks setup` — verify by checking `~/.claude/settings.json`
|
|
151
|
+
for `fast_hook.py` entries.
|
|
152
|
+
4. The old shell scripts (`hooks/memory-session-start.sh`,
|
|
153
|
+
`hooks/memory-post-compact.sh`) can be deleted from the project's
|
|
154
|
+
`.claude/hooks/` directory — they're no longer called.
|
|
155
|
+
|
|
156
|
+
**Tell the user:** "Memory hooks have been upgraded to omega native.
|
|
157
|
+
You now get 3 additional capabilities: real-time decision capture,
|
|
158
|
+
assistant insight extraction, and relevant memory surfacing before
|
|
159
|
+
file edits."
|
|
160
|
+
|
|
132
161
|
### 2.5. Legacy Detection and Migration
|
|
133
162
|
|
|
134
163
|
**This step runs ONLY when upgrading from v0.5.x or earlier** (detected
|
|
@@ -116,9 +116,44 @@ Read `phases/close-work.md` for how to match session work against open
|
|
|
116
116
|
items and close them. This includes marking tasks as done, resolving
|
|
117
117
|
feedback, and updating any tracking system.
|
|
118
118
|
|
|
119
|
-
**
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
**Default (absent/empty):** Match the session's work against open items
|
|
120
|
+
in pib-db and propose closing what was completed. If pib-db is not
|
|
121
|
+
initialized, skip gracefully.
|
|
122
|
+
|
|
123
|
+
1. **Get session work:** `git log --oneline` for this session's commits
|
|
124
|
+
(since session start or last 2 hours)
|
|
125
|
+
2. **Get open actions:**
|
|
126
|
+
```bash
|
|
127
|
+
sqlite3 pib.db "SELECT fid, text, project_fid FROM actions WHERE completed = 0 AND deleted_at IS NULL ORDER BY flagged DESC, sort_order ASC"
|
|
128
|
+
```
|
|
129
|
+
3. **Match:** For each open action, check if the session's commits
|
|
130
|
+
address it (compare action text/notes against commit messages and
|
|
131
|
+
changed files)
|
|
132
|
+
4. **Propose:** Present matched actions and ask the user to confirm
|
|
133
|
+
which to close
|
|
134
|
+
5. **Close confirmed:**
|
|
135
|
+
```bash
|
|
136
|
+
sqlite3 pib.db "UPDATE actions SET completed = 1, completed_at = date('now') WHERE fid = '<fid>'"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Project completion scan:** After closing actions, check for projects
|
|
140
|
+
where all actions are now done:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
sqlite3 pib.db "
|
|
144
|
+
SELECT p.fid, p.name,
|
|
145
|
+
(SELECT COUNT(*) FROM actions a WHERE a.project_fid = p.fid) as total,
|
|
146
|
+
(SELECT COUNT(*) FROM actions a WHERE a.project_fid = p.fid AND a.completed = 1) as done
|
|
147
|
+
FROM projects p
|
|
148
|
+
WHERE p.status = 'active'
|
|
149
|
+
AND p.deleted_at IS NULL
|
|
150
|
+
AND (SELECT COUNT(*) FROM actions a WHERE a.project_fid = p.fid) > 0
|
|
151
|
+
AND (SELECT COUNT(*) FROM actions a WHERE a.project_fid = p.fid AND a.completed = 0 AND a.deleted_at IS NULL) = 0
|
|
152
|
+
"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For each result, propose completing the project (show name + action
|
|
156
|
+
count, confirm before closing).
|
|
122
157
|
|
|
123
158
|
For each open item, determine:
|
|
124
159
|
- **Clearly complete** — mark it done with a reference to what was built
|
|
@@ -377,7 +412,7 @@ Read `phases/report.md` for how to present the debrief summary.
|
|
|
377
412
|
| Phase | Absent = | What it customizes |
|
|
378
413
|
|-------|----------|-------------------|
|
|
379
414
|
| `inventory.md` | Default: review git log + session | How to identify what was done |
|
|
380
|
-
| `close-work.md` |
|
|
415
|
+
| `close-work.md` | Default: match pib-db actions against git log | How to close work items |
|
|
381
416
|
| `auto-maintenance.md` | Skip | Recurring session-end tasks |
|
|
382
417
|
| `update-state.md` | Default: check system-status.md | What state files to update |
|
|
383
418
|
| `health-checks.md` | Skip | Session-end health checks |
|
|
@@ -61,6 +61,35 @@ Review the session and ask:
|
|
|
61
61
|
- Anything already in CLAUDE.md files
|
|
62
62
|
- Ephemeral task details only relevant to this session
|
|
63
63
|
|
|
64
|
+
## After Storing — Link and Check
|
|
65
|
+
|
|
66
|
+
After storing each memory, omega auto-relates it to similar existing
|
|
67
|
+
memories. Surface this to the user:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
71
|
+
from omega import find_similar_memories
|
|
72
|
+
result = find_similar_memories('THE_NEW_MEMORY_ID')
|
|
73
|
+
print(result)
|
|
74
|
+
"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If the new memory is similar to existing ones, mention it:
|
|
78
|
+
"This connects to your earlier memory about [topic]."
|
|
79
|
+
|
|
80
|
+
Also check for contradictions — if the new memory conflicts with an
|
|
81
|
+
existing one, ask the user which is correct:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
85
|
+
from omega import SQLiteStore
|
|
86
|
+
s = SQLiteStore()
|
|
87
|
+
edges = s.get_edges_by_type('contradicts')
|
|
88
|
+
for e in edges: print(f\"{e['source_id']} <-> {e['target_id']} ({e['weight']:.2f})\")
|
|
89
|
+
"
|
|
90
|
+
```
|
|
91
|
+
|
|
64
92
|
## Report What Was Recorded
|
|
65
93
|
Tell the user what memories were created or updated so they know what
|
|
66
|
-
the system will remember next time. Include the count and
|
|
94
|
+
the system will remember next time. Include the count, types, and any
|
|
95
|
+
new connections discovered in the knowledge graph.
|
|
@@ -27,9 +27,11 @@ If not available, tell the user:
|
|
|
27
27
|
|
|
28
28
|
## Adapter Reference
|
|
29
29
|
|
|
30
|
-
The adapter (`scripts/cabinet-memory-adapter.py`)
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
The adapter (`scripts/cabinet-memory-adapter.py`) provides project-scoped
|
|
31
|
+
queries and a stable JSON interface. Session-level capture and recall are
|
|
32
|
+
handled by omega's native hooks (configured globally). The adapter handles
|
|
33
|
+
skill-invoked operations. All commands read JSON from stdin, output JSON
|
|
34
|
+
to stdout, and exit 0 even on failure.
|
|
33
35
|
|
|
34
36
|
```bash
|
|
35
37
|
echo '<json>' | ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py <command>
|
|
@@ -37,16 +39,13 @@ echo '<json>' | ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-
|
|
|
37
39
|
|
|
38
40
|
| Command | Input | Output |
|
|
39
41
|
|---------|-------|--------|
|
|
40
|
-
| `welcome` | `{}` or hook JSON | `{ok, context}` — relevant memories |
|
|
41
42
|
| `store` | `{text, type, tags?, project?}` | `{ok, id}` — stored memory ID |
|
|
42
|
-
| `query` | `{text, limit?, type?, project?, scope?}` | `{ok, results}` — semantic search |
|
|
43
|
+
| `query` | `{text, limit?, type?, project?, scope?}` | `{ok, results}` — semantic search with project scoping |
|
|
43
44
|
| `delete` | `{id}` | `{ok, deleted}` — requires full node_id |
|
|
44
45
|
| `list` | `{type?, project?, limit?}` | `{ok, memories, count}` — all memories with full IDs |
|
|
45
|
-
| `capture` | hook JSON with `compact_summary` | `{ok, stored}` — auto-capture count |
|
|
46
|
-
| `status` | `{}` | `{ok, ...health info}` |
|
|
47
46
|
|
|
48
|
-
Memory types: `decision`, `
|
|
49
|
-
`
|
|
47
|
+
Memory types: `decision`, `lesson_learned`, `user_preference`, `constraint`,
|
|
48
|
+
`error_pattern`.
|
|
50
49
|
|
|
51
50
|
## Commands
|
|
52
51
|
|
|
@@ -83,6 +82,25 @@ Present results conversationally — highlight the most relevant matches,
|
|
|
83
82
|
their types, and which project they came from when cross-project results
|
|
84
83
|
appear.
|
|
85
84
|
|
|
85
|
+
**Graph enrichment:** For the top 1-2 results, check for related memories
|
|
86
|
+
via omega's graph traversal. This surfaces the knowledge network — not
|
|
87
|
+
just what matched, but what's connected to what matched:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
91
|
+
from omega import traverse
|
|
92
|
+
result = traverse('THE_MEMORY_ID', max_hops=2)
|
|
93
|
+
print(result)
|
|
94
|
+
"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If traversal returns connected memories, present them as "Related:"
|
|
98
|
+
under the main result. Edge types tell the story:
|
|
99
|
+
- `related` — semantically similar
|
|
100
|
+
- `evolution` — this understanding has developed over time
|
|
101
|
+
- `contradicts` — conflicts with another memory (surface both sides)
|
|
102
|
+
- `temporal_cluster` — captured in the same session
|
|
103
|
+
|
|
86
104
|
### Remember — user wants to store something
|
|
87
105
|
|
|
88
106
|
```bash
|
|
@@ -91,13 +109,59 @@ echo '{"text": "what to remember", "type": "preference"}' | \
|
|
|
91
109
|
```
|
|
92
110
|
|
|
93
111
|
Pick the type based on what the user said:
|
|
94
|
-
- `decision` — they made a choice and want it recorded
|
|
95
|
-
- `lesson` — they learned something
|
|
96
|
-
- `preference` — they want something done a certain way
|
|
97
|
-
- `constraint` — a limitation or prerequisite
|
|
98
|
-
- `
|
|
112
|
+
- `decision` — they made a choice and want it recorded (permanent)
|
|
113
|
+
- `lesson` — they learned something (maps to `lesson_learned`, permanent)
|
|
114
|
+
- `preference` — they want something done a certain way (maps to `user_preference`, permanent)
|
|
115
|
+
- `constraint` — a limitation or prerequisite (permanent)
|
|
116
|
+
- `error` — a failure pattern to avoid (maps to `error_pattern`, permanent)
|
|
117
|
+
|
|
118
|
+
The adapter maps friendly names to omega's native types for correct TTL.
|
|
119
|
+
|
|
120
|
+
Confirm what was stored. After storing, check for similar existing memories
|
|
121
|
+
and link them if relevant:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
125
|
+
from omega import find_similar_memories
|
|
126
|
+
result = find_similar_memories('THE_NEW_MEMORY_ID')
|
|
127
|
+
print(result)
|
|
128
|
+
"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
If similar memories exist, tell the user: "This connects to N existing
|
|
132
|
+
memories about [topic]." Omega auto-relates on store, but surfacing it
|
|
133
|
+
builds user confidence that the knowledge graph is working.
|
|
134
|
+
|
|
135
|
+
### Link — user wants to connect memories
|
|
136
|
+
|
|
137
|
+
If the user says "link these" or "these are related":
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
141
|
+
from omega import SQLiteStore
|
|
142
|
+
s = SQLiteStore()
|
|
143
|
+
s.add_edge('MEM_ID_1', 'MEM_ID_2', edge_type='related', weight=1.0)
|
|
144
|
+
print('Linked')
|
|
145
|
+
"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Edge types: `related`, `contradicts`, `supersedes`, `evolves`.
|
|
149
|
+
|
|
150
|
+
### Contradictions — user asks what conflicts
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
154
|
+
from omega import SQLiteStore
|
|
155
|
+
s = SQLiteStore()
|
|
156
|
+
edges = s.get_edges_by_type('contradicts')
|
|
157
|
+
for e in edges:
|
|
158
|
+
print(f\"{e['source_id']} <-> {e['target_id']} (confidence: {e['weight']:.2f})\")
|
|
159
|
+
if not edges: print('No contradictions found')
|
|
160
|
+
"
|
|
161
|
+
```
|
|
99
162
|
|
|
100
|
-
|
|
163
|
+
For each contradiction pair, query both memories to show the user what
|
|
164
|
+
conflicts. Ask which one is correct, then supersede the wrong one.
|
|
101
165
|
|
|
102
166
|
### Forget — user wants to remove something
|
|
103
167
|
|
|
@@ -171,7 +171,7 @@ Read `phases/work-tracking.md` for how to present work tracking options.
|
|
|
171
171
|
tasks.md, GitHub Issues, custom phase files). Present two built-in
|
|
172
172
|
options — SQLite database (pib-db) or markdown file (tasks.md) — plus
|
|
173
173
|
bring-your-own for external systems. User picks one, the other, or
|
|
174
|
-
neither. The choice is recorded in `.
|
|
174
|
+
neither. The choice is recorded in `.ccrc.json` under `workTracking`
|
|
175
175
|
and feeds into generate-briefing and generate-session-loop.
|
|
176
176
|
|
|
177
177
|
### 4. Options
|
|
@@ -49,7 +49,7 @@ early vs mature re-run:
|
|
|
49
49
|
| CLAUDE.md | Root `CLAUDE.md` | Project instructions exist |
|
|
50
50
|
| Rules files | `.claude/rules/*.md` | Scoped instructions exist |
|
|
51
51
|
| Hook config | `.claude/settings.json` or `.claude/settings.local.json` | Enforcement hooks exist |
|
|
52
|
-
| Omega memory | `~/.claude-cabinet/omega-venv/` and `
|
|
52
|
+
| Omega memory | `~/.claude-cabinet/omega-venv/` and `omega hooks doctor` OK | Semantic memory is active |
|
|
53
53
|
|
|
54
54
|
**Early re-run:** Fewer than 5 of the above are populated.
|
|
55
55
|
**Mature re-run:** 5 or more are populated.
|
|
@@ -89,16 +89,17 @@ sessions, and project-specific context.
|
|
|
89
89
|
- `.claude/memory/patterns/` — enforcement patterns from prior sessions.
|
|
90
90
|
Scan the directory, read each pattern file. These are project-level
|
|
91
91
|
feedback that guides behavior (what to avoid, what to keep doing).
|
|
92
|
-
- **Omega semantic memory** —
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
- **Omega semantic memory** — omega's native SessionStart hook
|
|
93
|
+
automatically surfaces recalled memories. During orient, query for
|
|
94
|
+
additional project-scoped context via the adapter:
|
|
95
95
|
```bash
|
|
96
96
|
echo '{"text": "session context project status recent decisions", "limit": 10}' | \
|
|
97
97
|
~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py query
|
|
98
98
|
```
|
|
99
99
|
Surface any relevant memories (decisions, lessons, constraints) that
|
|
100
|
-
inform the current session. If
|
|
101
|
-
|
|
100
|
+
inform the current session. If omega is unavailable, run `omega hooks
|
|
101
|
+
doctor` to diagnose. If the venv is missing but `.ccrc.json` lists
|
|
102
|
+
the memory module as installed, warn the user:
|
|
102
103
|
> ⚠ Memory module is installed but omega venv is missing.
|
|
103
104
|
> Run `npx create-claude-cabinet` to restore it.
|
|
104
105
|
|
|
@@ -211,9 +212,11 @@ Read `phases/auto-maintenance.md` for recurring automated tasks that
|
|
|
211
212
|
should run every session. These are operations that would decay if left
|
|
212
213
|
to human memory — the anti-entropy principle in action.
|
|
213
214
|
|
|
214
|
-
**
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
**Default (absent/empty):** If omega is active (`~/.claude-cabinet/omega-venv/bin/omega`
|
|
216
|
+
exists), run memory hygiene: `omega consolidate` every session (prune stale,
|
|
217
|
+
dedup), `omega compact` weekly (cluster similar memories), `omega backup`
|
|
218
|
+
weekly. Projects add additional maintenance tasks as they discover operations
|
|
219
|
+
that need regular execution.
|
|
217
220
|
|
|
218
221
|
### 6. Activate Cabinet Members (core)
|
|
219
222
|
|
|
@@ -259,7 +262,7 @@ stated a focus, ask.
|
|
|
259
262
|
| `data-sync.md` | Skip | How to sync remote data |
|
|
260
263
|
| `work-scan.md` | Default: pib-db scan + staleness detection | What work items to check |
|
|
261
264
|
| `health-checks.md` | Skip | System health checks |
|
|
262
|
-
| `auto-maintenance.md` |
|
|
265
|
+
| `auto-maintenance.md` | Default: omega memory hygiene | Recurring session-start tasks |
|
|
263
266
|
| `cabinet.md` | Skip | Which cabinet members to activate |
|
|
264
267
|
| `briefing.md` | Default: simple summary | How to present orientation |
|
|
265
268
|
|
|
@@ -6,43 +6,87 @@ applied to session management.
|
|
|
6
6
|
|
|
7
7
|
The distinction from health checks: health checks DETECT problems;
|
|
8
8
|
auto-maintenance DOES work. A health check reports "data is stale."
|
|
9
|
+
An auto-maintenance task runs the sync to fix it.
|
|
9
10
|
|
|
10
11
|
When this file is absent or empty, this step is skipped. (`skip: true`
|
|
11
12
|
is equivalent to absent here.)
|
|
12
|
-
An auto-maintenance task runs the sync to fix it.
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## Omega Memory Hygiene
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- **Why every session** — what decays if this is skipped
|
|
19
|
-
- **Command** — how to run it
|
|
20
|
-
- **Auto-execute?** — yes (run silently) or surface (ask user first)
|
|
16
|
+
If omega is active (`~/.claude-cabinet/omega-venv/bin/omega` exists),
|
|
17
|
+
run these maintenance tasks every session:
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
### Consolidate (every session)
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
Prune zero-access memories older than 30 days and deduplicate. Silent,
|
|
22
|
+
non-destructive — only removes never-accessed entries and exact duplicates.
|
|
25
23
|
|
|
26
|
-
<!--
|
|
27
|
-
### Process Pending Queue Items
|
|
28
24
|
```bash
|
|
29
|
-
|
|
30
|
-
curl -s https://your-api.example.com/api/queue/pending
|
|
25
|
+
~/.claude-cabinet/omega-venv/bin/omega consolidate --prune-days 30 2>&1
|
|
31
26
|
```
|
|
32
|
-
Items queued from a UI or external integration since last session.
|
|
33
|
-
Auto-execute routine items; surface unusual ones for confirmation.
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
Report only if something was actually pruned or merged (non-zero counts).
|
|
29
|
+
|
|
30
|
+
### Compact (weekly)
|
|
31
|
+
|
|
32
|
+
Cluster and summarize similar memories by type. Only run if 7+ days
|
|
33
|
+
since last compact. Check by looking for the most recent `compaction`
|
|
34
|
+
type memory via the adapter:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
echo '{"type": "compaction", "limit": 1}' | \
|
|
38
|
+
~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py list
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If the most recent compaction memory is older than 7 days (or none exists):
|
|
42
|
+
|
|
36
43
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
~/.claude-cabinet/omega-venv/bin/omega compact -t lesson_learned 2>&1
|
|
45
|
+
~/.claude-cabinet/omega-venv/bin/omega compact -t decision 2>&1
|
|
46
|
+
~/.claude-cabinet/omega-venv/bin/omega compact -t error_pattern 2>&1
|
|
39
47
|
```
|
|
40
|
-
Prevents log files from consuming disk. Silent, no user interaction.
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
Report results only if clusters were found and compacted.
|
|
50
|
+
|
|
51
|
+
### Discover Connections (weekly)
|
|
52
|
+
|
|
53
|
+
Scan for unlinked memories that should be related and create graph edges.
|
|
54
|
+
Auto-relate runs after each store but only checks the 3 nearest memories.
|
|
55
|
+
discover_connections does a broader sweep, turning isolated memories into
|
|
56
|
+
a connected knowledge graph. Runs alongside compact (same weekly cadence).
|
|
57
|
+
|
|
43
58
|
```bash
|
|
44
|
-
|
|
59
|
+
~/.claude-cabinet/omega-venv/bin/python3 -c "
|
|
60
|
+
from omega.bridge import discover_connections
|
|
61
|
+
result = discover_connections(lookback_hours=168) # 7 days
|
|
62
|
+
print(result if result else 'No new connections found')
|
|
63
|
+
"
|
|
45
64
|
```
|
|
46
|
-
|
|
47
|
-
|
|
65
|
+
|
|
66
|
+
Report: "Discovered N new connections between memories" if non-zero.
|
|
67
|
+
|
|
68
|
+
### Backup (weekly)
|
|
69
|
+
|
|
70
|
+
Back up the omega database. Runs alongside compact (same weekly cadence).
|
|
71
|
+
Omega keeps the last 5 backups automatically.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
~/.claude-cabinet/omega-venv/bin/omega backup 2>&1
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
<!--
|
|
78
|
+
## Project-Specific Maintenance
|
|
79
|
+
|
|
80
|
+
Add your own recurring tasks below. For each task, provide:
|
|
81
|
+
- **What** — the operation to perform
|
|
82
|
+
- **Why every session** — what decays if this is skipped
|
|
83
|
+
- **Command** — how to run it
|
|
84
|
+
- **Auto-execute?** — yes (run silently) or surface (ask user first)
|
|
85
|
+
|
|
86
|
+
### Example: Process Pending Queue Items
|
|
87
|
+
```bash
|
|
88
|
+
curl -s https://your-api.example.com/api/queue/pending
|
|
89
|
+
```
|
|
90
|
+
Items queued from a UI or external integration since last session.
|
|
91
|
+
Auto-execute routine items; surface unusual ones for confirmation.
|
|
48
92
|
-->
|
|
@@ -41,18 +41,9 @@ your investor-reports project too."
|
|
|
41
41
|
|
|
42
42
|
### Omega Semantic Memory
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
echo '{}' | ~/.claude-cabinet/omega-venv/bin/python3 \
|
|
50
|
-
scripts/cabinet-memory-adapter.py welcome
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The `welcome` command returns memories relevant to the current project.
|
|
54
|
-
The SessionStart hook (`memory-session-start.sh`) also does this
|
|
55
|
-
automatically, but during orient you can query for specific context:
|
|
44
|
+
Omega's native SessionStart hook (in `~/.claude/settings.json` global)
|
|
45
|
+
automatically surfaces recalled memories at session start. During orient,
|
|
46
|
+
you can query for additional specific context using the adapter:
|
|
56
47
|
|
|
57
48
|
```bash
|
|
58
49
|
echo '{"text": "recent decisions and lessons", "limit": 5}' | \
|
|
@@ -60,9 +51,11 @@ echo '{"text": "recent decisions and lessons", "limit": 5}' | \
|
|
|
60
51
|
scripts/cabinet-memory-adapter.py query
|
|
61
52
|
```
|
|
62
53
|
|
|
54
|
+
To verify omega is healthy, run `omega hooks doctor` or `omega status`.
|
|
55
|
+
|
|
63
56
|
If omega is not available, check whether the memory module is installed
|
|
64
57
|
(look for `"memory": true` in `.ccrc.json`). If it IS installed but the
|
|
65
|
-
venv
|
|
58
|
+
venv is missing, surface a warning:
|
|
66
59
|
|
|
67
60
|
> **⚠ Memory module is installed but omega is not available.**
|
|
68
61
|
> The venv at `~/.claude-cabinet/omega-venv/` may be missing or broken.
|