@nekzus/liop 2.6.1 → 2.7.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 (109) hide show
  1. package/README.md +85 -38
  2. package/dist/bin/agent.js +27 -894
  3. package/dist/bridge.d.ts +4 -3
  4. package/dist/bridge.js +1 -4
  5. package/dist/chunk-2XHSALII.js +3 -0
  6. package/dist/chunk-2ZYX736J.js +2 -0
  7. package/dist/chunk-3WRKTVOF.js +2 -0
  8. package/dist/chunk-6KFKO6ZX.js +2 -0
  9. package/dist/chunk-6VK2XALI.js +2 -0
  10. package/dist/chunk-AYDF3IFZ.js +2 -0
  11. package/dist/chunk-CTTTLCGL.js +31 -0
  12. package/dist/chunk-ECRS6N33.js +4 -0
  13. package/dist/chunk-FDJMH4CB.js +2 -0
  14. package/dist/chunk-FTF6AMF6.js +0 -1
  15. package/dist/chunk-GWVSCZUS.js +2 -0
  16. package/dist/chunk-LEXMMIQI.js +15 -0
  17. package/dist/chunk-LM26HOJ6.js +31 -0
  18. package/dist/chunk-MQ5SU26J.js +2 -0
  19. package/dist/chunk-N35BC62H.js +2 -0
  20. package/dist/chunk-P6IJ3VBD.js +3 -0
  21. package/dist/chunk-TKLRW52V.js +2 -0
  22. package/dist/chunk-V35CXJQN.js +2 -0
  23. package/dist/chunk-WP5ER7RH.js +3 -0
  24. package/dist/chunk-XLVEDKM6.js +2 -0
  25. package/dist/chunk-Y675R34Z.js +2 -0
  26. package/dist/chunk-YD2AF2M6.js +46 -0
  27. package/dist/chunk-YLCNV764.js +3 -0
  28. package/dist/chunk-ZZMSFCJP.js +3 -0
  29. package/dist/client.d.ts +5 -4
  30. package/dist/client.js +1 -11
  31. package/dist/gateway.d.ts +6 -5
  32. package/dist/gateway.js +1 -11
  33. package/dist/{hybrid-DWe1bMoV.d.ts → hybrid-BZpCiUaV.d.ts} +4 -4
  34. package/dist/{index-BuEQtBHD.d.ts → index-BYDtRGue.d.ts} +8 -4
  35. package/dist/{index-CdW8j8Bn.d.ts → index-ByzjpRCk.d.ts} +30 -2
  36. package/dist/index.d.ts +57 -10
  37. package/dist/index.js +4 -317
  38. package/dist/kyber-PULV7PQX.js +2 -0
  39. package/dist/mesh.d.ts +1 -1
  40. package/dist/mesh.js +1 -5
  41. package/dist/{node-B0b2vUFS.d.ts → node-Djzm6UYd.d.ts} +8 -0
  42. package/dist/protocol/liop_core.proto +22 -6
  43. package/dist/server.d.ts +4 -3
  44. package/dist/server.js +1 -8
  45. package/dist/{types-CzRSOlOo.d.ts → types-29zv9X1V.d.ts} +3 -0
  46. package/dist/types.d.ts +2 -1
  47. package/dist/types.js +1 -2
  48. package/dist/verifier-DqZ9MQ9l.d.ts +82 -0
  49. package/dist/verifier-J4NQYZX5.js +2 -0
  50. package/dist/workers/logic-execution.d.ts +7 -0
  51. package/dist/workers/logic-execution.js +1 -271
  52. package/dist/workers/zk-verifier.d.ts +9 -0
  53. package/dist/workers/zk-verifier.js +1 -173
  54. package/dist/zk-DzYNWBgo.d.ts +104 -0
  55. package/package.json +7 -2
  56. package/dist/bin/agent.js.map +0 -1
  57. package/dist/bridge.js.map +0 -1
  58. package/dist/chunk-2KSO3W4A.js +0 -77
  59. package/dist/chunk-2KSO3W4A.js.map +0 -1
  60. package/dist/chunk-2STZHJ24.js +0 -114
  61. package/dist/chunk-2STZHJ24.js.map +0 -1
  62. package/dist/chunk-3QH44NKZ.js +0 -115
  63. package/dist/chunk-3QH44NKZ.js.map +0 -1
  64. package/dist/chunk-5SWHE62F.js +0 -3683
  65. package/dist/chunk-5SWHE62F.js.map +0 -1
  66. package/dist/chunk-7BSCUYUE.js +0 -421
  67. package/dist/chunk-7BSCUYUE.js.map +0 -1
  68. package/dist/chunk-7PITYWOV.js +0 -68
  69. package/dist/chunk-7PITYWOV.js.map +0 -1
  70. package/dist/chunk-EJ426URA.js +0 -818
  71. package/dist/chunk-EJ426URA.js.map +0 -1
  72. package/dist/chunk-FCFTYOAS.js +0 -793
  73. package/dist/chunk-FCFTYOAS.js.map +0 -1
  74. package/dist/chunk-FTF6AMF6.js.map +0 -1
  75. package/dist/chunk-IK7CGWAZ.js +0 -24
  76. package/dist/chunk-IK7CGWAZ.js.map +0 -1
  77. package/dist/chunk-K3DGJLUY.js +0 -106
  78. package/dist/chunk-K3DGJLUY.js.map +0 -1
  79. package/dist/chunk-PAICJCKJ.js +0 -332
  80. package/dist/chunk-PAICJCKJ.js.map +0 -1
  81. package/dist/chunk-PUDETPL4.js +0 -279
  82. package/dist/chunk-PUDETPL4.js.map +0 -1
  83. package/dist/chunk-UJFWPRDM.js +0 -206884
  84. package/dist/chunk-UJFWPRDM.js.map +0 -1
  85. package/dist/chunk-VRB5HUYU.js +0 -1492
  86. package/dist/chunk-VRB5HUYU.js.map +0 -1
  87. package/dist/chunk-VRDZ5IKE.js +0 -558
  88. package/dist/chunk-VRDZ5IKE.js.map +0 -1
  89. package/dist/chunk-WPTOJYN5.js +0 -181
  90. package/dist/chunk-WPTOJYN5.js.map +0 -1
  91. package/dist/chunk-XRDN232O.js +0 -877
  92. package/dist/chunk-XRDN232O.js.map +0 -1
  93. package/dist/chunk-Y62GORQF.js +0 -51
  94. package/dist/chunk-Y62GORQF.js.map +0 -1
  95. package/dist/chunk-ZP3VVXOI.js +0 -66
  96. package/dist/chunk-ZP3VVXOI.js.map +0 -1
  97. package/dist/client.js.map +0 -1
  98. package/dist/gateway.js.map +0 -1
  99. package/dist/index.js.map +0 -1
  100. package/dist/kyber-CGOA7Q6A.js +0 -3
  101. package/dist/kyber-CGOA7Q6A.js.map +0 -1
  102. package/dist/mesh.js.map +0 -1
  103. package/dist/server.js.map +0 -1
  104. package/dist/types.js.map +0 -1
  105. package/dist/verifier-COnid_dg.d.ts +0 -31
  106. package/dist/verifier-XFU7ZB2W.js +0 -6
  107. package/dist/verifier-XFU7ZB2W.js.map +0 -1
  108. package/dist/workers/logic-execution.js.map +0 -1
  109. package/dist/workers/zk-verifier.js.map +0 -1
