critical-gate 2.4.4 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/dist/cli/args.d.ts +15 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +56 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands.d.ts +1 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +40 -1
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +24 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/init-project.d.ts +28 -0
- package/dist/cli/init-project.d.ts.map +1 -0
- package/dist/cli/init-project.js +600 -0
- package/dist/cli/init-project.js.map +1 -0
- package/dist/cli/io.d.ts.map +1 -1
- package/dist/cli/io.js +4 -0
- package/dist/cli/io.js.map +1 -1
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +4 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/detectors/blast-radius-detector.d.ts.map +1 -1
- package/dist/detectors/blast-radius-detector.js +18 -1
- package/dist/detectors/blast-radius-detector.js.map +1 -1
- package/dist/detectors/expected-companions-detector.js +12 -2
- package/dist/detectors/expected-companions-detector.js.map +1 -1
- package/dist/detectors/rewrite-detector.d.ts.map +1 -1
- package/dist/detectors/rewrite-detector.js +21 -1
- package/dist/detectors/rewrite-detector.js.map +1 -1
- package/dist/detectors/scope-detector.d.ts.map +1 -1
- package/dist/detectors/scope-detector.js +20 -0
- package/dist/detectors/scope-detector.js.map +1 -1
- package/dist/intent/intent-model.d.ts.map +1 -1
- package/dist/intent/intent-model.js +13 -0
- package/dist/intent/intent-model.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
4
|
+
import { CRITICAL_GATE_CONFIG_FILE } from "../config/index.js";
|
|
5
|
+
import { CRITICAL_GATE_VERSION } from "../version.js";
|
|
6
|
+
const detectorIds = [
|
|
7
|
+
"dependency",
|
|
8
|
+
"test-weakening",
|
|
9
|
+
"config-change",
|
|
10
|
+
"secret-path",
|
|
11
|
+
"api-surface",
|
|
12
|
+
"intent-verification",
|
|
13
|
+
"blast-radius",
|
|
14
|
+
"scope",
|
|
15
|
+
"rewrite",
|
|
16
|
+
"repository-intelligence",
|
|
17
|
+
"expected-companions",
|
|
18
|
+
"utility-reinvention",
|
|
19
|
+
"existing-solution",
|
|
20
|
+
"pattern-violation"
|
|
21
|
+
];
|
|
22
|
+
export function initProject(options, io) {
|
|
23
|
+
const root = io.getRoot?.() ?? io.readDiff().root;
|
|
24
|
+
const packageJsonPath = join(root, "package.json");
|
|
25
|
+
const packageManager = options.packageManager === undefined
|
|
26
|
+
? detectPackageManager(root, io)
|
|
27
|
+
: packageManagerByName(options.packageManager);
|
|
28
|
+
const written = [];
|
|
29
|
+
const skipped = [];
|
|
30
|
+
const now = io.now();
|
|
31
|
+
if (!exists(packageJsonPath, io)) {
|
|
32
|
+
writeJson(packageJsonPath, {
|
|
33
|
+
name: slugify(basename(root)) || "critical-gate-project",
|
|
34
|
+
version: "0.1.0",
|
|
35
|
+
private: true,
|
|
36
|
+
scripts: {}
|
|
37
|
+
}, io);
|
|
38
|
+
written.push("package.json");
|
|
39
|
+
}
|
|
40
|
+
if (options.install) {
|
|
41
|
+
installCriticalGate(packageManager, options.version ?? CRITICAL_GATE_VERSION, root);
|
|
42
|
+
}
|
|
43
|
+
const packageJson = readPackageJson(packageJsonPath, root, io);
|
|
44
|
+
writeJson(packageJsonPath, withPackageScripts(packageJson), io);
|
|
45
|
+
written.push("package.json");
|
|
46
|
+
writeFileIfAllowed(join(root, CRITICAL_GATE_CONFIG_FILE), `${JSON.stringify(createObserveOnlyPolicy(packageJson, now), null, 2)}\n`, options.force, io, written, skipped);
|
|
47
|
+
writeFileIfAllowed(join(root, "scripts", "critical-gate-evidence.mjs"), evidenceExporterSource, options.force, io, written, skipped);
|
|
48
|
+
writeFileIfAllowed(join(root, "docs", "critical-gate-dogfood.md"), dogfoodJournalSource(packageManager), options.force, io, written, skipped);
|
|
49
|
+
writeFileIfAllowed(join(root, "docs", "critical-gate-evidence", "README.md"), evidenceIndexSource, options.force, io, written, skipped);
|
|
50
|
+
if (!options.skipWorkflow) {
|
|
51
|
+
writeFileIfAllowed(join(root, ".github", "workflows", "critical-gate.yml"), githubWorkflowSource(options.version ?? CRITICAL_GATE_VERSION), options.force, io, written, skipped);
|
|
52
|
+
}
|
|
53
|
+
updateGitignore(root, io, written);
|
|
54
|
+
return {
|
|
55
|
+
root,
|
|
56
|
+
packageManager,
|
|
57
|
+
installed: options.install,
|
|
58
|
+
written: [...new Set(written.map((path) => relativeProjectPath(root, path)))],
|
|
59
|
+
skipped: [...new Set(skipped.map((path) => relativeProjectPath(root, path)))]
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function detectPackageManager(root, io) {
|
|
63
|
+
if (exists(join(root, "bun.lock"), io) || exists(join(root, "bun.lockb"), io)) {
|
|
64
|
+
return packageManagerByName("bun");
|
|
65
|
+
}
|
|
66
|
+
if (exists(join(root, "pnpm-lock.yaml"), io)) {
|
|
67
|
+
return packageManagerByName("pnpm");
|
|
68
|
+
}
|
|
69
|
+
if (exists(join(root, "yarn.lock"), io)) {
|
|
70
|
+
return packageManagerByName("yarn");
|
|
71
|
+
}
|
|
72
|
+
return packageManagerByName("npm");
|
|
73
|
+
}
|
|
74
|
+
export function packageManagerByName(name) {
|
|
75
|
+
if (name === "bun") {
|
|
76
|
+
return { name, command: "bun", addDev: ["add", "-d"], run: "bun run" };
|
|
77
|
+
}
|
|
78
|
+
if (name === "pnpm") {
|
|
79
|
+
return { name, command: "pnpm", addDev: ["add", "-D"], run: "pnpm run" };
|
|
80
|
+
}
|
|
81
|
+
if (name === "npm") {
|
|
82
|
+
return { name, command: "npm", addDev: ["install", "-D"], run: "npm run" };
|
|
83
|
+
}
|
|
84
|
+
if (name === "yarn") {
|
|
85
|
+
return { name, command: "yarn", addDev: ["add", "-D"], run: "yarn" };
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Unsupported package manager: ${name}`);
|
|
88
|
+
}
|
|
89
|
+
function installCriticalGate(packageManager, version, root) {
|
|
90
|
+
const packageName = version === "latest" ? "critical-gate" : `critical-gate@${version}`;
|
|
91
|
+
execFileSync(packageManager.command, [...getAddDevArgs(packageManager, root), packageName], {
|
|
92
|
+
cwd: root,
|
|
93
|
+
stdio: "inherit",
|
|
94
|
+
shell: process.platform === "win32"
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function getAddDevArgs(packageManager, root) {
|
|
98
|
+
if (packageManager.name === "pnpm" && existsSync(join(root, "pnpm-workspace.yaml"))) {
|
|
99
|
+
return [...packageManager.addDev, "-w"];
|
|
100
|
+
}
|
|
101
|
+
return packageManager.addDev;
|
|
102
|
+
}
|
|
103
|
+
function withPackageScripts(packageJson) {
|
|
104
|
+
return {
|
|
105
|
+
...packageJson,
|
|
106
|
+
scripts: {
|
|
107
|
+
...readRecord(packageJson.scripts),
|
|
108
|
+
gate: "critical-gate check --format markdown --fail-on blocker",
|
|
109
|
+
"gate:base": "critical-gate check --base main --format markdown --fail-on blocker",
|
|
110
|
+
"gate:sarif": "critical-gate check --format sarif --output critical-gate.sarif --fail-on blocker",
|
|
111
|
+
"gate:evidence": "node scripts/critical-gate-evidence.mjs"
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function createObserveOnlyPolicy(packageJson, now) {
|
|
116
|
+
return {
|
|
117
|
+
frameworkPacks: detectFrameworkPacks(packageJson),
|
|
118
|
+
policy: {
|
|
119
|
+
failOn: "blocker",
|
|
120
|
+
detectorOverrides: detectorIds.map((detector) => ({
|
|
121
|
+
detector,
|
|
122
|
+
mode: "observation",
|
|
123
|
+
reason: "Phase 1 dogfood rollout: collect evidence and calibrate findings before enforcement."
|
|
124
|
+
})),
|
|
125
|
+
allowedSupportFiles: [
|
|
126
|
+
{
|
|
127
|
+
id: "critical-gate-dogfood-docs",
|
|
128
|
+
whenChanged: CRITICAL_GATE_CONFIG_FILE,
|
|
129
|
+
allow: [
|
|
130
|
+
"docs/critical-gate-dogfood.md",
|
|
131
|
+
"docs/critical-gate-evidence/**",
|
|
132
|
+
"AGENTS.md",
|
|
133
|
+
"package.json",
|
|
134
|
+
"package-lock.json",
|
|
135
|
+
"npm-shrinkwrap.json",
|
|
136
|
+
"pnpm-lock.yaml",
|
|
137
|
+
"yarn.lock",
|
|
138
|
+
"bun.lock",
|
|
139
|
+
"bun.lockb"
|
|
140
|
+
],
|
|
141
|
+
reason: "Critical Gate rollout changes include package wiring, agent workflow notes, and dogfood evidence.",
|
|
142
|
+
createdAt: now.toISOString()
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: "workflow-operational-docs",
|
|
146
|
+
whenChanged: ".github/workflows/**",
|
|
147
|
+
allow: ["docs/**/*.md", "README.md", "AGENTS.md"],
|
|
148
|
+
reason: "Workflow changes may include operational documentation.",
|
|
149
|
+
createdAt: now.toISOString()
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
learning: {
|
|
154
|
+
acceptedFindings: [],
|
|
155
|
+
expectedSupportFiles: []
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function detectFrameworkPacks(packageJson) {
|
|
160
|
+
const dependencies = {
|
|
161
|
+
...readRecord(packageJson.dependencies),
|
|
162
|
+
...readRecord(packageJson.devDependencies),
|
|
163
|
+
...readRecord(packageJson.peerDependencies)
|
|
164
|
+
};
|
|
165
|
+
return ["astro", "vite", "next", "react", "vue", "svelte"].filter((name) => dependencies[name] !== undefined);
|
|
166
|
+
}
|
|
167
|
+
function updateGitignore(root, io, written) {
|
|
168
|
+
const path = join(root, ".gitignore");
|
|
169
|
+
const additions = [
|
|
170
|
+
".critical-gate/cache/",
|
|
171
|
+
"critical-gate.json",
|
|
172
|
+
"critical-gate.md",
|
|
173
|
+
"critical-gate.sarif",
|
|
174
|
+
"critical-gate-pr-comment.md"
|
|
175
|
+
];
|
|
176
|
+
const existing = exists(path, io) ? readFile(path, io) : "";
|
|
177
|
+
const lines = existing.split(/\r?\n/u);
|
|
178
|
+
const missing = additions.filter((line) => !lines.includes(line));
|
|
179
|
+
if (missing.length === 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
io.writeFile(path, `${existing.trimEnd()}\n${missing.join("\n")}\n`);
|
|
183
|
+
written.push(path);
|
|
184
|
+
}
|
|
185
|
+
function writeFileIfAllowed(path, content, force, io, written, skipped) {
|
|
186
|
+
if (exists(path, io) && !force) {
|
|
187
|
+
skipped.push(path);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
io.writeFile(path, content);
|
|
191
|
+
written.push(path);
|
|
192
|
+
}
|
|
193
|
+
function readPackageJson(path, root, io) {
|
|
194
|
+
if (exists(path, io)) {
|
|
195
|
+
return JSON.parse(readFile(path, io));
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
name: slugify(basename(root)) || "critical-gate-project",
|
|
199
|
+
version: "0.1.0",
|
|
200
|
+
private: true,
|
|
201
|
+
scripts: {}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function writeJson(path, value, io) {
|
|
205
|
+
io.writeFile(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
206
|
+
}
|
|
207
|
+
function exists(path, io) {
|
|
208
|
+
return io.exists?.(path) === true;
|
|
209
|
+
}
|
|
210
|
+
function readFile(path, io) {
|
|
211
|
+
if (io.readFile === undefined) {
|
|
212
|
+
throw new Error(`Cannot read ${path}.`);
|
|
213
|
+
}
|
|
214
|
+
return io.readFile(path);
|
|
215
|
+
}
|
|
216
|
+
function readRecord(value) {
|
|
217
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
218
|
+
? value
|
|
219
|
+
: {};
|
|
220
|
+
}
|
|
221
|
+
function relativeProjectPath(root, path) {
|
|
222
|
+
const normalizedRoot = root.replaceAll("\\", "/");
|
|
223
|
+
const normalizedPath = path.replaceAll("\\", "/");
|
|
224
|
+
return normalizedPath.startsWith(normalizedRoot)
|
|
225
|
+
? normalizedPath.slice(normalizedRoot.length + 1)
|
|
226
|
+
: normalizedPath;
|
|
227
|
+
}
|
|
228
|
+
function slugify(value) {
|
|
229
|
+
return value
|
|
230
|
+
.toLowerCase()
|
|
231
|
+
.replace(/[^a-z0-9]+/gu, "-")
|
|
232
|
+
.replace(/^-|-$/gu, "");
|
|
233
|
+
}
|
|
234
|
+
const evidenceExporterSource = `#!/usr/bin/env node
|
|
235
|
+
import { spawnSync } from "node:child_process";
|
|
236
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
237
|
+
import { join } from "node:path";
|
|
238
|
+
|
|
239
|
+
const root = process.cwd();
|
|
240
|
+
const args = parseArgs(process.argv.slice(2));
|
|
241
|
+
|
|
242
|
+
if (args.task === undefined || args.task.trim().length === 0) {
|
|
243
|
+
console.error('Usage: npm run gate:evidence -- --task "Describe the completed task"');
|
|
244
|
+
process.exit(2);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!hasMeaningfulDiff()) {
|
|
248
|
+
console.log("Critical Gate evidence skipped: no working-tree diff to analyze.");
|
|
249
|
+
process.exit(0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const now = new Date();
|
|
253
|
+
const day = now.toISOString().slice(0, 10);
|
|
254
|
+
const time = now.toISOString().slice(11, 19).replaceAll(":", "");
|
|
255
|
+
const slug = slugify(args.task);
|
|
256
|
+
const evidenceRoot = join(root, "docs", "critical-gate-evidence");
|
|
257
|
+
const runDir = join(evidenceRoot, day);
|
|
258
|
+
const basename = \`\${time}-\${slug}\`;
|
|
259
|
+
const markdownPath = join(runDir, \`\${basename}.md\`);
|
|
260
|
+
const jsonPath = join(runDir, \`\${basename}.json\`);
|
|
261
|
+
const tempDir = join(root, ".critical-gate", "cache", "evidence");
|
|
262
|
+
const tempMarkdownPath = join(tempDir, \`\${basename}.md\`);
|
|
263
|
+
const tempJsonPath = join(tempDir, \`\${basename}.json\`);
|
|
264
|
+
const indexPath = join(evidenceRoot, "README.md");
|
|
265
|
+
|
|
266
|
+
mkdirSync(runDir, { recursive: true });
|
|
267
|
+
mkdirSync(tempDir, { recursive: true });
|
|
268
|
+
|
|
269
|
+
const commonArgs = ["check", "--task", args.task, "--fail-on", "blocker"];
|
|
270
|
+
|
|
271
|
+
if (args.base !== undefined) {
|
|
272
|
+
commonArgs.push("--base", args.base);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (args.staged) {
|
|
276
|
+
commonArgs.push("--staged");
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const markdown = runCriticalGate([
|
|
280
|
+
...commonArgs,
|
|
281
|
+
"--format",
|
|
282
|
+
"markdown",
|
|
283
|
+
"--output",
|
|
284
|
+
tempMarkdownPath
|
|
285
|
+
]);
|
|
286
|
+
const json = runCriticalGate([...commonArgs, "--format", "json", "--output", tempJsonPath]);
|
|
287
|
+
|
|
288
|
+
copyFileSync(tempMarkdownPath, markdownPath);
|
|
289
|
+
copyFileSync(tempJsonPath, jsonPath);
|
|
290
|
+
|
|
291
|
+
const report = readJsonReport(jsonPath);
|
|
292
|
+
|
|
293
|
+
updateIndex(indexPath, {
|
|
294
|
+
day,
|
|
295
|
+
task: args.task,
|
|
296
|
+
markdownFile: relativeForMarkdown(evidenceRoot, markdownPath),
|
|
297
|
+
jsonFile: relativeForMarkdown(evidenceRoot, jsonPath),
|
|
298
|
+
decision: report?.summary?.decision ?? "unknown",
|
|
299
|
+
findings: report?.summary?.findingCount ?? "unknown",
|
|
300
|
+
coherence: formatScore(report?.summary?.diffCoherenceScore),
|
|
301
|
+
scope: formatScore(report?.summary?.scopeExpansionScore)
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
console.log("Critical Gate evidence exported:");
|
|
305
|
+
console.log(\`- Markdown: \${markdownPath}\`);
|
|
306
|
+
console.log(\`- JSON: \${jsonPath}\`);
|
|
307
|
+
|
|
308
|
+
process.exit(Math.max(markdown.status ?? 0, json.status ?? 0));
|
|
309
|
+
|
|
310
|
+
function parseArgs(argv) {
|
|
311
|
+
const parsed = {
|
|
312
|
+
staged: false
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
316
|
+
const arg = argv[index];
|
|
317
|
+
|
|
318
|
+
if (arg === "--staged") {
|
|
319
|
+
parsed.staged = true;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (arg !== "--task" && arg !== "--base") {
|
|
324
|
+
console.error(\`Unknown option: \${arg}\`);
|
|
325
|
+
process.exit(2);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const value = argv[index + 1];
|
|
329
|
+
|
|
330
|
+
if (value === undefined || value.startsWith("--")) {
|
|
331
|
+
console.error(\`Missing value for \${arg}.\`);
|
|
332
|
+
process.exit(2);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (arg === "--task") {
|
|
336
|
+
parsed.task = value;
|
|
337
|
+
} else {
|
|
338
|
+
parsed.base = value;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
index += 1;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return parsed;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function runCriticalGate(commandArgs) {
|
|
348
|
+
const result = spawnSync("critical-gate", commandArgs, {
|
|
349
|
+
cwd: root,
|
|
350
|
+
encoding: "utf8",
|
|
351
|
+
shell: process.platform === "win32",
|
|
352
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
if (result.error !== undefined) {
|
|
356
|
+
console.error(result.error.message);
|
|
357
|
+
process.exit(3);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (result.stdout.length > 0) {
|
|
361
|
+
process.stdout.write(result.stdout);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (result.stderr.length > 0) {
|
|
365
|
+
process.stderr.write(result.stderr);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function hasMeaningfulDiff() {
|
|
372
|
+
const tracked = spawnSync("git", ["diff", "--quiet", "HEAD", "--"], {
|
|
373
|
+
cwd: root,
|
|
374
|
+
stdio: "ignore"
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
if (tracked.status !== 0) {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const untracked = spawnSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
382
|
+
cwd: root,
|
|
383
|
+
encoding: "utf8",
|
|
384
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
return untracked.stdout.trim().length > 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function readJsonReport(path) {
|
|
391
|
+
try {
|
|
392
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
393
|
+
} catch {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function updateIndex(path, entry) {
|
|
399
|
+
const header = [
|
|
400
|
+
"# Critical Gate Evidence",
|
|
401
|
+
"",
|
|
402
|
+
"Timestamped reports from observe-only dogfooding runs.",
|
|
403
|
+
"",
|
|
404
|
+
"| Date | Decision | Findings | Coherence | Scope | Task | Reports |",
|
|
405
|
+
"| --- | --- | ---: | ---: | ---: | --- | --- |"
|
|
406
|
+
].join("\\n");
|
|
407
|
+
const existing = existsSync(path) ? readFileSync(path, "utf8") : \`\${header}\\n\`;
|
|
408
|
+
const line = [
|
|
409
|
+
\`| \${entry.day}\`,
|
|
410
|
+
entry.decision,
|
|
411
|
+
entry.findings,
|
|
412
|
+
entry.coherence,
|
|
413
|
+
entry.scope,
|
|
414
|
+
escapeCell(entry.task),
|
|
415
|
+
\`[md](\${entry.markdownFile}) / [json](\${entry.jsonFile}) |\`
|
|
416
|
+
].join(" | ");
|
|
417
|
+
|
|
418
|
+
if (existing.includes(line)) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
writeFileSync(path, \`\${existing.trimEnd()}\\n\${line}\\n\`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function relativeForMarkdown(fromDir, filePath) {
|
|
426
|
+
return filePath.slice(fromDir.length + 1).replaceAll("\\\\", "/");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function slugify(value) {
|
|
430
|
+
return value
|
|
431
|
+
.toLowerCase()
|
|
432
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
433
|
+
.replace(/^-|-$/g, "")
|
|
434
|
+
.slice(0, 80);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function escapeCell(value) {
|
|
438
|
+
return value.replaceAll("|", "\\\\|").replace(/\\s+/g, " ").trim();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function formatScore(score) {
|
|
442
|
+
if (score === undefined || score === null) {
|
|
443
|
+
return "unknown";
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (typeof score === "number" || typeof score === "string") {
|
|
447
|
+
return score;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (typeof score.value === "number" || typeof score.value === "string") {
|
|
451
|
+
return score.value;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (typeof score.score === "number" || typeof score.score === "string") {
|
|
455
|
+
return score.score;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return "unknown";
|
|
459
|
+
}
|
|
460
|
+
`;
|
|
461
|
+
function dogfoodJournalSource(packageManager) {
|
|
462
|
+
return `# Critical Gate Dogfood Journal
|
|
463
|
+
|
|
464
|
+
Critical Gate is adopted in observe-only mode for this repository.
|
|
465
|
+
|
|
466
|
+
The goal is to collect evidence from real AI-agent tasks before enabling local hooks or hard CI
|
|
467
|
+
blocking. After each agent task with a meaningful diff, export durable evidence:
|
|
468
|
+
|
|
469
|
+
\`\`\`bash
|
|
470
|
+
${packageManager.run} gate:evidence -- --task "Describe the completed task"
|
|
471
|
+
\`\`\`
|
|
472
|
+
|
|
473
|
+
This writes timestamped Markdown and JSON reports under \`docs/critical-gate-evidence/\`.
|
|
474
|
+
|
|
475
|
+
## Metrics
|
|
476
|
+
|
|
477
|
+
| Metric | Count |
|
|
478
|
+
| --- | ---: |
|
|
479
|
+
| Tasks analyzed | 0 |
|
|
480
|
+
| Useful findings | 0 |
|
|
481
|
+
| False positives | 0 |
|
|
482
|
+
| Missed findings | 0 |
|
|
483
|
+
| Exported evidence reports | 0 |
|
|
484
|
+
|
|
485
|
+
## Log Template
|
|
486
|
+
|
|
487
|
+
\`\`\`md
|
|
488
|
+
## YYYY-MM-DD
|
|
489
|
+
|
|
490
|
+
Task:
|
|
491
|
+
|
|
492
|
+
Finding:
|
|
493
|
+
|
|
494
|
+
Result:
|
|
495
|
+
|
|
496
|
+
Status:
|
|
497
|
+
Useful / False positive / Missed / Clean
|
|
498
|
+
|
|
499
|
+
Missed finding review:
|
|
500
|
+
Yes / No. Record anything Critical Gate failed to catch.
|
|
501
|
+
|
|
502
|
+
Repair loop:
|
|
503
|
+
Not needed / Attempted / Repaired / Partially repaired / Not repaired / Harmful.
|
|
504
|
+
|
|
505
|
+
Repair scope:
|
|
506
|
+
Stayed inside task: Yes / No / Not applicable.
|
|
507
|
+
Stayed inside repair contract: Yes / No / Not applicable.
|
|
508
|
+
|
|
509
|
+
Follow-up:
|
|
510
|
+
\`\`\`
|
|
511
|
+
|
|
512
|
+
## Label Sidecar Template
|
|
513
|
+
|
|
514
|
+
Create or update a \`.labels.json\` sidecar next to each exported JSON report. Use the repair-loop
|
|
515
|
+
fields when Critical Gate findings are fed back to an agent or developer for a rerun.
|
|
516
|
+
|
|
517
|
+
\`\`\`json
|
|
518
|
+
{
|
|
519
|
+
"schemaVersion": "1.0",
|
|
520
|
+
"reportId": "<report id>",
|
|
521
|
+
"repo": "<repo name>",
|
|
522
|
+
"reportPath": "docs/critical-gate-evidence/YYYY-MM-DD/<report>.json",
|
|
523
|
+
"task": "<task>",
|
|
524
|
+
"taskType": "feature|bugfix|docs|policy|evidence-workflow|release|other",
|
|
525
|
+
"runLabel": "useful|clean|false-positive",
|
|
526
|
+
"decision": "pass|fail",
|
|
527
|
+
"findingCount": 0,
|
|
528
|
+
"usefulFindingCount": 0,
|
|
529
|
+
"falsePositiveFindingCount": 0,
|
|
530
|
+
"missedFindingCount": 0,
|
|
531
|
+
"detectorsReviewed": [],
|
|
532
|
+
"findingIdsReviewed": [],
|
|
533
|
+
"repairOutcome": "none|not-needed|repaired|partially-repaired|not-repaired|harmful",
|
|
534
|
+
"repairAttempted": false,
|
|
535
|
+
"repairPromptCaptured": false,
|
|
536
|
+
"repairPromptPath": "",
|
|
537
|
+
"repairDiffPath": "",
|
|
538
|
+
"rerunReportPath": "",
|
|
539
|
+
"rerunDecision": "",
|
|
540
|
+
"repairScopeStayedWithinTask": false,
|
|
541
|
+
"repairScopeStayedWithinContract": false,
|
|
542
|
+
"missedFindingsReviewed": true,
|
|
543
|
+
"missedFindingNotes": "",
|
|
544
|
+
"fixtureNeeded": false,
|
|
545
|
+
"fixtureCreated": false,
|
|
546
|
+
"notes": ""
|
|
547
|
+
}
|
|
548
|
+
\`\`\`
|
|
549
|
+
`;
|
|
550
|
+
}
|
|
551
|
+
const evidenceIndexSource = `# Critical Gate Evidence
|
|
552
|
+
|
|
553
|
+
Timestamped reports from observe-only dogfooding runs.
|
|
554
|
+
|
|
555
|
+
| Date | Decision | Findings | Coherence | Scope | Task | Reports |
|
|
556
|
+
| --- | --- | ---: | ---: | ---: | --- | --- |
|
|
557
|
+
`;
|
|
558
|
+
function githubWorkflowSource(version) {
|
|
559
|
+
const actionVersion = version === "latest" ? "latest" : version.replace(/^[~^]/u, "");
|
|
560
|
+
return `name: Critical Gate
|
|
561
|
+
|
|
562
|
+
on:
|
|
563
|
+
pull_request:
|
|
564
|
+
|
|
565
|
+
permissions:
|
|
566
|
+
actions: read
|
|
567
|
+
contents: read
|
|
568
|
+
pull-requests: read
|
|
569
|
+
security-events: write
|
|
570
|
+
|
|
571
|
+
jobs:
|
|
572
|
+
critical-gate:
|
|
573
|
+
name: Advisory diff integrity
|
|
574
|
+
runs-on: ubuntu-latest
|
|
575
|
+
|
|
576
|
+
steps:
|
|
577
|
+
- name: Checkout
|
|
578
|
+
uses: actions/checkout@v6
|
|
579
|
+
with:
|
|
580
|
+
fetch-depth: 0
|
|
581
|
+
|
|
582
|
+
- name: Run Critical Gate
|
|
583
|
+
id: critical-gate
|
|
584
|
+
uses: criticaldeveloper/critical-gate@v2
|
|
585
|
+
continue-on-error: true
|
|
586
|
+
with:
|
|
587
|
+
version: "${actionVersion}"
|
|
588
|
+
task: \${{ github.event.pull_request.title }}
|
|
589
|
+
base: \${{ github.event.pull_request.base.sha }}
|
|
590
|
+
format: sarif
|
|
591
|
+
output: critical-gate.sarif
|
|
592
|
+
|
|
593
|
+
- name: Upload Critical Gate SARIF
|
|
594
|
+
if: always() && hashFiles('critical-gate.sarif') != ''
|
|
595
|
+
uses: github/codeql-action/upload-sarif@v4
|
|
596
|
+
with:
|
|
597
|
+
sarif_file: critical-gate.sarif
|
|
598
|
+
`;
|
|
599
|
+
}
|
|
600
|
+
//# sourceMappingURL=init-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-project.js","sourceRoot":"","sources":["../../src/cli/init-project.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/io.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/cli/io.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/cli/io.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,SAAS,EAAE,KAgBvB,CAAC"}
|
package/dist/cli/io.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
1
2
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { getApiSnapshotOutputDirectory, readGitDiff } from "../index.js";
|
|
3
4
|
export const defaultIo = {
|
|
@@ -8,6 +9,9 @@ export const defaultIo = {
|
|
|
8
9
|
writeFileSync(path, content, "utf8");
|
|
9
10
|
},
|
|
10
11
|
now: () => new Date(),
|
|
12
|
+
getRoot: () => execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
13
|
+
encoding: "utf8"
|
|
14
|
+
}).trim(),
|
|
11
15
|
exists: (path) => existsSync(path),
|
|
12
16
|
readFile: (path) => readFileSync(path, "utf8"),
|
|
13
17
|
chmodFile: (path, mode) => chmodSync(path, mode),
|
package/dist/cli/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/cli/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExF,OAAO,EAAE,6BAA6B,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzE,MAAM,CAAC,MAAM,SAAS,GAAU;IAC9B,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IACzC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAC3C,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QAC3B,SAAS,CAAC,6BAA6B,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9C,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;CAClF,CAAC"}
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/cli/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExF,OAAO,EAAE,6BAA6B,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzE,MAAM,CAAC,MAAM,SAAS,GAAU;IAC9B,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IACzC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAC3C,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QAC3B,SAAS,CAAC,6BAA6B,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IACrB,OAAO,EAAE,GAAG,EAAE,CACZ,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE;QACpD,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC,IAAI,EAAE;IACX,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC;IAC9C,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;CAClF,CAAC"}
|
package/dist/cli/main.d.ts
CHANGED
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,WAAW,UAAwB,CAAC;AAEjD,wBAAgB,IAAI,CAAC,IAAI,WAAwB,EAAE,EAAE,QAAY,GAAG,QAAQ,CAQ3E"}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { renderReport } from "../index.js";
|
|
2
2
|
import { CRITICAL_GATE_VERSION } from "../version.js";
|
|
3
3
|
import { parseCheckArgs, isCommandName } from "./args.js";
|
|
4
|
-
import { runAcceptCommand, runInitAgentCommand, runInitPolicyCommand, runInstallHooksCommand, runSnapshotApiCommand, runTeachCommand } from "./commands.js";
|
|
4
|
+
import { runAcceptCommand, runInitAgentCommand, runInitPolicyCommand, runInitProjectCommand, runInstallHooksCommand, runSnapshotApiCommand, runTeachCommand } from "./commands.js";
|
|
5
5
|
import { getCommandHelpText, getHelpText } from "./help.js";
|
|
6
6
|
import { defaultIo } from "./io.js";
|
|
7
7
|
import { createGateResult } from "./result.js";
|
|
@@ -48,6 +48,9 @@ function runCli(argv, io) {
|
|
|
48
48
|
if (command === "install-hooks") {
|
|
49
49
|
return runInstallHooksCommand(args, io);
|
|
50
50
|
}
|
|
51
|
+
if (command === "init") {
|
|
52
|
+
return runInitProjectCommand(args, io);
|
|
53
|
+
}
|
|
51
54
|
if (command === "init-policy") {
|
|
52
55
|
return runInitPolicyCommand(args, io);
|
|
53
56
|
}
|