enigma-memory 0.1.18 → 0.1.22

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 (276) hide show
  1. package/README.md +76 -24
  2. package/apps/cli/bin/enigma-desktop.mjs +140 -0
  3. package/apps/cli/bin/enigma-terminal.mjs +78 -0
  4. package/apps/cli/bin/enigma.mjs +1923 -285
  5. package/apps/desktop/electron-main.cjs +217 -0
  6. package/apps/desktop/package.json +12 -0
  7. package/apps/desktop/src/app.js +264 -7
  8. package/apps/desktop/src/index.html +3514 -1373
  9. package/apps/desktop/src/launch-electron.mjs +51 -0
  10. package/apps/desktop/src/server.mjs +2914 -0
  11. package/apps/desktop/src/styles.css +2972 -260
  12. package/apps/desktop/src/zk-browser-prove.mjs +53 -0
  13. package/apps/desktop/src/zk-state.mjs +1789 -0
  14. package/apps/gateway/bin/enigma-gateway.mjs +102 -5
  15. package/apps/gateway/src/server.mjs +271 -8
  16. package/apps/ios/EnigmaCore/Package.swift +12 -0
  17. package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
  18. package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
  19. package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
  20. package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
  21. package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
  22. package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
  23. package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
  24. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
  25. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
  26. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
  27. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
  28. package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
  29. package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
  30. package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
  31. package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
  32. package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
  33. package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
  34. package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
  35. package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
  36. package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
  37. package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
  38. package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
  39. package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
  40. package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
  41. package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
  42. package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
  43. package/apps/native-host/README.md +19 -8
  44. package/apps/native-host/bin/enigma-native-host.mjs +229 -13
  45. package/apps/relay/bin/enigma-relay.mjs +103 -5
  46. package/apps/relay/src/federation-runtime.mjs +618 -0
  47. package/apps/relay/src/server.mjs +310 -9
  48. package/apps/verifier/bin/enigma-verify.mjs +327 -11
  49. package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
  50. package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
  51. package/cortex-v3/circuits/build/vk_bytes.json +32 -0
  52. package/cortex-v3/proving-assets.json +64 -0
  53. package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
  54. package/cortex-v3/zk/action-transition-vk.json +119 -0
  55. package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
  56. package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
  57. package/cortex-v3/zk/intent-witness.mjs +365 -0
  58. package/cortex-v3/zk/intent-witness.test.mjs +485 -0
  59. package/cortex-v3/zk/proving-assets.mjs +203 -0
  60. package/cortex-v3/zk/sale-witness.mjs +783 -0
  61. package/cortex-v3/zk/sale-witness.test.mjs +784 -0
  62. package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
  63. package/cortex-v3/zk/settlement-evidence.mjs +722 -0
  64. package/cortex-v3/zk/setup-intent.mjs +688 -0
  65. package/cortex-v3/zk/setup-sale.mjs +666 -0
  66. package/cortex-v3/zk/setup.mjs +594 -0
  67. package/cortex-v3/zk/witness.mjs +184 -0
  68. package/cortex-v3/zk/zk-codec.mjs +232 -0
  69. package/cortex-v3/zk/zk-codec.test.mjs +293 -0
  70. package/cortex-v3/zk/zk-settle.mjs +370 -0
  71. package/cortex-v3/zk/zk-tree.mjs +256 -0
  72. package/cortex-v3/zk/zk-tree.test.mjs +419 -0
  73. package/deploy/docker-compose.local-production-simulation.yml +36 -0
  74. package/docs/browser-extension-install.md +8 -6
  75. package/docs/client-connectors.md +15 -11
  76. package/docs/developer-ecosystem.md +15 -13
  77. package/docs/enigma-memory-ready-conformance.md +11 -9
  78. package/docs/install-anywhere.md +61 -28
  79. package/docs/installers-and-desktop.md +8 -7
  80. package/docs/novelty-invention-candidates.md +161 -161
  81. package/docs/proof-network-claim-boundaries.md +320 -318
  82. package/examples/01-quickstart-agent/index.mjs +49 -0
  83. package/examples/01_agent_memory_quickstart.mjs +57 -0
  84. package/examples/02-multi-agent-swarm/index.mjs +57 -0
  85. package/examples/02_cross_model_passport.mjs +64 -0
  86. package/examples/03-langchain-memory/index.mjs +41 -0
  87. package/examples/03_poseidon_commitment_verification.mjs +71 -0
  88. package/examples/04-python-trading-agent/trader.py +49 -0
  89. package/examples/README.md +27 -0
  90. package/examples/ci/github-actions.yml +7 -2
  91. package/package.json +142 -11
  92. package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
  93. package/packages/connectors/src/index.js +196 -4
  94. package/packages/connectors/swarm-router.mjs +168 -0
  95. package/packages/core/src/index.js +248 -1
  96. package/packages/core/src/version.mjs +7 -0
  97. package/packages/dev-tools/package.json +19 -0
  98. package/packages/dev-tools/src/index.js +4 -0
  99. package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
  100. package/packages/dev-tools/src/swarm-simulator.js +101 -0
  101. package/packages/dev-tools/src/vault-inspector.js +114 -0
  102. package/packages/dev-tools/src/vector-benchmark.js +100 -0
  103. package/packages/developer-platform/src/access-credentials.js +341 -0
  104. package/packages/developer-platform/src/http.js +132 -0
  105. package/packages/developer-platform/src/index.js +4 -0
  106. package/packages/developer-platform/src/usage-http.js +60 -0
  107. package/packages/developer-platform/src/usage.js +295 -0
  108. package/packages/enclave-runtime/attestation.mjs +159 -0
  109. package/packages/enclave-runtime/index.mjs +47 -0
  110. package/packages/enclave-runtime/session-manager.mjs +253 -0
  111. package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
  112. package/packages/enigma-reflex/package.json +14 -0
  113. package/packages/enigma-reflex/src/index.js +204 -0
  114. package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
  115. package/packages/enigma-reflex/training/requirements.txt +8 -0
  116. package/packages/enigma-reflex/training/train.py +314 -0
  117. package/packages/enigma-weave/LICENSE +22 -0
  118. package/packages/enigma-weave/UPSTREAM.json +21 -0
  119. package/packages/enigma-weave/package.json +14 -0
  120. package/packages/enigma-weave/src/index.js +286 -0
  121. package/packages/hosted-cloud/src/index.js +80 -5
  122. package/packages/importers/src/index.js +432 -0
  123. package/packages/inference-runtime/src/browser.js +401 -0
  124. package/packages/inference-runtime/src/chat.js +265 -0
  125. package/packages/inference-runtime/src/code.js +407 -0
  126. package/packages/inference-runtime/src/contracts.js +162 -0
  127. package/packages/inference-runtime/src/http.js +232 -0
  128. package/packages/inference-runtime/src/image.js +186 -0
  129. package/packages/inference-runtime/src/index.js +10 -0
  130. package/packages/inference-runtime/src/model-router.js +320 -0
  131. package/packages/inference-runtime/src/platform.js +125 -0
  132. package/packages/inference-runtime/src/privacy.js +400 -0
  133. package/packages/inference-runtime/src/video.js +253 -0
  134. package/packages/mcp-server/README.md +22 -6
  135. package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
  136. package/packages/mcp-server/src/index.js +1418 -105
  137. package/packages/mcp-server/src/oauth.js +561 -0
  138. package/packages/mcp-server/src/private-handoff.js +84 -0
  139. package/packages/mcp-server/src/remote-http.js +273 -0
  140. package/packages/mcp-server/src/remote-policy.js +72 -0
  141. package/packages/mcp-server/swarm-bridge.mjs +361 -0
  142. package/packages/mesh/index.d.ts +283 -0
  143. package/packages/mesh/package.json +23 -0
  144. package/packages/mesh/src/crypto.js +189 -0
  145. package/packages/mesh/src/federation-packets.js +353 -0
  146. package/packages/mesh/src/gossip.js +311 -0
  147. package/packages/mesh/src/index.js +6 -0
  148. package/packages/mesh/src/protocol.js +255 -0
  149. package/packages/mesh/src/router.js +279 -0
  150. package/packages/mesh/src/transport.js +306 -0
  151. package/packages/passport/src/index.js +426 -1
  152. package/packages/private-economy/src/credits-http.js +100 -0
  153. package/packages/private-economy/src/credits.js +447 -0
  154. package/packages/private-economy/src/index.js +5 -0
  155. package/packages/private-economy/src/payments-http.js +120 -0
  156. package/packages/private-economy/src/payments.js +509 -0
  157. package/packages/private-economy/src/x402.js +346 -0
  158. package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
  159. package/packages/rag/index.d.ts +182 -0
  160. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
  161. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
  162. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
  163. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
  164. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
  165. package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
  166. package/packages/rag/package.json +27 -0
  167. package/packages/rag/src/blinded-search.js +109 -0
  168. package/packages/rag/src/bm25.js +169 -0
  169. package/packages/rag/src/embeddings.js +459 -0
  170. package/packages/rag/src/hybrid.js +76 -0
  171. package/packages/rag/src/index.js +38 -0
  172. package/packages/rag/src/reranker.js +61 -0
  173. package/packages/rag/src/research.js +107 -0
  174. package/packages/rag/src/vector-store.js +430 -0
  175. package/packages/rag/src/verify-model-artifacts.mjs +4 -0
  176. package/packages/sdk/index.d.ts +760 -0
  177. package/packages/sdk/package.json +33 -0
  178. package/packages/sdk/python/README.md +24 -0
  179. package/packages/sdk/python/enigma_sdk.py +250 -0
  180. package/packages/sdk/python/pyproject.toml +34 -0
  181. package/packages/sdk/python/requirements.txt +1 -0
  182. package/packages/sdk/python/setup.py +20 -0
  183. package/packages/sdk/src/federation/capability-grant.js +389 -0
  184. package/packages/sdk/src/federation/federation-router.js +360 -0
  185. package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
  186. package/packages/sdk/src/federation/index.js +3 -0
  187. package/packages/sdk/src/index.js +1796 -0
  188. package/packages/sdk/src/intelligence/contradiction.js +337 -0
  189. package/packages/sdk/src/intelligence/decision-engine.js +155 -0
  190. package/packages/sdk/src/intelligence/index.js +4 -0
  191. package/packages/sdk/src/intelligence/ontology.js +122 -0
  192. package/packages/sdk/src/intelligence/temporal.js +123 -0
  193. package/packages/sdk/src/market-client.js +142 -0
  194. package/packages/sdk/src/mesh-client.js +110 -0
  195. package/packages/sdk/src/middleware/index.js +3 -0
  196. package/packages/sdk/src/middleware/langchain.js +159 -0
  197. package/packages/sdk/src/middleware/llamaindex.js +101 -0
  198. package/packages/sdk/src/middleware/vercel-ai.js +112 -0
  199. package/packages/sdk/src/rag-client.js +85 -0
  200. package/packages/sdk/src/swarm-orchestrator.js +260 -0
  201. package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
  202. package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
  203. package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
  204. package/packages/snapcompact/index.d.ts +284 -0
  205. package/packages/snapcompact/package.json +25 -0
  206. package/packages/snapcompact/src/index.js +716 -0
  207. package/packages/storage/PACKAGE_CONTRACT.md +1 -1
  208. package/packages/terminal-console/animations.mjs +240 -0
  209. package/packages/terminal-console/auto-anchor.mjs +220 -0
  210. package/packages/terminal-console/banner.mjs +91 -0
  211. package/packages/terminal-console/commands.mjs +459 -0
  212. package/packages/terminal-console/delegation.mjs +152 -0
  213. package/packages/terminal-console/index.mjs +5 -0
  214. package/packages/terminal-console/outbox.mjs +143 -0
  215. package/packages/terminal-console/phantom-bridge.mjs +637 -0
  216. package/packages/terminal-console/repl.mjs +136 -0
  217. package/packages/terminal-console/signer-store.mjs +130 -0
  218. package/packages/terminal-console/solana-rpc.mjs +214 -0
  219. package/packages/terminal-console/solana-transport.mjs +189 -0
  220. package/packages/terminal-tui/dashboard.mjs +214 -0
  221. package/packages/terminal-tui/index.mjs +28 -0
  222. package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
  223. package/packages/terminal-tui/telemetry-hud.mjs +137 -0
  224. package/packages/vault/index.d.ts +449 -0
  225. package/packages/vault/package.json +27 -0
  226. package/packages/vault/src/e2ee.mjs +393 -0
  227. package/packages/vault/src/enclave.js +481 -0
  228. package/packages/vault/src/erasure.js +207 -0
  229. package/packages/vault/src/index.js +1018 -155
  230. package/packages/vault/src/persistence.js +307 -0
  231. package/packages/vault/src/poseidon.js +354 -0
  232. package/packages/vault/src/receipt.js +459 -0
  233. package/scripts/benchmark-optical-context.mjs +166 -0
  234. package/scripts/bootstrap-enigma.mjs +502 -0
  235. package/scripts/build-edge-backend-workers.mjs +20 -5
  236. package/scripts/build-goal-completion-audit.mjs +72 -25
  237. package/scripts/build-hosted-api-key-lifecycle.mjs +26 -8
  238. package/scripts/build-hosted-customer-lifecycle.mjs +20 -3
  239. package/scripts/build-hosted-probe-worker.mjs +19 -4
  240. package/scripts/build-installer-assets.mjs +41 -21
  241. package/scripts/build-operator-evidence-starter.mjs +59 -1
  242. package/scripts/build-production-backend-env-kit.mjs +2 -0
  243. package/scripts/build-production-unblocker.mjs +3 -0
  244. package/scripts/check.mjs +17 -3
  245. package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
  246. package/scripts/install-enigma-local.mjs +18 -5
  247. package/scripts/release-audit.mjs +65 -109
  248. package/scripts/release-provenance.mjs +6 -0
  249. package/scripts/run-backend-readiness-smoke.mjs +112 -10
  250. package/scripts/scan-secrets.mjs +1 -0
  251. package/scripts/simulate-production-env.mjs +7 -2
  252. package/scripts/validate-hosted-backend-live.mjs +112 -1
  253. package/specs/antibody-pack-v1.schema.json +95 -0
  254. package/specs/antigen-envelope-v1.schema.json +81 -0
  255. package/specs/boundary-manifest-v1.schema.json +35 -35
  256. package/specs/capsule-v1.schema.json +55 -55
  257. package/specs/claim-boundary-manifest-v1.schema.json +22 -22
  258. package/specs/claim-ledger-v1.schema.json +291 -0
  259. package/specs/context-passport-v1.schema.json +59 -0
  260. package/specs/deletion-tombstone-v1.schema.json +26 -26
  261. package/specs/evidence-packet-v1.schema.json +177 -0
  262. package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
  263. package/specs/immune-scan-report-v1.schema.json +112 -0
  264. package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
  265. package/specs/memory-atom-v1.schema.json +59 -0
  266. package/specs/memory-event-v1.schema.json +42 -42
  267. package/specs/passport-v1.schema.json +50 -50
  268. package/specs/proof-of-non-use-v1.schema.json +65 -0
  269. package/specs/quarantine-record-v1.schema.json +126 -0
  270. package/specs/receipt-v1.schema.json +61 -61
  271. package/specs/state-checkpoint-v1.schema.json +37 -37
  272. package/specs/trust-bundle-v1.schema.json +56 -56
  273. package/specs/trust-card-v1.schema.json +119 -0
  274. package/docs/proof-network-launch-plan.md +0 -421
  275. package/packages/metering/PACKAGE_CONTRACT.md +0 -20
  276. package/scripts/build-ai-orchestration-plan.mjs +0 -248
