@nekzus/liop 1.0.0-alpha.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 (87) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +24 -0
  3. package/README.md +641 -0
  4. package/dist/bin/agent.d.ts +1 -0
  5. package/dist/bin/agent.js +897 -0
  6. package/dist/bin/agent.js.map +1 -0
  7. package/dist/bridge.d.ts +105 -0
  8. package/dist/bridge.js +5 -0
  9. package/dist/bridge.js.map +1 -0
  10. package/dist/chunk-3L2O2XKG.js +723 -0
  11. package/dist/chunk-3L2O2XKG.js.map +1 -0
  12. package/dist/chunk-7BSCUYUE.js +421 -0
  13. package/dist/chunk-7BSCUYUE.js.map +1 -0
  14. package/dist/chunk-7PITYWOV.js +68 -0
  15. package/dist/chunk-7PITYWOV.js.map +1 -0
  16. package/dist/chunk-7RXOIDXP.js +877 -0
  17. package/dist/chunk-7RXOIDXP.js.map +1 -0
  18. package/dist/chunk-BOISQ45Z.js +558 -0
  19. package/dist/chunk-BOISQ45Z.js.map +1 -0
  20. package/dist/chunk-DZ2FQGJD.js +206712 -0
  21. package/dist/chunk-DZ2FQGJD.js.map +1 -0
  22. package/dist/chunk-EG46XMJT.js +77 -0
  23. package/dist/chunk-EG46XMJT.js.map +1 -0
  24. package/dist/chunk-ESRXG36Y.js +115 -0
  25. package/dist/chunk-ESRXG36Y.js.map +1 -0
  26. package/dist/chunk-FTF6AMF6.js +3 -0
  27. package/dist/chunk-FTF6AMF6.js.map +1 -0
  28. package/dist/chunk-HA6YZ42O.js +64 -0
  29. package/dist/chunk-HA6YZ42O.js.map +1 -0
  30. package/dist/chunk-HD2N3IJX.js +3634 -0
  31. package/dist/chunk-HD2N3IJX.js.map +1 -0
  32. package/dist/chunk-IK7CGWAZ.js +24 -0
  33. package/dist/chunk-IK7CGWAZ.js.map +1 -0
  34. package/dist/chunk-L6J72C5X.js +1477 -0
  35. package/dist/chunk-L6J72C5X.js.map +1 -0
  36. package/dist/chunk-PAICJCKJ.js +332 -0
  37. package/dist/chunk-PAICJCKJ.js.map +1 -0
  38. package/dist/chunk-PEN3KFLF.js +114 -0
  39. package/dist/chunk-PEN3KFLF.js.map +1 -0
  40. package/dist/chunk-T7R5HUFD.js +775 -0
  41. package/dist/chunk-T7R5HUFD.js.map +1 -0
  42. package/dist/chunk-TKRX6CFI.js +168 -0
  43. package/dist/chunk-TKRX6CFI.js.map +1 -0
  44. package/dist/chunk-UCVP3XAL.js +279 -0
  45. package/dist/chunk-UCVP3XAL.js.map +1 -0
  46. package/dist/chunk-VH4K4U45.js +180 -0
  47. package/dist/chunk-VH4K4U45.js.map +1 -0
  48. package/dist/chunk-Y62GORQF.js +51 -0
  49. package/dist/chunk-Y62GORQF.js.map +1 -0
  50. package/dist/chunk-ZP3VVXOI.js +66 -0
  51. package/dist/chunk-ZP3VVXOI.js.map +1 -0
  52. package/dist/client.d.ts +7 -0
  53. package/dist/client.js +13 -0
  54. package/dist/client.js.map +1 -0
  55. package/dist/gateway.d.ts +7 -0
  56. package/dist/gateway.js +13 -0
  57. package/dist/gateway.js.map +1 -0
  58. package/dist/hybrid-CrKB50nh.d.ts +170 -0
  59. package/dist/index-CX43dvMs.d.ts +170 -0
  60. package/dist/index-DoW2gzBZ.d.ts +566 -0
  61. package/dist/index.d.ts +810 -0
  62. package/dist/index.js +357 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/kyber-CGOA7Q6A.js +3 -0
  65. package/dist/kyber-CGOA7Q6A.js.map +1 -0
  66. package/dist/mesh.d.ts +32 -0
  67. package/dist/mesh.js +6 -0
  68. package/dist/mesh.js.map +1 -0
  69. package/dist/node-B0b2vUFS.d.ts +164 -0
  70. package/dist/protocol/liop_core.proto +47 -0
  71. package/dist/server.d.ts +5 -0
  72. package/dist/server.js +9 -0
  73. package/dist/server.js.map +1 -0
  74. package/dist/types-lJIxBlWF.d.ts +256 -0
  75. package/dist/types.d.ts +3 -0
  76. package/dist/types.js +3 -0
  77. package/dist/types.js.map +1 -0
  78. package/dist/verifier-COnid_dg.d.ts +31 -0
  79. package/dist/verifier-HRFXBKT5.js +6 -0
  80. package/dist/verifier-HRFXBKT5.js.map +1 -0
  81. package/dist/workers/logic-execution.d.ts +26 -0
  82. package/dist/workers/logic-execution.js +272 -0
  83. package/dist/workers/logic-execution.js.map +1 -0
  84. package/dist/workers/zk-verifier.d.ts +26 -0
  85. package/dist/workers/zk-verifier.js +174 -0
  86. package/dist/workers/zk-verifier.js.map +1 -0
  87. package/package.json +230 -0
