cclaw-cli 0.48.11 → 0.48.12
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 +1 -1
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +22 -44
- package/dist/content/node-hooks.d.ts +7 -3
- package/dist/content/node-hooks.js +15 -18
- package/dist/doctor.js +9 -9
- package/dist/install.js +3 -4
- package/dist/types.d.ts +13 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,7 +158,7 @@ If cclaw detects a Node / Python / Go project at init time, a sixth
|
|
|
158
158
|
`pyproject.toml` / `requirements.txt`, `go.mod`). That is the full
|
|
159
159
|
default surface — a new user sees nothing they need to understand yet.
|
|
160
160
|
|
|
161
|
-
Advanced knobs (`
|
|
161
|
+
Advanced knobs (`ironLaws.strictLaws` per-law escapes,
|
|
162
162
|
`tdd.testPathPatterns` / `tdd.productionPathPatterns`,
|
|
163
163
|
`compound.recurrenceThreshold`, `defaultTrack`, `trackHeuristics`,
|
|
164
164
|
`sliceReview`) are **opt-in**: add them by hand when you need them.
|
package/dist/cli.js
CHANGED
|
@@ -828,7 +828,7 @@ async function runCommand(parsed, ctx) {
|
|
|
828
828
|
ctx.stdout.write(`${JSON.stringify({
|
|
829
829
|
track: previewConfig.defaultTrack ?? "standard",
|
|
830
830
|
harnesses: previewConfig.harnesses,
|
|
831
|
-
|
|
831
|
+
strictness: previewConfig.strictness ?? "advisory",
|
|
832
832
|
gitHookGuards: previewConfig.gitHookGuards,
|
|
833
833
|
languageRulePacks: previewConfig.languageRulePacks,
|
|
834
834
|
generatedSurfaces: previewSurfaces
|
package/dist/config.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare function readConfig(projectRoot: string): Promise<CclawConfig>;
|
|
|
42
42
|
* the user set them explicitly. Keeps the default template small and honest:
|
|
43
43
|
* only knobs a new user would meaningfully flip show up.
|
|
44
44
|
*/
|
|
45
|
-
type AdvancedConfigKey = "
|
|
45
|
+
type AdvancedConfigKey = "tddTestGlobs" | "tdd" | "compound" | "defaultTrack" | "languageRulePacks" | "trackHeuristics" | "sliceReview" | "ironLaws";
|
|
46
46
|
/**
|
|
47
47
|
* Options controlling the serialisation shape of `config.yaml`.
|
|
48
48
|
*
|
package/dist/config.js
CHANGED
|
@@ -17,8 +17,6 @@ const ALLOWED_CONFIG_KEYS = new Set([
|
|
|
17
17
|
"flowVersion",
|
|
18
18
|
"harnesses",
|
|
19
19
|
"strictness",
|
|
20
|
-
"promptGuardMode",
|
|
21
|
-
"tddEnforcement",
|
|
22
20
|
"tddTestGlobs",
|
|
23
21
|
"tdd",
|
|
24
22
|
"compound",
|
|
@@ -29,6 +27,16 @@ const ALLOWED_CONFIG_KEYS = new Set([
|
|
|
29
27
|
"sliceReview",
|
|
30
28
|
"ironLaws"
|
|
31
29
|
]);
|
|
30
|
+
/**
|
|
31
|
+
* Config keys removed in the advisory-by-default consolidation. Kept here so
|
|
32
|
+
* the parser can emit a helpful migration error pointing users at the new
|
|
33
|
+
* single `strictness` knob instead of a generic "unknown key" message.
|
|
34
|
+
*/
|
|
35
|
+
const RETIRED_GUARD_CONFIG_KEYS = new Set([
|
|
36
|
+
"promptGuardMode",
|
|
37
|
+
"tddEnforcement",
|
|
38
|
+
"workflowGuardMode"
|
|
39
|
+
]);
|
|
32
40
|
/**
|
|
33
41
|
* Config keys always present in the minimal init template. Everything else
|
|
34
42
|
* is "advanced" — parsed when present, but not pre-populated by `cclaw init`.
|
|
@@ -131,8 +139,6 @@ export function createDefaultConfig(harnesses = DEFAULT_HARNESSES, defaultTrack
|
|
|
131
139
|
flowVersion: FLOW_VERSION,
|
|
132
140
|
harnesses,
|
|
133
141
|
strictness: "advisory",
|
|
134
|
-
promptGuardMode: "advisory",
|
|
135
|
-
tddEnforcement: "advisory",
|
|
136
142
|
tddTestGlobs: [...tddTestPathPatterns],
|
|
137
143
|
tdd: {
|
|
138
144
|
testPathPatterns: tddTestPathPatterns,
|
|
@@ -145,7 +151,6 @@ export function createDefaultConfig(harnesses = DEFAULT_HARNESSES, defaultTrack
|
|
|
145
151
|
defaultTrack,
|
|
146
152
|
languageRulePacks: [],
|
|
147
153
|
ironLaws: {
|
|
148
|
-
mode: "advisory",
|
|
149
154
|
strictLaws: []
|
|
150
155
|
}
|
|
151
156
|
};
|
|
@@ -208,6 +213,12 @@ export async function readConfig(projectRoot) {
|
|
|
208
213
|
const parsed = (parsedUnknown && typeof parsedUnknown === "object"
|
|
209
214
|
? parsedUnknown
|
|
210
215
|
: {});
|
|
216
|
+
const retiredGuardKeys = Object.keys(parsed).filter((key) => RETIRED_GUARD_CONFIG_KEYS.has(key));
|
|
217
|
+
if (retiredGuardKeys.length > 0) {
|
|
218
|
+
throw configValidationError(fullPath, `config key(s) ${retiredGuardKeys.join(", ")} were removed; ` +
|
|
219
|
+
`use the single \`strictness: advisory|strict\` knob instead ` +
|
|
220
|
+
`(advisory is the default). See docs/config.md#strictness for migration.`);
|
|
221
|
+
}
|
|
211
222
|
const unknownKeys = Object.keys(parsed).filter((key) => !ALLOWED_CONFIG_KEYS.has(key));
|
|
212
223
|
if (unknownKeys.length > 0) {
|
|
213
224
|
throw configValidationError(fullPath, `unknown top-level key(s): ${unknownKeys.join(", ")}`);
|
|
@@ -235,29 +246,6 @@ export async function readConfig(projectRoot) {
|
|
|
235
246
|
throw configValidationError(fullPath, `"strictness" must be "advisory" or "strict"`);
|
|
236
247
|
}
|
|
237
248
|
const strictness = strictnessRaw === "strict" ? "strict" : "advisory";
|
|
238
|
-
// Legacy guard fields — keep honouring explicit values for power users who
|
|
239
|
-
// want asymmetric behaviour (e.g. strict prompt guard + advisory TDD).
|
|
240
|
-
// When the user only set `strictness`, both axes inherit from it.
|
|
241
|
-
const hasExplicitPromptGuard = Object.prototype.hasOwnProperty.call(parsed, "promptGuardMode");
|
|
242
|
-
const promptGuardModeRaw = parsed.promptGuardMode;
|
|
243
|
-
if (hasExplicitPromptGuard &&
|
|
244
|
-
promptGuardModeRaw !== "advisory" &&
|
|
245
|
-
promptGuardModeRaw !== "strict") {
|
|
246
|
-
throw configValidationError(fullPath, `"promptGuardMode" must be "advisory" or "strict"`);
|
|
247
|
-
}
|
|
248
|
-
const promptGuardMode = hasExplicitPromptGuard
|
|
249
|
-
? (promptGuardModeRaw === "strict" ? "strict" : "advisory")
|
|
250
|
-
: strictness;
|
|
251
|
-
const hasExplicitTddEnforcement = Object.prototype.hasOwnProperty.call(parsed, "tddEnforcement");
|
|
252
|
-
const tddEnforcementRaw = parsed.tddEnforcement;
|
|
253
|
-
if (hasExplicitTddEnforcement &&
|
|
254
|
-
tddEnforcementRaw !== "advisory" &&
|
|
255
|
-
tddEnforcementRaw !== "strict") {
|
|
256
|
-
throw configValidationError(fullPath, `"tddEnforcement" must be "advisory" or "strict"`);
|
|
257
|
-
}
|
|
258
|
-
const tddEnforcement = hasExplicitTddEnforcement
|
|
259
|
-
? (tddEnforcementRaw === "strict" ? "strict" : "advisory")
|
|
260
|
-
: strictness;
|
|
261
249
|
const tddTestGlobsRaw = parsed.tddTestGlobs;
|
|
262
250
|
const tddTestGlobs = validateStringArray(tddTestGlobsRaw, "tddTestGlobs", fullPath)
|
|
263
251
|
?? [...DEFAULT_TDD_TEST_GLOBS];
|
|
@@ -421,37 +409,31 @@ export async function readConfig(projectRoot) {
|
|
|
421
409
|
if (!isRecord(ironLawsRaw)) {
|
|
422
410
|
throw configValidationError(fullPath, `"ironLaws" must be an object`);
|
|
423
411
|
}
|
|
424
|
-
|
|
412
|
+
if (Object.prototype.hasOwnProperty.call(ironLawsRaw, "mode")) {
|
|
413
|
+
throw configValidationError(fullPath, `"ironLaws.mode" was removed; the project-wide \`strictness\` knob now ` +
|
|
414
|
+
`controls iron-law enforcement. Use \`ironLaws.strictLaws\` for per-law overrides.`);
|
|
415
|
+
}
|
|
416
|
+
const unknownIronLawKeys = Object.keys(ironLawsRaw).filter((key) => key !== "strictLaws");
|
|
425
417
|
if (unknownIronLawKeys.length > 0) {
|
|
426
418
|
throw configValidationError(fullPath, `"ironLaws" has unknown key(s): ${unknownIronLawKeys.join(", ")}`);
|
|
427
419
|
}
|
|
428
|
-
const modeRaw = ironLawsRaw.mode;
|
|
429
|
-
if (modeRaw !== undefined && modeRaw !== "advisory" && modeRaw !== "strict") {
|
|
430
|
-
throw configValidationError(fullPath, `"ironLaws.mode" must be "advisory" or "strict"`);
|
|
431
|
-
}
|
|
432
420
|
const strictLawIdsRaw = validateStringArray(ironLawsRaw.strictLaws, "ironLaws.strictLaws", fullPath) ?? [];
|
|
433
421
|
const unknownStrictLawIds = strictLawIdsRaw.filter((id) => !isIronLawId(id));
|
|
434
422
|
if (unknownStrictLawIds.length > 0) {
|
|
435
423
|
throw configValidationError(fullPath, `"ironLaws.strictLaws" contains unknown law id(s): ${unknownStrictLawIds.join(", ")}`);
|
|
436
424
|
}
|
|
437
425
|
ironLaws = {
|
|
438
|
-
mode: modeRaw === "strict" ? "strict" : "advisory",
|
|
439
426
|
strictLaws: normalizeStrictLawIds(strictLawIdsRaw)
|
|
440
427
|
};
|
|
441
428
|
}
|
|
442
429
|
else {
|
|
443
|
-
ironLaws = {
|
|
444
|
-
mode: strictness,
|
|
445
|
-
strictLaws: []
|
|
446
|
-
};
|
|
430
|
+
ironLaws = { strictLaws: [] };
|
|
447
431
|
}
|
|
448
432
|
return {
|
|
449
433
|
version: parsed.version ?? CCLAW_VERSION,
|
|
450
434
|
flowVersion: parsed.flowVersion ?? FLOW_VERSION,
|
|
451
435
|
harnesses,
|
|
452
436
|
strictness,
|
|
453
|
-
promptGuardMode,
|
|
454
|
-
tddEnforcement,
|
|
455
437
|
tddTestGlobs,
|
|
456
438
|
tdd: {
|
|
457
439
|
testPathPatterns: resolvedTddTestPathPatterns,
|
|
@@ -480,8 +462,6 @@ function buildSerializableConfig(config, options = {}) {
|
|
|
480
462
|
"flowVersion",
|
|
481
463
|
"harnesses",
|
|
482
464
|
"strictness",
|
|
483
|
-
"promptGuardMode",
|
|
484
|
-
"tddEnforcement",
|
|
485
465
|
"tddTestGlobs",
|
|
486
466
|
"tdd",
|
|
487
467
|
"compound",
|
|
@@ -536,8 +516,6 @@ export async function detectAdvancedKeys(projectRoot) {
|
|
|
536
516
|
if (!isRecord(parsedUnknown))
|
|
537
517
|
return new Set();
|
|
538
518
|
const advancedCandidates = [
|
|
539
|
-
"promptGuardMode",
|
|
540
|
-
"tddEnforcement",
|
|
541
519
|
"tddTestGlobs",
|
|
542
520
|
"tdd",
|
|
543
521
|
"compound",
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export interface NodeHookRuntimeOptions {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Single enforcement knob derived from `config.strictness`. Generated hooks
|
|
4
|
+
* embed this value as the default for every guard (prompt, workflow, TDD,
|
|
5
|
+
* iron-laws-coupled blocks). `CCLAW_STRICTNESS` env var overrides at run
|
|
6
|
+
* time; per-law strictness still flows through `iron-laws.json`.
|
|
7
|
+
*/
|
|
8
|
+
strictness?: "advisory" | "strict";
|
|
5
9
|
tddTestPathPatterns?: string[];
|
|
6
10
|
tddProductionPathPatterns?: string[];
|
|
7
11
|
}
|
|
@@ -11,9 +11,7 @@ function normalizePatterns(patterns, fallback) {
|
|
|
11
11
|
* bash/python/jq runtime dependencies.
|
|
12
12
|
*/
|
|
13
13
|
export function nodeHookRuntimeScript(options = {}) {
|
|
14
|
-
const
|
|
15
|
-
const workflowGuardMode = options.workflowGuardMode === "strict" ? "strict" : "advisory";
|
|
16
|
-
const tddEnforcementMode = options.tddEnforcementMode === "strict" ? "strict" : "advisory";
|
|
14
|
+
const strictness = options.strictness === "strict" ? "strict" : "advisory";
|
|
17
15
|
const tddTestPathPatterns = normalizePatterns(options.tddTestPathPatterns, [
|
|
18
16
|
"**/*.test.*",
|
|
19
17
|
"**/tests/**",
|
|
@@ -27,12 +25,17 @@ import process from "node:process";
|
|
|
27
25
|
import { spawn } from "node:child_process";
|
|
28
26
|
|
|
29
27
|
const RUNTIME_ROOT = ${JSON.stringify(RUNTIME_ROOT)};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
// Single strictness default, derived from config.strictness at install time.
|
|
29
|
+
// \`CCLAW_STRICTNESS\` env var overrides for the current process. All guards
|
|
30
|
+
// (prompt, workflow, TDD, iron-laws) route through \`resolveStrictness()\`.
|
|
31
|
+
const DEFAULT_STRICTNESS = ${JSON.stringify(strictness)};
|
|
33
32
|
const DEFAULT_TDD_TEST_PATH_PATTERNS = ${JSON.stringify(tddTestPathPatterns)};
|
|
34
33
|
const DEFAULT_TDD_PRODUCTION_PATH_PATTERNS = ${JSON.stringify(tddProductionPathPatterns)};
|
|
35
34
|
|
|
35
|
+
function resolveStrictness() {
|
|
36
|
+
return process.env.CCLAW_STRICTNESS === "strict" ? "strict" : DEFAULT_STRICTNESS;
|
|
37
|
+
}
|
|
38
|
+
|
|
36
39
|
function toObject(value) {
|
|
37
40
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
38
41
|
return value;
|
|
@@ -1024,9 +1027,7 @@ async function handlePreCompact(runtime) {
|
|
|
1024
1027
|
}
|
|
1025
1028
|
|
|
1026
1029
|
async function handlePromptGuard(runtime) {
|
|
1027
|
-
const mode =
|
|
1028
|
-
? "strict"
|
|
1029
|
-
: DEFAULT_PROMPT_GUARD_MODE;
|
|
1030
|
+
const mode = resolveStrictness();
|
|
1030
1031
|
const stateDir = path.join(runtime.root, RUNTIME_ROOT, "state");
|
|
1031
1032
|
const guardLog = path.join(stateDir, "prompt-guard.jsonl");
|
|
1032
1033
|
|
|
@@ -1202,17 +1203,15 @@ function isProductionPath(rawPath, testPatterns, productionPatterns) {
|
|
|
1202
1203
|
}
|
|
1203
1204
|
|
|
1204
1205
|
async function handleWorkflowGuard(runtime) {
|
|
1205
|
-
const mode =
|
|
1206
|
-
? "strict"
|
|
1207
|
-
: DEFAULT_WORKFLOW_GUARD_MODE;
|
|
1206
|
+
const mode = resolveStrictness();
|
|
1208
1207
|
const maxAgeRaw = process.env.CCLAW_WORKFLOW_GUARD_MAX_AGE_SEC;
|
|
1209
1208
|
const maxAgeSec =
|
|
1210
1209
|
typeof maxAgeRaw === "string" && /^[0-9]+$/u.test(maxAgeRaw)
|
|
1211
1210
|
? Number(maxAgeRaw)
|
|
1212
1211
|
: 1800;
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1212
|
+
// TDD enforcement now follows the same single strictness knob — keeping the
|
|
1213
|
+
// distinct local binding so the downstream block rules stay self-documenting.
|
|
1214
|
+
const tddEnforcement = mode;
|
|
1216
1215
|
|
|
1217
1216
|
const stateDir = path.join(runtime.root, RUNTIME_ROOT, "state");
|
|
1218
1217
|
const guardStateFile = path.join(stateDir, "workflow-guard.json");
|
|
@@ -1513,9 +1512,7 @@ async function handleContextMonitor(runtime) {
|
|
|
1513
1512
|
}
|
|
1514
1513
|
|
|
1515
1514
|
async function handleVerifyCurrentState(runtime) {
|
|
1516
|
-
const mode =
|
|
1517
|
-
? "strict"
|
|
1518
|
-
: DEFAULT_WORKFLOW_GUARD_MODE;
|
|
1515
|
+
const mode = resolveStrictness();
|
|
1519
1516
|
const result = await runCclawInternal(runtime.root, ["verify-current-state", "--quiet"]);
|
|
1520
1517
|
if (result.missingBinary) {
|
|
1521
1518
|
process.stderr.write("[cclaw] hook: cclaw binary is required for verify-current-state\\n");
|
package/dist/doctor.js
CHANGED
|
@@ -483,17 +483,17 @@ export async function doctorChecks(projectRoot, options = {}) {
|
|
|
483
483
|
: `warning: ${RUNTIME_ROOT}/config.yaml uses deprecated "tddTestGlobs". Migrate to "tdd.testPathPatterns".`
|
|
484
484
|
: `no deprecated "tddTestGlobs" key detected in ${RUNTIME_ROOT}/config.yaml`
|
|
485
485
|
});
|
|
486
|
-
const
|
|
487
|
-
const
|
|
488
|
-
let
|
|
489
|
-
if (await exists(
|
|
490
|
-
const
|
|
491
|
-
|
|
486
|
+
const expectedStrictness = parsedConfig.strictness === "strict" ? "strict" : "advisory";
|
|
487
|
+
const hookRuntimePath = path.join(projectRoot, RUNTIME_ROOT, "hooks", "run-hook.mjs");
|
|
488
|
+
let strictnessOk = false;
|
|
489
|
+
if (await exists(hookRuntimePath)) {
|
|
490
|
+
const runtimeContent = await fs.readFile(hookRuntimePath, "utf8");
|
|
491
|
+
strictnessOk = runtimeContent.includes(`const DEFAULT_STRICTNESS = "${expectedStrictness}"`);
|
|
492
492
|
}
|
|
493
493
|
checks.push({
|
|
494
|
-
name: "hook:
|
|
495
|
-
ok:
|
|
496
|
-
details: `${
|
|
494
|
+
name: "hook:runtime:strictness",
|
|
495
|
+
ok: strictnessOk,
|
|
496
|
+
details: `${hookRuntimePath} must embed DEFAULT_STRICTNESS = "${expectedStrictness}" matching config.strictness`
|
|
497
497
|
});
|
|
498
498
|
if (parsedConfig.gitHookGuards === true) {
|
|
499
499
|
const runtimePreCommit = path.join(projectRoot, RUNTIME_ROOT, "hooks", "git", "pre-commit.mjs");
|
package/dist/install.js
CHANGED
|
@@ -720,15 +720,14 @@ async function writeHooks(projectRoot, config) {
|
|
|
720
720
|
const stateDir = runtimePath(projectRoot, "state");
|
|
721
721
|
await ensureDir(hooksDir);
|
|
722
722
|
await ensureDir(stateDir);
|
|
723
|
+
const effectiveStrictness = config.strictness ?? "advisory";
|
|
723
724
|
await writeFileSafe(runtimePath(projectRoot, "state", "iron-laws.json"), `${JSON.stringify(ironLawRuntimeDocument({
|
|
724
|
-
mode:
|
|
725
|
+
mode: effectiveStrictness,
|
|
725
726
|
strictLaws: config.ironLaws?.strictLaws
|
|
726
727
|
}), null, 2)}\n`);
|
|
727
728
|
await writeFileSafe(path.join(hooksDir, "stage-complete.mjs"), stageCompleteScript());
|
|
728
729
|
await writeFileSafe(path.join(hooksDir, "run-hook.mjs"), nodeHookRuntimeScript({
|
|
729
|
-
|
|
730
|
-
workflowGuardMode: config.strictness ?? "advisory",
|
|
731
|
-
tddEnforcementMode: config.tddEnforcement ?? config.strictness ?? "advisory",
|
|
730
|
+
strictness: effectiveStrictness,
|
|
732
731
|
tddTestPathPatterns: config.tdd?.testPathPatterns ?? config.tddTestGlobs,
|
|
733
732
|
tddProductionPathPatterns: config.tdd?.productionPathPatterns
|
|
734
733
|
}));
|
package/dist/types.d.ts
CHANGED
|
@@ -110,7 +110,12 @@ export interface CompoundConfig {
|
|
|
110
110
|
recurrenceThreshold?: number;
|
|
111
111
|
}
|
|
112
112
|
export interface IronLawsConfig {
|
|
113
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Per-law escape hatch: list the iron-law ids that must always be strict,
|
|
115
|
+
* independent of the project-wide `strictness` knob. Kept as an advanced
|
|
116
|
+
* override for teams that want e.g. `tdd-red-before-write` strict while the
|
|
117
|
+
* rest of the pipeline stays advisory.
|
|
118
|
+
*/
|
|
114
119
|
strictLaws?: string[];
|
|
115
120
|
}
|
|
116
121
|
export interface CclawConfig {
|
|
@@ -118,30 +123,16 @@ export interface CclawConfig {
|
|
|
118
123
|
flowVersion: string;
|
|
119
124
|
harnesses: HarnessId[];
|
|
120
125
|
/**
|
|
121
|
-
* Single
|
|
122
|
-
*
|
|
123
|
-
*
|
|
126
|
+
* Single knob that controls enforcement behaviour of all hook-driven guards
|
|
127
|
+
* (prompt guard, workflow guard, TDD enforcement, iron laws). Default:
|
|
128
|
+
* `"advisory"` — hooks append a stderr nudge and exit 0. `"strict"` flips
|
|
129
|
+
* the same hooks to fail-closed (non-zero exit) so the harness refuses the
|
|
130
|
+
* offending action.
|
|
124
131
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* prompt guard, advisory TDD) can still set the legacy fields directly —
|
|
128
|
-
* explicit per-axis values override the derived strictness.
|
|
132
|
+
* Per-law escapes live on `ironLaws.strictLaws` for teams that need to keep
|
|
133
|
+
* specific iron laws strict while the project-wide knob stays advisory.
|
|
129
134
|
*/
|
|
130
135
|
strictness?: "advisory" | "strict";
|
|
131
|
-
/**
|
|
132
|
-
* Prompt guard behavior for runtime write-risk detection hooks.
|
|
133
|
-
*
|
|
134
|
-
* Since v0.43.0 this is an advanced override. Prefer `strictness` in new
|
|
135
|
-
* configs; set this explicitly only when you need strict prompt guarding
|
|
136
|
-
* while keeping TDD advisory, or vice versa.
|
|
137
|
-
*/
|
|
138
|
-
promptGuardMode?: "advisory" | "strict";
|
|
139
|
-
/**
|
|
140
|
-
* TDD RED -> GREEN -> REFACTOR enforcement mode used by workflow guard hooks.
|
|
141
|
-
*
|
|
142
|
-
* Since v0.43.0 this is an advanced override — see `strictness`.
|
|
143
|
-
*/
|
|
144
|
-
tddEnforcement?: "advisory" | "strict";
|
|
145
136
|
/**
|
|
146
137
|
* Legacy alias for test-side path detection in workflow-guard.
|
|
147
138
|
* Prefer `tdd.testPathPatterns` in new configs.
|