@paths.design/caws-cli 3.1.0 → 3.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/README.md +295 -150
- package/dist/budget-derivation.d.ts +35 -0
- package/dist/budget-derivation.d.ts.map +1 -0
- package/dist/budget-derivation.js +204 -0
- package/dist/cicd-optimizer.d.ts +142 -0
- package/dist/cicd-optimizer.d.ts.map +1 -0
- package/dist/cicd-optimizer.js +504 -0
- package/dist/commands/burnup.d.ts +6 -0
- package/dist/commands/burnup.d.ts.map +1 -0
- package/dist/commands/burnup.js +90 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +514 -0
- package/dist/commands/provenance.d.ts +32 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +979 -0
- package/dist/commands/tool.d.ts +13 -0
- package/dist/commands/tool.d.ts.map +1 -0
- package/dist/commands/tool.js +138 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +80 -0
- package/dist/config/index.d.ts +29 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +132 -0
- package/dist/error-handler.d.ts +50 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +253 -0
- package/dist/generators/working-spec.d.ts +13 -0
- package/dist/generators/working-spec.d.ts.map +1 -0
- package/dist/generators/working-spec.js +204 -0
- package/dist/index.d.ts +3 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -2983
- package/dist/scaffold/cursor-hooks.d.ts +7 -0
- package/dist/scaffold/cursor-hooks.d.ts.map +1 -0
- package/dist/scaffold/cursor-hooks.js +152 -0
- package/dist/scaffold/git-hooks.d.ts +20 -0
- package/dist/scaffold/git-hooks.d.ts.map +1 -0
- package/dist/scaffold/git-hooks.js +417 -0
- package/dist/scaffold/index.d.ts +20 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +486 -0
- package/dist/test-analysis.d.ts +182 -0
- package/dist/test-analysis.d.ts.map +1 -0
- package/dist/test-analysis.js +580 -0
- package/dist/tool-interface.d.ts +236 -0
- package/dist/tool-interface.d.ts.map +1 -0
- package/dist/tool-interface.js +314 -0
- package/dist/tool-loader.d.ts +77 -0
- package/dist/tool-loader.d.ts.map +1 -0
- package/dist/tool-loader.js +298 -0
- package/dist/tool-validator.d.ts +72 -0
- package/dist/tool-validator.d.ts.map +1 -0
- package/dist/tool-validator.js +387 -0
- package/dist/utils/detection.d.ts +7 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/detection.js +174 -0
- package/dist/utils/finalization.d.ts +17 -0
- package/dist/utils/finalization.d.ts.map +1 -0
- package/dist/utils/finalization.js +229 -0
- package/dist/utils/project-analysis.d.ts +14 -0
- package/dist/utils/project-analysis.d.ts.map +1 -0
- package/dist/utils/project-analysis.js +105 -0
- package/dist/validation/spec-validation.d.ts +29 -0
- package/dist/validation/spec-validation.d.ts.map +1 -0
- package/dist/validation/spec-validation.js +376 -0
- package/dist/waivers-manager.d.ts +167 -0
- package/dist/waivers-manager.d.ts.map +1 -0
- package/dist/waivers-manager.js +549 -0
- package/package.json +10 -12
- package/templates/.cursor/README.md +311 -0
- package/templates/.cursor/hooks/audit.sh +55 -0
- package/templates/.cursor/hooks/block-dangerous.sh +77 -0
- package/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/templates/.cursor/hooks/caws-scope-guard.sh +74 -0
- package/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/templates/.cursor/hooks/format.sh +38 -0
- package/templates/.cursor/hooks/naming-check.sh +64 -0
- package/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/templates/.cursor/hooks/validate-spec.sh +38 -0
- package/templates/.cursor/hooks.json +59 -0
- package/templates/.github/copilot/instructions.md +311 -0
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/templates/.vscode/launch.json +56 -0
- package/templates/.vscode/settings.json +93 -0
- package/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/templates/apps/tools/caws/README.md +1 -1
- package/templates/apps/tools/caws/schemas/working-spec.schema.json +21 -3
- package/templates/codemod/test.js +93 -1
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Working Spec Validation Utilities
|
|
3
|
+
* Functions for validating CAWS working specifications
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { deriveBudget, checkBudgetCompliance } = require('../budget-derivation');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Basic validation of working spec
|
|
11
|
+
* @param {Object} spec - Working spec object
|
|
12
|
+
* @param {Object} options - Validation options
|
|
13
|
+
* @returns {Object} Validation result
|
|
14
|
+
*/
|
|
15
|
+
const validateWorkingSpec = (spec, _options = {}) => {
|
|
16
|
+
try {
|
|
17
|
+
// Basic structural validation for essential fields
|
|
18
|
+
const requiredFields = [
|
|
19
|
+
'id',
|
|
20
|
+
'title',
|
|
21
|
+
'risk_tier',
|
|
22
|
+
'mode',
|
|
23
|
+
'blast_radius',
|
|
24
|
+
'operational_rollback_slo',
|
|
25
|
+
'scope',
|
|
26
|
+
'invariants',
|
|
27
|
+
'acceptance',
|
|
28
|
+
'non_functional',
|
|
29
|
+
'contracts',
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// For new policy-based specs, change_budget is not required
|
|
33
|
+
// It's derived from policy.yaml + waivers
|
|
34
|
+
|
|
35
|
+
for (const field of requiredFields) {
|
|
36
|
+
if (!spec[field]) {
|
|
37
|
+
return {
|
|
38
|
+
valid: false,
|
|
39
|
+
errors: [
|
|
40
|
+
{
|
|
41
|
+
instancePath: `/${field}`,
|
|
42
|
+
message: `Missing required field: ${field}`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Validate specific field formats
|
|
50
|
+
if (!/^[A-Z]+-\d+$/.test(spec.id)) {
|
|
51
|
+
return {
|
|
52
|
+
valid: false,
|
|
53
|
+
errors: [
|
|
54
|
+
{
|
|
55
|
+
instancePath: '/id',
|
|
56
|
+
message: 'Project ID should be in format: PREFIX-NUMBER (e.g., FEAT-1234)',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Validate experimental mode
|
|
63
|
+
if (spec.experimental_mode) {
|
|
64
|
+
if (typeof spec.experimental_mode !== 'object') {
|
|
65
|
+
return {
|
|
66
|
+
valid: false,
|
|
67
|
+
errors: [
|
|
68
|
+
{
|
|
69
|
+
instancePath: '/experimental_mode',
|
|
70
|
+
message:
|
|
71
|
+
'Experimental mode must be an object with enabled, rationale, and expires_at fields',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const requiredExpFields = ['enabled', 'rationale', 'expires_at'];
|
|
78
|
+
for (const field of requiredExpFields) {
|
|
79
|
+
if (!(field in spec.experimental_mode)) {
|
|
80
|
+
return {
|
|
81
|
+
valid: false,
|
|
82
|
+
errors: [
|
|
83
|
+
{
|
|
84
|
+
instancePath: `/experimental_mode/${field}`,
|
|
85
|
+
message: `Missing required experimental mode field: ${field}`,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (spec.experimental_mode.enabled && spec.risk_tier < 3) {
|
|
93
|
+
return {
|
|
94
|
+
valid: false,
|
|
95
|
+
errors: [
|
|
96
|
+
{
|
|
97
|
+
instancePath: '/experimental_mode',
|
|
98
|
+
message: 'Experimental mode can only be used with Tier 3 (low risk) changes',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (spec.risk_tier < 1 || spec.risk_tier > 3) {
|
|
106
|
+
return {
|
|
107
|
+
valid: false,
|
|
108
|
+
errors: [
|
|
109
|
+
{
|
|
110
|
+
instancePath: '/risk_tier',
|
|
111
|
+
message: 'Risk tier must be 1, 2, or 3',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!spec.scope || !spec.scope.in || spec.scope.in.length === 0) {
|
|
118
|
+
return {
|
|
119
|
+
valid: false,
|
|
120
|
+
errors: [
|
|
121
|
+
{
|
|
122
|
+
instancePath: '/scope/in',
|
|
123
|
+
message: 'Scope IN must not be empty',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return { valid: true };
|
|
130
|
+
} catch (error) {
|
|
131
|
+
return {
|
|
132
|
+
valid: false,
|
|
133
|
+
errors: [
|
|
134
|
+
{
|
|
135
|
+
instancePath: '',
|
|
136
|
+
message: `Validation error: ${error.message}`,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Enhanced validation with suggestions and auto-fix
|
|
145
|
+
* @param {Object} spec - Working spec object
|
|
146
|
+
* @param {Object} options - Validation options
|
|
147
|
+
* @returns {Object} Enhanced validation result
|
|
148
|
+
*/
|
|
149
|
+
function validateWorkingSpecWithSuggestions(spec, options = {}) {
|
|
150
|
+
const { autoFix = false, checkBudget = false, projectRoot } = options;
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Basic structural validation for essential fields
|
|
154
|
+
const requiredFields = [
|
|
155
|
+
'id',
|
|
156
|
+
'title',
|
|
157
|
+
'risk_tier',
|
|
158
|
+
'mode',
|
|
159
|
+
'blast_radius',
|
|
160
|
+
'operational_rollback_slo',
|
|
161
|
+
'scope',
|
|
162
|
+
'invariants',
|
|
163
|
+
'acceptance',
|
|
164
|
+
'non_functional',
|
|
165
|
+
'contracts',
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
let errors = [];
|
|
169
|
+
let warnings = [];
|
|
170
|
+
let fixes = [];
|
|
171
|
+
|
|
172
|
+
for (const field of requiredFields) {
|
|
173
|
+
if (!spec[field]) {
|
|
174
|
+
errors.push({
|
|
175
|
+
instancePath: `/${field}`,
|
|
176
|
+
message: `Missing required field: ${field}`,
|
|
177
|
+
suggestion: getFieldSuggestion(field, spec),
|
|
178
|
+
canAutoFix: canAutoFixField(field, spec),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Validate specific field formats
|
|
184
|
+
if (spec.id && !/^[A-Z]+-\d+$/.test(spec.id)) {
|
|
185
|
+
errors.push({
|
|
186
|
+
instancePath: '/id',
|
|
187
|
+
message: 'Project ID should be in format: PREFIX-NUMBER (e.g., FEAT-1234)',
|
|
188
|
+
suggestion: 'Use format like: PROJ-001, FEAT-002, FIX-003',
|
|
189
|
+
canAutoFix: false,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Validate risk tier
|
|
194
|
+
if (spec.risk_tier !== undefined && (spec.risk_tier < 1 || spec.risk_tier > 3)) {
|
|
195
|
+
errors.push({
|
|
196
|
+
instancePath: '/risk_tier',
|
|
197
|
+
message: 'Risk tier must be 1, 2, or 3',
|
|
198
|
+
suggestion:
|
|
199
|
+
'Tier 1: Critical (auth, billing), Tier 2: Standard (features), Tier 3: Low risk (UI)',
|
|
200
|
+
canAutoFix: true,
|
|
201
|
+
});
|
|
202
|
+
fixes.push({ field: 'risk_tier', value: Math.max(1, Math.min(3, spec.risk_tier || 2)) });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Validate scope.in is not empty
|
|
206
|
+
if (!spec.scope || !spec.scope.in || spec.scope.in.length === 0) {
|
|
207
|
+
errors.push({
|
|
208
|
+
instancePath: '/scope/in',
|
|
209
|
+
message: 'Scope IN must not be empty',
|
|
210
|
+
suggestion: 'Specify directories/files that are included in changes',
|
|
211
|
+
canAutoFix: false,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Check for common issues
|
|
216
|
+
if (!spec.invariants || spec.invariants.length === 0) {
|
|
217
|
+
warnings.push({
|
|
218
|
+
instancePath: '/invariants',
|
|
219
|
+
message: 'No system invariants defined',
|
|
220
|
+
suggestion: 'Add 1-3 statements about what must always remain true',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!spec.acceptance || spec.acceptance.length === 0) {
|
|
225
|
+
warnings.push({
|
|
226
|
+
instancePath: '/acceptance',
|
|
227
|
+
message: 'No acceptance criteria defined',
|
|
228
|
+
suggestion: 'Add acceptance criteria in GIVEN/WHEN/THEN format',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Tier-specific validations
|
|
233
|
+
if (spec.risk_tier === 1 || spec.risk_tier === 2) {
|
|
234
|
+
if (!spec.contracts || spec.contracts.length === 0) {
|
|
235
|
+
errors.push({
|
|
236
|
+
instancePath: '/contracts',
|
|
237
|
+
message: 'Contracts required for Tier 1 and 2 changes',
|
|
238
|
+
suggestion: 'Specify API contracts (OpenAPI, GraphQL, etc.)',
|
|
239
|
+
canAutoFix: false,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Validate waiver_ids format if present
|
|
245
|
+
if (spec.waiver_ids) {
|
|
246
|
+
if (!Array.isArray(spec.waiver_ids)) {
|
|
247
|
+
errors.push({
|
|
248
|
+
instancePath: '/waiver_ids',
|
|
249
|
+
message: 'waiver_ids must be an array of waiver IDs',
|
|
250
|
+
suggestion: 'Use format: ["WV-0001", "WV-0002"]',
|
|
251
|
+
canAutoFix: false,
|
|
252
|
+
});
|
|
253
|
+
} else {
|
|
254
|
+
for (const waiverId of spec.waiver_ids) {
|
|
255
|
+
if (!/^WV-\d{4}$/.test(waiverId)) {
|
|
256
|
+
errors.push({
|
|
257
|
+
instancePath: '/waiver_ids',
|
|
258
|
+
message: `Invalid waiver ID format: ${waiverId}`,
|
|
259
|
+
suggestion: 'Use format: WV-XXXX (e.g., WV-0001)',
|
|
260
|
+
canAutoFix: false,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Derive and check budget if requested
|
|
268
|
+
let budgetCheck = null;
|
|
269
|
+
if (checkBudget && projectRoot) {
|
|
270
|
+
try {
|
|
271
|
+
const derivedBudget = deriveBudget(spec, projectRoot);
|
|
272
|
+
|
|
273
|
+
// Mock current stats for now - in real implementation this would analyze git changes
|
|
274
|
+
const mockStats = {
|
|
275
|
+
files_changed: 50, // This would be calculated from actual changes
|
|
276
|
+
lines_changed: 5000,
|
|
277
|
+
risk_tier: spec.risk_tier,
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
budgetCheck = checkBudgetCompliance(derivedBudget, mockStats);
|
|
281
|
+
|
|
282
|
+
if (!budgetCheck.compliant) {
|
|
283
|
+
for (const violation of budgetCheck.violations) {
|
|
284
|
+
errors.push({
|
|
285
|
+
instancePath: '/budget',
|
|
286
|
+
message: violation.message,
|
|
287
|
+
suggestion: 'Create a waiver or reduce scope to fit within budget',
|
|
288
|
+
canAutoFix: false,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
} catch (error) {
|
|
293
|
+
warnings.push({
|
|
294
|
+
instancePath: '/budget',
|
|
295
|
+
message: `Budget derivation failed: ${error.message}`,
|
|
296
|
+
suggestion: 'Check that .caws/policy.yaml exists and is valid',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Apply auto-fixes if requested
|
|
302
|
+
if (autoFix && fixes.length > 0) {
|
|
303
|
+
console.log('🔧 Applying auto-fixes...');
|
|
304
|
+
for (const fix of fixes) {
|
|
305
|
+
const pathParts = fix.field.split('.');
|
|
306
|
+
let current = spec;
|
|
307
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
308
|
+
if (!current[pathParts[i]]) current[pathParts[i]] = {};
|
|
309
|
+
current = current[pathParts[i]];
|
|
310
|
+
}
|
|
311
|
+
current[pathParts[pathParts.length - 1]] = fix.value;
|
|
312
|
+
console.log(` Fixed ${fix.field}: ${fix.value}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
valid: errors.length === 0,
|
|
318
|
+
errors,
|
|
319
|
+
warnings,
|
|
320
|
+
fixes: fixes.length > 0 ? fixes : undefined,
|
|
321
|
+
budget_check: budgetCheck,
|
|
322
|
+
};
|
|
323
|
+
} catch (error) {
|
|
324
|
+
return {
|
|
325
|
+
valid: false,
|
|
326
|
+
errors: [
|
|
327
|
+
{
|
|
328
|
+
instancePath: '',
|
|
329
|
+
message: `Validation error: ${error.message}`,
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Get suggestion for a missing field
|
|
338
|
+
* @param {string} field - Field name
|
|
339
|
+
* @param {Object} _spec - Spec object (for context)
|
|
340
|
+
* @returns {string} Suggestion text
|
|
341
|
+
*/
|
|
342
|
+
function getFieldSuggestion(field, _spec) {
|
|
343
|
+
const suggestions = {
|
|
344
|
+
id: 'Use format like: PROJ-001, FEAT-002, FIX-003',
|
|
345
|
+
title: 'Add a descriptive project title',
|
|
346
|
+
risk_tier: 'Choose: 1 (critical), 2 (standard), or 3 (low risk)',
|
|
347
|
+
mode: 'Choose: feature, refactor, fix, doc, or chore',
|
|
348
|
+
waiver_ids: 'Reference active waivers by ID (e.g., ["WV-0001"]) if budget exceptions needed',
|
|
349
|
+
blast_radius: 'List affected modules and data migration needs',
|
|
350
|
+
operational_rollback_slo: 'Choose: 1m, 5m, 15m, or 1h',
|
|
351
|
+
scope: "Define what's included (in) and excluded (out) from changes",
|
|
352
|
+
invariants: 'Add 1-3 statements about what must always remain true',
|
|
353
|
+
acceptance: 'Add acceptance criteria in GIVEN/WHEN/THEN format',
|
|
354
|
+
non_functional: 'Define accessibility, performance, and security requirements',
|
|
355
|
+
contracts: 'Specify API contracts (OpenAPI, GraphQL, etc.)',
|
|
356
|
+
};
|
|
357
|
+
return suggestions[field] || `Add the ${field} field`;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Check if a field can be auto-fixed
|
|
362
|
+
* @param {string} field - Field name
|
|
363
|
+
* @param {Object} _spec - Spec object (for context)
|
|
364
|
+
* @returns {boolean} Whether field can be auto-fixed
|
|
365
|
+
*/
|
|
366
|
+
function canAutoFixField(field, _spec) {
|
|
367
|
+
const autoFixable = ['risk_tier'];
|
|
368
|
+
return autoFixable.includes(field);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
module.exports = {
|
|
372
|
+
validateWorkingSpec,
|
|
373
|
+
validateWorkingSpecWithSuggestions,
|
|
374
|
+
getFieldSuggestion,
|
|
375
|
+
canAutoFixField,
|
|
376
|
+
};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export = WaiversManager;
|
|
2
|
+
/**
|
|
3
|
+
* Waiver Manager Class
|
|
4
|
+
* Handles waiver creation, validation, expiration, and audit logging
|
|
5
|
+
*/
|
|
6
|
+
declare class WaiversManager {
|
|
7
|
+
constructor(options?: {});
|
|
8
|
+
projectRoot: any;
|
|
9
|
+
waiversDir: string;
|
|
10
|
+
waiversFile: string;
|
|
11
|
+
auditLogFile: string;
|
|
12
|
+
/**
|
|
13
|
+
* Waiver Schema Definition
|
|
14
|
+
*/
|
|
15
|
+
getWaiverSchema(): {
|
|
16
|
+
type: string;
|
|
17
|
+
required: string[];
|
|
18
|
+
properties: {
|
|
19
|
+
id: {
|
|
20
|
+
type: string;
|
|
21
|
+
pattern: string;
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
24
|
+
title: {
|
|
25
|
+
type: string;
|
|
26
|
+
minLength: number;
|
|
27
|
+
maxLength: number;
|
|
28
|
+
description: string;
|
|
29
|
+
};
|
|
30
|
+
reason: {
|
|
31
|
+
type: string;
|
|
32
|
+
enum: string[];
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
description: {
|
|
36
|
+
type: string;
|
|
37
|
+
minLength: number;
|
|
38
|
+
maxLength: number;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
gates: {
|
|
42
|
+
type: string;
|
|
43
|
+
items: {
|
|
44
|
+
type: string;
|
|
45
|
+
enum: string[];
|
|
46
|
+
};
|
|
47
|
+
minItems: number;
|
|
48
|
+
description: string;
|
|
49
|
+
};
|
|
50
|
+
risk_assessment: {
|
|
51
|
+
type: string;
|
|
52
|
+
properties: {
|
|
53
|
+
impact_level: {
|
|
54
|
+
type: string;
|
|
55
|
+
enum: string[];
|
|
56
|
+
};
|
|
57
|
+
mitigation_plan: {
|
|
58
|
+
type: string;
|
|
59
|
+
minLength: number;
|
|
60
|
+
};
|
|
61
|
+
review_required: {
|
|
62
|
+
type: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
required: string[];
|
|
66
|
+
};
|
|
67
|
+
expires_at: {
|
|
68
|
+
type: string;
|
|
69
|
+
format: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
approved_by: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
created_at: {
|
|
77
|
+
type: string;
|
|
78
|
+
format: string;
|
|
79
|
+
description: string;
|
|
80
|
+
};
|
|
81
|
+
metadata: {
|
|
82
|
+
type: string;
|
|
83
|
+
properties: {
|
|
84
|
+
related_pr: {
|
|
85
|
+
type: string;
|
|
86
|
+
};
|
|
87
|
+
related_issue: {
|
|
88
|
+
type: string;
|
|
89
|
+
};
|
|
90
|
+
environment: {
|
|
91
|
+
type: string;
|
|
92
|
+
enum: string[];
|
|
93
|
+
};
|
|
94
|
+
urgency: {
|
|
95
|
+
type: string;
|
|
96
|
+
enum: string[];
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Create a new waiver
|
|
104
|
+
*/
|
|
105
|
+
createWaiver(waiverData: any): Promise<{
|
|
106
|
+
id: string;
|
|
107
|
+
title: any;
|
|
108
|
+
reason: any;
|
|
109
|
+
description: any;
|
|
110
|
+
gates: any;
|
|
111
|
+
risk_assessment: any;
|
|
112
|
+
expires_at: any;
|
|
113
|
+
approved_by: any;
|
|
114
|
+
created_at: string;
|
|
115
|
+
metadata: any;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Check if waiver applies to specific gates
|
|
119
|
+
*/
|
|
120
|
+
checkWaiverCoverage(gatesToCheck: any, context?: {}): Promise<{
|
|
121
|
+
coveredGates: any[];
|
|
122
|
+
waiverDetails: {
|
|
123
|
+
gate: any;
|
|
124
|
+
waiver_id: any;
|
|
125
|
+
reason: any;
|
|
126
|
+
expires_at: any;
|
|
127
|
+
approved_by: any;
|
|
128
|
+
}[];
|
|
129
|
+
allCovered: boolean;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Get all active waivers
|
|
133
|
+
*/
|
|
134
|
+
getActiveWaivers(): Promise<any>;
|
|
135
|
+
/**
|
|
136
|
+
* Revoke a waiver
|
|
137
|
+
*/
|
|
138
|
+
revokeWaiver(waiverId: any, reason?: string): Promise<any>;
|
|
139
|
+
/**
|
|
140
|
+
* Extend waiver expiration
|
|
141
|
+
*/
|
|
142
|
+
extendWaiver(waiverId: any, newExpiryDate: any, approvedBy: any): Promise<any>;
|
|
143
|
+
/**
|
|
144
|
+
* Get waiver statistics and health metrics
|
|
145
|
+
*/
|
|
146
|
+
getWaiverStats(): Promise<{
|
|
147
|
+
total_active: any;
|
|
148
|
+
by_reason: {};
|
|
149
|
+
by_risk_level: {};
|
|
150
|
+
expiring_soon: any[];
|
|
151
|
+
high_risk: any[];
|
|
152
|
+
total_gates_waived: number;
|
|
153
|
+
average_lifespan_days: number;
|
|
154
|
+
}>;
|
|
155
|
+
generateWaiverId(): Promise<string>;
|
|
156
|
+
validateWaiver(waiver: any): {
|
|
157
|
+
valid: boolean;
|
|
158
|
+
errors: string[];
|
|
159
|
+
};
|
|
160
|
+
checkWaiverConflicts(newWaiver: any): Promise<string[]>;
|
|
161
|
+
waiverAppliesToContext(waiver: any, context: any): boolean;
|
|
162
|
+
loadActiveWaivers(): Promise<unknown>;
|
|
163
|
+
saveActiveWaivers(waivers: any): Promise<void>;
|
|
164
|
+
auditLog(action: any, waiverId: any, details: any): Promise<void>;
|
|
165
|
+
flagForReview(waiver: any): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=waivers-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers-manager.d.ts","sourceRoot":"","sources":["../src/waivers-manager.js"],"names":[],"mappings":";AAaA;;;GAGG;AACH;IACE,0BAUC;IATC,iBAAuD;IACvD,mBAAiE;IACjE,oBAAoE;IACpE,qBAAkE;IAQpE;;OAEG;IACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiGC;IAED;;OAEG;IACH;;;;;;;;;;;OA4DC;IAED;;OAEG;IACH;;;;;;;;;;OA+BC;IAED;;OAEG;IACH,iCAgBC;IAED;;OAEG;IACH,2DAeC;IAED;;OAEG;IACH,+EAuBC;IAED;;OAEG;IACH;;;;;;;;OA2DC;IAID,oCAUC;IAED;;;MAkDC;IAED,wDAkBC;IAED,2DAUC;IAED,sCAYC;IAED,+CAOC;IAED,kEAaC;IAED,0CA2CC;CACF"}
|