@devrik-tools/claude-gates 0.1.2 → 0.2.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 +7 -1
- package/cli/__tests__/config.test.mjs +113 -101
- package/cli/__tests__/install.test.mjs +102 -0
- package/cli/__tests__/materialize.test.mjs +95 -0
- package/cli/__tests__/registry-gates-consistency.test.mjs +52 -44
- package/cli/__tests__/task.test.mjs +124 -0
- package/cli/__tests__/version-consistency.test.mjs +44 -0
- package/cli/config.mjs +124 -113
- package/cli/index.mjs +100 -97
- package/cli/init.mjs +259 -256
- package/cli/install.mjs +150 -80
- package/cli/materialize.mjs +102 -51
- package/cli/registry.mjs +136 -127
- package/cli/task.mjs +140 -0
- package/package.json +2 -1
- package/plugins/gates/.claude-plugin/plugin.json +8 -2
- package/plugins/gates/hooks/__tests__/ask-adoption.test.mjs +83 -0
- package/plugins/gates/hooks/__tests__/doctor.test.mjs +85 -0
- package/plugins/gates/hooks/__tests__/wiring-check.test.mjs +65 -0
- package/plugins/gates/hooks/ask-adoption.mjs +147 -0
- package/plugins/gates/hooks/doctor.mjs +207 -0
- package/plugins/gates/hooks/gates/audit-before-build/audit-before-build.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/audit-before-build/index.mjs +88 -88
- package/plugins/gates/hooks/gates/audit-before-build/test.mjs +117 -92
- package/plugins/gates/hooks/gates/autonomous-mode/autonomous.edge.test.mjs +104 -0
- package/plugins/gates/hooks/gates/autonomous-mode/index.mjs +48 -45
- package/plugins/gates/hooks/gates/bash-commands/bash-commands.edge.test.mjs +165 -0
- package/plugins/gates/hooks/gates/bash-commands/index.mjs +285 -268
- package/plugins/gates/hooks/gates/brief-before-delegate/brief-before-delegate.edge.test.mjs +151 -0
- package/plugins/gates/hooks/gates/brief-before-delegate/index.mjs +265 -177
- package/plugins/gates/hooks/gates/circuit-breaker/circuit-breaker.edge.test.mjs +207 -0
- package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +501 -456
- package/plugins/gates/hooks/gates/circuit-breaker/test.mjs +161 -143
- package/plugins/gates/hooks/gates/dependency-skills/dependency-skills.edge.test.mjs +69 -0
- package/plugins/gates/hooks/gates/dependency-skills/index.mjs +126 -118
- package/plugins/gates/hooks/gates/diagnosis-before-patch/diagnosis-before-patch.edge.test.mjs +68 -0
- package/plugins/gates/hooks/gates/diagnosis-before-patch/index.mjs +43 -49
- package/plugins/gates/hooks/gates/feature-catalog/edge.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/feature-catalog/index.mjs +83 -100
- package/plugins/gates/hooks/gates/force-parallel/index.mjs +119 -0
- package/plugins/gates/hooks/gates/force-parallel/test.mjs +88 -0
- package/plugins/gates/hooks/gates/forge-flow/forge-flow.edge.test.mjs +155 -0
- package/plugins/gates/hooks/gates/forge-flow/index.mjs +134 -112
- package/plugins/gates/hooks/gates/implementation-pipeline/edge.edge.test.mjs +66 -0
- package/plugins/gates/hooks/gates/implementation-pipeline/index.mjs +187 -186
- package/plugins/gates/hooks/gates/intent-flow/index.mjs +260 -238
- package/plugins/gates/hooks/gates/intent-flow/intent-flow.edge.test.mjs +96 -0
- package/plugins/gates/hooks/gates/intent-flow/test.mjs +165 -136
- package/plugins/gates/hooks/gates/lint-commit/index.mjs +149 -0
- package/plugins/gates/hooks/gates/lint-commit/test.mjs +85 -0
- package/plugins/gates/hooks/gates/mandatory-flow/edge.edge.test.mjs +100 -0
- package/plugins/gates/hooks/gates/mandatory-flow/index.mjs +180 -166
- package/plugins/gates/hooks/gates/neutral-spanish/index.mjs +79 -85
- package/plugins/gates/hooks/gates/neutral-spanish/neutral-spanish.edge.test.mjs +80 -0
- package/plugins/gates/hooks/gates/never-assume/index.mjs +58 -55
- package/plugins/gates/hooks/gates/never-assume/never-assume.edge.test.mjs +71 -0
- package/plugins/gates/hooks/gates/never-assume/test.mjs +95 -78
- package/plugins/gates/hooks/gates/no-blocking/index.mjs +148 -142
- package/plugins/gates/hooks/gates/no-blocking/no-blocking.edge.test.mjs +109 -0
- package/plugins/gates/hooks/gates/no-memory-dependency/index.mjs +123 -120
- package/plugins/gates/hooks/gates/no-memory-dependency/no-memory-dependency.edge.test.mjs +83 -0
- package/plugins/gates/hooks/gates/no-reconfirm/no-reconfirm.edge.test.mjs +91 -0
- package/plugins/gates/hooks/gates/protected-paths/index.mjs +144 -147
- package/plugins/gates/hooks/gates/protected-paths/protected-paths.edge.test.mjs +126 -0
- package/plugins/gates/hooks/gates/recurrence-lock/index.mjs +89 -64
- package/plugins/gates/hooks/gates/recurrence-lock/recurrence-lock.edge.test.mjs +102 -0
- package/plugins/gates/hooks/gates/reuse-before-build/edge.edge.test.mjs +94 -0
- package/plugins/gates/hooks/gates/reuse-before-build/index.mjs +159 -150
- package/plugins/gates/hooks/gates/risk-level/index.mjs +263 -203
- package/plugins/gates/hooks/gates/risk-level/risk-level.edge.test.mjs +116 -0
- package/plugins/gates/hooks/gates/risk-level/test.mjs +153 -125
- package/plugins/gates/hooks/gates/root-cause-first/index.mjs +56 -50
- package/plugins/gates/hooks/gates/root-cause-first/root-cause-first.edge.test.mjs +58 -0
- package/plugins/gates/hooks/gates/root-whitelist/index.mjs +116 -111
- package/plugins/gates/hooks/gates/root-whitelist/root-whitelist.edge.test.mjs +97 -0
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/index.mjs +184 -99
- package/plugins/gates/hooks/gates/rule-skill-autodiscovery/rule-skill-autodiscovery.edge.test.mjs +126 -0
- package/plugins/gates/hooks/gates/sdd-specs/edge.edge.test.mjs +130 -0
- package/plugins/gates/hooks/gates/sdd-specs/index.mjs +256 -251
- package/plugins/gates/hooks/gates/stop-pending/index.mjs +159 -0
- package/plugins/gates/hooks/gates/stop-pending/test.mjs +114 -0
- package/plugins/gates/hooks/gates/test-after-implementation/index.mjs +101 -101
- package/plugins/gates/hooks/gates/test-after-implementation/test-after-implementation.edge.test.mjs +72 -0
- package/plugins/gates/hooks/gates/test-matrix/edge.edge.test.mjs +63 -0
- package/plugins/gates/hooks/gates/test-matrix/index.mjs +187 -181
- package/plugins/gates/hooks/gates/test-matrix/test.mjs +114 -87
- package/plugins/gates/hooks/gates/tool-map/edge.edge.test.mjs +62 -0
- package/plugins/gates/hooks/gates/tool-map/index.mjs +143 -140
- package/plugins/gates/hooks/hooks.json +346 -286
- package/plugins/gates/hooks/lib/__tests__/config.test.mjs +173 -154
- package/plugins/gates/hooks/lib/__tests__/hook-io.test.mjs +210 -154
- package/plugins/gates/hooks/lib/__tests__/signals.test.mjs +114 -0
- package/plugins/gates/hooks/lib/config.mjs +172 -165
- package/plugins/gates/hooks/lib/hook-io-config.edge.test.mjs +189 -0
- package/plugins/gates/hooks/lib/hook-io.mjs +318 -208
- package/plugins/gates/hooks/lib/signals.mjs +127 -0
- package/plugins/gates/hooks/wiring-check.mjs +227 -0
- package/plugins/tasks/.claude-plugin/plugin.json +14 -0
- package/plugins/tasks/hooks/__tests__/register-requests.test.mjs +100 -0
- package/plugins/tasks/hooks/__tests__/session-tasks.test.mjs +95 -0
- package/plugins/tasks/hooks/hooks.json +26 -0
- package/plugins/tasks/hooks/lib/__tests__/task-store.test.mjs +180 -132
- package/plugins/tasks/hooks/lib/task-store.mjs +197 -159
- package/plugins/tasks/hooks/register-requests.mjs +141 -108
- package/plugins/tasks/hooks/session-tasks.mjs +108 -0
- package/registry.json +793 -686
|
@@ -1,186 +1,187 @@
|
|
|
1
|
-
// implementation-pipeline — denies a delegation that sends a builder subagent straight
|
|
2
|
-
// to writing code without the prompt declaring the pipeline stages around it:
|
|
3
|
-
// definition (where the context came from), writing's own verification plan, and a
|
|
4
|
-
// separate reviewer for validation/QA/closure. Migrated from
|
|
5
|
-
// ~/.claude/hooks/guard-pipeline-de-implementacion.mjs.
|
|
6
|
-
//
|
|
7
|
-
// ── What a project can configure (params) ───────────────────────────────────────────
|
|
8
|
-
// builderSubagents subagent types that count as builders — the ones this gate
|
|
9
|
-
// holds to the pipeline. Replaces the built-in list wholesale.
|
|
10
|
-
// exemptSubagents subagent types exempt outright: read-only pipeline stages that
|
|
11
|
-
// cannot be required to declare a pipeline around themselves.
|
|
12
|
-
// Replaces the built-in list wholesale.
|
|
13
|
-
// The defaults live here, in the source, so a project reads them and knows exactly what
|
|
14
|
-
// its override replaces.
|
|
15
|
-
//
|
|
16
|
-
// ── Off by default, and quiet outside its narrow trigger ───────────────────────────
|
|
17
|
-
// This gate only evaluates a delegation whose prompt declares a STANDARD/HIGH-RISK
|
|
18
|
-
// level, uses an implementation verb, targets a builder subagent, and is not about the
|
|
19
|
-
// harness itself. A prompt that only describes work, or that is read-only/exploratory,
|
|
20
|
-
// never reaches the check.
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
/(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
/\
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (!
|
|
139
|
-
if (
|
|
140
|
-
return
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
1
|
+
// implementation-pipeline — denies a delegation that sends a builder subagent straight
|
|
2
|
+
// to writing code without the prompt declaring the pipeline stages around it:
|
|
3
|
+
// definition (where the context came from), writing's own verification plan, and a
|
|
4
|
+
// separate reviewer for validation/QA/closure. Migrated from
|
|
5
|
+
// ~/.claude/hooks/guard-pipeline-de-implementacion.mjs.
|
|
6
|
+
//
|
|
7
|
+
// ── What a project can configure (params) ───────────────────────────────────────────
|
|
8
|
+
// builderSubagents subagent types that count as builders — the ones this gate
|
|
9
|
+
// holds to the pipeline. Replaces the built-in list wholesale.
|
|
10
|
+
// exemptSubagents subagent types exempt outright: read-only pipeline stages that
|
|
11
|
+
// cannot be required to declare a pipeline around themselves.
|
|
12
|
+
// Replaces the built-in list wholesale.
|
|
13
|
+
// The defaults live here, in the source, so a project reads them and knows exactly what
|
|
14
|
+
// its override replaces.
|
|
15
|
+
//
|
|
16
|
+
// ── Off by default, and quiet outside its narrow trigger ───────────────────────────
|
|
17
|
+
// This gate only evaluates a delegation whose prompt declares a STANDARD/HIGH-RISK
|
|
18
|
+
// level, uses an implementation verb, targets a builder subagent, and is not about the
|
|
19
|
+
// harness itself. A prompt that only describes work, or that is read-only/exploratory,
|
|
20
|
+
// never reaches the check.
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
runGate,
|
|
24
|
+
deny,
|
|
25
|
+
toolInGroups,
|
|
26
|
+
delegationPromptOf,
|
|
27
|
+
} from '../../lib/hook-io.mjs';
|
|
28
|
+
|
|
29
|
+
const GATE_ID = 'implementation-pipeline';
|
|
30
|
+
const CONFIG_KEY = 'requireImplementationPipeline';
|
|
31
|
+
|
|
32
|
+
const DEFAULT_BUILDER_SUBAGENTS = [
|
|
33
|
+
'frontend',
|
|
34
|
+
'backend',
|
|
35
|
+
'worker',
|
|
36
|
+
'worker-senior',
|
|
37
|
+
'general-purpose',
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const DEFAULT_EXEMPT_SUBAGENTS = [
|
|
41
|
+
'scout',
|
|
42
|
+
'explore',
|
|
43
|
+
'plan',
|
|
44
|
+
'revision',
|
|
45
|
+
'contraste',
|
|
46
|
+
'test-planner',
|
|
47
|
+
'qa',
|
|
48
|
+
'ui',
|
|
49
|
+
'ux',
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
function withWordBoundary(alternation) {
|
|
53
|
+
return new RegExp(
|
|
54
|
+
`(?:^|[^\\p{L}\\p{N}_])(?:${alternation})(?:[^\\p{L}\\p{N}_]|$)`,
|
|
55
|
+
'iu',
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const IMPLEMENTATION_VERBS = withWordBoundary(
|
|
60
|
+
'implementa|implementar|implement(á|é)|agreg(a|á)|agregar|añad(e|í)|añadir|cre(a|á)|crear|' +
|
|
61
|
+
'arregl(a|á)|arreglar|cambi(a|á)|cambiar|migr(a|á)|migrar|' +
|
|
62
|
+
'corrige|corregir|correg(í|ir)|constru(ye|í)|construir|modific(a|á)|modificar|' +
|
|
63
|
+
'refactoriz(a|á)|refactorizar|elimin(a|á)|eliminar|reescrib(e|í)|reescribir|desplieg(a|á)|desplegar|' +
|
|
64
|
+
'escrib(í|e)|escribir|implement\\w*|writ(?:e|ing)|creat\\w*|fix\\w*|build\\w*|refactor\\w*|migrat\\w*|' +
|
|
65
|
+
'add\\w*|remov\\w*|delet\\w*|modify|modifies|modifying|rewrit\\w*',
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
/** Declared LEVEL near the word "level"/"classification" in Spanish or English, matching
|
|
69
|
+
* the plugin-wide convention (see risk-level.mjs). */
|
|
70
|
+
const DEMANDING_LEVEL_PATTERN =
|
|
71
|
+
/(nivel|level|clasificaci[oó]n|classification)[^\n]{0,25}?\b(STANDARD|HIGH-RISK)\b/iu;
|
|
72
|
+
const EXEMPT_LEVEL_PATTERN =
|
|
73
|
+
/(nivel|level|clasificaci[oó]n|classification)[^\n]{0,25}?\b(QUESTION|MICRO)\b/iu;
|
|
74
|
+
const HIGH_RISK_PATTERN =
|
|
75
|
+
/(nivel|level|clasificaci[oó]n|classification)[^\n]{0,25}?\bHIGH-RISK\b/iu;
|
|
76
|
+
|
|
77
|
+
const HARNESS_PATTERN =
|
|
78
|
+
/(\.claude[\\/]|hooks[\\/]|plugins[\\/]gates|settings\.json|[\\/]agents[\\/]\w|[\\/]rules[\\/]\w|[\\/]skills[\\/]\w)/i;
|
|
79
|
+
|
|
80
|
+
// Several small patterns instead of one long alternation: a single big regex here
|
|
81
|
+
// tripped the linter's regex-complexity limit. Any one matching counts as declared.
|
|
82
|
+
const REVIEWER_NAME_PATTERN =
|
|
83
|
+
/\b(reviewer|revisor|separate review|revisi[oó]n separada|contraste|auditor)\b/i;
|
|
84
|
+
const REVIEWER_LABEL_PATTERN = /(review|revisi[oó]n)\s*:/i;
|
|
85
|
+
const REVIEWER_ACTION_EN_PATTERN =
|
|
86
|
+
/\breview\s+(?:the\s+)?(?:diff|result|work)\b/i;
|
|
87
|
+
const REVIEWER_ACTION_ES_PATTERN =
|
|
88
|
+
/\brevisa\s+(?:el\s+)?(?:diff|resultado|trabajo)\b/i;
|
|
89
|
+
const REVIEWER_CODE_REVIEW_PATTERN = /code.review/i;
|
|
90
|
+
|
|
91
|
+
function reviewerStageDeclared(prompt) {
|
|
92
|
+
return (
|
|
93
|
+
REVIEWER_NAME_PATTERN.test(prompt) ||
|
|
94
|
+
REVIEWER_LABEL_PATTERN.test(prompt) ||
|
|
95
|
+
REVIEWER_ACTION_EN_PATTERN.test(prompt) ||
|
|
96
|
+
REVIEWER_ACTION_ES_PATTERN.test(prompt) ||
|
|
97
|
+
REVIEWER_CODE_REVIEW_PATTERN.test(prompt)
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const DEFINITION_PATTERN =
|
|
102
|
+
/\b(scout|reconnaissance|reconocimiento|prior exploration|explora(?:ci[oó]n)? previa|verified context|contexto verificado|asserts\.md|brief\.md)\b/i;
|
|
103
|
+
const WRITING_PATTERN =
|
|
104
|
+
/\b(test|tests|prueba|pruebas|vitest|jest|playwright|typecheck|lint|verification|verificaci[oó]n|verification criteria)\b/i;
|
|
105
|
+
|
|
106
|
+
/** The three pipeline stages this gate requires be declared, in this order. */
|
|
107
|
+
const REQUIRED_STAGES = [
|
|
108
|
+
{
|
|
109
|
+
id: 'definition',
|
|
110
|
+
isDeclared: (prompt) => DEFINITION_PATTERN.test(prompt),
|
|
111
|
+
missing:
|
|
112
|
+
'DEFINITION: does not declare where the context came from (a prior scout, read-only exploration, or an already-written asserts/brief).',
|
|
113
|
+
line: 'Verified context: <path to the cited asserts/brief> — or: a prior scout ran, findings at <path>.',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'writing',
|
|
117
|
+
isDeclared: (prompt) => WRITING_PATTERN.test(prompt),
|
|
118
|
+
missing:
|
|
119
|
+
'WRITING: does not declare what is verified nor with what command. A builder does not validate its own work without a criterion written beforehand.',
|
|
120
|
+
line: 'Verification: <exact command> and what is expected. Anything that cannot run is reported OMITTED, never PASS.',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: 'reviewer',
|
|
124
|
+
isDeclared: reviewerStageDeclared,
|
|
125
|
+
missing:
|
|
126
|
+
'REVIEWER: does not declare who reviews the result. Whoever implements does not validate their own work.',
|
|
127
|
+
line: 'Review: the coordinator reviews the diff and the evidence before closing — or: a read-only `revision`/`contraste` agent reviews it.',
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
function isExempt(toolInput, prompt, builderSubagents, exemptSubagents) {
|
|
132
|
+
const subagentType = String(
|
|
133
|
+
toolInput.subagent_type ?? toolInput.subagentType ?? '',
|
|
134
|
+
).toLowerCase();
|
|
135
|
+
if (exemptSubagents.includes(subagentType)) return true;
|
|
136
|
+
// An unknown type is not assumed to be a builder: the safe side here is not to
|
|
137
|
+
// invent requirements for agents this gate cannot classify.
|
|
138
|
+
if (subagentType && !builderSubagents.includes(subagentType)) return true;
|
|
139
|
+
if (EXEMPT_LEVEL_PATTERN.test(prompt)) return true;
|
|
140
|
+
if (!DEMANDING_LEVEL_PATTERN.test(prompt)) return true;
|
|
141
|
+
if (!IMPLEMENTATION_VERBS.test(prompt)) return true;
|
|
142
|
+
if (HARNESS_PATTERN.test(prompt)) return true;
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
runGate(
|
|
147
|
+
{
|
|
148
|
+
id: GATE_ID,
|
|
149
|
+
configKey: CONFIG_KEY,
|
|
150
|
+
enabledByDefault: false,
|
|
151
|
+
defaultParams: {
|
|
152
|
+
builderSubagents: DEFAULT_BUILDER_SUBAGENTS,
|
|
153
|
+
exemptSubagents: DEFAULT_EXEMPT_SUBAGENTS,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
({ toolName, toolInput, parameters }) => {
|
|
157
|
+
if (!toolInGroups(toolName, ['delegation'])) return;
|
|
158
|
+
|
|
159
|
+
const prompt = delegationPromptOf(toolInput);
|
|
160
|
+
if (!prompt.trim()) return;
|
|
161
|
+
|
|
162
|
+
const builderSubagents =
|
|
163
|
+
parameters.builderSubagents ?? DEFAULT_BUILDER_SUBAGENTS;
|
|
164
|
+
const exemptSubagents =
|
|
165
|
+
parameters.exemptSubagents ?? DEFAULT_EXEMPT_SUBAGENTS;
|
|
166
|
+
if (isExempt(toolInput, prompt, builderSubagents, exemptSubagents)) return;
|
|
167
|
+
|
|
168
|
+
const missingStages = REQUIRED_STAGES.filter(
|
|
169
|
+
(stage) => !stage.isDeclared(prompt),
|
|
170
|
+
);
|
|
171
|
+
if (missingStages.length === 0) return;
|
|
172
|
+
|
|
173
|
+
const isHighRisk = HIGH_RISK_PATTERN.test(prompt);
|
|
174
|
+
const details = missingStages.map((stage) => stage.missing).join(' ');
|
|
175
|
+
const lines = missingStages.map((stage) => ` ${stage.line}`).join('\n');
|
|
176
|
+
|
|
177
|
+
deny(
|
|
178
|
+
GATE_ID,
|
|
179
|
+
`This delegation is going to build code but skips ${missingStages.length} pipeline ` +
|
|
180
|
+
`stage(s). ${details} ${
|
|
181
|
+
isHighRisk
|
|
182
|
+
? 'In HIGH-RISK a separate reviewer is not negotiable. '
|
|
183
|
+
: ''
|
|
184
|
+
}PASTE THESE LINES INTO THE PROMPT AND RELAUNCH:\n${lines}`,
|
|
185
|
+
);
|
|
186
|
+
},
|
|
187
|
+
);
|