continuous-improvement 3.20.4 → 3.21.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.
@@ -7,8 +7,8 @@
7
7
  "plugins": [
8
8
  {
9
9
  "name": "continuous-improvement",
10
- "description": "The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 27 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.",
11
- "version": "3.20.4",
10
+ "description": "The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 28 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.",
11
+ "version": "3.21.0",
12
12
  "source": "./plugins/continuous-improvement",
13
13
  "author": {
14
14
  "name": "naimkatiman"
package/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ All notable changes to this skill are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## [3.21.0] — 2026-07-11
8
+
9
+ ### Added
10
+
11
+ - **`/simplicity-review`**: a diff-scoped over-engineering reviewer. It reads the current diff and walks a reuse ladder (does it need to exist? already in the codebase? stdlib? native feature? one line?), reporting `GO` or `TRIM` trim findings without editing, with a safety carve-out that never flags input validation, data-loss handling, security, or accessibility. Review-only (Law 4), tier 2, routed into `proceed-with-the-recommendation`. Brings the bundle to 28 skills. (#285)
12
+
13
+ ### Changed
14
+
15
+ - **`/production-readiness-review` gains a fifth blind reviewer**: a simplicity and over-engineering dimension that delegates to the `simplicity-review` skill, so the readiness gate now spans performance, security, UI/UX, test coverage, and simplicity. (#286)
16
+
7
17
  ## [3.17.0] — 2026-06-28
8
18
 
9
19
  ### Added
package/QUICKSTART.md CHANGED
@@ -139,7 +139,7 @@ npx continuous-improvement install --mode expert
139
139
  npx continuous-improvement install --pack react # optional: react | python | go | meta
140
140
  ```
141
141
 
142
- Preconditions: Node 18 / 20 / 22, plus Git Bash on Windows (`hooks/observe.sh` is a Bash script). WSL Bash launched from native Windows cannot resolve the `C:/...` hook paths written by the installer. See [README.md § Expert](README.md#expert--adds-mcp-server-observation-hooks-and-instinct-packs) for the full preconditions and troubleshooting matrix.
142
+ Precondition: Node 18 / 20 / 22. Runtime hooks execute Node directly, so Git Bash and `jq` are not required. Re-run the installer once after upgrading to migrate legacy Bash hook rows. See [README.md § Expert](README.md#expert--adds-mcp-server-observation-hooks-and-instinct-packs) for the troubleshooting matrix.
143
143
 
144
144
  Verify with `/dashboard` — you should see instinct health and observation count.
145
145
 
package/README.md CHANGED
@@ -137,7 +137,7 @@ V1 honest limitations: the runtime gate is honor-system once the agent flips `_g
137
137
 
138
138
  Pick this if you want the MCP tools (19 of them, including `ci_plan_init` / `ci_plan_status` for `task_plan.md`-style planning), the session hooks that feed Mulahazah, and starter packs.
139
139
 
140
- Preconditions: Node 18 / 20 / 22, plus Git Bash on Windows (`hooks/observe.sh` is a Bash script). WSL Bash launched from native Windows cannot resolve the `C:/...` hook paths written by the installer. **`jq` is no longer required**: as of v3.6.0, `observe.sh` prefers the Node observer (`bin/observe.mjs`) which writes the rich event schema natively without external dependencies. The bash thin-schema path is kept as a two-phase shim, so legacy installs that have not re-run `npx continuous-improvement install` since v3.5.x will still degrade silently without `jq` (`winget install jqlang.jq` on Windows, `brew install jq` on macOS, `apt install jq` on Debian/Ubuntu) — re-running the installer is the cleaner fix and removes the dependency entirely. See [CHANGELOG.md](CHANGELOG.md) `[3.6.0]` for the migration details.
140
+ Precondition: Node 18 / 20 / 22. Observation and session hooks execute Node directly, so Git Bash and `jq` are not required. Re-run the installer once after upgrading to migrate installer-owned `observe.sh` and `session.sh` rows to the Node entrypoints.
141
141
 
142
142
  ```bash
143
143
  npx continuous-improvement install --mode expert
@@ -158,7 +158,7 @@ Three failures account for nearly every install support thread. Try them in orde
158
158
  | Symptom | Real cause | Fix |
159
159
  |---|---|---|
160
160
  | `/discipline` says "command not recognized" right after `/plugin install` | Slash commands load on session start; the marketplace did pick the plugin up | Quit and reopen Claude Code, then run `/discipline` again |
161
- | Expert mode hooks never fire on Windows | WSL Bash cannot resolve the native `C:/...` hook paths | Install Git Bash, ensure its `bin` directory precedes `C:\Windows\System32` on PATH, then re-run `npx continuous-improvement install --mode expert` |
161
+ | Hooks report Bash path errors after upgrading | Stale installer-owned `observe.sh` or `session.sh` rows remain in `settings.json` | Re-run `npx continuous-improvement install --mode expert`; the installer migrates those rows to Node and preserves foreign hooks |
162
162
  | `/plugin marketplace add ...` returned nothing visible | Marketplace add was silent; the plugin is not yet selected | Run `/plugin install continuous-improvement@continuous-improvement` to select and activate it |
163
163
 
164
164
  If none of those apply, paste the output of `npx continuous-improvement install` into a GitHub issue — that surface logs every step.
@@ -270,7 +270,7 @@ Hooks capture every tool call. After ~20 observations Claude analyzes patterns a
270
270
  ## Slash commands
271
271
 
272
272
  <details>
273
- <summary><b>All 28 commands (Beginner gets every one)</b></summary>
273
+ <summary><b>All 29 commands (Beginner gets every one)</b></summary>
274
274
 
275
275
  `/seven-laws` is the canonical reflect-and-learn command. `/continuous-improvement` is kept as an alias for backward compatibility — both run the same workflow.
276
276
 
@@ -290,6 +290,7 @@ Hooks capture every tool call. After ~20 observations Claude analyzes patterns a
290
290
  /audit Audit recent commits for real defects, confirm each before fixing
291
291
  /ship Single-defect fast path — reconcile, TDD fix, verify, one PR
292
292
  /production-readiness-review Parallel readiness gate — severity-ranked punch-list (reports only)
293
+ /simplicity-review Judge the current diff for over-engineering (GO / TRIM, reports only)
293
294
  /handoff End-of-session compaction into mktemp brief for the next agent
294
295
  /recall BM25 search over past observations — "have I hit this before?"
295
296
  /discipline Quick reference card of the 7 Laws
@@ -305,7 +306,7 @@ Hooks capture every tool call. After ~20 observations Claude analyzes patterns a
305
306
  /swarm Fan-out coordination across parallel sub-agents
306
307
  ```
307
308
 
308
- All 28 ship in the marketplace bundle. The Beginner install gets all of them — with one caveat: `/learn-eval`, `/harvest`, and `/distill` only produce useful output once Mulahazah has accumulated observation history (~20 observations), so running them on day 1 returns an empty result, not a broken command. `/swarm` and `/release-train` are orchestration commands aimed at larger multi-agent or multi-PR work. In Expert (`npx`) mode, the installer mirrors the full set into `~/.claude/commands/` and additionally exposes the planning workflow through the MCP tools `ci_plan_init` (initialize `task_plan.md`, `findings.md`, `progress.md` in the project root) and `ci_plan_status` (summarize their current contents).
309
+ All 29 ship in the marketplace bundle. The Beginner install gets all of them — with one caveat: `/learn-eval`, `/harvest`, and `/distill` only produce useful output once Mulahazah has accumulated observation history (~20 observations), so running them on day 1 returns an empty result, not a broken command. `/swarm` and `/release-train` are orchestration commands aimed at larger multi-agent or multi-PR work. In Expert (`npx`) mode, the installer mirrors the full set into `~/.claude/commands/` and additionally exposes the planning workflow through the MCP tools `ci_plan_init` (initialize `task_plan.md`, `findings.md`, `progress.md` in the project root) and `ci_plan_status` (summarize their current contents).
309
310
 
310
311
  </details>
311
312
 
@@ -313,7 +314,7 @@ All 28 ship in the marketplace bundle. The Beginner install gets all of them —
313
314
 
314
315
  ## Skills
315
316
 
316
- The plugin ships **27 skills** — 1 core + 1 featured + 6 tier-1 + 16 tier-2 + 3 always-bundled. Beginner install gets tier-1, featured, and the always-bundled companion; Expert adds tier-2, the MCP server, and observation hooks. Full catalog with per-skill descriptions, Law tagging, and drop-in single-file install: [docs/skills.md](docs/skills.md). Adding a 28th skill: [CONTRIBUTING.md § Evolution — adding a new skill](CONTRIBUTING.md#evolution--adding-a-new-skill).
317
+ The plugin ships **28 skills** — 1 core + 1 featured + 6 tier-1 + 17 tier-2 + 3 always-bundled. Beginner install gets tier-1, featured, and the always-bundled companion; Expert adds tier-2, the MCP server, and observation hooks. Full catalog with per-skill descriptions, Law tagging, and drop-in single-file install: [docs/skills.md](docs/skills.md). Adding a 29th skill: [CONTRIBUTING.md § Evolution — adding a new skill](CONTRIBUTING.md#evolution--adding-a-new-skill).
317
318
 
318
319
  ---
319
320
 
@@ -356,7 +357,7 @@ Proof-format templates ship in [templates/](templates/): `release_receipt_templa
356
357
 
357
358
  - [QUICKSTART.md](QUICKSTART.md) — 2-minute setup
358
359
  - [SKILL.md](SKILL.md) — full 7 Laws spec
359
- - [docs/skills.md](docs/skills.md) — full 27-skill catalog
360
+ - [docs/skills.md](docs/skills.md) — full 28-skill catalog
360
361
  - [examples/](examples/) — bug fix, feature build, refactor walkthroughs
361
362
  - [templates/insights-claude-md.md](templates/insights-claude-md.md) — paste-in CLAUDE.md blocks for verification discipline, environment notes, think-before-acting, and git/deploy workflow (sourced from the 28-day usage report)
362
363
  - [CONTRIBUTING.md](CONTRIBUTING.md) — architecture, repo internals, adding a new skill
package/bin/install.mjs CHANGED
@@ -10,7 +10,7 @@
10
10
  * npx continuous-improvement install --uninstall # remove everything
11
11
  */
12
12
  import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from "node:fs";
13
- import { execFileSync as runFileSync, execSync } from "node:child_process";
13
+ import { execSync } from "node:child_process";
14
14
  import { homedir } from "node:os";
15
15
  import { dirname, join } from "node:path";
16
16
  import { fileURLToPath } from "node:url";
@@ -45,29 +45,25 @@ const SESSION_HOOK_TYPES = ["SessionStart", "SessionEnd"];
45
45
  // accidental overlap between HOOK_TYPES and SESSION_HOOK_TYPES never causes
46
46
  // a hook bucket to be processed twice.
47
47
  const ALL_HOOK_TYPES = Array.from(new Set([...HOOK_TYPES, ...SESSION_HOOK_TYPES]));
48
- // Our installer writes `bash ".../.claude/instincts/(observe|session).sh"`.
49
- // Older Windows installs sometimes stored the same command with backslashes in
50
- // the quoted path; those no-op because bash can't resolve them. We strip only
51
- // that installer-owned command shape so foreign hooks that merely mention
52
- // observe.sh/session.sh survive.
53
- const INSTALLER_OBSERVE_SESSION_COMMAND_RE = /^bash ".*[\\/]\.claude[\\/]instincts[\\/](?:observe|session)\.sh"$/;
54
- function isBrokenObserveOrSessionCommand(command) {
48
+ // Match only installer-owned lifecycle commands. Bash rows are legacy and get
49
+ // migrated on install; both legacy and current Node rows are removed on uninstall.
50
+ const LEGACY_OBSERVE_SESSION_COMMAND_RE = /^bash ".*[\\/]\.claude[\\/]instincts[\\/](?:observe|session)\.sh"$/;
51
+ const NODE_OBSERVE_SESSION_COMMAND_RE = /^node ".*[\\/]\.claude[\\/]instincts[\\/](?:bin[\\/]observe|session)\.mjs"$/;
52
+ function isLegacyObserveOrSessionCommand(command) {
55
53
  if (typeof command !== "string")
56
54
  return false;
57
- return command.includes("\\") && INSTALLER_OBSERVE_SESSION_COMMAND_RE.test(command);
55
+ return LEGACY_OBSERVE_SESSION_COMMAND_RE.test(command);
58
56
  }
59
- // Any installer-owned observe.sh / session.sh hook command, broken or clean.
60
- // Used by uninstall to drop both freshly-installed forward-slash hooks and any
61
- // stale legacy entries. Pairs with isBrokenObserveOrSessionCommand above.
62
57
  function isOurObserveOrSessionCommand(command) {
63
58
  if (typeof command !== "string")
64
59
  return false;
65
- return INSTALLER_OBSERVE_SESSION_COMMAND_RE.test(command);
60
+ return LEGACY_OBSERVE_SESSION_COMMAND_RE.test(command) ||
61
+ NODE_OBSERVE_SESSION_COMMAND_RE.test(command);
66
62
  }
67
63
  function getHomeDir() {
68
64
  return process.env.HOME || process.env.USERPROFILE || homedir();
69
65
  }
70
- function toBashPath(filePath) {
66
+ function toCommandPath(filePath) {
71
67
  return filePath.replace(/\\/g, "/");
72
68
  }
73
69
  function isInstallMode(value) {
@@ -84,28 +80,6 @@ function readJsonFile(filePath) {
84
80
  return null;
85
81
  }
86
82
  }
87
- // The observation hooks are Bash scripts, and the native Windows settings use
88
- // forward-slash drive paths such as C:/Users/... . Git Bash resolves that form;
89
- // WSL's C:\Windows\System32\bash.exe does not. Probe the real packaged hook path
90
- // instead of accepting any executable that happens to answer `bash --version`.
91
- function assertBashCanReadHookOnWindows() {
92
- if (process.platform !== "win32")
93
- return;
94
- const hookSource = toBashPath(join(REPO_ROOT, "hooks", "observe.sh"));
95
- try {
96
- runFileSync("bash", ["-c", 'test -r "$CONTINUOUS_IMPROVEMENT_HOOK_SOURCE"'], {
97
- env: { ...process.env, CONTINUOUS_IMPROVEMENT_HOOK_SOURCE: hookSource },
98
- stdio: "ignore",
99
- });
100
- }
101
- catch {
102
- console.error(` ✗ Install refused: Bash on PATH cannot read the Windows hook path ${hookSource}. ` +
103
- "Install Git Bash and ensure its bin directory comes before " +
104
- "C:\\Windows\\System32 on PATH, then reopen your shell and re-run. " +
105
- "See README > Troubleshooting install.");
106
- process.exit(1);
107
- }
108
- }
109
83
  // The marketplace `/plugin install` path and this npx installer both write into
110
84
  // ~/.claude/. Running both duplicates hooks, commands, and skills. We cannot
111
85
  // fully resolve Claude Code's marketplace layout from here, so this is a loud
@@ -169,39 +143,26 @@ function setupMulahazah() {
169
143
  const globalDir = join(instinctsDir, "global");
170
144
  mkdirSync(globalDir, { recursive: true });
171
145
  console.log(` ✓ Instincts dir → ${instinctsDir}/`);
172
- const observeSrc = join(REPO_ROOT, "hooks", "observe.sh");
173
- const observeDest = join(instinctsDir, "observe.sh");
174
- if (existsSync(observeSrc)) {
175
- copyFileSync(observeSrc, observeDest);
176
- chmodSync(observeDest, 0o755);
177
- console.log(` ✓ observe.sh → ${observeDest}`);
178
- }
179
- // Node observer (Phase 1 of the two-phase hook). The bash shim above
180
- // exec's this when `node` and the file are both present; otherwise it
181
- // falls back to the in-bash thin-schema path. Layout under instinctsDir
182
- // mirrors the repo's bin/ + lib/ structure so the relative import in
183
- // observe.mjs (`../lib/observe-event.mjs`) resolves correctly.
146
+ // Layout mirrors bin/ + lib/ so observe.mjs's relative import resolves.
184
147
  const observerJsSrc = join(REPO_ROOT, "bin", "observe.mjs");
185
148
  const observeEventSrc = join(REPO_ROOT, "lib", "observe-event.mjs");
149
+ const observerJsDest = join(instinctsDir, "bin", "observe.mjs");
186
150
  if (existsSync(observerJsSrc) && existsSync(observeEventSrc)) {
187
151
  const binDir = join(instinctsDir, "bin");
188
152
  const libDir = join(instinctsDir, "lib");
189
153
  mkdirSync(binDir, { recursive: true });
190
154
  mkdirSync(libDir, { recursive: true });
191
- const observerJsDest = join(binDir, "observe.mjs");
192
155
  const observeEventDest = join(libDir, "observe-event.mjs");
193
156
  copyFileSync(observerJsSrc, observerJsDest);
194
157
  copyFileSync(observeEventSrc, observeEventDest);
195
158
  console.log(` ✓ Node observer → ${observerJsDest}`);
196
159
  }
197
- if (INSTALL_MODE === "expert") {
198
- const sessionSrc = join(REPO_ROOT, "hooks", "session.sh");
199
- const sessionDest = join(instinctsDir, "session.sh");
200
- if (existsSync(sessionSrc)) {
201
- copyFileSync(sessionSrc, sessionDest);
202
- chmodSync(sessionDest, 0o755);
203
- console.log(` ✓ session.sh → ${sessionDest}`);
204
- }
160
+ const sessionSrc = join(REPO_ROOT, "hooks", "session.mjs");
161
+ const sessionDest = join(instinctsDir, "session.mjs");
162
+ if (existsSync(sessionSrc)) {
163
+ copyFileSync(sessionSrc, sessionDest);
164
+ chmodSync(sessionDest, 0o755);
165
+ console.log(` ✓ Node session hook → ${sessionDest}`);
205
166
  }
206
167
  const commandsDir = join(home, ".claude", "commands");
207
168
  mkdirSync(commandsDir, { recursive: true });
@@ -213,7 +174,7 @@ function setupMulahazah() {
213
174
  console.log(` ✓ /${commandFile.replace(".md", "")} command → ${commandDest}`);
214
175
  }
215
176
  }
216
- patchClaudeSettings(observeDest);
177
+ patchClaudeSettings(observerJsDest);
217
178
  if (INSTALL_MODE === "expert") {
218
179
  setupMcpServer();
219
180
  }
@@ -276,6 +237,10 @@ function patchClaudeSettings(observePath) {
276
237
  if (!settings.hooks) {
277
238
  settings.hooks = {};
278
239
  }
240
+ const preserveSessionHooks = INSTALL_MODE === "expert" || SESSION_HOOK_TYPES.some((hookType) => {
241
+ const entries = settings.hooks?.[hookType];
242
+ return Array.isArray(entries) && entries.some((entry) => Array.isArray(entry?.hooks) && entry.hooks.some((hook) => isOurObserveOrSessionCommand(hook?.command)));
243
+ });
279
244
  // Strip broken legacy observe/session hooks at the hook level, not the entry
280
245
  // level. A single entry may carry a foreign command alongside a broken hook;
281
246
  // dropping the whole entry to remove the broken hook would also wipe the
@@ -294,7 +259,7 @@ function patchClaudeSettings(observePath) {
294
259
  cleanedEntries.push(entry);
295
260
  continue;
296
261
  }
297
- const filteredHooks = entryHooks.filter((hook) => !isBrokenObserveOrSessionCommand(hook?.command));
262
+ const filteredHooks = entryHooks.filter((hook) => !isLegacyObserveOrSessionCommand(hook?.command));
298
263
  if (filteredHooks.length === entryHooks.length) {
299
264
  cleanedEntries.push(entry);
300
265
  continue;
@@ -313,7 +278,7 @@ function patchClaudeSettings(observePath) {
313
278
  changed = true;
314
279
  }
315
280
  }
316
- const observeCommand = `bash "${toBashPath(observePath)}"`;
281
+ const observeCommand = `node "${toCommandPath(observePath)}"`;
317
282
  for (const hookType of HOOK_TYPES) {
318
283
  if (!Array.isArray(settings.hooks[hookType])) {
319
284
  settings.hooks[hookType] = [];
@@ -332,9 +297,9 @@ function patchClaudeSettings(observePath) {
332
297
  changed = true;
333
298
  }
334
299
  }
335
- if (INSTALL_MODE === "expert") {
336
- const sessionPath = join(getHomeDir(), ".claude", "instincts", "session.sh");
337
- const sessionCommand = `bash "${toBashPath(sessionPath)}"`;
300
+ if (preserveSessionHooks) {
301
+ const sessionPath = join(getHomeDir(), ".claude", "instincts", "session.mjs");
302
+ const sessionCommand = `node "${toCommandPath(sessionPath)}"`;
338
303
  for (const hookType of SESSION_HOOK_TYPES) {
339
304
  if (!Array.isArray(settings.hooks[hookType])) {
340
305
  settings.hooks[hookType] = [];
@@ -351,7 +316,7 @@ function patchClaudeSettings(observePath) {
351
316
  }
352
317
  if (changed) {
353
318
  writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
354
- const hookTypes = INSTALL_MODE === "expert"
319
+ const hookTypes = preserveSessionHooks
355
320
  ? "PreToolUse/PostToolUse/SessionStart/SessionEnd"
356
321
  : "PreToolUse/PostToolUse";
357
322
  console.log(` ✓ Patched ~/.claude/settings.json with ${hookTypes} hooks`);
@@ -387,7 +352,7 @@ function uninstallAll() {
387
352
  console.error(` ✗ ${commandName}: ${getErrorMessage(error)}`);
388
353
  }
389
354
  }
390
- for (const hookFile of ["observe.sh", "session.sh"]) {
355
+ for (const hookFile of ["observe.sh", "session.sh", "session.mjs"]) {
391
356
  const filePath = join(home, ".claude", "instincts", hookFile);
392
357
  if (!existsSync(filePath)) {
393
358
  continue;
@@ -617,10 +582,6 @@ function installNonClaudeTargets(targetIds) {
617
582
  for (const note of notes)
618
583
  console.log(` ℹ ${note}`);
619
584
  }
620
- // A mixed target install can write non-Claude rule files below. Validate the
621
- // Claude hook runtime first so an incompatible Bash cannot leave a partial install.
622
- if (requestedTargets.includes("claude"))
623
- assertBashCanReadHookOnWindows();
624
585
  const nonClaudeTargets = requestedTargets.filter((targetId) => targetId !== "claude");
625
586
  if (nonClaudeTargets.length > 0) {
626
587
  console.log("\ncontinuous-improvement multi-platform install\n");
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: production-readiness-review
3
- description: "Parallel multi-agent readiness gate — fan blind reviewers across performance, security, UI/UX, and test coverage, each grounding findings in real code/logs/live data, then reconcile into one deduplicated, severity-ranked punch-list. Reports only; never fixes, merges, or deploys."
3
+ description: "Parallel multi-agent readiness gate — fan blind reviewers across performance, security, UI/UX, test coverage, and simplicity, each grounding findings in real code/logs/live data, then reconcile into one deduplicated, severity-ranked punch-list. Reports only; never fixes, merges, or deploys."
4
4
  ---
5
5
 
6
6
  # /production-readiness-review
@@ -20,11 +20,12 @@ Pure routing over existing skills and agents. Adds no new code.
20
20
  ## Behavior
21
21
 
22
22
  1. **Scope** — establish ground truth: the diff under review and which changes are recent (`git diff`; `reconcile` fallback for branch/base state). Recent changes get extra scrutiny because they are the likeliest source of self-inflicted defects.
23
- 2. **Fan out** — `superpowers:dispatching-parallel-agents` launches four reviewers, each blind to the others. Every reviewer is instructed to ground each finding in real code, logs, or live queries, and never to assume or fabricate state:
23
+ 2. **Fan out** — `superpowers:dispatching-parallel-agents` launches five reviewers, each blind to the others. Every reviewer is instructed to ground each finding in real code, logs, or live queries, and never to assume or fabricate state:
24
24
  - **Performance & bundle-size** — hot paths, N+1 queries, unbounded work, regressions.
25
25
  - **Security & data-access** (`security-auditor`) — authn/authz, input handling, injection, secret exposure, unsafe data access.
26
26
  - **UI/UX correctness** — verified live with Playwright when the MCP is available, else static review of the changed surface.
27
27
  - **Test coverage & flaky/stale mocks** (`test-engineer`) — uncovered branches, stale mocks, timing-flaky tests.
28
+ - **Simplicity & over-engineering** (`simplicity-review`) — code that could reuse an existing file, a stdlib or native feature, or fewer lines; reports trim opportunities via the reuse ladder and never flags input validation, data-loss handling, security, or accessibility.
28
29
  3. **Reconcile** — a final pass dedupes findings across reviewers, ranks each CRITICAL / HIGH / MEDIUM / LOW by severity and confidence, and explicitly flags any defect introduced by the changes under review.
29
30
  4. **Present** — emit the consolidated punch-list, severity-ranked, with file references. **Stop.**
30
31
 
@@ -42,7 +43,7 @@ Pure routing over existing skills and agents. Adds no new code.
42
43
 
43
44
  ## Composition
44
45
 
45
- Routes through: `reconcile` (scope/ground truth) → `superpowers:dispatching-parallel-agents` (fan-out) → the `security-auditor` and `test-engineer` agents (two of the four dimensions) → a reconciliation pass that ranks and dedupes. Each step falls back to its inline behavior when the preferred skill or agent is not installed.
46
+ Routes through: `reconcile` (scope/ground truth) → `superpowers:dispatching-parallel-agents` (fan-out) → the `security-auditor` and `test-engineer` agents and the `simplicity-review` skill (three of the five dimensions) → a reconciliation pass that ranks and dedupes. Each step falls back to its inline behavior when the preferred skill or agent is not installed.
46
47
 
47
48
  ## Example
48
49
 
@@ -50,4 +51,4 @@ Routes through: `reconcile` (scope/ground truth) → `superpowers:dispatching-pa
50
51
  /production-readiness-review #246
51
52
  ```
52
53
 
53
- Scopes PR #246's diff, fans four blind reviewers across performance, security, UI/UX, and test coverage, then returns one deduplicated severity-ranked punch-list — flagging anything the PR's own changes introduced — and stops for you to prioritize.
54
+ Scopes PR #246's diff, fans five blind reviewers across performance, security, UI/UX, test coverage, and simplicity, then returns one deduplicated severity-ranked punch-list — flagging anything the PR's own changes introduced — and stops for you to prioritize.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: simplicity-review
3
+ description: Review the current diff for over-engineering — flag code that could reuse an existing file, a stdlib or native feature, or fewer lines — and report GO/TRIM findings without touching code. Enforces Law 4 (Verify Before Reporting).
4
+ ---
5
+
6
+ # /simplicity-review — Judge the Diff Before You Ship It
7
+
8
+ Read the current change like the laziest senior dev in the room: could this have been smaller? Passing tests prove correctness, not minimality. Backed by the `simplicity-review` skill.
9
+
10
+ ## What it does
11
+
12
+ Takes the working-tree diff (vs HEAD by default; accepts an optional commit range or file list), reads each changed block, and walks a fixed reuse ladder:
13
+
14
+ ```
15
+ 1. Does this need to exist? -> skip it (YAGNI)
16
+ 2. Already in this codebase? -> reuse it
17
+ 3. Stdlib does it? -> use it
18
+ 4. Native platform feature? -> use it
19
+ 5. Installed dependency? -> use it
20
+ 6. One line? -> one line
21
+ 7. Only then: the minimum that works
22
+ ```
23
+
24
+ It reports `file:line`, what is over-built, the specific simpler path, and closes with `GO` (already minimal) or `TRIM` (findings to apply). It does not edit code.
25
+
26
+ ## Default skeptical
27
+
28
+ A finding is a hypothesis. Read the surrounding code and prove the simpler path exists and preserves behavior before asserting it; a wrong trim is worse than the over-build. Never flag input validation, data-loss-preventing error handling, security, or accessibility — lazy, not negligent.
29
+
30
+ ## Pairs with
31
+
32
+ - **`simplicity-review`** skill — the discipline this command runs.
33
+ - **`proceed-with-the-recommendation`** — apply the trims under the 7 Laws.
34
+ - **`verification-loop`** — the ladder to re-run on whatever you trim.
35
+ - **`production-readiness-review`** — the sibling diff review for performance, security, UI, and test coverage.
@@ -40,8 +40,8 @@ The observation hook appends one row per tool call to
40
40
  `<project-hash>` from the current repo, or check `~/.claude/instincts/global/`).
41
41
 
42
42
  - If it exists and has at least one row — capture is recording. Record `observe: ✓`.
43
- - If it is missing or empty record `observe: ✗ (observation hook not recording
44
- on Windows confirm Git Bash is installed before WSL Bash on PATH, then re-run the installer)`.
43
+ - If it is missing or empty, record `observe: ✗ (observation hook not recording; re-run
44
+ the installer to migrate legacy Bash hook rows to the Node observer)`.
45
45
 
46
46
  ## Report
47
47
 
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from "node:child_process";
3
+ import { createHash } from "node:crypto";
4
+ import { readFileSync, readdirSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { resolveHomeDir } from "../lib/resolve-home-dir.mjs";
7
+ function read(path) {
8
+ try {
9
+ return readFileSync(path, "utf8");
10
+ }
11
+ catch {
12
+ return "";
13
+ }
14
+ }
15
+ function eventFromStdin() {
16
+ const raw = read(0);
17
+ if (!raw)
18
+ return null;
19
+ try {
20
+ const payload = JSON.parse(raw);
21
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
22
+ return null;
23
+ const event = payload.hook_event_name ?? payload.hook_type ?? payload.event_type;
24
+ return event === "SessionStart" || event === "SessionEnd" ? event : "unknown";
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ function projectRoot() {
31
+ if (process.env.CLAUDE_PROJECT_DIR)
32
+ return process.env.CLAUDE_PROJECT_DIR;
33
+ try {
34
+ return execFileSync("git", ["rev-parse", "--show-toplevel"], {
35
+ encoding: "utf8",
36
+ stdio: ["ignore", "pipe", "ignore"],
37
+ }).trim() || "global";
38
+ }
39
+ catch {
40
+ return "global";
41
+ }
42
+ }
43
+ function yamlFiles(dir) {
44
+ try {
45
+ return readdirSync(dir)
46
+ .filter((name) => name.endsWith(".yaml"))
47
+ .map((name) => join(dir, name));
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ function main() {
54
+ const event = eventFromStdin();
55
+ if (event === null)
56
+ return;
57
+ if (event === "SessionEnd") {
58
+ process.stderr.write("[continuous-improvement] Session ending. Run /continuous-improvement to reflect and capture learnings.\n");
59
+ return;
60
+ }
61
+ const home = resolveHomeDir();
62
+ if (!home)
63
+ return;
64
+ const instinctsRoot = join(home, ".claude", "instincts");
65
+ const hash = createHash("sha256").update(projectRoot()).digest("hex").slice(0, 12);
66
+ const projectDir = join(instinctsRoot, hash);
67
+ const files = [...yamlFiles(projectDir), ...yamlFiles(join(instinctsRoot, "global"))];
68
+ const observations = read(join(projectDir, "observations.jsonl")).split(/\r?\n/).filter(Boolean).length;
69
+ let level = observations >= 20 || files.length > 0 ? "ANALYZE" : "CAPTURE";
70
+ for (const file of files) {
71
+ const value = Number(read(file).match(/^confidence:\s*([0-9]*\.?[0-9]+)/m)?.[1]);
72
+ if (Number.isFinite(value) && value >= 0.7) {
73
+ level = "AUTO-APPLY";
74
+ break;
75
+ }
76
+ if (Number.isFinite(value) && value >= 0.5)
77
+ level = "SUGGEST";
78
+ }
79
+ process.stderr.write(`[continuous-improvement] Level: ${level} | Observations: ${observations} | Instincts: ${files.length}\n`);
80
+ }
81
+ try {
82
+ main();
83
+ }
84
+ catch {
85
+ }
@@ -26,7 +26,7 @@ const KEYWORDS = [
26
26
  "transcript-linter",
27
27
  ];
28
28
  const CLAUDE_PLUGIN_CATEGORY = "productivity";
29
- const SHARED_PLUGIN_DESCRIPTION = "The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 27 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.";
29
+ const SHARED_PLUGIN_DESCRIPTION = "The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 28 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.";
30
30
  // Four vendored upstream companions registered alongside the CI plugin.
31
31
  // Each entry points at a pinned-SHA snapshot under third-party/<name>/.
32
32
  // See third-party/MANIFEST.md for refresh recipes and per-snapshot
@@ -457,76 +457,74 @@ export function getClaudePluginManifest() {
457
457
  };
458
458
  }
459
459
  export function getPluginHooksConfig() {
460
+ // Cold Node startup on loaded Windows hosts has exceeded five seconds.
461
+ const hookTimeoutSeconds = 30;
460
462
  const gateguardCommand = {
461
463
  type: "command",
462
464
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/gateguard.mjs\"",
463
- timeout: 5,
465
+ timeout: hookTimeoutSeconds,
464
466
  };
465
467
  const companionPreferenceCommand = {
466
468
  type: "command",
467
469
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/companion-preference.mjs\"",
468
- timeout: 5,
470
+ timeout: hookTimeoutSeconds,
469
471
  };
470
472
  const hookPackCommand = {
471
473
  type: "command",
472
474
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/hook-pack.mjs\"",
473
- timeout: 5,
475
+ timeout: hookTimeoutSeconds,
474
476
  };
475
477
  const observeCommand = {
476
478
  type: "command",
477
- command: "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/observe.sh\"",
478
- timeout: 5,
479
+ command: "node \"${CLAUDE_PLUGIN_ROOT}/bin/observe.mjs\"",
480
+ timeout: hookTimeoutSeconds,
479
481
  };
480
482
  const sessionCommand = {
481
483
  type: "command",
482
- command: "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session.sh\"",
483
- timeout: 5,
484
+ command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session.mjs\"",
485
+ timeout: hookTimeoutSeconds,
484
486
  };
485
487
  const threeSectionCloseCommand = {
486
488
  type: "command",
487
489
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/three-section-close.mjs\"",
488
- timeout: 5,
490
+ timeout: hookTimeoutSeconds,
489
491
  };
490
492
  const goalDriftStopCommand = {
491
493
  type: "command",
492
494
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/goal-drift-stop.mjs\"",
493
- timeout: 5,
495
+ timeout: hookTimeoutSeconds,
494
496
  };
495
497
  const workflowDistillCommand = {
496
498
  type: "command",
497
499
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/workflow-distill.mjs\"",
498
- timeout: 5,
500
+ timeout: hookTimeoutSeconds,
499
501
  };
500
502
  const typecheckStopCommand = {
501
503
  type: "command",
502
504
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/typecheck-stop.mjs\"",
503
- // Longer than the 5s hooks: tsc is slower. Opt-in via CLAUDE_TYPECHECK_GATE
504
- // (off by default) and near-zero cost when off / no TS file changed; on an
505
- // internal timeout it fails open (allow) rather than blocking.
506
- timeout: 30,
505
+ timeout: hookTimeoutSeconds,
507
506
  };
508
507
  const queryCostNudgeCommand = {
509
508
  type: "command",
510
509
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/query-cost-nudge.mjs\"",
511
- timeout: 5,
510
+ timeout: hookTimeoutSeconds,
512
511
  };
513
512
  const routePromptCommand = {
514
513
  type: "command",
515
514
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/route-prompt.mjs\"",
516
- timeout: 5,
515
+ timeout: hookTimeoutSeconds,
517
516
  };
518
517
  const recallBriefingCommand = {
519
518
  type: "command",
520
519
  command: "node \"${CLAUDE_PLUGIN_ROOT}/hooks/recall-briefing.mjs\"",
521
- timeout: 5,
520
+ timeout: hookTimeoutSeconds,
522
521
  };
523
522
  return {
524
- description: "Gateguard fact-forcing PreToolUse, companion-preference enforcement, observation, session lifecycle, 3-section-close discipline, goal-drift Stop gate, opt-in workflow-distill Stop nudge, opt-in typecheck Stop gate, opt-in query-cost Stop nudge, and UserPromptSubmit lazy-routing plus opt-in proactive recall-briefing hooks for continuous-improvement.",
525
523
  hooks: {
526
524
  // gateguard runs FIRST on PreToolUse so its block decision short-circuits
527
525
  // before companion-preference sees the call. companion-preference runs
528
526
  // second on Skill tool calls; it is a no-op under ci-first (the default)
529
- // and never blocks under companions-first. observe.sh only runs on
527
+ // and never blocks under companions-first. The observer only runs on
530
528
  // PostToolUse: gateguard-blocked calls are intentionally not observed so
531
529
  // PreToolUse stays at two subprocesses on the hot path. route-prompt
532
530
  // fires on UserPromptSubmit and emits a system-reminder when a prompt
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # continuous-improvement
2
2
 
3
- > The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 27 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.
3
+ > The persistent-memory and runtime-discipline layer for Claude Code. It remembers the corrections you already gave, grounds every edit in real facts before it lands, and — through the Mulahazah engine — turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Built on the 7 Laws of AI Agent Discipline (research, plan, verify, reflect, learn) and shipped as 28 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts.
4
4
 
5
5
  ## What This Is
6
6
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "continuous-improvement",
3
- "version": "3.20.4",
4
- "description": "Claude Code that gets sharper every session: the persistent-memory and runtime-discipline layer built on the 7 Laws of AI Agent Discipline. It grounds every edit in real facts before it lands and, through the Mulahazah engine, turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Shipped as 27 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts. Beginner: one /plugin install command. Expert: adds MCP tools and session hooks.",
3
+ "version": "3.21.0",
4
+ "description": "Claude Code that gets sharper every session: the persistent-memory and runtime-discipline layer built on the 7 Laws of AI Agent Discipline. It grounds every edit in real facts before it lands and, through the Mulahazah engine, turns each fix into a reusable instinct, so a lesson learned once is applied automatically next time with no re-teaching. Shipped as 28 bundled skills, instinct-aware hooks, an MCP toolset for recall and reflection, and a GitHub Action transcript linter that feeds real work history back into sharper instincts. Beginner: one /plugin install command. Expert: adds MCP tools and session hooks.",
5
5
  "keywords": [
6
6
  "claude-code",
7
7
  "claude-code-plugin",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "continuous-improvement",
3
- "version": "3.20.4",
3
+ "version": "3.21.0",
4
4
  "mode": "beginner",
5
5
  "description": "Beginner mode: see what your agent learned, list its instincts, and request a session reflection. Bundles three grounding skills (gateguard, tdd-workflow, verification-loop) so research, memory, tests, and verification happen by default — every edit starts from facts, not guesses.",
6
6
  "tools": [