pumuki-ast-hooks 5.3.19 → 5.3.21

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.
Files changed (46) hide show
  1. package/docs/RELEASE_NOTES.md +35 -0
  2. package/docs/VIOLATIONS_RESOLUTION_PLAN.md +64 -60
  3. package/package.json +9 -3
  4. package/scripts/hooks-system/.AI_TOKEN_STATUS.txt +1 -1
  5. package/scripts/hooks-system/.audit-reports/notifications.log +935 -0
  6. package/scripts/hooks-system/.audit-reports/token-monitor.log +2809 -0
  7. package/scripts/hooks-system/application/CompositionRoot.js +38 -22
  8. package/scripts/hooks-system/application/services/DynamicRulesLoader.js +2 -1
  9. package/scripts/hooks-system/application/services/GitTreeState.js +2 -1
  10. package/scripts/hooks-system/application/services/PlaybookRunner.js +1 -1
  11. package/scripts/hooks-system/application/services/RealtimeGuardService.js +71 -14
  12. package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +31 -2
  13. package/scripts/hooks-system/application/services/guard/GuardConfig.js +17 -9
  14. package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +6 -9
  15. package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +23 -0
  16. package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +1 -1
  17. package/scripts/hooks-system/application/services/installation/HookInstaller.js +62 -5
  18. package/scripts/hooks-system/application/services/installation/McpConfigurator.js +2 -1
  19. package/scripts/hooks-system/application/services/logging/AuditLogger.js +0 -4
  20. package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +13 -4
  21. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +4 -3
  22. package/scripts/hooks-system/application/services/token/TokenMetricsService.js +2 -1
  23. package/scripts/hooks-system/bin/cli.js +15 -1
  24. package/scripts/hooks-system/bin/guard-env.sh +18 -38
  25. package/scripts/hooks-system/bin/guard-supervisor.js +5 -515
  26. package/scripts/hooks-system/bin/session-loader.sh +3 -262
  27. package/scripts/hooks-system/bin/start-guards.sh +21 -184
  28. package/scripts/hooks-system/bin/update-evidence.sh +10 -1161
  29. package/scripts/hooks-system/config/project.config.json +1 -1
  30. package/scripts/hooks-system/domain/events/index.js +32 -6
  31. package/scripts/hooks-system/domain/exceptions/index.js +87 -0
  32. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +3 -2
  33. package/scripts/hooks-system/infrastructure/ast/ast-core.js +12 -20
  34. package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +8 -18
  35. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -1
  36. package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +10 -8
  37. package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
  38. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +3 -2
  39. package/scripts/hooks-system/infrastructure/config/config.js +5 -0
  40. package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +3 -2
  41. package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -4
  42. package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +88 -0
  43. package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +17 -16
  44. package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
  45. package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +3 -2
  46. package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +6 -8
@@ -1,516 +1,6 @@
1
1
  #!/usr/bin/env node