@@ -0,0 +1,187 @@
1
+ import Foundation
2
+
3
+ public enum PrivacyMode: String, Codable, Sendable, CaseIterable {
4
+ case off, smart, full
5
+ }
6
+
7
+ public enum PrivacyCategory: String, Codable, Sendable, CaseIterable {
8
+ case email, phone, ipv4, paymentCard, apiKey, privateKey, evmWallet, solanaWallet
9
+ case person, location, address, organization, medical, legalMatter, account
10
+ }
11
+
12
+ public struct SemanticPrivacyFinding: Hashable, Sendable {
13
+ public let range: Range<String.Index>
14
+ public let category: PrivacyCategory
15
+
16
+ public init(range: Range<String.Index>, category: PrivacyCategory) {
17
+ self.range = range
18
+ self.category = category
19
+ }
20
+ }
21
+
22
+ public protocol SemanticPrivacyTagging: Sendable {
23
+ func findings(in text: String) -> [SemanticPrivacyFinding]
24
+ }
25
+
26
+ public struct HeuristicSemanticPrivacyTagger: SemanticPrivacyTagging {
27
+ public init() {}
28
+
29
+ public func findings(in text: String) -> [SemanticPrivacyFinding] {
30
+ let rules: [(String, PrivacyCategory)] = [
31
+ (#"(?i)\b(?:my name is|i am|i'm)\s+([A-Z][\p{L}'-]+(?:\s+[A-Z][\p{L}'-]+){0,2})"#, .person),
32
+ (#"(?i)\b(?:i live in|i am based in|my address is)\s+([^,.!?\n]{2,80})"#, .location),
33
+ (#"(?i)\b(?:my employer is|i work (?:at|for))\s+([^,.!?\n]{2,80})"#, .organization),
34
+ (#"(?i)\b(?:my diagnosis is|i was diagnosed with)\s+([^,.!?\n]{2,80})"#, .medical),
35
+ (#"(?i)\b(?:my case number is|my lawyer is)\s+([^,.!?\n]{2,80})"#, .legalMatter),
36
+ (#"(?i)\b(?:my account number is|account id is)\s+([A-Za-z0-9_-]{4,80})"#, .account),
37
+ ]
38
+ var output: [SemanticPrivacyFinding] = []
39
+ let full = NSRange(text.startIndex..<text.endIndex, in: text)
40
+ for (pattern, category) in rules {
41
+ guard let regex = try? NSRegularExpression(pattern: pattern) else { continue }
42
+ for match in regex.matches(in: text, range: full) {
43
+ let target = match.numberOfRanges > 1 ? match.range(at: 1) : match.range
44
+ if let range = Range(target, in: text) { output.append(.init(range: range, category: category)) }
45
+ }
46
+ }
47
+ return output
48
+ }
49
+ }
50
+
51
+ public struct PrivacyReceipt: Codable, Sendable {
52
+ public struct Summary: Codable, Hashable, Sendable {
53
+ public let category: PrivacyCategory
54
+ public let action: String
55
+ public let count: Int
56
+ }
57
+
58
+ public let schema: String
59
+ public let mode: PrivacyMode
60
+ public let safeForExternal: Bool
61
+ public let inputCharacters: Int
62
+ public let outputCharacters: Int
63
+ public let summary: [Summary]
64
+ public let receiptReference: UUID
65
+
66
+ public init(mode: PrivacyMode, safeForExternal: Bool, inputCharacters: Int, outputCharacters: Int, summary: [Summary], receiptReference: UUID = UUID()) {
67
+ self.schema = "enigma.ios_privacy_receipt.v1"
68
+ self.mode = mode
69
+ self.safeForExternal = safeForExternal
70
+ self.inputCharacters = inputCharacters
71
+ self.outputCharacters = outputCharacters
72
+ self.summary = summary
73
+ self.receiptReference = receiptReference
74
+ }
75
+ }
76
+
77
+ public final class PrivacySession: @unchecked Sendable {
78
+ public let messages: [EnigmaMessage]
79
+ public let receipt: PrivacyReceipt
80
+ private let lock = NSLock()
81
+ private var replacements: [String: String]
82
+
83
+ init(messages: [EnigmaMessage], receipt: PrivacyReceipt, replacements: [String: String]) {
84
+ self.messages = messages
85
+ self.receipt = receipt
86
+ self.replacements = replacements
87
+ }
88
+
89
+ public func restore(_ value: String) -> String {
90
+ lock.lock()
91
+ let current = replacements
92
+ lock.unlock()
93
+ return current.reduce(value) { output, replacement in output.replacingOccurrences(of: replacement.key, with: replacement.value) }
94
+ }
95
+
96
+ public func dispose() {
97
+ lock.lock()
98
+ replacements.removeAll(keepingCapacity: false)
99
+ lock.unlock()
100
+ }
101
+
102
+ deinit { dispose() }
103
+ }
104
+
105
+ public struct PrivacyMinimizer: Sendable {
106
+ private struct Rule: Sendable {
107
+ let pattern: String
108
+ let category: PrivacyCategory
109
+ let validator: @Sendable (String) -> Bool
110
+ }
111
+
112
+ private let rules: [Rule] = [
113
+ .init(pattern: #"(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b"#, category: .email, validator: { _ in true }),
114
+ .init(pattern: #"\b(?:\+?\d[\d .()-]{7,}\d)\b"#, category: .phone, validator: { value in value.filter(\.isNumber).count >= 8 }),
115
+ .init(pattern: #"\b(?:\d{1,3}\.){3}\d{1,3}\b"#, category: .ipv4, validator: { value in value.split(separator: ".").allSatisfy { (0...255).contains(Int($0) ?? -1) } }),
116
+ .init(pattern: #"\b(?:\d[ -]*?){13,19}\b"#, category: .paymentCard, validator: Self.luhn),
117
+ .init(pattern: #"(?i)\b(?:sk|pk|api|token|key)[_-](?:live|test)?[_-]?[A-Za-z0-9]{16,}\b"#, category: .apiKey, validator: { _ in true }),
118
+ .init(pattern: #"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"#, category: .privateKey, validator: { _ in true }),
119
+ .init(pattern: #"\b0x[a-fA-F0-9]{40}\b"#, category: .evmWallet, validator: { _ in true }),
120
+ .init(pattern: #"\b[1-9A-HJ-NP-Za-km-z]{32,44}\b"#, category: .solanaWallet, validator: { _ in true }),
121
+ ]
122
+ private let semanticTagger: any SemanticPrivacyTagging
123
+
124
+ public init(semanticTagger: any SemanticPrivacyTagging = HeuristicSemanticPrivacyTagger()) {
125
+ self.semanticTagger = semanticTagger
126
+ }
127
+
128
+ public func minimize(_ messages: [EnigmaMessage], mode: PrivacyMode) -> PrivacySession {
129
+ guard mode != .off else {
130
+ let count = messages.reduce(0) { $0 + $1.content.count }
131
+ return PrivacySession(messages: messages, receipt: .init(mode: mode, safeForExternal: true, inputCharacters: count, outputCharacters: count, summary: []), replacements: [:])
132
+ }
133
+ var replacements: [String: String] = [:]
134
+ var counts: [PrivacyCategory: Int] = [:]
135
+ let inputCharacters = messages.reduce(0) { $0 + $1.content.count }
136
+ let minimized = messages.map { message -> EnigmaMessage in
137
+ guard message.role == .user || message.role == .system else { return message }
138
+ if mode == .full {
139
+ counts[.account, default: 0] += 1
140
+ return EnigmaMessage(id: message.id, role: message.role, content: "[PRIVATE_INPUT_WITHHELD]", createdAt: message.createdAt)
141
+ }
142
+ var text = message.content
143
+ var candidates: [(Range<String.Index>, PrivacyCategory)] = []
144
+ for rule in rules {
145
+ guard let regex = try? NSRegularExpression(pattern: rule.pattern) else { continue }
146
+ let full = NSRange(text.startIndex..<text.endIndex, in: text)
147
+ for match in regex.matches(in: text, range: full) {
148
+ guard let range = Range(match.range, in: text), rule.validator(String(text[range])) else { continue }
149
+ candidates.append((range, rule.category))
150
+ }
151
+ }
152
+ candidates.append(contentsOf: semanticTagger.findings(in: text).map { ($0.range, $0.category) })
153
+ let nonOverlapping = candidates.sorted { $0.0.lowerBound > $1.0.lowerBound }.reduce(into: [(Range<String.Index>, PrivacyCategory)]()) { accepted, candidate in
154
+ if !accepted.contains(where: { $0.0.overlaps(candidate.0) }) { accepted.append(candidate) }
155
+ }
156
+ for (range, category) in nonOverlapping {
157
+ let raw = String(text[range])
158
+ let token = "⟪ENIGMA_\(category.rawValue.uppercased())_\(UUID().uuidString)⟫"
159
+ text.replaceSubrange(range, with: token)
160
+ replacements[token] = raw
161
+ counts[category, default: 0] += 1
162
+ }
163
+ return EnigmaMessage(id: message.id, role: message.role, content: text, createdAt: message.createdAt)
164
+ }
165
+ let outputCharacters = minimized.reduce(0) { $0 + $1.content.count }
166
+ let summary = counts.keys.sorted { $0.rawValue < $1.rawValue }.map {
167
+ PrivacyReceipt.Summary(category: $0, action: mode == .full ? "withheld" : "masked", count: counts[$0] ?? 0)
168
+ }
169
+ return PrivacySession(
170
+ messages: minimized,
171
+ receipt: .init(mode: mode, safeForExternal: mode == .full || !summary.isEmpty, inputCharacters: inputCharacters, outputCharacters: outputCharacters, summary: summary),
172
+ replacements: replacements
173
+ )
174
+ }
175
+
176
+ private static func luhn(_ value: String) -> Bool {
177
+ let digits = value.compactMap(\.wholeNumberValue)
178
+ guard (13...19).contains(digits.count) else { return false }
179
+ let sum = digits.reversed().enumerated().reduce(0) { partial, element in
180
+ let (index, digit) = element
181
+ if index.isMultiple(of: 2) { return partial + digit }
182
+ let doubled = digit * 2
183
+ return partial + (doubled > 9 ? doubled - 9 : doubled)
184
+ }
185
+ return sum.isMultiple(of: 10)
186
+ }
187
+ }
@@ -0,0 +1,129 @@
1
+ import Foundation
2
+
3
+ public struct VideoQueueRequest: Codable, Sendable {
4
+ public let prompt: String
5
+ public let model: String
6
+ public let duration: Int
7
+ public let resolution: String
8
+ public let aspectRatio: String
9
+
10
+ public init(prompt: String, model: String, duration: Int = 5, resolution: String = "720p", aspectRatio: String = "16:9") {
11
+ self.prompt = prompt
12
+ self.model = model
13
+ self.duration = duration
14
+ self.resolution = resolution
15
+ self.aspectRatio = aspectRatio
16
+ }
17
+
18
+ enum CodingKeys: String, CodingKey {
19
+ case prompt, model, duration, resolution
20
+ case aspectRatio = "aspect_ratio"
21
+ }
22
+ }
23
+
24
+ public struct VideoJob: Codable, Sendable {
25
+ public let id: String
26
+ public let model: String
27
+ public let provider: String
28
+ public let status: String
29
+ public let progress: Double
30
+ public let error: String?
31
+ }
32
+
33
+ public struct VideoAsset: Codable, Sendable {
34
+ public let url: String?
35
+ public let base64: String?
36
+ public let mimeType: String?
37
+
38
+ enum CodingKeys: String, CodingKey {
39
+ case url, base64
40
+ case mimeType = "mimeType"
41
+ }
42
+ }
43
+
44
+ public struct VideoRetrieveResponse: Decodable, Sendable {
45
+ public let job: VideoJob
46
+ public let asset: VideoAsset?
47
+
48
+ public init(from decoder: Decoder) throws {
49
+ let container = try decoder.container(keyedBy: DynamicCodingKey.self)
50
+ if container.contains(DynamicCodingKey("job")) {
51
+ job = try container.decode(VideoJob.self, forKey: DynamicCodingKey("job"))
52
+ asset = try container.decodeIfPresent(VideoAsset.self, forKey: DynamicCodingKey("asset"))
53
+ } else {
54
+ job = try VideoJob(from: decoder)
55
+ asset = nil
56
+ }
57
+ }
58
+ }
59
+
60
+ public struct CodeSession: Codable, Sendable {
61
+ public let id: String
62
+ public let provider: String
63
+ public let status: String
64
+ public let language: String
65
+ public let network: String
66
+ }
67
+
68
+ public struct CodeSessionEnvelope: Codable, Sendable { public let session: CodeSession }
69
+ public struct CodeUploadRequest: Codable, Sendable {
70
+ public let path: String
71
+ public let data: String
72
+ public let encoding: String
73
+ public init(path: String = "main.js", data: String, encoding: String = "utf8") {
74
+ self.path = path; self.data = data; self.encoding = encoding
75
+ }
76
+ }
77
+ public struct CodeExecuteRequest: Codable, Sendable {
78
+ public let entry: String
79
+ public init(entry: String = "main.js") { self.entry = entry }
80
+ }
81
+ public struct CodeExecutionResponse: Codable, Sendable {
82
+ public let ok: Bool
83
+ public let code: Int?
84
+ public let signal: String?
85
+ public let timedOut: Bool?
86
+ public let session: CodeSession
87
+ }
88
+ public struct CodeEventData: Codable, Sendable {
89
+ public let stream: String?
90
+ public let data: String?
91
+ public let message: String?
92
+ }
93
+ public struct CodeEvent: Codable, Identifiable, Sendable {
94
+ public var id: Int { cursor }
95
+ public let cursor: Int
96
+ public let type: String
97
+ public let data: CodeEventData?
98
+ }
99
+ public struct CodeEventsResponse: Codable, Sendable {
100
+ public let session: CodeSession
101
+ public let events: [CodeEvent]
102
+ }
103
+
104
+ public struct BrowserPrivacy: Codable, Sendable {
105
+ public let ephemeralProfile: Bool
106
+ public let privateNetworkBlocked: Bool
107
+ public let egressLayer: String?
108
+ public let egressPolicyHash: String?
109
+ }
110
+ public struct BrowserSession: Codable, Sendable {
111
+ public let id: String
112
+ public let provider: String
113
+ public let state: String
114
+ public let streamUrl: String?
115
+ public let privacy: BrowserPrivacy
116
+ }
117
+ public struct BrowserSessionEnvelope: Codable, Sendable { public let session: BrowserSession }
118
+ public struct BrowserNavigateRequest: Codable, Sendable {
119
+ public let url: String
120
+ public init(url: String) { self.url = url }
121
+ }
122
+
123
+ private struct DynamicCodingKey: CodingKey {
124
+ let stringValue: String
125
+ let intValue: Int? = nil
126
+ init(_ value: String) { stringValue = value }
127
+ init?(stringValue: String) { self.stringValue = stringValue }
128
+ init?(intValue: Int) { return nil }
129
+ }
@@ -0,0 +1,42 @@
1
+ import Foundation
2
+ import Testing
3
+ @testable import EnigmaCore
4
+
5
+ @Test func pkceMatchesRFC7636Vector() {
6
+ let verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
7
+ #expect(PKCE.challenge(for: verifier) == "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM")
8
+ }
9
+ @Test func iosOAuthScopeContractCoversEveryMobileSurface() {
10
+ #expect(Set(EnigmaOAuthScopes.iOSPlatform) == Set([
11
+ "models:invoke",
12
+ "images:generate",
13
+ "video:generate",
14
+ "code:execute",
15
+ "browser:control",
16
+ "usage:read",
17
+ "credits:create",
18
+ "offline_access",
19
+ ]))
20
+ }
21
+
22
+
23
+ @Test func smartPrivacyMasksRestoresAndKeepsReceiptContentFree() throws {
24
+ let canary = "Alice Smith"
25
+ let messages = [EnigmaMessage(role: .user, content: "My name is \(canary), email alice@example.com, and I live in Paris.")]
26
+ let session = PrivacyMinimizer().minimize(messages, mode: .smart)
27
+ #expect(!session.messages[0].content.contains(canary))
28
+ #expect(!session.messages[0].content.contains("alice@example.com"))
29
+ #expect(session.restore(session.messages[0].content).contains(canary))
30
+ let receipt = try JSONEncoder().encode(session.receipt)
31
+ let serialized = String(decoding: receipt, as: UTF8.self)
32
+ #expect(!serialized.contains(canary))
33
+ #expect(!serialized.contains("alice@example.com"))
34
+ session.dispose()
35
+ #expect(!session.restore(session.messages[0].content).contains(canary))
36
+ }
37
+
38
+ @Test func fullPrivacyWithholdsUserInput() {
39
+ let session = PrivacyMinimizer().minimize([EnigmaMessage(role: .user, content: "private prose")], mode: .full)
40
+ #expect(session.messages[0].content == "[PRIVATE_INPUT_WITHHELD]")
41
+ #expect(session.receipt.mode == .full)
42
+ }