pumuki-ast-hooks 6.0.5 → 6.0.7

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 CHANGED
@@ -53,6 +53,14 @@ Documentation:
53
53
 
54
54
  - `docs/USAGE.md` (Interactive Menu, non‑interactive `AUDIT_OPTION`, and typical flows)
55
55
  - `CHANGELOG.md` (Release notes and changes)
56
+ - Keychain/Security casts are exempted from `ios.types.forbidden_type_cast` to avoid false positives in secure storage implementations.
57
+
58
+ Release 6.0.6:
59
+ - Keychain/Security casts are exempted from `ios.types.forbidden_type_cast` to avoid false positives in secure storage implementations.
60
+ - Staging-only detection now ignores deleted files when building the file list.
61
+
62
+ Release 6.0.7:
63
+ - God Class detection (backend): baseline-first by default; optional hard cap via env; detector always runs (with or without baseline).
56
64
 
57
65
  ---
58
66
 
@@ -1,3 +1,17 @@
1
+ # Release Notes - v6.0.7
2
+
3
+ **Release Date**: January 13, 2026
4
+ **Type**: Patch Release
5
+ **Compatibility**: Fully backward compatible with 6.0.x
6
+
7
+ ---
8
+
9
+ ## ✅ Fixes
10
+
11
+ - **God Class detection (backend)**: baseline-first by default; optional hard cap via env; detector always runs (with or without baseline).
12
+
13
+ ---
14
+
1
15
  # Release Notes - v5.5.25
2
16
 
3
17
  **Release Date**: January 4, 2026
package/docs/USAGE.md CHANGED
@@ -12,6 +12,13 @@
12
12
 
13
13
  ---
14
14
 
15
+ ## Recent Changes (v6.0.6)
16
+
17
+ - Keychain/Security casts are exempted from `ios.types.forbidden_type_cast` to avoid false positives.
18
+ - Staging gate evaluation ignores deleted files when assembling the staged file list.
19
+
20
+ ---
21
+
15
22
  ## Minimal Example (5 minutes)
16
23
 
17
24
  ### Step 1: Install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki-ast-hooks",
3
- "version": "6.0.5",
3
+ "version": "6.0.7",
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": {
@@ -18,3 +18,5 @@
18
18
  {"timestamp":"2026-01-12T19:29:17.037Z","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":{}}
19
19
  {"timestamp":"2026-01-12T23:31:06.880Z","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":{}}
20
20
  {"timestamp":"2026-01-12T23:36:15.876Z","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":{}}
21
+ {"timestamp":"2026-01-13T00:00:36.969Z","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":{}}
22
+ {"timestamp":"2026-01-13T07:51:05.490Z","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":{}}
@@ -82,3 +82,11 @@
82
82
  {"timestamp":"2026-01-12T23:36:15.949Z","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":{}}
83
83
  {"timestamp":"2026-01-12T23:36:15.950Z","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":{}}