2
- const fs = require('fs');
3
- const path = require('path');
4
- const { spawn } = require('child_process');
5
- const { getGitTreeState } = require('../application/services/GitTreeState');
6
- const GitTreeMonitorService = require('../application/services/monitoring/GitTreeMonitorService');
7
- const HeartbeatMonitorService = require('../application/services/monitoring/HeartbeatMonitorService');
8
- const { HealthCheckService } = require('../application/services/monitoring/HealthCheckService');
9
- const { createHealthCheckProviders } = require('../application/services/monitoring/HealthCheckProviders');
10
- const NotificationCenterService = require('../application/services/notification/NotificationCenterService');
11
- const { AutoRecoveryManager } = require('../application/services/recovery/AutoRecoveryManager');
12
- const { EvidenceContextManager } = require('../application/services/evidence/EvidenceContextManager');
13
- const { createUnifiedLogger } = require('../infrastructure/logging/UnifiedLoggerFactory');
14
- const PlatformDetectionService = require('../application/services/PlatformDetectionService');
15
-
16
- const repoRoot = process.cwd();
17
- const tmpDir = path.join(repoRoot, '.audit_tmp');
18
- const reportsDir = path.join(repoRoot, '.audit-reports');
19
- const lockDir = path.join(tmpDir, 'guard-supervisor.lock');
20
- const logPath = path.join(reportsDir, 'guard-supervisor.log');
21
- const restartDebounceMs = Number(process.env.HOOK_GUARD_AUTORELOAD_DEBOUNCE || 1500);
22
- const restartForceMs = Number(process.env.HOOK_GUARD_AUTORELOAD_FORCE || 3000);
23
- const dirtyTreeLimit = Number(process.env.HOOK_GUARD_DIRTY_TREE_LIMIT || 24);
24
- const dirtyTreeWarning = Number(process.env.HOOK_GUARD_DIRTY_TREE_WARNING || Math.max(1, Math.floor(dirtyTreeLimit / 2)));
25
- const dirtyTreeIntervalMs = Number(process.env.HOOK_GUARD_DIRTY_TREE_INTERVAL || 60000);
26
- const dirtyTreeReminderMs = Number(process.env.HOOK_GUARD_DIRTY_TREE_REMINDER || 300000);
27
- const heartbeatRelativePath = process.env.HOOK_GUARD_HEARTBEAT_PATH || '.audit_tmp/guard-heartbeat.json';
28
- const heartbeatPath = path.isAbsolute(heartbeatRelativePath) ? heartbeatRelativePath : path.join(repoRoot, heartbeatRelativePath);
29
- const heartbeatIntervalMs = Number(process.env.HOOK_GUARD_HEARTBEAT_INTERVAL || 15000);
30
- const heartbeatMaxAgeMs = Number(process.env.HOOK_GUARD_HEARTBEAT_MAX_AGE || 60000);
31
- const heartbeatCheckIntervalMs = Number(process.env.HOOK_GUARD_HEARTBEAT_CHECK_INTERVAL || 5000);
32
- const debugLogPath = path.join(reportsDir, 'guard-debug.log');
33
- const healthIntervalMs = Number(process.env.HOOK_GUARD_HEALTH_INTERVAL || 60000);
34
- const evidenceIntervalMs = Number(process.env.HOOK_GUARD_EVIDENCE_INTERVAL || 120000);
35
- const evidencePlatforms = process.env.HOOK_GUARD_EVIDENCE_PLATFORMS
36
- ? process.env.HOOK_GUARD_EVIDENCE_PLATFORMS.split(',').map(item => item.trim()).filter(Boolean)
37
- : undefined;
38
-
39
- fs.mkdirSync(tmpDir, { recursive: true });
40
- fs.mkdirSync(reportsDir, { recursive: true });
41
- const unifiedLogger = createUnifiedLogger({
42
- repoRoot,
43
- component: 'GuardSupervisor',
44
- fileName: 'guard-supervisor.log'
45
- });
46
-
47
- const notificationCenter = new NotificationCenterService({
48
- repoRoot,
49
- logger: unifiedLogger,
50
- cooldownsByType: {
51
- health_check_error: 300000,
52
- health_check_warn: 120000,
53
- auto_recovery_error: 300000,
54
- auto_recovery_warn: 180000
55
- }
56
- });
57
-
58
- const autoRecoveryManager = new AutoRecoveryManager({
59
- repoRoot,
60
- logger: unifiedLogger,
61
- notificationCenter,
62
- strategies: [
63
- AutoRecoveryManager.createSupervisorRestartStrategy(),
64
- {
65
- id: 'guard-child-exit',
66
- condition: ({ reason }) => typeof reason === 'string' && reason.startsWith('child-exit:guard'),
67
- action: async ({ logger: recoveryLogger }) => {
68
- recoveryLogger.info('Attempting guard restart via auto recovery');
69
- return AutoRecoveryManager.runScript('start-guards.sh', ['restart']);
70
- }
71
- },
72
- {
73
- id: 'token-child-exit',
74
- condition: ({ reason }) => typeof reason === 'string' && reason.startsWith('child-exit:tokenMonitor'),
75
- action: async ({ logger: recoveryLogger }) => {
76
- recoveryLogger.info('Attempting token monitor restart via auto recovery');
77
- return AutoRecoveryManager.runScript('start-guards.sh', ['restart']);
78
- }
79
- }
80
- ]
81
- });
82
-
83
- const originalEnqueue = notificationCenter.enqueue.bind(notificationCenter);
84
- notificationCenter.enqueue = payload => {
85
- const result = originalEnqueue(payload);
86
- if (payload && payload.type === 'health_check_error') {
87
- autoRecoveryManager.recover({
88
- key: 'health',
89
- reason: `health-error:${payload.metadata?.reason || 'unknown'}`,
90
- context: payload.metadata || {}
91
- }).catch(error => {
92
- unifiedLogger.error('GUARD_HEALTH_RECOVERY_ERROR', { message: error.message });
93
- });
94
- }
95
- if (payload && payload.type === 'health_check_info') {
96
- autoRecoveryManager.clear('health');
97
- }
98
- return result;
99
- };
100
-
101
- if (!acquireLock()) {
102
- log('Another guard supervisor instance is already running. Exiting.');
103
- process.exit(0);
104
- }
105
-
106
- const childDefs = {
107
- guard: {
108
- command: 'node',
109
- args: [path.join(repoRoot, 'bin', 'watch-hooks.js')],
110
- cwd: repoRoot,
111
- stdio: 'inherit',
112
- env: { ...process.env, HOOK_GUARD_DIRTY_TREE_DISABLED: 'true' }
113
- },
114
- tokenMonitor: {
115
- command: 'bash',
116
- args: [path.join(repoRoot, 'infrastructure', 'watchdog', 'token-monitor-loop.sh')],
117
- cwd: repoRoot,
118
- stdio: 'inherit',
119
- env: process.env
120
- }
121
- };
122
-
123
- const targets = [
124
- 'bin/watch-hooks.js',
125
- 'bin/guard-supervisor.js',
126
- 'bin/start-guards.sh',
127
- 'application/services/RealtimeGuardService.js',
128
- 'infrastructure/watchdog/token-monitor-loop.sh',
129
- 'infrastructure/watchdog/token-monitor.js',
130
- 'infrastructure/watchdog/token-tracker.sh'
131
- ];
132
-
133
- const watchers = [];
134
- const children = new Map();
135
- let restartTimer = null;
136
- let restartPromise = Promise.resolve();
137
- let shuttingDown = false;
138
-
139
- const platformDetector = new PlatformDetectionService();
140
-
141
- function appendDebugLogSync(message) {
142
- const timestamp = new Date().toISOString();
143
- fs.appendFileSync(debugLogPath, `${timestamp}|${message}\n`);
144
- }
145
-
146
- const gitTreeMonitor = new GitTreeMonitorService({
147
- repoRoot,
148
- limit: dirtyTreeLimit,
149
- warning: dirtyTreeWarning,
150
- reminderMs: dirtyTreeReminderMs,
151
- intervalMs: dirtyTreeIntervalMs,
152
- getState: getGitTreeState,
153
- notifier: (message, level) => log(message, { level }),
154
- logger: unifiedLogger,
155
- debugLogger: appendDebugLogSync
156
- });
157
-
158
- const heartbeatMonitor = new HeartbeatMonitorService({
159
- heartbeatPath,
160
- intervalMs: heartbeatIntervalMs,
161
- statusProvider: buildHeartbeatPayload,
162
- logger: unifiedLogger
163
- });
164
-
165
- const healthCheckProviders = createHealthCheckProviders({
166
- repoRoot,
167
- getGitTreeState,
168
- heartbeatPath,
169
- tokenUsagePath: path.join(tmpDir, 'token-usage.jsonl'),
170
- evidencePath: path.join(repoRoot, '.AI_EVIDENCE.json'),
171
- processes: [
172
- {
173
- name: 'watchHooks',
174
- pidResolver: () => {
175
- const description = describeChild('guard');
176
- return description.running ? description.pid : null;
177
- }
178
- },
179
- {
180
- name: 'tokenMonitor',
181
- pidResolver: () => {
182
- const description = describeChild('tokenMonitor');
183
- return description.running ? description.pid : null;
184
- }
185
- }
186
- ]
187
- });
188
-
189
- const healthCheckService = new HealthCheckService({
190
- repoRoot,
191
- providers: healthCheckProviders,
192
- notificationCenter,
193
- logger: unifiedLogger,
194
- outputFile: path.join(tmpDir, 'health-status.json'),
195
- intervalMs: healthIntervalMs
196
- });
197
-
198
- const evidenceContextManager = new EvidenceContextManager({
199
- repoRoot,
200
- updateScript: path.join(repoRoot, 'bin', 'update-evidence.sh'),
201
- notificationCenter,
202
- logger: unifiedLogger,
203
- intervalMs: evidenceIntervalMs,
204
- autoPlatforms: evidencePlatforms
205
- });
206
-
207
- function acquireLock() {
208
- try {
209
- fs.mkdirSync(lockDir, { recursive: false });
210
- return true;
211
- } catch (error) {
212
- return false;
213
- }
214
- }
215
-
216
- function releaseLock() {
217
- try {
218
- fs.rmdirSync(lockDir);
219
- } catch (error) {
220
- log(`Error releasing lock: ${error.message}`);
221
- }
222
- }
223
-
224
- function log(message, data = {}) {
225
- const timestamp = formatLocalTimestamp();
226
- fs.appendFileSync(logPath, `[${timestamp}] ${message}\n`);
227
- unifiedLogger.info('GUARD_SUPERVISOR_EVENT', { message, ...data });
228
- }
229
-
230
- async function startChild(name) {
231
- const def = childDefs[name];
232
- if (!def) {
233
- log(`Unknown child ${name}`);
234
- return;
235
- }
236
- await stopChild(name);
237
- const child = spawn(def.command, def.args, {
238
- cwd: def.cwd,
239
- stdio: def.stdio,
240
- env: def.env || process.env
241
- });
242
- children.set(name, { child });
243
- autoRecoveryManager.clear(name);
244
- log(`${name} started (pid ${child.pid})`);
245
- child.on('exit', (code, signal) => {
246
- log(`${name} exited (code ${code ?? 'null'} signal ${signal ?? 'null'})`);
247
- children.delete(name);
248
- autoRecoveryManager.recover({
249
- key: name,
250
- reason: `child-exit:${name}`,
251
- context: { code, signal }
252
- }).catch(error => {
253
- unifiedLogger.error('GUARD_CHILD_RECOVERY_ERROR', { name, message: error.message });
254
- });
255
- if (!shuttingDown) {
256
- scheduleRestart(`${name}-exit:${code ?? 'null'}:${signal ?? 'null'}`);
257
- }
258
- });
259
- }
260
-
261
- function stopChild(name) {
262
- const entry = children.get(name);
263
- if (!entry) {
264
- return Promise.resolve();
265
- }
266
- const { child } = entry;
267
- return new Promise(resolve => {
268
- const timeout = setTimeout(() => {
269
- try {
270
- child.kill('SIGKILL');
271
- } catch (error) {
272
- log(`Failed to SIGKILL ${name}: ${error.message}`);
273
- }
274
- }, restartForceMs);
275
- child.once('exit', () => {
276
- clearTimeout(timeout);
277
- resolve();
278
- });
279
- try {
280
- child.kill('SIGTERM');
281
- } catch (error) {
282
- log(`Failed to SIGTERM ${name}: ${error.message}`);
283
- resolve();
284
- }
285
- });
286
- }
287
-
288
- function startAll() {
289
- return Promise.all(Object.keys(childDefs).map(name => startChild(name)));
290
- }
291
-
292
- function stopAll() {
293
- const names = Array.from(children.keys());
294
- if (!names.length) {
295
- return Promise.resolve();
296
- }
297
- return Promise.all(names.map(name => stopChild(name)));
298
- }
299
-
300
- function scheduleRestart(reason) {
301
- if (restartTimer) {
302
- return;
303
- }
304
- log(`Scheduling restart due to ${reason}`);
305
- restartTimer = setTimeout(() => {
306
- restartTimer = null;
307
- restartAll(reason);
308
- }, restartDebounceMs);
309
- }
310
-
311
- function restartAll(reason) {
312
- restartPromise = restartPromise.then(async () => {
313
- if (shuttingDown) {
314
- return;
315
- }
316
- log(`Restarting guards (${reason})`);
317
- await stopAll();
318
- await startAll();
319
- heartbeatMonitor.emitHeartbeat();
320
- evidenceContextManager.ensureFresh('restart').catch(error => {
321
- unifiedLogger.error('GUARD_EVIDENCE_REFRESH_FAILED', { message: error.message });
322
- });
323
- healthCheckService.collect('restart').catch(error => {
324
- unifiedLogger.error('GUARD_HEALTHCHECK_RESTART_FAILED', { message: error.message });
325
- });
326
- });
327
- }
328
-
329
- function watchTargets() {
330
- const directories = new Map();
331
- targets.forEach(relPath => {
332
- const absolute = path.join(repoRoot, relPath);
333
- if (!fs.existsSync(absolute)) {
334
- log(`Warning: ${relPath} missing; auto-restart will ignore it.`);
335
- return;
336
- }
337
- const dir = path.dirname(absolute);
338
- const list = directories.get(dir) || [];
339
- list.push(path.basename(absolute));
340
- directories.set(dir, list);
341
- });
342
-
343
- directories.forEach((files, dir) => {
344
- try {
345
- const watcher = fs.watch(dir, (event, filename) => {
346
- if (!filename) {
347
- return;
348
- }
349
- const normalized = filename.toString();
350
- if (files.includes(normalized)) {
351
- scheduleRestart(`${path.relative(repoRoot, path.join(dir, normalized))}:${event}`);
352
- }
353
- });
354
- watchers.push(watcher);
355
- } catch (error) {
356
- log(`Error watching ${dir}: ${error.message}`);
357
- }
358
- });
359
- }
360
-
361
- function buildHeartbeatPayload() {
362
- const guardStatus = describeChild('guard');
363
- const tokenStatus = describeChild('tokenMonitor');
364
- const status = guardStatus.running && tokenStatus.running ? 'healthy' : 'degraded';
365
- const payload = {
366
- timestamp: new Date().toISOString(),
367
- supervisorPid: process.pid,
368
- status,
369
- guard: guardStatus,
370
- tokenMonitor: tokenStatus
371
- };
372
- return payload;
373
- }
374
-
375
- function describeChild(name) {
376
- const entry = children.get(name);
377
- if (!entry || !entry.child) {
378
- return { running: false, pid: null };
379
- }
380
- const { child } = entry;
381
- if (!child || child.killed) {
382
- return { running: false, pid: null };
383
- }
384
- return { running: true, pid: child.pid };
385
- }
386
-
387
- function formatLocalTimestamp(date = new Date()) {
388
- const year = date.getFullYear();
389
- const month = String(date.getMonth() + 1).padStart(2, '0');
390
- const day = String(date.getDate()).padStart(2, '0');
391
- const hours = String(date.getHours()).padStart(2, '0');
392
- const minutes = String(date.getMinutes()).padStart(2, '0');
393
- const seconds = String(date.getSeconds()).padStart(2, '0');
394
- const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
395
- const offsetMinutes = date.getTimezoneOffset();
396
- const sign = offsetMinutes <= 0 ? '+' : '-';
397
- const absolute = Math.abs(offsetMinutes);
398
- const offsetHours = String(Math.floor(absolute / 60)).padStart(2, '0');
399
- const offsetMins = String(absolute % 60).padStart(2, '0');
400
- return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}${sign}${offsetHours}:${offsetMins}`;
401
- }
402
-
403
- function shutdown() {
404
- if (shuttingDown) {
405
- return;
406
- }
407
- shuttingDown = true;
408
- log('Shutting down guard supervisor');
409
- watchers.forEach(w => {
410
- try {
411
- w.close();
412
- } catch (error) {
413
- log(`Error closing watcher: ${error.message}`);
414
- }
415
- });
416
- gitTreeMonitor.stop();
417
- heartbeatMonitor.stop();
418
- stopHeartbeatStalenessMonitor();
419
- healthCheckService.stop();
420
- evidenceContextManager.stop();
421
- autoRecoveryManager.clear('guard');
422
- autoRecoveryManager.clear('tokenMonitor');
423
- autoRecoveryManager.clear('health');
424
- notificationCenter.shutdown();
425
- stopAll().finally(() => {
426
- releaseLock();
427
- process.exit(0);
428
- });
429
- }
430
-
431
- process.on('SIGINT', shutdown);
432
- process.on('SIGTERM', shutdown);
433
- process.on('exit', releaseLock);
434
- process.on('uncaughtException', error => {
435
- log(`Uncaught exception: ${error.stack || error.message}`);
436
- shutdown();
437
- });
438
- process.on('unhandledRejection', reason => {
439
- log(`Unhandled rejection: ${reason instanceof Error ? reason.stack || reason.message : reason}`);
440
- shutdown();
441
- });
442
-
443
- log('Guard supervisor started');
444
-
445
- let lastHeartbeatStale = false;
446
- let heartbeatStalenessTimer = null;
447
-
448
- function appendDebugLog(message) {
449
- const timestamp = new Date().toISOString();
450
- fs.appendFileSync(debugLogPath, `${timestamp}|${message}\n`);
451
- }
452
-
453
- function checkHeartbeatStaleness() {
454
- if (shuttingDown) {
455
- return;
456
- }
457
- try {
458
- if (!fs.existsSync(heartbeatPath)) {
459
- return;
460
- }
461
- const raw = fs.readFileSync(heartbeatPath, 'utf8');
462
- if (!raw) {
463
- return;
464
- }
465
- const data = JSON.parse(raw);
466
- const timestamp = Date.parse(data.timestamp);
467
- if (!Number.isFinite(timestamp)) {
468
- return;
469
- }
470
- const age = Date.now() - timestamp;
471
- if (age > heartbeatMaxAgeMs) {
472
- if (!lastHeartbeatStale) {
473
- lastHeartbeatStale = true;
474
- appendDebugLog(`HEARTBEAT_ALERT|stale|ageMs=${age}`);
475
- }
476
- } else {
477
- if (lastHeartbeatStale) {
478
- lastHeartbeatStale = false;
479
- appendDebugLog('HEARTBEAT_RECOVERED');
480
- }
481
- }
482
- } catch (error) {
483
- appendDebugLog(`HEARTBEAT_CHECK_ERROR|${error.message}`);
484
- }
485
- }
486
-
487
- function startHeartbeatStalenessMonitor() {
488
- if (heartbeatStalenessTimer) {
489
- clearInterval(heartbeatStalenessTimer);
490
- }
491
- if (heartbeatCheckIntervalMs > 0 && heartbeatMaxAgeMs > 0) {
492
- heartbeatStalenessTimer = setInterval(checkHeartbeatStaleness, heartbeatCheckIntervalMs);
493
- if (heartbeatStalenessTimer && typeof heartbeatStalenessTimer.unref === 'function') {
494
- heartbeatStalenessTimer.unref();
495
- }
496
- }
497
- }
498
-
499
- function stopHeartbeatStalenessMonitor() {
500
- if (heartbeatStalenessTimer) {
501
- clearInterval(heartbeatStalenessTimer);
502
- heartbeatStalenessTimer = null;
503
- }
504
- }
505
-
506
- startAll().then(() => {
507
- watchTargets();
508
- gitTreeMonitor.start();
509
- heartbeatMonitor.start();
510
- startHeartbeatStalenessMonitor();
511
- healthCheckService.start('startup');
512
- evidenceContextManager.start('startup');
513
- }).catch(error => {
514
- log(`Failed to start guards: ${error.message}`);
515
- shutdown();
516
- });
2
+ /**
3
+ * Script Wrapper
4
+ * Redirects to the centralized implementation in scripts/hooks-system
5
+ */
6
+ require('../scripts/hooks-system/bin/guard-supervisor.js');