pumuki-ast-hooks 5.3.18 → 5.3.20
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/docs/VIOLATIONS_RESOLUTION_PLAN.md +39 -37
- package/package.json +8 -2
- package/scripts/hooks-system/application/CompositionRoot.js +24 -73
- package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +18 -0
- package/scripts/hooks-system/application/services/ContextDetectionEngine.js +58 -0
- package/scripts/hooks-system/application/services/DynamicRulesLoader.js +12 -2
- package/scripts/hooks-system/application/services/GitFlowService.js +80 -0
- package/scripts/hooks-system/application/services/GitTreeState.js +143 -13
- package/scripts/hooks-system/application/services/HookSystemScheduler.js +47 -0
- package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +25 -0
- package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +11 -0
- package/scripts/hooks-system/application/services/PlatformAnalysisService.js +19 -0
- package/scripts/hooks-system/application/services/PlatformDetectionService.js +19 -0
- package/scripts/hooks-system/application/services/PlaybookRunner.js +22 -1
- package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +19 -0
- package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +25 -0
- package/scripts/hooks-system/application/services/RealtimeGuardService.js +41 -84
- package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +11 -0
- package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +11 -0
- package/scripts/hooks-system/application/services/commit/FeatureDetector.js +11 -0
- package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +25 -0
- package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +21 -31
- package/scripts/hooks-system/application/services/guard/GuardConfig.js +18 -15
- package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +26 -0
- package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +20 -6
- package/scripts/hooks-system/application/services/guard/GuardLockManager.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +25 -0
- package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +10 -28
- package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +11 -0
- package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +18 -0
- package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +18 -0
- package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +18 -3
- package/scripts/hooks-system/application/services/installation/HookInstaller.js +19 -0
- package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +11 -0
- package/scripts/hooks-system/application/services/installation/InstallService.js +25 -1
- package/scripts/hooks-system/application/services/installation/McpConfigurator.js +19 -2
- package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +11 -0
- package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +11 -0
- package/scripts/hooks-system/application/services/logging/AuditLogger.js +90 -1
- package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +15 -13
- package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +33 -0
- package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +27 -0
- package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +19 -0
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +27 -6
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +28 -0
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/HealthCheckProviders.js +4 -0
- package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +25 -0
- package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +26 -0
- package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +11 -0
- package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +18 -0
- package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +11 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +18 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +18 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +11 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +20 -0
- package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +19 -0
- package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +19 -0
- package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +11 -0
- package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +19 -0
- package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +4 -0
- package/scripts/hooks-system/application/services/token/CursorTokenService.js +20 -0
- package/scripts/hooks-system/application/services/token/TokenMetricsService.js +11 -13
- package/scripts/hooks-system/application/services/token/TokenMonitorService.js +19 -0
- package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +12 -0
- package/scripts/hooks-system/bin/__tests__/evidence-update.spec.js +49 -0
- package/scripts/hooks-system/bin/cli.js +1 -15
- package/scripts/hooks-system/config/project.config.json +1 -1
- package/scripts/hooks-system/domain/events/index.js +24 -31
- package/scripts/hooks-system/domain/exceptions/index.js +87 -0
- package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +2 -3
- package/scripts/hooks-system/infrastructure/ast/ast-core.js +20 -12
- package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +18 -8
- package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +1 -2
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +14 -18
- package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/__tests__/iOSASTIntelligentAnalyzer.spec.js +66 -0
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +2 -3
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSArchitectureRules.js +24 -86
- package/scripts/hooks-system/infrastructure/config/config.js +5 -0
- package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +2 -3
- package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -35
- package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +16 -86
- package/scripts/hooks-system/infrastructure/shell/orchestrators/audit-orchestrator.sh +54 -92
- package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
- package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +2 -51
- package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +8 -6
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
+
const {
|
|
5
|
+
createMetricScope: createMetricScope
|
|
6
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
7
|
+
|
|
4
8
|
const METRICS_FILE = path.join(process.cwd(), '.audit_tmp', 'hook-metrics.jsonl');
|
|
5
9
|
|
|
6
10
|
class PredictiveHookAdvisor {
|
|
7
11
|
constructor({ windowSize = 200 } = {}) {
|
|
12
|
+
const m_constructor = createMetricScope({
|
|
13
|
+
hook: 'predictive_hook_advisor',
|
|
14
|
+
operation: 'constructor'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
m_constructor.started();
|
|
8
18
|
this.windowSize = windowSize;
|
|
19
|
+
m_constructor.success();
|
|
9
20
|
}
|
|
10
21
|
|
|
11
22
|
loadMetrics() {
|
|
@@ -24,6 +35,12 @@ class PredictiveHookAdvisor {
|
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
getFailureProbabilities() {
|
|
38
|
+
const m_get_failure_probabilities = createMetricScope({
|
|
39
|
+
hook: 'predictive_hook_advisor',
|
|
40
|
+
operation: 'get_failure_probabilities'
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
m_get_failure_probabilities.started();
|
|
27
44
|
const metrics = this.loadMetrics();
|
|
28
45
|
const stats = {};
|
|
29
46
|
|
|
@@ -38,6 +55,8 @@ class PredictiveHookAdvisor {
|
|
|
38
55
|
}
|
|
39
56
|
}
|
|
40
57
|
|
|
58
|
+
m_get_failure_probabilities.success();
|
|
59
|
+
|
|
41
60
|
return Object.entries(stats)
|
|
42
61
|
.map(([hook, { total, failures }]) => ({
|
|
43
62
|
hook,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const EvidenceMonitorService = require('./monitoring/EvidenceMonitorService');
|
|
2
2
|
|
|
3
|
+
const {
|
|
4
|
+
createMetricScope: createMetricScope
|
|
5
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
6
|
+
|
|
3
7
|
class EvidenceRealtimeGuardPlugin {
|
|
4
8
|
constructor({
|
|
5
9
|
repoRoot = process.cwd(),
|
|
@@ -7,6 +11,12 @@ class EvidenceRealtimeGuardPlugin {
|
|
|
7
11
|
logger = console,
|
|
8
12
|
evidenceMonitor = null
|
|
9
13
|
} = {}) {
|
|
14
|
+
const m_constructor = createMetricScope({
|
|
15
|
+
hook: 'realtime_guard_plugin',
|
|
16
|
+
operation: 'constructor'
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
m_constructor.started();
|
|
10
20
|
this.repoRoot = repoRoot;
|
|
11
21
|
this.notificationCenter = notificationCenter;
|
|
12
22
|
this.logger = logger || console;
|
|
@@ -16,18 +26,33 @@ class EvidenceRealtimeGuardPlugin {
|
|
|
16
26
|
logger: this.logger,
|
|
17
27
|
notifier: payload => this.forwardNotification(payload)
|
|
18
28
|
});
|
|
29
|
+
m_constructor.success();
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
start() {
|
|
33
|
+
const m_start = createMetricScope({
|
|
34
|
+
hook: 'realtime_guard_plugin',
|
|
35
|
+
operation: 'start'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
m_start.started();
|
|
22
39
|
if (typeof this.evidenceMonitor.start === 'function') {
|
|
23
40
|
this.evidenceMonitor.start();
|
|
24
41
|
}
|
|
42
|
+
m_start.success();
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
stop() {
|
|
46
|
+
const m_stop = createMetricScope({
|
|
47
|
+
hook: 'realtime_guard_plugin',
|
|
48
|
+
operation: 'stop'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
m_stop.started();
|
|
28
52
|
if (typeof this.evidenceMonitor.stop === 'function') {
|
|
29
53
|
this.evidenceMonitor.stop();
|
|
30
54
|
}
|
|
55
|
+
m_stop.success();
|
|
31
56
|
}
|
|
32
57
|
|
|
33
58
|
forwardNotification(payload) {
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { getGitTreeState, isTreeBeyondLimit } = require('./GitTreeState');
|
|
4
|
-
|
|
5
|
-
const { recordMetric } = require('
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
createMetricScope: createMetricScope
|
|
9
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
7
10
|
|
|
8
11
|
class RealtimeGuardService {
|
|
9
12
|
/**
|
|
@@ -15,12 +18,13 @@ class RealtimeGuardService {
|
|
|
15
18
|
* @param {Object} dependencies.config
|
|
16
19
|
*/
|
|
17
20
|
constructor(dependencies = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
recordMetric({
|
|
22
|
+
hook: 'realtime_guard_service',
|
|
23
|
+
operation: 'constructor',
|
|
24
|
+
status: 'started',
|
|
25
|
+
hasDependencies: !!dependencies
|
|
26
|
+
});
|
|
22
27
|
|
|
23
|
-
_initializeDependencies(dependencies = {}) {
|
|
24
28
|
const {
|
|
25
29
|
logger,
|
|
26
30
|
notificationService,
|
|
@@ -39,49 +43,45 @@ class RealtimeGuardService {
|
|
|
39
43
|
this.monitors = monitors || {};
|
|
40
44
|
this.orchestration = orchestration;
|
|
41
45
|
this.config = config || {};
|
|
42
|
-
this.auditLogger = dependencies.auditLogger || new AuditLogger({ repoRoot: process.cwd(), logger: this.logger });
|
|
43
|
-
}
|
|
44
46
|
|
|
45
|
-
_initializeConfiguration() {
|
|
46
47
|
if (!this.config.debugLogPath) {
|
|
47
48
|
this.config.debugLogPath = path.join(process.cwd(), '.audit-reports', 'guard-debug.log');
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
this.evidencePath = this.config.evidencePath || path.join(
|
|
51
|
-
this.staleThresholdMs = env.
|
|
52
|
-
this.reminderIntervalMs = env.
|
|
53
|
-
this.inactivityGraceMs = env.
|
|
54
|
-
this.pollIntervalMs = env.
|
|
51
|
+
this.evidencePath = this.config.evidencePath || path.join(process.cwd(), '.AI_EVIDENCE.json');
|
|
52
|
+
this.staleThresholdMs = Number(process.env.HOOK_GUARD_EVIDENCE_STALE_THRESHOLD || 60000);
|
|
53
|
+
this.reminderIntervalMs = Number(process.env.HOOK_GUARD_EVIDENCE_REMINDER_INTERVAL || 60000);
|
|
54
|
+
this.inactivityGraceMs = Number(process.env.HOOK_GUARD_INACTIVITY_GRACE_MS || 120000);
|
|
55
|
+
this.pollIntervalMs = Number(process.env.HOOK_GUARD_EVIDENCE_POLL_INTERVAL || 30000);
|
|
55
56
|
this.pollTimer = null;
|
|
56
57
|
this.lastStaleNotification = 0;
|
|
57
58
|
this.lastUserActivityAt = 0;
|
|
58
59
|
|
|
59
|
-
this.gitTreeStagedThreshold = env.
|
|
60
|
-
this.gitTreeUnstagedThreshold = env.
|
|
61
|
-
this.gitTreeTotalThreshold = env.
|
|
62
|
-
this.gitTreeCheckIntervalMs = env.
|
|
63
|
-
this.gitTreeReminderMs = env.
|
|
60
|
+
this.gitTreeStagedThreshold = Number(process.env.HOOK_GUARD_DIRTY_TREE_STAGED_LIMIT || 10);
|
|
61
|
+
this.gitTreeUnstagedThreshold = Number(process.env.HOOK_GUARD_DIRTY_TREE_UNSTAGED_LIMIT || 15);
|
|
62
|
+
this.gitTreeTotalThreshold = Number(process.env.HOOK_GUARD_DIRTY_TREE_TOTAL_LIMIT || 20);
|
|
63
|
+
this.gitTreeCheckIntervalMs = Number(process.env.HOOK_GUARD_DIRTY_TREE_INTERVAL || 60000);
|
|
64
|
+
this.gitTreeReminderMs = Number(process.env.HOOK_GUARD_DIRTY_TREE_REMINDER || 300000);
|
|
64
65
|
this.gitTreeTimer = null;
|
|
65
66
|
this.lastDirtyTreeNotification = 0;
|
|
66
67
|
this.dirtyTreeActive = false;
|
|
67
68
|
|
|
68
|
-
this.autoRefreshCooldownMs = env.
|
|
69
|
+
this.autoRefreshCooldownMs = Number(process.env.HOOK_GUARD_EVIDENCE_AUTO_REFRESH_COOLDOWN || 180000);
|
|
69
70
|
this.lastAutoRefresh = 0;
|
|
70
71
|
this.autoRefreshInFlight = false;
|
|
71
72
|
|
|
72
73
|
this.watchers = [];
|
|
73
|
-
this.embedTokenMonitor = env.
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
_initializeMonitors() {
|
|
77
|
-
// Monitors are configured but not started here
|
|
78
|
-
// They are started in the start() method to allow for proper initialization order
|
|
74
|
+
this.embedTokenMonitor = process.env.HOOK_GUARD_EMBEDDED_TOKEN_MONITOR === 'true';
|
|
79
75
|
}
|
|
80
76
|
|
|
81
77
|
start() {
|
|
78
|
+
const m_start = createMetricScope({
|
|
79
|
+
hook: 'realtime_guard_service',
|
|
80
|
+
operation: 'start'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
m_start.started();
|
|
82
84
|
this.logger.info('Starting RealtimeGuardService...');
|
|
83
|
-
this.auditLogger.record({ action: 'guard.realtime.start', resource: 'realtime_guard', status: 'success' });
|
|
84
|
-
recordMetric({ hook: 'realtime_guard', status: 'start' });
|
|
85
85
|
|
|
86
86
|
// Start all monitors
|
|
87
87
|
this._startEvidenceMonitoring();
|
|
@@ -97,12 +97,17 @@ class RealtimeGuardService {
|
|
|
97
97
|
this._startGitFlowSync();
|
|
98
98
|
|
|
99
99
|
this.logger.info('[RealtimeGuardService] All services started');
|
|
100
|
+
m_start.success();
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
stop() {
|
|
104
|
+
const m_stop = createMetricScope({
|
|
105
|
+
hook: 'realtime_guard_service',
|
|
106
|
+
operation: 'stop'
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
m_stop.started();
|
|
103
110
|
this.logger.info('Stopping RealtimeGuardService...');
|
|
104
|
-
this.auditLogger.record({ action: 'guard.realtime.stop', resource: 'realtime_guard', status: 'success' });
|
|
105
|
-
recordMetric({ hook: 'realtime_guard', status: 'stop' });
|
|
106
111
|
|
|
107
112
|
this.watchers.forEach(w => w.close());
|
|
108
113
|
this.watchers = [];
|
|
@@ -114,6 +119,7 @@ class RealtimeGuardService {
|
|
|
114
119
|
});
|
|
115
120
|
|
|
116
121
|
this.logger.info('[RealtimeGuardService] All services stopped');
|
|
122
|
+
m_stop.success();
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
_startEvidenceMonitoring() {
|
|
@@ -124,27 +130,14 @@ class RealtimeGuardService {
|
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
_startGitTreeMonitoring() {
|
|
127
|
-
if (env.
|
|
133
|
+
if (process.env.HOOK_GUARD_DIRTY_TREE_DISABLED === 'true') return;
|
|
128
134
|
|
|
129
135
|
this.monitors.gitTree.startMonitoring((state) => {
|
|
130
136
|
if (state.isBeyondLimit) {
|
|
131
137
|
const message = `Git tree has too many files: ${state.total} total (${state.staged} staged, ${state.unstaged} unstaged)`;
|
|
132
138
|
this.notify(message, 'error', { forceDialog: true });
|
|
133
|
-
this.auditLogger.record({
|
|
134
|
-
action: 'guard.git_tree.dirty',
|
|
135
|
-
resource: 'git_tree',
|
|
136
|
-
status: 'warning',
|
|
137
|
-
meta: { total: state.total, staged: state.staged, unstaged: state.unstaged }
|
|
138
|
-
});
|
|
139
|
-
recordMetric({ hook: 'git_tree', status: 'dirty', total: state.total, staged: state.staged, unstaged: state.unstaged });
|
|
140
139
|
} else {
|
|
141
140
|
this.notify('✅ Git tree is clean', 'success');
|
|
142
|
-
this.auditLogger.record({
|
|
143
|
-
action: 'guard.git_tree.clean',
|
|
144
|
-
resource: 'git_tree',
|
|
145
|
-
status: 'success'
|
|
146
|
-
});
|
|
147
|
-
recordMetric({ hook: 'git_tree', status: 'clean' });
|
|
148
141
|
}
|
|
149
142
|
});
|
|
150
143
|
}
|
|
@@ -158,44 +151,22 @@ class RealtimeGuardService {
|
|
|
158
151
|
try {
|
|
159
152
|
this.monitors.token.start();
|
|
160
153
|
this.notify('🔋 Token monitor started', 'info');
|
|
161
|
-
this.auditLogger.record({
|
|
162
|
-
action: 'guard.token_monitor.start',
|
|
163
|
-
resource: 'token_monitor',
|
|
164
|
-
status: 'success'
|
|
165
|
-
});
|
|
166
|
-
recordMetric({ hook: 'token_monitor', status: 'start' });
|
|
167
154
|
} catch (error) {
|
|
168
155
|
this.notify(`Failed to start token monitor: ${error.message}`, 'error');
|
|
169
|
-
this.auditLogger.record({
|
|
170
|
-
action: 'guard.token_monitor.start',
|
|
171
|
-
resource: 'token_monitor',
|
|
172
|
-
status: 'fail',
|
|
173
|
-
meta: { message: error.message }
|
|
174
|
-
});
|
|
175
|
-
recordMetric({ hook: 'token_monitor', status: 'fail' });
|
|
176
156
|
}
|
|
177
157
|
}
|
|
178
158
|
|
|
179
159
|
_startGitFlowSync() {
|
|
180
160
|
if (!this.monitors.gitFlow.autoSyncEnabled) return;
|
|
181
161
|
|
|
182
|
-
this.auditLogger.record({
|
|
183
|
-
action: 'guard.gitflow.autosync.enabled',
|
|
184
|
-
resource: 'gitflow',
|
|
185
|
-
status: 'success',
|
|
186
|
-
meta: { intervalMs: env.getNumber('HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL', 300000) }
|
|
187
|
-
});
|
|
188
|
-
recordMetric({ hook: 'gitflow_autosync', status: 'enabled' });
|
|
189
|
-
|
|
190
162
|
const syncInterval = setInterval(() => {
|
|
191
163
|
if (this.monitors.gitFlow.isClean()) {
|
|
192
164
|
const result = this.monitors.gitFlow.syncBranches();
|
|
193
165
|
if (result.success) {
|
|
194
166
|
this.notify('🔄 Branches synchronized', 'info');
|
|
195
|
-
recordMetric({ hook: 'gitflow_autosync', status: 'sync_success' });
|
|
196
167
|
}
|
|
197
168
|
}
|
|
198
|
-
}, env.
|
|
169
|
+
}, Number(process.env.HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL || 300000));
|
|
199
170
|
|
|
200
171
|
syncInterval.unref();
|
|
201
172
|
}
|
|
@@ -303,18 +274,11 @@ class RealtimeGuardService {
|
|
|
303
274
|
this.lastStaleNotification = now;
|
|
304
275
|
const ageSec = Math.floor(ageMs / 1000);
|
|
305
276
|
this.notify(`Evidence has been stale for ${ageSec}s (source: ${source}).`, 'warn', { forceDialog: true });
|
|
306
|
-
this.auditLogger.record({
|
|
307
|
-
action: 'guard.evidence.stale',
|
|
308
|
-
resource: 'evidence',
|
|
309
|
-
status: 'warning',
|
|
310
|
-
meta: { ageSec, source }
|
|
311
|
-
});
|
|
312
|
-
recordMetric({ hook: 'evidence', status: 'stale', ageSec, source });
|
|
313
277
|
void this.attemptAutoRefresh('stale');
|
|
314
278
|
}
|
|
315
279
|
|
|
316
280
|
async attemptAutoRefresh(reason = 'manual') {
|
|
317
|
-
if (
|
|
281
|
+
if (process.env.HOOK_GUARD_AUTO_REFRESH !== 'true') {
|
|
318
282
|
return;
|
|
319
283
|
}
|
|
320
284
|
|
|
@@ -347,13 +311,6 @@ class RealtimeGuardService {
|
|
|
347
311
|
try {
|
|
348
312
|
await this.runDirectEvidenceRefresh(reason);
|
|
349
313
|
this.lastAutoRefresh = now;
|
|
350
|
-
this.auditLogger.record({
|
|
351
|
-
action: 'guard.evidence.auto_refresh',
|
|
352
|
-
resource: 'evidence',
|
|
353
|
-
status: 'success',
|
|
354
|
-
meta: { reason }
|
|
355
|
-
});
|
|
356
|
-
recordMetric({ hook: 'evidence', status: 'auto_refresh_success', reason });
|
|
357
314
|
} finally {
|
|
358
315
|
this.autoRefreshInFlight = false;
|
|
359
316
|
}
|
|
@@ -3,12 +3,22 @@ const FileContextGrouper = require('./smart-commit/FileContextGrouper');
|
|
|
3
3
|
const CommitMessageSuggester = require('./smart-commit/CommitMessageSuggester');
|
|
4
4
|
const SmartCommitSummaryBuilder = require('./smart-commit/SmartCommitSummaryBuilder');
|
|
5
5
|
|
|
6
|
+
const {
|
|
7
|
+
createMetricScope: createMetricScope
|
|
8
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
9
|
+
|
|
6
10
|
class SmartDirtyTreeAnalyzer {
|
|
7
11
|
constructor({
|
|
8
12
|
platformDetector = null,
|
|
9
13
|
repoRoot = process.cwd(),
|
|
10
14
|
logger = console
|
|
11
15
|
} = {}) {
|
|
16
|
+
const m_constructor = createMetricScope({
|
|
17
|
+
hook: 'smart_dirty_tree_analyzer',
|
|
18
|
+
operation: 'constructor'
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
m_constructor.started();
|
|
12
22
|
this.repoRoot = repoRoot;
|
|
13
23
|
this.logger = logger;
|
|
14
24
|
|
|
@@ -16,6 +26,7 @@ class SmartDirtyTreeAnalyzer {
|
|
|
16
26
|
this.grouper = new FileContextGrouper(this.featureDetector, platformDetector);
|
|
17
27
|
this.suggester = new CommitMessageSuggester(this.featureDetector);
|
|
18
28
|
this.summaryBuilder = new SmartCommitSummaryBuilder();
|
|
29
|
+
m_constructor.success();
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
analyze(files) {
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
const {
|
|
2
|
+
createMetricScope: createMetricScope
|
|
3
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
4
|
+
|
|
1
5
|
class CommitMessageGenerator {
|
|
2
6
|
constructor(logger = console) {
|
|
7
|
+
const m_constructor = createMetricScope({
|
|
8
|
+
hook: 'commit_message_generator',
|
|
9
|
+
operation: 'constructor'
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
m_constructor.started();
|
|
3
13
|
this.logger = logger;
|
|
14
|
+
m_constructor.success();
|
|
4
15
|
}
|
|
5
16
|
|
|
6
17
|
/**
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
const {
|
|
2
|
+
createMetricScope: createMetricScope
|
|
3
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
4
|
+
|
|
1
5
|
class FeatureDetector {
|
|
2
6
|
constructor(logger = console) {
|
|
7
|
+
const m_constructor = createMetricScope({
|
|
8
|
+
hook: 'feature_detector',
|
|
9
|
+
operation: 'constructor'
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
m_constructor.started();
|
|
3
13
|
this.logger = logger;
|
|
14
|
+
m_constructor.success();
|
|
4
15
|
}
|
|
5
16
|
|
|
6
17
|
/**
|
|
@@ -3,6 +3,10 @@ const path = require('path');
|
|
|
3
3
|
const { spawnSync } = require('child_process');
|
|
4
4
|
const { DomainError } = require('../../../domain/errors');
|
|
5
5
|
|
|
6
|
+
const {
|
|
7
|
+
createMetricScope: createMetricScope
|
|
8
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
9
|
+
|
|
6
10
|
const DEFAULT_PLATFORMS = ['1', '2', '3', '4'];
|
|
7
11
|
|
|
8
12
|
function resolveUpdateEvidenceScript(repoRoot) {
|
|
@@ -33,6 +37,12 @@ class EvidenceContextManager {
|
|
|
33
37
|
timers = { setInterval, clearInterval },
|
|
34
38
|
runCommand = EvidenceContextManager.runUpdateScript
|
|
35
39
|
} = {}) {
|
|
40
|
+
const m_constructor = createMetricScope({
|
|
41
|
+
hook: 'evidence_context_manager',
|
|
42
|
+
operation: 'constructor'
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
m_constructor.started();
|
|
36
46
|
this.repoRoot = repoRoot;
|
|
37
47
|
this.updateScript = updateScript;
|
|
38
48
|
this.thresholdSeconds = thresholdSeconds;
|
|
@@ -44,6 +54,7 @@ class EvidenceContextManager {
|
|
|
44
54
|
this.runCommand = runCommand;
|
|
45
55
|
this.timerRef = null;
|
|
46
56
|
this.refreshInProgress = false;
|
|
57
|
+
m_constructor.success();
|
|
47
58
|
}
|
|
48
59
|
|
|
49
60
|
static runUpdateScript(scriptPath, platforms) {
|
|
@@ -61,6 +72,12 @@ class EvidenceContextManager {
|
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
start(reason = 'startup') {
|
|
75
|
+
const m_start = createMetricScope({
|
|
76
|
+
hook: 'evidence_context_manager',
|
|
77
|
+
operation: 'start'
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
m_start.started();
|
|
64
81
|
this.ensureFresh(reason).catch(error => {
|
|
65
82
|
this.log('error', 'EVIDENCE_STARTUP_REFRESH_FAILED', { error: error.message });
|
|
66
83
|
});
|
|
@@ -74,13 +91,21 @@ class EvidenceContextManager {
|
|
|
74
91
|
this.timerRef.unref();
|
|
75
92
|
}
|
|
76
93
|
}
|
|
94
|
+
m_start.success();
|
|
77
95
|
}
|
|
78
96
|
|
|
79
97
|
stop() {
|
|
98
|
+
const m_stop = createMetricScope({
|
|
99
|
+
hook: 'evidence_context_manager',
|
|
100
|
+
operation: 'stop'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
m_stop.started();
|
|
80
104
|
if (this.timerRef) {
|
|
81
105
|
this.timers.clearInterval(this.timerRef);
|
|
82
106
|
this.timerRef = null;
|
|
83
107
|
}
|
|
108
|
+
m_stop.success();
|
|
84
109
|
}
|
|
85
110
|
|
|
86
111
|
async ensureFresh(reason = 'manual') {
|
|
@@ -10,9 +10,10 @@ const GuardConfig = require('./GuardConfig');
|
|
|
10
10
|
const GuardNotificationHandler = require('./GuardNotificationHandler');
|
|
11
11
|
const GuardMonitorLoop = require('./GuardMonitorLoop');
|
|
12
12
|
const GuardHealthReminder = require('./GuardHealthReminder');
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
createMetricScope: createMetricScope
|
|
16
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
16
17
|
|
|
17
18
|
class GuardAutoManagerService {
|
|
18
19
|
constructor({
|
|
@@ -22,11 +23,16 @@ class GuardAutoManagerService {
|
|
|
22
23
|
fsModule = fs,
|
|
23
24
|
childProcess = { spawnSync },
|
|
24
25
|
timers = { setInterval, clearInterval },
|
|
25
|
-
env =
|
|
26
|
+
env = process.env,
|
|
26
27
|
processRef = process,
|
|
27
|
-
heartbeatMonitor = null
|
|
28
|
-
auditLogger = null
|
|
28
|
+
heartbeatMonitor = null
|
|
29
29
|
} = {}) {
|
|
30
|
+
const m_constructor = createMetricScope({
|
|
31
|
+
hook: 'guard_auto_manager_service',
|
|
32
|
+
operation: 'constructor'
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
m_constructor.started();
|
|
30
36
|
this.process = processRef;
|
|
31
37
|
|
|
32
38
|
// Configuration & Infrastructure
|
|
@@ -34,7 +40,6 @@ class GuardAutoManagerService {
|
|
|
34
40
|
this.eventLogger = new GuardEventLogger({ repoRoot, logger, fsModule });
|
|
35
41
|
this.lockManager = new GuardLockManager({ repoRoot, logger, fsModule });
|
|
36
42
|
this.processManager = new GuardProcessManager({ repoRoot, logger, fsModule, childProcess });
|
|
37
|
-
this.auditLogger = auditLogger || new AuditLogger({ repoRoot, logger });
|
|
38
43
|
|
|
39
44
|
// Monitors & Handlers
|
|
40
45
|
this.heartbeatMonitor = heartbeatMonitor || new GuardHeartbeatMonitor({
|
|
@@ -54,6 +59,7 @@ class GuardAutoManagerService {
|
|
|
54
59
|
this.lastHeartbeatState = { healthy: true, reason: 'healthy' };
|
|
55
60
|
this.lastHeartbeatRestart = 0;
|
|
56
61
|
this.shuttingDown = false;
|
|
62
|
+
m_constructor.success();
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
notifyUser(message, level = 'info', metadata = {}) {
|
|
@@ -62,21 +68,25 @@ class GuardAutoManagerService {
|
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
start() {
|
|
71
|
+
const m_start = createMetricScope({
|
|
72
|
+
hook: 'guard_auto_manager_service',
|
|
73
|
+
operation: 'start'
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
m_start.started();
|
|
65
77
|
if (!this.lockManager.acquireLock()) {
|
|
66
78
|
this.eventLogger.log('Another guard auto manager instance detected. Exiting.');
|
|
67
|
-
|
|
68
|
-
recordMetric({ hook: 'guard_auto_manager', status: 'lock_fail' });
|
|
79
|
+
m_start.success();
|
|
69
80
|
return false;
|
|
70
81
|
}
|
|
71
82
|
this.lockManager.writePidFile();
|
|
72
83
|
this.eventLogger.log('Guard auto manager started');
|
|
73
|
-
this.auditLogger.record({ action: 'guard.manager.start', resource: 'guard_auto_manager', status: 'success' });
|
|
74
|
-
recordMetric({ hook: 'guard_auto_manager', status: 'start' });
|
|
75
84
|
|
|
76
85
|
this.ensureSupervisor('initial-start');
|
|
77
86
|
this._startReminder();
|
|
78
87
|
this.monitorLoop.start();
|
|
79
88
|
this.registerProcessHooks();
|
|
89
|
+
m_start.success();
|
|
80
90
|
return true;
|
|
81
91
|
}
|
|
82
92
|
|
|
@@ -103,12 +113,6 @@ class GuardAutoManagerService {
|
|
|
103
113
|
handleMissingSupervisor() {
|
|
104
114
|
this.lastHeartbeatState = { healthy: false, reason: 'missing-supervisor' };
|
|
105
115
|
this.eventLogger.recordEvent('Guard supervisor no se encuentra en ejecución; reinicio automático.');
|
|
106
|
-
this.auditLogger.record({
|
|
107
|
-
action: 'guard.supervisor.missing',
|
|
108
|
-
resource: 'guard_supervisor',
|
|
109
|
-
status: 'fail',
|
|
110
|
-
meta: { reason: 'missing-supervisor' }
|
|
111
|
-
});
|
|
112
116
|
this.ensureSupervisor('missing-supervisor');
|
|
113
117
|
}
|
|
114
118
|
|
|
@@ -121,21 +125,9 @@ class GuardAutoManagerService {
|
|
|
121
125
|
this.eventLogger.log(`Heartbeat degraded (${heartbeat.reason}); attempting supervisor ensure.`);
|
|
122
126
|
this.lastHeartbeatRestart = now;
|
|
123
127
|
this.ensureSupervisor(`heartbeat-${heartbeat.reason}`);
|
|
124
|
-
this.auditLogger.record({
|
|
125
|
-
action: 'guard.supervisor.ensure',
|
|
126
|
-
resource: 'guard_supervisor',
|
|
127
|
-
status: 'success',
|
|
128
|
-
meta: { reason: heartbeat.reason }
|
|
129
|
-
});
|
|
130
128
|
} else {
|
|
131
129
|
this.eventLogger.log(`Heartbeat degraded (${heartbeat.reason}); restart suppressed (cooldown).`);
|
|
132
130
|
this.eventLogger.recordEvent(`Heartbeat degradado (${heartbeat.reason}); reinicio omitido por cooldown.`);
|
|
133
|
-
this.auditLogger.record({
|
|
134
|
-
action: 'guard.supervisor.ensure',
|
|
135
|
-
resource: 'guard_supervisor',
|
|
136
|
-
status: 'fail',
|
|
137
|
-
meta: { reason: heartbeat.reason, suppressed: true }
|
|
138
|
-
});
|
|
139
131
|
}
|
|
140
132
|
} else {
|
|
141
133
|
this.eventLogger.recordEvent(`Heartbeat en estado ${heartbeat.reason}; reinicio no requerido.`);
|
|
@@ -175,8 +167,6 @@ class GuardAutoManagerService {
|
|
|
175
167
|
this.lockManager.removePidFile();
|
|
176
168
|
this.lockManager.releaseLock();
|
|
177
169
|
this.healthReminder.stop();
|
|
178
|
-
this.auditLogger.record({ action: 'guard.manager.stop', resource: 'guard_auto_manager', status: 'success' });
|
|
179
|
-
recordMetric({ hook: 'guard_auto_manager', status: 'stop' });
|
|
180
170
|
}
|
|
181
171
|
|
|
182
172
|
ensureSupervisor(reason) {
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
const
|
|
1
|
+
const {
|
|
2
|
+
createMetricScope: createMetricScope
|
|
3
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
2
4
|
|
|
3
5
|
class GuardConfig {
|
|
4
|
-
constructor(env =
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
constructor(env = process.env) {
|
|
7
|
+
const m_constructor = createMetricScope({
|
|
8
|
+
hook: 'guard_config',
|
|
9
|
+
operation: 'constructor'
|
|
10
|
+
});
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
13
|
-
|
|
14
|
-
this.healthyReminderIntervalMs > 0 ? this.healthyReminderIntervalMs : 0
|
|
12
|
+
m_constructor.started();
|
|
13
|
+
this.healthyReminderIntervalMs = Number(env.GUARD_AUTOSTART_HEALTHY_INTERVAL || 0);
|
|
14
|
+
this.heartbeatNotifyCooldownMs = Number(env.GUARD_AUTOSTART_NOTIFY_COOLDOWN || 60000);
|
|
15
|
+
this.healthyReminderCooldownMs = Number(
|
|
16
|
+
env.GUARD_AUTOSTART_HEALTHY_COOLDOWN || (this.healthyReminderIntervalMs > 0 ? this.healthyReminderIntervalMs : 0)
|
|
15
17
|
);
|
|
16
|
-
this.heartbeatRestartCooldownMs =
|
|
17
|
-
this.monitorIntervalMs =
|
|
18
|
-
this.restartCooldownMs =
|
|
19
|
-
this.stopSupervisorOnExit =
|
|
18
|
+
this.heartbeatRestartCooldownMs = Number(env.GUARD_AUTOSTART_HEARTBEAT_COOLDOWN || 60000);
|
|
19
|
+
this.monitorIntervalMs = Number(env.GUARD_AUTOSTART_MONITOR_INTERVAL || 5000);
|
|
20
|
+
this.restartCooldownMs = Number(env.GUARD_AUTOSTART_RESTART_COOLDOWN || 2000);
|
|
21
|
+
this.stopSupervisorOnExit = env.GUARD_AUTOSTART_STOP_SUPERVISOR_ON_EXIT !== 'false';
|
|
22
|
+
m_constructor.success();
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
+
const {
|
|
5
|
+
createMetricScope: createMetricScope
|
|
6
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
7
|
+
|
|
4
8
|
class GuardEventLogger {
|
|
5
9
|
constructor({
|
|
6
10
|
repoRoot = process.cwd(),
|
|
7
11
|
logger = console,
|
|
8
12
|
fsModule = fs
|
|
9
13
|
} = {}) {
|
|
14
|
+
const m_constructor = createMetricScope({
|
|
15
|
+
hook: 'guard_event_logger',
|
|
16
|
+
operation: 'constructor'
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
m_constructor.started();
|
|
10
20
|
this.repoRoot = repoRoot;
|
|
11
21
|
this.logger = logger;
|
|
12
22
|
this.fs = fsModule;
|
|
@@ -26,6 +36,7 @@ class GuardEventLogger {
|
|
|
26
36
|
this.logger.debug('GUARD_EVENT_LOGGER_INIT_ERROR', { error: error.message });
|
|
27
37
|
}
|
|
28
38
|
}
|
|
39
|
+
m_constructor.success();
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
log(message, data = {}) {
|