@intutic/mcp-governance-proxy 1.9.0 → 1.10.1

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 (123) hide show
  1. package/README.md +28 -0
  2. package/dist/anomaly/detectors.d.ts +129 -0
  3. package/dist/anomaly/detectors.d.ts.map +1 -0
  4. package/dist/anomaly/detectors.js +368 -0
  5. package/dist/anomaly/detectors.js.map +1 -0
  6. package/dist/anomaly/index.d.ts +52 -0
  7. package/dist/anomaly/index.d.ts.map +1 -0
  8. package/dist/anomaly/index.js +71 -0
  9. package/dist/anomaly/index.js.map +1 -0
  10. package/dist/config.d.ts +107 -1
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +129 -6
  13. package/dist/config.js.map +1 -1
  14. package/dist/daemon/healthMonitor.d.ts.map +1 -1
  15. package/dist/daemon/healthMonitor.js +45 -46
  16. package/dist/daemon/healthMonitor.js.map +1 -1
  17. package/dist/daemon/index.d.ts +15 -1
  18. package/dist/daemon/index.d.ts.map +1 -1
  19. package/dist/daemon/index.js +78 -9
  20. package/dist/daemon/index.js.map +1 -1
  21. package/dist/daemon/instrumentation.d.ts +20 -0
  22. package/dist/daemon/instrumentation.d.ts.map +1 -0
  23. package/dist/daemon/instrumentation.js +61 -0
  24. package/dist/daemon/instrumentation.js.map +1 -0
  25. package/dist/daemon/policyCache.d.ts +83 -0
  26. package/dist/daemon/policyCache.d.ts.map +1 -1
  27. package/dist/daemon/policyCache.js +280 -11
  28. package/dist/daemon/policyCache.js.map +1 -1
  29. package/dist/daemon/statusReporter.d.ts +12 -0
  30. package/dist/daemon/statusReporter.d.ts.map +1 -0
  31. package/dist/daemon/statusReporter.js +130 -0
  32. package/dist/daemon/statusReporter.js.map +1 -0
  33. package/dist/daemon/telemetryBatcher.d.ts +3 -1
  34. package/dist/daemon/telemetryBatcher.d.ts.map +1 -1
  35. package/dist/daemon/telemetryBatcher.js +56 -13
  36. package/dist/daemon/telemetryBatcher.js.map +1 -1
  37. package/dist/daemonClient.d.ts +1 -1
  38. package/dist/daemonClient.d.ts.map +1 -1
  39. package/dist/daemonClient.js +0 -2
  40. package/dist/daemonClient.js.map +1 -1
  41. package/dist/dlp.d.ts +19 -0
  42. package/dist/dlp.d.ts.map +1 -1
  43. package/dist/dlp.js +95 -18
  44. package/dist/dlp.js.map +1 -1
  45. package/dist/emitter.d.ts +40 -2
  46. package/dist/emitter.d.ts.map +1 -1
  47. package/dist/emitter.js +27 -5
  48. package/dist/emitter.js.map +1 -1
  49. package/dist/index.js +13 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/injection.d.ts +46 -0
  52. package/dist/injection.d.ts.map +1 -0
  53. package/dist/injection.js +147 -0
  54. package/dist/injection.js.map +1 -0
  55. package/dist/interceptor.d.ts +131 -1
  56. package/dist/interceptor.d.ts.map +1 -1
  57. package/dist/interceptor.js +301 -5
  58. package/dist/interceptor.js.map +1 -1
  59. package/dist/policy.d.ts +110 -2
  60. package/dist/policy.d.ts.map +1 -1
  61. package/dist/policy.js +206 -5
  62. package/dist/policy.js.map +1 -1
  63. package/dist/proxy.d.ts +205 -0
  64. package/dist/proxy.d.ts.map +1 -1
  65. package/dist/proxy.js +572 -65
  66. package/dist/proxy.js.map +1 -1
  67. package/dist/remoteBridge.d.ts +51 -0
  68. package/dist/remoteBridge.d.ts.map +1 -0
  69. package/dist/remoteBridge.js +182 -0
  70. package/dist/remoteBridge.js.map +1 -0
  71. package/dist/session.d.ts +158 -0
  72. package/dist/session.d.ts.map +1 -0
  73. package/dist/session.js +206 -0
  74. package/dist/session.js.map +1 -0
  75. package/dist/sessionScope.d.ts +51 -0
  76. package/dist/sessionScope.d.ts.map +1 -0
  77. package/dist/sessionScope.js +94 -0
  78. package/dist/sessionScope.js.map +1 -0
  79. package/dist/sessionStore.d.ts +69 -0
  80. package/dist/sessionStore.d.ts.map +1 -0
  81. package/dist/sessionStore.js +143 -0
  82. package/dist/sessionStore.js.map +1 -0
  83. package/dist/tofu.d.ts +112 -0
  84. package/dist/tofu.d.ts.map +1 -0
  85. package/dist/tofu.js +180 -0
  86. package/dist/tofu.js.map +1 -0
  87. package/dist/toolPoison.d.ts +32 -0
  88. package/dist/toolPoison.d.ts.map +1 -0
  89. package/dist/toolPoison.js +81 -0
  90. package/dist/toolPoison.js.map +1 -0
  91. package/dist/valkeyErrors.d.ts +17 -0
  92. package/dist/valkeyErrors.d.ts.map +1 -0
  93. package/dist/valkeyErrors.js +24 -0
  94. package/dist/valkeyErrors.js.map +1 -0
  95. package/dist/wasm/context.d.ts +57 -0
  96. package/dist/wasm/context.d.ts.map +1 -0
  97. package/dist/wasm/context.js +59 -0
  98. package/dist/wasm/context.js.map +1 -0
  99. package/dist/wasm/hostImports.d.ts +43 -0
  100. package/dist/wasm/hostImports.d.ts.map +1 -0
  101. package/dist/wasm/hostImports.js +158 -0
  102. package/dist/wasm/hostImports.js.map +1 -0
  103. package/dist/wasm/loader.d.ts +95 -0
  104. package/dist/wasm/loader.d.ts.map +1 -0
  105. package/dist/wasm/loader.js +198 -0
  106. package/dist/wasm/loader.js.map +1 -0
  107. package/dist/wasm/referencedFiles.d.ts +115 -0
  108. package/dist/wasm/referencedFiles.d.ts.map +1 -0
  109. package/dist/wasm/referencedFiles.js +366 -0
  110. package/dist/wasm/referencedFiles.js.map +1 -0
  111. package/dist/wasm/runner.d.ts +91 -0
  112. package/dist/wasm/runner.d.ts.map +1 -0
  113. package/dist/wasm/runner.js +308 -0
  114. package/dist/wasm/runner.js.map +1 -0
  115. package/dist/wasm/watch.d.ts +5 -0
  116. package/dist/wasm/watch.d.ts.map +1 -0
  117. package/dist/wasm/watch.js +54 -0
  118. package/dist/wasm/watch.js.map +1 -0
  119. package/dist/wasm/worker.d.ts +39 -0
  120. package/dist/wasm/worker.d.ts.map +1 -0
  121. package/dist/wasm/worker.js +245 -0
  122. package/dist/wasm/worker.js.map +1 -0
  123. package/package.json +14 -4