@@ -0,0 +1,47 @@
1
+ // Copyright 2026 Nekzus Solutions and contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ syntax = "proto3";
5
+ package liop.v1;
6
+
7
+ // LogicMesh (formerly NeuralMesh) is the next-generation binary transport protocol for Logic-on-Origin AI
8
+ service LogicMesh {
9
+ // Intent negotiation before transferring data or execution logic
10
+ // Validates Identity, Capability Hashes and Cryptographic signatures
11
+ rpc NegotiateIntent (IntentRequest) returns (IntentResponse);
12
+
13
+ // Execution of Logic-on-Origin in a secure remote (WASM / WASI) sandbox
14
+ rpc ExecuteLogic (LogicRequest) returns (stream LogicResponse);
15
+ }
16
+
17
+ // Request to negotiate an intent to execute a WASM capability
18
+ message IntentRequest {
19
+ string agent_did = 1; // Decentralized Identifier (DID) e.g., spiffe:// or Noise PeerID
20
+ string capability_hash = 2; // Cryptographic hash of the targeted capability / tool
21
+ bytes proof_of_intent = 3; // Cryptographic signature of the task intent
22
+ }
23
+
24
+ // Response from the host confirming or denying the intent negotiation
25
+ message IntentResponse {
26
+ bool accepted = 1; // True if the zero-trust host allows the execution
27
+ string session_token = 2; // Ephemeral token to be used on ExecuteLogic stream
28
+ string error_message = 3; // Capability Violation message if any
29
+ bytes kyber_public_key = 4; // Post-Quantum Kyber (ML-KEM-768) Public Key (1184 bytes)
30
+ }
31
+
32
+ // Request to push a WASM module down to the origin for execution
33
+ message LogicRequest {
34
+ string session_token = 1; // Token acquired from NegotiateIntent
35
+ bytes wasm_binary = 2; // AES-GCM Encrypted .wasm Logic-on-Origin filter code
36
+ map<string, bytes> inputs = 3; // AES-GCM Encrypted input parameters
37
+ bytes pqc_ciphertext = 4; // Kyber (ML-KEM-768) Ciphertext encapsulating the AES shared secret
38
+ bytes aes_nonce = 5; // 12-byte nonce for AES-GCM
39
+ }
40
+
41
+ // Streamed Response back to the LLM agent containing reduced, semantically rich semantic responses
42
+ message LogicResponse {
43
+ string semantic_evidence = 1; // Condensed semantic result for the LLM
44
+ bytes cryptographic_proof = 2; // Integrity signature (SHA256)
45
+ bytes zk_receipt = 3; // Zero-Knowledge Proof Receipt (e.g. risc0 zkVM) for Computational Integrity
46
+ bool is_error = 4; // Execution status
47
+ }
@@ -0,0 +1,5 @@
1
+ export { b as AggregationPolicy, L as LiopServer, a as LiopServerOptions, i as LogicExecutionPolicy, N as NerScanner, j as OutputSanitizerConfig, P as PII_PATTERNS, k as PII_PRESETS, l as PiiRule, m as PiiScanner, T as ToolHandler, s as sanitizeOutput } from './index-DoW2gzBZ.js';
2
+ import 'zod';
3
+ import './node-B0b2vUFS.js';
4
+ import './types-lJIxBlWF.js';
5
+ import 'jose';
package/dist/server.js ADDED
@@ -0,0 +1,9 @@
1
+ export { LiopServer, NerScanner, PII_PATTERNS, PII_PRESETS, PiiScanner } from './chunk-HD2N3IJX.js';
2
+ export { sanitizeOutput } from './chunk-Y62GORQF.js';
3
+ import './chunk-VH4K4U45.js';
4
+ import './chunk-TKRX6CFI.js';
5
+ import './chunk-PAICJCKJ.js';
6
+ import './chunk-7RXOIDXP.js';
7
+ import './chunk-HA6YZ42O.js';
8
+ //# sourceMappingURL=server.js.map
9
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"server.js"}
@@ -0,0 +1,256 @@
1
+ import { z } from 'zod';
2
+ import * as jose from 'jose';
3
+
4
+ /**
5
+ * LIOP JWT Validator — Token Verification Engine
6
+ *
7
+ * Validates JWT Access Tokens using the `jose` library.
8
+ * Supports two modes:
9
+ * - Local JWKS (Nexus role): Keys in memory, zero network latency.
10
+ * - Remote JWKS (Node role): Fetched from Nexus /oidc/jwks with 10min cache.
11
+ *
12
+ * Standards: NIST SP 800-207 (continuous verification), OWASP API-A01
13
+ * Source: panva/jose DeepWiki — createRemoteJWKSet, jwtVerify
14
+ */
15
+
16
+ /**
17
+ * Authorization context extracted from a validated JWT.
18
+ * Compatible with MCP TypeScript SDK AuthInfo interface.
19
+ */
20
+ interface AuthInfo {
21
+ /** Raw JWT string. */
22
+ token: string;
23
+ /** Subject claim (client_id for M2M flows). */
24
+ clientId: string;
25
+ /** Space-delimited scopes parsed into an array. */
26
+ scopes: string[];
27
+ /** Token expiration timestamp (Unix seconds). */
28
+ expiresAt?: number;
29
+ }
30
+ /**
31
+ * JWT Validator with dual-mode JWKS resolution.
32
+ *
33
+ * - Nexus role: `new JwtValidator(issuer, audience, localJwks)` (createLocalJWKSet)
34
+ * - Node role: `new JwtValidator(issuer, audience, new URL(jwksUri))` (createRemoteJWKSet)
35
+ */
36
+ declare class JwtValidator {
37
+ private readonly jwksResolver;
38
+ private readonly issuer;
39
+ private readonly audience;
40
+ constructor(issuer: string, audience: string, jwksSource: URL | jose.JSONWebKeySet);
41
+ /**
42
+ * Validates a JWT access token and extracts authorization context.
43
+ *
44
+ * Checks performed (jose.jwtVerify):
45
+ * - Cryptographic signature verification (EdDSA or ES256)
46
+ * - Issuer claim matches configured issuer
47
+ * - Audience claim matches configured audience
48
+ * - Token is not expired (with clock tolerance for mesh skew)
49
+ * - Required claims (sub, scope) are present
50
+ *
51
+ * @throws JOSEError if validation fails (expired, wrong issuer, bad signature, etc.)
52
+ */
53
+ validate(token: string): Promise<AuthInfo>;
54
+ /**
55
+ * Builds a complete set of issuer URL aliases for the LIOP demo topology.
56
+ *
57
+ * The LIOP mesh runs on Docker Desktop with the following network layout:
58
+ * Container hostnames: "nexus", "liop-nexus" (internal port 3000)
59
+ * Host-published ports: 13000 (HTTP/MCP), 13001 (libp2p TCP)
60
+ * Loopback addresses: 127.0.0.1, localhost
61
+ *
62
+ * The Nexus OAuth server may set its issuer to any of these depending on
63
+ * how it was configured, and nodes may resolve it via LIOP_NEXUS_URL
64
+ * which varies by context. This method generates all equivalent aliases
65
+ * so that jose.jwtVerify accepts the token regardless of which alias
66
+ * was used as `iss` in the JWT.
67
+ *
68
+ * Security note: This does NOT weaken validation — the cryptographic
69
+ * signature is still verified against the same JWKS keys. Only the
70
+ * string comparison of the `iss` claim is relaxed across known aliases.
71
+ */
72
+ private buildIssuerAliases;
73
+ /**
74
+ * Returns the configured issuer URL for PRM (RFC 9728) metadata.
75
+ */
76
+ getIssuer(): string;
77
+ /**
78
+ * Returns the configured audience for PRM metadata.
79
+ */
80
+ getAudience(): string;
81
+ }
82
+
83
+ /**
84
+ * @mcp-legacy ENTIRE FILE — MCP 2025-era backward compatibility layer.
85
+ * Remove this file when MCP v1 (2025-11-25) reaches EOL.
86
+ *
87
+ * SUNSET INSTRUCTION: Delete this file, then grep for "@mcp-legacy" in the
88
+ * codebase to find and remove all remaining legacy seams.
89
+ */
90
+ /**
91
+ * @mcp-legacy Master kill switch for MCP 2025-era backward compatibility.
92
+ * Set to `false` when MCP v1 reaches End-of-Life (EOL) to disable all legacy seams.
93
+ */
94
+ declare const MCP_LEGACY_SUPPORT_ENABLED = true;
95
+ /**
96
+ * @mcp-legacy Legacy protocol version constant.
97
+ */
98
+ declare const MCP_PROTOCOL_VERSION_LEGACY: "2025-11-25";
99
+
100
+ /**
101
+ * Protocol Version Identifiers
102
+ */
103
+ declare const MCP_PROTOCOL_VERSION: "2026-07-28";
104
+
105
+ /**
106
+ * Protocol Era Classification
107
+ */
108
+ type McpEra = "legacy" | "modern";
109
+ /**
110
+ * Caching Hints for MCP 2026-07-28 Spec
111
+ */
112
+ interface CacheableResult {
113
+ ttlMs?: number;
114
+ cacheScope?: "public" | "private";
115
+ }
116
+ /**
117
+ * Multi-Round-Trip Requests (MRTR) Specification Types
118
+ */
119
+ interface InputRequest {
120
+ id: string;
121
+ message: string;
122
+ schema?: Record<string, unknown>;
123
+ }
124
+ interface InputResponse {
125
+ id: string;
126
+ value: unknown;
127
+ }
128
+ interface InputRequiredResult {
129
+ resultType: "input_required";
130
+ inputRequests: InputRequest[];
131
+ requestState?: string;
132
+ }
133
+ /**
134
+ * Modern Envelope Metadata (_meta)
135
+ */
136
+ interface McpRequestMeta {
137
+ "io.modelcontextprotocol/protocolVersion"?: string;
138
+ "io.modelcontextprotocol/clientInfo"?: {
139
+ name: string;
140
+ version: string;
141
+ };
142
+ "io.modelcontextprotocol/clientCapabilities"?: Record<string, unknown>;
143
+ [key: string]: unknown;
144
+ }
145
+ /**
146
+ * Base Protocol Types representing parity with Model Context Protocol
147
+ */
148
+ declare const ToolSchema: z.ZodObject<{
149
+ name: z.ZodString;
150
+ description: z.ZodOptional<z.ZodString>;
151
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
152
+ }, z.core.$strip>;
153
+ type Tool = z.infer<typeof ToolSchema>;
154
+ declare const ResourceSchema: z.ZodObject<{
155
+ uri: z.ZodString;
156
+ name: z.ZodString;
157
+ description: z.ZodOptional<z.ZodString>;
158
+ mimeType: z.ZodOptional<z.ZodString>;
159
+ }, z.core.$strip>;
160
+ type Resource = z.infer<typeof ResourceSchema>;
161
+ declare const PromptSchema: z.ZodObject<{
162
+ name: z.ZodString;
163
+ description: z.ZodOptional<z.ZodString>;
164
+ arguments: z.ZodOptional<z.ZodArray<z.ZodObject<{
165
+ name: z.ZodString;
166
+ description: z.ZodOptional<z.ZodString>;
167
+ required: z.ZodOptional<z.ZodBoolean>;
168
+ }, z.core.$strip>>>;
169
+ }, z.core.$strip>;
170
+ type Prompt = z.infer<typeof PromptSchema>;
171
+ interface CallToolRequest {
172
+ name: string;
173
+ arguments?: Record<string, unknown>;
174
+ }
175
+ interface CallToolResult {
176
+ content: Array<{
177
+ type: "text" | "image" | "resource";
178
+ text?: string;
179
+ data?: string;
180
+ mimeType?: string;
181
+ resource?: {
182
+ uri: string;
183
+ text?: string;
184
+ blob?: string;
185
+ };
186
+ }>;
187
+ isError?: boolean;
188
+ }
189
+ interface GetPromptRequest {
190
+ name: string;
191
+ arguments?: Record<string, string>;
192
+ }
193
+ interface GetPromptResult {
194
+ description?: string;
195
+ messages: Array<{
196
+ role: "user" | "assistant";
197
+ content: {
198
+ type: "text";
199
+ text: string;
200
+ } | {
201
+ type: "image";
202
+ data: string;
203
+ mimeType: string;
204
+ } | {
205
+ type: "resource";
206
+ resource: {
207
+ uri: string;
208
+ text?: string;
209
+ blob?: string;
210
+ };
211
+ };
212
+ }>;
213
+ }
214
+ interface ServerInfo {
215
+ name: string;
216
+ version: string;
217
+ capabilities?: {
218
+ prompts?: {
219
+ listChanged?: boolean;
220
+ };
221
+ resources?: {
222
+ subscribe?: boolean;
223
+ listChanged?: boolean;
224
+ };
225
+ tools?: {
226
+ listChanged?: boolean;
227
+ };
228
+ /** @mcp-legacy @deprecated Deprecated in MCP 2026-07-28 spec */
229
+ logging?: Record<string, unknown>;
230
+ };
231
+ }
232
+ interface DiscoverResult {
233
+ resultType: "complete";
234
+ supportedVersions: string[];
235
+ capabilities: ServerInfo["capabilities"];
236
+ serverInfo: ServerInfo;
237
+ instructions?: string;
238
+ }
239
+ interface McpRequest {
240
+ method: string;
241
+ params?: unknown;
242
+ id?: string | number | null;
243
+ jsonrpc?: "2.0";
244
+ }
245
+ interface McpResponse {
246
+ jsonrpc: "2.0";
247
+ id?: string | number | null;
248
+ result?: unknown;
249
+ error?: {
250
+ code: number;
251
+ message: string;
252
+ data?: unknown;
253
+ };
254
+ }
255
+
256
+ export { type AuthInfo as A, type CallToolRequest as C, type DiscoverResult as D, type GetPromptRequest as G, type InputRequest as I, JwtValidator as J, type McpEra as M, type Prompt as P, type Resource as R, type ServerInfo as S, type Tool as T, type CallToolResult as a, type McpRequest as b, type McpResponse as c, type GetPromptResult as d, type CacheableResult as e, type InputRequiredResult as f, type InputResponse as g, MCP_LEGACY_SUPPORT_ENABLED as h, MCP_PROTOCOL_VERSION as i, MCP_PROTOCOL_VERSION_LEGACY as j, type McpRequestMeta as k, PromptSchema as l, ResourceSchema as m, ToolSchema as n };
@@ -0,0 +1,3 @@
1
+ import 'zod';
2
+ export { A as AuthInfo, e as CacheableResult, C as CallToolRequest, a as CallToolResult, D as DiscoverResult, G as GetPromptRequest, d as GetPromptResult, I as InputRequest, f as InputRequiredResult, g as InputResponse, h as MCP_LEGACY_SUPPORT_ENABLED, i as MCP_PROTOCOL_VERSION, j as MCP_PROTOCOL_VERSION_LEGACY, M as McpEra, b as McpRequest, k as McpRequestMeta, c as McpResponse, P as Prompt, l as PromptSchema, R as Resource, m as ResourceSchema, S as ServerInfo, T as Tool, n as ToolSchema } from './types-lJIxBlWF.js';
3
+ import 'jose';
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ export { MCP_LEGACY_SUPPORT_ENABLED, MCP_PROTOCOL_VERSION, MCP_PROTOCOL_VERSION_LEGACY, PromptSchema, ResourceSchema, ToolSchema } from './chunk-EG46XMJT.js';
2
+ //# sourceMappingURL=types.js.map
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"types.js"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * LIOP Tier-0 Industrial Verifier
3
+ *
4
+ * This engine is responsible for the trustless verification of remote logic execution.
5
+ * It validates both the integrity of the code (ZkImageID) and the mathematical proof
6
+ * of its execution (ZkSeal), as well as hardware-level attestation (TEE).
7
+ */
8
+ declare class LiopVerifier {
9
+ private static zkWorkerPool;
10
+ private getZkPool;
11
+ /**
12
+ * Verifies a Zero-Knowledge Receipt from a remote LIOP node via Worker Pool.
13
+ *
14
+ * @param logicPayload The raw WASM or JS logic that was sent to the provider.
15
+ * @param remoteImageIdHex The ImageID reported by the provider (must match our local calculation).
16
+ * @param zkReceipt The mathematical proof (Seal + Journal) from the zkVM.
17
+ */
18
+ verifyZkReceipt(logicPayload: Buffer, remoteImageIdHex: string, zkReceipt: Buffer, sessionSecret?: Buffer, expectedOutput?: unknown): Promise<boolean>;
19
+ /**
20
+ * Verifies if a node is running inside an authenticated TEE (e.g. AWS Nitro).
21
+ *
22
+ * @param attestationReport The COSE-signed attestation document from the hardware.
23
+ */
24
+ verifyTeeAttestation(attestationReport: Buffer): Promise<boolean>;
25
+ /**
26
+ * Derives the ImageID of a logic payload following the LIOP v1 Standard.
27
+ */
28
+ deriveImageId(logicPayload: Buffer): Buffer;
29
+ }
30
+
31
+ export { LiopVerifier as L };
@@ -0,0 +1,6 @@
1
+ export { LiopVerifier } from './chunk-PEN3KFLF.js';
2
+ import './chunk-IK7CGWAZ.js';
3
+ import './chunk-PAICJCKJ.js';
4
+ import './chunk-HA6YZ42O.js';
5
+ //# sourceMappingURL=verifier-HRFXBKT5.js.map
6
+ //# sourceMappingURL=verifier-HRFXBKT5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"verifier-HRFXBKT5.js"}
@@ -0,0 +1,26 @@
1
+ interface WorkerData {
2
+ isWarmup?: boolean;
3
+ ciphertext?: Uint8Array;
4
+ secretKeyObj?: ArrayLike<number>;
5
+ kyberPublicKey?: Uint8Array;
6
+ wasmBinary?: Uint8Array;
7
+ inputs?: Record<string, Uint8Array>;
8
+ records?: Record<string, unknown>[];
9
+ sessionToken?: string;
10
+ sessionTimestamp?: number;
11
+ isEncrypted?: boolean;
12
+ aesNonce?: Uint8Array;
13
+ dpConfig?: {
14
+ epsilon: number;
15
+ sensitivity: number;
16
+ smallDatasetThreshold: number;
17
+ };
18
+ }
19
+ declare function processLogicExecution(data: WorkerData): Promise<{
20
+ image_id: string;
21
+ output: unknown;
22
+ fuel_consumed: number;
23
+ zk_receipt?: string;
24
+ }>;
25
+
26
+ export { type WorkerData, processLogicExecution as default };
@@ -0,0 +1,272 @@
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
272
+ //# sourceMappingURL=logic-execution.js.map