hackmyagent 0.16.7 → 0.17.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.
@@ -2,9 +2,9 @@
2
2
  * Behavioral risk signal channel (AIComply P1, coordinator hot path).
3
3
  *
4
4
  * The `IntelligenceCoordinator` needs a way to ask the behavioral twin
5
- * (`NanoMindL1` in `nanomind-l1.ts`) "how anomalous does this event look
6
- * against the agent's behavioral baseline?" without importing the twin
7
- * directly into the comply path. Direct coupling would re-introduce the
5
+ * (`RuntimeTwin` in `runtime-twin.ts`) "how anomalous does this event
6
+ * look against the agent's behavioral baseline?" without importing the
7
+ * twin directly into the comply path. Direct coupling would re-introduce the
8
8
  * layering break that the L0-comply gate was added to prevent: the twin
9
9
  * would sit inline with the crypto verifier, and a bug in the twin would
10
10
  * cascade into every classified event.
@@ -16,8 +16,8 @@
16
16
  * - `InProcessBehavioralRiskSource` wraps any object that exposes
17
17
  * `scoreARPEvent(event)`. This is the single-process fast path: no
18
18
  * serialization, no socket, just a direct call guarded by a try/catch.
19
- * `NanoMindL1` satisfies the interface via its readonly scoreARPEvent
20
- * method, but tests can inject any stub.
19
+ * `RuntimeTwin` satisfies the interface via its readonly
20
+ * scoreARPEvent method, but tests can inject any stub.
21
21
  *
22
22
  * - `UnixSocketBehavioralRiskSource` speaks newline-delimited JSON over
23
23
  * a unix domain socket (or a Windows named pipe via node `net`). This
@@ -51,10 +51,10 @@
51
51
  */
52
52
  import type { ARPEvent } from '../types';
53
53
  /**
54
- * Shape returned by the twin's on-demand scorer. Mirrors NanoMindL1's
54
+ * Shape returned by the twin's on-demand scorer. Mirrors RuntimeTwin's
55
55
  * internal AnomalyResult so this module does not need to import the twin
56
56
  * directly, and so test stubs can produce it without depending on the
57
- * full NanoMindL1 class surface.
57
+ * full RuntimeTwin class surface.
58
58
  */
