kodelyth-ecc 1.5.0 → 1.5.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,60 @@
2
2
 
3
3
  All notable changes to Kodelyth ECC are documented here.
4
4
 
5
+ ## v1.5.1 — Compound Learning System (May 2026)
6
+
7
+ ### The Self-Improvement Loop
8
+
9
+ Every correction you make to Claude gets encoded permanently into your project. Next session, Claude doesn't repeat the mistake. The month after, it matches how you think. After a year, it works like a team member who has been here for years.
10
+
11
+ ### New: Three-Layer Compound Memory Architecture
12
+
13
+ | Layer | File | Scope | How it works |
14
+ |---|---|---|---|
15
+ | Project Lessons | `tasks/lessons.md` | Per-project | Hard rules from your corrections. Injected at session start. |
16
+ | Global Memory | `~/.kodelyth/memory/` | Cross-project | BM25 fuzzy recall of past solutions. Auto-fires on every prompt. |
17
+ | Intent Routing | 61 agents | Always-on | Routes your message to the right specialist from the first word. |
18
+
19
+ ### Added
20
+
21
+ #### `hooks/memory/capture-correction.js` (Stop hook)
22
+ - Scans session JSONL for user correction patterns (12 signal types: "no don't", "use X instead", "stop doing Y", "we always", "wrong approach", etc.)
23
+ - Extracts corrections as hard rules and appends to `tasks/lessons.md` in the project root
24
+ - Runs async at session end — zero latency impact
25
+ - Self-deduplicates: same rule never written twice
26
+
27
+ #### `hooks/memory/read-lessons.js` (SessionStart hook)
28
+ - Reads `tasks/lessons.md` at session start and injects rules as high-priority context
29
+ - Detects project tech stack (Node.js + framework, Go, Rust, Python, Java) and injects a project DNA brief
30
+ - Reads open items from `tasks/todo.md` and surfaces them at session start
31
+ - Fires before all other hooks — lessons are always loaded first
32
+
33
+ #### `rules/common/self-improvement-workflow.md`
34
+ - Encodes Boris Cherny's internal Claude Code team workflow (6 patterns)
35
+ - Extended with ECC's three-layer compound memory architecture
36
+ - Plan Node Default, Subagent Strategy, Self-Improvement Loop, Verification Before Done, Demand Elegance, Autonomous Bug Fixing
37
+ - Task Management Protocol: `tasks/todo.md` + `tasks/lessons.md` as first-class project artifacts
38
+
39
+ ### How Addiction Works
40
+
41
+ ```
42
+ Session 1: You say "use pnpm not npm"
43
+ → capture-correction.js writes: "- use pnpm not npm" to tasks/lessons.md
44
+
45
+ Session 2: read-lessons.js fires at start
46
+ → "PROJECT LESSONS — HARD RULES" injected into context
47
+ → Claude uses pnpm without being told
48
+
49
+ Month 1: 10+ lessons stacked
50
+ → Claude matches your style, your conventions, your preferences
51
+
52
+ Month 3: You open another AI tool
53
+ → It feels like a new hire who knows nothing about your project
54
+ → You come back
55
+ ```
56
+
57
+ ---
58
+
5
59
  ## v1.5.0 — Incident Response + Load Testing + Complete Visual Refresh (May 2026)
6
60
 
7
61
  ### Added — 2 New Specialist Agents
package/SECURITY.md CHANGED
@@ -4,8 +4,12 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |---------|-----------|
7
- | 1.1.x | Yes — active |
8
- | 1.0.x | Noupgrade to 1.1.x |
7
+ | 1.5.x | Yes — current stable |
8
+ | 1.4.x | Yessecurity fixes only |
9
+ | 1.3.x | Yes — security fixes only |
10
+ | 1.2.x | No — upgrade to 1.5.x |
11
+ | 1.1.x | No — upgrade to 1.5.x |
12
+ | 1.0.x | No — upgrade to 1.5.x |
9
13
  | < 1.0 | No |
