continuous-improvement 3.20.0 → 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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +10 -0
- package/QUICKSTART.md +1 -1
- package/README.md +7 -6
- package/bin/check-landing-version.mjs +63 -0
- package/bin/check-scripts-citation-drift.mjs +61 -13
- package/bin/generate-plugin-manifests.mjs +2 -0
- package/bin/install.mjs +29 -60
- package/commands/production-readiness-review.md +5 -4
- package/commands/simplicity-review.md +35 -0
- package/commands/verify-install.md +2 -2
- package/hooks/gateguard.mjs +22 -3
- package/hooks/query-cost-nudge.mjs +1 -0
- package/hooks/session.mjs +85 -0
- package/hooks/typecheck-stop.mjs +2 -1
- package/lib/plugin-metadata.mjs +18 -20
- package/llms.txt +1 -1
- package/package.json +6 -4
- package/plugins/beginner.json +1 -1
- package/plugins/continuous-improvement/.claude-plugin/marketplace.json +2 -2
- package/plugins/continuous-improvement/.claude-plugin/plugin.json +2 -2
- package/plugins/continuous-improvement/README.md +1 -0
- package/plugins/continuous-improvement/commands/production-readiness-review.md +5 -4
- package/plugins/continuous-improvement/commands/simplicity-review.md +35 -0
- package/plugins/continuous-improvement/commands/verify-install.md +2 -2
- package/plugins/continuous-improvement/hooks/gateguard.mjs +22 -3
- package/plugins/continuous-improvement/hooks/hooks.json +15 -16
- package/plugins/continuous-improvement/hooks/query-cost-nudge.mjs +1 -0
- package/plugins/continuous-improvement/hooks/session.mjs +85 -0
- package/plugins/continuous-improvement/hooks/typecheck-stop.mjs +2 -1
- package/plugins/continuous-improvement/lib/plugin-metadata.mjs +18 -20
- package/plugins/continuous-improvement/scripts/README.md +33 -0
- package/plugins/continuous-improvement/scripts/detect-deploy-target.sh +66 -0
- package/plugins/continuous-improvement/scripts/get-deployed-sha.sh +113 -0
- package/plugins/continuous-improvement/scripts/git-state-snapshot.sh +48 -0
- package/plugins/continuous-improvement/scripts/resolve-verify-ladder.mjs +241 -0
- package/plugins/continuous-improvement/scripts/route-recommendation.mjs +178 -0
- package/plugins/continuous-improvement/scripts/route-recommendation.routes.json +213 -0
- package/plugins/continuous-improvement/scripts/run-synthetic.mjs +298 -0
- package/plugins/continuous-improvement/scripts/scan-past-mistakes.mjs +285 -0
- package/plugins/continuous-improvement/skills/README.md +1 -0
- package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +2 -2
- package/plugins/continuous-improvement/skills/gateguard/SKILL.md +2 -2
- package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +3 -2
- package/plugins/continuous-improvement/skills/reconcile/SKILL.md +1 -1
- package/plugins/continuous-improvement/skills/simplicity-review/SKILL.md +80 -0
- package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +5 -5
- package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +1 -1
- package/plugins/continuous-improvement/skills/worktree-safety/SKILL.md +1 -1
- package/plugins/expert.json +1 -1
- package/scripts/README.md +33 -0
- package/scripts/detect-deploy-target.sh +66 -0
- package/scripts/get-deployed-sha.sh +113 -0
- package/scripts/git-state-snapshot.sh +48 -0
- package/scripts/resolve-verify-ladder.mjs +241 -0
- package/scripts/route-recommendation.mjs +178 -0
- package/scripts/route-recommendation.routes.json +213 -0
- package/scripts/run-synthetic.mjs +298 -0
- package/scripts/scan-past-mistakes.mjs +285 -0
- package/skills/deploy-receipt.md +2 -2
- package/skills/gateguard.md +2 -2
- package/skills/proceed-with-the-recommendation.md +3 -2
- package/skills/reconcile.md +1 -1
- package/skills/simplicity-review.md +80 -0
- package/skills/verification-loop.md +5 -5
- package/skills/workspace-surface-audit.md +1 -1
- package/skills/worktree-safety.md +1 -1
package/hooks/gateguard.mjs
CHANGED
|
@@ -210,6 +210,16 @@ function buildMutatingFileReason(toolName, filePaths, stateFilePath) {
|
|
|
210
210
|
" `_gateguard_facts_presented: true`; Claude Code's strict schema rejects that, so use A or B.)",
|
|
211
211
|
].join("\n");
|
|
212
212
|
}
|
|
213
|
+
function isGitBraceSelector(value) {
|
|
214
|
+
const selector = value.trim();
|
|
215
|
+
if (/^(?:u|upstream|push|-?\d+)$/i.test(selector))
|
|
216
|
+
return true;
|
|
217
|
+
if (/^(?:now|today|yesterday|tomorrow|noon|midnight|tea)$/i.test(selector))
|
|
218
|
+
return true;
|
|
219
|
+
if (/^\d{4}-\d{1,2}-\d{1,2}(?:[ T].*)?$/.test(selector))
|
|
220
|
+
return true;
|
|
221
|
+
return !selector.startsWith("#") && /(?:^|[.\s])ago$/i.test(selector);
|
|
222
|
+
}
|
|
213
223
|
function findUnquotedBraceRef(command) {
|
|
214
224
|
let quote = null;
|
|
215
225
|
for (let i = 0; i < command.length; i++) {
|
|
@@ -224,17 +234,26 @@ function findUnquotedBraceRef(command) {
|
|
|
224
234
|
continue;
|
|
225
235
|
}
|
|
226
236
|
if (ch === "@" && command[i + 1] === "{") {
|
|
237
|
+
const braceEnd = command.indexOf("}", i + 2);
|
|
238
|
+
if (braceEnd === -1)
|
|
239
|
+
continue;
|
|
240
|
+
const selector = command.slice(i + 2, braceEnd);
|
|
241
|
+
// Deny only recognized Git selector grammar. PowerShell hashtables can
|
|
242
|
+
// contain comments, quoted braces, or arbitrary key expressions.
|
|
243
|
+
if (!isGitBraceSelector(selector)) {
|
|
244
|
+
i = braceEnd;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
227
247
|
// Expand to the whitespace-delimited word that carries this @{ ref, then
|
|
228
248
|
// single-quote that whole word in the suggested fix.
|
|
229
249
|
let wordStart = i;
|
|
230
250
|
while (wordStart > 0 && !/\s/.test(command[wordStart - 1]))
|
|
231
251
|
wordStart--;
|
|
232
|
-
let wordEnd =
|
|
252
|
+
let wordEnd = braceEnd + 1;
|
|
233
253
|
while (wordEnd < command.length && !/\s/.test(command[wordEnd]))
|
|
234
254
|
wordEnd++;
|
|
235
255
|
const word = command.slice(wordStart, wordEnd);
|
|
236
|
-
const
|
|
237
|
-
const ref = braceEnd === -1 ? command.slice(i, wordEnd) : command.slice(i, braceEnd + 1);
|
|
256
|
+
const ref = command.slice(i, braceEnd + 1);
|
|
238
257
|
const fixed = `${command.slice(0, wordStart)}'${word}'${command.slice(wordEnd)}`;
|
|
239
258
|
return { ref, fixed };
|
|
240
259
|
}
|
|
@@ -61,6 +61,7 @@ function collectChangedFiles(root) {
|
|
|
61
61
|
return [
|
|
62
62
|
...parseChangedFiles(run(["diff", "--name-only", "--diff-filter=ACMR"])),
|
|
63
63
|
...parseChangedFiles(run(["diff", "--cached", "--name-only", "--diff-filter=ACMR"])),
|
|
64
|
+
...parseChangedFiles(run(["ls-files", "--others", "--exclude-standard"])),
|
|
64
65
|
];
|
|
65
66
|
}
|
|
66
67
|
// Marker key: the sanitized session_id when present (the normal case), else a
|
|
@@ -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
|
+
}
|
package/hooks/typecheck-stop.mjs
CHANGED
|
@@ -51,7 +51,8 @@ function collectChangedFiles(root) {
|
|
|
51
51
|
};
|
|
52
52
|
const unstaged = run(["diff", "--name-only", "--diff-filter=ACMR"]);
|
|
53
53
|
const staged = run(["diff", "--cached", "--name-only", "--diff-filter=ACMR"]);
|
|
54
|
-
|
|
54
|
+
const untracked = run(["ls-files", "--others", "--exclude-standard"]);
|
|
55
|
+
return [...parseChangedFiles(unstaged), ...parseChangedFiles(staged), ...parseChangedFiles(untracked)];
|
|
55
56
|
}
|
|
56
57
|
function hasNpmTypecheckScript(root) {
|
|
57
58
|
try {
|
package/lib/plugin-metadata.mjs
CHANGED
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
475
|
+
timeout: hookTimeoutSeconds,
|
|
474
476
|
};
|
|
475
477
|
const observeCommand = {
|
|
476
478
|
type: "command",
|
|
477
|
-
command: "
|
|
478
|
-
timeout:
|
|
479
|
+
command: "node \"${CLAUDE_PLUGIN_ROOT}/bin/observe.mjs\"",
|
|
480
|
+
timeout: hookTimeoutSeconds,
|
|
479
481
|
};
|
|
480
482
|
const sessionCommand = {
|
|
481
483
|
type: "command",
|
|
482
|
-
command: "
|
|
483
|
-
timeout:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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",
|
|
@@ -56,10 +56,11 @@
|
|
|
56
56
|
"verify:routing-targets": "node bin/check-routing-targets.mjs",
|
|
57
57
|
"verify:doc-runtime-claims": "node bin/check-doc-runtime-claims.mjs",
|
|
58
58
|
"verify:test-imports-only": "node bin/check-test-imports-only.mjs",
|
|
59
|
-
"verify:
|
|
59
|
+
"verify:landing-version": "node bin/check-landing-version.mjs",
|
|
60
|
+
"verify:scripts-citation-drift": "node bin/check-scripts-citation-drift.mjs && node bin/check-scripts-citation-drift.mjs plugins/continuous-improvement",
|
|
60
61
|
"verify:third-party-shape": "node bin/check-third-party-shape.mjs",
|
|
61
62
|
"verify:tool-count": "node bin/check-tool-count.mjs",
|
|
62
|
-
"verify:all": "npm run verify:skill-mirror && npm run verify:skill-tiers && npm run verify:skill-law-tag && npm run verify:skill-count && npm run verify:skill-count-prose && npm run verify:command-count && npm run verify:docs-substrings && npm run verify:everything-mirror && npm run verify:routing-targets && npm run verify:doc-runtime-claims && npm run verify:test-imports-only && npm run verify:scripts-citation-drift && npm run verify:third-party-shape && npm run verify:tool-count && npm run typecheck"
|
|
63
|
+
"verify:all": "npm run verify:skill-mirror && npm run verify:skill-tiers && npm run verify:skill-law-tag && npm run verify:skill-count && npm run verify:skill-count-prose && npm run verify:command-count && npm run verify:docs-substrings && npm run verify:everything-mirror && npm run verify:routing-targets && npm run verify:doc-runtime-claims && npm run verify:test-imports-only && npm run verify:landing-version && npm run verify:scripts-citation-drift && npm run verify:third-party-shape && npm run verify:tool-count && npm run typecheck"
|
|
63
64
|
},
|
|
64
65
|
"files": [
|
|
65
66
|
".claude-plugin/",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
"hooks/",
|
|
75
76
|
"commands/",
|
|
76
77
|
"skills/",
|
|
78
|
+
"scripts/",
|
|
77
79
|
"templates/",
|
|
78
80
|
"plugins/",
|
|
79
81
|
"instinct-packs/"
|
package/plugins/beginner.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "continuous-improvement",
|
|
3
|
-
"version": "3.
|
|
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": [
|
|
@@ -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
|
|
11
|
-
"version": "3.
|
|
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": "./",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "naimkatiman"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "continuous-improvement",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"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
|
|
3
|
+
"version": "3.21.0",
|
|
4
|
+
"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.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "naimkatiman",
|
|
7
7
|
"url": "https://github.com/naimkatiman"
|
|
@@ -10,6 +10,7 @@ Included surfaces:
|
|
|
10
10
|
- `commands/`
|
|
11
11
|
- `agents/` — `code-reviewer`, `security-auditor`, `test-engineer` personas (auto-discovered Claude Code subagents; pattern from addy/agent-skills)
|
|
12
12
|
- `hooks/`
|
|
13
|
+
- `scripts/`
|
|
13
14
|
- `bin/mcp-server.mjs`
|
|
14
15
|
- `bin/observe.mjs`
|
|
15
16
|
- `bin/backfill.mjs`
|
|
@@ -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,
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
44
|
-
|
|
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
|
|
|
@@ -210,6 +210,16 @@ function buildMutatingFileReason(toolName, filePaths, stateFilePath) {
|
|
|
210
210
|
" `_gateguard_facts_presented: true`; Claude Code's strict schema rejects that, so use A or B.)",
|
|
211
211
|
].join("\n");
|
|
212
212
|
}
|
|
213
|
+
function isGitBraceSelector(value) {
|
|
214
|
+
const selector = value.trim();
|
|
215
|
+
if (/^(?:u|upstream|push|-?\d+)$/i.test(selector))
|
|
216
|
+
return true;
|
|
217
|
+
if (/^(?:now|today|yesterday|tomorrow|noon|midnight|tea)$/i.test(selector))
|
|
218
|
+
return true;
|
|
219
|
+
if (/^\d{4}-\d{1,2}-\d{1,2}(?:[ T].*)?$/.test(selector))
|
|
220
|
+
return true;
|
|
221
|
+
return !selector.startsWith("#") && /(?:^|[.\s])ago$/i.test(selector);
|
|
222
|
+
}
|
|
213
223
|
function findUnquotedBraceRef(command) {
|
|
214
224
|
let quote = null;
|
|
215
225
|
for (let i = 0; i < command.length; i++) {
|
|
@@ -224,17 +234,26 @@ function findUnquotedBraceRef(command) {
|
|
|
224
234
|
continue;
|
|
225
235
|
}
|
|
226
236
|
if (ch === "@" && command[i + 1] === "{") {
|
|
237
|
+
const braceEnd = command.indexOf("}", i + 2);
|
|
238
|
+
if (braceEnd === -1)
|
|
239
|
+
continue;
|
|
240
|
+
const selector = command.slice(i + 2, braceEnd);
|
|
241
|
+
// Deny only recognized Git selector grammar. PowerShell hashtables can
|
|
242
|
+
// contain comments, quoted braces, or arbitrary key expressions.
|
|
243
|
+
if (!isGitBraceSelector(selector)) {
|
|
244
|
+
i = braceEnd;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
227
247
|
// Expand to the whitespace-delimited word that carries this @{ ref, then
|
|
228
248
|
// single-quote that whole word in the suggested fix.
|
|
229
249
|
let wordStart = i;
|
|
230
250
|
while (wordStart > 0 && !/\s/.test(command[wordStart - 1]))
|
|
231
251
|
wordStart--;
|
|
232
|
-
let wordEnd =
|
|
252
|
+
let wordEnd = braceEnd + 1;
|
|
233
253
|
while (wordEnd < command.length && !/\s/.test(command[wordEnd]))
|
|
234
254
|
wordEnd++;
|
|
235
255
|
const word = command.slice(wordStart, wordEnd);
|
|
236
|
-
const
|
|
237
|
-
const ref = braceEnd === -1 ? command.slice(i, wordEnd) : command.slice(i, braceEnd + 1);
|
|
256
|
+
const ref = command.slice(i, braceEnd + 1);
|
|
238
257
|
const fixed = `${command.slice(0, wordStart)}'${word}'${command.slice(wordEnd)}`;
|
|
239
258
|
return { ref, fixed };
|
|
240
259
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"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.",
|
|
3
2
|
"hooks": {
|
|
4
3
|
"PreToolUse": [
|
|
5
4
|
{
|
|
@@ -7,12 +6,12 @@
|
|
|
7
6
|
{
|
|
8
7
|
"type": "command",
|
|
9
8
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/gateguard.mjs\"",
|
|
10
|
-
"timeout":
|
|
9
|
+
"timeout": 30
|
|
11
10
|
},
|
|
12
11
|
{
|
|
13
12
|
"type": "command",
|
|
14
13
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/companion-preference.mjs\"",
|
|
15
|
-
"timeout":
|
|
14
|
+
"timeout": 30
|
|
16
15
|
}
|
|
17
16
|
]
|
|
18
17
|
},
|
|
@@ -22,7 +21,7 @@
|
|
|
22
21
|
{
|
|
23
22
|
"type": "command",
|
|
24
23
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/hook-pack.mjs\"",
|
|
25
|
-
"timeout":
|
|
24
|
+
"timeout": 30
|
|
26
25
|
}
|
|
27
26
|
]
|
|
28
27
|
}
|
|
@@ -32,8 +31,8 @@
|
|
|
32
31
|
"hooks": [
|
|
33
32
|
{
|
|
34
33
|
"type": "command",
|
|
35
|
-
"command": "
|
|
36
|
-
"timeout":
|
|
34
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/bin/observe.mjs\"",
|
|
35
|
+
"timeout": 30
|
|
37
36
|
}
|
|
38
37
|
]
|
|
39
38
|
}
|
|
@@ -44,12 +43,12 @@
|
|
|
44
43
|
{
|
|
45
44
|
"type": "command",
|
|
46
45
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/route-prompt.mjs\"",
|
|
47
|
-
"timeout":
|
|
46
|
+
"timeout": 30
|
|
48
47
|
},
|
|
49
48
|
{
|
|
50
49
|
"type": "command",
|
|
51
50
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/recall-briefing.mjs\"",
|
|
52
|
-
"timeout":
|
|
51
|
+
"timeout": 30
|
|
53
52
|
}
|
|
54
53
|
]
|
|
55
54
|
}
|
|
@@ -59,8 +58,8 @@
|
|
|
59
58
|
"hooks": [
|
|
60
59
|
{
|
|
61
60
|
"type": "command",
|
|
62
|
-
"command": "
|
|
63
|
-
"timeout":
|
|
61
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session.mjs\"",
|
|
62
|
+
"timeout": 30
|
|
64
63
|
}
|
|
65
64
|
]
|
|
66
65
|
}
|
|
@@ -70,8 +69,8 @@
|
|
|
70
69
|
"hooks": [
|
|
71
70
|
{
|
|
72
71
|
"type": "command",
|
|
73
|
-
"command": "
|
|
74
|
-
"timeout":
|
|
72
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session.mjs\"",
|
|
73
|
+
"timeout": 30
|
|
75
74
|
}
|
|
76
75
|
]
|
|
77
76
|
}
|
|
@@ -82,17 +81,17 @@
|
|
|
82
81
|
{
|
|
83
82
|
"type": "command",
|
|
84
83
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/three-section-close.mjs\"",
|
|
85
|
-
"timeout":
|
|
84
|
+
"timeout": 30
|
|
86
85
|
},
|
|
87
86
|
{
|
|
88
87
|
"type": "command",
|
|
89
88
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/goal-drift-stop.mjs\"",
|
|
90
|
-
"timeout":
|
|
89
|
+
"timeout": 30
|
|
91
90
|
},
|
|
92
91
|
{
|
|
93
92
|
"type": "command",
|
|
94
93
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/workflow-distill.mjs\"",
|
|
95
|
-
"timeout":
|
|
94
|
+
"timeout": 30
|
|
96
95
|
},
|
|
97
96
|
{
|
|
98
97
|
"type": "command",
|
|
@@ -102,7 +101,7 @@
|
|
|
102
101
|
{
|
|
103
102
|
"type": "command",
|
|
104
103
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/query-cost-nudge.mjs\"",
|
|
105
|
-
"timeout":
|
|
104
|
+
"timeout": 30
|
|
106
105
|
}
|
|
107
106
|
]
|
|
108
107
|
}
|
|
@@ -61,6 +61,7 @@ function collectChangedFiles(root) {
|
|
|
61
61
|
return [
|
|
62
62
|
...parseChangedFiles(run(["diff", "--name-only", "--diff-filter=ACMR"])),
|
|
63
63
|
...parseChangedFiles(run(["diff", "--cached", "--name-only", "--diff-filter=ACMR"])),
|
|
64
|
+
...parseChangedFiles(run(["ls-files", "--others", "--exclude-standard"])),
|
|
64
65
|
];
|
|
65
66
|
}
|
|
66
67
|
// Marker key: the sanitized session_id when present (the normal case), else a
|