@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.
- package/README.md +1 -1
- package/dist/agentTools.d.ts +15 -0
- package/dist/agentTools.d.ts.map +1 -1
- package/dist/agentTools.js +21 -1
- package/dist/agentTools.js.map +1 -1
- package/dist/chaos.d.ts +90 -0
- package/dist/chaos.d.ts.map +1 -0
- package/dist/chaos.js +174 -0
- package/dist/chaos.js.map +1 -0
- package/dist/daemon/policyCache.d.ts +7 -0
- package/dist/daemon/policyCache.d.ts.map +1 -1
- package/dist/daemon/policyCache.js +2 -0
- package/dist/daemon/policyCache.js.map +1 -1
- package/dist/emitter.d.ts +40 -2
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +7 -1
- package/dist/emitter.js.map +1 -1
- package/dist/httpJson.d.ts +7 -0
- package/dist/httpJson.d.ts.map +1 -1
- package/dist/httpJson.js +39 -0
- package/dist/httpJson.js.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptor.d.ts +24 -0
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +58 -11
- package/dist/interceptor.js.map +1 -1
- package/dist/policy.d.ts +26 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +49 -3
- package/dist/policy.js.map +1 -1
- package/dist/proxy.d.ts +32 -6
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +107 -55
- package/dist/proxy.js.map +1 -1
- package/dist/refusals.d.ts +25 -0
- package/dist/refusals.d.ts.map +1 -1
- package/dist/refusals.js +50 -0
- package/dist/refusals.js.map +1 -1
- package/dist/remoteBridge.d.ts +2 -1
- package/dist/remoteBridge.d.ts.map +1 -1
- package/dist/remoteBridge.js +4 -3
- package/dist/remoteBridge.js.map +1 -1
- package/dist/wasm/cloudRules.d.ts +138 -0
- package/dist/wasm/cloudRules.d.ts.map +1 -0
- package/dist/wasm/cloudRules.js +242 -0
- package/dist/wasm/cloudRules.js.map +1 -0
- package/dist/wasm/loader.d.ts +3 -1
- package/dist/wasm/loader.d.ts.map +1 -1
- package/dist/wasm/loader.js.map +1 -1
- package/dist/wasm/runner.d.ts +63 -9
- package/dist/wasm/runner.d.ts.map +1 -1
- package/dist/wasm/runner.js +107 -12
- package/dist/wasm/runner.js.map +1 -1
- 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":"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"}
|
package/dist/wasm/loader.d.ts
CHANGED
|
@@ -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:
|
|
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,
|
|
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"}
|
package/dist/wasm/loader.js.map
CHANGED
|
@@ -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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"}
|
package/dist/wasm/runner.d.ts
CHANGED
|
@@ -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),
|
|
4
|
-
* evaluate-all-rules union logic
|
|
5
|
-
* `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner`
|
|
6
|
-
* wins, short-circuit on a block, carry the first reask
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/wasm/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/wasm/runner.js
CHANGED
|
@@ -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),
|
|
4
|
-
* evaluate-all-rules union logic
|
|
5
|
-
* `packages/proxy/src/wasm/registry.rs`'s `evaluate_inner`
|
|
6
|
-
* wins, short-circuit on a block, carry the first reask
|
|
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
|
-
|
|
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
|
|
140
|
+
/** Currently loaded rule ids, in evaluation order — observability for callers/tests. */
|
|
126
141
|
getLoadedRuleIds() {
|
|
127
|
-
return this.
|
|
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
|
-
|
|
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.
|
|
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))
|