10
14
 
11
15
  ---
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 1.5.1
package/hooks/hooks.json CHANGED
@@ -168,6 +168,19 @@
168
168
  }
169
169
  ],
170
170
  "SessionStart": [
171
+ {
172
+ "matcher": "*",
173
+ "hooks": [
174
+ {
175
+ "type": "command",
176
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/read-lessons.js\"",
177
+ "async": false,
178
+ "timeout": 4
179
+ }
180
+ ],
181
+ "description": "Kodelyth ECC: inject project lessons (tasks/lessons.md) and project DNA as hard rules at session start",
182
+ "id": "kodelyth:session:start:read-lessons"
183
+ },
171
184
  {
172
185
  "matcher": "*",
173
186
  "hooks": [
@@ -340,6 +353,19 @@
340
353
  }
341
354
  ],
342
355
  "Stop": [
356
+ {
357
+ "matcher": "*",
358
+ "hooks": [
359
+ {
360
+ "type": "command",
361
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/memory/capture-correction.js\"",
362
+ "async": true,
363
+ "timeout": 8
364
+ }
365
+ ],
366
+ "description": "Kodelyth ECC: detect user corrections in session and encode them as hard rules to tasks/lessons.md (Self-Improvement Loop)",
367
+ "id": "kodelyth:stop:capture-correction"
368
+ },
343
369
  {
344
370
  "matcher": "*",
345
371
  "hooks": [
@@ -375,7 +401,7 @@
375
401
  "timeout": 300
376
402
  }
377
403
  ],
378
- "description": "Batch format (Biome/Prettier) and typecheck (tsc) all JS/TS files edited this response runs once at Stop instead of after every Edit",
404
+ "description": "Batch format (Biome/Prettier) and typecheck (tsc) all JS/TS files edited this response \u2014 runs once at Stop instead of after every Edit",
379
405
  "id": "stop:format-typecheck"
380
406
  },
381
407
  {
@@ -458,4 +484,4 @@
458
484
  }
459
485
  ]
460
486
  }