@@ -1,272 +1,2 @@
1
- import { ASTGuardian, WasiSandbox } from '../chunk-7BSCUYUE.js';
2
- import { sanitizeOutput } from '../chunk-Y62GORQF.js';
3
- import { normalizeLogicSource, deriveLogicImageDigest } from '../chunk-IK7CGWAZ.js';
4
- import { Buffer } from 'buffer';
5
- import crypto2 from 'crypto';
6
- import { createMlKem768 } from 'mlkem';
7
-
8
- var DEFAULT_DP_CONFIG = {
9
- epsilon: 1,
10
- sensitivity: 1,
11
- smallDatasetThreshold: 50
12
- };
13
- var EPSILON_FLOOR = 1;
14
- var EPSILON_FLOOR_THRESHOLD = 10;
15
- function laplaceSample(scale, prngState) {
16
- let u;
17
- do {
18
- if (prngState) {
19
- const hash = crypto2.createHash("sha256").update(`${prngState.seed}:${prngState.counter++}`).digest();
20
- u = hash.readUInt32BE(0) / 4294967296 - 0.5;
21
- } else {
22
- const buf = crypto2.randomBytes(4);
23
- const rawVal = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
24
- const cleanVal = Number.parseInt(rawVal.toString(10), 10);
25
- u = cleanVal / 4294967296;
26
- }
27
- } while (u === 0 || u === -0.5);
28
- return -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
29
- }
30
- function addLaplaceNoise(value, config = {}, prngState) {
31
- const merged = { ...DEFAULT_DP_CONFIG, ...config };
32
- const scale = merged.sensitivity / merged.epsilon;
33
- const noisyValue = value + laplaceSample(scale, prngState);
34
- return Math.round(noisyValue * 1e4) / 1e4;
35
- }
36
- function deriveFieldSensitivity(key, globalSensitivity, recordCount) {
37
- if (!key) return globalSensitivity;
38
- const lk = key.toLowerCase();
39
- const isCountWord = /count|length|size|num|gainer|loser|positive|negative|nan_|null_|empty_|finite_|non_finite_|instruments|tickers|users|records/i.test(
40
- lk
41
- );
42
- const isTotalCount = lk === "total" || lk === "n" || lk === "total_records" || lk.startsWith("total_") || // Catch total_tickers, total_users
43
- lk.startsWith("num_") || // Catch num_records, num_ticks
44
- /total.*(count|items|entries|rows|records|tickers)/i.test(lk);
45
- if (isCountWord || isTotalCount) return 1;
46
- if (/avg|mean|average|var|variance|std|stddev|ratio|bps|drift|pct|percent|imbalance/i.test(
47
- lk
48
- ) && recordCount > 0) {
49
- return globalSensitivity / recordCount;
50
- }
51
- return globalSensitivity;
52
- }
53
- function applyDpToOutput(output, config = {}, recordCount) {
54
- const merged = { ...DEFAULT_DP_CONFIG, ...config };
55
- if (recordCount >= merged.smallDatasetThreshold) {
56
- return output;
57
- }
58
- if (recordCount < EPSILON_FLOOR_THRESHOLD && merged.epsilon < EPSILON_FLOOR) {
59
- merged.epsilon = EPSILON_FLOOR;
60
- }
61
- let prngState;
62
- if (merged.seed) {
63
- prngState = { seed: merged.seed, counter: 0 };
64
- }
65
- return walkAndNoise(output, merged, recordCount, void 0, prngState);
66
- }
67
- function walkAndNoise(node, config, recordCount, currentKey, prngState) {
68
- if (typeof node === "number" && Number.isFinite(node)) {
69
- const fieldSensitivity = deriveFieldSensitivity(
70
- currentKey,
71
- config.sensitivity,
72
- recordCount
73
- );
74
- let noisyValue = addLaplaceNoise(
75
- node,
76
- {
77
- ...config,
78
- sensitivity: fieldSensitivity
79
- },
80
- prngState
81
- );
82
- const isCountKey = currentKey != null && deriveFieldSensitivity(currentKey, config.sensitivity, recordCount) === 1;
83
- if (Number.isInteger(node) || isCountKey) {
84
- noisyValue = Math.round(noisyValue);
85
- }
86
- if (node >= 0) {
87
- noisyValue = Math.max(0, noisyValue);
88
- }
89
- return noisyValue;
90
- }
91
- if (Array.isArray(node)) {
92
- return node.map(
93
- (item) => walkAndNoise(item, config, recordCount, currentKey, prngState)
94
- );
95
- }
96
- if (node !== null && typeof node === "object") {
97
- const result = {};
98
- for (const [key, value] of Object.entries(
99
- node
100
- )) {
101
- result[key] = walkAndNoise(value, config, recordCount, key, prngState);
102
- }
103
- return result;
104
- }
105
- return node;
106
- }
107
-
108
- // src/workers/logic-execution.ts
109
- async function processLogicExecution(data) {
110
- if (typeof Object.prototype === "object" && !Object.isFrozen(Object.prototype)) {
111
- Object.freeze(Object.prototype);
112
- Object.freeze(Array.prototype);
113
- Object.freeze(String.prototype);
114
- Object.freeze(Number.prototype);
115
- Object.freeze(Boolean.prototype);
116
- Object.freeze(RegExp.prototype);
117
- Object.freeze(Map.prototype);
118
- Object.freeze(Set.prototype);
119
- Object.freeze(Promise.prototype);
120
- Object.freeze(Error.prototype);
121
- }
122
- if (data.isWarmup) {
123
- return {
124
- image_id: "",
125
- output: "warm",
126
- fuel_consumed: 0
127
- };
128
- }
129
- if (data.sessionTimestamp !== void 0) {
130
- const MAX_SESSION_KEY_LIFETIME_MS = 3600 * 1e3;
131
- const age = Date.now() - data.sessionTimestamp;
132
- if (age > MAX_SESSION_KEY_LIFETIME_MS) {
133
- throw new Error(
134
- `[LIOP-PQC] Session secret expired: Age (${Math.round(age / 1e3)}s) exceeds 3600s TTL limit.`
135
- );
136
- }
137
- if (data.sessionTimestamp > Date.now() + 6e4) {
138
- throw new Error(
139
- "[LIOP-PQC] Session secret invalid: Timestamp is in the future."
140
- );
141
- }
142
- }
143
- const {
144
- ciphertext,
145
- secretKeyObj,
146
- wasmBinary,
147
- inputs,
148
- aesNonce,
149
- records,
150
- isEncrypted = true,
151
- dpConfig
152
- } = data;
153
- let decryptedPayload;
154
- const decryptedInputs = {};
155
- let sessionSecret = Buffer.alloc(32);
156
- if (isEncrypted) {
157
- const sk = new Uint8Array(secretKeyObj);
158
- const ct = new Uint8Array(ciphertext);
159
- const kem = await createMlKem768();
160
- const sharedSecret = kem.decap(ct, sk);
161
- const aesKey = Buffer.from(sharedSecret);
162
- sessionSecret = aesKey;
163
- const wasmBuffer = Buffer.from(wasmBinary);
164
- const authTag = wasmBuffer.subarray(-16);
165
- const encryptedData = wasmBuffer.subarray(0, -16);
166
- const decipher = crypto2.createDecipheriv(
167
- "aes-256-gcm",
168
- aesKey,
169
- Buffer.from(aesNonce || new Uint8Array(12))
170
- );
171
- decipher.setAuthTag(authTag);
172
- let decrypted = decipher.update(encryptedData);
173
- decrypted = Buffer.concat([decrypted, decipher.final()]);
174
- decryptedPayload = decrypted;
175
- for (const [key, encValue] of Object.entries(inputs || {})) {
176
- const valBuffer = Buffer.from(encValue);
177
- const inputNonce = valBuffer.subarray(0, 12);
178
- const valTag = valBuffer.subarray(-16);
179
- const valData = valBuffer.subarray(12, -16);
180
- const valDecipher = crypto2.createDecipheriv(
181
- "aes-256-gcm",
182
- aesKey,
183
- inputNonce
184
- );
185
- valDecipher.setAuthTag(valTag);
186
- let valDecrypted = valDecipher.update(valData);
187
- valDecrypted = Buffer.concat([valDecrypted, valDecipher.final()]);
188
- decryptedInputs[key] = JSON.parse(valDecrypted.toString("utf-8"));
189
- }
190
- } else {
191
- if (wasmBinary[0] === 0 && wasmBinary[1] === 97 && wasmBinary[2] === 115 && wasmBinary[3] === 109) {
192
- decryptedPayload = Buffer.from(wasmBinary);
193
- } else {
194
- decryptedPayload = Buffer.from(wasmBinary).toString("utf-8");
195
- }
196
- }
197
- const isWasm = decryptedPayload[0] === 0 && decryptedPayload[1] === 97 && decryptedPayload[2] === 115 && decryptedPayload[3] === 109;
198
- if (decryptedPayload instanceof Buffer && isWasm) {
199
- const wasmBytes = new Uint8Array(decryptedPayload);
200
- const compiledModule = await WebAssembly.compile(wasmBytes);
201
- ASTGuardian.analyze(compiledModule);
202
- } else if (decryptedPayload instanceof Buffer && !isWasm) {
203
- decryptedPayload = decryptedPayload.toString("utf-8");
204
- }
205
- if (typeof decryptedPayload === "string") {
206
- decryptedPayload = normalizeLogicSource(decryptedPayload);
207
- }
208
- const sandbox = new WasiSandbox();
209
- await sandbox.init();
210
- try {
211
- const result = await sandbox.execute(
212
- decryptedPayload,
213
- records,
214
- decryptedInputs
215
- );
216
- let finalOutput = result.output;
217
- let logicBytes;
218
- if (typeof decryptedPayload === "string") {
219
- logicBytes = Buffer.from(decryptedPayload, "utf-8");
220
- } else {
221
- logicBytes = new Uint8Array(decryptedPayload);
222
- }
223
- const imageId = deriveLogicImageDigest(logicBytes).toString("hex");
224
- const datasetHash = crypto2.createHash("sha256").update(JSON.stringify(records || [])).digest("hex");
225
- if (dpConfig) {
226
- finalOutput = applyDpToOutput(
227
- finalOutput,
228
- {
229
- ...dpConfig,
230
- seed: `${datasetHash}:${imageId}`
231
- },
232
- records?.length || 0
233
- );
234
- }
235
- finalOutput = sanitizeOutput(finalOutput);
236
- const journal = Buffer.from(
237
- JSON.stringify({
238
- image_id: imageId,
239
- dataset_hash: datasetHash,
240
- output_hash: crypto2.createHash("sha256").update(
241
- typeof finalOutput === "string" ? finalOutput : finalOutput === void 0 ? "undefined" : JSON.stringify(finalOutput)
242
- ).digest("hex"),
243
- fuel: result.fuelConsumed,
244
- ts: Date.now()
245
- })
246
- );
247
- const seal = crypto2.createHmac("sha256", sessionSecret).update(journal).digest();
248
- const journalLen = Buffer.alloc(2);
249
- journalLen.writeUInt16BE(journal.length);
250
- const receiptBuf = Buffer.concat([
251
- Buffer.from([1]),
252
- // Receipt format v1
253
- journalLen,
254
- journal,
255
- seal
256
- // 32 bytes HMAC
257
- ]);
258
- const zkReceipt = receiptBuf.toString("base64");
259
- return {
260
- image_id: imageId,
261
- zk_receipt: zkReceipt,
262
- output: finalOutput,
263
- fuel_consumed: result.fuelConsumed
264
- };
265
- } finally {
266
- await sandbox.teardown();
267
- }
268
- }
269
-
270
- export { processLogicExecution as default };
271
- //# sourceMappingURL=logic-execution.js.map
1
+ import {a as a$1,d}from'../chunk-CTTTLCGL.js';import {a as a$3}from'../chunk-MQ5SU26J.js';import {a as a$2,b}from'../chunk-TKLRW52V.js';import {b as b$1}from'../chunk-2ZYX736J.js';import {f,h}from'../chunk-6VK2XALI.js';import {a}from'../chunk-AYDF3IFZ.js';import {Buffer}from'buffer';import m from'crypto';import {createMlKem768}from'mlkem';var Y={epsilon:1,sensitivity:1,smallDatasetThreshold:50},J=1,ee=10;function te(e,i){let o;do if(i)o=m.createHash("sha256").update(`${i.seed}:${i.counter++}`).digest().readUInt32BE(0)/4294967296-.5;else {let t=m.randomBytes(4),a=t[0]<<24|t[1]<<16|t[2]<<8|t[3];o=Number.parseInt(a.toString(10),10)/4294967296;}while(o===0||o===-0.5);return -e*Math.sign(o)*Math.log(1-2*Math.abs(o))}a(te,"laplaceSample");function re(e,i={},o){let t={...Y,...i},a=t.sensitivity/t.epsilon,c=e+te(a,o);return Math.round(c*1e4)/1e4}a(re,"addLaplaceNoise");function $(e,i,o){if(!e)return i;let t=e.toLowerCase(),a=/count|length|size|num|gainer|loser|positive|negative|nan_|null_|empty_|finite_|non_finite_|instruments|tickers|users|records/i.test(t),c=t==="total"||t==="n"||t==="total_records"||t.startsWith("total_")||t.startsWith("num_")||/total.*(count|items|entries|rows|records|tickers)/i.test(t);return a||c?1:/avg|mean|average|var|variance|std|stddev|ratio|bps|drift|pct|percent|imbalance/i.test(t)&&o>0?i/o:i}a($,"deriveFieldSensitivity");function Z(e,i={},o){let t={...Y,...i};if(o>=t.smallDatasetThreshold)return e;o<ee&&t.epsilon<J&&(t.epsilon=J);let a;return t.seed&&(a={seed:t.seed,counter:0}),R(e,t,o,void 0,a)}a(Z,"applyDpToOutput");function R(e,i,o,t,a){if(typeof e=="number"&&Number.isFinite(e)){let c=$(t,i.sensitivity,o),u=re(e,{...i,sensitivity:c},a),w=t!=null&&$(t,i.sensitivity,o)===1;return (Number.isInteger(e)||w)&&(u=Math.round(u)),e>=0&&(u=Math.max(0,u)),u}if(Array.isArray(e))return e.map(c=>R(c,i,o,t,a));if(e!==null&&typeof e=="object"){let c={};for(let[u,w]of Object.entries(e))c[u]=R(w,i,o,u,a);return c}return e}a(R,"walkAndNoise");async function oe(e){if(typeof Object.prototype=="object"&&!Object.isFrozen(Object.prototype)&&(Object.freeze(Object.prototype),Object.freeze(Array.prototype),Object.freeze(String.prototype),Object.freeze(Number.prototype),Object.freeze(Boolean.prototype),Object.freeze(RegExp.prototype),Object.freeze(Map.prototype),Object.freeze(Set.prototype),Object.freeze(Promise.prototype),Object.freeze(Error.prototype)),e.isWarmup)return {image_id:"",output:"warm",fuel_consumed:0};if(e.sessionTimestamp!==void 0){let n=Date.now()-e.sessionTimestamp;if(n>36e5)throw new Error(`[LIOP-PQC] Session secret expired: Age (${Math.round(n/1e3)}s) exceeds 3600s TTL limit.`);if(e.sessionTimestamp>Date.now()+6e4)throw new Error("[LIOP-PQC] Session secret invalid: Timestamp is in the future.")}let{ciphertext:i,secretKeyObj:o,wasmBinary:t,inputs:a,aesNonce:c,records:u,isEncrypted:w=true,dpConfig:z}=e,s,D={},C=Buffer.alloc(32);if(w){let p=new Uint8Array(o),n=new Uint8Array(i),g=(await createMlKem768()).decap(n,p),d=Buffer.from(g);C=d;let _=Buffer.from(t),k=_.subarray(-16),T=_.subarray(0,-16),A=m.createDecipheriv("aes-256-gcm",d,Buffer.from(c||new Uint8Array(12)));A.setAuthTag(k);let S=A.update(T);S=Buffer.concat([S,A.final()]),s=S;for(let[E,B]of Object.entries(a||{})){let y=Buffer.from(B),f=y.subarray(0,12),h=y.subarray(-16),x=y.subarray(12,-16),O=m.createDecipheriv("aes-256-gcm",d,f);O.setAuthTag(h);let v=O.update(x);v=Buffer.concat([v,O.final()]),D[E]=JSON.parse(v.toString("utf-8"));}}else t[0]===0&&t[1]===97&&t[2]===115&&t[3]===109?s=Buffer.from(t):s=Buffer.from(t).toString("utf-8");let K=s[0]===0&&s[1]===97&&s[2]===115&&s[3]===109;if(s instanceof Buffer&&K){let p=new Uint8Array(s),n=await WebAssembly.compile(p);a$1.analyze(n);}else s instanceof Buffer&&!K&&(s=s.toString("utf-8"));typeof s=="string"&&(s=a$2(s));let N=new d;await N.init();try{let p=await N.execute(s,u,D),n=p.output,I;typeof s=="string"?I=Buffer.from(s,"utf-8"):I=new Uint8Array(s);let g=b(I).toString("hex"),d=m.createHash("sha256").update(JSON.stringify(u||[])).digest("hex");if(z&&(n=Z(n,{...z,seed:`${d}:${g}`},u?.length||0)),n=a$3(n),e.proofMode===1||e.proofMode===2){let E=e.guestImageId?Buffer.from(e.guestImageId,"hex"):m.createHash("sha256").update("liop-default-guest-v2").digest(),B=typeof n=="string"?n:n===void 0?"undefined":JSON.stringify(n),y=f({guestImageId:E,logicDigest:Buffer.from(g,"hex"),datasetDigest:Buffer.from(d,"hex"),outputDigest:m.createHash("sha256").update(B).digest(),fuelConsumed:BigInt(p.fuelConsumed),executionTimestamp:BigInt(Date.now())}),f$1,h$1=null;try{h$1=await import('@nekzus/liop-zk-native');}catch{h$1=null;}if(h$1&&typeof h$1.prove_analytical_query=="function")try{let b=typeof D?.operation=="string"?D.operation:"sum",M=JSON.stringify({records:Array.isArray(u)?u.map(P=>Number(P.amount??P.value??1)):[1],expected_sum:typeof n=="number"?n:void 0});f$1=await h$1.prove_analytical_query(b,M);}catch(b){if(e.proofMode===2)throw new Error(`ZK PROOF GENERATION FAILED: Native Groth16 prover execution error: ${b instanceof Error?b.message:String(b)}`);f$1=Buffer.alloc(128,66);}else {if(e.proofMode===2)throw new Error("ZK PROOF GENERATION FAILED: Native Groth16 prover module unavailable for required policy.");f$1=Buffer.alloc(128,66);}let x,O=2;if(e.pqcSigningKey&&e.pqcSigningKey.length>0){O=3;let b=m.createHash("sha256").update(Buffer.concat([y,f$1])).digest(),M=b$1.sign(b,e.pqcSigningKey),P=b$1.getPublicKey(e.pqcSigningKey);x=h.encodeHybridV2(y,f$1,Buffer.from(M),Buffer.from(P));}else x=h.encodeV2(2,y,f$1);let v=x.toString("base64");return {image_id:g,zk_receipt:v,output:n,fuel_consumed:p.fuelConsumed,proof_type:O,guest_image_id:E.toString("hex")}}let _=Buffer.from(JSON.stringify({image_id:g,dataset_hash:d,output_hash:m.createHash("sha256").update(typeof n=="string"?n:n===void 0?"undefined":JSON.stringify(n)).digest("hex"),fuel:p.fuelConsumed,ts:Date.now()})),k=m.createHmac("sha256",C).update(_).digest(),T=Buffer.alloc(2);T.writeUInt16BE(_.length);let S=Buffer.concat([Buffer.from([1]),T,_,k]).toString("base64");return {image_id:g,zk_receipt:S,output:n,fuel_consumed:p.fuelConsumed,proof_type:0}}finally{await N.teardown();}}a(oe,"processLogicExecution");export{oe as default};//# sourceMappingURL=logic-execution.js.map
272
2
  //# sourceMappingURL=logic-execution.js.map