84
84
  {"timestamp":"2026-01-12T23:36:15.950Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
85
+ {"timestamp":"2026-01-13T00:00:37.042Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
86
+ {"timestamp":"2026-01-13T00:00:37.050Z","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":{}}
87
+ {"timestamp":"2026-01-13T00:00:37.050Z","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":{}}
88
+ {"timestamp":"2026-01-13T00:00:37.050Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
89
+ {"timestamp":"2026-01-13T07:51:05.568Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
90
+ {"timestamp":"2026-01-13T07:51:05.577Z","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":{}}
91
+ {"timestamp":"2026-01-13T07:51:05.577Z","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":{}}
92
+ {"timestamp":"2026-01-13T07:51:05.577Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
@@ -738,3 +738,55 @@
738
738
  {"timestamp":1768260975876,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
739
739
  {"timestamp":1768260975876,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
740
740
  {"timestamp":1768260975876,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
741
+ {"timestamp":1768262436967,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
742
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
743
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
744
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
745
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
746
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
747
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
748
+ {"timestamp":1768262436968,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
749
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
750
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
751
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
752
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
753
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
754
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
755
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
756
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
757
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
758
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
759
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
760
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
761
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
762
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
763
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
764
+ {"timestamp":1768262436969,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
765
+ {"timestamp":1768288829103,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
766
+ {"timestamp":1768288829103,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
767
+ {"timestamp":1768288829103,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
768
+ {"timestamp":1768288829103,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
769
+ {"timestamp":1768290665487,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
770
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
771
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
772
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
773
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
774
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
775
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
776
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
777
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
778
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
779
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
780
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
781
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
782
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
783
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
784
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
785
+ {"timestamp":1768290665488,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
786
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
787
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
788
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
789
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
790
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
791
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
792
+ {"timestamp":1768290665489,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
@@ -58,7 +58,7 @@ function getCurrentBranchSafe() {
58
58
 
59
59
  function getStagedFilesSafe() {
60
60
  try {
61
- const output = execSync('git diff --cached --name-only', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
61
+ const output = execSync('git diff --cached --name-only --diff-filter=ACMRT', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
62
62
  return output.trim().split('\n').filter(Boolean);
63
63
  } catch (e) {
64
64
  return [];
@@ -310,9 +310,19 @@ function runBackendIntelligence(project, findings, platform) {
310
310
  pushFinding("backend.config.missing_validation", "warning", sf, sf, "Environment variables without validation - consider Joi or class-validator", findings);
311
311
  }
312
312
 
313
- if (godClassBaseline) {
314
- analyzeGodClasses(sf, findings, { SyntaxKind, pushFinding, godClassBaseline });
315
- }
313
+ const hardMaxLines = env.getNumber('AST_GODCLASS_HARD_MAX_LINES', 0);
314
+ const softMaxLines = env.getNumber('AST_GODCLASS_SOFT_MAX_LINES', 500);
315
+ const absoluteGodLines = env.getNumber('AST_GODCLASS_ABSOLUTE_LINES', 1000);
316
+ const underThresholdLines = env.getNumber('AST_GODCLASS_UNDER_THRESHOLD_LINES', 300);
317
+ analyzeGodClasses(sf, findings, {
318
+ SyntaxKind,
319
+ pushFinding,
320
+ godClassBaseline,
321
+ hardMaxLines,
322
+ softMaxLines,
323
+ absoluteGodLines,
324
+ underThresholdLines
325
+ });
316
326
 
317
327
  if (!isRealBackendAppFile) {
318
328
  return;
@@ -1,7 +1,15 @@
1
1
  /**
2
2
  * God Class detector extracted from ast-backend.js to keep responsibilities separated.
3
3
  */
4
- function analyzeGodClasses(sourceFile, findings, { SyntaxKind, pushFinding, godClassBaseline }) {
4
+ function analyzeGodClasses(sourceFile, findings, {
5
+ SyntaxKind,
6
+ pushFinding,
7
+ godClassBaseline,
8
+ hardMaxLines,
9
+ softMaxLines,
10
+ absoluteGodLines,
11
+ underThresholdLines
12
+ }) {
5
13
  const filePath = sourceFile.getFilePath().replace(/\\/g, '/');
6
14
  if (
7
15
  /\/infrastructure\/ast\//i.test(filePath) ||
@@ -24,6 +32,12 @@ function analyzeGodClasses(sourceFile, findings, { SyntaxKind, pushFinding, godC
24
32
  const endLine = cls.getEndLineNumber();
25
33
  const lineCount = Math.max(0, endLine - startLine);
26
34
 
35
+ const hardMax = Number.isFinite(hardMaxLines) && hardMaxLines > 0 ? hardMaxLines : 0;
36
+ const softMax = Number.isFinite(softMaxLines) && softMaxLines > 0 ? softMaxLines : 500;
37
+ const absoluteLines = Number.isFinite(absoluteGodLines) && absoluteGodLines > 0 ? absoluteGodLines : 1000;
38
+ const underLines = Number.isFinite(underThresholdLines) && underThresholdLines > 0 ? underThresholdLines : 300;
39
+ const isHardMaxViolation = hardMax > 0 && lineCount > hardMax;
40
+
27
41
  const decisionKinds = [
28
42
  SyntaxKind.IfStatement,
29
43
  SyntaxKind.ForStatement,
@@ -51,12 +65,20 @@ function analyzeGodClasses(sourceFile, findings, { SyntaxKind, pushFinding, godC
51
65
  if (/\bgit\b|rev-parse|git diff|git status|git log/i.test(clsText)) concerns.add('git');
52
66
  const concernCount = concerns.size;
53
67
 
54
- const isMassiveFile = lineCount > 500;
55
- const isAbsoluteGod = lineCount > 1000 ||
56
- (lineCount > 500 && complexity > 50) ||
57
- (lineCount > 500 && methodsCount > 20) ||
58
- (lineCount > 600 && methodsCount > 30 && complexity > 80);
59
- const isUnderThreshold = lineCount < 300 && methodsCount < 15 && complexity < 30;
68
+ if (isHardMaxViolation) {
69
+ pushFinding("backend.antipattern.god_classes", "critical", sourceFile, cls,
70
+ `God class detected: ${methodsCount} methods, ${propertiesCount} properties, ${lineCount} lines, complexity ${complexity}, concerns ${concernCount} - VIOLATES SRP`,
71
+ findings
72
+ );
73
+ return;
74
+ }
75
+
76
+ const isMassiveFile = lineCount > softMax;
77
+ const isAbsoluteGod = lineCount > absoluteLines ||
78
+ (lineCount > softMax && complexity > 50) ||
79
+ (lineCount > softMax && methodsCount > 20) ||
80
+ (lineCount > (softMax + 100) && methodsCount > 30 && complexity > 80);
81
+ const isUnderThreshold = lineCount < underLines && methodsCount < 15 && complexity < 30;
60
82
 
61
83
  if (!godClassBaseline) {
62
84
  if (!isUnderThreshold && (isMassiveFile || isAbsoluteGod)) {
@@ -154,14 +154,18 @@ class iOSForbiddenLiteralsAnalyzer {
154
154
 
155
155
  analyzeTypeCasts(asExpressions, sf, findings, pushFinding) {
156
156
  if (!sf || typeof sf.getFilePath !== 'function') return;
157
+ const fullText = sf.getFullText();
158
+ const filePath = sf.getFilePath();
159
+ const hasSecurityImport = /import\s+Security\b/.test(fullText);
160
+ const isKeychainHelper = /KeychainHelper\.swift$/i.test(filePath);
161
+ if (hasSecurityImport || isKeychainHelper) return;
157
162
  asExpressions.forEach((expr) => {
158
- const fullText = sf.getFullText();
159
163
  const exprIndex = expr.getStart();
160
164
  const lineStart = fullText.lastIndexOf('\n', exprIndex) + 1;
161
165
  const lineEnd = fullText.indexOf('\n', exprIndex);
162
166
  const fullLine = fullText.substring(lineStart, lineEnd === -1 ? undefined : lineEnd);
163
167
 
164
- const isInTestFile = /\.(spec|test)\.(swift)$/i.test(sf.getFilePath());
168
+ const isInTestFile = /\.(spec|test)\.(swift)$/i.test(filePath);
165
169
  const isTypeAssertion = /as\s+(UserRole|OrderStatus|UserStatus|AlertStatus)/i.test(fullLine);
166
170
 
167
171
  if (isInTestFile || isTypeAssertion) return;
@@ -578,7 +578,7 @@ function getStagedFiles() {
578
578
  const { execSync } = require('child_process');
579
579
 
580
580
  try {
581
- const result = execSync('git diff --cached --name-only', { encoding: 'utf8' });
581
+ const result = execSync('git diff --cached --name-only --diff-filter=ACMRT', { encoding: 'utf8' });
582
582
  return result.trim().split('\n').filter(f => f);
583
583
  } catch (error) {
584
584
  process.stderr.write(`[Intelligent Audit] ⚠️ Failed to read staged files: ${toErrorMessage(error)}\n`);
@@ -58,3 +58,9 @@
58
58
  {"timestamp":"2026-01-12T23:36:17.856Z","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"}}
59
59
  {"timestamp":"2026-01-12T23:36:17.857Z","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"}}
60
60
  {"timestamp":"2026-01-12T23:36:17.857Z","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)"}}
61
+ {"timestamp":"2026-01-13T00:00:38.463Z","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"}}
62
+ {"timestamp":"2026-01-13T00:00:38.464Z","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"}}
63
+ {"timestamp":"2026-01-13T00:00:38.464Z","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)"}}
64
+ {"timestamp":"2026-01-13T07:51:07.491Z","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"}}
65
+ {"timestamp":"2026-01-13T07:51:07.492Z","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"}}
66
+ {"timestamp":"2026-01-13T07:51:07.493Z","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)"}}