@tracehound/core 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +125 -0
  2. package/dist/core/agent.d.ts +89 -0
  3. package/dist/core/agent.d.ts.map +1 -0
  4. package/dist/core/agent.js +141 -0
  5. package/dist/core/agent.js.map +1 -0
  6. package/dist/core/audit-chain.d.ts +39 -0
  7. package/dist/core/audit-chain.d.ts.map +1 -0
  8. package/dist/core/audit-chain.js +87 -0
  9. package/dist/core/audit-chain.js.map +1 -0
  10. package/dist/core/cold-storage.d.ts +87 -0
  11. package/dist/core/cold-storage.d.ts.map +1 -0
  12. package/dist/core/cold-storage.js +53 -0
  13. package/dist/core/cold-storage.js.map +1 -0
  14. package/dist/core/evidence-factory.d.ts +85 -0
  15. package/dist/core/evidence-factory.d.ts.map +1 -0
  16. package/dist/core/evidence-factory.js +96 -0
  17. package/dist/core/evidence-factory.js.map +1 -0
  18. package/dist/core/evidence.d.ts +48 -0
  19. package/dist/core/evidence.d.ts.map +1 -0
  20. package/dist/core/evidence.js +135 -0
  21. package/dist/core/evidence.js.map +1 -0
  22. package/dist/core/fail-safe.d.ts +149 -0
  23. package/dist/core/fail-safe.d.ts.map +1 -0
  24. package/dist/core/fail-safe.js +217 -0
  25. package/dist/core/fail-safe.js.map +1 -0
  26. package/dist/core/hound-ipc.d.ts +91 -0
  27. package/dist/core/hound-ipc.d.ts.map +1 -0
  28. package/dist/core/hound-ipc.js +196 -0
  29. package/dist/core/hound-ipc.js.map +1 -0
  30. package/dist/core/hound-pool.d.ts +157 -0
  31. package/dist/core/hound-pool.d.ts.map +1 -0
  32. package/dist/core/hound-pool.js +337 -0
  33. package/dist/core/hound-pool.js.map +1 -0
  34. package/dist/core/hound-process.d.ts +14 -0
  35. package/dist/core/hound-process.d.ts.map +1 -0
  36. package/dist/core/hound-process.js +112 -0
  37. package/dist/core/hound-process.js.map +1 -0
  38. package/dist/core/hound-worker.d.ts +14 -0
  39. package/dist/core/hound-worker.d.ts.map +1 -0
  40. package/dist/core/hound-worker.js +112 -0
  41. package/dist/core/hound-worker.js.map +1 -0
  42. package/dist/core/lane-queue.d.ts +121 -0
  43. package/dist/core/lane-queue.d.ts.map +1 -0
  44. package/dist/core/lane-queue.js +181 -0
  45. package/dist/core/lane-queue.js.map +1 -0
  46. package/dist/core/license-manager.d.ts +128 -0
  47. package/dist/core/license-manager.d.ts.map +1 -0
  48. package/dist/core/license-manager.js +219 -0
  49. package/dist/core/license-manager.js.map +1 -0
  50. package/dist/core/notification-emitter.d.ts +140 -0
  51. package/dist/core/notification-emitter.d.ts.map +1 -0
  52. package/dist/core/notification-emitter.js +197 -0
  53. package/dist/core/notification-emitter.js.map +1 -0
  54. package/dist/core/process-adapter.d.ts +146 -0
  55. package/dist/core/process-adapter.d.ts.map +1 -0
  56. package/dist/core/process-adapter.js +174 -0
  57. package/dist/core/process-adapter.js.map +1 -0
  58. package/dist/core/quarantine.d.ts +95 -0
  59. package/dist/core/quarantine.d.ts.map +1 -0
  60. package/dist/core/quarantine.js +221 -0
  61. package/dist/core/quarantine.js.map +1 -0
  62. package/dist/core/rate-limiter.d.ts +94 -0
  63. package/dist/core/rate-limiter.d.ts.map +1 -0
  64. package/dist/core/rate-limiter.js +156 -0
  65. package/dist/core/rate-limiter.js.map +1 -0
  66. package/dist/core/s3-cold-storage.d.ts +116 -0
  67. package/dist/core/s3-cold-storage.d.ts.map +1 -0
  68. package/dist/core/s3-cold-storage.js +198 -0
  69. package/dist/core/s3-cold-storage.js.map +1 -0
  70. package/dist/core/scheduler.d.ts +126 -0
  71. package/dist/core/scheduler.d.ts.map +1 -0
  72. package/dist/core/scheduler.js +138 -0
  73. package/dist/core/scheduler.js.map +1 -0
  74. package/dist/core/security-state.d.ts +170 -0
  75. package/dist/core/security-state.d.ts.map +1 -0
  76. package/dist/core/security-state.js +156 -0
  77. package/dist/core/security-state.js.map +1 -0
  78. package/dist/core/tier-capacity.d.ts +58 -0
  79. package/dist/core/tier-capacity.d.ts.map +1 -0
  80. package/dist/core/tier-capacity.js +89 -0
  81. package/dist/core/tier-capacity.js.map +1 -0
  82. package/dist/core/tracehound.d.ts +85 -0
  83. package/dist/core/tracehound.d.ts.map +1 -0
  84. package/dist/core/tracehound.js +90 -0
  85. package/dist/core/tracehound.js.map +1 -0
  86. package/dist/core/trust-boundary.d.ts +85 -0
  87. package/dist/core/trust-boundary.d.ts.map +1 -0
  88. package/dist/core/trust-boundary.js +71 -0
  89. package/dist/core/trust-boundary.js.map +1 -0
  90. package/dist/core/watcher.d.ts +153 -0
  91. package/dist/core/watcher.d.ts.map +1 -0
  92. package/dist/core/watcher.js +141 -0
  93. package/dist/core/watcher.js.map +1 -0
  94. package/dist/index.d.ts +53 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +112 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/types/audit.d.ts +45 -0
  99. package/dist/types/audit.d.ts.map +1 -0
  100. package/dist/types/audit.js +5 -0
  101. package/dist/types/audit.js.map +1 -0
  102. package/dist/types/common.d.ts +12 -0
  103. package/dist/types/common.d.ts.map +1 -0
  104. package/dist/types/common.js +5 -0
  105. package/dist/types/common.js.map +1 -0
  106. package/dist/types/config.d.ts +98 -0
  107. package/dist/types/config.d.ts.map +1 -0
  108. package/dist/types/config.js +58 -0
  109. package/dist/types/config.js.map +1 -0
  110. package/dist/types/errors.d.ts +118 -0
  111. package/dist/types/errors.d.ts.map +1 -0
  112. package/dist/types/errors.js +266 -0
  113. package/dist/types/errors.js.map +1 -0
  114. package/dist/types/evidence.d.ts +102 -0
  115. package/dist/types/evidence.d.ts.map +1 -0
  116. package/dist/types/evidence.js +5 -0
  117. package/dist/types/evidence.js.map +1 -0
  118. package/dist/types/index.d.ts +18 -0
  119. package/dist/types/index.d.ts.map +1 -0
  120. package/dist/types/index.js +9 -0
  121. package/dist/types/index.js.map +1 -0
  122. package/dist/types/result.d.ts +62 -0
  123. package/dist/types/result.d.ts.map +1 -0
  124. package/dist/types/result.js +34 -0
  125. package/dist/types/result.js.map +1 -0
  126. package/dist/types/scent.d.ts +55 -0
  127. package/dist/types/scent.d.ts.map +1 -0
  128. package/dist/types/scent.js +5 -0
  129. package/dist/types/scent.js.map +1 -0
  130. package/dist/types/signature.d.ts +47 -0
  131. package/dist/types/signature.d.ts.map +1 -0
  132. package/dist/types/signature.js +68 -0
  133. package/dist/types/signature.js.map +1 -0
  134. package/dist/types/threat.d.ts +38 -0
  135. package/dist/types/threat.d.ts.map +1 -0
  136. package/dist/types/threat.js +18 -0
  137. package/dist/types/threat.js.map +1 -0
  138. package/dist/utils/binary-codec.d.ts +225 -0
  139. package/dist/utils/binary-codec.d.ts.map +1 -0
  140. package/dist/utils/binary-codec.js +266 -0
  141. package/dist/utils/binary-codec.js.map +1 -0
  142. package/dist/utils/compare.d.ts +26 -0
  143. package/dist/utils/compare.d.ts.map +1 -0
  144. package/dist/utils/compare.js +44 -0
  145. package/dist/utils/compare.js.map +1 -0
  146. package/dist/utils/encode.d.ts +39 -0
  147. package/dist/utils/encode.d.ts.map +1 -0
  148. package/dist/utils/encode.js +124 -0
  149. package/dist/utils/encode.js.map +1 -0
  150. package/dist/utils/hash.d.ts +19 -0
  151. package/dist/utils/hash.d.ts.map +1 -0
  152. package/dist/utils/hash.js +25 -0
  153. package/dist/utils/hash.js.map +1 -0
  154. package/dist/utils/id.d.ts +20 -0
  155. package/dist/utils/id.d.ts.map +1 -0
  156. package/dist/utils/id.js +47 -0
  157. package/dist/utils/id.js.map +1 -0
  158. package/dist/utils/runtime.d.ts +24 -0
  159. package/dist/utils/runtime.d.ts.map +1 -0
  160. package/dist/utils/runtime.js +68 -0
  161. package/dist/utils/runtime.js.map +1 -0
  162. package/dist/utils/serialize.d.ts +14 -0
  163. package/dist/utils/serialize.d.ts.map +1 -0
  164. package/dist/utils/serialize.js +27 -0
  165. package/dist/utils/serialize.js.map +1 -0
  166. package/package.json +54 -0
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Fail-Safe Panic - Threshold-triggered emergency callbacks.
3
+ *
4
+ * Provides hooks for emergency situations:
5
+ * - Memory threshold exceeded
6
+ * - Quarantine capacity critical
7
+ * - Error rate exceeded
8
+ * - Manual panic trigger
9
+ *
10
+ * DESIGN:
11
+ * - Panic levels: warning, critical, emergency
12
+ * - Each level can have multiple callbacks
13
+ * - Emergency triggers immediate flush and cleanup
14
+ * - All callbacks are non-blocking (fire-and-forget)
15
+ */
16
+ /**
17
+ * Default thresholds.
18
+ */
19
+ export const DEFAULT_FAIL_SAFE_CONFIG = {
20
+ memory: {
21
+ warning: 0.7, // 70%
22
+ critical: 0.85, // 85%
23
+ emergency: 0.95, // 95%
24
+ },
25
+ quarantine: {
26
+ warning: 0.7,
27
+ critical: 0.85,
28
+ emergency: 0.95,
29
+ },
30
+ errorRate: {
31
+ warning: 10, // 10 errors/min
32
+ critical: 50, // 50 errors/min
33
+ emergency: 100, // 100 errors/min
34
+ },
35
+ };
36
+ // ─────────────────────────────────────────────────────────────────────────────
37
+ // Implementation
38
+ // ─────────────────────────────────────────────────────────────────────────────
39
+ /**
40
+ * Fail-Safe Panic system.
41
+ */
42
+ export class FailSafe {
43
+ config;
44
+ callbacks = new Map([
45
+ ['warning', []],
46
+ ['critical', []],
47
+ ['emergency', []],
48
+ ]);
49
+ panicHistory = [];
50
+ maxHistory = 100;
51
+ constructor(config = DEFAULT_FAIL_SAFE_CONFIG) {
52
+ this.config = config;
53
+ }
54
+ /**
55
+ * Register a callback for a panic level.
56
+ *
57
+ * @param level - Panic level to listen for
58
+ * @param callback - Callback function
59
+ */
60
+ on(level, callback) {
61
+ this.callbacks.get(level).push(callback);
62
+ }
63
+ /**
64
+ * Register a callback for all panic levels.
65
+ *
66
+ * @param callback - Callback function
67
+ */
68
+ onAny(callback) {
69
+ this.on('warning', callback);
70
+ this.on('critical', callback);
71
+ this.on('emergency', callback);
72
+ }
73
+ /**
74
+ * Check memory usage and trigger panic if needed.
75
+ *
76
+ * @param usedBytes - Current memory usage
77
+ * @param totalBytes - Total available memory
78
+ */
79
+ checkMemory(usedBytes, totalBytes) {
80
+ const ratio = usedBytes / totalBytes;
81
+ const level = this.determineLevel(ratio, this.config.memory);
82
+ if (level) {
83
+ this.trigger({
84
+ level,
85
+ reason: 'memory_threshold',
86
+ timestamp: Date.now(),
87
+ context: {
88
+ current: ratio,
89
+ threshold: this.config.memory[level],
90
+ details: `Memory usage: ${(ratio * 100).toFixed(1)}%`,
91
+ },
92
+ });
93
+ }
94
+ }
95
+ /**
96
+ * Check quarantine capacity and trigger panic if needed.
97
+ *
98
+ * @param current - Current quarantine count
99
+ * @param max - Maximum quarantine capacity
100
+ */
101
+ checkQuarantine(current, max) {
102
+ const ratio = current / max;
103
+ const level = this.determineLevel(ratio, this.config.quarantine);
104
+ if (level) {
105
+ this.trigger({
106
+ level,
107
+ reason: 'quarantine_capacity',
108
+ timestamp: Date.now(),
109
+ context: {
110
+ current: ratio,
111
+ threshold: this.config.quarantine[level],
112
+ details: `Quarantine: ${current}/${max}`,
113
+ },
114
+ });
115
+ }
116
+ }
117
+ /**
118
+ * Check error rate and trigger panic if needed.
119
+ *
120
+ * @param errorsPerMinute - Current error rate
121
+ */
122
+ checkErrorRate(errorsPerMinute) {
123
+ const level = this.determineLevel(errorsPerMinute, this.config.errorRate);
124
+ if (level) {
125
+ this.trigger({
126
+ level,
127
+ reason: 'error_rate',
128
+ timestamp: Date.now(),
129
+ context: {
130
+ current: errorsPerMinute,
131
+ threshold: this.config.errorRate[level],
132
+ details: `Error rate: ${errorsPerMinute}/min`,
133
+ },
134
+ });
135
+ }
136
+ }
137
+ /**
138
+ * Manually trigger a panic.
139
+ *
140
+ * @param level - Panic level
141
+ * @param details - Optional details
142
+ */
143
+ panic(level, details) {
144
+ this.trigger({
145
+ level,
146
+ reason: 'manual',
147
+ timestamp: Date.now(),
148
+ context: details ? { details } : {},
149
+ });
150
+ }
151
+ /**
152
+ * Trigger a panic event.
153
+ *
154
+ * @param event - Panic event
155
+ */
156
+ trigger(event) {
157
+ // Add to history
158
+ this.panicHistory.push(event);
159
+ if (this.panicHistory.length > this.maxHistory) {
160
+ this.panicHistory.shift();
161
+ }
162
+ // Fire callbacks (non-blocking)
163
+ const callbacks = this.callbacks.get(event.level);
164
+ for (const callback of callbacks) {
165
+ try {
166
+ const result = callback(event);
167
+ if (result instanceof Promise) {
168
+ result.catch(() => {
169
+ // Swallow async errors - fail-safe must not throw
170
+ });
171
+ }
172
+ }
173
+ catch {
174
+ // Swallow sync errors - fail-safe must not throw
175
+ }
176
+ }
177
+ }
178
+ /**
179
+ * Get panic history.
180
+ */
181
+ get history() {
182
+ return this.panicHistory;
183
+ }
184
+ /**
185
+ * Get last panic event.
186
+ */
187
+ get lastPanic() {
188
+ return this.panicHistory[this.panicHistory.length - 1];
189
+ }
190
+ /**
191
+ * Determine panic level based on value and thresholds.
192
+ */
193
+ determineLevel(value, thresholds) {
194
+ if (value >= thresholds.emergency)
195
+ return 'emergency';
196
+ if (value >= thresholds.critical)
197
+ return 'critical';
198
+ if (value >= thresholds.warning)
199
+ return 'warning';
200
+ return null;
201
+ }
202
+ }
203
+ /**
204
+ * Create a fail-safe instance.
205
+ *
206
+ * @param config - Optional configuration
207
+ * @returns FailSafe instance
208
+ */
209
+ export function createFailSafe(config) {
210
+ const mergedConfig = {
211
+ memory: { ...DEFAULT_FAIL_SAFE_CONFIG.memory, ...config?.memory },
212
+ quarantine: { ...DEFAULT_FAIL_SAFE_CONFIG.quarantine, ...config?.quarantine },
213
+ errorRate: { ...DEFAULT_FAIL_SAFE_CONFIG.errorRate, ...config?.errorRate },
214
+ };
215
+ return new FailSafe(mergedConfig);
216
+ }
217
+ //# sourceMappingURL=fail-safe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fail-safe.js","sourceRoot":"","sources":["../../src/core/fail-safe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Hound IPC - Binary length-prefixed protocol for child process communication.
3
+ *
4
+ * RFC-0000 REQUIREMENTS:
5
+ * - Length-prefixed binary over stdio
6
+ * - JSON encoding is explicitly forbidden
7
+ * - No retry semantics
8
+ * - Fire-and-forget
9
+ */
10
+ /**
11
+ * Message types that can be sent over IPC.
12
+ * Matches RFC-0000 HoundMessage types.
13
+ */
14
+ export type HoundMessageType = 'status' | 'metrics';
15
+ export type HoundStatus = 'processing' | 'complete' | 'error';
16
+ export interface HoundStatusMessage {
17
+ type: 'status';
18
+ state: HoundStatus;
19
+ error?: string;
20
+ }
21
+ export interface HoundMetricsMessage {
22
+ type: 'metrics';
23
+ processingTime: number;
24
+ memoryUsed: number;
25
+ }
26
+ export type HoundMessage = HoundStatusMessage | HoundMetricsMessage;
27
+ /**
28
+ * Parsed message from IPC stream.
29
+ */
30
+ export interface ParsedMessage {
31
+ payload: ArrayBuffer;
32
+ bytesConsumed: number;
33
+ }
34
+ /**
35
+ * Encode a payload with length prefix.
36
+ *
37
+ * Format: [4 bytes length BE][N bytes payload]
38
+ *
39
+ * @param payload - Raw payload bytes
40
+ * @returns Length-prefixed buffer
41
+ */
42
+ export declare function encodeMessage(payload: ArrayBuffer): Buffer;
43
+ /**
44
+ * Encode a HoundMessage to binary.
45
+ *
46
+ * @param message - Message to encode
47
+ * @returns Length-prefixed buffer
48
+ */
49
+ export declare function encodeHoundMessage(message: HoundMessage): Buffer;
50
+ /**
51
+ * Try to parse a message from a buffer.
52
+ * Handles partial buffers gracefully.
53
+ *
54
+ * @param buffer - Input buffer (may contain partial message)
55
+ * @returns Parsed message or null if incomplete
56
+ */
57
+ export declare function tryParseMessage(buffer: Buffer): ParsedMessage | null;
58
+ /**
59
+ * Decode a HoundMessage from binary payload.
60
+ *
61
+ * @param payload - Raw payload bytes (without length prefix)
62
+ * @returns Decoded message
63
+ */
64
+ export declare function decodeHoundMessage(payload: ArrayBuffer): HoundMessage;
65
+ /**
66
+ * Streaming message parser.
67
+ * Handles partial buffers and backpressure.
68
+ */
69
+ export interface MessageParser {
70
+ /**
71
+ * Feed data into parser.
72
+ * @param chunk - New data chunk
73
+ * @returns Array of complete messages
74
+ */
75
+ feed(chunk: Buffer): ArrayBuffer[];
76
+ /**
77
+ * Get remaining buffered bytes.
78
+ */
79
+ readonly bufferedBytes: number;
80
+ /**
81
+ * Reset parser state.
82
+ */
83
+ reset(): void;
84
+ }
85
+ /**
86
+ * Create a streaming message parser.
87
+ *
88
+ * @returns Message parser instance
89
+ */
90
+ export declare function createMessageParser(): MessageParser;
91
+ //# sourceMappingURL=hound-ipc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hound-ipc.d.ts","sourceRoot":"","sources":["../../src/core/hound-ipc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEnD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAA;AAE7D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,mBAAmB,CAAA;AAEnE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB;AAgBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAiB1D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CA8BhE;AAmBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA2BpE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CAqCrE;AAmBD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAAA;IAElC;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CA8BnD"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Hound IPC - Binary length-prefixed protocol for child process communication.
3
+ *
4
+ * RFC-0000 REQUIREMENTS:
5
+ * - Length-prefixed binary over stdio
6
+ * - JSON encoding is explicitly forbidden
7
+ * - No retry semantics
8
+ * - Fire-and-forget
9
+ */
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+ // Constants
12
+ // ─────────────────────────────────────────────────────────────────────────────
13
+ /** Length prefix size in bytes (32-bit BE) */
14
+ const LENGTH_PREFIX_SIZE = 4;
15
+ /** Maximum message size (1MB) */
16
+ const MAX_MESSAGE_SIZE = 1024 * 1024;
17
+ // ─────────────────────────────────────────────────────────────────────────────
18
+ // Encoding
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ /**
21
+ * Encode a payload with length prefix.
22
+ *
23
+ * Format: [4 bytes length BE][N bytes payload]
24
+ *
25
+ * @param payload - Raw payload bytes
26
+ * @returns Length-prefixed buffer
27
+ */
28
+ export function encodeMessage(payload) {
29
+ const payloadBuffer = Buffer.from(payload);
30
+ const length = payloadBuffer.length;
31
+ if (length > MAX_MESSAGE_SIZE) {
32
+ throw new Error(`Message too large: ${length} > ${MAX_MESSAGE_SIZE}`);
33
+ }
34
+ const result = Buffer.allocUnsafe(LENGTH_PREFIX_SIZE + length);
35
+ // Write length as 32-bit BE
36
+ result.writeUInt32BE(length, 0);
37
+ // Copy payload
38
+ payloadBuffer.copy(result, LENGTH_PREFIX_SIZE);
39
+ return result;
40
+ }
41
+ /**
42
+ * Encode a HoundMessage to binary.
43
+ *
44
+ * @param message - Message to encode
45
+ * @returns Length-prefixed buffer
46
+ */
47
+ export function encodeHoundMessage(message) {
48
+ // Use minimal binary encoding (not JSON)
49
+ // Format: [1 byte type][payload bytes]
50
+ if (message.type === 'status') {
51
+ // Type 0x01 = status
52
+ // [1 byte type][1 byte state][optional error string]
53
+ const stateCode = encodeStatusState(message.state);
54
+ const errorBytes = message.error ? Buffer.from(message.error, 'utf8') : Buffer.alloc(0);
55
+ const payload = Buffer.allocUnsafe(2 + errorBytes.length);
56
+ payload[0] = 0x01; // type: status
57
+ payload[1] = stateCode;
58
+ errorBytes.copy(payload, 2);
59
+ return encodeMessage(payload.buffer.slice(payload.byteOffset, payload.byteOffset + payload.length));
60
+ }
61
+ else {
62
+ // Type 0x02 = metrics
63
+ // [1 byte type][8 bytes processingTime][8 bytes memoryUsed]
64
+ const payload = Buffer.allocUnsafe(17);
65
+ payload[0] = 0x02; // type: metrics
66
+ payload.writeDoubleBE(message.processingTime, 1);
67
+ payload.writeDoubleBE(message.memoryUsed, 9);
68
+ return encodeMessage(payload.buffer.slice(payload.byteOffset, payload.byteOffset + payload.length));
69
+ }
70
+ }
71
+ function encodeStatusState(state) {
72
+ switch (state) {
73
+ case 'processing':
74
+ return 0x01;
75
+ case 'complete':
76
+ return 0x02;
77
+ case 'error':
78
+ return 0x03;
79
+ default:
80
+ return 0x00;
81
+ }
82
+ }
83
+ // ─────────────────────────────────────────────────────────────────────────────
84
+ // Decoding
85
+ // ─────────────────────────────────────────────────────────────────────────────
86
+ /**
87
+ * Try to parse a message from a buffer.
88
+ * Handles partial buffers gracefully.
89
+ *
90
+ * @param buffer - Input buffer (may contain partial message)
91
+ * @returns Parsed message or null if incomplete
92
+ */
93
+ export function tryParseMessage(buffer) {
94
+ // Need at least length prefix
95
+ if (buffer.length < LENGTH_PREFIX_SIZE) {
96
+ return null;
97
+ }
98
+ const length = buffer.readUInt32BE(0);
99
+ // Validate length
100
+ if (length > MAX_MESSAGE_SIZE) {
101
+ throw new Error(`Invalid message length: ${length}`);
102
+ }
103
+ const totalSize = LENGTH_PREFIX_SIZE + length;
104
+ // Check if we have full message
105
+ if (buffer.length < totalSize) {
106
+ return null;
107
+ }
108
+ // Extract payload
109
+ const payloadSlice = buffer.subarray(LENGTH_PREFIX_SIZE, totalSize);
110
+ return {
111
+ payload: new Uint8Array(payloadSlice).buffer,
112
+ bytesConsumed: totalSize,
113
+ };
114
+ }
115
+ /**
116
+ * Decode a HoundMessage from binary payload.
117
+ *
118
+ * @param payload - Raw payload bytes (without length prefix)
119
+ * @returns Decoded message
120
+ */
121
+ export function decodeHoundMessage(payload) {
122
+ const buffer = Buffer.from(payload);
123
+ if (buffer.length < 1) {
124
+ throw new Error('Empty message payload');
125
+ }
126
+ const type = buffer[0];
127
+ if (type === 0x01) {
128
+ // Status message
129
+ if (buffer.length < 2) {
130
+ throw new Error('Invalid status message: too short');
131
+ }
132
+ const stateCode = buffer[1] ?? 0;
133
+ const state = decodeStatusState(stateCode);
134
+ const errorStr = buffer.length > 2 ? buffer.subarray(2).toString('utf8') : undefined;
135
+ const result = { type: 'status', state };
136
+ if (errorStr) {
137
+ result.error = errorStr;
138
+ }
139
+ return result;
140
+ }
141
+ else if (type === 0x02) {
142
+ // Metrics message
143
+ if (buffer.length < 17) {
144
+ throw new Error('Invalid metrics message: too short');
145
+ }
146
+ const processingTime = buffer.readDoubleBE(1);
147
+ const memoryUsed = buffer.readDoubleBE(9);
148
+ return { type: 'metrics', processingTime, memoryUsed };
149
+ }
150
+ else {
151
+ throw new Error(`Unknown message type: ${type}`);
152
+ }
153
+ }
154
+ function decodeStatusState(code) {
155
+ switch (code) {
156
+ case 0x01:
157
+ return 'processing';
158
+ case 0x02:
159
+ return 'complete';
160
+ case 0x03:
161
+ return 'error';
162
+ default:
163
+ throw new Error(`Unknown status state: ${code}`);
164
+ }
165
+ }
166
+ /**
167
+ * Create a streaming message parser.
168
+ *
169
+ * @returns Message parser instance
170
+ */
171
+ export function createMessageParser() {
172
+ let buffer = Buffer.alloc(0);
173
+ return {
174
+ feed(chunk) {
175
+ // Append chunk to buffer
176
+ buffer = Buffer.concat([buffer, chunk]);
177
+ const messages = [];
178
+ // Parse all complete messages
179
+ while (true) {
180
+ const result = tryParseMessage(buffer);
181
+ if (!result)
182
+ break;
183
+ messages.push(result.payload);
184
+ buffer = buffer.subarray(result.bytesConsumed);
185
+ }
186
+ return messages;
187
+ },
188
+ get bufferedBytes() {
189
+ return buffer.length;
190
+ },
191
+ reset() {
192
+ buffer = Buffer.alloc(0);
193
+ },
194
+ };
195
+ }
196
+ //# sourceMappingURL=hound-ipc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hound-ipc.js","sourceRoot":"","sources":["../../src/core/hound-ipc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Hound Pool - Process-based isolation pool for evidence processing.
3
+ *
4
+ * RFC-0000 CRITICAL INVARIANTS:
5
+ * - activate() returns void, NOT Promise (Agent NEVER awaits)
6
+ * - OS-level process isolation (child processes, not threads)
7
+ * - Pre-spawned processes with jittered rotation
8
+ * - Timeout + SIGKILL for stuck processes
9
+ * - Binary IPC over stdio (no JSON)
10
+ *
11
+ * INVARIANT: activeProcesses <= totalProcesses
12
+ * activeProcesses reflects OS-level active child processes
13
+ */
14
+ import type { Evidence } from './evidence.js';
15
+ import { createMockAdapter, type HoundProcessConstraints, type IHoundProcessAdapter } from './process-adapter.js';
16
+ /**
17
+ * Hound execution result.
18
+ * Delivered via internal queue, NOT via Promise to Agent.
19
+ */
20
+ export interface HoundResult {
21
+ /** Evidence signature */
22
+ signature: string;
23
+ /** Execution status */
24
+ status: 'processed' | 'timeout' | 'error';
25
+ /** Processing duration in ms */
26
+ durationMs: number;
27
+ /** Process ID that processed this */
28
+ processId: string;
29
+ /** Error message if status is 'error' */
30
+ error?: string;
31
+ }
32
+ /**
33
+ * Hound pool statistics (immutable snapshot).
34
+ *
35
+ * INVARIANT: activeProcesses <= totalProcesses
36
+ */
37
+ export interface HoundPoolStats {
38
+ /** Number of active processes (OS-level) */
39
+ activeProcesses: number;
40
+ /** Total processes in pool */
41
+ totalProcesses: number;
42
+ /** Total activations */
43
+ totalActivations: number;
44
+ /** Total timeouts */
45
+ totalTimeouts: number;
46
+ /** Total errors */
47
+ totalErrors: number;
48
+ /** Average processing time in ms */
49
+ avgProcessingMs: number;
50
+ }
51
+ /**
52
+ * Pool exhaustion action.
53
+ */
54
+ export type PoolExhaustedAction = 'drop' | 'escalate' | 'defer';
55
+ /**
56
+ * Hound pool configuration.
57
+ */
58
+ export interface HoundPoolConfig {
59
+ /** Number of pre-spawned processes */
60
+ poolSize: number;
61
+ /** Timeout per process in ms */
62
+ timeout: number;
63
+ /** Jitter range for rotation in ms */
64
+ rotationJitterMs: number;
65
+ /** Action when pool exhausted (default: 'drop') */
66
+ onPoolExhausted?: PoolExhaustedAction;
67
+ /** Max queue size for 'defer' action (default: 100) */
68
+ deferQueueLimit?: number;
69
+ /** Process constraints (declarative, best-effort) */
70
+ processConstraints?: Partial<HoundProcessConstraints>;
71
+ /** Path to hound process script */
72
+ processScriptPath?: string;
73
+ /** Custom process adapter (for testing) */
74
+ adapter?: IHoundProcessAdapter;
75
+ }
76
+ /**
77
+ * Hound pool interface.
78
+ *
79
+ * CRITICAL: activate() returns void.
80
+ * Agent NEVER awaits Hound Pool.
81
+ */
82
+ export interface IHoundPool {
83
+ /**
84
+ * Activate hound for evidence processing.
85
+ * Returns immediately. Result via onResult callback.
86
+ *
87
+ * @param evidence - Evidence to process
88
+ */
89
+ activate(evidence: Evidence): void;
90
+ /**
91
+ * Force terminate specific hound by signature.
92
+ *
93
+ * @param signature - Evidence signature to terminate
94
+ */
95
+ terminate(signature: string): void;
96
+ /**
97
+ * Get pool statistics (immutable snapshot).
98
+ */
99
+ readonly stats: Readonly<HoundPoolStats>;
100
+ /**
101
+ * Register result handler.
102
+ * Internal use only - NOT exposed to Agent.
103
+ */
104
+ onResult(handler: (result: HoundResult) => void): void;
105
+ /**
106
+ * Shutdown all processes.
107
+ */
108
+ shutdown(): void;
109
+ }
110
+ /**
111
+ * Hound Pool implementation.
112
+ *
113
+ * Uses child process isolation per RFC-0000 amendment.
114
+ */
115
+ export declare class HoundPool implements IHoundPool {
116
+ private readonly config;
117
+ private readonly processes;
118
+ private readonly pendingQueue;
119
+ private readonly resultHandlers;
120
+ private readonly processingTimes;
121
+ private readonly adapter;
122
+ private readonly processScriptPath;
123
+ private readonly onPoolExhausted;
124
+ private readonly deferQueueLimit;
125
+ private _totalActivations;
126
+ private _totalTimeouts;
127
+ private _totalErrors;
128
+ constructor(config: HoundPoolConfig);
129
+ /**
130
+ * Process constraints (declarative, best-effort).
131
+ */
132
+ static readonly DEFAULT_CONSTRAINTS: Readonly<HoundProcessConstraints>;
133
+ activate(evidence: Evidence): void;
134
+ private handlePoolExhausted;
135
+ terminate(signature: string): void;
136
+ get stats(): Readonly<HoundPoolStats>;
137
+ onResult(handler: (result: HoundResult) => void): void;
138
+ shutdown(): void;
139
+ private createProcessState;
140
+ private findAvailableProcess;
141
+ private assignToProcess;
142
+ private handleProcessMessage;
143
+ private handleProcessExit;
144
+ private handleTimeout;
145
+ private terminateProcess;
146
+ private completeProcessing;
147
+ private processNextInQueue;
148
+ private emitResult;
149
+ }
150
+ /**
151
+ * Create a Hound Pool instance.
152
+ *
153
+ * @param config - Pool configuration
154
+ */
155
+ export declare function createHoundPool(config: HoundPoolConfig): IHoundPool;
156
+ export { createMockAdapter };
157
+ //# sourceMappingURL=hound-pool.d.ts.map