@@ -1,3 +1,5 @@
1
+ import { Z as ZkPolicy } from '../zk-DzYNWBgo.js';
2
+
1
3
  /**
2
4
  * ZK Verification Payload Structure.
3
5
  * Modeled after RISC Zero & SP1 Receipt formats.
@@ -8,12 +10,18 @@ interface ZkVerificationPayload {
8
10
  logicPayload?: Uint8Array;
9
11
  /** Expected ImageID (SHA-256) of the execution state */
10
12
  remoteImageIdHex?: string;
13
+ /** Expected Guest ImageID (SHA-256) of the zkVM interpreter */
14
+ guestImageIdHex?: string;
11
15
  /** Cbor-encoded or raw buffer containing the execution Receipt (Journal + Seal) */
12
16
  zkReceipt?: Uint8Array;
13
17
  /** Kyber-derived session secret to verify HMAC signature */
14
18
  sessionSecret?: Uint8Array;
19
+ /** Serialized VerificationKey buffer for Groth16 mathematical verification */
20
+ vkeyRaw?: Uint8Array;
15
21
  /** The expected output value of the computation for anti-replay/tampering verification */
16
22
  expectedOutput?: unknown;
23
+ /** Enforcement policy for clearance tiers */
24
+ zkPolicy?: ZkPolicy;
17
25
  }