package/dist/policy.js CHANGED
@@ -11,6 +11,37 @@ import * as node_http from 'node:http';
11
11
  import { createStderrLogger as createLogger } from './stderrLog.js';
12
12
  import { callDaemonSocket } from './daemonClient.js';
13
13
  const log = createLogger('mcp-proxy-policy');
14
+ /**
15
+ * Is this unvalidated object actually a policy rule?
16
+ *
17
+ * The daemon caches `sopRules` as `Record<string, unknown>[]` — it filters the
18
+ * control plane's response to plain objects and validates nothing further. The
19
+ * client then used `as SopRule[]`, behind a `Promise<any>` that hid the
20
+ * mismatch entirely.
21
+ *
22
+ * That matters because these drive blocking decisions: a rule missing
23
+ * `toolPattern` reaches `new RegExp(undefined)` and matches everything, and a
24
+ * rule with an unrecognised `action` falls through every branch and enforces
25
+ * nothing. Neither is a shape the control plane intends to send — which is the
26
+ * argument for dropping the malformed ones loudly rather than trusting a cast.
27
+ */
28
+ /**
29
+ * Exported because it is the contract between this package and whatever
30
+ * produces rules for it, not merely an internal helper. `policyCache`'s snapshot
31
+ * seed has to satisfy it, and a test that asserted against a *copy* of this
32
+ * predicate would prove nothing about the real one — which is precisely the
33
+ * two-copies-of-one-rule failure the harness gates were just rebuilt to remove.
34
+ */
35
+ export function isSopRule(value) {
36
+ if (typeof value !== 'object' || value === null)
37
+ return false;
38
+ const r = value;
39
+ return (typeof r['id'] === 'string' &&
40
+ typeof r['toolPattern'] === 'string' &&
41
+ typeof r['reason'] === 'string' &&
42
+ (r['argPattern'] === undefined || typeof r['argPattern'] === 'string') &&
43
+ (r['action'] === 'block' || r['action'] === 'warn' || r['action'] === 'require_approval'));
44
+ }
14
45
  export class PolicyClient {
15
46
  controlPlaneUrl;
16
47
  apiKey;
@@ -18,6 +49,57 @@ export class PolicyClient {
18
49
  ttlMs;
19
50
  mcpProxyMode;
20
51
  rules = [];
52
+ /**
53
+ * Workspace DLP regex sources, delivered to the scanner on every refresh.
54
+ * The daemon has cached these since the policy cache existed; this client
55
+ * received and dropped them — a workspace's custom patterns were a setting
56
+ * wired to nothing.
57
+ */
58
+ dlpPatterns = [];
59
+ /** Workspace injection-pattern sources (`mcpInjectionPatterns`, TD-436); empty = floor only. */
60
+ injectionPatterns = [];
61
+ /**
62
+ * Additive tool scoping: when non-empty, ONLY these tools may be called
63
+ * through this proxy. Empty means unrestricted — the same convention as
64
+ * `allow_harnesses` and the starter rules' allowlist inversion warnings:
65
+ * an empty allowlist read as "permit nothing" would block every workspace
66
+ * that never declared one.
67
+ */
68
+ allowedTools = [];
69
+ /** Operator-curated tool descriptions, applied to tools/list responses. */
70
+ toolDescriptionOverrides = {};
71
+ /**
72
+ * Additive SERVER scoping: when non-empty, ONLY these MCP server names may
73
+ * be proxied by this process. Empty means unrestricted — same convention
74
+ * and same source as `allowedTools` above (mirrors `mcpAllowedTools` /
75
+ * `mcpAllowedServers` in workspace settings, delivered via the same
76
+ * `GET /api/v1/sop/rules` response this class already polls).
77
+ */
78
+ allowedServers = [];
79
+ /**
80
+ * Control-plane-delivered prompt-injection disposition override. `undefined`
81
+ * (never `'warn'`/`'block'` by default) means "the control plane did not
82
+ * send this field" — distinct from the field being explicitly set to
83
+ * `'warn'` — so the caller (interceptor.ts) knows to fall back to
84
+ * `config.ts`'s `mcpInjectionAction` env-derived default rather than
85
+ * silently treating an unset policy as an explicit warn.
86
+ */
87
+ injectionAction;
88
+ /**
89
+ * Control-plane-delivered anomaly-detection mode override (Phase 2).
90
+ * `undefined` when absent — same "absent means no override, fall back to
91
+ * config.ts's env-derived default" convention as `injectionAction` above.
92
+ */
93
+ anomalyMode;
94
+ /**
95
+ * Control-plane-delivered per-detector disposition overrides. Always an
96
+ * object (never `undefined`) — an absent policy field reads as "no
97
+ * overrides," which `resolveEffectiveDisposition` (anomaly/index.ts)
98
+ * already treats as a no-op via `overrides[detectorId] === undefined`, the
99
+ * same empty-object-means-unrestricted convention `toolDescriptionOverrides`
100
+ * above uses.
101
+ */
102
+ anomalyOverrides = {};
21
103
  lastFetchAt = 0;
22
104
  refreshTimer = null;
23
105
  constructor(controlPlaneUrl, apiKey, workspaceId, ttlMs = 60_000, mcpProxyMode = 'per-session') {
@@ -27,17 +109,31 @@ export class PolicyClient {
27
109
  this.ttlMs = ttlMs;
28
110
  this.mcpProxyMode = mcpProxyMode;
29
111
  }
30
- /** Start background refresh timer. */
31
- start() {
112
+ /**
113
+ * Start background refresh timer.
114
+ *
115
+ * @param onTick - Optional callback invoked on the SAME interval as the
116
+ * policy refresh (including the initial kick below) — Phase 3's
117
+ * `~/.intutic/wasm/` rescan (`WasmRunner.rescan`, wired from proxy.ts)
118
+ * hooks this rather than starting a second timer, per the task's own
119
+ * "don't add a second timer" instruction. Errors are swallowed the same
120
+ * way `refresh()`'s own are — a rescan failure must not take down the
121
+ * policy refresh it rides alongside.
122
+ */
123
+ start(onTick) {
32
124
  this.refreshTimer = setInterval(() => {
33
125
  void this.refresh().catch(() => {
34
126
  // Errors already logged inside refresh()
35
127
  });
128
+ if (onTick)
129
+ void Promise.resolve(onTick()).catch(() => { });
36
130
  }, this.ttlMs);
37
131
  // Don't block Node.js exit on this timer
38
132
  this.refreshTimer.unref();
39
133
  // Kick off initial fetch (non-blocking — proxy starts immediately)
40
134
  void this.refresh().catch(() => { });
135
+ if (onTick)
136
+ void Promise.resolve(onTick()).catch(() => { });
41
137
  }
42
138
  /** Stop the background refresh timer. */
43
139
  stop() {
@@ -50,6 +146,82 @@ export class PolicyClient {
50
146
  getRules() {
51
147
  return this.rules;
52
148
  }
149
+ /** Workspace DLP regex sources from the last successful refresh. */
150
+ /** Workspace-supplied prompt-injection regex sources; empty means the hardcoded floor alone. */
151
+ getInjectionPatterns() {
152
+ return this.injectionPatterns;
153
+ }
154
+ getDlpPatterns() {
155
+ return this.dlpPatterns;
156
+ }
157
+ /** The additive tool allowlist; empty means unrestricted. */
158
+ getAllowedTools() {
159
+ return this.allowedTools;
160
+ }
161
+ /** The additive MCP server allowlist; empty means unrestricted. */
162
+ getAllowedServers() {
163
+ return this.allowedServers;
164
+ }
165
+ /** Operator description overrides for tools/list curation. */
166
+ getToolDescriptionOverrides() {
167
+ return this.toolDescriptionOverrides;
168
+ }
169
+ /**
170
+ * The control-plane-delivered prompt-injection disposition, or `undefined`
171
+ * when the policy source never sent `mcpInjectionAction` — absent means
172
+ * "no override", not "warn". Callers (interceptor.ts) fall back to
173
+ * `config.ts`'s env-derived default in that case, the same "absent means
174
+ * default" convention every other optional policy field in this class
175
+ * follows.
176
+ */
177
+ getInjectionAction() {
178
+ return this.injectionAction;
179
+ }
180
+ /** The control-plane-delivered anomaly mode, or `undefined` if unset (see field doc). */
181
+ getAnomalyMode() {
182
+ return this.anomalyMode;
183
+ }
184
+ /** Per-detector disposition overrides; always an object, empty means none. */
185
+ getAnomalyOverrides() {
186
+ return this.anomalyOverrides;
187
+ }
188
+ /** Parse the optional curation fields shared by both refresh paths. */
189
+ absorbCuration(source) {
190
+ const allowed = source['allowedTools'] ?? source['mcpAllowedTools'];
191
+ this.allowedTools = Array.isArray(allowed)
192
+ ? allowed.filter((t) => typeof t === 'string')
193
+ : [];
194
+ const overrides = source['toolDescriptionOverrides'] ?? source['mcpToolDescriptionOverrides'];
195
+ this.toolDescriptionOverrides = {};
196
+ if (typeof overrides === 'object' && overrides !== null && !Array.isArray(overrides)) {
197
+ for (const [k, v] of Object.entries(overrides)) {
198
+ if (typeof v === 'string')
199
+ this.toolDescriptionOverrides[k] = v;
200
+ }
201
+ }
202
+ const allowedServers = source['allowedServers'] ?? source['mcpAllowedServers'];
203
+ this.allowedServers = Array.isArray(allowedServers)
204
+ ? allowedServers.filter((s) => typeof s === 'string')
205
+ : [];
206
+ const injectionPatterns = source['mcpInjectionPatterns'];
207
+ this.injectionPatterns = Array.isArray(injectionPatterns)
208
+ ? injectionPatterns.filter((p) => typeof p === 'string')
209
+ : [];
210
+ const injectionAction = source['mcpInjectionAction'];
211
+ this.injectionAction =
212
+ injectionAction === 'warn' || injectionAction === 'block' ? injectionAction : undefined;
213
+ const anomalyMode = source['mcpAnomalyMode'];
214
+ this.anomalyMode =
215
+ anomalyMode === 'enforce' || anomalyMode === 'warn' || anomalyMode === 'off' ? anomalyMode : undefined;
216
+ const anomalyOverrides = source['mcpAnomalyOverrides'];
217
+ this.anomalyOverrides = {};
218
+ if (typeof anomalyOverrides === 'object' && anomalyOverrides !== null && !Array.isArray(anomalyOverrides)) {
219
+ for (const [k, v] of Object.entries(anomalyOverrides)) {
220
+ if (v === 'steer' || v === 'reask' || v === 'kill' || v === 'off')
221
+ this.anomalyOverrides[k] = v;
222
+ }
223
+ }
224
+ }
53
225
  /** Find the first matching rule for a given tool name + serialized args. */
54
226
  matchRule(toolName, toolInputJson) {
55
227
  for (const rule of this.rules) {
@@ -74,16 +246,40 @@ export class PolicyClient {
74
246
  async refresh() {
75
247
  if (this.mcpProxyMode === 'daemon') {
76
248
  try {
77
- const policy = await callDaemonSocket('policy.get', { workspaceId: this.workspaceId });
249
+ // The socket returns whatever the daemon serialised, so the caller
250
+ // names the shape it expects. `policy.get` is answered by `resolvePolicy`
251
+ // in the daemon's own policyCache, which is where this type comes from —
252
+ // not an assertion, the actual producer's return type.
253
+ const policy = await callDaemonSocket('policy.get', {
254
+ workspaceId: this.workspaceId,
255
+ });
78
256
  if (policy) {
79
- this.rules = (policy.sopRules || []);
257
+ const candidates = policy.sopRules ?? [];
258
+ // An explicit loop rather than `.filter(isSopRule)`: TypeScript will
259
+ // not narrow `Record<string, unknown>[]` to `SopRule[]` through a type
260
+ // predicate, because an interface has no implicit index signature.
261
+ const accepted = [];
262
+ for (const candidate of candidates) {
263
+ if (isSopRule(candidate))
264
+ accepted.push(candidate);
265
+ }
266
+ this.rules = accepted;
267
+ const dropped = candidates.length - accepted.length;
268
+ if (dropped > 0) {
269
+ log.warn({ action: 'policy_rules_malformed', dropped, kept: this.rules.length }, 'Dropped malformed SOP rules from the daemon — they cannot be enforced');
270
+ }
271
+ this.dlpPatterns = (policy.dlpPatterns ?? []).filter((p) => typeof p === 'string');
272
+ this.absorbCuration(policy);
80
273
  this.lastFetchAt = Date.now();
81
274
  log.info({ action: 'policy_refreshed_from_daemon', ruleCount: this.rules.length }, 'SOP rules refreshed from daemon');
82
275
  return;
83
276
  }
84
277
  }
85
278
  catch (err) {
86
- log.warn({ action: 'policy_daemon_failed', err: err.message }, 'Failed to refresh policy from daemon socket — falling back to HTTP');
279
+ log.warn({
280
+ action: 'policy_daemon_failed',
281
+ err: err instanceof Error ? err.message : String(err),
282
+ }, 'Failed to refresh policy from daemon socket — falling back to HTTP');
87
283
  }
88
284
  }
89
285
  const url = `${this.controlPlaneUrl}/api/v1/sop/rules?workspaceId=${encodeURIComponent(this.workspaceId)}&active=true`;
@@ -92,6 +288,11 @@ export class PolicyClient {
92
288
  const parsed = JSON.parse(body);
93
289
  const rules = Array.isArray(parsed.rules) ? parsed.rules : [];
94
290
  this.rules = rules;
291
+ const dlp = parsed['dlpPatterns'];
292
+ this.dlpPatterns = Array.isArray(dlp)
293
+ ? dlp.filter((p) => typeof p === 'string')
294
+ : [];
295
+ this.absorbCuration(parsed);
95
296
  this.lastFetchAt = Date.now();
96
297
  log.info({ action: 'policy_refreshed', ruleCount: rules.length }, 'SOP rules refreshed');
97
298
  }
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,UAAU,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGpD,MAAM,GAAG,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAA;AAc5C;;;;;;;;;;;;;GAaG;AACH;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,CAAC,GAAG,KAAgC,CAAA;IAC1C,OAAO,CACL,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ;QAC3B,OAAO,CAAC,CAAC,aAAa,CAAC,KAAK,QAAQ;QACpC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ;QAC/B,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC;QACtE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,kBAAkB,CAAC,CAC1F,CAAA;AACH,CAAC;AAMD,MAAM,OAAO,YAAY;IAyDJ;IACA;IACA;IACA;IACA;IA5DX,KAAK,GAAc,EAAE,CAAA;IAC7B;;;;;OAKG;IACK,WAAW,GAAa,EAAE,CAAA;IAClC,gGAAgG;IACxF,iBAAiB,GAAa,EAAE,CAAA;IACxC;;;;;;OAMG;IACK,YAAY,GAAa,EAAE,CAAA;IACnC,2EAA2E;IACnE,wBAAwB,GAA2B,EAAE,CAAA;IAC7D;;;;;;OAMG;IACK,cAAc,GAAa,EAAE,CAAA;IACrC;;;;;;;OAOG;IACK,eAAe,CAA8B;IACrD;;;;OAIG;IACK,WAAW,CAAwC;IAC3D;;;;;;;OAOG;IACK,gBAAgB,GAAuD,EAAE,CAAA;IACzE,WAAW,GAAG,CAAC,CAAA;IACf,YAAY,GAA0B,IAAI,CAAA;IAElD,YACmB,eAAuB,EACvB,MAAc,EACd,WAAmB,EACnB,QAAgB,MAAM,EACtB,eAAuB,aAAa;QAJpC,oBAAe,GAAf,eAAe,CAAQ;QACvB,WAAM,GAAN,MAAM,CAAQ;QACd,gBAAW,GAAX,WAAW,CAAQ;QACnB,UAAK,GAAL,KAAK,CAAiB;QACtB,iBAAY,GAAZ,YAAY,CAAwB;IACpD,CAAC;IAEJ;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAmC;QACvC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC7B,yCAAyC;YAC3C,CAAC,CAAC,CAAA;YACF,IAAI,MAAM;gBAAE,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAC5D,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QACd,yCAAyC;QACzC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;QAEzB,mEAAmE;QACnE,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACnC,IAAI,MAAM;YAAE,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,yCAAyC;IACzC,IAAI;QACF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;QAC1B,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,oEAAoE;IACpE,gGAAgG;IAChG,oBAAoB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAA;IAC/B,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAED,6DAA6D;IAC7D,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAA;IAC1B,CAAC;IAED,mEAAmE;IACnE,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAA;IAC5B,CAAC;IAED,8DAA8D;IAC9D,2BAA2B;QACzB,OAAO,IAAI,CAAC,wBAAwB,CAAA;IACtC,CAAC;IAED;;;;;;;OAOG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAA;IAC7B,CAAC;IAED,yFAAyF;IACzF,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAED,8EAA8E;IAC9E,mBAAmB;QACjB,OAAO,IAAI,CAAC,gBAAgB,CAAA;IAC9B,CAAC;IAED,uEAAuE;IAC/D,cAAc,CAAC,MAA+B;QACpD,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAA;QACnE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACxC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YAC3D,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,SAAS,GAAG,MAAM,CAAC,0BAA0B,CAAC,IAAI,MAAM,CAAC,6BAA6B,CAAC,CAAA;QAC7F,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAA;QAClC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACrF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAoC,CAAC,EAAE,CAAC;gBAC1E,IAAI,OAAO,CAAC,KAAK,QAAQ;oBAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YACjE,CAAC;QACH,CAAC;QACD,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,MAAM,CAAC,mBAAmB,CAAC,CAAA;QAC9E,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;YACjD,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YAClE,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,iBAAiB,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAA;QACxD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC;YACvD,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACrE,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,eAAe,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAA;QACpD,IAAI,CAAC,eAAe;YAClB,eAAe,KAAK,MAAM,IAAI,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAA;QACzF,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAC5C,IAAI,CAAC,WAAW;YACd,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,MAAM,IAAI,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;QACxG,MAAM,gBAAgB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAA;QACtD,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC1B,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC1G,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAA2C,CAAC,EAAE,CAAC;gBACjF,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK;oBAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YACjG,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,SAAS,CAAC,QAAgB,EAAE,aAAqB;QAC/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAE,SAAQ;gBACvC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACpB,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;oBAC5C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;wBAAE,SAAQ;gBAC7C,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,gDAAgD;IAChD,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,mEAAmE;gBACnE,0EAA0E;gBAC1E,yEAAyE;gBACzE,uDAAuD;gBACvD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAwB,YAAY,EAAE;oBACzE,WAAW,EAAE,IAAI,CAAC,WAAW;iBAC9B,CAAC,CAAA;gBACF,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAA;oBACxC,qEAAqE;oBACrE,uEAAuE;oBACvE,mEAAmE;oBACnE,MAAM,QAAQ,GAAc,EAAE,CAAA;oBAC9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;wBACnC,IAAI,SAAS,CAAC,SAAS,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;oBACpD,CAAC;oBACD,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;oBACrB,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;oBACnD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;wBAChB,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,wBAAwB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EACtE,uEAAuE,CACxE,CAAA;oBACH,CAAC;oBACD,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,MAAM,CAClD,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAC1C,CAAA;oBACD,IAAI,CAAC,cAAc,CAAC,MAA4C,CAAC,CAAA;oBACjE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;oBAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,8BAA8B,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,iCAAiC,CAAC,CAAA;oBACrH,OAAM;gBACR,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN;oBACE,MAAM,EAAE,sBAAsB;oBAC9B,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACtD,EACD,oEAAoE,CACrE,CAAA;YACH,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,eAAe,iCAAiC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAA;QACtH,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,EAAE,uCAAuC,CAAC,CAAA;QAErF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA+C,CAAA;QAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QAC7D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,MAAM,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,CAAA;QACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YACnC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACvD,CAAC,CAAC,EAAE,CAAA;QACN,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAA;IAC1F,CAAC;CACF;AAED,qEAAqE;AACrE,SAAS,OAAO,CAAC,GAAW,EAAE,MAAc;IAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAA;QACjE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CACjB,GAAG,EACH;YACE,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,EAAE;gBACjC,MAAM,EAAE,kBAAkB;aAC3B;YACD,OAAO,EAAE,IAAI;SACd,EACD,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,MAAM,GAAa,EAAE,CAAA;YAC3B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;gBACpD,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,UAAU,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;gBACnE,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,CAAA;gBACf,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;QACD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QACvB,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAA;YACb,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAA;QAC7C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
package/dist/proxy.d.ts CHANGED
@@ -9,6 +9,16 @@
9
9
  * Harness ↔ [McpGovernanceProxy as MCP Server] ↔ Control Plane REST API
10
10
  * Exposes governance tools: intutic_governance_status, intutic_list_sops, intutic_list_incidents.
11
11
  *
12
+ * Architecture (remote bridge mode — `--remote-url`, see remoteBridge.ts):
13
+ * Harness stdin → [McpGovernanceProxy] → remote MCP server (HTTP/SSE)
14
+ * Remote MCP server → [McpGovernanceProxy] → Harness stdout
15
+ * The harness still spawns this proxy as an ordinary stdio child process —
16
+ * only the UPSTREAM side changes, from a spawned child's stdin/stdout to an
17
+ * MCP SDK client transport talking HTTP/SSE. `handleHarnessLine` (request
18
+ * direction) and `handleServerLine` (response direction) are the exact same
19
+ * functions proxy mode uses; remoteBridge.ts only supplies a different
20
+ * upstream and a different `forward`.
21
+ *
12
22
  * CRITICAL: Never write to process.stdout except for valid JSON-RPC frames.
13
23
  * All logging MUST go to process.stderr via @intutic/logger.
14
24
  *
@@ -17,13 +27,187 @@
17
27
  * @module
18
28
  */
19
29
  import type { ProxyConfig } from './config.js';
30
+ import { ToolCallInterceptor } from './interceptor.js';
31
+ import { type InjectionSource } from './injection.js';
32
+ import { SessionState } from './session.js';
33
+ /** What the harness asked for under a given request id, awaiting its response. */
34
+ export interface PendingRequest {
35
+ method: 'tools/call' | 'tools/list' | 'resources/read';
36
+ toolName?: string;
37
+ }
38
+ /** The outcome of inspecting one server→harness line. */
39
+ export interface ServerLineOutcome {
40
+ /** The line to forward — possibly rewritten. */
41
+ line: string;
42
+ /** Set when result content was redacted: the tool (or resource) it came from. */
43
+ redactedTool?: string;
44
+ /** Pattern descriptions redacted out of the result. */
45
+ redactions?: string[];
46
+ /** Set when a tools/list response was filtered or had descriptions overridden. */
47
+ curated?: {
48
+ hidden: number;
49
+ overridden: number;
50
+ };
51
+ /**
52
+ * The (post-curation) tool array, set whenever this line was a `tools/list`
53
+ * response — regardless of whether curation changed anything — so the
54
+ * caller can run TOFU pinning (tofu.ts) over it. `undefined` for every
55
+ * other line.
56
+ */
57
+ toolsListTools?: Array<Record<string, unknown>>;
58
+ /** The JSON-RPC id of the `tools/list` response, needed to build a block
59
+ * frame in the caller if TOFU refuses it. Set alongside `toolsListTools`. */
60
+ toolsListMsgId?: string | number | null;
61
+ /**
62
+ * Prompt-injection findings (injection.ts) from this line, one entry per
63
+ * scanned surface that matched — a `tools/call`/`resources/read` result
64
+ * (`tool_result`) yields at most one entry; a `tools/list` response can
65
+ * yield one per tool whose (post-curation) description matched. The
66
+ * caller (`handleServerLine`) emits `injection_detected` (and, on a
67
+ * response-direction block, `tool_blocked`) from these — `processServerLine`
68
+ * itself stays a pure function with no emitter access, the same reason
69
+ * `redactedTool`/`redactions` exist as outcome fields rather than emitting
70
+ * directly.
71
+ */
72
+ injectionFindings?: Array<{
73
+ source: InjectionSource;
74
+ toolName: string;
75
+ patterns: string[];
76
+ }>;
77
+ /**
78
+ * Set when a response-direction injection match, under `mcpInjectionAction:
79
+ * 'block'`, caused `line` to carry a withheld-result error frame instead of
80
+ * the real result — mirrors `redactedTool` for the injection path, so the
81
+ * caller can log/emit the block distinctly from a plain redaction.
82
+ */
83
+ injectionBlocked?: boolean;
84
+ /**
85
+ * Phase 2's `dlp_escalation` finding (anomaly/detectors.ts), set when a
86
+ * `tools/call`/`resources/read` result carried ≥3 distinct DLP-redacted
87
+ * pattern types. Severity-escalation only — see `dlpEscalation`'s own doc
88
+ * comment for why this never becomes a NEW block: the content is already
89
+ * redacted (`redactions` above), and this proxy's DLP scan already blocks
90
+ * any request-direction finding unconditionally, so escalating an
91
+ * already-redacted RESPONSE protects nothing further.
92
+ */
93
+ dlpEscalationReason?: string;
94
+ /**
95
+ * Phase 2's `tool_poisoning` finding (anomaly/detectors.ts), set on a
96
+ * `tools/list` response whose post-curation tool descriptions matched
97
+ * `toolPoison.ts`'s 7-pattern scanner. Report-only, same as
98
+ * `injectionFindings` on this same response type — never removes or
99
+ * blocks a listing.
100
+ */
101
+ toolPoisoningReason?: string;
102
+ }
103
+ /**
104
+ * Inspect one line of real-server output before it reaches the harness.
105
+ *
106
+ * This is the seam the byte-for-byte pipe never had: the request direction has
107
+ * been scanned since the interceptor existed, while the real server's stdout —
108
+ * tool results, resource reads, every tools/list — streamed into the agent's
109
+ * context untouched. A result carrying a credential put it straight into
110
+ * model-visible context; a `redact` Decision variant and a `tool_redacted`
111
+ * event existed as declared types with no producer. This function is the
112
+ * producer.
113
+ *
114
+ * Redaction, not blocking, on results: the call already executed, so refusing
115
+ * the response protects nothing — keeping the secret out of the agent's
116
+ * context is the only thing still at stake. If the redacted result no longer
117
+ * parses (a secret that spanned JSON syntax), the whole result is withheld
118
+ * and replaced with an error naming why — forwarding either the original or
119
+ * a broken body would be worse, the same fail-closed reparse rule the Rust
120
+ * proxy applies to non-streaming bodies.
121
+ *
122
+ * tools/list curation (the Uber-gateway mechanism): when the workspace
123
+ * declares an additive allowlist, tools outside it are removed from the
124
+ * listing — an agent that never sees a tool does not hallucinate calls to
125
+ * it, and the call-time block in the interceptor stays as the enforcement
126
+ * backstop. Operator description overrides apply to what remains, which is
127
+ * also the counter to a poisoned upstream description — the pin detects the
128
+ * change; the override controls what the agent actually reads.
129
+ */
130
+ export declare function processServerLine(raw: string, pending: Map<string | number, PendingRequest>, allowedTools: readonly string[], overrides: Readonly<Record<string, string>>, injectionAction?: 'warn' | 'block', injectionPatterns?: readonly string[]): ServerLineOutcome;
131
+ /**
132
+ * Handle one harness→upstream line — shared, byte-for-byte, between stdio
133
+ * proxy mode (`McpGovernanceProxy.runProxy`, below) and the remote HTTP/SSE
134
+ * bridge (`remoteBridge.ts`'s `runRemoteProxy`): parse JSON-RPC, register any
135
+ * `tools/list`/`resources/read` request so its response gets inspected on the
136
+ * way back (see `processServerLine`), and run every `tools/call` through the
137
+ * SAME `interceptor.decide()` call this proxy has always used. `forward` is
138
+ * the ONLY thing that differs by upstream transport — stdio mode writes to
139
+ * the spawned child process's stdin, remote bridge mode calls the MCP SDK
140
+ * transport's `send()` — so pulling it out as a parameter, rather than
141
+ * forking this whole function, is what keeps governance identical across
142
+ * both upstream transports instead of two copies that could quietly drift.
143
+ *
144
+ * A free function (like `processServerLine`), not a class method, precisely
145
+ * so `remoteBridge.ts` can call it without needing a `McpGovernanceProxy`
146
+ * instance shaped for the stdio child-process lifecycle it doesn't have.
147
+ */
148
+ export declare function handleHarnessLine(line: string, pending: Map<string | number, PendingRequest>, interceptor: ToolCallInterceptor, forward: (line: string) => void, session?: SessionState): void;
20
149
  export declare class McpGovernanceProxy {
21
150
  private readonly config;
22
151
  private readonly policy;
23
152
  private readonly emitter;
24
153
  private readonly interceptor;
154
+ /**
155
+ * Phase 2's session state — the tool-call sequence and per-detector reask
156
+ * counters. ONE instance per proxy process, shared with the interceptor
157
+ * (for detection + reask counting), `handleHarnessLine` (for post-decision
158
+ * recording), and this class's own `handleServerLine` (for caching the
159
+ * post-curation tools/list the tool_poisoning detector reads). Since Wave
160
+ * 5.3 (TD-437) it is also shared ACROSS the session's sibling proxy
161
+ * processes through `sessionStore` when a Valkey URL is configured — see
162
+ * session.ts's module doc.
163
+ */
164
+ private readonly session;
165
+ /** The Valkey-backed shared window, when `config.valkeyUrl` is set and this is not the standalone entry. */
166
+ private readonly sessionStore;
167
+ /**
168
+ * Phase 3's WASM custom-rule runner — owns the one dedicated
169
+ * `worker_threads` Worker and the `~/.intutic/wasm/` directory loader.
170
+ * Rescanned on the SAME 60s policy-tick timer `PolicyClient.start` already
171
+ * runs, not a second one (see `policy.ts`'s `start(onTick)`).
172
+ */
173
+ private readonly wasmRunner;
25
174
  private realServer;
26
175
  constructor(config: ProxyConfig);
176
+ /**
177
+ * The tools/call decision engine — exposed so `remoteBridge.ts` can drive
178
+ * `handleHarnessLine` (the exported free function above) against the SAME
179
+ * interceptor instance this class builds from `config` in its constructor,
180
+ * rather than constructing a second one that could drift.
181
+ */
182
+ getInterceptor(): ToolCallInterceptor;
183
+ /**
184
+ * The shared session state — exposed for the same reason `getInterceptor`
185
+ * is: `remoteBridge.ts` drives `handleHarnessLine` with this exact
186
+ * instance so the sequence detectors read and the sequence
187
+ * `handleHarnessLine` records into are never two different objects.
188
+ */
189
+ getSessionState(): SessionState;
190
+ /**
191
+ * Start the policy client's background refresh timer. Exposed alongside
192
+ * `stopPolicy` so `remoteBridge.ts` can drive the same policy lifecycle
193
+ * `runProxy` below drives for stdio mode, without reaching into `policy`
194
+ * (private) directly. Also rides this same tick to rescan Phase 3's
195
+ * `~/.intutic/wasm/` directory — see `policy.ts`'s `start(onTick)` doc.
196
+ */
197
+ startPolicy(): void;
198
+ private wasmWatch;
199
+ /**
200
+ * Hot reload for `~/.intutic/wasm/` (TD-442): a directory watcher, not a
201
+ * second timer, so a dropped-in rule takes effect within a second instead
202
+ * of at the next 60-second tick. Re-armed on every tick because the
203
+ * directory may not exist when the proxy starts.
204
+ */
205
+ private ensureWasmWatch;
206
+ /**
207
+ * Stop the policy client's background refresh timer, and shut down the
208
+ * WASM worker thread. See `startPolicy`.
209
+ */
210
+ stopPolicy(): void;
27
211
  /**
28
212
  * Start the proxy. Dispatches to standalone or proxy mode based on config.
29
213
  */
@@ -34,6 +218,27 @@ export declare class McpGovernanceProxy {
34
218
  * Gracefully degrades when the control plane is unreachable.
35
219
  */
36
220
  private runStandalone;
221
+ /**
222
+ * Inspects one real-server → harness line (see `processServerLine`) and
223
+ * writes the outcome to stdout. Async, unlike the byte pipe this replaced,
224
+ * because a `tools/list` response also runs server-level TOFU pinning
225
+ * (tofu.ts), which does file I/O — the ONLY case this awaits before
226
+ * writing; every other line is forwarded exactly as fast as before.
227
+ *
228
+ * On a TOFU mismatch, honors `mcpProxyFailBehavior` via `config.failOpen` —
229
+ * the SAME field `interceptor.ts` already reads for its own fail-open/
230
+ * fail-closed branches, not a new mechanism: fail-open logs and forwards
231
+ * the (possibly curated) tools/list response as normal; fail-closed
232
+ * replaces it with a JSON-RPC error naming the server and the setting,
233
+ * mirroring `buildBlockResponse`'s existing wording style.
234
+ *
235
+ * Public (not `private`) so `remoteBridge.ts` can hand it every message
236
+ * `transport.onmessage` receives from a remote upstream, VERBATIM — DLP
237
+ * redaction, TOFU pinning, and event emission on the response direction
238
+ * must apply identically regardless of which upstream transport produced
239
+ * the line, and this is the one place that logic lives.
240
+ */
241
+ handleServerLine(rawLine: string, pending: Map<string | number, PendingRequest>): Promise<void>;
37
242
  /**
38
243
  * Start the proxy. Spawns the real MCP server and begins proxying stdin/stdout.
39
244
  * Returns a promise that resolves when the real server exits.
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAkD9C,qBAAa,kBAAkB;IAMjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,UAAU,CAAuC;gBAE5B,MAAM,EAAE,WAAW;IAoBhD;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAS1B;;;;OAIG;YACW,aAAa;IA0G3B;;;OAGG;YACW,QAAQ;CAqGvB"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}