@devrik-tools/claude-gates 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +17 -0
- package/README.es.md +219 -0
- package/README.md +222 -0
- package/cli/__tests__/config.test.mjs +101 -0
- package/cli/__tests__/init-flags.test.mjs +111 -0
- package/cli/__tests__/registry-gates-consistency.test.mjs +44 -0
- package/cli/__tests__/selection.test.mjs +200 -0
- package/cli/config.mjs +113 -0
- package/cli/constants.mjs +36 -0
- package/cli/index.mjs +97 -0
- package/cli/init.mjs +256 -0
- package/cli/install.mjs +80 -0
- package/cli/materialize.mjs +51 -0
- package/cli/registry.mjs +127 -0
- package/cli/selection.mjs +83 -0
- package/package.json +73 -0
- package/plugins/gates/.claude-plugin/plugin.json +9 -0
- package/plugins/gates/hooks/gates/audit-before-build/index.mjs +88 -0
- package/plugins/gates/hooks/gates/audit-before-build/test.mjs +92 -0
- package/plugins/gates/hooks/gates/bash-commands/index.mjs +233 -0
- package/plugins/gates/hooks/gates/bash-commands/test.mjs +113 -0
- package/plugins/gates/hooks/gates/brief-before-delegate/index.mjs +177 -0
- package/plugins/gates/hooks/gates/brief-before-delegate/test.mjs +111 -0
- package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +456 -0
- package/plugins/gates/hooks/gates/circuit-breaker/test.mjs +143 -0
- package/plugins/gates/hooks/gates/dependency-skills/index.mjs +118 -0
- package/plugins/gates/hooks/gates/dependency-skills/test.mjs +109 -0
- package/plugins/gates/hooks/gates/diagnosis-before-patch/index.mjs +49 -0
- package/plugins/gates/hooks/gates/diagnosis-before-patch/test.mjs +68 -0
- package/plugins/gates/hooks/gates/feature-catalog/index.mjs +100 -0
- package/plugins/gates/hooks/gates/feature-catalog/test.mjs +97 -0
- package/plugins/gates/hooks/gates/forge-flow/index.mjs +112 -0
- package/plugins/gates/hooks/gates/forge-flow/test.mjs +135 -0
- package/plugins/gates/hooks/gates/implementation-pipeline/index.mjs +186 -0
- package/plugins/gates/hooks/gates/implementation-pipeline/test.mjs +86 -0
- package/plugins/gates/hooks/gates/intent-flow/index.mjs +238 -0
- package/plugins/gates/hooks/gates/intent-flow/test.mjs +136 -0
- package/plugins/gates/hooks/gates/mandatory-flow/index.mjs +166 -0
- package/plugins/gates/hooks/gates/mandatory-flow/test.mjs +119 -0
- package/plugins/gates/hooks/gates/neutral-spanish/index.mjs +85 -0
- package/plugins/gates/hooks/gates/neutral-spanish/test.mjs +65 -0
- package/plugins/gates/hooks/gates/never-assume/index.mjs +55 -0
- package/plugins/gates/hooks/gates/never-assume/test.mjs +78 -0
- package/plugins/gates/hooks/gates/no-blocking/index.mjs +142 -0
- package/plugins/gates/hooks/gates/no-blocking/test.mjs +108 -0
- package/plugins/gates/hooks/gates/no-memory-dependency/index.mjs +120 -0
- package/plugins/gates/hooks/gates/no-memory-dependency/test.mjs +106 -0
- package/plugins/gates/hooks/gates/no-reconfirm/index.mjs +202 -0
- package/plugins/gates/hooks/gates/no-reconfirm/test.mjs +131 -0
- package/plugins/gates/hooks/gates/protected-paths/index.mjs +147 -0
- package/plugins/gates/hooks/gates/protected-paths/test.mjs +75 -0
- package/plugins/gates/hooks/gates/recurrence-lock/index.mjs +64 -0
- package/plugins/gates/hooks/gates/recurrence-lock/test.mjs +99 -0
- package/plugins/gates/hooks/gates/reuse-before-build/index.mjs +150 -0
- package/plugins/gates/hooks/gates/reuse-before-build/test.mjs +101 -0
- package/plugins/gates/hooks/gates/risk-level/index.mjs +203 -0
- package/plugins/gates/hooks/gates/risk-level/test.mjs +125 -0
- package/plugins/gates/hooks/gates/root-cause-first/index.mjs +50 -0
- package/plugins/gates/hooks/gates/root-cause-first/test.mjs +73 -0
- package/plugins/gates/hooks/gates/root-whitelist/index.mjs +111 -0
- package/plugins/gates/hooks/gates/root-whitelist/test.mjs +80 -0
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/index.mjs +99 -0
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/test.mjs +78 -0
- package/plugins/gates/hooks/gates/sdd-specs/index.mjs +251 -0
- package/plugins/gates/hooks/gates/sdd-specs/test.mjs +163 -0
- package/plugins/gates/hooks/gates/test-after-implementation/index.mjs +101 -0
- package/plugins/gates/hooks/gates/test-after-implementation/test.mjs +81 -0
- package/plugins/gates/hooks/gates/test-matrix/index.mjs +181 -0
- package/plugins/gates/hooks/gates/test-matrix/test.mjs +87 -0
- package/plugins/gates/hooks/gates/tool-map/index.mjs +140 -0
- package/plugins/gates/hooks/gates/tool-map/test.mjs +87 -0
- package/plugins/gates/hooks/hooks.json +266 -0
- package/plugins/gates/hooks/lib/__tests__/config.test.mjs +154 -0
- package/plugins/gates/hooks/lib/__tests__/hook-io.test.mjs +154 -0
- package/plugins/gates/hooks/lib/config.mjs +165 -0
- package/plugins/gates/hooks/lib/hook-io.mjs +208 -0
- package/plugins/tasks/hooks/lib/__tests__/task-store.test.mjs +132 -0
- package/plugins/tasks/hooks/lib/task-store.mjs +159 -0
- package/plugins/tasks/hooks/register-requests.mjs +108 -0
- package/registry.json +668 -0
package/registry.json
ADDED
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gateVersion": "3.0.0",
|
|
3
|
+
"families": [
|
|
4
|
+
{
|
|
5
|
+
"id": "security",
|
|
6
|
+
"name": "Security",
|
|
7
|
+
"description": "Deterministic blocks on destructive commands, sensitive paths and file placement.",
|
|
8
|
+
"gates": [
|
|
9
|
+
{
|
|
10
|
+
"id": "bash-commands",
|
|
11
|
+
"configKey": "blockDestructiveShellCommands",
|
|
12
|
+
"default": true,
|
|
13
|
+
"event": "PreToolUse",
|
|
14
|
+
"tools": [
|
|
15
|
+
"shell",
|
|
16
|
+
"delegation"
|
|
17
|
+
],
|
|
18
|
+
"script": "gates/bash-commands/index.mjs",
|
|
19
|
+
"description": "Denies git reset --hard, rm -rf, force push, taskkill by image, and unauthorized remote publish.",
|
|
20
|
+
"params": [
|
|
21
|
+
{
|
|
22
|
+
"name": "denyPatterns",
|
|
23
|
+
"type": "string[]",
|
|
24
|
+
"description": "Regex sources of destructive commands to deny. Replaces the built-in list."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "rmRfProtectedAreas",
|
|
28
|
+
"type": "string[]",
|
|
29
|
+
"description": "Paths that rm -rf may not target (e.g. /, *, src, tests)."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "embeddedInterpreterEnabled",
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"description": "Whether to block node/python -e that does raw file ops. Off by default."
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "protected-paths",
|
|
40
|
+
"configKey": "blockWritesToProtectedPaths",
|
|
41
|
+
"default": true,
|
|
42
|
+
"event": "PreToolUse",
|
|
43
|
+
"tools": [
|
|
44
|
+
"write",
|
|
45
|
+
"shell"
|
|
46
|
+
],
|
|
47
|
+
"description": "Denies writes to .env, lockfiles and the harness itself.",
|
|
48
|
+
"script": "gates/protected-paths/index.mjs",
|
|
49
|
+
"params": [
|
|
50
|
+
{
|
|
51
|
+
"name": "protectedPaths",
|
|
52
|
+
"type": "string[]",
|
|
53
|
+
"description": "Path fragments no write or mutating command may target."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "mutatingCommands",
|
|
57
|
+
"type": "string[]",
|
|
58
|
+
"description": "Shell command names treated as mutating (touch, rm, cp, mv, sed -i, tee, chmod...)."
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "root-whitelist",
|
|
64
|
+
"configKey": "blockPathsOutsideRootWhitelist",
|
|
65
|
+
"default": true,
|
|
66
|
+
"event": "PreToolUse",
|
|
67
|
+
"tools": [
|
|
68
|
+
"write"
|
|
69
|
+
],
|
|
70
|
+
"description": "Denies new root-level files/folders outside the project's whitelist.",
|
|
71
|
+
"script": "gates/root-whitelist/index.mjs",
|
|
72
|
+
"params": [
|
|
73
|
+
{
|
|
74
|
+
"name": "rootFilesWhitelist",
|
|
75
|
+
"type": "string[]",
|
|
76
|
+
"description": "Root-level file names allowed to be created."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "rootFoldersWhitelist",
|
|
80
|
+
"type": "string[]",
|
|
81
|
+
"description": "Root-level folder names allowed to be created."
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "no-blocking",
|
|
87
|
+
"configKey": "blockWaitingCommands",
|
|
88
|
+
"default": false,
|
|
89
|
+
"event": "PreToolUse",
|
|
90
|
+
"tools": [
|
|
91
|
+
"shell",
|
|
92
|
+
"delegation"
|
|
93
|
+
],
|
|
94
|
+
"description": "Denies sleep, tail -f, polling loops and foreground servers.",
|
|
95
|
+
"script": "gates/no-blocking/index.mjs",
|
|
96
|
+
"params": [
|
|
97
|
+
{
|
|
98
|
+
"name": "blockingPatterns",
|
|
99
|
+
"type": "string[]",
|
|
100
|
+
"description": "Regex sources of blocking/waiting forms to deny."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "waitJustifiedMarker",
|
|
104
|
+
"type": "string",
|
|
105
|
+
"description": "Comment marker that authorizes a justified wait as an escape hatch."
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "delegation",
|
|
113
|
+
"name": "Delegation",
|
|
114
|
+
"description": "Requirements on the brief of a subagent delegation.",
|
|
115
|
+
"gates": [
|
|
116
|
+
{
|
|
117
|
+
"id": "brief-before-delegate",
|
|
118
|
+
"configKey": "requireBriefBeforeDelegating",
|
|
119
|
+
"default": false,
|
|
120
|
+
"event": "PreToolUse",
|
|
121
|
+
"tools": [
|
|
122
|
+
"delegation"
|
|
123
|
+
],
|
|
124
|
+
"description": "Requires goal, steps and done-when criteria in the prompt.",
|
|
125
|
+
"script": "gates/brief-before-delegate/index.mjs",
|
|
126
|
+
"params": [
|
|
127
|
+
{
|
|
128
|
+
"name": "minBriefLength",
|
|
129
|
+
"type": "number",
|
|
130
|
+
"description": "Minimum brief length before it is considered complete."
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "readOnlySubagents",
|
|
134
|
+
"type": "string[]",
|
|
135
|
+
"description": "Subagent types exempt from the brief requirement (read-only work)."
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "intent-flow",
|
|
141
|
+
"configKey": "requireScopeListBeforeDelegating",
|
|
142
|
+
"default": false,
|
|
143
|
+
"event": "PreToolUse",
|
|
144
|
+
"tools": [
|
|
145
|
+
"delegation"
|
|
146
|
+
],
|
|
147
|
+
"description": "Requires IN SCOPE / OUT OF SCOPE / EDGE CASES sections.",
|
|
148
|
+
"script": "gates/intent-flow/index.mjs",
|
|
149
|
+
"params": [
|
|
150
|
+
{
|
|
151
|
+
"name": "highImpactPatterns",
|
|
152
|
+
"type": "string[]",
|
|
153
|
+
"description": "Regex sources for high-impact work whose scope declaration is enforced."
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "readOnlySubagents",
|
|
157
|
+
"type": "string[]",
|
|
158
|
+
"description": "Subagent types exempt from the scope-list requirement."
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": "risk-level",
|
|
164
|
+
"configKey": "requireDeclaredRiskLevel",
|
|
165
|
+
"default": false,
|
|
166
|
+
"event": "PreToolUse",
|
|
167
|
+
"tools": [
|
|
168
|
+
"delegation"
|
|
169
|
+
],
|
|
170
|
+
"description": "Requires LEVEL: QUESTION|MICRO|STANDARD|HIGH-RISK consistent with the request.",
|
|
171
|
+
"script": "gates/risk-level/index.mjs",
|
|
172
|
+
"params": [
|
|
173
|
+
{
|
|
174
|
+
"name": "highImpactPatterns",
|
|
175
|
+
"type": "string[]",
|
|
176
|
+
"description": "Regex sources for high-impact signals that demand a declared level."
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "readOnlySubagents",
|
|
180
|
+
"type": "string[]",
|
|
181
|
+
"description": "Subagent types exempt from the risk-level requirement."
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"id": "circuit-breaker",
|
|
187
|
+
"configKey": "requireCircuitBreakerOnDelegation",
|
|
188
|
+
"default": false,
|
|
189
|
+
"event": "PreToolUse",
|
|
190
|
+
"tools": [
|
|
191
|
+
"delegation"
|
|
192
|
+
],
|
|
193
|
+
"description": "Cuts the same delegation retried without substantial changes.",
|
|
194
|
+
"script": "gates/circuit-breaker/index.mjs",
|
|
195
|
+
"params": [
|
|
196
|
+
{
|
|
197
|
+
"name": "retryThreshold",
|
|
198
|
+
"type": "number",
|
|
199
|
+
"description": "Identical consecutive retries before the delegation is cut."
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "similarityThreshold",
|
|
203
|
+
"type": "number",
|
|
204
|
+
"description": "Dice similarity (0-1) above which two prompts count as the same."
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"id": "no-memory-dependency",
|
|
210
|
+
"configKey": "warnMemoryDependencyInBrief",
|
|
211
|
+
"default": false,
|
|
212
|
+
"event": "PreToolUse",
|
|
213
|
+
"tools": [
|
|
214
|
+
"delegation"
|
|
215
|
+
],
|
|
216
|
+
"description": "Warns when the brief relies on the subagent remembering the conversation.",
|
|
217
|
+
"script": "gates/no-memory-dependency/index.mjs",
|
|
218
|
+
"params": [
|
|
219
|
+
{
|
|
220
|
+
"name": "memoryDependencyPatterns",
|
|
221
|
+
"type": "string[]",
|
|
222
|
+
"description": "Regex sources for phrases that lean on the subagent's memory."
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"id": "sdd",
|
|
230
|
+
"name": "Spec-driven flow",
|
|
231
|
+
"description": "Only meaningful when the project adopted spec-driven development (feature list, specs).",
|
|
232
|
+
"gates": [
|
|
233
|
+
{
|
|
234
|
+
"id": "feature-catalog",
|
|
235
|
+
"configKey": "requireFeatureCatalog",
|
|
236
|
+
"default": true,
|
|
237
|
+
"event": "PreToolUse",
|
|
238
|
+
"tools": [
|
|
239
|
+
"write"
|
|
240
|
+
],
|
|
241
|
+
"description": "Single in_progress; done requires asserts and review.",
|
|
242
|
+
"script": "gates/feature-catalog/index.mjs",
|
|
243
|
+
"params": [
|
|
244
|
+
{
|
|
245
|
+
"name": "catalogFileName",
|
|
246
|
+
"type": "string",
|
|
247
|
+
"description": "Name of the feature catalog file (default feature_list.json)."
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"name": "maxInProgress",
|
|
251
|
+
"type": "number",
|
|
252
|
+
"description": "Maximum features allowed in_progress at once."
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"id": "sdd-specs",
|
|
258
|
+
"configKey": "requireSpecBeforeImplementing",
|
|
259
|
+
"default": false,
|
|
260
|
+
"event": "PreToolUse",
|
|
261
|
+
"tools": [
|
|
262
|
+
"write",
|
|
263
|
+
"delegation"
|
|
264
|
+
],
|
|
265
|
+
"description": "Non-empty requirements/design/tasks before in_progress.",
|
|
266
|
+
"script": "gates/sdd-specs/index.mjs",
|
|
267
|
+
"params": [
|
|
268
|
+
{
|
|
269
|
+
"name": "catalogLocations",
|
|
270
|
+
"type": "string[]",
|
|
271
|
+
"description": "Paths searched for the feature catalog."
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"name": "exemptSubagents",
|
|
275
|
+
"type": "string[]",
|
|
276
|
+
"description": "Subagent types exempt from the spec requirement."
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"id": "implementation-pipeline",
|
|
282
|
+
"configKey": "requireImplementationPipeline",
|
|
283
|
+
"default": false,
|
|
284
|
+
"event": "PreToolUse",
|
|
285
|
+
"tools": [
|
|
286
|
+
"delegation"
|
|
287
|
+
],
|
|
288
|
+
"description": "Definition, writing, validation, QA and closure declared before building.",
|
|
289
|
+
"script": "gates/implementation-pipeline/index.mjs",
|
|
290
|
+
"params": [
|
|
291
|
+
{
|
|
292
|
+
"name": "builderSubagents",
|
|
293
|
+
"type": "string[]",
|
|
294
|
+
"description": "Subagent types that count as builders (subject to the pipeline)."
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"name": "exemptSubagents",
|
|
298
|
+
"type": "string[]",
|
|
299
|
+
"description": "Subagent types exempt from the pipeline requirement."
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"id": "mandatory-flow",
|
|
305
|
+
"configKey": "requireLiveTaskWhenImplementing",
|
|
306
|
+
"default": false,
|
|
307
|
+
"event": "PreToolUse",
|
|
308
|
+
"tools": [
|
|
309
|
+
"delegation"
|
|
310
|
+
],
|
|
311
|
+
"description": "Requires an active task with a contract before implementing.",
|
|
312
|
+
"script": "gates/mandatory-flow/index.mjs",
|
|
313
|
+
"params": [
|
|
314
|
+
{
|
|
315
|
+
"name": "activePointerPath",
|
|
316
|
+
"type": "string",
|
|
317
|
+
"description": "Path to the active-pipeline pointer file."
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"name": "exemptSubagents",
|
|
321
|
+
"type": "string[]",
|
|
322
|
+
"description": "Subagent types exempt from the live-task requirement."
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"id": "test-matrix",
|
|
328
|
+
"configKey": "requireTestMatrixWhenImplementing",
|
|
329
|
+
"default": false,
|
|
330
|
+
"event": "PreToolUse",
|
|
331
|
+
"tools": [
|
|
332
|
+
"delegation"
|
|
333
|
+
],
|
|
334
|
+
"description": "Requires a test matrix (types the requirement makes mandatory) in the brief.",
|
|
335
|
+
"script": "gates/test-matrix/index.mjs",
|
|
336
|
+
"params": [
|
|
337
|
+
{
|
|
338
|
+
"name": "e2eSignals",
|
|
339
|
+
"type": "string[]",
|
|
340
|
+
"description": "Regex sources that make an E2E row mandatory (money, auth, data...)."
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"name": "visualSignals",
|
|
344
|
+
"type": "string[]",
|
|
345
|
+
"description": "Regex sources that make a visual/QA row mandatory (UI signals)."
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"name": "exemptSubagents",
|
|
349
|
+
"type": "string[]",
|
|
350
|
+
"description": "Subagent types exempt from the test-matrix requirement."
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"id": "quality",
|
|
358
|
+
"name": "Quality and hygiene",
|
|
359
|
+
"description": "Dependencies, diagnosis before patching, assumptions and language.",
|
|
360
|
+
"gates": [
|
|
361
|
+
{
|
|
362
|
+
"id": "dependency-skills",
|
|
363
|
+
"configKey": "requireSkillForNewDependency",
|
|
364
|
+
"default": true,
|
|
365
|
+
"event": "PreToolUse",
|
|
366
|
+
"tools": [
|
|
367
|
+
"write"
|
|
368
|
+
],
|
|
369
|
+
"description": "A new direct dependency requires a current skill.",
|
|
370
|
+
"script": "gates/dependency-skills/index.mjs",
|
|
371
|
+
"params": [
|
|
372
|
+
{
|
|
373
|
+
"name": "depsWithoutOwnApi",
|
|
374
|
+
"type": "string[]",
|
|
375
|
+
"description": "Dependencies exempt because they have no API of their own."
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"name": "projectSkillsDir",
|
|
379
|
+
"type": "string",
|
|
380
|
+
"description": "Directory where the project's skills live."
|
|
381
|
+
}
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"id": "root-cause-first",
|
|
386
|
+
"configKey": "requireRootCauseBeforePatch",
|
|
387
|
+
"default": false,
|
|
388
|
+
"event": "PreToolUse",
|
|
389
|
+
"tools": [
|
|
390
|
+
"write",
|
|
391
|
+
"delegation"
|
|
392
|
+
],
|
|
393
|
+
"description": "Requires an origin-to-symptom diagnosis before a patch.",
|
|
394
|
+
"script": "gates/root-cause-first/index.mjs",
|
|
395
|
+
"params": [
|
|
396
|
+
{
|
|
397
|
+
"name": "patchMarkerPatterns",
|
|
398
|
+
"type": "string[]",
|
|
399
|
+
"description": "Regex sources for temporary-patch markers that require a diagnosis."
|
|
400
|
+
}
|
|
401
|
+
]
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"id": "audit-before-build",
|
|
405
|
+
"configKey": "requireAuditBeforeBuilding",
|
|
406
|
+
"default": false,
|
|
407
|
+
"event": "PreToolUse",
|
|
408
|
+
"tools": [
|
|
409
|
+
"write",
|
|
410
|
+
"delegation"
|
|
411
|
+
],
|
|
412
|
+
"description": "Before a new script/gate, state that no existing tool covers it.",
|
|
413
|
+
"script": "gates/audit-before-build/index.mjs",
|
|
414
|
+
"params": [
|
|
415
|
+
{
|
|
416
|
+
"name": "executableExtensions",
|
|
417
|
+
"type": "string[]",
|
|
418
|
+
"description": "File extensions treated as executable tools."
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"name": "toolFolders",
|
|
422
|
+
"type": "string[]",
|
|
423
|
+
"description": "Folders where a new tool triggers the audit requirement."
|
|
424
|
+
}
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"id": "never-assume",
|
|
429
|
+
"configKey": "requireVerificationBeforeAssuming",
|
|
430
|
+
"default": false,
|
|
431
|
+
"event": "PreToolUse",
|
|
432
|
+
"tools": [
|
|
433
|
+
"write",
|
|
434
|
+
"delegation"
|
|
435
|
+
],
|
|
436
|
+
"description": "Flags unverified assumptions in briefs and code.",
|
|
437
|
+
"script": "gates/never-assume/index.mjs",
|
|
438
|
+
"params": [
|
|
439
|
+
{
|
|
440
|
+
"name": "conjecturePatterns",
|
|
441
|
+
"type": "string[]",
|
|
442
|
+
"description": "Regex sources for conjecture phrases (I assume, probably, should be...)."
|
|
443
|
+
}
|
|
444
|
+
]
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"id": "rule-skill-autodiscovery",
|
|
448
|
+
"configKey": "autodiscoverRulesAndSkills",
|
|
449
|
+
"default": false,
|
|
450
|
+
"event": "PreToolUse",
|
|
451
|
+
"tools": [
|
|
452
|
+
"execution",
|
|
453
|
+
"delegation"
|
|
454
|
+
],
|
|
455
|
+
"description": "Loads gates declared by the project's rules/*.mjs and skills/*/gate.mjs.",
|
|
456
|
+
"script": "gates/rule-skill-autodiscovery/index.mjs",
|
|
457
|
+
"params": [
|
|
458
|
+
{
|
|
459
|
+
"name": "rulesDir",
|
|
460
|
+
"type": "string",
|
|
461
|
+
"description": "Directory scanned for rule gate modules."
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"name": "gateFileNames",
|
|
465
|
+
"type": "string[]",
|
|
466
|
+
"description": "File names recognized as a skill/rule gate."
|
|
467
|
+
}
|
|
468
|
+
]
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"id": "recurrence-lock",
|
|
472
|
+
"configKey": "blockRegisteredRecurrences",
|
|
473
|
+
"default": true,
|
|
474
|
+
"event": "PreToolUse",
|
|
475
|
+
"tools": [
|
|
476
|
+
"execution",
|
|
477
|
+
"delegation"
|
|
478
|
+
],
|
|
479
|
+
"description": "A second occurrence of a defect class requires its deterministic block.",
|
|
480
|
+
"script": "gates/recurrence-lock/index.mjs",
|
|
481
|
+
"params": [
|
|
482
|
+
{
|
|
483
|
+
"name": "thresholdAppearances",
|
|
484
|
+
"type": "number",
|
|
485
|
+
"description": "Appearances of a defect class before its block is required."
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"id": "test-after-implementation",
|
|
491
|
+
"configKey": "warnTestWrittenAfterImplementation",
|
|
492
|
+
"default": false,
|
|
493
|
+
"event": "PreToolUse",
|
|
494
|
+
"tools": [
|
|
495
|
+
"write"
|
|
496
|
+
],
|
|
497
|
+
"description": "Warns when a test is created after its paired implementation.",
|
|
498
|
+
"script": "gates/test-after-implementation/index.mjs",
|
|
499
|
+
"params": [
|
|
500
|
+
{
|
|
501
|
+
"name": "implementationExtensions",
|
|
502
|
+
"type": "string[]",
|
|
503
|
+
"description": "Source extensions whose paired test is checked."
|
|
504
|
+
}
|
|
505
|
+
]
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"id": "no-reconfirm",
|
|
509
|
+
"configKey": "requireNoReconfirmOfApproved",
|
|
510
|
+
"default": true,
|
|
511
|
+
"event": "PreToolUse",
|
|
512
|
+
"tools": [
|
|
513
|
+
"question"
|
|
514
|
+
],
|
|
515
|
+
"description": "Never re-ask what the user already answered.",
|
|
516
|
+
"script": "gates/no-reconfirm/index.mjs",
|
|
517
|
+
"params": [
|
|
518
|
+
{
|
|
519
|
+
"name": "overlapThreshold",
|
|
520
|
+
"type": "number",
|
|
521
|
+
"description": "Word-overlap ratio (0-1) above which a question counts as a re-ask."
|
|
522
|
+
}
|
|
523
|
+
]
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"id": "neutral-spanish",
|
|
527
|
+
"configKey": "warnNonNeutralSpanish",
|
|
528
|
+
"default": true,
|
|
529
|
+
"event": "PreToolUse",
|
|
530
|
+
"tools": [
|
|
531
|
+
"write"
|
|
532
|
+
],
|
|
533
|
+
"description": "Warns on voseo or regional lexicon in written text.",
|
|
534
|
+
"script": "gates/neutral-spanish/index.mjs",
|
|
535
|
+
"params": [
|
|
536
|
+
{
|
|
537
|
+
"name": "regionalMarkers",
|
|
538
|
+
"type": "string[]",
|
|
539
|
+
"description": "Regional words to warn about. Replaces the built-in list."
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"id": "diagnosis-before-patch",
|
|
545
|
+
"configKey": "warnTimeoutChangeWithoutDiagnosis",
|
|
546
|
+
"default": true,
|
|
547
|
+
"event": "PreToolUse",
|
|
548
|
+
"tools": [
|
|
549
|
+
"write"
|
|
550
|
+
],
|
|
551
|
+
"description": "Warns when timeouts/retries change without evidence.",
|
|
552
|
+
"script": "gates/diagnosis-before-patch/index.mjs",
|
|
553
|
+
"params": [
|
|
554
|
+
{
|
|
555
|
+
"name": "timeoutPatterns",
|
|
556
|
+
"type": "string[]",
|
|
557
|
+
"description": "Regex sources for timeout/deadline/retry keys to watch."
|
|
558
|
+
}
|
|
559
|
+
]
|
|
560
|
+
}
|
|
561
|
+
]
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
"id": "discovery",
|
|
565
|
+
"name": "Tool discovery",
|
|
566
|
+
"description": "Do not reinvent the wheel: consult a per-project tool map before building.",
|
|
567
|
+
"gates": [
|
|
568
|
+
{
|
|
569
|
+
"id": "reuse-before-build",
|
|
570
|
+
"configKey": "requireReuseCheckBeforeBuilding",
|
|
571
|
+
"default": false,
|
|
572
|
+
"event": "PreToolUse",
|
|
573
|
+
"tools": [
|
|
574
|
+
"write",
|
|
575
|
+
"delegation"
|
|
576
|
+
],
|
|
577
|
+
"description": "Consults the project tool map; blocks building a tool absent from it without an audit.",
|
|
578
|
+
"script": "gates/reuse-before-build/index.mjs",
|
|
579
|
+
"params": [
|
|
580
|
+
{
|
|
581
|
+
"name": "toolMapFile",
|
|
582
|
+
"type": "string",
|
|
583
|
+
"description": "Path to the per-project tool map (default .ai/tool-map.json)."
|
|
584
|
+
}
|
|
585
|
+
]
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
"id": "tool-map",
|
|
589
|
+
"configKey": "maintainToolMap",
|
|
590
|
+
"default": false,
|
|
591
|
+
"event": "PreToolUse",
|
|
592
|
+
"tools": [
|
|
593
|
+
"write"
|
|
594
|
+
],
|
|
595
|
+
"description": "Records discovered tools into the per-project map so exploration is not repeated.",
|
|
596
|
+
"script": "gates/tool-map/index.mjs",
|
|
597
|
+
"params": [
|
|
598
|
+
{
|
|
599
|
+
"name": "toolMapFile",
|
|
600
|
+
"type": "string",
|
|
601
|
+
"description": "Path to the per-project tool map (default .ai/tool-map.json)."
|
|
602
|
+
}
|
|
603
|
+
]
|
|
604
|
+
}
|
|
605
|
+
]
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"id": "forge",
|
|
609
|
+
"name": "Forge pipeline",
|
|
610
|
+
"description": "Enforce the forge pipeline: a project that adopted forge routes every change through it.",
|
|
611
|
+
"gates": [
|
|
612
|
+
{
|
|
613
|
+
"id": "forge-flow",
|
|
614
|
+
"configKey": "requireForgeRunToEdit",
|
|
615
|
+
"default": false,
|
|
616
|
+
"event": "PreToolUse",
|
|
617
|
+
"tools": [
|
|
618
|
+
"write",
|
|
619
|
+
"shell"
|
|
620
|
+
],
|
|
621
|
+
"description": "In a forge-adopted project, denies edits/commands unless an active forge run exists for it.",
|
|
622
|
+
"script": "gates/forge-flow/index.mjs",
|
|
623
|
+
"params": [
|
|
624
|
+
{
|
|
625
|
+
"name": "forgeDbPath",
|
|
626
|
+
"type": "string",
|
|
627
|
+
"description": "Path to forge's global SQLite DB (default ~/.forge/forge-mcp.db)."
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
]
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
"id": "session",
|
|
635
|
+
"name": "Session start",
|
|
636
|
+
"description": "SessionStart hooks: environment validation and project sync.",
|
|
637
|
+
"gates": [
|
|
638
|
+
{
|
|
639
|
+
"id": "doctor",
|
|
640
|
+
"configKey": "validateEnvironmentOnStart",
|
|
641
|
+
"default": true,
|
|
642
|
+
"event": "SessionStart",
|
|
643
|
+
"tools": [],
|
|
644
|
+
"description": "Runs the environment validator and only speaks on failure.",
|
|
645
|
+
"script": "doctor.mjs"
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
"id": "ask-adoption",
|
|
649
|
+
"configKey": "askAdoptionInNewProject",
|
|
650
|
+
"default": true,
|
|
651
|
+
"event": "SessionStart",
|
|
652
|
+
"tools": [],
|
|
653
|
+
"description": "In a project that never answered, makes the assistant ask what to adopt.",
|
|
654
|
+
"script": "ask-adoption.mjs"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"id": "wiring-check",
|
|
658
|
+
"configKey": "checkWiringOnStart",
|
|
659
|
+
"default": true,
|
|
660
|
+
"event": "SessionStart",
|
|
661
|
+
"tools": [],
|
|
662
|
+
"description": "Warns when a registered hook is missing or a script is orphaned.",
|
|
663
|
+
"script": "wiring-check.mjs"
|
|
664
|
+
}
|
|
665
|
+
]
|
|
666
|
+
}
|
|
667
|
+
]
|
|
668
|
+
}
|