create-claude-cabinet 0.23.1 → 0.25.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/README.md +5 -5
- package/lib/cli.js +64 -2
- package/lib/verify-setup.js +140 -0
- package/package.json +1 -1
- package/templates/skills/debrief/SKILL.md +19 -22
- package/templates/skills/debrief/phases/record-lessons.md +152 -73
- package/templates/skills/debrief/phases/verify-coverage.md +101 -0
- package/templates/skills/execute/phases/verify-emit.md +104 -0
- package/templates/skills/orient/SKILL.md +30 -22
- package/templates/skills/plan/phases/verify-plan.md +97 -0
- package/templates/skills/verify/SKILL.md +228 -0
- package/templates/skills/verify/install.sh +342 -0
- package/templates/skills/verify/phases/calibrate.md +115 -0
- package/templates/skills/verify/phases/discover.md +114 -0
- package/templates/skills/verify/phases/draft.md +92 -0
- package/templates/skills/verify/phases/generate.md +71 -0
- package/templates/skills/verify/phases/scenario-template.md +119 -0
- package/templates/skills/verify/phases/update.md +81 -0
- package/templates/verify-runtime/CONVENTIONS.md +331 -0
- package/templates/verify-runtime/README.md +59 -0
- package/templates/verify-runtime/package-lock.json +2008 -0
- package/templates/verify-runtime/package.json +34 -0
- package/templates/verify-runtime/src/auto-check.ts +56 -0
- package/templates/verify-runtime/src/cli/preflight.ts +14 -0
- package/templates/verify-runtime/src/cli/report-last.ts +191 -0
- package/templates/verify-runtime/src/cli/report-status.ts +365 -0
- package/templates/verify-runtime/src/fixture-loader.ts +87 -0
- package/templates/verify-runtime/src/fresh-pass-cache.ts +193 -0
- package/templates/verify-runtime/src/human-verdict.ts +194 -0
- package/templates/verify-runtime/src/index.ts +66 -0
- package/templates/verify-runtime/src/manual-runner.ts +257 -0
- package/templates/verify-runtime/src/output.ts +177 -0
- package/templates/verify-runtime/src/path-hash.ts +241 -0
- package/templates/verify-runtime/src/preflight.ts +120 -0
- package/templates/verify-runtime/src/verdict-recorder.ts +318 -0
- package/templates/verify-runtime/src/world.ts +188 -0
- package/templates/verify-runtime/test/fixtures/sample.feature +17 -0
- package/templates/verify-runtime/test/fresh-pass-cache.test.ts +289 -0
- package/templates/verify-runtime/test/path-hash.test.ts +264 -0
- package/templates/verify-runtime/test/verdict-recorder.test.ts +58 -0
- package/templates/verify-runtime/tsconfig.json +16 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ gives Claude a memory, 31 domain experts, a planning process, and the
|
|
|
5
5
|
habit of starting sessions informed and ending them properly.
|
|
6
6
|
|
|
7
7
|
Built by a guy who'd rather talk to Claude than write code. Most of it
|
|
8
|
-
was built by Claude. I just complained until it worked.
|
|
8
|
+
was built by Claude. I just complained until it (mostly) worked.
|
|
9
9
|
|
|
10
10
|
## The Idea
|
|
11
11
|
|
|
@@ -63,8 +63,8 @@ automatically.
|
|
|
63
63
|
|
|
64
64
|
- **`/orient`** — open every session with this. Claude reads project
|
|
65
65
|
state, checks health, surfaces what needs attention, and briefs you
|
|
66
|
-
so you never start blind. Think of it as the
|
|
67
|
-
|
|
66
|
+
so you never start blind. Think of it as the briefing before the
|
|
67
|
+
cabinet gets to work.
|
|
68
68
|
- **`/debrief`** — close every session with this. Claude marks work
|
|
69
69
|
done, records lessons, updates state, and prepares the briefing for
|
|
70
70
|
next time. Without debrief, the next orient starts with stale
|
|
@@ -134,7 +134,7 @@ hooks — things that keep going wrong become things that can't go wrong.
|
|
|
134
134
|
|
|
135
135
|
## Your Workflow
|
|
136
136
|
|
|
137
|
-
The
|
|
137
|
+
The rhythm of each session:
|
|
138
138
|
|
|
139
139
|
1. **Start a session** → `/orient` (get briefed)
|
|
140
140
|
2. **Do your work** → talk to Claude, use `/plan` for anything non-trivial
|
|
@@ -227,7 +227,7 @@ other.
|
|
|
227
227
|
## Philosophy
|
|
228
228
|
|
|
229
229
|
This started as the process layer of [Flow](https://github.com/orenmagid/flow),
|
|
230
|
-
a cognitive workspace built on Claude Code over months of
|
|
230
|
+
a cognitive workspace built on Claude Code over months of intensive use. The
|
|
231
231
|
patterns that emerged — the session loop, cabinet-style audits, feedback
|
|
232
232
|
enforcement — turned out to be transferable to any project.
|
|
233
233
|
|
package/lib/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ const { mergeSettings } = require('./settings-merge');
|
|
|
8
8
|
const { create: createMetadata, read: readMetadata } = require('./metadata');
|
|
9
9
|
const { setupDb } = require('./db-setup');
|
|
10
10
|
const { setupOmega } = require('./omega-setup');
|
|
11
|
+
const { setupVerifyRuntime } = require('./verify-setup');
|
|
11
12
|
const { reset } = require('./reset');
|
|
12
13
|
|
|
13
14
|
const VERSION = require('../package.json').version;
|
|
@@ -356,6 +357,7 @@ const MODULES = {
|
|
|
356
357
|
// Instruction phases — always ship, overriding the default skip-phases rule in copy.js
|
|
357
358
|
'skills/debrief/phases/audit-pattern-capture.md',
|
|
358
359
|
'skills/debrief/phases/methodology-capture.md',
|
|
360
|
+
'skills/debrief/phases/record-lessons.md',
|
|
359
361
|
'skills/debrief/phases/upstream-feedback.md',
|
|
360
362
|
'skills/menu',
|
|
361
363
|
],
|
|
@@ -450,6 +452,20 @@ const MODULES = {
|
|
|
450
452
|
needsOmega: true,
|
|
451
453
|
templates: ['skills/memory', 'scripts/cabinet-memory-adapter.py', 'scripts/migrate-memory-to-omega.py', 'rules/memory-capture.md', 'hooks/omega-memory-guard.sh'],
|
|
452
454
|
},
|
|
455
|
+
'verify': {
|
|
456
|
+
name: 'Verification Harness (Cucumber + Playwright)',
|
|
457
|
+
description: 'Walkthrough verification with human-in-the-loop verdict pauses. Replaces flat AC lists with re-runnable user-journey scenarios. Includes /verify skeleton skill + cabinet-verify npm runtime + opt-in integration phases for /plan, /execute, /debrief.',
|
|
458
|
+
mandatory: false,
|
|
459
|
+
default: false,
|
|
460
|
+
lean: false,
|
|
461
|
+
templates: [
|
|
462
|
+
'skills/verify',
|
|
463
|
+
'skills/plan/phases/verify-plan.md',
|
|
464
|
+
'skills/execute/phases/verify-emit.md',
|
|
465
|
+
'skills/debrief/phases/verify-coverage.md',
|
|
466
|
+
],
|
|
467
|
+
postInstall: 'verify-setup',
|
|
468
|
+
},
|
|
453
469
|
};
|
|
454
470
|
|
|
455
471
|
/** Recursively collect all relative file paths under a directory. */
|
|
@@ -503,7 +519,8 @@ function parseArgs(argv) {
|
|
|
503
519
|
targetDir: '.',
|
|
504
520
|
};
|
|
505
521
|
|
|
506
|
-
for (
|
|
522
|
+
for (let i = 0; i < args.length; i++) {
|
|
523
|
+
const arg = args[i];
|
|
507
524
|
if (arg === '--yes' || arg === '-y') flags.yes = true;
|
|
508
525
|
else if (arg === '--lean') flags.lean = true;
|
|
509
526
|
else if (arg === '--no-db') flags.noDb = true;
|
|
@@ -511,6 +528,9 @@ function parseArgs(argv) {
|
|
|
511
528
|
else if (arg === '--help' || arg === '-h') flags.help = true;
|
|
512
529
|
else if (arg === '--reset') flags.reset = true;
|
|
513
530
|
else if (arg === '--force') flags.force = true;
|
|
531
|
+
else if (arg === '--modules' && i + 1 < args.length) {
|
|
532
|
+
flags.modules = args[++i].split(',').map(s => s.trim()).filter(Boolean);
|
|
533
|
+
}
|
|
514
534
|
else if (!arg.startsWith('-')) flags.targetDir = arg;
|
|
515
535
|
}
|
|
516
536
|
|
|
@@ -525,6 +545,8 @@ function printHelp() {
|
|
|
525
545
|
--yes, -y Accept all defaults, no prompts
|
|
526
546
|
--lean Install core modules only (no work-tracking, compliance, validate)
|
|
527
547
|
--no-db Skip work tracking database setup
|
|
548
|
+
--modules <keys> Comma-separated module keys to install (e.g., 'verify,memory').
|
|
549
|
+
Mandatory modules are always included.
|
|
528
550
|
--dry-run Show what would be copied without writing
|
|
529
551
|
--reset Remove Claude Cabinet files (uses manifest for safety)
|
|
530
552
|
--force With --reset: remove even customized files
|
|
@@ -664,7 +686,27 @@ async function run() {
|
|
|
664
686
|
let skippedModules = {};
|
|
665
687
|
let includeDb = !flags.noDb;
|
|
666
688
|
|
|
667
|
-
if (flags.
|
|
689
|
+
if (flags.modules) {
|
|
690
|
+
// Explicit module selection via --modules <key1,key2,...>. Mandatory
|
|
691
|
+
// modules are always included regardless of the flag value, so the
|
|
692
|
+
// installer always has session-loop etc. available.
|
|
693
|
+
const mandatoryKeys = Object.entries(MODULES)
|
|
694
|
+
.filter(([, mod]) => mod.mandatory)
|
|
695
|
+
.map(([key]) => key);
|
|
696
|
+
const requested = flags.modules.filter(k => MODULES[k]);
|
|
697
|
+
const unknown = flags.modules.filter(k => !MODULES[k]);
|
|
698
|
+
if (unknown.length > 0) {
|
|
699
|
+
console.log(` ⚠ Unknown modules ignored: ${unknown.join(', ')}`);
|
|
700
|
+
console.log(` Known modules: ${Object.keys(MODULES).join(', ')}`);
|
|
701
|
+
}
|
|
702
|
+
selectedModules = [...new Set([...mandatoryKeys, ...requested])];
|
|
703
|
+
const skippedKeys = Object.keys(MODULES).filter(k => !selectedModules.includes(k));
|
|
704
|
+
for (const k of skippedKeys) {
|
|
705
|
+
skippedModules[k] = `Skipped by --modules flag`;
|
|
706
|
+
}
|
|
707
|
+
if (!selectedModules.includes('work-tracking')) includeDb = false;
|
|
708
|
+
console.log(` Installing modules: ${selectedModules.join(', ')}\n`);
|
|
709
|
+
} else if (flags.lean) {
|
|
668
710
|
selectedModules = Object.entries(MODULES)
|
|
669
711
|
.filter(([, mod]) => mod.mandatory || mod.lean)
|
|
670
712
|
.map(([key]) => key);
|
|
@@ -954,6 +996,26 @@ async function run() {
|
|
|
954
996
|
}
|
|
955
997
|
}
|
|
956
998
|
|
|
999
|
+
// --- Run module postInstall hooks ---
|
|
1000
|
+
// Modules with a `postInstall` field dispatch to a matching setup
|
|
1001
|
+
// function after templates are copied. Currently only 'verify-setup'
|
|
1002
|
+
// (the cabinet-verify tarball builder) is wired.
|
|
1003
|
+
for (const moduleKey of selectedModules) {
|
|
1004
|
+
const mod = MODULES[moduleKey];
|
|
1005
|
+
if (!mod.postInstall) continue;
|
|
1006
|
+
if (mod.postInstall === 'verify-setup') {
|
|
1007
|
+
try {
|
|
1008
|
+
console.log('');
|
|
1009
|
+
const verifyResult = setupVerifyRuntime({ dryRun: !!flags.dryRun });
|
|
1010
|
+
for (const r of verifyResult.results || []) console.log(` 📋 ${r}`);
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
console.log(` ⚠ cabinet-verify runtime setup failed: ${err.message}`);
|
|
1013
|
+
console.log(' /verify install.sh will fail until the runtime is installed.');
|
|
1014
|
+
console.log(' Re-run the installer to retry.');
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
|
|
957
1019
|
// --- Manifest key migration (act:d1f16bee) ---
|
|
958
1020
|
// When CC renames directories (e.g., perspectives/ → cabinet-*/), old manifest
|
|
959
1021
|
// keys no longer match new template paths. Migrate keys BEFORE cleanup so the
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verify-setup.js — install the cabinet-verify runtime tarball at
|
|
3
|
+
* ~/.claude-cabinet/verify/<version>/dist/.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the omega-setup.js pattern: dispatched from cli.js's install
|
|
6
|
+
* pipeline when the `verify` module is selected. Idempotent: skips if
|
|
7
|
+
* the matching-version tarball is already present.
|
|
8
|
+
*
|
|
9
|
+
* See templates/verify-runtime/CONVENTIONS.md §Install Dir and
|
|
10
|
+
* §Tarball Install Pattern for the frozen contract this implements.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const os = require('os');
|
|
17
|
+
|
|
18
|
+
const CC_HOME = path.join(os.homedir(), '.claude-cabinet');
|
|
19
|
+
const VERIFY_BASE = path.join(CC_HOME, 'verify');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Set up the cabinet-verify runtime.
|
|
23
|
+
*
|
|
24
|
+
* Steps:
|
|
25
|
+
* 1. Read the version from templates/verify-runtime/package.json
|
|
26
|
+
* 2. Compute installDir = ~/.claude-cabinet/verify/<version>/dist/
|
|
27
|
+
* 3. If a tarball already exists at that path with the same version,
|
|
28
|
+
* log "already installed" and skip
|
|
29
|
+
* 4. Otherwise: mkdir -p installDir; npm pack inside templates/verify-runtime/;
|
|
30
|
+
* move the .tgz to installDir
|
|
31
|
+
* 5. Write ~/.claude-cabinet/verify/current/VERSION (single-line pointer
|
|
32
|
+
* used by /verify install.sh per CONVENTIONS.md Version Resolution)
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} opts
|
|
35
|
+
* @param {boolean} [opts.dryRun] — print planned actions, don't execute
|
|
36
|
+
* @param {string} [opts.runtimeSourceDir] — override the templates/verify-runtime/
|
|
37
|
+
* location. Defaults to <repo>/templates/verify-runtime/ resolved from __dirname.
|
|
38
|
+
* @returns {Object} { installPath, version, status: 'installed'|'skipped'|'dry-run' }
|
|
39
|
+
*/
|
|
40
|
+
function setupVerifyRuntime(opts = {}) {
|
|
41
|
+
const dryRun = !!opts.dryRun;
|
|
42
|
+
const runtimeSourceDir =
|
|
43
|
+
opts.runtimeSourceDir || path.resolve(__dirname, '..', 'templates', 'verify-runtime');
|
|
44
|
+
|
|
45
|
+
// 1. Read version
|
|
46
|
+
const packageJsonPath = path.join(runtimeSourceDir, 'package.json');
|
|
47
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`verify-setup: ${packageJsonPath} not found. Cannot resolve cabinet-verify version.`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
53
|
+
const version = pkg.version;
|
|
54
|
+
if (typeof version !== 'string' || version.length === 0) {
|
|
55
|
+
throw new Error(`verify-setup: ${packageJsonPath} has no version field`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 2. Compute installDir
|
|
59
|
+
const installDir = path.join(VERIFY_BASE, version, 'dist');
|
|
60
|
+
const tarballName = `cabinet-verify-${version}.tgz`;
|
|
61
|
+
const tarballPath = path.join(installDir, tarballName);
|
|
62
|
+
const versionPointer = path.join(VERIFY_BASE, 'current', 'VERSION');
|
|
63
|
+
|
|
64
|
+
const results = [];
|
|
65
|
+
|
|
66
|
+
if (dryRun) {
|
|
67
|
+
results.push(`Would install cabinet-verify@${version}`);
|
|
68
|
+
results.push(` source: ${runtimeSourceDir}`);
|
|
69
|
+
results.push(` target: ${tarballPath}`);
|
|
70
|
+
results.push(` pointer: ${versionPointer}`);
|
|
71
|
+
return { installPath: installDir, version, status: 'dry-run', results };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 3. Idempotency check. Existence alone is not enough — an earlier
|
|
75
|
+
// stub-touch (e.g., a test fixture) can leave a 0-byte file at the
|
|
76
|
+
// tarball path. npm install on the consumer side then fails with
|
|
77
|
+
// ENODATA / TAR_BAD_ARCHIVE. Validate the file has non-trivial size
|
|
78
|
+
// before treating it as installed.
|
|
79
|
+
if (fs.existsSync(tarballPath) && fs.statSync(tarballPath).size > 1024) {
|
|
80
|
+
results.push(`cabinet-verify@${version} already installed (${tarballPath})`);
|
|
81
|
+
// Even on skip, ensure the VERSION pointer is up-to-date so a later
|
|
82
|
+
// version downgrade doesn't leave a stale pointer behind.
|
|
83
|
+
writeVersionPointer(versionPointer, version);
|
|
84
|
+
results.push(`Updated VERSION pointer: ${versionPointer}`);
|
|
85
|
+
return { installPath: installDir, version, status: 'skipped', results };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Remove a 0-byte stub before re-packing so the move below doesn't
|
|
89
|
+
// hit a "file exists" surprise.
|
|
90
|
+
if (fs.existsSync(tarballPath)) {
|
|
91
|
+
fs.unlinkSync(tarballPath);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 4. mkdir + npm pack + move
|
|
95
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
96
|
+
// Run npm pack in the runtime source dir. --pack-destination writes
|
|
97
|
+
// the tarball directly to installDir without an intermediate cwd move.
|
|
98
|
+
const packStdout = execSync(`npm pack --silent --pack-destination "${installDir}"`, {
|
|
99
|
+
cwd: runtimeSourceDir,
|
|
100
|
+
encoding: 'utf8',
|
|
101
|
+
}).trim();
|
|
102
|
+
|
|
103
|
+
// npm pack prints the tarball filename to stdout on the last non-empty line.
|
|
104
|
+
// Normalise to the expected name so consuming projects can rely on the
|
|
105
|
+
// CONVENTIONS.md-documented path.
|
|
106
|
+
const lastLine = packStdout.split('\n').filter(Boolean).pop() || '';
|
|
107
|
+
const producedName = path.basename(lastLine);
|
|
108
|
+
if (producedName && producedName !== tarballName) {
|
|
109
|
+
// npm pack may produce a name like 'cabinet-verify-0.1.0.tgz' that already
|
|
110
|
+
// matches; if it doesn't (e.g., npm prefixes with @scope/), rename to match.
|
|
111
|
+
const producedPath = path.join(installDir, producedName);
|
|
112
|
+
if (fs.existsSync(producedPath)) {
|
|
113
|
+
fs.renameSync(producedPath, tarballPath);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!fs.existsSync(tarballPath)) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
`verify-setup: npm pack completed but ${tarballPath} not found. ` +
|
|
120
|
+
`stdout was: ${packStdout.slice(0, 500)}`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
results.push(`Installed cabinet-verify@${version} to ${tarballPath}`);
|
|
125
|
+
|
|
126
|
+
// 5. Write VERSION pointer
|
|
127
|
+
writeVersionPointer(versionPointer, version);
|
|
128
|
+
results.push(`Wrote VERSION pointer: ${versionPointer}`);
|
|
129
|
+
|
|
130
|
+
return { installPath: installDir, version, status: 'installed', results };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function writeVersionPointer(pointerPath, version) {
|
|
134
|
+
fs.mkdirSync(path.dirname(pointerPath), { recursive: true });
|
|
135
|
+
// No trailing newline — CONVENTIONS.md frozen contract requires the
|
|
136
|
+
// file to equal the version string exactly under `cat`.
|
|
137
|
+
fs.writeFileSync(pointerPath, version, 'utf8');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = { setupVerifyRuntime };
|
package/package.json
CHANGED
|
@@ -306,27 +306,24 @@ Don't silently bundle unrelated changes.
|
|
|
306
306
|
|
|
307
307
|
### 9. Record Lessons (core)
|
|
308
308
|
|
|
309
|
-
Read `phases/record-lessons.md` for how to
|
|
310
|
-
This is the second irreducible purpose of debrief —
|
|
311
|
-
closing work, this is ensuring the next session is smarter
|
|
312
|
-
one.
|
|
313
|
-
|
|
314
|
-
**
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
Types: `decision`, `lesson`, `preference`, `constraint`, `pattern`.
|
|
329
|
-
Flat markdown memory is the fallback only when omega is unavailable.
|
|
309
|
+
Read `phases/record-lessons.md` for how to route session outputs to
|
|
310
|
+
their real homes. This is the second irreducible purpose of debrief —
|
|
311
|
+
the first is closing work, this is ensuring the next session is smarter
|
|
312
|
+
than this one.
|
|
313
|
+
|
|
314
|
+
**The phase file teaches a routing discipline:** every output has
|
|
315
|
+
exactly one home with a forcing function — omega `decision`/`lesson`/
|
|
316
|
+
`constraint`/`preference` memory, inline in CLAUDE.md or a briefing
|
|
317
|
+
(for load-bearing project facts), a pib-db deferred action (for
|
|
318
|
+
conditional revisits), or the upstream-feedback phase (for CC-applicable
|
|
319
|
+
friction). Loose `.md` files written next to the code they describe
|
|
320
|
+
are explicitly an **anti-pattern** — they rot silently when the code
|
|
321
|
+
changes. Hybrid observations (part project, part CC) must be split.
|
|
322
|
+
|
|
323
|
+
**Default (absent/empty):** Follow the routing tree in the phase file.
|
|
324
|
+
Ask the user only when routing is genuinely ambiguous — not as a
|
|
325
|
+
catch-all "what did we learn?" prompt, which tends to produce vague
|
|
326
|
+
lessons that don't get recorded anywhere useful.
|
|
330
327
|
|
|
331
328
|
**Omega broken:** If the memory module is installed (check `.ccrc.json`
|
|
332
329
|
for `"memory": true`) but the venv or adapter is missing, surface this
|
|
@@ -485,7 +482,7 @@ Read `phases/report.md` for how to present the debrief summary.
|
|
|
485
482
|
| `auto-maintenance.md` | Skip | Recurring session-end tasks |
|
|
486
483
|
| `update-state.md` | Default: check system-status.md | What state files to update |
|
|
487
484
|
| `health-checks.md` | Skip | Session-end health checks |
|
|
488
|
-
| `record-lessons.md` | Default:
|
|
485
|
+
| `record-lessons.md` | Default: route outputs per the decision tree | How to route session outputs to omega / CLAUDE.md / pib-db triggers / upstream |
|
|
489
486
|
| `audit-pattern-capture.md` | **Instruction: always runs** | Detect recurring audit findings, write to patterns-project.md |
|
|
490
487
|
| `methodology-capture.md` | **Instruction: always runs** | Detect methodology-level work; capture reasoning chain + narrative to `.claude/methodology/` |
|
|
491
488
|
| `upstream-feedback.md` | **Instruction: always runs** | Surface CC friction to source repo |
|
|
@@ -1,94 +1,173 @@
|
|
|
1
|
-
# Record Lessons —
|
|
1
|
+
# Record Lessons — Route Session Outputs to Their Real Homes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
smarter
|
|
5
|
-
|
|
3
|
+
This is debrief's second irreducible purpose: make sure the next session
|
|
4
|
+
is smarter than this one. Without it, the system does work but doesn't
|
|
5
|
+
learn from it.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
skip lesson recording, write only `skip: true`.
|
|
7
|
+
Lessons are perishable. A lesson captured while context is fresh is
|
|
8
|
+
worth ten captured from memory next week.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
ten captured from memory next week. This is why recording happens during
|
|
13
|
-
debrief, not "sometime later."
|
|
10
|
+
## The Routing Principle
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
Every session output has **exactly one primary home**. The home must
|
|
13
|
+
have a forcing function — something that keeps the content accurate
|
|
14
|
+
when the code it describes changes. Loose `.md` files next to code
|
|
15
|
+
are the wrong home: they rot silently because nothing invalidates
|
|
16
|
+
them when the system evolves.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
**Each output has one home. Don't double-store.** A decision stored
|
|
19
|
+
in omega doesn't also need a `.md` file. A constraint documented in
|
|
20
|
+
CLAUDE.md doesn't also need an omega entry "for backup." Duplication
|
|
21
|
+
just creates two things to keep in sync.
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
## Routing Decision Tree
|
|
24
|
+
|
|
25
|
+
For each thing you'd want future sessions to know, pick the single
|
|
26
|
+
best home:
|
|
27
|
+
|
|
28
|
+
### Decisions — "we chose X over Y because Z"
|
|
29
|
+
|
|
30
|
+
Architectural choices, tradeoff resolutions, accepted gaps, rejected
|
|
31
|
+
alternatives.
|
|
32
|
+
|
|
33
|
+
**Primary home:** omega `decision` memory. Omega has contradiction
|
|
34
|
+
detection — when a later decision supersedes this one, the old entry
|
|
35
|
+
can be marked `status=superseded` instead of silently rotting.
|
|
24
36
|
|
|
25
37
|
```bash
|
|
26
|
-
echo '{"text": "the
|
|
38
|
+
echo '{"text": "the decision + why", "type": "decision"}' | \
|
|
27
39
|
~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
|
|
28
40
|
```
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- `pattern` — conventions established, recurring solutions
|
|
36
|
-
|
|
37
|
-
**When omega is NOT available:** Only then use flat markdown memory
|
|
38
|
-
(auto-memory in `~/.claude/projects/` memory directory). Check omega
|
|
39
|
-
availability first — don't assume it's unavailable without checking.
|
|
40
|
-
|
|
41
|
-
## What to Look For
|
|
42
|
-
|
|
43
|
-
Review the session and ask:
|
|
44
|
-
- Did we learn something future sessions need to know?
|
|
45
|
-
- A new pattern established
|
|
46
|
-
- A gotcha discovered
|
|
47
|
-
- A process gap identified
|
|
48
|
-
- A user preference revealed
|
|
49
|
-
- Is this the second or third time something came up? If the same kind
|
|
50
|
-
of problem keeps recurring, the lesson is "create a prevention mechanism"
|
|
51
|
-
not just "remember this."
|
|
52
|
-
- Did the session's work contradict any existing recorded knowledge?
|
|
53
|
-
If so, update or remove the stale record (in omega: use `query` to
|
|
54
|
-
find it, then note the contradiction in the new memory).
|
|
55
|
-
|
|
56
|
-
## What NOT to Record
|
|
57
|
-
- Code patterns derivable by reading current files
|
|
58
|
-
- Git history (use git log)
|
|
59
|
-
- Debugging solutions (the fix is in the code)
|
|
60
|
-
- Anything already in CLAUDE.md files
|
|
61
|
-
- Ephemeral task details only relevant to this session
|
|
42
|
+
**Also add to CLAUDE.md** only if the decision is load-bearing enough
|
|
43
|
+
that *every* session needs to know it at startup (not just sessions
|
|
44
|
+
that touch the relevant code). Examples: "auth is per-user via FastAPI
|
|
45
|
+
Users (no shared passwords)" is load-bearing. "We rejected a specific
|
|
46
|
+
library option after evaluation" is not — omega is enough.
|
|
62
47
|
|
|
63
|
-
|
|
48
|
+
### Project constraints / conventions / gotchas
|
|
64
49
|
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
Environmental quirks, dev-workflow requirements, "this project has a
|
|
51
|
+
weird setup" facts.
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
53
|
+
**Primary home:** inline in `CLAUDE.md` or the project briefing. These
|
|
54
|
+
files get edited when the code changes — the forcing function is that
|
|
55
|
+
they're load-bearing for every session, so staleness surfaces fast.
|
|
56
|
+
|
|
57
|
+
Use omega `constraint` type only for cross-project patterns (e.g.,
|
|
58
|
+
"in any project with nested package.json..."). Project-specific
|
|
59
|
+
constraints belong inline.
|
|
60
|
+
|
|
61
|
+
### Conditional revisits — "do X later when Y happens"
|
|
62
|
+
|
|
63
|
+
"If we ever get multiple concurrent users, add a token blocklist."
|
|
64
|
+
"When curl becomes annoying, build a /settings UI."
|
|
65
|
+
|
|
66
|
+
**Primary home:** pib-db deferred action with `trigger_condition`.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
pib_create_action text="..." status="deferred" trigger_condition="..."
|
|
74
70
|
```
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
Orient's deferred-check phase re-evaluates these every session. If the
|
|
73
|
+
condition has fired, the user gets asked; if it's obsolete, it gets
|
|
74
|
+
marked so. No silent rot.
|
|
75
|
+
|
|
76
|
+
### CC upstream friction embedded in a project observation
|
|
77
|
+
|
|
78
|
+
Sometimes a project-scoped observation contains a CC-applicable piece:
|
|
79
|
+
"in this project auth tests are hard, AND cabinet-qa should flag this
|
|
80
|
+
pattern in any auth work." That's two things, not one.
|
|
81
|
+
|
|
82
|
+
**Split it.** Route the project piece to its home (omega / CLAUDE.md /
|
|
83
|
+
trigger). Route the CC piece to the upstream-feedback phase (step 11)
|
|
84
|
+
where it will be drafted and delivered. Don't bury the upstream piece
|
|
85
|
+
inside a project decision doc — it will never find its way home.
|
|
86
|
+
|
|
87
|
+
### Lessons, gotchas, discoveries (not decisions, not constraints)
|
|
88
|
+
|
|
89
|
+
"We learned that X behaves differently from docs." "This pattern
|
|
90
|
+
works." "The CI was green but prod failed because…"
|
|
91
|
+
|
|
92
|
+
**Primary home:** omega `lesson` memory. Same forcing function as
|
|
93
|
+
decisions — superseded lessons can be marked and surfaced.
|
|
94
|
+
|
|
95
|
+
### User preferences
|
|
96
|
+
|
|
97
|
+
Style choices, workflow preferences, corrections the user made.
|
|
98
|
+
|
|
99
|
+
**Primary home:** omega `preference` memory.
|
|
78
100
|
|
|
79
|
-
|
|
80
|
-
|
|
101
|
+
## The Anti-Pattern: Loose Project-Scoped .md Files
|
|
102
|
+
|
|
103
|
+
**Do not write `feedback-project-*.md`, `decision-*.md`, or similar
|
|
104
|
+
loose .md files as the primary record of a session output.** This
|
|
105
|
+
pattern has been observed to rot — in one audited case, 4 of 5 such
|
|
106
|
+
files went stale within 7 days because the underlying code changed
|
|
107
|
+
and the files had no forcing function to catch it.
|
|
108
|
+
|
|
109
|
+
If you are tempted to write a loose .md file:
|
|
110
|
+
- Is it a decision? → omega `decision`
|
|
111
|
+
- Is it a constraint everyone needs? → CLAUDE.md / briefing
|
|
112
|
+
- Is it a conditional revisit? → pib-db deferred trigger
|
|
113
|
+
- Is it CC upstream friction? → upstream-feedback phase
|
|
114
|
+
- None of the above? → it probably doesn't need recording at all
|
|
115
|
+
|
|
116
|
+
## Before Writing — Contradiction Check
|
|
117
|
+
|
|
118
|
+
For each memory you're about to write, query omega for existing
|
|
119
|
+
entries on the same topic:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
~/.claude-cabinet/omega-venv/bin/omega query "topic keywords" --limit 5
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
If an existing entry contradicts or is superseded by the new one,
|
|
126
|
+
mark the old one:
|
|
81
127
|
|
|
82
128
|
```bash
|
|
83
|
-
~/.claude-cabinet/omega-venv/bin/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
129
|
+
~/.claude-cabinet/omega-venv/bin/omega update <old-id> --status superseded
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This is the forcing function that turns omega into a living record
|
|
133
|
+
instead of another pile of rotting notes.
|
|
134
|
+
|
|
135
|
+
## When Omega Is Not Available
|
|
136
|
+
|
|
137
|
+
If `~/.claude-cabinet/omega-venv/bin/python3` is missing AND the
|
|
138
|
+
memory module is not installed (check `.ccrc.json`), fall back to
|
|
139
|
+
flat markdown memory in `~/.claude/projects/...`. But recognize
|
|
140
|
+
this fallback has the same rot problem — prefer CLAUDE.md for
|
|
141
|
+
anything load-bearing and pib-db triggers for anything conditional.
|
|
142
|
+
|
|
143
|
+
If the memory module IS installed but omega is broken, surface this
|
|
144
|
+
in the debrief report:
|
|
145
|
+
|
|
146
|
+
> **⚠ Memory module is installed but omega is not working.**
|
|
147
|
+
> Decisions/lessons from this session were saved to flat markdown
|
|
148
|
+
> instead. Run `npx create-claude-cabinet` to rebuild the omega venv.
|
|
149
|
+
|
|
150
|
+
## What NOT to Record — Anywhere
|
|
151
|
+
|
|
152
|
+
- Code patterns derivable by reading current files
|
|
153
|
+
- Git history (use `git log`)
|
|
154
|
+
- Debugging solutions (the fix is already in the code; the commit
|
|
155
|
+
message has the context)
|
|
156
|
+
- Anything already in CLAUDE.md files
|
|
157
|
+
- Ephemeral task details only relevant to this session
|
|
158
|
+
- "We made progress on X" session summaries — that's what git is for
|
|
159
|
+
|
|
160
|
+
## Report What Was Routed
|
|
161
|
+
|
|
162
|
+
Tell the user what went where so they can audit the routing:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
Routed this session:
|
|
166
|
+
- 1 decision → omega mem-xxxxx (JWT revocation tradeoff)
|
|
167
|
+
- 1 constraint → article-rewriter/CLAUDE.md (tsc must run from frontend)
|
|
168
|
+
- 1 deferred trigger → pib-db act:xxxxxxxx (add blocklist if multi-user)
|
|
169
|
+
- 1 upstream piece → CC feedback outbox (cabinet-qa testability)
|
|
89
170
|
```
|
|
90
171
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
the system will remember next time. Include the count, types, and any
|
|
94
|
-
new connections discovered in the knowledge graph.
|
|
172
|
+
This is also how you catch routing errors: if everything ended up in
|
|
173
|
+
omega, the routing discipline didn't actually run.
|