18
26
  /**
19
27
  * Main worker entry point for Piscina.
@@ -21,6 +29,7 @@ interface ZkVerificationPayload {
21
29
  declare function workerHandler(task: ZkVerificationPayload): Promise<{
22
30
  verified: boolean;
23
31
  message: string;
32
+ proofType?: string;
24
33
  }>;
25
34
 
26
35
  export { type ZkVerificationPayload, workerHandler as default };
@@ -1,174 +1,2 @@
1
- import { deriveLogicImageDigest } from '../chunk-IK7CGWAZ.js';
2
- import crypto from 'crypto';
3
- import 'worker_threads';
4
-
5
- function deriveImageId(logicPayload) {
6
- return deriveLogicImageDigest(logicPayload);
7
- }
8
- function tryExtractProxyOutput(logicPayload) {
9
- try {
10
- const logicStr = Buffer.from(logicPayload).toString("utf-8").trim();
11
- if (!logicStr.includes("__liop_proxy_tool")) {
12
- return null;
13
- }
14
- const firstBraceIdx = logicStr.indexOf("{");
15
- if (firstBraceIdx === -1) {
16
- return null;
17
- }
18
- let braceCount = 0;
19
- let inDoubleQuote = false;
20
- let inSingleQuote = false;
21
- let inBacktick = false;
22
- let escaped = false;
23
- let lastBraceIdx = -1;
24
- for (let i = firstBraceIdx; i < logicStr.length; i++) {
25
- const char = logicStr[i];
26
- if (escaped) {
27
- escaped = false;
28
- continue;
29
- }
30
- if (char === "\\") {
31
- escaped = true;
32
- continue;
33
- }
34
- if (char === '"' && !inSingleQuote && !inBacktick) {
35
- inDoubleQuote = !inDoubleQuote;
36
- continue;
37
- }
38
- if (char === "'" && !inDoubleQuote && !inBacktick) {
39
- inSingleQuote = !inSingleQuote;
40
- continue;
41
- }
42
- if (char === "`" && !inDoubleQuote && !inSingleQuote) {
43
- inBacktick = !inBacktick;
44
- continue;
45
- }
46
- if (!inDoubleQuote && !inSingleQuote && !inBacktick) {
47
- if (char === "{") {
48
- braceCount++;
49
- } else if (char === "}") {
50
- braceCount--;
51
- if (braceCount === 0) {
52
- lastBraceIdx = i;
53
- break;
54
- }
55
- }
56
- }
57
- }
58
- if (lastBraceIdx !== -1) {
59
- const jsonStr = logicStr.slice(firstBraceIdx, lastBraceIdx + 1);
60
- const parsed = JSON.parse(jsonStr);
61
- if (parsed?.__liop_proxy_tool) {
62
- return parsed;
63
- }
64
- }
65
- } catch (_e) {
66
- }
67
- return null;
68
- }
69
- async function verifyZkReceipt(payload) {
70
- const {
71
- logicPayload,
72
- remoteImageIdHex,
73
- zkReceipt,
74
- sessionSecret,
75
- expectedOutput
76
- } = payload;
77
- if (!logicPayload || !remoteImageIdHex || !zkReceipt) {
78
- return {
79
- verified: false,
80
- message: "Missing required verification fields."
81
- };
82
- }
83
- const localImageId = deriveImageId(logicPayload);
84
- const localImageIdHex = localImageId.toString("hex");
85
- if (localImageIdHex !== remoteImageIdHex) {
86
- return {
87
- verified: false,
88
- message: `Integrity Violation: Local (${localImageIdHex.slice(0, 8)}) != Remote (${remoteImageIdHex.slice(0, 8)})`
89
- };
90
- }
91
- const receiptBuf = Buffer.from(zkReceipt);
92
- if (receiptBuf.length < 35) {
93
- return {
94
- verified: false,
95
- message: "Receipt too short for binary format."
96
- };
97
- }
98
- const version = receiptBuf[0];
99
- if (version !== 1) {
100
- return {
101
- verified: false,
102
- message: `Unknown receipt version: ${version}`
103
- };
104
- }
105
- const journalLen = receiptBuf.readUInt16BE(1);
106
- const journal = receiptBuf.subarray(3, 3 + journalLen);
107
- const seal = receiptBuf.subarray(3 + journalLen);
108
- if (seal.length !== 32) {
109
- return {
110
- verified: false,
111
- message: "Invalid seal length (expected 32 bytes HMAC-SHA256)."
112
- };
113
- }
114
- let journalData;
115
- try {
116
- journalData = JSON.parse(journal.toString());
117
- if (journalData.image_id !== localImageIdHex) {
118
- return {
119
- verified: false,
120
- message: `Journal ImageID mismatch: ${journalData.image_id.slice(0, 8)} != ${localImageIdHex.slice(0, 8)}`
121
- };
122
- }
123
- } catch (_e) {
124
- return { verified: false, message: "Failed to parse journal data." };
125
- }
126
- if (sessionSecret && sessionSecret.length > 0) {
127
- const expectedSeal = crypto.createHmac("sha256", sessionSecret).update(journal).digest();
128
- if (!crypto.timingSafeEqual(seal, expectedSeal)) {
129
- return {
130
- verified: false,
131
- message: "Invalid seal: HMAC verification failed."
132
- };
133
- }
134
- }
135
- if (expectedOutput !== void 0) {
136
- const proxyOutput = tryExtractProxyOutput(logicPayload);
137
- const actualExpected = proxyOutput !== null ? proxyOutput : expectedOutput;
138
- const expectedOutputStr = typeof actualExpected === "string" ? actualExpected : actualExpected === void 0 ? "undefined" : JSON.stringify(actualExpected);
139
- const expectedOutputHash = crypto.createHash("sha256").update(expectedOutputStr).digest("hex");
140
- if (journalData.output_hash !== expectedOutputHash) {
141
- return {
142
- verified: false,
143
- message: `Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${journalData.output_hash.slice(0, 8)}) != Calculated output_hash (${expectedOutputHash.slice(0, 8)})`
144
- };
145
- }
146
- }
147
- return {
148
- verified: true,
149
- message: "HMAC Commitment Verified: Integrity intact."
150
- };
151
- }
152
- async function workerHandler(task) {
153
- try {
154
- if (task.action === "warmup") {
155
- return {
156
- verified: true,
157
- message: "warm"
158
- };
159
- }
160
- if (task.action === "verify_receipt") {
161
- return await verifyZkReceipt(task);
162
- }
163
- throw new Error("Unknown action in ZkVerifier Worker.");
164
- } catch (error) {
165
- return {
166
- verified: false,
167
- message: `Verification Error: ${error.message}`
168
- };
169
- }
170
- }
171
-
172
- export { workerHandler as default };
173
- //# sourceMappingURL=zk-verifier.js.map
1
+ import {d,f,b as b$3}from'../chunk-FDJMH4CB.js';import {b}from'../chunk-TKLRW52V.js';import {b as b$2}from'../chunk-2ZYX736J.js';import {h,b as b$1,c,g}from'../chunk-6VK2XALI.js';import {a}from'../chunk-AYDF3IFZ.js';import v from'crypto';import'worker_threads';function D(s){return b(s)}a(D,"deriveImageId");function O(s){try{let i=Buffer.from(s).toString("utf-8").trim();if(!i.includes("__liop_proxy_tool"))return null;let d=i.indexOf("{");if(d===-1)return null;let p=0,c=!1,n=!1,o=!1,f=!1,y=-1;for(let e=d;e<i.length;e++){let t=i[e];if(f){f=!1;continue}if(t==="\\"){f=!0;continue}if(t==='"'&&!n&&!o){c=!c;continue}if(t==="'"&&!c&&!o){n=!n;continue}if(t==="`"&&!c&&!n){o=!o;continue}if(!c&&!n&&!o){if(t==="{")p++;else if(t==="}"&&(p--,p===0)){y=e;break}}}if(y!==-1){let e=i.slice(d,y+1),t=JSON.parse(e);if(t?.__liop_proxy_tool)return t}}catch{}return null}a(O,"tryExtractProxyOutput");async function T(s){let{logicPayload:i,remoteImageIdHex:d$1,guestImageIdHex:p,zkReceipt:c$1,sessionSecret:n,vkeyRaw:o,expectedOutput:f$1,zkPolicy:y}=s;if(!i||!d$1||!c$1)return {verified:false,message:"Missing required verification fields."};let e;try{e=h.decode(Buffer.from(c$1));}catch(t){return {verified:false,message:`Receipt Decode Failed: ${t.message}`}}if(e.version===b$1){if(y==="required")return {verified:false,message:"Policy Violation: Clearance Tier requires ZK proof (Groth16), but received legacy HMAC."};let g=D(i).toString("hex");if(g!==d$1)return {verified:false,message:`Integrity Violation: Local (${g.slice(0,8)}) != Remote (${d$1.slice(0,8)})`};let u;try{if(u=JSON.parse(e.journal.toString()),u.image_id!==g)return {verified:!1,message:`Journal ImageID mismatch: ${u.image_id.slice(0,8)} != ${g.slice(0,8)}`}}catch{return {verified:false,message:"Failed to parse journal data."}}if(n&&n.length>0){let r=v.createHmac("sha256",n).update(e.journal).digest();if(!v.timingSafeEqual(e.proof,r))return {verified:false,message:"Invalid seal: HMAC verification failed."}}if(f$1!==void 0){let r=O(i),a=r!==null?r:f$1,m=typeof a=="string"?a:a===void 0?"undefined":JSON.stringify(a),l=v.createHash("sha256").update(m).digest("hex");if(u.output_hash!==l)return {verified:false,message:`Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${u.output_hash.slice(0,8)}) != Calculated output_hash (${l.slice(0,8)})`}}return {verified:true,message:"HMAC Commitment Verified: Integrity intact.",proofType:"hmac"}}if(e.version===c){if(e.proofType!==2&&e.proofType!==3)return {verified:false,message:`Unsupported ZK proof type in v2 receipt: ${e.proofType}`};if(e.proofType===3){let{pqcSignature:r,pqcPublicKey:a}=e;if(!r||!a)return {verified:false,message:"Hybrid Receipt Error: Missing ML-DSA-65 signature or public key."};let m=v.createHash("sha256").update(Buffer.concat([e.journal,e.proof])).digest();try{if(!b$2.verify(new Uint8Array(r),m,new Uint8Array(a)))return {verified:!1,message:"PQC Signature Verification Failed: ML-DSA-65 co-sign is forged or corrupted."}}catch(l){return {verified:false,message:`PQC Verification Error: ${l.message}`}}}let t;try{t=g(e.journal);}catch(r){return {verified:false,message:`Failed to decode ZkJournalV2: ${r.message}`}}if(p){let r=t.guestImageId.toString("hex");if(r!==p)return {verified:false,message:`Guest ImageID Mismatch: Injected guest environment tampered (${r.slice(0,8)} != ${p.slice(0,8)}).`}}let g$1=D(i);if(!t.logicDigest.equals(g$1))return {verified:false,message:`Logic Digest Mismatch: Remote origin executed unexpected logic (${t.logicDigest.toString("hex").slice(0,8)} != ${g$1.toString("hex").slice(0,8)})`};if(o&&o.length>0)try{let r=d(Buffer.from(o)),a=f(e.proof);if(!b$3(r,a))return {verified:!1,message:"Groth16 mathematical pairing verification failed: invalid proof."}}catch(r){return {verified:false,message:`Groth16 verification failed to execute: ${r.message}`}}if(f$1!==void 0){let r=O(i),a=r!==null?r:f$1,m=typeof a=="string"?a:a===void 0?"undefined":JSON.stringify(a),l=v.createHash("sha256").update(m).digest();if(!t.outputDigest.equals(l))return {verified:false,message:`Output Digest Mismatch (Replay/Tamper attempt): Journal (${t.outputDigest.toString("hex").slice(0,8)}) != Calculated (${l.toString("hex").slice(0,8)})`}}let u=e.proofType===3;return {verified:true,message:u?"Groth16 + ML-DSA-65 Post-Quantum Hybrid Receipt Certified.":o&&o.length>0?"Groth16 Zero-Knowledge Proof Mathematically Certified.":"Groth16 Receipt Structure and Journal Integrity Certified.",proofType:u?"groth16_pqc_hybrid":"groth16"}}return {verified:false,message:`Unsupported receipt version: ${e.version}`}}a(T,"verifyZkReceipt");async function C(s){try{if(s.action==="warmup")return {verified:!0,message:"warm"};if(s.action==="verify_receipt")return await T(s);throw new Error("Unknown action in ZkVerifier Worker.")}catch(i){return {verified:false,message:`Verification Error: ${i.message}`}}}a(C,"workerHandler");export{C as default};//# sourceMappingURL=zk-verifier.js.map
174
2
  //# sourceMappingURL=zk-verifier.js.map
@@ -0,0 +1,104 @@
1
+ declare enum ProofType {
2
+ HMAC_LEGACY = 0,
3
+ GROTH16 = 2,
4
+ GROTH16_PQC_HYBRID = 3
5
+ }
6
+ declare const RECEIPT_VERSION_V1 = 1;
7
+ declare const RECEIPT_VERSION_V2 = 2;
8
+ declare const ZK_JOURNAL_V2_SIZE = 144;
9
+ interface ZkJournalV2 {
10
+ /** Image ID (SHA-256) of the guest interpreter */
11
+ guestImageId: Buffer;
12
+ /** SHA-256 digest of injected logic */
13
+ logicDigest: Buffer;
14
+ /** SHA-256 digest of dataset records */
15
+ datasetDigest: Buffer;
16
+ /** SHA-256 digest of sanitized output */
17
+ outputDigest: Buffer;
18
+ /** Micro-instruction fuel consumed */
19
+ fuelConsumed: bigint;
20
+ /** Timestamp in milliseconds since unix epoch */
21
+ executionTimestamp: bigint;
22
+ }
23
+ type ZkPolicy = "none" | "optimistic" | "required";
24
+ interface ZkReceipt {
25
+ /** Cryptographic proof generated by a zero-knowledge VM (e.g., RISC Zero, SP1) or Groth16 */
26
+ proof: Buffer;
27
+ /** The public inputs/outputs of the execution (the "Journal" in RISC Zero terminology) */
28
+ journal: Buffer;
29
+ /** The expected image ID / verification key of the WASM binary that was executed */
30
+ imageId: Buffer;
31
+ /** Type of cryptographic proof (HMAC legacy or Groth16) */
32
+ proofType?: ProofType;
33
+ /** Binary receipt version (0x01 or 0x02) */
34
+ version?: number;
35
+ }
36
+ declare class ZkVerificationError extends Error {
37
+ constructor(message: string);
38
+ }
39
+ /**
40
+ * Serializes a structured ZkJournalV2 into a strictly validated 144-byte binary layout.
41
+ */
42
+ declare function encodeJournalV2(fields: ZkJournalV2): Buffer;
43
+ /**
44
+ * Deserializes and validates a 144-byte binary buffer into a typed ZkJournalV2.
45
+ */
46
+ declare function decodeJournalV2(buf: Buffer): ZkJournalV2;
47
+ interface DecodedReceipt {
48
+ version: number;
49
+ proofType: ProofType;
50
+ journal: Buffer;
51
+ proof: Buffer;
52
+ raw: Buffer;
53
+ pqcSignature?: Buffer;
54
+ pqcPublicKey?: Buffer;
55
+ }
56
+ declare const receiptCodec: {
57
+ /**
58
+ * Encodes a version 2 Binary Receipt with trailing SHA-256 checksum.
59
+ * Layout: [0x02][proofType: 1B][journalLen: 4B UInt32BE][journal][proof][checksum: 32B]
60
+ */
61
+ encodeV2(proofType: ProofType, journal: Buffer, proof: Buffer): Buffer;
62
+ /**
63
+ * Encodes a version 2.1 Hybrid Binary Receipt (Groth16 + ML-DSA-65 co-sign).
64
+ * Layout:
65
+ * [0x02][0x03 ProofType.GROTH16_PQC_HYBRID][journalLen: 4B UInt32BE][journal: 144B]
66
+ * [proofLen: 2B UInt16BE][groth16 proof: ~260B]
67
+ * [sigLen: 2B UInt16BE][signature: 3309B]
68
+ * [publicKey: 1952B]
69
+ * [checksum: 32B SHA-256]
70
+ */
71
+ encodeHybridV2(journal: Buffer, proof: Buffer, pqcSignature: Buffer, pqcPublicKey: Buffer): Buffer;
72
+ /**
73
+ * Decodes any LIOP Binary Receipt (v1 HMAC or v2 ZK).
74
+ */
75
+ decode(raw: Buffer): DecodedReceipt;
76
+ };
77
+ /**
78
+ * ZK-Proofs Verifier for Logic-Injection-on-Origin Protocol (LIOP)
79
+ *
80
+ * Validates that an executed Logic (WASM) actually produced the reported output,
81
+ * verifying the Zero-Knowledge receipt generated by the remote host's Trusted Execution
82
+ * Environment (TEE) or zkVM (Zero-Knowledge Virtual Machine).
83
+ */
84
+ declare const ZkVerifier: {
85
+ /**
86
+ * Validates a ZK receipt using structural Binary Receipt verification.
87
+ * Parses the HMAC-SHA256 commitment format (v1) and verifies journal integrity.
88
+ *
89
+ * @param receipt - Complete ZkReceipt to verify
90
+ * @param expectedImageId - Hash or ImageID of the WASM file dispatched to the host
91
+ * @throws ZkVerificationError if the proof is invalid or image IDs mismatch
92
+ * @returns true if the proof mathematically verifies the execution
93
+ */
94
+ verify(receipt: ZkReceipt, expectedImageId: Buffer, sessionSecret?: Buffer): boolean;
95
+ /**
96
+ * Derives a predictable ImageID (usually a Hash) from a raw WASM binary.
97
+ *
98
+ * @param wasmBytes - The raw bytes of the WASM logic file
99
+ * @returns The SHA-256 ImageID of the logic
100
+ */
101
+ deriveImageId(wasmBytes: Buffer): Buffer;
102
+ };
103
+
104
+ export { type DecodedReceipt as D, ProofType as P, RECEIPT_VERSION_V1 as R, type ZkPolicy as Z, RECEIPT_VERSION_V2 as a, ZK_JOURNAL_V2_SIZE as b, type ZkJournalV2 as c, type ZkReceipt as d, ZkVerificationError as e, ZkVerifier as f, decodeJournalV2 as g, encodeJournalV2 as h, receiptCodec as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nekzus/liop",
3
- "version": "2.6.1",
3
+ "version": "2.7.1",
4
4
  "description": "Official SDK for Logic-Injection-on-Origin Protocol (LIOP). Deploy Logic-on-Origin with WebAssembly at gRPC speed and bidirectional MCP compatibility.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -32,6 +32,7 @@
32
32
  "sideEffects": false,
33
33
  "files": [
34
34
  "dist",
35
+ "!dist/**/*.js.map",
35
36
  "README.md",
36
37
  "LICENSE",
37
38
  "NOTICE"
@@ -92,7 +93,6 @@
92
93
  "@types/node": "26.4.0",
93
94
  "@types/oidc-provider": "9.12.1",
94
95
  "@vitest/coverage-v8": "4.1.11",
95
- "gpt-tokenizer": "4.0.0",
96
96
  "tsup": "8.5.1",
97
97
  "tsx": "4.23.13",
98
98
  "typescript": "6.0.3",
@@ -121,10 +121,12 @@
121
121
  "@noble/post-quantum": "0.7.1",
122
122
  "acorn": "8.18.0",
123
123
  "acorn-walk": "8.3.5",
124
+ "gpt-tokenizer": "4.0.0",
124
125
  "hono": "4.13.8",
125
126
  "it-pipe": "3.0.1",
126
127
  "jose": "6.2.12",
127
128
  "libp2p": "3.3.11",
129
+ "micro-zk-proofs": "0.3.1",
128
130
  "mlkem": "2.7.0",
129
131
  "multiformats": "14.0.5",
130
132
  "oidc-provider": "9.12.2",
@@ -225,6 +227,9 @@
225
227
  "audit:prod:run": "tsx tests/infra/production-audit/cli/audit-run.ts",
226
228
  "audit:prod:runner": "docker compose -f tests/infra/production-audit/docker-compose.production-audit.yml run --rm audit-runner",
227
229
  "audit:prod:clean": "tsx tests/infra/production-audit/cli/audit-clean.ts",
230
+ "audit:local:start": "tsx tests/infra/production-audit/cli/audit-start-local.ts",
231
+ "audit:local:run": "tsx tests/infra/production-audit/cli/audit-run.ts --local",
232
+ "audit:local:runner": "docker compose -f tests/infra/production-audit/docker-compose.production-audit.yml -f tests/infra/production-audit/docker-compose.local.yml run --rm audit-runner",
228
233
  "telemetry:stream": "tsx scripts/telemetry-stream.ts"
229
234
  }
230
235
  }