461
- }
487
+ }
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env node
2
+ // =============================================================================
3
+ // Kodelyth ECC — Correction Capture Hook (Stop)
4
+ //
5
+ // Runs at the end of every Claude Code session. Scans the session JSONL for
6
+ // user messages that contain corrections (e.g. "no don't", "use X instead",
7
+ // "stop doing Y", "wrong approach"). Extracts them as hard rules and appends
8
+ // them to tasks/lessons.md in the project root.
9
+ //
10
+ // This is the engine behind the Self-Improvement Loop:
11
+ // User corrects Claude → rule encoded → next session it doesn't repeat it
12
+ //
13
+ // Output contract: always pass stdin through to stdout. Never block a session.
14
+ // =============================================================================
15
+
16
+ 'use strict';
17
+
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+
21
+ // ── Correction signal patterns ─────────────────────────────────────────────
22
+ const CORRECTION_SIGNALS = [
23
+ /\bno[,.]?\s+(don'?t|do not|never|stop|that'?s)/i,
24
+ /\bthat'?s?\s+(wrong|incorrect|not right|not what I|not how I)/i,
25
+ /\b(don'?t|do not|never)\s+(do that|use that|write that|add that|put that)/i,
26
+ /\b(stop|avoid)\s+(doing|using|writing|adding|calling)/i,
27
+ /\binstead[,\s]\s*(use|do|write|call|import|prefer)/i,
28
+ /\b(wrong approach|bad approach|hacky|not the right way|not how we do)/i,
29
+ /\b(I said|I told you|I asked you)\s+(not to|to not|don'?t|to use|to avoid)/i,
30
+ /\b(always|never)\s+(use|do|write|prefer|avoid|import|call)\b/i,
31
+ /\buse\s+\w[\w-]*\s+(not|instead of|rather than)\s+\w/i,
32
+ /\b(we use|we prefer|we don'?t use|we never|we always)\b/i,
33
+ /\b(please don'?t|please use|please avoid|please stop)\b/i,
34
+ /\bthat'?s not (what|how|the way)/i,
35
+ ];
36
+
37
+ // ── Messages that look like corrections but are questions ──────────────────
38
+ const EXCLUDE_PATTERNS = [
39
+ /\?$/,
40
+ /^(what|how|why|when|where|which|who|can you|could you|would you|should I)/i,
41
+ ];
42
+
43
+ // ── Minimum message length to bother with ─────────────────────────────────
44
+ const MIN_LEN = 8;
45
+
46
+ // ── Entry point ───────────────────────────────────────────────────────────
47
+ let raw = '';
48
+ process.stdin.setEncoding('utf8');
49
+ process.stdin.on('data', chunk => { raw += chunk; });
50
+ process.stdin.on('end', run);
51
+ setTimeout(() => { if (!process.stdin.readableEnded) run(); }, 150);
52
+
53
+ function run() {
54
+ // Always pass stdin through — never block a session
55
+ if (raw) process.stdout.write(raw);
56
+
57
+ try {
58
+ const payload = raw ? JSON.parse(raw) : {};
59
+ const sessionJsonl = payload.session_path
60
+ || payload.transcript_path
61
+ || findLatestSession(payload.cwd || process.cwd());
62
+
63
+ if (!sessionJsonl || !fs.existsSync(sessionJsonl)) return;
64
+
65
+ const corrections = extractCorrections(sessionJsonl);
66
+ if (corrections.length === 0) return;
67
+
68
+ writeToLessons(corrections, payload.cwd || process.cwd());
69
+ } catch (err) {
70
+ process.stderr.write(`[ecc:correction-capture] ${err.message}\n`);
71
+ }
72
+ }
73
+
74
+ // ── Extract corrections from session JSONL ─────────────────────────────────
75
+ function extractCorrections(sessionJsonl) {
76
+ const lines = fs.readFileSync(sessionJsonl, 'utf8').split('\n').filter(Boolean);
77
+ const corrections = [];
78
+
79
+ for (const line of lines) {
80
+ let event;
81
+ try { event = JSON.parse(line); } catch { continue; }
82
+
83
+ // Only process user turns
84
+ if (event.type !== 'user') continue;
85
+
86
+ const text = extractText(event);
87
+ if (!text || text.length < MIN_LEN) continue;
88
+
89
+ // Skip if it looks like a question
90
+ if (EXCLUDE_PATTERNS.some(p => p.test(text.trim()))) continue;
91
+
92
+ // Check for correction signals
93
+ if (!CORRECTION_SIGNALS.some(p => p.test(text))) continue;
94
+
95
+ // Clean up and cap length
96
+ const cleaned = text.trim().replace(/\s+/g, ' ').slice(0, 300);
97
+ corrections.push(cleaned);
98
+ }
99
+
100
+ // Deduplicate
101
+ return [...new Set(corrections)];
102
+ }
103
+
104
+ // ── Pull plain text from an event ─────────────────────────────────────────
105
+ function extractText(event) {
106
+ const content = event.message?.content ?? event.content ?? '';
107
+ if (typeof content === 'string') return content;
108
+ if (Array.isArray(content)) {
109
+ return content
110
+ .filter(b => b.type === 'text')
111
+ .map(b => b.text || '')
112
+ .join(' ')
113
+ .trim();
114
+ }
115
+ return '';
116
+ }
117
+
118
+ // ── Write lessons to tasks/lessons.md ─────────────────────────────────────
119
+ function writeToLessons(corrections, cwd) {
120
+ const tasksDir = path.join(cwd, 'tasks');
121
+ const lessonsFile = path.join(tasksDir, 'lessons.md');
122
+
123
+ try {
124
+ fs.mkdirSync(tasksDir, { recursive: true });
125
+
126
+ const isNew = !fs.existsSync(lessonsFile);
127
+ const date = new Date().toISOString().split('T')[0];
128
+ const project = path.basename(cwd);
129
+
130
+ let header = '';
131
+ if (isNew) {
132
+ header = [
133
+ '# Claude Lessons',
134
+ '',
135
+ `Project: **${project}**`,
136
+ '',
137
+ 'Auto-generated by Kodelyth ECC. Each entry is a rule Claude learned from a correction.',
138
+ 'Edit freely — add, remove, reword. These are YOUR rules.',
139
+ '',
140
+ '---',
141
+ '',
142
+ ].join('\n');
143
+ }
144
+
145
+ const block = [
146
+ `## ${date}`,
147
+ '',
148
+ ...corrections.map(c => `- ${c}`),
149
+ '',
150
+ ].join('\n');
151
+
152
+ fs.appendFileSync(lessonsFile, header + block, 'utf8');
153
+
154
+ process.stderr.write(
155
+ `[ecc:correction-capture] ${corrections.length} lesson(s) written to tasks/lessons.md\n`
156
+ );
157
+ } catch (err) {
158
+ process.stderr.write(`[ecc:correction-capture] Could not write lessons: ${err.message}\n`);
159
+ }
160
+ }
161
+
162
+ // ── Find the latest session JSONL for this project ────────────────────────
163
+ function findLatestSession(cwd) {
164
+ try {
165
+ const os = require('os');
166
+ const projectsDir = path.join(os.homedir(), '.claude', 'projects');
167
+ if (!fs.existsSync(projectsDir)) return null;
168
+
169
+ const encoded = cwd.replace(/\//g, '-');
170
+ const dirs = fs.readdirSync(projectsDir)
171
+ .filter(d => encoded.endsWith(d.slice(-20)) || d.endsWith(encoded.slice(-30)));
172
+
173
+ if (dirs.length === 0) return null;
174
+
175
+ const projectDir = path.join(projectsDir, dirs[0]);
176
+ const sessions = fs.readdirSync(projectDir)
177
+ .filter(f => f.endsWith('.jsonl'))
178
+ .map(f => ({ f, mtime: fs.statSync(path.join(projectDir, f)).mtimeMs }))
179
+ .sort((a, b) => b.mtime - a.mtime);
180
+
181
+ return sessions[0] ? path.join(projectDir, sessions[0].f) : null;
182
+ } catch {
183
+ return null;
184
+ }
185
+ }
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env node
2
+ // =============================================================================
3
+ // Kodelyth ECC — Lessons + Project DNA Hook (SessionStart)
4
+ //
5
+ // Runs at the start of every Claude Code session. Does two things:
6
+ //
7
+ // 1. LESSONS: Reads tasks/lessons.md from the project root (if it exists)
8
+ // and injects the encoded rules as high-priority context. These are
9
+ // corrections the user made in past sessions — hard rules, not soft
10
+ // suggestions. Claude MUST follow them for this session.
11
+ //
12
+ // 2. PROJECT DNA: Detects the tech stack, package manager, and key
13
+ // conventions from the project root (package.json, go.mod, Cargo.toml,
14
+ // etc.) and injects a concise project brief so Claude doesn't need to
15
+ // re-discover basics each session.
16
+ //
17
+ // Output contract: emit { additionalContext: "..." } to stdout.
18
+ // Never block a session — exit 0 even on any error.
19
+ // =============================================================================
20
+
21
+ 'use strict';
22
+
23
+ const fs = require('fs');
24
+ const path = require('path');
25
+
26
+ let raw = '';
27
+ process.stdin.setEncoding('utf8');
28
+ process.stdin.on('data', chunk => { raw += chunk; });
29
+ process.stdin.on('end', run);
30
+ setTimeout(() => { if (!process.stdin.readableEnded) run(); }, 150);
31
+
32
+ function run() {
33
+ try {
34
+ const payload = raw ? JSON.parse(raw) : {};
35
+ const projectRoot = payload.cwd || payload.project_root || process.cwd();
36
+
37
+ const parts = [];
38
+
39
+ const lessons = readLessons(projectRoot);
40
+ if (lessons) parts.push(lessons);
41
+
42
+ const dna = buildProjectDNA(projectRoot);
43
+ if (dna) parts.push(dna);
44
+
45
+ if (parts.length === 0) {
46
+ process.exit(0);
47
+ }
48
+
49
+ process.stdout.write(JSON.stringify({
50
+ additionalContext: parts.join('\n\n---\n\n'),
51
+ meta: { source: 'kodelyth-ecc:read-lessons', hasLessons: !!lessons, hasDNA: !!dna },
52
+ }));
53
+ process.exit(0);
54
+ } catch (err) {
55
+ process.stderr.write(`[ecc:read-lessons] ${err.message}\n`);
56
+ process.exit(0);
57
+ }
58
+ }
59
+
60
+ // ── Read tasks/lessons.md and format as hard rules ────────────────────────
61
+ function readLessons(projectRoot) {
62
+ const lessonsFile = path.join(projectRoot, 'tasks', 'lessons.md');
63
+ if (!fs.existsSync(lessonsFile)) return null;
64
+
65
+ const content = fs.readFileSync(lessonsFile, 'utf8').trim();
66
+ if (!content) return null;
67
+
68
+ // Extract all bullet rules across all dated sections
69
+ const rules = content
70
+ .split('\n')
71
+ .filter(line => line.match(/^-\s+.{5,}/))
72
+ .map(line => line.trim())
73
+ .filter(Boolean);
74
+
75
+ if (rules.length === 0) return null;
76
+
77
+ return [
78
+ '## PROJECT LESSONS — HARD RULES (from past corrections)',
79
+ '',
80
+ 'These rules were encoded from corrections made in previous sessions.',
81
+ 'You MUST follow them for this entire session. They override generic defaults.',
82
+ '',
83
+ rules.join('\n'),
84
+ ].join('\n');
85
+ }
86
+
87
+ // ── Detect project tech stack and conventions ─────────────────────────────
88
+ function buildProjectDNA(projectRoot) {
89
+ const facts = [];
90
+
91
+ // Node / JS / TS
92
+ const pkgPath = path.join(projectRoot, 'package.json');
93
+ if (fs.existsSync(pkgPath)) {
94
+ try {
95
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
96
+ const name = pkg.name || path.basename(projectRoot);
97
+ facts.push(`Project: ${name} (Node.js / JavaScript)`);
98
+
99
+ // Package manager
100
+ if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) {
101
+ facts.push('Package manager: pnpm');
102
+ } else if (fs.existsSync(path.join(projectRoot, 'bun.lockb')) || fs.existsSync(path.join(projectRoot, 'bun.lock'))) {
103
+ facts.push('Package manager: bun');
104
+ } else if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) {
105
+ facts.push('Package manager: yarn');
106
+ } else {
107
+ facts.push('Package manager: npm');
108
+ }
109
+
110
+ // Framework detection
111
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
112
+ const frameworks = [];
113
+ if (deps.next) frameworks.push(`Next.js ${deps.next}`);
114
+ if (deps.react) frameworks.push(`React ${deps.react}`);
115
+ if (deps.vue) frameworks.push(`Vue ${deps.vue}`);
116
+ if (deps.svelte) frameworks.push(`Svelte`);
117
+ if (deps.express) frameworks.push(`Express ${deps.express}`);
118
+ if (deps.fastify) frameworks.push(`Fastify`);
119
+ if (deps.nestjs || deps['@nestjs/core']) frameworks.push('NestJS');
120
+ if (deps.typescript || deps['ts-node']) frameworks.push('TypeScript');
121
+ if (deps.prisma || deps['@prisma/client']) frameworks.push('Prisma');
122
+ if (deps.drizzle) frameworks.push('Drizzle ORM');
123
+ if (frameworks.length > 0) facts.push(`Stack: ${frameworks.join(', ')}`);
124
+
125
+ // Test runner
126
+ if (deps.jest) facts.push('Test runner: Jest');
127
+ else if (deps.vitest) facts.push('Test runner: Vitest');
128
+ else if (deps.mocha) facts.push('Test runner: Mocha');
129
+ } catch {}
130
+ }
131
+
132
+ // Go
133
+ const goModPath = path.join(projectRoot, 'go.mod');
134
+ if (fs.existsSync(goModPath)) {
135
+ try {
136
+ const goMod = fs.readFileSync(goModPath, 'utf8');
137
+ const moduleLine = goMod.match(/^module (.+)/m);
138
+ const goVersion = goMod.match(/^go (.+)/m);
139
+ facts.push(`Project: ${moduleLine?.[1] || 'Go module'} (Go${goVersion ? ' ' + goVersion[1] : ''})`);
140
+ } catch {}
141
+ }
142
+
143
+ // Rust
144
+ const cargoPath = path.join(projectRoot, 'Cargo.toml');
145
+ if (fs.existsSync(cargoPath)) {
146
+ try {
147
+ const cargo = fs.readFileSync(cargoPath, 'utf8');
148
+ const name = cargo.match(/^name\s*=\s*"(.+)"/m);
149
+ facts.push(`Project: ${name?.[1] || 'Rust crate'} (Rust / Cargo)`);
150
+ } catch {}
151
+ }
152
+
153
+ // Python
154
+ const reqPath = path.join(projectRoot, 'requirements.txt');
155
+ const pyprojPath = path.join(projectRoot, 'pyproject.toml');
156
+ if (fs.existsSync(reqPath) || fs.existsSync(pyprojPath)) {
157
+ facts.push('Language: Python');
158
+ if (fs.existsSync(path.join(projectRoot, 'poetry.lock'))) facts.push('Package manager: Poetry');
159
+ else if (fs.existsSync(path.join(projectRoot, 'Pipfile.lock'))) facts.push('Package manager: Pipenv');
160
+ else facts.push('Package manager: pip');
161
+ }
162
+
163
+ // Java / Kotlin
164
+ if (fs.existsSync(path.join(projectRoot, 'build.gradle')) || fs.existsSync(path.join(projectRoot, 'build.gradle.kts'))) {
165
+ facts.push('Build: Gradle (Java / Kotlin)');
166
+ }
167
+ if (fs.existsSync(path.join(projectRoot, 'pom.xml'))) {
168
+ facts.push('Build: Maven (Java)');
169
+ }
170
+
171
+ // Existing tasks/todo.md
172
+ const todoPath = path.join(projectRoot, 'tasks', 'todo.md');
173
+ if (fs.existsSync(todoPath)) {
174
+ const todo = fs.readFileSync(todoPath, 'utf8').trim();
175
+ const openItems = todo.split('\n').filter(l => l.match(/^-\s*\[ \]/)).slice(0, 5);
176
+ if (openItems.length > 0) {
177
+ facts.push('');
178
+ facts.push('Open tasks (from tasks/todo.md):');
179
+ openItems.forEach(item => facts.push(item.trim()));
180
+ }
181
+ }
182
+
183
+ if (facts.length === 0) return null;
184
+
185
+ return [
186
+ '## PROJECT DNA (auto-detected)',
187
+ '',
188
+ facts.join('\n'),
189
+ ].join('\n');
190
+ }
package/install.sh CHANGED
@@ -47,7 +47,7 @@ echo -e "${RED}${BOLD} ║ DANGER LEVEL: GOD TIER · NOT FOR JUNIOR DEV
47
47
  echo -e "${RED}${BOLD} ╚══════════════════════════════════════════════════════════════╝${RESET}"
48
48
  echo ""
49
49
  echo -e "${BOLD} Kodelyth ECC — The most dangerous AI coding toolkit on the planet${RESET}"
50
- echo -e "${CYAN} 59 specialist agents · 188 skills · 80 commands · 18+ hooks · intent routing · local memory${RESET}"
50
+ echo -e "${CYAN} 61 specialist agents · 188 skills · 80 commands · 20+ hooks · intent routing · compound memory${RESET}"
51
51
  echo -e "${CYAN} Any language · Any framework · Any scale · 300B-level quality${RESET}"
52
52
  echo ""
53
53
  echo -e " github.com/sifxprime/kodelyth-ecc"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kodelyth-ecc",
3
- "version": "1.5.0",
4
- "description": "Production-grade AI coding toolkit 61 agents, 188 skills, 80 commands, god-tier intent routing, local self-learning memory with auto chat detection, incident response, load testing. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, and OpenCode.",
3
+ "version": "1.5.1",
4
+ "description": "Production-grade AI coding toolkit \u2014 61 agents, 188 skills, 80 commands, god-tier intent routing, local self-learning memory with auto chat detection, incident response, load testing. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, and OpenCode.",
5
5
  "author": "Kodelyth <github.com/sifxprime>",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -0,0 +1,126 @@
1
+ # Self-Improvement Workflow — Compound Learning System
2
+
3
+ This rule encodes the workflow used by the Claude Code team internally, extended with ECC's three-layer compound memory architecture. Every session makes Claude more aligned with how YOU think and work.
4
+
5
+ ---
6
+
7
+ ## 1. Plan Node Default
8
+
9
+ Enter plan mode for ANY non-trivial task (3+ steps, architectural decisions, or anything that touches more than 2 files):
10
+
11
+ - Write the plan to `tasks/todo.md` with checkable items before writing a single line of code
12
+ - If something goes sideways mid-task: STOP, re-plan, do not keep pushing
13
+ - Use plan mode for verification steps, not just building
14
+ - Write detailed specs upfront — ambiguity at start = bugs at end
15
+ - Check plan with the user before executing when scope is large
16
+
17
+ ## 2. Subagent Strategy
18
+
19
+ The 61 ECC specialist agents exist so the main context window stays clean:
20
+
21
+ - Offload research, exploration, and parallel analysis to subagents
22
+ - For complex problems: throw more compute via agents, not more tokens in main context
23
+ - One task per subagent — focused execution beats monolithic threads
24
+ - Intent routing picks the right specialist automatically — trust it
25
+
26
+ ## 3. Self-Improvement Loop (CRITICAL)
27
+
28
+ **After ANY correction from the user — no matter how small — encode it permanently.**
29
+
30
+ When the user says something like "no, don't do that", "use X instead", "I told you to", "wrong approach", "stop doing X":
31
+
32
+ 1. **Acknowledge** the correction in one line
33
+ 2. **Apply** it immediately in the current response
34
+ 3. **Encode** it: mentally append the rule to `tasks/lessons.md` in the project root
35
+
36
+ The AI MUST track corrections within a session and apply them consistently from that point forward. The `capture-correction.js` hook writes them to disk automatically at session end.
37
+
38
+ ### How lessons compound
39
+
40
+ ```
41
+ Session 1: User corrects "use pnpm not npm" → lesson written
42
+ Session 2: Claude reads lesson → never uses npm again in this project
43
+ Session 3+: New lessons stack → Claude increasingly matches YOUR style
44
+ Month 3: Claude works like a team member who has been here for years
45
+ ```
46
+
47
+ **Review and extend lessons** at `tasks/lessons.md` — edit them freely, they are yours.
48
+
49
+ ## 4. Verification Before Done
50
+
51
+ Never mark a task complete without proving it works:
52
+
53
+ - Run the actual code, test, or command — do not assume
54
+ - Diff behavior between baseline and your changes when relevant
55
+ - Ask: "Would a staff engineer approve this PR?"
56
+ - Run tests, check logs, demonstrate correctness with evidence
57
+ - If verification fails: fix, do not close the loop
58
+
59
+ ## 5. Demand Elegance (Balanced)
60
+
61
+ For non-trivial changes, pause before presenting:
62
+
63
+ - Ask internally: "Is there a more elegant solution?"
64
+ - If the fix feels hacky: "Knowing everything I know now, implement the elegant solution"
65
+ - **Skip this for simple, obvious fixes** — do not over-engineer
66
+ - Challenge your own work before presenting it
67
+ - Three lines of clear code beat a clever one-liner every time
68
+
69
+ ## 6. Autonomous Bug Fixing
70
+
71
+ When given a bug report: fix it. Do not ask for hand-holding:
72
+
73
+ - Point at logs, errors, and failing tests — then resolve them
74
+ - Zero context switching required from the user
75
+ - Go fix failing CI tests without being told how
76
+ - Use `debug-detective` for root cause analysis (never patch symptoms)
77
+ - Use `silent-failure-hunter` when there is no error message
78
+
79
+ ---
80
+
81
+ ## Task Management Protocol
82
+
83
+ When starting any non-trivial task:
84
+
85
+ 1. **Plan First** — write plan to `tasks/todo.md` with checkable items
86
+ 2. **Verify Plan** — check in before starting implementation on large tasks
87
+ 3. **Track Progress** — mark items complete as you go
88
+ 4. **Explain Changes** — high-level summary at each step
89
+ 5. **Document Results** — add review section to `tasks/todo.md`
90
+ 6. **Capture Lessons** — `tasks/lessons.md` is updated automatically by the correction hook
91
+
92
+ ---
93
+
94
+ ## Three-Layer Compound Memory Architecture
95
+
96
+ ECC uses three compounding memory layers — together they make Claude increasingly match how you think:
97
+
98
+ ### Layer 1 — Project Lessons (`tasks/lessons.md`)
99
+ - Per-project. Human-readable. Hard rules.
100
+ - Written automatically when you correct Claude (via `capture-correction.js` Stop hook)
101
+ - Injected at session start (via `read-lessons.js` SessionStart hook)
102
+ - Edit freely — these are YOUR rules for this project
103
+ - Example: "Always use pnpm. Never npm. Never yarn."
104
+
105
+ ### Layer 2 — Global Memory (`~/.kodelyth/memory/`)
106
+ - Cross-project. BM25 fuzzy search. Solution patterns.
107
+ - Captures solutions from every session
108
+ - Auto-recalls relevant past solutions on every prompt you type
109
+ - Example: "Last time you had a CORS issue in Express, you added this middleware..."
110
+
111
+ ### Layer 3 — Intent Routing (`rules/common/agent-intent-routing.md`)
112
+ - Always-on. 61 specialists. Zero setup.
113
+ - Routes your message to the right expert from the first word
114
+ - No agent names needed — just describe the problem
115
+
116
+ **Combined effect**: Layer 1 knows your project rules. Layer 2 knows your past solutions. Layer 3 knows your intent. Together they eliminate the ramp-up cost of every session.
117
+
118
+ ---
119
+
120
+ ## Core Principles
121
+
122
+ - **Simplicity First** — make every change as simple as possible, impact minimal code
123
+ - **No Laziness** — find root causes, no temporary fixes, senior developer standards
124
+ - **Minimal Impact** — changes touch only what's necessary, avoid introducing bugs
125
+ - **Immutability** — create new objects, never mutate existing ones
126
+ - **No Guessing** — if uncertain, ask. Never fabricate facts or behavior.