@kiwidata/grimoire 0.1.3 → 0.1.5
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/AGENTS.md +56 -4
- package/README.md +107 -59
- package/dist/cli/index.js +7 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/configure.d.ts +3 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +19 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/core/check.d.ts.map +1 -1
- package/dist/core/check.js +165 -111
- package/dist/core/check.js.map +1 -1
- package/dist/core/ci.d.ts.map +1 -1
- package/dist/core/ci.js +50 -69
- package/dist/core/ci.js.map +1 -1
- package/dist/core/configure.d.ts +14 -0
- package/dist/core/configure.d.ts.map +1 -0
- package/dist/core/configure.js +434 -0
- package/dist/core/configure.js.map +1 -0
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +153 -26
- package/dist/core/detect.js.map +1 -1
- package/dist/core/diff.d.ts.map +1 -1
- package/dist/core/diff.js +62 -93
- package/dist/core/diff.js.map +1 -1
- package/dist/core/doc-style.d.ts +0 -4
- package/dist/core/doc-style.d.ts.map +1 -1
- package/dist/core/doc-style.js +103 -22
- package/dist/core/doc-style.js.map +1 -1
- package/dist/core/docs.js +202 -170
- package/dist/core/docs.js.map +1 -1
- package/dist/core/health.d.ts +6 -0
- package/dist/core/health.d.ts.map +1 -1
- package/dist/core/health.js +133 -96
- package/dist/core/health.js.map +1 -1
- package/dist/core/hooks.d.ts +0 -3
- package/dist/core/hooks.d.ts.map +1 -1
- package/dist/core/hooks.js +11 -16
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/init.d.ts +2 -0
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +230 -406
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +55 -65
- package/dist/core/list.js.map +1 -1
- package/dist/core/risk-register.d.ts +17 -0
- package/dist/core/risk-register.d.ts.map +1 -0
- package/dist/core/risk-register.js +73 -0
- package/dist/core/risk-register.js.map +1 -0
- package/dist/core/shared-setup.d.ts +0 -40
- package/dist/core/shared-setup.d.ts.map +1 -1
- package/dist/core/shared-setup.js +92 -56
- package/dist/core/shared-setup.js.map +1 -1
- package/dist/core/status.d.ts.map +1 -1
- package/dist/core/status.js +42 -52
- package/dist/core/status.js.map +1 -1
- package/dist/core/test-quality.d.ts +0 -8
- package/dist/core/test-quality.d.ts.map +1 -1
- package/dist/core/test-quality.js +24 -30
- package/dist/core/test-quality.js.map +1 -1
- package/dist/core/trace.d.ts.map +1 -1
- package/dist/core/trace.js +67 -75
- package/dist/core/trace.js.map +1 -1
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +61 -11
- package/dist/core/update.js.map +1 -1
- package/dist/core/validate.d.ts +1 -4
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +126 -148
- package/dist/core/validate.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts +15 -5
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +63 -42
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/fs.d.ts +0 -12
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +0 -12
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -6
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +0 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/spawn.d.ts +0 -3
- package/dist/utils/spawn.d.ts.map +1 -1
- package/dist/utils/spawn.js +0 -3
- package/dist/utils/spawn.js.map +1 -1
- package/package.json +1 -1
- package/skills/grimoire-apply/SKILL.md +89 -25
- package/skills/grimoire-audit/SKILL.md +21 -1
- package/skills/grimoire-bug/SKILL.md +48 -9
- package/skills/grimoire-commit/SKILL.md +3 -2
- package/skills/grimoire-design/SKILL.md +259 -0
- package/skills/grimoire-design-consult/SKILL.md +200 -0
- package/skills/grimoire-discover/SKILL.md +139 -109
- package/skills/grimoire-draft/SKILL.md +131 -15
- package/skills/grimoire-plan/SKILL.md +119 -46
- package/skills/grimoire-pr/SKILL.md +7 -10
- package/skills/grimoire-pr-review/SKILL.md +46 -115
- package/skills/grimoire-precommit-review/SKILL.md +205 -0
- package/skills/grimoire-refactor/SKILL.md +6 -6
- package/skills/grimoire-review/SKILL.md +95 -156
- package/skills/grimoire-verify/SKILL.md +40 -7
- package/skills/grimoire-vuln-remediate/SKILL.md +107 -0
- package/skills/grimoire-vuln-triage/SKILL.md +109 -0
- package/skills/references/adversarial-personas.md +225 -0
- package/skills/references/brand-tokens-format.md +186 -0
- package/skills/references/code-quality.md +172 -0
- package/skills/references/container-scan-triage.md +102 -0
- package/skills/references/dependency-vuln-triage.md +236 -0
- package/skills/references/design-heuristics.md +138 -0
- package/skills/references/design-input-formats.md +190 -0
- package/skills/references/pattern-guard.md +180 -0
- package/skills/references/principles.md +82 -0
- package/skills/references/refactor-scan-categories.md +154 -2
- package/skills/references/review-personas.md +406 -0
- package/skills/references/security-compliance.md +22 -1
- package/skills/references/testing-contracts.md +1 -1
- package/skills/references/visual-fidelity.md +206 -0
- package/templates/accepted-risks.yml +47 -0
- package/templates/brand-tokens-example.json +13 -0
- package/templates/brand-voice-example.md +22 -0
- package/templates/constraints.md +25 -0
- package/templates/design-tool-setup-stub.md +59 -0
- package/dist/commands/archive.d.ts +0 -3
- package/dist/commands/archive.d.ts.map +0 -1
- package/dist/commands/archive.js +0 -22
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/log.d.ts +0 -3
- package/dist/commands/log.d.ts.map +0 -1
- package/dist/commands/log.js +0 -15
- package/dist/commands/log.js.map +0 -1
- package/dist/commands/map.d.ts +0 -3
- package/dist/commands/map.d.ts.map +0 -1
- package/dist/commands/map.js +0 -17
- package/dist/commands/map.js.map +0 -1
- package/dist/core/archive.d.ts +0 -9
- package/dist/core/archive.d.ts.map +0 -1
- package/dist/core/archive.js +0 -92
- package/dist/core/archive.js.map +0 -1
- package/dist/core/log.d.ts +0 -8
- package/dist/core/log.d.ts.map +0 -1
- package/dist/core/log.js +0 -150
- package/dist/core/log.js.map +0 -1
- package/dist/core/map.d.ts +0 -9
- package/dist/core/map.d.ts.map +0 -1
- package/dist/core/map.js +0 -302
- package/dist/core/map.js.map +0 -1
- package/templates/dupignore +0 -93
- package/templates/mapignore +0 -58
- package/templates/mapkeys +0 -65
package/dist/utils/config.js
CHANGED
|
@@ -3,6 +3,13 @@ import { join } from "node:path";
|
|
|
3
3
|
import { parse as parseYaml } from "yaml";
|
|
4
4
|
import { findProjectRoot } from "./paths.js";
|
|
5
5
|
export const CURRENT_CONFIG_VERSION = 2;
|
|
6
|
+
const PROJECT_SURFACES = [
|
|
7
|
+
"tui",
|
|
8
|
+
"web",
|
|
9
|
+
"mobile",
|
|
10
|
+
"api",
|
|
11
|
+
"mixed",
|
|
12
|
+
];
|
|
6
13
|
const DEFAULT_CHECKS = [
|
|
7
14
|
"lint",
|
|
8
15
|
"format",
|
|
@@ -21,7 +28,7 @@ const DEFAULT_LLM = {
|
|
|
21
28
|
coding: { command: "claude" },
|
|
22
29
|
};
|
|
23
30
|
const DEFAULT_CONFIG = {
|
|
24
|
-
version:
|
|
31
|
+
version: CURRENT_CONFIG_VERSION,
|
|
25
32
|
project: {
|
|
26
33
|
commit_style: "conventional",
|
|
27
34
|
},
|
|
@@ -48,29 +55,41 @@ function parseTools(raw) {
|
|
|
48
55
|
}
|
|
49
56
|
return tools;
|
|
50
57
|
}
|
|
58
|
+
function parseDesignTool(projectRaw) {
|
|
59
|
+
if (!projectRaw.design_tool || typeof projectRaw.design_tool !== "object")
|
|
60
|
+
return undefined;
|
|
61
|
+
const dt = projectRaw.design_tool;
|
|
62
|
+
return { name: String(dt.name ?? ""), path: str(dt.path), url: str(dt.url), mcp: parseMcpServer(dt) };
|
|
63
|
+
}
|
|
64
|
+
function parseIntegrations(projectRaw) {
|
|
65
|
+
if (!projectRaw.integrations || typeof projectRaw.integrations !== "object")
|
|
66
|
+
return undefined;
|
|
67
|
+
const it = projectRaw.integrations;
|
|
68
|
+
return {
|
|
69
|
+
codebase_memory_mcp: typeof it.codebase_memory_mcp === "boolean" ? it.codebase_memory_mcp : undefined,
|
|
70
|
+
caveman_plugin: typeof it.caveman_plugin === "boolean" ? it.caveman_plugin : undefined,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function parsePrecommitReview(projectRaw) {
|
|
74
|
+
if (!projectRaw.precommit_review || typeof projectRaw.precommit_review !== "object")
|
|
75
|
+
return undefined;
|
|
76
|
+
const pr = projectRaw.precommit_review;
|
|
77
|
+
const depth = str(pr.depth);
|
|
78
|
+
const blockOn = str(pr.block_on);
|
|
79
|
+
return {
|
|
80
|
+
depth: depth === "quick" || depth === "full" ? depth : undefined,
|
|
81
|
+
block_on: blockOn === "blocker" || blockOn === "none" ? blockOn : undefined,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function parseSurface(projectRaw) {
|
|
85
|
+
const surfaceRaw = str(projectRaw.surface);
|
|
86
|
+
return PROJECT_SURFACES.includes(surfaceRaw) ? surfaceRaw : undefined;
|
|
87
|
+
}
|
|
88
|
+
function parseStringArray(val) {
|
|
89
|
+
return Array.isArray(val) ? val.map(String) : undefined;
|
|
90
|
+
}
|
|
51
91
|
function parseProject(raw) {
|
|
52
|
-
const projectRaw = raw.project && typeof raw.project === "object"
|
|
53
|
-
? raw.project
|
|
54
|
-
: {};
|
|
55
|
-
let design_tool;
|
|
56
|
-
if (projectRaw.design_tool && typeof projectRaw.design_tool === "object") {
|
|
57
|
-
const dt = projectRaw.design_tool;
|
|
58
|
-
design_tool = {
|
|
59
|
-
name: String(dt.name ?? ""),
|
|
60
|
-
path: str(dt.path),
|
|
61
|
-
url: str(dt.url),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
let integrations;
|
|
65
|
-
if (projectRaw.integrations && typeof projectRaw.integrations === "object") {
|
|
66
|
-
const it = projectRaw.integrations;
|
|
67
|
-
integrations = {
|
|
68
|
-
codebase_memory_mcp: typeof it.codebase_memory_mcp === "boolean"
|
|
69
|
-
? it.codebase_memory_mcp
|
|
70
|
-
: undefined,
|
|
71
|
-
caveman_plugin: typeof it.caveman_plugin === "boolean" ? it.caveman_plugin : undefined,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
92
|
+
const projectRaw = raw.project && typeof raw.project === "object" ? raw.project : {};
|
|
74
93
|
return {
|
|
75
94
|
language: str(projectRaw.language ?? raw.language),
|
|
76
95
|
package_manager: str(projectRaw.package_manager),
|
|
@@ -78,14 +97,13 @@ function parseProject(raw) {
|
|
|
78
97
|
doc_tool: str(projectRaw.doc_tool ?? raw.doc_tool),
|
|
79
98
|
comment_style: str(projectRaw.comment_style ?? raw.comment_style),
|
|
80
99
|
caveman: str(projectRaw.caveman),
|
|
81
|
-
compliance:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
integrations,
|
|
100
|
+
compliance: parseStringArray(projectRaw.compliance),
|
|
101
|
+
design_tool: parseDesignTool(projectRaw),
|
|
102
|
+
agents: parseStringArray(projectRaw.agents),
|
|
103
|
+
integrations: parseIntegrations(projectRaw),
|
|
104
|
+
precommit_review: parsePrecommitReview(projectRaw),
|
|
105
|
+
surface: parseSurface(projectRaw),
|
|
106
|
+
brand_dir: str(projectRaw.brand_dir),
|
|
89
107
|
};
|
|
90
108
|
}
|
|
91
109
|
function parseLlm(raw) {
|
|
@@ -116,6 +134,19 @@ function parseLlm(raw) {
|
|
|
116
134
|
coding: { command: cmd },
|
|
117
135
|
};
|
|
118
136
|
}
|
|
137
|
+
function buildConfig(raw) {
|
|
138
|
+
return {
|
|
139
|
+
version: Number(raw.version ?? 1),
|
|
140
|
+
project: parseProject(raw),
|
|
141
|
+
features_dir: String(raw.features_dir ?? DEFAULT_CONFIG.features_dir),
|
|
142
|
+
decisions_dir: String(raw.decisions_dir ?? DEFAULT_CONFIG.decisions_dir),
|
|
143
|
+
tools: parseTools(raw),
|
|
144
|
+
checks: Array.isArray(raw.checks) ? raw.checks : DEFAULT_CHECKS,
|
|
145
|
+
llm: parseLlm(raw),
|
|
146
|
+
bug_trackers: Array.isArray(raw.bug_trackers) ? parseBugTrackers(raw.bug_trackers) : undefined,
|
|
147
|
+
testing_tools: Array.isArray(raw.testing_tools) ? parseTestingTools(raw.testing_tools) : undefined,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
119
150
|
export async function loadConfig(root) {
|
|
120
151
|
const projectRoot = root ?? (await findProjectRoot());
|
|
121
152
|
const configPath = join(projectRoot, ".grimoire", "config.yaml");
|
|
@@ -136,17 +167,7 @@ export async function loadConfig(root) {
|
|
|
136
167
|
console.warn(`Warning: failed to parse ${configPath}: ${msg}\nFalling back to default config.`);
|
|
137
168
|
return structuredClone(DEFAULT_CONFIG);
|
|
138
169
|
}
|
|
139
|
-
return
|
|
140
|
-
version: Number(raw.version ?? 1),
|
|
141
|
-
project: parseProject(raw),
|
|
142
|
-
features_dir: String(raw.features_dir ?? DEFAULT_CONFIG.features_dir),
|
|
143
|
-
decisions_dir: String(raw.decisions_dir ?? DEFAULT_CONFIG.decisions_dir),
|
|
144
|
-
tools: parseTools(raw),
|
|
145
|
-
checks: Array.isArray(raw.checks) ? raw.checks : DEFAULT_CHECKS,
|
|
146
|
-
llm: parseLlm(raw),
|
|
147
|
-
bug_trackers: Array.isArray(raw.bug_trackers) ? parseBugTrackers(raw.bug_trackers) : undefined,
|
|
148
|
-
testing_tools: Array.isArray(raw.testing_tools) ? parseTestingTools(raw.testing_tools) : undefined,
|
|
149
|
-
};
|
|
170
|
+
return buildConfig(raw);
|
|
150
171
|
}
|
|
151
172
|
function parseMcpServer(raw) {
|
|
152
173
|
if (!raw.mcp || typeof raw.mcp !== "object")
|
package/dist/utils/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAW7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/fs.d.ts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if a path exists (file or directory).
|
|
3
|
-
*/
|
|
4
1
|
export declare function fileExists(path: string): Promise<boolean>;
|
|
5
|
-
/**
|
|
6
|
-
* Read a file, returning null if it doesn't exist or can't be read.
|
|
7
|
-
*/
|
|
8
2
|
export declare function readFileOrNull(path: string): Promise<string | null>;
|
|
9
|
-
/**
|
|
10
|
-
* Escape a string for use in a RegExp constructor.
|
|
11
|
-
*/
|
|
12
3
|
export declare function escapeRegex(str: string): string;
|
|
13
|
-
/**
|
|
14
|
-
* Find files matching a glob extension pattern under a directory.
|
|
15
|
-
*/
|
|
16
4
|
export declare function findFiles(dir: string, ext: string): Promise<string[]>;
|
|
17
5
|
//# sourceMappingURL=fs.d.ts.map
|
package/dist/utils/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMzE;AAGD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAGD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE3E"}
|
package/dist/utils/fs.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { access, readFile } from "node:fs/promises";
|
|
2
2
|
import fg from "fast-glob";
|
|
3
|
-
/**
|
|
4
|
-
* Check if a path exists (file or directory).
|
|
5
|
-
*/
|
|
6
3
|
export async function fileExists(path) {
|
|
7
4
|
try {
|
|
8
5
|
await access(path);
|
|
@@ -12,9 +9,6 @@ export async function fileExists(path) {
|
|
|
12
9
|
return false;
|
|
13
10
|
}
|
|
14
11
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Read a file, returning null if it doesn't exist or can't be read.
|
|
17
|
-
*/
|
|
18
12
|
export async function readFileOrNull(path) {
|
|
19
13
|
try {
|
|
20
14
|
return await readFile(path, "utf-8");
|
|
@@ -23,15 +17,9 @@ export async function readFileOrNull(path) {
|
|
|
23
17
|
return null;
|
|
24
18
|
}
|
|
25
19
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Escape a string for use in a RegExp constructor.
|
|
28
|
-
*/
|
|
29
20
|
export function escapeRegex(str) {
|
|
30
21
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
31
22
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Find files matching a glob extension pattern under a directory.
|
|
34
|
-
*/
|
|
35
23
|
export async function findFiles(dir, ext) {
|
|
36
24
|
return fg(`**/*${ext}`, { cwd: dir, absolute: true });
|
|
37
25
|
}
|
package/dist/utils/fs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,WAAW,CAAC;AAG3B,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAGD,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW;IACtD,OAAO,EAAE,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC"}
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Walk up from cwd to find a directory containing .grimoire/ or features/
|
|
3
|
-
*/
|
|
4
1
|
export declare function findProjectRoot(): Promise<string>;
|
|
5
2
|
export declare function resolveChangePath(root: string, changeId: string): string;
|
|
6
|
-
/**
|
|
7
|
-
* Resolve a path and verify it stays within the project root.
|
|
8
|
-
*/
|
|
9
3
|
export declare function safePath(root: string, filePath: string): string;
|
|
10
4
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAIA,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAgBvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKxE;AAGD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM/D"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { join, resolve } from "node:path";
|
|
2
2
|
import { fileExists } from "./fs.js";
|
|
3
|
-
/**
|
|
4
|
-
* Walk up from cwd to find a directory containing .grimoire/ or features/
|
|
5
|
-
*/
|
|
6
3
|
export async function findProjectRoot() {
|
|
7
4
|
let dir = process.cwd();
|
|
8
5
|
const root = resolve("/");
|
|
@@ -22,9 +19,6 @@ export function resolveChangePath(root, changeId) {
|
|
|
22
19
|
}
|
|
23
20
|
return join(root, ".grimoire", "changes", changeId);
|
|
24
21
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Resolve a path and verify it stays within the project root.
|
|
27
|
-
*/
|
|
28
22
|
export function safePath(root, filePath) {
|
|
29
23
|
const resolved = resolve(root, filePath);
|
|
30
24
|
if (!resolved.startsWith(root + "/") && resolved !== root) {
|
package/dist/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1B,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC;QACpB,IACE,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;YAC1C,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EACzC,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,mBAAmB;IACnB,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IAC9D,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAGD,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,QAAgB;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/utils/spawn.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/utils/spawn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/utils/spawn.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
|
package/dist/utils/spawn.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
/**
|
|
3
|
-
* Spawn a command with stdin piped, avoiding sh -c shell interpretation.
|
|
4
|
-
*/
|
|
5
2
|
export function spawnWithStdin(command, args, input, cwd) {
|
|
6
3
|
return new Promise((resolve, reject) => {
|
|
7
4
|
const parts = command.split(/\s+/);
|
package/dist/utils/spawn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/utils/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/utils/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,IAAc,EACd,KAAa,EACb,GAAW;IAEX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE;YACzD,GAAG;YACH,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACtC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACtC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,4BAA4B,IAAI,EAAE,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YACpD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;YAC9B,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: grimoire-apply
|
|
3
|
-
description: Implement tasks from a planned grimoire change
|
|
3
|
+
description: Implement tasks from a planned grimoire change, test-first at the right level (BDD scenario, unit-invariant, or characterization). Use when tasks.md exists and is ready for implementation.
|
|
4
4
|
compatibility: Designed for Claude Code (or similar products)
|
|
5
5
|
metadata:
|
|
6
6
|
author: kiwi-data
|
|
@@ -9,7 +9,19 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
# grimoire-apply
|
|
11
11
|
|
|
12
|
-
Implement tasks from a planned grimoire change
|
|
12
|
+
Implement tasks from a planned grimoire change using **test-first discipline at the right level**: write the failing test first, then the production code that makes it pass. A task is not complete until its test passes.
|
|
13
|
+
|
|
14
|
+
**Red-green is the discipline; the test vehicle matches the artifact the task came from** (set by `grimoire-plan` as each task's `verify:` tag):
|
|
15
|
+
|
|
16
|
+
| `verify:` | Task came from | Test vehicle |
|
|
17
|
+
|-----------|----------------|--------------|
|
|
18
|
+
| `scenario` | a `.feature` (actor-observable behavior) | Gherkin scenario + step definitions |
|
|
19
|
+
| `unit-invariant` | the constraints register (security/NFR/observability) | unit/integration test asserting the invariant |
|
|
20
|
+
| `characterization` | internal change / refactor (no spec) | unit / characterization test |
|
|
21
|
+
|
|
22
|
+
Do NOT write a `.feature` scenario for a `unit-invariant` or `characterization` task — forcing Gherkin where a unit test is correct is the antipattern that fills feature files with slop. One right way: behavior → scenario, everything else → unit test.
|
|
23
|
+
|
|
24
|
+
**Artifacts are edited live on the feature branch.** Features, decisions, constraints, and schema are real files in `features/`, `.grimoire/decisions/`, `.grimoire/docs/`. There is no copy-into-change-folder and no promote step — `git diff` is the staging area. The change folder holds only ephemeral process scaffolding (`manifest.md`, `tasks.md`).
|
|
13
25
|
|
|
14
26
|
## CRITICAL: Two Rules That Must Not Be Broken
|
|
15
27
|
|
|
@@ -41,8 +53,8 @@ This applies to all LLMs: Claude, Codex, Cursor, Copilot, etc. The task list is
|
|
|
41
53
|
## Prerequisites
|
|
42
54
|
- A change exists in `.grimoire/changes/<change-id>/` with:
|
|
43
55
|
- `manifest.md`
|
|
44
|
-
- `tasks.md` (from plan stage)
|
|
45
|
-
|
|
56
|
+
- `tasks.md` (from plan stage, each task carrying a `verify:` tag)
|
|
57
|
+
- The change's live artifacts exist on the branch — at least one `.feature` (in `features/`), constraint (in `.grimoire/docs/constraints.md`), or decision record (in `.grimoire/decisions/`)
|
|
46
58
|
|
|
47
59
|
## Workflow
|
|
48
60
|
|
|
@@ -119,6 +131,21 @@ The parent agent is the **orchestrator only** — it does NOT implement tasks it
|
|
|
119
131
|
You are implementing grimoire tasks. Read `.grimoire/changes/<change-id>/tasks.md`,
|
|
120
132
|
find section <N>, and implement all unchecked tasks in that section.
|
|
121
133
|
Follow the red-green BDD cycle for each task. Mark tasks [x] when done.
|
|
134
|
+
|
|
135
|
+
Before writing any production code, read `../references/code-quality.md`,
|
|
136
|
+
`../references/testing-contracts.md`, and `../references/pattern-guard.md`.
|
|
137
|
+
Apply the code-quality rules WHILE you write (not after) — reuse before write,
|
|
138
|
+
trust callers (no defensive guards inside the trust boundary), specific names
|
|
139
|
+
(no `data`/`result`/`temp`), branching budget ~7, function size ~30 lines,
|
|
140
|
+
no premature abstraction, comments only for non-obvious WHY.
|
|
141
|
+
Before writing the test for each task, run the pattern-guard brief (Steps 1–1b–2–4):
|
|
142
|
+
classify the code type (Step 1), run reuse discovery — two search_graph calls
|
|
143
|
+
by concept and by name to find existing code to call instead of writing (Step 1b),
|
|
144
|
+
find 3–5 peers via search_graph (Step 2), extract the modal pattern, write a brief.
|
|
145
|
+
Write code that matches the brief. After writing production code, run the
|
|
146
|
+
hallucination check (Step 6): verify every called external function exists in
|
|
147
|
+
the graph before running tests.
|
|
148
|
+
|
|
122
149
|
When the section is complete, write a <!-- SESSION: ... --> handoff note
|
|
123
150
|
under the last task and exit.
|
|
124
151
|
```
|
|
@@ -170,9 +197,11 @@ Before writing any code, ensure you're on a feature branch for this change:
|
|
|
170
197
|
git checkout -b <type>/<change-id>
|
|
171
198
|
```
|
|
172
199
|
|
|
173
|
-
Where `<type>` is `feat`, `fix`, `refactor`, or `chore` based on the change. If a branch already exists (
|
|
200
|
+
Where `<type>` is `feat`, `fix`, `refactor`, or `chore` based on the change. If a branch already exists (`grimoire-branch-guard` or `grimoire-draft` usually created it), switch to it. Update the manifest's `branch:` field with the branch name.
|
|
201
|
+
|
|
202
|
+
The branch links the git history to the change via the `Change: <change-id>` commit trailer. The branch IS the isolation and `git diff` IS the staging — there is no separate promote step.
|
|
174
203
|
|
|
175
|
-
|
|
204
|
+
> **No promote.** Feature files, decisions, and constraints were drafted directly into their live locations (`features/`, `.grimoire/decisions/`, `.grimoire/docs/constraints.md`) on this branch. BDD runners already discover the scenarios from `features/`. Do not copy anything out of `.grimoire/changes/` — that folder holds only `manifest.md` and `tasks.md`.
|
|
176
205
|
|
|
177
206
|
### 4. Load Context
|
|
178
207
|
|
|
@@ -181,7 +210,7 @@ This links the git history to the grimoire change — `grimoire trace` and `grim
|
|
|
181
210
|
**Loading order:**
|
|
182
211
|
1. `tasks.md` — your checklist (load once at start, find the current section)
|
|
183
212
|
2. Read the `<!-- context: ... -->` block for the current section
|
|
184
|
-
3. Load each file listed in the context block
|
|
213
|
+
3. Load each file listed in the context block — this includes relevant `.grimoire/docs/conventions/<area>.md` files for directories touched by the diff (placement/naming guidance)
|
|
185
214
|
4. If a listed file doesn't exist, it may need to be created as part of the task — that's fine
|
|
186
215
|
|
|
187
216
|
**If the context window fills up** (degraded output quality, forgotten context, repeated mistakes):
|
|
@@ -190,27 +219,38 @@ This links the git history to the grimoire change — `grimoire trace` and `grim
|
|
|
190
219
|
3. Tell the user: "Context is getting large. I've updated tasks.md with progress. A fresh session can resume from here."
|
|
191
220
|
|
|
192
221
|
### 5. Implement Tasks
|
|
193
|
-
Work through `tasks.md` sequentially. **Every task follows the same cycle:
|
|
222
|
+
Work through `tasks.md` sequentially. **Every task follows the same cycle: test → red → code → green → next.** The cycle is identical at every level; only the *test vehicle* changes per the task's `verify:` tag (`scenario` → step definitions; `unit-invariant` / `characterization` → unit/integration test). "Step definitions" below means *the failing test at the task's level* — for non-`scenario` tasks, write a unit test, not a `.feature`.
|
|
194
223
|
|
|
195
224
|
**For each task:**
|
|
196
225
|
1. Announce which task you're working on
|
|
197
|
-
|
|
198
|
-
3
|
|
199
|
-
|
|
226
|
+
- Read the task's `verify:` tag — it decides the test vehicle. `scenario` → write/extend step definitions for the named scenario. `unit-invariant` → write a unit/integration test asserting the constraint. `characterization` → write a unit test pinning current/intended behavior. If a `unit-invariant` task has no matching constraint in `.grimoire/docs/constraints.md`, STOP and flag — don't invent a scenario to fill the gap.
|
|
227
|
+
- **Pattern brief** (before writing anything): classify code type → `search_graph` for 3–5 peers (excluding last 60 days) → `get_code_snippet` → extract modal pattern across the four critical seams (error handling, dependency access, abstraction depth, return shape) → write a 5–8 rule brief. Skip if graph not indexed or < 3 peers. Full instructions in `../references/pattern-guard.md`.
|
|
228
|
+
2. Write the test FIRST, at the task's level (step definitions for `scenario`; unit/integration test for `unit-invariant`/`characterization`)
|
|
229
|
+
3. Run the test — **it MUST FAIL (red)**
|
|
230
|
+
4. If the test passes immediately, STOP. The test is broken — it's not actually testing anything. Fix it so it makes a real assertion that fails without production code. Common causes:
|
|
200
231
|
- Empty step definition body (passes by default)
|
|
201
232
|
- Assertion against a mock/fixture that already satisfies the condition
|
|
202
233
|
- Step wired to wrong function or missing the actual check
|
|
203
234
|
- Overly broad assertion that matches anything
|
|
204
|
-
5. Once confirmed red: write the production code to make it pass
|
|
235
|
+
5. Once confirmed red: write the production code to make it pass. **While writing — not after — apply the rules in `../references/code-quality.md` and the pattern brief from step 1. Do not write the slop version first and clean up later.** Inline rules:
|
|
236
|
+
- **Reuse first — search before write.** Before writing any new function or class, run two searches: `search_graph(semantic_query=["<concept>", "<verb>", "<domain_noun>"])` to find it by concept, then `search_graph(name_pattern="<likely_prefix_or_suffix>")` to find it by name. If either returns something that does the job → call it. If something almost fits → use it directly; don't generalize for a hypothetical second caller. Write new code only when both searches return nothing usable. No one-line wrappers. No re-implementations. Full instructions: `../references/pattern-guard.md` Step 1b.
|
|
237
|
+
- **Trust your callers.** No `if x is None` / `isinstance` / `try-except` guards inside the trust boundary. Validate at edges (user input, external APIs, file/network) only.
|
|
238
|
+
- **Names reveal intent.** No `data` / `result` / `temp` / `info` / `obj` when a specific name fits. Booleans read as yes/no questions (`is_expired`, `has_admin_role`).
|
|
239
|
+
- **Branching budget ~7.** If a function has more `if` / `else` / `case` / `&&` than that, split or drop dead guards.
|
|
240
|
+
- **Function size ~30 lines.** One job per function. If the name needs "and", split.
|
|
241
|
+
- **No premature abstraction.** Three near-identical copies is fine. No new `BaseX` / factory / strategy / config object for a single caller.
|
|
242
|
+
- **Comments: terse, self-contained, no essays** (`../references/code-quality.md` §7). Default to none; add only a one-line non-obvious *why*. Terse voice — drop "this function", filler, restated types. **Self-contained:** never name an external artifact that moves independently — no feature/scenario/`.feature`, MADR/ADR number, change-id, ticket/PR, test name, or tag code (`LOG-OBS-003`) in a comment; describe the behavior, not where it's specced. **No paragraphs:** summary is 1–2 lines, then the `comment_style` params if the project requires them — no prose block before them. No comments restating the code (`# loop over users`). If removing it wouldn't confuse a future reader, don't write it.
|
|
205
243
|
6. Run the step definitions again — they should PASS (green)
|
|
206
244
|
7. If still red, fix the production code (not the test)
|
|
207
|
-
8. **
|
|
245
|
+
8. **Hallucination check:** Before running tests, verify every external function/method your new code calls actually exists in the graph: `search_graph(name_pattern="<name>")` for each. If not found: find the correct function or stop and flag to user. Do not run tests against calls to non-existent functions. (Full instructions in `../references/pattern-guard.md` Step 6.)
|
|
246
|
+
9. **Test quality check:** Before marking done, verify your step definitions have strong assertions:
|
|
208
247
|
- Every Then step has a specific `assert` or `expect` with an exact expected value (not `assert True`, not `toBeDefined()`)
|
|
209
248
|
- No empty function bodies (`pass`, `...`, or no-op)
|
|
210
249
|
- Assertions check behavior, not just types or existence — "response status is 302 and redirect URL is /dashboard/" not "response is not None"
|
|
211
250
|
- If you wrote a test that would pass against a null/trivial implementation, strengthen it
|
|
212
|
-
|
|
213
|
-
|
|
251
|
+
10. **Code quality check:** Walk the seven-point checklist in `../references/code-quality.md` against every file you changed. Any fail → fix code, re-run tests, re-check. Do not mark `[x]` while a check fails.
|
|
252
|
+
11. Mark complete: `- [ ]` → `- [x]`
|
|
253
|
+
12. Move to next task
|
|
214
254
|
|
|
215
255
|
**This is strict red-green BDD.** A test that has never been red has never proven it can catch a failure. The red step is NOT a formality — it is the proof that the test works. If you skip it or the test passes immediately, you have a false positive that provides zero safety.
|
|
216
256
|
|
|
@@ -238,15 +278,36 @@ When all implementation tasks are complete:
|
|
|
238
278
|
**The verify step is not optional. Do not proceed to finalize with failing tests.**
|
|
239
279
|
|
|
240
280
|
### 7. Finalize
|
|
241
|
-
When all tests are green:
|
|
242
|
-
1.
|
|
243
|
-
2.
|
|
244
|
-
3.
|
|
245
|
-
4.
|
|
246
|
-
5.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
281
|
+
When all tests are green. Features, decisions, and constraints were edited live on the branch — finalize flips states, applies the schema delta, and clears the ephemeral scaffolding:
|
|
282
|
+
1. Decision records already live in `.grimoire/decisions/` (drafted there, numbered at draft time). Flip MADR status from `proposed` to `accepted` and set the date.
|
|
283
|
+
2. Constraints (`.grimoire/docs/constraints.md`) were edited in place — nothing to move.
|
|
284
|
+
3. If the change has a `data.yml` (schema delta), apply its `add`/`modify`/`remove` entries to the live `.grimoire/docs/data/schema.yml` so the baseline schema stays current. `data.yml` is a migration-delta spec (ephemeral scaffolding carrying nullability/safety/ordering intent a raw diff wouldn't), not a copy of the schema — `schema.yml` is the live target; the delta is discarded with the change folder.
|
|
285
|
+
4. Refresh the project overview: run `grimoire docs`. It regenerates `.grimoire/docs/OVERVIEW.md` (the human entry point) from the now-current features, constraints, decisions, and schema — superseded decisions drop out automatically. This is the existing `docs` command, not a new one.
|
|
286
|
+
5. Remove the change directory `.grimoire/changes/<change-id>/`. Its `manifest.md` + `tasks.md` (+ any `data.yml`) are ephemeral process scaffolding. The durable record is the branch, the PR, and `git log` — linked by the `Change: <change-id>` trailer. **There is no archive tree** (don't reinvent git history).
|
|
287
|
+
|
|
288
|
+
### 8. Commit
|
|
289
|
+
|
|
290
|
+
Finalize must be complete before committing — the commit captures the finished state (accepted decisions, cleared scaffolding), not mid-flight change artefacts.
|
|
291
|
+
|
|
292
|
+
Stage the live artifacts and the scaffolding removal:
|
|
293
|
+
```
|
|
294
|
+
git add features/ .grimoire/decisions/ .grimoire/docs/ src/ tests/
|
|
295
|
+
git add -u # picks up the removed change directory
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Then commit using `/grimoire:commit` (reads change context for the message) or write a manual message following `AGENTS.md` commit trailer conventions:
|
|
299
|
+
```
|
|
300
|
+
feat(<change-id>): <short description>
|
|
301
|
+
|
|
302
|
+
<body if needed>
|
|
303
|
+
|
|
304
|
+
Change: <change-id>
|
|
305
|
+
Scenarios: "<scenario 1>", "<scenario 2>"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Mid-task commits are fine — commit whenever it makes sense during implementation. **Do not open a PR before finalize is complete.** The PR should represent the finished, archived state of the change.
|
|
309
|
+
|
|
310
|
+
### 9. Summary
|
|
250
311
|
Present a brief summary:
|
|
251
312
|
- What was implemented
|
|
252
313
|
- Which features now pass (with test counts if available)
|
|
@@ -255,7 +316,10 @@ Present a brief summary:
|
|
|
255
316
|
|
|
256
317
|
## References
|
|
257
318
|
|
|
258
|
-
**Before writing code**, read
|
|
319
|
+
**Before writing code**, read all three:
|
|
320
|
+
- `../references/pattern-guard.md` — run before each task: (1) classify code type, (1b) reuse discovery — two `search_graph` calls (semantic_query by concept + name_pattern by likely name) to find existing code to call instead of writing new code, (2) find 3–5 peers, extract modal pattern across four seams (error handling, dependency, abstraction depth, return shape), write a pattern brief. Apply the brief while writing. Run hallucination check after writing (verify called functions exist in graph). Skip if graph not indexed.
|
|
321
|
+
- `../references/code-quality.md` — anti-slop rules to apply *while writing*: reuse before write, trust callers, names reveal intent, branching budget, function size, no premature abstraction, zero comments by default (only non-obvious *why*, never *what*). Includes a seven-point quality gate to run before marking each task `[x]`.
|
|
322
|
+
- `../references/testing-contracts.md` — verify-before-using rules (imports, packages, APIs), mocking strategy (HTTP boundary not client), fixture management, contract tests, and step definition quality checks.
|
|
259
323
|
|
|
260
324
|
## Important
|
|
261
325
|
- **Tests are not optional.** Every task produces both production code and passing step definitions. No exceptions.
|
|
@@ -28,7 +28,8 @@ Audit an existing codebase to discover undocumented features and architecture de
|
|
|
28
28
|
Ask the user what to audit:
|
|
29
29
|
- **Features** — find behavioral functionality that has no `.feature` file
|
|
30
30
|
- **Decisions** — find implicit architecture decisions that have no ADR
|
|
31
|
-
- **
|
|
31
|
+
- **Conventions** — find conventions files in `.grimoire/docs/conventions/` whose placement/naming rules no longer match the codebase
|
|
32
|
+
- **Both** / **All** — full audit (default: features + decisions + conventions)
|
|
32
33
|
|
|
33
34
|
Check what's already documented:
|
|
34
35
|
- Read all files in `features/` for existing behavioral specs
|
|
@@ -60,9 +61,27 @@ Scan for implicit architecture decisions:
|
|
|
60
61
|
|
|
61
62
|
For each pattern found, check if a corresponding ADR exists. If not, note it as undocumented.
|
|
62
63
|
|
|
64
|
+
### 3.5. Conventions Drift Detection
|
|
65
|
+
Read each file in `.grimoire/docs/conventions/`. For each file:
|
|
66
|
+
1. Use MCP `get_architecture` or `search_graph` to query the current code structure for the relevant area
|
|
67
|
+
2. Compare the conventions file's placement rules, naming rules, and patterns against what MCP reports the codebase actually does
|
|
68
|
+
3. Flag any conventions rule that no longer matches:
|
|
69
|
+
- "api.md says new views go in `src/api/views/` but MCP shows views now in `src/api/handlers/`"
|
|
70
|
+
- "models.md says models are prefixed with `I` but no `I`-prefixed models found in MCP graph"
|
|
71
|
+
|
|
72
|
+
Present drifted conventions to the user with the same batched interview approach:
|
|
73
|
+
> "api.md states that new views go in `src/api/views/`, but the codebase now places them in `src/api/handlers/`. Options:
|
|
74
|
+
> - **refresh** — update the conventions file to match current code (I'll open it for editing with MCP-sourced state)
|
|
75
|
+
> - **accept-as-is** — the conventions file is intentionally ahead of the code
|
|
76
|
+
> - **skip** — leave for now"
|
|
77
|
+
|
|
78
|
+
Skip this step when the user's scope answer was "features only" or "decisions only".
|
|
79
|
+
|
|
63
80
|
### 4. Interview the User
|
|
64
81
|
Do NOT dump a massive list. Present findings in batches of 3-5, grouped by area, and ask the user about each:
|
|
65
82
|
|
|
83
|
+
Clearly label each batch item as one of: "undocumented feature", "undocumented decision", or "drifted convention"
|
|
84
|
+
|
|
66
85
|
For features:
|
|
67
86
|
> "I found a document review workflow with routes for `/dais/review/document/<id>/`. There's tab switching, error modals, and tag editing. I don't see a feature file covering this. Should I draft one?"
|
|
68
87
|
|
|
@@ -114,6 +133,7 @@ After the interview, summarize:
|
|
|
114
133
|
- How many features are dead or stale
|
|
115
134
|
- How many decisions are documented vs. undocumented
|
|
116
135
|
- How many decisions are stale
|
|
136
|
+
- How many conventions files drifted vs. up-to-date
|
|
117
137
|
- Suggest which areas to address first (highest risk / most complex / most frequently changed)
|
|
118
138
|
|
|
119
139
|
## Important
|