@intutic/mcp-governance-proxy 2.3.0 → 2.5.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 (55) hide show
  1. package/README.md +1 -1
  2. package/dist/agentTools.d.ts +15 -0
  3. package/dist/agentTools.d.ts.map +1 -1
  4. package/dist/agentTools.js +21 -1
  5. package/dist/agentTools.js.map +1 -1
  6. package/dist/chaos.d.ts +90 -0
  7. package/dist/chaos.d.ts.map +1 -0
  8. package/dist/chaos.js +174 -0
  9. package/dist/chaos.js.map +1 -0
  10. package/dist/daemon/policyCache.d.ts +7 -0
  11. package/dist/daemon/policyCache.d.ts.map +1 -1
  12. package/dist/daemon/policyCache.js +2 -0
  13. package/dist/daemon/policyCache.js.map +1 -1
  14. package/dist/emitter.d.ts +40 -2
  15. package/dist/emitter.d.ts.map +1 -1
  16. package/dist/emitter.js +7 -1
  17. package/dist/emitter.js.map +1 -1
  18. package/dist/httpJson.d.ts +7 -0
  19. package/dist/httpJson.d.ts.map +1 -1
  20. package/dist/httpJson.js +39 -0
  21. package/dist/httpJson.js.map +1 -1
  22. package/dist/index.js +15 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/interceptor.d.ts +24 -0
  25. package/dist/interceptor.d.ts.map +1 -1
  26. package/dist/interceptor.js +58 -11
  27. package/dist/interceptor.js.map +1 -1
  28. package/dist/policy.d.ts +26 -1
  29. package/dist/policy.d.ts.map +1 -1
  30. package/dist/policy.js +49 -3
  31. package/dist/policy.js.map +1 -1
  32. package/dist/proxy.d.ts +32 -6
  33. package/dist/proxy.d.ts.map +1 -1
  34. package/dist/proxy.js +107 -55
  35. package/dist/proxy.js.map +1 -1
  36. package/dist/refusals.d.ts +25 -0
  37. package/dist/refusals.d.ts.map +1 -1
  38. package/dist/refusals.js +50 -0
  39. package/dist/refusals.js.map +1 -1
  40. package/dist/remoteBridge.d.ts +2 -1
  41. package/dist/remoteBridge.d.ts.map +1 -1
  42. package/dist/remoteBridge.js +4 -3
  43. package/dist/remoteBridge.js.map +1 -1
  44. package/dist/wasm/cloudRules.d.ts +138 -0
  45. package/dist/wasm/cloudRules.d.ts.map +1 -0
  46. package/dist/wasm/cloudRules.js +242 -0
  47. package/dist/wasm/cloudRules.js.map +1 -0
  48. package/dist/wasm/loader.d.ts +3 -1
  49. package/dist/wasm/loader.d.ts.map +1 -1
  50. package/dist/wasm/loader.js.map +1 -1
  51. package/dist/wasm/runner.d.ts +63 -9
  52. package/dist/wasm/runner.d.ts.map +1 -1
  53. package/dist/wasm/runner.js +107 -12
  54. package/dist/wasm/runner.js.map +1 -1
  55. package/package.json +4 -4