59
59
  export interface BehavioralRiskScore {
60
60
  /** Normalized anomaly score in [0, 1]. Higher is riskier. */
@@ -66,7 +66,7 @@ export interface BehavioralRiskScore {
66
66
  }
67
67
  /**
68
68
  * Minimum interface an in-process twin handle must satisfy to be plugged
69
- * into `InProcessBehavioralRiskSource`. NanoMindL1.scoreARPEvent matches
69
+ * into `InProcessBehavioralRiskSource`. RuntimeTwin.scoreARPEvent matches
70
70
  * this shape by construction.
71
71
  */
72
72
  export interface BehavioralRiskScoreable {
@@ -158,7 +158,7 @@ export declare function defaultBehavioralRiskSocketPath(agentId: string): string
158
158
  * misbehaving twin that throws.
159
159
  *
160
160
  * Decoupling rationale: the coordinator holds this as a
161
- * `BehavioralRiskSource`, not as a `NanoMindL1`. The comply path has no
161
+ * `BehavioralRiskSource`, not as a `RuntimeTwin`. The comply path has no
162
162
  * knowledge of twin internals and a bug in the twin surfaces as an
163
163
  * `unavailable` result, not a cascade failure.
164
164
  */
@@ -3,9 +3,9 @@
3
3
  * Behavioral risk signal channel (AIComply P1, coordinator hot path).
4
4
  *
5
5
  * The `IntelligenceCoordinator` needs a way to ask the behavioral twin
6
- * (`NanoMindL1` in `nanomind-l1.ts`) "how anomalous does this event look
7
- * against the agent's behavioral baseline?" without importing the twin
8
- * directly into the comply path. Direct coupling would re-introduce the
6
+ * (`RuntimeTwin` in `runtime-twin.ts`) "how anomalous does this event
7
+ * look against the agent's behavioral baseline?" without importing the
8
+ * twin directly into the comply path. Direct coupling would re-introduce the
9
9
  * layering break that the L0-comply gate was added to prevent: the twin
10
10
  * would sit inline with the crypto verifier, and a bug in the twin would
11
11
  * cascade into every classified event.
@@ -17,8 +17,8 @@
17
17
  * - `InProcessBehavioralRiskSource` wraps any object that exposes
18
18
  * `scoreARPEvent(event)`. This is the single-process fast path: no
19
19
  * serialization, no socket, just a direct call guarded by a try/catch.
20
- * `NanoMindL1` satisfies the interface via its readonly scoreARPEvent
21
- * method, but tests can inject any stub.
20
+ * `RuntimeTwin` satisfies the interface via its readonly
21
+ * scoreARPEvent method, but tests can inject any stub.
22
22
  *
23
23
  * - `UnixSocketBehavioralRiskSource` speaks newline-delimited JSON over
24
24
  * a unix domain socket (or a Windows named pipe via node `net`). This
@@ -135,7 +135,7 @@ function defaultBehavioralRiskSocketPath(agentId) {
135
135
  * misbehaving twin that throws.
136
136
  *
137
137
  * Decoupling rationale: the coordinator holds this as a
138
- * `BehavioralRiskSource`, not as a `NanoMindL1`. The comply path has no
138
+ * `BehavioralRiskSource`, not as a `RuntimeTwin`. The comply path has no
139
139
  * knowledge of twin internals and a bug in the twin surfaces as an
140
140
  * `unavailable` result, not a cascade failure.
141
141
  */
@@ -476,8 +476,8 @@ function raiseSeverity(current, floor) {
476
476
  /**
477
477
  * Bands the behavioral risk score is sorted into, matched to severity
478
478
  * floors raised on the event when the band fires. The score ranges come
479
- * from NanoMindL1's response table; they are deliberately mirrored here
480
- * rather than imported, so the coordinator's policy can drift
479
+ * from RuntimeTwin's response table; they are deliberately mirrored
480
+ * here rather than imported, so the coordinator's policy can drift
481
481
  * independently of the twin's internal action labels if needed.
482
482
  *
483
483
  * >= 0.8 : critical -> event.category >= threat, severity >= critical
@@ -0,0 +1,157 @@
1
+ /**
2
+ * RuntimeTwin - Behavioral Anomaly Detection Layer (L1).
3
+ *
4
+ * Integrates the RuntimeTwin behavioral scorer into ARP's event pipeline.
5
+ * Processes every L0 event through the twin for anomaly scoring.
6
+ *
7
+ * Three-tier ARP model:
8
+ * L0: Rule-based (EventEngine) microseconds, always runs
9
+ * L1: RuntimeTwin behavioral twin milliseconds, this module
10
+ * L2: Claude or local LLM intelligence seconds, IntelligenceCoordinator
11
+ *
12
+ * L1 runs in parallel with L0. It never blocks the L0 decision.
13
+ *
14
+ * === SOURCE-OF-TRUTH NOTE ===
15
+ *
16
+ * The canonical implementation of this class lives at:
17
+ * opena2a-org/nanomind/packages/nanomind-runtime-core/src/index.ts
18
+ *
19
+ * This file is a temporary integration-layer mirror maintained in lockstep
20
+ * with the canonical source until PR 1b publishes @nanomind/runtime-core
21
+ * to npm. Until that cut-over, any change to the LSTM scoring logic,
22
+ * gradient accumulation, or differential privacy path MUST be made in
23
+ * both files. See todo/NANOMIND_V3_AUDIT.md Section 8 PR 1 and Section 9
24
+ * item 1 for the rationale.
25
+ *
26
+ * This mirror retains the hackmyagent-local imports of ARPEvent and
27
+ * ARPConfig so ARP integration stays type-safe. The canonical package
28
+ * defines a structural ARPEventInput equivalent to keep itself free of
29
+ * cross-repo dependencies.
30
+ */
31
+ import type { ARPEvent } from '../types';
32
+ import type { EventEngine } from '../engine/event-engine';
33
+ type EventType = 'TOOL_CALL' | 'CAPABILITY_CHECK' | 'MCP_CALL' | 'MEMORY_READ' | 'MEMORY_WRITE' | 'EXTERNAL_CALL';
34
+ type ARPAction = 'allow' | 'alert' | 'throttle' | 'suspend' | 'kill';
35
+ interface BehavioralEvent {
36
+ agentId: string;
37
+ sessionId: string;
38
+ sequenceNum: number;
39
+ eventType: EventType;
40
+ capability: string;
41
+ toolName: string | null;
42
+ argHash: string;
43
+ timestampDelta: number;
44
+ wallClock: number;
45
+ responseSize: number;
46
+ responseCode: number;
47
+ l0Decision: 'allow' | 'block' | 'alert';
48
+ }
49
+ interface BaselineStats {
50
+ eventTypeCounts: Record<string, number>;
51
+ avgTimingDelta: number;
52
+ stdTimingDelta: number;
53
+ capabilitySet: Set<string>;
54
+ avgResponseSize: number;
55
+ totalEvents: number;
56
+ errorRate: number;
57
+ }
58
+ interface AnomalyResult {
59
+ score: number;
60
+ action: ARPAction;
61
+ reason: string;
62
+ }
63
+ export declare class RuntimeTwin {
64
+ private agentId;
65
+ private sessionId;
66
+ private baseline;
67
+ private eventBuffer;
68
+ private sequenceNum;
69
+ private lastEventTime;
70
+ private eventLogPath;
71
+ private enabled;
72
+ private gradientAccumulator;
73
+ private gradientEventCount;
74
+ private gradientLossSum;
75
+ private fleetEnabled;
76
+ private agentCategory;
77
+ constructor(agentId: string, config?: {
78
+ enabled?: boolean;
79
+ fleetEnabled?: boolean;
80
+ agentCategory?: string;
81
+ });
82
+ /**
83
+ * Attach to an ARP EventEngine — processes every event for anomaly detection.
84
+ * Non-blocking: L1 runs in parallel, L0 decision is returned immediately.
85
+ */
86
+ attach(engine: EventEngine): void;
87
+ /**
88
+ * Score an ARP event for behavioral risk WITHOUT mutating any twin state.
89
+ *
90
+ * Used by the behavioral risk IPC server (behavioral-risk-server.ts) to
91
+ * answer on-demand scoring requests from a coordinator running in another
92
+ * process, or by InProcessBehavioralRiskSource for single-process wiring.
93
+ * Unlike `processEvent`, this does not advance the sequence number, append
94
+ * to the event log, add to the event buffer, or accumulate the gradient.
95
+ * It is a pure read against the current baseline.
96
+ *
97
+ * Returns null when the twin is disabled or the baseline is not yet
98
+ * trained (totalEvents < 100). The caller must surface this to the IPC
99
+ * client as a NOT_READY signal; silently returning a zero score would
100
+ * misrepresent the twin's confidence.
101
+ */
102
+ scoreARPEvent(event: ARPEvent): AnomalyResult | null;
103
+ /**
104
+ * Readonly variant of convertEvent that does not mutate lastEventTime or
105
+ * sequenceNum. Used by scoreARPEvent for on-demand IPC scoring.
106
+ */
107
+ private convertEventReadonly;
108
+ /**
109
+ * Test-only seam: force-install a baseline so unit tests can exercise
110
+ * scoreARPEvent without first calling processEvent a hundred times. Marked
111
+ * with a leading underscore so it is easy to grep for in production code.
112
+ */
113
+ _setBaselineForTest(baseline: BaselineStats): void;
114
+ /**
115
+ * Process a behavioral event and return anomaly score.
116
+ */
117
+ processEvent(event: BehavioralEvent): AnomalyResult;
118
+ /**
119
+ * Convert an ARP event to a NanoMind behavioral event.
120
+ */
121
+ private convertEvent;
122
+ /**
123
+ * Compute anomaly score (same algorithm as @nanomind/runtime-core).
124
+ */
125
+ private computeAnomalyScore;
126
+ private updateBaseline;
127
+ private getResponse;
128
+ private loadBaseline;
129
+ private appendToLog;
130
+ private logEscalation;
131
+ /**
132
+ * Accumulate behavioral features into gradient vector.
133
+ * Each event contributes to a running gradient that captures the
134
+ * distribution of event types, timing anomalies, error rates,
135
+ * and capability novelty seen by this agent.
136
+ */
137
+ private accumulateGradient;
138
+ /**
139
+ * Submit accumulated gradient to Registry fleet endpoint.
140
+ * Normalizes by event count before submission (the fleet module
141
+ * handles clipping and differential privacy noise).
142
+ */
143
+ private flushGradient;
144
+ /**
145
+ * Apply differential privacy: clip to L2 norm 1.0, add Gaussian noise.
146
+ * Matches the privacy guarantees inlined in @nanomind/runtime-core
147
+ * (epsilon=1.0, delta=1e-5). The statistical twin's @nanomind/runtime
148
+ * package was retired in the Q5 split (audit Section 9 item 1).
149
+ */
150
+ private addPrivacyNoise;
151
+ /**
152
+ * Force flush any remaining gradient (call on shutdown).
153
+ */
154
+ shutdown(): Promise<void>;
155
+ }
156
+ export {};
157
+ //# sourceMappingURL=runtime-twin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-twin.d.ts","sourceRoot":"","sources":["../../../src/arp/intelligence/runtime-twin.ts"],"names":[],"mappings":"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"}