pumuki-ast-hooks 5.6.12 → 5.6.14
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/package.json +1 -1
- package/scripts/hooks-system/.audit-reports/auto-recovery.log +1 -0
- package/scripts/hooks-system/.audit-reports/install-wizard.log +4 -0
- package/scripts/hooks-system/.audit_tmp/hook-metrics.jsonl +28 -0
- package/scripts/hooks-system/infrastructure/ast/common/__tests__/ast-common.spec.js +126 -0
- package/scripts/hooks-system/infrastructure/ast/common/ast-common.js +75 -4
- package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki-ast-hooks",
|
|
3
|
-
"version": "5.6.
|
|
3
|
+
"version": "5.6.14",
|
|
4
4
|
"description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,3 +9,4 @@
|
|
|
9
9
|
{"timestamp":"2026-01-11T18:48:20.329Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
10
10
|
{"timestamp":"2026-01-11T18:54:50.282Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
11
11
|
{"timestamp":"2026-01-11T19:08:34.232Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
12
|
+
{"timestamp":"2026-01-11T20:43:24.310Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
@@ -42,3 +42,7 @@
|
|
|
42
42
|
{"timestamp":"2026-01-11T19:08:34.083Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
43
43
|
{"timestamp":"2026-01-11T19:08:34.083Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
44
44
|
{"timestamp":"2026-01-11T19:08:34.083Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
45
|
+
{"timestamp":"2026-01-11T20:43:24.451Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
46
|
+
{"timestamp":"2026-01-11T20:43:24.460Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
47
|
+
{"timestamp":"2026-01-11T20:43:24.461Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
48
|
+
{"timestamp":"2026-01-11T20:43:24.461Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
@@ -502,3 +502,31 @@
|
|
|
502
502
|
{"timestamp":1768158974401,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
503
503
|
{"timestamp":1768158974401,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
504
504
|
{"timestamp":1768158974402,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
505
|
+
{"timestamp":1768162663136,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
506
|
+
{"timestamp":1768162663136,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
507
|
+
{"timestamp":1768162663136,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
508
|
+
{"timestamp":1768162663136,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
509
|
+
{"timestamp":1768164204308,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
510
|
+
{"timestamp":1768164204309,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
511
|
+
{"timestamp":1768164204309,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
512
|
+
{"timestamp":1768164204309,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
513
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
514
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
515
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
516
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
517
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
518
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
519
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
520
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
521
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
522
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
523
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
524
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
525
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
526
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
527
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
528
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
529
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
530
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
531
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
532
|
+
{"timestamp":1768164204310,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
@@ -58,6 +58,132 @@ describe('AST Common Module', () => {
|
|
|
58
58
|
expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
|
|
59
59
|
expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
it('does not report false positives for Swift test files when getFullText is non-empty but incomplete (prefer disk)', () => {
|
|
63
|
+
const project = new Project({
|
|
64
|
+
useInMemoryFileSystem: true,
|
|
65
|
+
skipAddingFilesFromTsConfig: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const swiftPath = '/tmp/DomainAPIEndpointTests.spec.swift';
|
|
69
|
+
const swiftContent = [
|
|
70
|
+
'import XCTest',
|
|
71
|
+
'final class DomainAPIEndpointTests: XCTestCase {',
|
|
72
|
+
' private func makeSUT() -> Foo { Foo() }',
|
|
73
|
+
' func test_example() {',
|
|
74
|
+
' let sut = makeSUT()',
|
|
75
|
+
' trackForMemoryLeaks(sut, testCase: self, file: #file, line: #line)',
|
|
76
|
+
' }',
|
|
77
|
+
'}',
|
|
78
|
+
].join('\n');
|
|
79
|
+
|
|
80
|
+
const sf = project.createSourceFile(swiftPath, swiftContent);
|
|
81
|
+
jest.spyOn(sf, 'getFullText').mockReturnValue('import XCTest\nfinal class DomainAPIEndpointTests: XCTestCase {}');
|
|
82
|
+
jest.spyOn(fs, 'readFileSync').mockReturnValue(swiftContent);
|
|
83
|
+
|
|
84
|
+
const findings = [];
|
|
85
|
+
runCommonIntelligence(project, findings);
|
|
86
|
+
|
|
87
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
|
|
88
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('does not report false positives for simple value type tests (Ruralgo case)', () => {
|
|
92
|
+
const project = new Project({
|
|
93
|
+
useInMemoryFileSystem: true,
|
|
94
|
+
skipAddingFilesFromTsConfig: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const swiftPath = '/tmp/DomainAPIEndpointTests.spec.swift';
|
|
98
|
+
const simpleValueTypeTest = `import Domain
|
|
99
|
+
import XCTest
|
|
100
|
+
|
|
101
|
+
final class DomainAPIEndpointTests: XCTestCase {
|
|
102
|
+
func test_givenCustomInit_whenAccessingProperties_thenReturnsExpectedValues() {
|
|
103
|
+
let body = Data([0x01, 0x02])
|
|
104
|
+
let queryItems = [URLQueryItem(name: "page", value: "1")]
|
|
105
|
+
|
|
106
|
+
let endpointPatch = APIEndpoint(
|
|
107
|
+
path: "/any", method: .patch, body: body, queryItems: queryItems)
|
|
108
|
+
|
|
109
|
+
XCTAssertEqual(endpointPatch.path, "/any")
|
|
110
|
+
XCTAssertEqual(endpointPatch.method, .patch)
|
|
111
|
+
XCTAssertEqual(endpointPatch.body, body)
|
|
112
|
+
XCTAssertEqual(endpointPatch.queryItems, queryItems)
|
|
113
|
+
}
|
|
114
|
+
}`;
|
|
115
|
+
|
|
116
|
+
const sf = project.createSourceFile(swiftPath, simpleValueTypeTest);
|
|
117
|
+
jest.spyOn(fs, 'readFileSync').mockReturnValue(simpleValueTypeTest);
|
|
118
|
+
|
|
119
|
+
const findings = [];
|
|
120
|
+
runCommonIntelligence(project, findings);
|
|
121
|
+
|
|
122
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
|
|
123
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('does apply rules to complex tests with async/classes', () => {
|
|
127
|
+
const project = new Project({
|
|
128
|
+
useInMemoryFileSystem: true,
|
|
129
|
+
skipAddingFilesFromTsConfig: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const swiftPath = '/tmp/NetworkClientTests.spec.swift';
|
|
133
|
+
const complexTest = `import XCTest
|
|
134
|
+
|
|
135
|
+
final class NetworkClientTests: XCTestCase {
|
|
136
|
+
override func setUp() {
|
|
137
|
+
super.setUp()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
func test_load_deliversErrorOnClientError() async {
|
|
141
|
+
let client = HTTPClient()
|
|
142
|
+
let result = await client.load()
|
|
143
|
+
XCTAssertNotNil(result)
|
|
144
|
+
}
|
|
145
|
+
}`;
|
|
146
|
+
|
|
147
|
+
const sf = project.createSourceFile(swiftPath, complexTest);
|
|
148
|
+
jest.spyOn(fs, 'readFileSync').mockReturnValue(complexTest);
|
|
149
|
+
|
|
150
|
+
const findings = [];
|
|
151
|
+
runCommonIntelligence(project, findings);
|
|
152
|
+
|
|
153
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(true);
|
|
154
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('respects ast-ignore comments', () => {
|
|
158
|
+
const project = new Project({
|
|
159
|
+
useInMemoryFileSystem: true,
|
|
160
|
+
skipAddingFilesFromTsConfig: true,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const swiftPath = '/tmp/SomeTests.spec.swift';
|
|
164
|
+
const testWithIgnore = `import XCTest
|
|
165
|
+
// ast-ignore: missing_makesut, missing_track_for_memory_leaks
|
|
166
|
+
|
|
167
|
+
final class SomeTests: XCTestCase {
|
|
168
|
+
override func setUp() {
|
|
169
|
+
super.setUp()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
func test_something() async {
|
|
173
|
+
let result = await someAsyncCall()
|
|
174
|
+
XCTAssertNotNil(result)
|
|
175
|
+
}
|
|
176
|
+
}`;
|
|
177
|
+
|
|
178
|
+
const sf = project.createSourceFile(swiftPath, testWithIgnore);
|
|
179
|
+
jest.spyOn(fs, 'readFileSync').mockReturnValue(testWithIgnore);
|
|
180
|
+
|
|
181
|
+
const findings = [];
|
|
182
|
+
runCommonIntelligence(project, findings);
|
|
183
|
+
|
|
184
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
|
|
185
|
+
expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
|
|
186
|
+
});
|
|
61
187
|
});
|
|
62
188
|
|
|
63
189
|
describe('exports', () => {
|
|
@@ -71,6 +71,66 @@ function hasTrackForMemoryLeaksEvidence(content) {
|
|
|
71
71
|
return hasTrackForMemoryLeaks(content) || hasMakeSUT(content);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Detect if a test file is a simple value type test that doesn't need makeSUT/trackForMemoryLeaks.
|
|
76
|
+
* Simple tests typically:
|
|
77
|
+
* - Have no async/await or closures capturing self
|
|
78
|
+
* - Have no class instantiation patterns (reference types)
|
|
79
|
+
* - Test only property access or simple assertions
|
|
80
|
+
* - Have no setUp/tearDown methods
|
|
81
|
+
*/
|
|
82
|
+
function isSimpleValueTypeTest(content) {
|
|
83
|
+
// If it has setUp/tearDown, it's not simple - needs proper patterns
|
|
84
|
+
if (/\boverride\s+func\s+(setUp|tearDown)/.test(content)) return false;
|
|
85
|
+
|
|
86
|
+
// If it has async/await, needs memory tracking
|
|
87
|
+
if (/\basync\b|\bawait\b|\bexpectation\(|\bwaitForExpectations\b/.test(content)) return false;
|
|
88
|
+
|
|
89
|
+
// If it has closures that might capture self, needs tracking
|
|
90
|
+
if (/\[\s*(weak|unowned)?\s*self\s*\]/.test(content)) return false;
|
|
91
|
+
|
|
92
|
+
// If it has completion handlers or callbacks, needs tracking
|
|
93
|
+
if (/completion\s*:|\@escaping|\bresult\s*in\b/i.test(content)) return false;
|
|
94
|
+
|
|
95
|
+
// If it creates classes (not structs), needs makeSUT pattern
|
|
96
|
+
// Look for "= ClassName(" but not "= StructName(" - heuristic: classes often have "Client", "Service", "Manager", "Repository"
|
|
97
|
+
if (/=\s*\w*(Client|Service|Manager|Repository|UseCase|Interactor|Presenter|ViewModel|Controller)\s*\(/.test(content)) return false;
|
|
98
|
+
|
|
99
|
+
// If it's a very short test (likely simple property test), skip rules
|
|
100
|
+
const lines = content.split('\n').filter(l => l.trim().length > 0);
|
|
101
|
+
if (lines.length <= 40) return true;
|
|
102
|
+
|
|
103
|
+
// If it only has XCTAssertEqual for properties, it's likely a simple value type test
|
|
104
|
+
const testMethods = content.match(/func\s+test_[^{]+\{[^}]+\}/gs) || [];
|
|
105
|
+
if (testMethods.length > 0) {
|
|
106
|
+
const allSimple = testMethods.every(method => {
|
|
107
|
+
// Simple test: mostly XCTAssert* calls, no complex setup
|
|
108
|
+
const hasOnlyAsserts = /XCTAssert(Equal|True|False|Nil|NotNil)/.test(method);
|
|
109
|
+
const hasNoComplexSetup = !/\bsut\b|makeSUT|\bawait\b|completion/.test(method);
|
|
110
|
+
return hasOnlyAsserts && hasNoComplexSetup;
|
|
111
|
+
});
|
|
112
|
+
if (allSimple && testMethods.length <= 3) return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check for ast-ignore comments in content
|
|
120
|
+
* Supports: // ast-ignore: rule_name or // ast-ignore: rule1, rule2
|
|
121
|
+
*/
|
|
122
|
+
function hasAstIgnoreComment(content, ruleId) {
|
|
123
|
+
const ignorePattern = /\/\/\s*ast-ignore:\s*([^\n]+)/gi;
|
|
124
|
+
let match;
|
|
125
|
+
while ((match = ignorePattern.exec(content)) !== null) {
|
|
126
|
+
const rules = match[1].split(',').map(r => r.trim().toLowerCase());
|
|
127
|
+
if (rules.includes(ruleId.toLowerCase()) || rules.includes('all')) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
74
134
|
function detectMockSignals(content) {
|
|
75
135
|
const signals = [
|
|
76
136
|
/\bjest\.mock\s*\(/,
|
|
@@ -214,9 +274,12 @@ function runCommonIntelligence(project, findings) {
|
|
|
214
274
|
const ext = path.extname(filePath).toLowerCase();
|
|
215
275
|
const isSwiftOrKotlinTest = ext === '.swift' || ext === '.kt' || ext === '.kts';
|
|
216
276
|
|
|
217
|
-
if (isSwiftOrKotlinTest
|
|
277
|
+
if (isSwiftOrKotlinTest) {
|
|
218
278
|
try {
|
|
219
|
-
|
|
279
|
+
const diskContent = fs.readFileSync(filePath, 'utf8');
|
|
280
|
+
if (diskContent && diskContent.trim().length > 0) {
|
|
281
|
+
content = diskContent;
|
|
282
|
+
}
|
|
220
283
|
} catch (error) {
|
|
221
284
|
if (process.env.DEBUG) {
|
|
222
285
|
console.debug(`[ast-common] Failed to read test file content for ${filePath}: ${error.message}`);
|
|
@@ -225,7 +288,12 @@ function runCommonIntelligence(project, findings) {
|
|
|
225
288
|
}
|
|
226
289
|
|
|
227
290
|
if (isSwiftOrKotlinTest) {
|
|
228
|
-
|
|
291
|
+
const isSimple = isSimpleValueTypeTest(content);
|
|
292
|
+
|
|
293
|
+
if (!shouldSkipMakeSUTRule(filePath) &&
|
|
294
|
+
!hasMakeSUT(content) &&
|
|
295
|
+
!isSimple &&
|
|
296
|
+
!hasAstIgnoreComment(content, 'missing_makesut')) {
|
|
229
297
|
pushFinding(
|
|
230
298
|
'common.testing.missing_makesut',
|
|
231
299
|
'high',
|
|
@@ -236,7 +304,10 @@ function runCommonIntelligence(project, findings) {
|
|
|
236
304
|
);
|
|
237
305
|
}
|
|
238
306
|
|
|
239
|
-
if (!shouldSkipTrackForMemoryLeaksRule(filePath) &&
|
|
307
|
+
if (!shouldSkipTrackForMemoryLeaksRule(filePath) &&
|
|
308
|
+
!hasTrackForMemoryLeaksEvidence(content) &&
|
|
309
|
+
!isSimple &&
|
|
310
|
+
!hasAstIgnoreComment(content, 'missing_track_for_memory_leaks')) {
|
|
240
311
|
pushFinding(
|
|
241
312
|
'common.testing.missing_track_for_memory_leaks',
|
|
242
313
|
'critical',
|
package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log
CHANGED
|
@@ -25,3 +25,6 @@
|
|
|
25
25
|
{"timestamp":"2026-01-11T19:08:37.452Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
26
26
|
{"timestamp":"2026-01-11T19:08:37.467Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
27
27
|
{"timestamp":"2026-01-11T19:08:37.468Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
28
|
+
{"timestamp":"2026-01-11T20:43:25.680Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
29
|
+
{"timestamp":"2026-01-11T20:43:25.683Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
30
|
+
{"timestamp":"2026-01-11T20:43:25.683Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|