@@ -0,0 +1,242 @@
1
+ /**
2
+ * wasm/cloudRules.ts — the workspace's custom rules from the control plane:
3
+ * the rules uploaded from the dashboard, the CLI or Terraform, which the LLM
4
+ * proxy enforces too.
5
+ *
6
+ * Port of the control-plane half of `packages/proxy/src/wasm/registry.rs`
7
+ * (`ensure_up_to_date`, `load_descriptor`, `report_refusal`). The descriptors
8
+ * arrive with the workspace policy this proxy already fetches (`wasmRules` on
9
+ * `GET /api/v1/sop/rules`, or on the MCP daemon's cached
10
+ * `GET /api/v1/policy/resolve`), so they refresh when the policy does. Each
11
+ * binary is fetched by the SHA-256 its descriptor names, only when no loaded
12
+ * rule already has that hash, and must hash to it before it is compiled:
13
+ * whoever can answer for that hash could otherwise swap a governance rule for
14
+ * one that allows everything.
15
+ *
16
+ * A version that cannot load — binary missing, hash mismatch, or a module the
17
+ * worker refuses — is reported once per hash and reason, and the version of
18
+ * that rule already loaded, if any, keeps enforcing. A control plane that
19
+ * cannot be reached for a binary leaves the whole loaded set as it was, as
20
+ * `registry.rs` does when its fetch fails.
21
+ *
22
+ * @module
23
+ */
24
+ import { createHash } from 'node:crypto';
25
+ import { createStderrLogger as createLogger } from '../stderrLog.js';
26
+ import { HttpStatusError, getBytes } from '../httpJson.js';
27
+ import { MAX_RULE_FILE_BYTES } from './loader.js';
28
+ const log = createLogger('mcp-proxy-wasm-cloud');
29
+ /**
30
+ * Minimum time between attempts after a sync that could not reach the control
31
+ * plane or refused a version — the Rust proxy's 5-second rescan, so a binary
32
+ * published a moment after its descriptor is picked up as quickly there.
33
+ */
34
+ export const CLOUD_RETRY_MS = 5_000;
35
+ /**
36
+ * Fetches binaries from the control plane's rule store by hash. A 404 is a
37
+ * binary the control plane does not have; any other failure means it could
38
+ * not be asked.
39
+ */
40
+ export function fetchRuleBinaryFrom(controlPlaneUrl, apiKey) {
41
+ return async (sha256) => {
42
+ const url = `${controlPlaneUrl}/api/v1/wasm-rules/binaries/${encodeURIComponent(sha256)}`;
43
+ try {
44
+ return await getBytes(url, apiKey, MAX_RULE_FILE_BYTES);
45
+ }
46
+ catch (err) {
47
+ if (err instanceof HttpStatusError && err.status === 404)
48
+ return null;
49
+ throw err;
50
+ }
51
+ };
52
+ }
53
+ /** A refusal as the `wasm_rule_refused` event carries it. */
54
+ export function refusalDetail(report) {
55
+ const { descriptor, refusal } = report;
56
+ return {
57
+ ruleId: descriptor.ruleId,
58
+ name: descriptor.name,
59
+ sha256: descriptor.sha256,
60
+ refusal: refusal.kind,
61
+ ...(refusal.kind === 'hash_mismatch' ? { actualSha256: refusal.actual } : {}),
62
+ previousInForce: report.hasPrevious,
63
+ };
64
+ }
65
+ /** Whether `bytes` are the binary `sha256` names; case is not significant in hex. */
66
+ export function binaryMatches(bytes, sha256) {
67
+ const actual = createHash('sha256').update(bytes).digest('hex');
68
+ return { matches: actual === sha256.toLowerCase(), actual };
69
+ }
70
+ /** What makes two refusals of one version the same report (`Refusal::key`). */
71
+ function refusalKey(refusal) {
72
+ if (refusal.kind === 'hash_mismatch')
73
+ return refusal.actual;
74
+ return refusal.kind;
75
+ }
76
+ export function describeRefusal(descriptor, refusal, hasPrevious) {
77
+ const why = refusal.kind === 'missing'
78
+ ? "its binary is missing from the control plane"
79
+ : refusal.kind === 'hash_mismatch'
80
+ ? `its binary hashes to ${refusal.actual} but its descriptor names ${descriptor.sha256}`
81
+ : `it cannot be loaded: ${refusal.error}`;
82
+ const consequence = hasPrevious
83
+ ? 'The previously loaded version stays in force.'
84
+ : 'No version of this rule has loaded on this proxy, so it enforces nothing until one does.';
85
+ return `WASM rule '${descriptor.name}' (${descriptor.ruleId}) was refused: ${why}. ${consequence}`;
86
+ }
87
+ export class CloudRuleSet {
88
+ fetchBinary;
89
+ report;
90
+ rules = [];
91
+ /** The descriptor list last applied, serialized; `undefined` until one has been. */
92
+ appliedKey;
93
+ /** The list of the last attempt, applied or not, and when it ran. */
94
+ attemptedKey;
95
+ attemptedAt = 0;
96
+ /** Whether the applied list left a version unloaded, so it is retried. */
97
+ incomplete = false;
98
+ syncing = null;
99
+ refusalsReported = new Set();
100
+ constructor(fetchBinary, report) {
101
+ this.fetchBinary = fetchBinary;
102
+ this.report = report;
103
+ }
104
+ /** Whether a descriptor list has been applied, so the loaded set is the workspace's. */
105
+ isLoaded() {
106
+ return this.appliedKey !== undefined;
107
+ }
108
+ /** The loaded rules, in descriptor order. */
109
+ getRules() {
110
+ return this.rules;
111
+ }
112
+ /**
113
+ * Brings the loaded set in line with `descriptors`.
114
+ *
115
+ * A changed list is applied before this resolves, so the call that follows
116
+ * a policy refresh is judged by the new set. Retrying versions the applied
117
+ * list refused, at most every {@link CLOUD_RETRY_MS}, runs in the
118
+ * background: the loaded set is already the workspace's. A list that could
119
+ * not be applied is retried no sooner either, so an unreachable control
120
+ * plane costs a call one fetch timeout at most every few seconds rather
121
+ * than on every call.
122
+ */
123
+ async sync(descriptors, bridge) {
124
+ while (this.syncing)
125
+ await this.syncing;
126
+ const key = JSON.stringify(descriptors);
127
+ const due = Date.now() - this.attemptedAt >= CLOUD_RETRY_MS;
128
+ if (key === this.appliedKey) {
129
+ if (this.incomplete && due)
130
+ void this.run(descriptors, key, bridge);
131
+ return;
132
+ }
133
+ if (key === this.attemptedKey && !due)
134
+ return;
135
+ await this.run(descriptors, key, bridge);
136
+ }
137
+ /**
138
+ * Recompiles every loaded rule from its kept bytes — the worker that held
139
+ * them was replaced. Waits for a sync in flight, which may have compiled
140
+ * into the old worker.
141
+ */
142
+ async reload(bridge) {
143
+ while (this.syncing)
144
+ await this.syncing;
145
+ for (const rule of this.rules)
146
+ await bridge.compile(rule.ruleId, rule.bytes);
147
+ }
148
+ run(descriptors, key, bridge) {
149
+ const run = this.apply(descriptors, key, bridge)
150
+ .catch((err) => {
151
+ // The worker itself failed under the sync; the loaded set is unchanged
152
+ // and the next sync tries again.
153
+ log.warn({ action: 'wasm_cloud_sync_failed', err: err.message }, "Syncing the workspace's custom rules failed");
154
+ })
155
+ .finally(() => {
156
+ if (this.syncing === run)
157
+ this.syncing = null;
158
+ });
159
+ this.syncing = run;
160
+ return run;
161
+ }
162
+ async apply(descriptors, key, bridge) {
163
+ this.attemptedKey = key;
164
+ this.attemptedAt = Date.now();
165
+ const previousBySha = new Map(this.rules.map((r) => [r.sha256, r]));
166
+ const previousByRule = new Map(this.rules.map((r) => [r.ruleId, r]));
167
+ // Every binary no loaded rule already has, fetched before anything
168
+ // changes: a control plane that cannot be reached leaves the loaded set
169
+ // exactly as it was.
170
+ const wanted = [...new Set(descriptors.map((d) => d.sha256).filter((sha) => !previousBySha.has(sha)))];
171
+ let fetched;
172
+ try {
173
+ fetched = new Map(await Promise.all(wanted.map(async (sha) => [sha, await this.fetchBinary(sha)])));
174
+ }
175
+ catch (err) {
176
+ log.warn({ action: 'wasm_cloud_fetch_failed', err: err.message, loaded: this.rules.length }, this.isLoaded()
177
+ ? "Could not fetch the workspace's custom rules; the loaded set stays in force"
178
+ : "Could not fetch the workspace's custom rules; none have loaded yet");
179
+ return;
180
+ }
181
+ const next = [];
182
+ let incomplete = false;
183
+ for (const descriptor of descriptors) {
184
+ const reuse = previousBySha.get(descriptor.sha256);
185
+ const outcome = reuse
186
+ ? await this.reuse(descriptor, reuse, bridge)
187
+ : await this.load(descriptor, fetched.get(descriptor.sha256) ?? null, bridge);
188
+ if ('kind' in outcome) {
189
+ incomplete = true;
190
+ const previous = previousByRule.get(descriptor.ruleId);
191
+ this.reportOnce(descriptor, outcome, previous !== undefined);
192
+ if (previous)
193
+ next.push(previous);
194
+ continue;
195
+ }
196
+ if (previousByRule.get(descriptor.ruleId)?.sha256 !== descriptor.sha256)
197
+ bridge.replaced(descriptor.ruleId);
198
+ next.push(outcome);
199
+ }
200
+ // A rule no longer listed — deleted, or switched off — stops enforcing.
201
+ const kept = new Set(next.map((r) => r.ruleId));
202
+ for (const rule of this.rules) {
203
+ if (!kept.has(rule.ruleId))
204
+ bridge.remove(rule.ruleId);
205
+ }
206
+ this.rules = next;
207
+ this.appliedKey = key;
208
+ this.incomplete = incomplete;
209
+ log.info({ action: 'wasm_cloud_rules_loaded', rules: next.length, listed: descriptors.length }, "Workspace's custom rules loaded");
210
+ }
211
+ /** A binary some loaded rule already has: compiled again only when it is new to this rule id. */
212
+ async reuse(descriptor, loaded, bridge) {
213
+ if (loaded.ruleId !== descriptor.ruleId) {
214
+ const result = await bridge.compile(descriptor.ruleId, loaded.bytes);
215
+ if (!result.ok)
216
+ return { kind: result.reason, error: result.error };
217
+ }
218
+ return { ...loaded, ...descriptor };
219
+ }
220
+ /** `load_descriptor`: the hash, then the same load checks as a local rule. */
221
+ async load(descriptor, bytes, bridge) {
222
+ if (!bytes)
223
+ return { kind: 'missing' };
224
+ const { matches, actual } = binaryMatches(bytes, descriptor.sha256);
225
+ if (!matches)
226
+ return { kind: 'hash_mismatch', actual };
227
+ const result = await bridge.compile(descriptor.ruleId, bytes);
228
+ if (!result.ok)
229
+ return { kind: result.reason, error: result.error };
230
+ return { ...descriptor, readsReferencedFiles: result.readsReferencedFiles, rego: result.rego, bytes };
231
+ }
232
+ reportOnce(descriptor, refusal, hasPrevious) {
233
+ const id = [descriptor.sha256, refusalKey(refusal)].join('\u0000');
234
+ if (this.refusalsReported.has(id))
235
+ return;
236
+ this.refusalsReported.add(id);
237
+ const description = describeRefusal(descriptor, refusal, hasPrevious);
238
+ log.error({ action: 'wasm_cloud_rule_refused', ruleId: descriptor.ruleId, sha256: descriptor.sha256, refusal: refusal.kind }, description);
239
+ this.report({ descriptor, refusal, hasPrevious, description });
240
+ }
241
+ }
242
+ //# sourceMappingURL=cloudRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudRules.js","sourceRoot":"","sources":["../../src/wasm/cloudRules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE1D,OAAO,EAAE,mBAAmB,EAAiD,MAAM,aAAa,CAAA;AAEhG,MAAM,GAAG,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAAA;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAiDnC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,eAAuB,EAAE,MAAc;IACzE,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,MAAM,GAAG,GAAG,GAAG,eAAe,+BAA+B,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAA;QACzF,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAA;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAA;YACrE,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,aAAa,CAAC,MAA8B;IAC1D,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;IACtC,OAAO;QACL,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,eAAe,EAAE,MAAM,CAAC,WAAW;KACpC,CAAA;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,MAAc;IAC7D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAA;AAC7D,CAAC;AAED,+EAA+E;AAC/E,SAAS,UAAU,CAAC,OAAyB;IAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,OAAO,CAAC,MAAM,CAAA;IAC3D,OAAO,OAAO,CAAC,IAAI,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAA8B,EAAE,OAAyB,EAAE,WAAoB;IAC7G,MAAM,GAAG,GACP,OAAO,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,8CAA8C;QAChD,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,eAAe;YAChC,CAAC,CAAC,wBAAwB,OAAO,CAAC,MAAM,6BAA6B,UAAU,CAAC,MAAM,EAAE;YACxF,CAAC,CAAC,wBAAwB,OAAO,CAAC,KAAK,EAAE,CAAA;IAC/C,MAAM,WAAW,GAAG,WAAW;QAC7B,CAAC,CAAC,+CAA+C;QACjD,CAAC,CAAC,0FAA0F,CAAA;IAC9F,OAAO,cAAc,UAAU,CAAC,IAAI,MAAM,UAAU,CAAC,MAAM,kBAAkB,GAAG,KAAK,WAAW,EAAE,CAAA;AACpG,CAAC;AAED,MAAM,OAAO,YAAY;IAaJ;IACA;IAbX,KAAK,GAAoB,EAAE,CAAA;IACnC,oFAAoF;IAC5E,UAAU,CAAoB;IACtC,qEAAqE;IAC7D,YAAY,CAAoB;IAChC,WAAW,GAAG,CAAC,CAAA;IACvB,0EAA0E;IAClE,UAAU,GAAG,KAAK,CAAA;IAClB,OAAO,GAAyB,IAAI,CAAA;IAC3B,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IAErD,YACmB,WAA4B,EAC5B,MAAgD;QADhD,gBAAW,GAAX,WAAW,CAAiB;QAC5B,WAAM,GAAN,MAAM,CAA0C;IAChE,CAAC;IAEJ,wFAAwF;IACxF,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,KAAK,SAAS,CAAA;IACtC,CAAC;IAED,6CAA6C;IAC7C,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,IAAI,CAAC,WAA0C,EAAE,MAAuB;QAC5E,OAAO,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAA;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI,cAAc,CAAA;QAC3D,IAAI,GAAG,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,UAAU,IAAI,GAAG;gBAAE,KAAK,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;YACnE,OAAM;QACR,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,CAAC,YAAY,IAAI,CAAC,GAAG;YAAE,OAAM;QAC7C,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IAC1C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,MAAqB;QAChC,OAAO,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAA;QACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IAC9E,CAAC;IAEO,GAAG,CAAC,WAA0C,EAAE,GAAW,EAAE,MAAuB;QAC1F,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC;aAC7C,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACtB,uEAAuE;YACvE,iCAAiC;YACjC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,GAAG,EAAG,GAAa,CAAC,OAAO,EAAE,EAAE,6CAA6C,CAAC,CAAA;QAC5H,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAC/C,CAAC,CAAC,CAAA;QACJ,IAAI,CAAC,OAAO,GAAG,GAAG,CAAA;QAClB,OAAO,GAAG,CAAA;IACZ,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,WAA0C,EAAE,GAAW,EAAE,MAAuB;QAClG,IAAI,CAAC,YAAY,GAAG,GAAG,CAAA;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE7B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QACnE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAEpE,mEAAmE;QACnE,wEAAwE;QACxE,qBAAqB;QACrB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACtG,IAAI,OAAuC,CAAA;QAC3C,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAU,CAAC,CAAC,CAAC,CAAA;QAC9G,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,yBAAyB,EAAE,GAAG,EAAG,GAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAC7F,IAAI,CAAC,QAAQ,EAAE;gBACb,CAAC,CAAC,6EAA6E;gBAC/E,CAAC,CAAC,oEAAoE,CACzE,CAAA;YACD,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAoB,EAAE,CAAA;QAChC,IAAI,UAAU,GAAG,KAAK,CAAA;QACtB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YAClD,MAAM,OAAO,GAAG,KAAK;gBACnB,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC;gBAC7C,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,CAAA;YAC/E,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;gBACtB,UAAU,GAAG,IAAI,CAAA;gBACjB,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;gBACtD,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAA;gBAC5D,IAAI,QAAQ;oBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACjC,SAAQ;YACV,CAAC;YACD,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC,MAAM;gBAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YAC3G,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC;QAED,wEAAwE;QACxE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QAC/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAA;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,yBAAyB,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,EACrF,iCAAiC,CAClC,CAAA;IACH,CAAC;IAED,iGAAiG;IACzF,KAAK,CAAC,KAAK,CACjB,UAA8B,EAC9B,MAAqB,EACrB,MAAqB;QAErB,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;YACpE,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;QACrE,CAAC;QACD,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;IACrC,CAAC;IAED,8EAA8E;IACtE,KAAK,CAAC,IAAI,CAChB,UAA8B,EAC9B,KAAwB,EACxB,MAAqB;QAErB,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QACtC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;QACnE,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAA;QACtD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC7D,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;QACnE,OAAO,EAAE,GAAG,UAAU,EAAE,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;IACvG,CAAC;IAEO,UAAU,CAAC,UAA8B,EAAE,OAAyB,EAAE,WAAoB;QAChG,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAM;QACzC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC7B,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;QACrE,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAA;QAC1I,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAA;IAChE,CAAC;CACF"}
@@ -61,6 +61,8 @@ export interface LoadedRuleMeta {
61
61
  * currently-loaded rule without re-reading the directory from disk. */
62
62
  bytes: Uint8Array;
63
63
  }
