@rigour-labs/core 2.21.2 → 3.0.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 +58 -0
- package/dist/context.test.js +2 -3
- package/dist/environment.test.js +2 -1
- package/dist/gates/agent-team.d.ts +2 -1
- package/dist/gates/agent-team.js +1 -0
- package/dist/gates/base.d.ts +4 -2
- package/dist/gates/base.js +5 -1
- package/dist/gates/checkpoint.d.ts +2 -1
- package/dist/gates/checkpoint.js +3 -2
- package/dist/gates/content.js +1 -1
- package/dist/gates/context-window-artifacts.d.ts +34 -0
- package/dist/gates/context-window-artifacts.js +214 -0
- package/dist/gates/context.d.ts +2 -1
- package/dist/gates/context.js +4 -3
- package/dist/gates/coverage.js +3 -1
- package/dist/gates/dependency.js +5 -5
- package/dist/gates/duplication-drift.d.ts +33 -0
- package/dist/gates/duplication-drift.js +190 -0
- package/dist/gates/environment.js +4 -4
- package/dist/gates/file.js +1 -1
- package/dist/gates/hallucinated-imports.d.ts +63 -0
- package/dist/gates/hallucinated-imports.js +406 -0
- package/dist/gates/inconsistent-error-handling.d.ts +39 -0
- package/dist/gates/inconsistent-error-handling.js +236 -0
- package/dist/gates/promise-safety.d.ts +68 -0
- package/dist/gates/promise-safety.js +509 -0
- package/dist/gates/retry-loop-breaker.d.ts +2 -1
- package/dist/gates/retry-loop-breaker.js +2 -1
- package/dist/gates/runner.js +62 -1
- package/dist/gates/safety.d.ts +2 -1
- package/dist/gates/safety.js +2 -1
- package/dist/gates/security-patterns.d.ts +2 -1
- package/dist/gates/security-patterns.js +2 -1
- package/dist/gates/structure.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/fix-packet-service.d.ts +0 -1
- package/dist/services/fix-packet-service.js +9 -14
- package/dist/services/score-history.d.ts +54 -0
- package/dist/services/score-history.js +122 -0
- package/dist/templates/index.js +195 -0
- package/dist/types/fix-packet.d.ts +5 -5
- package/dist/types/fix-packet.js +1 -1
- package/dist/types/index.d.ts +430 -0
- package/dist/types/index.js +57 -0
- package/package.json +21 -1
- package/src/context.test.ts +0 -256
- package/src/discovery.test.ts +0 -88
- package/src/discovery.ts +0 -112
- package/src/environment.test.ts +0 -115
- package/src/gates/agent-team.test.ts +0 -134
- package/src/gates/agent-team.ts +0 -210
- package/src/gates/ast-handlers/base.ts +0 -13
- package/src/gates/ast-handlers/python.ts +0 -145
- package/src/gates/ast-handlers/python_parser.py +0 -181
- package/src/gates/ast-handlers/typescript.ts +0 -264
- package/src/gates/ast-handlers/universal.ts +0 -184
- package/src/gates/ast.ts +0 -54
- package/src/gates/base.ts +0 -27
- package/src/gates/checkpoint.test.ts +0 -135
- package/src/gates/checkpoint.ts +0 -311
- package/src/gates/content.ts +0 -50
- package/src/gates/context.ts +0 -267
- package/src/gates/coverage.ts +0 -74
- package/src/gates/dependency.ts +0 -108
- package/src/gates/environment.ts +0 -94
- package/src/gates/file.ts +0 -42
- package/src/gates/retry-loop-breaker.ts +0 -151
- package/src/gates/runner.ts +0 -156
- package/src/gates/safety.ts +0 -56
- package/src/gates/security-patterns.test.ts +0 -162
- package/src/gates/security-patterns.ts +0 -305
- package/src/gates/structure.ts +0 -36
- package/src/index.ts +0 -13
- package/src/pattern-index/embeddings.ts +0 -84
- package/src/pattern-index/index.ts +0 -59
- package/src/pattern-index/indexer.test.ts +0 -276
- package/src/pattern-index/indexer.ts +0 -1023
- package/src/pattern-index/matcher.test.ts +0 -293
- package/src/pattern-index/matcher.ts +0 -493
- package/src/pattern-index/overrides.ts +0 -235
- package/src/pattern-index/security.ts +0 -151
- package/src/pattern-index/staleness.test.ts +0 -313
- package/src/pattern-index/staleness.ts +0 -568
- package/src/pattern-index/types.ts +0 -339
- package/src/safety.test.ts +0 -53
- package/src/services/adaptive-thresholds.test.ts +0 -189
- package/src/services/adaptive-thresholds.ts +0 -275
- package/src/services/context-engine.ts +0 -104
- package/src/services/fix-packet-service.ts +0 -42
- package/src/services/state-service.ts +0 -138
- package/src/smoke.test.ts +0 -18
- package/src/templates/index.ts +0 -312
- package/src/types/fix-packet.ts +0 -32
- package/src/types/index.ts +0 -159
- package/src/utils/logger.ts +0 -43
- package/src/utils/scanner.test.ts +0 -37
- package/src/utils/scanner.ts +0 -43
- package/tsconfig.json +0 -10
- package/vitest.config.ts +0 -7
- package/vitest.setup.ts +0 -30
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pattern Matcher Tests
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive tests for the pattern matcher.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect } from 'vitest';
|
|
8
|
-
import { PatternMatcher, checkPatternDuplicate } from './matcher.js';
|
|
9
|
-
import type { PatternIndex, PatternEntry } from './types.js';
|
|
10
|
-
|
|
11
|
-
// Helper to create a mock pattern
|
|
12
|
-
function createPattern(overrides: Partial<PatternEntry> = {}): PatternEntry {
|
|
13
|
-
return {
|
|
14
|
-
id: 'test-id',
|
|
15
|
-
type: 'function',
|
|
16
|
-
name: 'testFunction',
|
|
17
|
-
file: 'src/utils.ts',
|
|
18
|
-
line: 1,
|
|
19
|
-
endLine: 5,
|
|
20
|
-
signature: '(input: string): string',
|
|
21
|
-
description: 'A test function',
|
|
22
|
-
keywords: ['test', 'function'],
|
|
23
|
-
hash: 'abc123',
|
|
24
|
-
exported: true,
|
|
25
|
-
usageCount: 0,
|
|
26
|
-
indexedAt: new Date().toISOString(),
|
|
27
|
-
...overrides
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Helper to create a mock index
|
|
32
|
-
function createIndex(patterns: PatternEntry[]): PatternIndex {
|
|
33
|
-
return {
|
|
34
|
-
version: '1.0.0',
|
|
35
|
-
lastUpdated: new Date().toISOString(),
|
|
36
|
-
rootDir: '/test',
|
|
37
|
-
patterns,
|
|
38
|
-
stats: {
|
|
39
|
-
totalPatterns: patterns.length,
|
|
40
|
-
totalFiles: 1,
|
|
41
|
-
byType: { function: patterns.length } as any,
|
|
42
|
-
indexDurationMs: 100
|
|
43
|
-
},
|
|
44
|
-
files: []
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
describe('PatternMatcher', () => {
|
|
49
|
-
describe('exact name match', () => {
|
|
50
|
-
it('should find exact name matches with 100% confidence', async () => {
|
|
51
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
52
|
-
const index = createIndex([pattern]);
|
|
53
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
54
|
-
|
|
55
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
56
|
-
|
|
57
|
-
expect(result.status).toBe('FOUND_SIMILAR');
|
|
58
|
-
expect(result.matches).toHaveLength(1);
|
|
59
|
-
expect(result.matches[0].matchType).toBe('exact');
|
|
60
|
-
expect(result.matches[0].confidence).toBe(100);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should be case-insensitive for exact matches', async () => {
|
|
64
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
65
|
-
const index = createIndex([pattern]);
|
|
66
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
67
|
-
|
|
68
|
-
const result = await matcher.match({ name: 'FormatDate' });
|
|
69
|
-
|
|
70
|
-
expect(result.matches).toHaveLength(1);
|
|
71
|
-
expect(result.matches[0].matchType).toBe('exact');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('should set action to BLOCK for exact matches', async () => {
|
|
75
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
76
|
-
const index = createIndex([pattern]);
|
|
77
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
78
|
-
|
|
79
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
80
|
-
|
|
81
|
-
expect(result.action).toBe('BLOCK');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('fuzzy name match', () => {
|
|
86
|
-
it('should find fuzzy matches for similar names', async () => {
|
|
87
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
88
|
-
const index = createIndex([pattern]);
|
|
89
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
90
|
-
|
|
91
|
-
// 'formatDate' vs 'formatDates' have extremely high similarity
|
|
92
|
-
const result = await matcher.match({ name: 'formatDates' });
|
|
93
|
-
|
|
94
|
-
expect(result.status).toBe('FOUND_SIMILAR');
|
|
95
|
-
expect(result.matches.some(m => m.matchType === 'fuzzy')).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should find matches for renamed patterns', async () => {
|
|
99
|
-
const pattern = createPattern({
|
|
100
|
-
name: 'formatDate',
|
|
101
|
-
keywords: ['format', 'date']
|
|
102
|
-
});
|
|
103
|
-
const index = createIndex([pattern]);
|
|
104
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
105
|
-
|
|
106
|
-
const result = await matcher.match({ name: 'formatDateString' });
|
|
107
|
-
|
|
108
|
-
expect(result.matches.length).toBeGreaterThan(0);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('should not match completely unrelated names', async () => {
|
|
112
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
113
|
-
const index = createIndex([pattern]);
|
|
114
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
115
|
-
|
|
116
|
-
const result = await matcher.match({ name: 'sendEmail' });
|
|
117
|
-
|
|
118
|
-
expect(result.status).toBe('NO_MATCH');
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('signature match', () => {
|
|
123
|
-
it('should find matches with identical signatures', async () => {
|
|
124
|
-
const pattern = createPattern({
|
|
125
|
-
name: 'formatDate',
|
|
126
|
-
signature: '(date: Date): string'
|
|
127
|
-
});
|
|
128
|
-
const index = createIndex([pattern]);
|
|
129
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
130
|
-
|
|
131
|
-
const result = await matcher.match({
|
|
132
|
-
name: 'myDateFormatter',
|
|
133
|
-
signature: '(date: Date): string'
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
expect(result.matches.some(m => m.matchType === 'signature')).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should match similar parameter patterns', async () => {
|
|
140
|
-
const pattern = createPattern({
|
|
141
|
-
name: 'formatDate',
|
|
142
|
-
signature: '(date: Date, format: string): string'
|
|
143
|
-
});
|
|
144
|
-
const index = createIndex([pattern]);
|
|
145
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
146
|
-
|
|
147
|
-
const result = await matcher.match({
|
|
148
|
-
signature: '(input: Date, pattern: string): string'
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
expect(result.matches.length).toBeGreaterThan(0);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
describe('keyword match', () => {
|
|
156
|
-
it('should find matches based on keywords', async () => {
|
|
157
|
-
const pattern = createPattern({
|
|
158
|
-
name: 'formatDate',
|
|
159
|
-
keywords: ['format', 'date', 'time']
|
|
160
|
-
});
|
|
161
|
-
const index = createIndex([pattern]);
|
|
162
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
163
|
-
|
|
164
|
-
const result = await matcher.match({
|
|
165
|
-
keywords: ['date', 'format']
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
expect(result.matches.some(m => m.matchType === 'semantic')).toBe(true);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('overrides', () => {
|
|
173
|
-
it('should allow overridden patterns', async () => {
|
|
174
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
175
|
-
const index = createIndex([pattern]);
|
|
176
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false }, [
|
|
177
|
-
{
|
|
178
|
-
pattern: 'formatDate',
|
|
179
|
-
reason: 'Refactoring in progress',
|
|
180
|
-
createdAt: new Date().toISOString()
|
|
181
|
-
}
|
|
182
|
-
]);
|
|
183
|
-
|
|
184
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
185
|
-
|
|
186
|
-
expect(result.status).toBe('OVERRIDE_ALLOWED');
|
|
187
|
-
expect(result.action).toBe('ALLOW');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('should support glob overrides', async () => {
|
|
191
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
192
|
-
const index = createIndex([pattern]);
|
|
193
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false }, [
|
|
194
|
-
{
|
|
195
|
-
pattern: 'format*',
|
|
196
|
-
reason: 'All format functions are exempt',
|
|
197
|
-
createdAt: new Date().toISOString()
|
|
198
|
-
}
|
|
199
|
-
]);
|
|
200
|
-
|
|
201
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
202
|
-
|
|
203
|
-
expect(result.status).toBe('OVERRIDE_ALLOWED');
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it('should ignore expired overrides', async () => {
|
|
207
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
208
|
-
const index = createIndex([pattern]);
|
|
209
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false }, [
|
|
210
|
-
{
|
|
211
|
-
pattern: 'formatDate',
|
|
212
|
-
reason: 'Expired override',
|
|
213
|
-
createdAt: '2020-01-01T00:00:00Z',
|
|
214
|
-
expiresAt: '2020-01-02T00:00:00Z' // Expired
|
|
215
|
-
}
|
|
216
|
-
]);
|
|
217
|
-
|
|
218
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
219
|
-
|
|
220
|
-
expect(result.status).toBe('FOUND_SIMILAR');
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
describe('configuration', () => {
|
|
225
|
-
it('should respect minConfidence setting', async () => {
|
|
226
|
-
const pattern = createPattern({ name: 'formatDate' });
|
|
227
|
-
const index = createIndex([pattern]);
|
|
228
|
-
const matcher = new PatternMatcher(index, { minConfidence: 95, useEmbeddings: false });
|
|
229
|
-
|
|
230
|
-
// Fuzzy match won't meet 95% threshold
|
|
231
|
-
const result = await matcher.match({ name: 'dateFormat' });
|
|
232
|
-
|
|
233
|
-
// Should only include exact matches at 95%+ threshold
|
|
234
|
-
expect(result.matches.every(m => m.confidence >= 95)).toBe(true);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should respect maxMatches setting', async () => {
|
|
238
|
-
const patterns = [
|
|
239
|
-
createPattern({ id: '1', name: 'formatDate1' }),
|
|
240
|
-
createPattern({ id: '2', name: 'formatDate2' }),
|
|
241
|
-
createPattern({ id: '3', name: 'formatDate3' }),
|
|
242
|
-
createPattern({ id: '4', name: 'formatDate4' }),
|
|
243
|
-
];
|
|
244
|
-
const index = createIndex(patterns);
|
|
245
|
-
const matcher = new PatternMatcher(index, { maxMatches: 2, useEmbeddings: false });
|
|
246
|
-
|
|
247
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
248
|
-
|
|
249
|
-
expect(result.matches.length).toBeLessThanOrEqual(2);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
describe('suggestions', () => {
|
|
254
|
-
it('should suggest importing exported patterns', async () => {
|
|
255
|
-
const pattern = createPattern({
|
|
256
|
-
name: 'formatDate',
|
|
257
|
-
file: 'src/utils/date.ts',
|
|
258
|
-
exported: true
|
|
259
|
-
});
|
|
260
|
-
const index = createIndex([pattern]);
|
|
261
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
262
|
-
|
|
263
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
264
|
-
|
|
265
|
-
expect(result.suggestion).toContain('Import');
|
|
266
|
-
expect(result.suggestion).toContain('src/utils/date.ts');
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('should suggest extracting non-exported patterns', async () => {
|
|
270
|
-
const pattern = createPattern({
|
|
271
|
-
name: 'formatDate',
|
|
272
|
-
exported: false
|
|
273
|
-
});
|
|
274
|
-
const index = createIndex([pattern]);
|
|
275
|
-
const matcher = new PatternMatcher(index, { useEmbeddings: false });
|
|
276
|
-
|
|
277
|
-
const result = await matcher.match({ name: 'formatDate' });
|
|
278
|
-
|
|
279
|
-
expect(result.suggestion).toContain('similar pattern');
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
describe('checkPatternDuplicate', () => {
|
|
285
|
-
it('should be a quick helper for duplicate checking', async () => {
|
|
286
|
-
const pattern = createPattern({ name: 'myUtil' });
|
|
287
|
-
const index = createIndex([pattern]);
|
|
288
|
-
|
|
289
|
-
const result = await checkPatternDuplicate(index, 'myUtil');
|
|
290
|
-
|
|
291
|
-
expect(result.status).toBe('FOUND_SIMILAR');
|
|
292
|
-
});
|
|
293
|
-
});
|