64
+ /** Why a module did not compile or load: the reasons a compile can reach, never a missing binary or a hash mismatch. */
65
+ export type CompileFailureReason = Exclude<RuleLoadFailureReason, 'missing' | 'hash_mismatch'>;
64
66
  export type CompileOutcome = {
65
67
  ok: true;
66
68
  readsReferencedFiles: boolean;
@@ -70,7 +72,7 @@ export type CompileOutcome = {
70
72
  | {
71
73
  ok: false;
72
74
  error: string;
73
- reason: RuleLoadFailureReason;
75
+ reason: CompileFailureReason;
74
76
  unsupportedImports?: string[];
75
77
  };
76
78
  /** What `WasmLoader` needs from the worker to load/unload a rule — implemented by `WasmRunner`. */
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/wasm/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAKlE,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,QAAmB,CAAA;AAEnD,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9D;AAOD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAWlF;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAsBrF;AAWD,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,4GAA4G;IAC5G,IAAI,EAAE,OAAO,CAAA;IACb;4EACwE;IACxE,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,oBAAoB,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE;AAC5D,2GAA2G;GACzG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAE9F,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACnE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED;;;;GAIG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,MAAM,CAAoC;gBAErB,GAAG,EAAE,MAAM;IAExC,MAAM,IAAI,MAAM;IAIhB,0FAA0F;IAC1F,QAAQ,IAAI,cAAc,EAAE;IAI5B;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAiFlE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/wasm/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAKlE,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,QAAmB,CAAA;AAEnD,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9D;AAOD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAWlF;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAsBrF;AAWD,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,4GAA4G;IAC5G,IAAI,EAAE,OAAO,CAAA;IACb;4EACwE;IACxE,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,wHAAwH;AACxH,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,EAAE,SAAS,GAAG,eAAe,CAAC,CAAA;AAE9F,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,oBAAoB,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE;AAC5D,2GAA2G;GACzG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAE7F,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACnE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED;;;;GAIG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,MAAM,CAAoC;gBAErB,GAAG,EAAE,MAAM;IAExC,MAAM,IAAI,MAAM;IAIhB,0FAA0F;IAC1F,QAAQ,IAAI,cAAc,EAAE;IAI5B;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAiFlE"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/wasm/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/wasm/loader.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,17 @@
1
1
  /**
2
2
  * wasm/runner.ts — WasmRunner: owns the one dedicated `worker_threads`
3
- * Worker (worker.ts), the local-rules loader (loader.ts), and the
4
- * evaluate-all-rules union logic ported from
5
- * `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner` (most-restrictive-
6
- * wins, short-circuit on a block, carry the first reask through).
3
+ * Worker (worker.ts), the local-rules loader (loader.ts), the workspace's
4
+ * control-plane rules (cloudRules.ts), and the evaluate-all-rules union logic
5
+ * ported from `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner`
6
+ * (most-restrictive-wins, short-circuit on a block, carry the first reask
7
+ * through).
8
+ *
9
+ * Both sources run as one list in priority order, lower first; on a tie a
10
+ * control-plane rule runs before a local one, as in `registry.rs`. Local rules
11
+ * are `local:<file name>`; a control-plane rule keeps the control plane's id,
12
+ * the one the LLM proxy and the dashboard name it by. A control-plane rule in
13
+ * `SHADOW` mode is evaluated like any other and logged, and never decides the
14
+ * call — not even when it reaches no verdict.
7
15
  *
8
16
  * ## Divergences from the Rust runner (all recorded as TD entries)
9
17
  *
@@ -35,7 +43,9 @@
35
43
  *
36
44
  * @module
37
45
  */
38
- import { type CompileBridge, type CompileOutcome } from './loader.js';
46
+ import type { WasmRuleDescriptor } from '@intutic/shared-types';
47
+ import { type CompileOutcome } from './loader.js';
48
+ import type { CloudRuleBridge, CloudRuleSet } from './cloudRules.js';
39
49
  import { type WasmContextInput } from './context.js';
40
50
  /**
41
51
  * A native rule's deadline: a backstop for stalls the instruction budget
@@ -98,7 +108,18 @@ export type WasmVerdict = {
98
108
  ruleId: string;
99
109
  stop: RuleStop;
100
110
  };
101
- export declare class WasmRunner implements CompileBridge {
111
+ /**
112
+ * One shadowed rule's outcome on one call, as the LLM proxy reports it on a
113
+ * trace (`registry.rs`'s `ShadowReport`): the bypasses are reported too,
114
+ * because they are the denominator promotion divides by.
115
+ */
116
+ export interface ShadowReport {
117
+ ruleId: string;
118
+ /** False when the rule allowed the call; true for a block, a reask, a hold, or no verdict. */
119
+ wouldAct: boolean;
120
+ }
121
+ export declare class WasmRunner implements CloudRuleBridge {
122
+ private readonly cloud?;
102
123
  private readonly loader;
103
124
  private worker;
104
125
  private nextRequestId;
@@ -107,17 +128,43 @@ export declare class WasmRunner implements CompileBridge {
107
128
  /** The worker replacing one that missed a deadline, while its rules recompile. */
108
129
  private respawning;
109
130
  private quarantined;
110
- constructor(dirOverride?: string);
131
+ /**
132
+ * @param dirOverride - the local rules directory (see `resolveWasmDir`).
133
+ * @param cloud - the workspace's control-plane rules; absent where there is
134
+ * no control plane to fetch them from (tests, local-only use).
135
+ */
136
+ constructor(dirOverride?: string, cloud?: CloudRuleSet | undefined);
111
137
  /** The resolved local rules directory, for logging. */
112
138
  getDir(): string;
113
- /** Currently loaded rule ids (`local:<file name>`), priority order — observability for callers/tests. */
139
+ /** Currently loaded rule ids, in evaluation order — observability for callers/tests. */
114
140
  getLoadedRuleIds(): string[];
141
+ /**
142
+ * Every loaded rule in evaluation order: by priority, and on a tie the
143
+ * control-plane rules first (a stable sort over cloud-then-local, as
144
+ * `registry.rs` sorts).
145
+ */
146
+ private activeRules;
147
+ /**
148
+ * Brings the control-plane rules in line with the descriptors the policy
149
+ * carries. `undefined` — no policy from the control plane yet — leaves them
150
+ * as they are. See `CloudRuleSet.sync` for when this waits.
151
+ */
152
+ syncCloudRules(descriptors: readonly WasmRuleDescriptor[] | undefined): Promise<void>;
153
+ /**
154
+ * Whether the workspace's control-plane rules are known: a descriptor list
155
+ * has been applied (or this runner has no control plane to ask). Until then,
156
+ * a call is judged without them, which the interceptor allows only under
157
+ * the fail-open setting.
158
+ */
159
+ cloudRulesLoaded(): boolean;
115
160
  private ensureWorker;
116
161
  /** Send one message and wait for its correlated reply, or `null` on timeout. */
117
162
  private send;
118
163
  private allocId;
119
164
  compile(ruleId: string, bytes: Uint8Array): Promise<CompileOutcome>;
120
165
  remove(ruleId: string): void;
166
+ /** A control-plane rule's version changed: the old version's runaways do not count against the new one. */
167
+ replaced(ruleId: string): void;
121
168
  /**
122
169
  * Rescans `~/.intutic/wasm/` and (re)compiles anything changed. Also
123
170
  * releases every quarantined rule — "quarantined until the next
@@ -154,8 +201,15 @@ export declare class WasmRunner implements CompileBridge {
154
201
  *
155
202
  * A quarantined rule (see {@link countRunaway}) refuses at once, without
156
203
  * anything being evaluated, until the next rescan.
204
+ *
205
+ * A `SHADOW` rule is evaluated in its place and decides nothing: what it
206
+ * would have done, a refusal for reaching no verdict included, leaves the
207
+ * call as the other rules decide it. Each evaluation is appended to
208
+ * `shadowOut`, the evidence promotion out of shadow is judged on, and a
209
+ * would-act is logged. A quarantined one is skipped, and reported as
210
+ * nothing, since nothing ran.
157
211
  */
158
- evaluate(input: WasmContextInput): Promise<WasmVerdict>;
212
+ evaluate(input: WasmContextInput, shadowOut?: ShadowReport[]): Promise<WasmVerdict>;
159
213
  /**
160
214
  * The referenced-files table for this evaluation. With no
161
215
  * `INTUTIC_WASM_MANIFEST_ROOT` the table is empty and every read refuses.
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/wasm/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAOH,OAAO,EAA8B,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAoC,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAKtF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,OAAQ,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAA;AAM9C;;;GAGG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAA;AAEjF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACnD,qFAAqF;GACnF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AACrE;;;GAGG;GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAA;AAoD3E,qBAAa,UAAW,YAAW,aAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,mBAAmB,CAA4B;IACvD,kFAAkF;IAClF,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,WAAW,CAAoB;gBAE3B,WAAW,CAAC,EAAE,MAAM;IAIhC,uDAAuD;IACvD,MAAM,IAAI,MAAM;IAIhB,yGAAyG;IACzG,gBAAgB,IAAI,MAAM,EAAE;IAI5B,OAAO,CAAC,YAAY;IAmBpB,gFAAgF;IAChF,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,OAAO;IAQT,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IA0BzE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ5B;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAO7B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,aAAa;IA0BrB;;;;;;;;;;;;;;;;;;OAkBG;IACG,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IA2G7D;;;OAGG;YACW,uBAAuB;IAUrC,6FAA6F;YAC/E,WAAW;IA8DzB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAYpB,yEAAyE;IACnE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAUhC;AAyBD,YAAY,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/wasm/runner.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,17 @@
1
1
  /**
2
2
  * wasm/runner.ts — WasmRunner: owns the one dedicated `worker_threads`
3
- * Worker (worker.ts), the local-rules loader (loader.ts), and the
4
- * evaluate-all-rules union logic ported from
5
- * `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner` (most-restrictive-
6
- * wins, short-circuit on a block, carry the first reask through).
3
+ * Worker (worker.ts), the local-rules loader (loader.ts), the workspace's
4
+ * control-plane rules (cloudRules.ts), and the evaluate-all-rules union logic
5
+ * ported from `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner`
6
+ * (most-restrictive-wins, short-circuit on a block, carry the first reask
7
+ * through).
8
+ *
9
+ * Both sources run as one list in priority order, lower first; on a tie a
10
+ * control-plane rule runs before a local one, as in `registry.rs`. Local rules
11
+ * are `local:<file name>`; a control-plane rule keeps the control plane's id,
12
+ * the one the LLM proxy and the dashboard name it by. A control-plane rule in
13
+ * `SHADOW` mode is evaluated like any other and logged, and never decides the
14
+ * call — not even when it reaches no verdict.
7
15
  *
8
16
  * ## Divergences from the Rust runner (all recorded as TD entries)
9
17
  *
@@ -107,6 +115,7 @@ function workerScriptSpec() {
107
115
  return { url, execArgv: isSource ? ['--import', 'tsx/esm'] : [] };
108
116
  }
109
117
  export class WasmRunner {
118
+ cloud;
110
119
  loader;
111
120
  worker = null;
112
121
  nextRequestId = 1;
@@ -115,16 +124,64 @@ export class WasmRunner {
115
124
  /** The worker replacing one that missed a deadline, while its rules recompile. */
116
125
  respawning = null;
117
126
  quarantined = new Set();
118
- constructor(dirOverride) {
127
+ /**
128
+ * @param dirOverride - the local rules directory (see `resolveWasmDir`).
129
+ * @param cloud - the workspace's control-plane rules; absent where there is
130
+ * no control plane to fetch them from (tests, local-only use).
131
+ */
132
+ constructor(dirOverride, cloud) {
133
+ this.cloud = cloud;
119
134
  this.loader = new WasmLoader(resolveWasmDir(dirOverride));
120
135
  }
121
136
  /** The resolved local rules directory, for logging. */
122
137
  getDir() {
123
138
  return this.loader.getDir();
124
139
  }
125
- /** Currently loaded rule ids (`local:<file name>`), priority order — observability for callers/tests. */
140
+ /** Currently loaded rule ids, in evaluation order — observability for callers/tests. */
126
141
  getLoadedRuleIds() {
127
- return this.loader.getRules().map((r) => r.ruleId);
142
+ return this.activeRules().map((r) => r.ruleId);
143
+ }
144
+ /**
145
+ * Every loaded rule in evaluation order: by priority, and on a tie the
146
+ * control-plane rules first (a stable sort over cloud-then-local, as
147
+ * `registry.rs` sorts).
148
+ */
149
+ activeRules() {
150
+ const cloud = (this.cloud?.getRules() ?? []).map((r) => ({
151
+ ruleId: r.ruleId,
152
+ priority: r.priority,
153
+ rego: r.rego,
154
+ readsReferencedFiles: r.readsReferencedFiles,
155
+ shadow: r.mode === 'SHADOW',
156
+ }));
157
+ const local = this.loader.getRules().map((r) => ({
158
+ ruleId: r.ruleId,
159
+ priority: r.priority,
160
+ rego: r.rego,
161
+ readsReferencedFiles: r.readsReferencedFiles,
162
+ shadow: false,
163
+ }));
164
+ return [...cloud, ...local].sort((a, b) => a.priority - b.priority);
165
+ }
166
+ /**
167
+ * Brings the control-plane rules in line with the descriptors the policy
168
+ * carries. `undefined` — no policy from the control plane yet — leaves them
169
+ * as they are. See `CloudRuleSet.sync` for when this waits.
170
+ */
171
+ async syncCloudRules(descriptors) {
172
+ if (!this.cloud || !descriptors)
173
+ return;
174
+ await this.respawning;
175
+ await this.cloud.sync(descriptors, this);
176
+ }
177
+ /**
178
+ * Whether the workspace's control-plane rules are known: a descriptor list
179
+ * has been applied (or this runner has no control plane to ask). Until then,
180
+ * a call is judged without them, which the interceptor allows only under
181
+ * the fail-open setting.
182
+ */
183
+ cloudRulesLoaded() {
184
+ return !this.cloud || this.cloud.isLoaded();
128
185
  }
129
186
  ensureWorker() {
130
187
  if (this.worker)
@@ -185,6 +242,10 @@ export class WasmRunner {
185
242
  }
186
243
  remove(ruleId) {
187
244
  this.ensureWorker().postMessage({ type: 'remove', ruleId });
245
+ this.replaced(ruleId);
246
+ }
247
+ /** A control-plane rule's version changed: the old version's runaways do not count against the new one. */
248
+ replaced(ruleId) {
188
249
  this.consecutiveRunaways.delete(ruleId);
189
250
  this.quarantined.delete(ruleId);
190
251
  }
@@ -228,8 +289,11 @@ export class WasmRunner {
228
289
  }
229
290
  // Force-reload every currently-known file into the new worker — its
230
291
  // module cache started empty. `force: true` mirrors this loader's own
231
- // "worker cache was lost, nothing on disk moved" case.
232
- const respawning = this.loader.rescan(this, true).finally(() => {
292
+ // "worker cache was lost, nothing on disk moved" case. The control-plane
293
+ // rules recompile from the bytes they were fetched with.
294
+ const respawning = Promise.all([this.loader.rescan(this, true), this.cloud?.reload(this)])
295
+ .then(() => undefined)
296
+ .finally(() => {
233
297
  if (this.respawning === respawning)
234
298
  this.respawning = null;
235
299
  });
@@ -254,10 +318,17 @@ export class WasmRunner {
254
318
  *
255
319
  * A quarantined rule (see {@link countRunaway}) refuses at once, without
256
320
  * anything being evaluated, until the next rescan.
321
+ *
322
+ * A `SHADOW` rule is evaluated in its place and decides nothing: what it
323
+ * would have done, a refusal for reaching no verdict included, leaves the
324
+ * call as the other rules decide it. Each evaluation is appended to
325
+ * `shadowOut`, the evidence promotion out of shadow is judged on, and a
326
+ * would-act is logged. A quarantined one is skipped, and reported as
327
+ * nothing, since nothing ran.
257
328
  */
258
- async evaluate(input) {
259
- const rules = this.loader.getRules();
260
- const held = rules.find((r) => this.quarantined.has(r.ruleId));
329
+ async evaluate(input, shadowOut) {
330
+ const rules = this.activeRules();
331
+ const held = rules.find((r) => !r.shadow && this.quarantined.has(r.ruleId));
261
332
  if (held) {
262
333
  return {
263
334
  code: 'unavailable',
@@ -281,8 +352,18 @@ export class WasmRunner {
281
352
  // deadline covers guest execution only — and only when a rule will ask.
282
353
  const files = rules.some((r) => r.readsReferencedFiles) ? await this.prefetchReferencedFiles(input) : undefined;
283
354
  for (const rule of rules) {
355
+ if (rule.shadow && this.quarantined.has(rule.ruleId))
356
+ continue;
284
357
  const outcome = await this.evaluateOne(rule.ruleId, bytesFor(rule.rego), rule.rego ? REGO_EVALUATE_TIMEOUT_MS : EVALUATE_TIMEOUT_MS, rule.readsReferencedFiles ? files : undefined);
285
358
  const failure = 'stop' in outcome ? outcome : undefinedVerdict(outcome);
359
+ if (rule.shadow) {
360
+ // A rule that reached no verdict would have refused the call, so it
361
+ // counts as acting, as the LLM proxy counts its `Unavailable`.
362
+ const wouldDo = failure ? `no verdict (${failure.stop}): ${failure.detail}` : describeResult(outcome);
363
+ logShadow(rule.ruleId, wouldDo);
364
+ shadowOut?.push({ ruleId: rule.ruleId, wouldAct: wouldDo !== undefined });
365
+ continue;
366
+ }
286
367
  if (failure) {
287
368
  const quarantinedNow = this.quarantined.has(rule.ruleId);
288
369
  const detail = quarantinedNow
@@ -422,6 +503,20 @@ export class WasmRunner {
422
503
  await worker.terminate();
423
504
  }
424
505
  }
506
+ /** What a rule's answer would do to the call, for the shadow log; `undefined` when it allows. */
507
+ function describeResult(result) {
508
+ if ('decision' in result)
509
+ return result.decision === 'allow' ? undefined : result.decision;
510
+ if (result.code === 0)
511
+ return undefined;
512
+ return result.code === 3 ? 'reask' : 'block';
513
+ }
514
+ /** A shadowed rule's outcome, logged when it would have acted. */
515
+ function logShadow(ruleId, wouldDo) {
516
+ if (wouldDo === undefined)
517
+ return;
518
+ log.info({ action: 'wasm_shadow_would_act', ruleId, shadowed: true, verdict: wouldDo }, 'WASM rule would have acted; shadow mode, call unchanged');
519
+ }
425
520
  /** A native code that is not a verdict: the rule reached none. */
426
521
  function undefinedVerdict(result) {
427
522
  if ('decision' in result || [0, 1, 2, 3].includes(result.code))