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
@@ -1,8 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { once } from 'node:events';
3
3
  import { pathToFileURL } from 'node:url';
4
- import { createRelayServer } from '../apps/relay/src/server.mjs';
5
- import { createGatewayServer } from '../apps/gateway/src/server.mjs';
4
+ import {
5
+ FEDERATION_STORAGE_ADAPTER_SCHEMA,
6
+ RELAY_STATE_ADAPTER_SCHEMA,
7
+ createRelayServer,
8
+ } from '../apps/relay/src/server.mjs';
9
+ import {
10
+ GATEWAY_KMS_SIGNER_ADAPTER_SCHEMA,
11
+ GATEWAY_SIEM_SINK_ADAPTER_SCHEMA,
12
+ GATEWAY_STATE_ADAPTER_SCHEMA,
13
+ createGatewayServer,
14
+ } from '../apps/gateway/src/server.mjs';
6
15
 
7
16
  export const BACKEND_READINESS_SMOKE_SCHEMA = 'enigma.backend_readiness_smoke.v1';
8
17
 
@@ -21,6 +30,76 @@ const SHARED_READINESS_REFS = Object.freeze({
21
30
  incident_drill_ref: 'incident-drill-smoke-ref',
22
31
  backup_restore_drill_ref: 'backup-restore-drill-smoke-ref',
23
32
  });
33
+ function transactionalStateAdapter(schema, service, ready) {
34
+ let snapshot = null;
35
+ return {
36
+ schema,
37
+ ref: `fixture://${service}/durable-state`,
38
+ durable: true,
39
+ encryptedAtRest: true,
40
+ supportsMultiReplica: true,
41
+ async isReady() { return ready; },
42
+ async transaction(operation, options) {
43
+ const result = await operation(snapshot ?? options.initialSnapshot);
44
+ snapshot = structuredClone(result.snapshot);
45
+ return result.value;
46
+ },
47
+ };
48
+ }
49
+
50
+ function federationFixture(service, ready) {
51
+ const bridge = {
52
+ started: false,
53
+ async start() { this.started = true; },
54
+ async stop() { this.started = false; },
55
+ };
56
+ return {
57
+ storage: {
58
+ schema: FEDERATION_STORAGE_ADAPTER_SCHEMA,
59
+ ref: `fixture://${service}/opaque-federation-storage`,
60
+ durable: true,
61
+ async isReady() { return ready; },
62
+ async appendOpaqueFrame() {},
63
+ },
64
+ authenticator: {
65
+ ref: `fixture://${service}/federation-auth`,
66
+ async isReady() { return ready; },
67
+ async authenticate() { return { ok: false }; },
68
+ },
69
+ bridge,
70
+ kmsRef: `fixture://${service}/kms-custody`,
71
+ };
72
+ }
73
+
74
+ function relayRuntimeFixture(ready) {
75
+ return {
76
+ relayStateAdapter: transactionalStateAdapter(RELAY_STATE_ADAPTER_SCHEMA, 'relay', ready),
77
+ federation: federationFixture('relay', ready),
78
+ };
79
+ }
80
+
81
+ function gatewayRuntimeFixture(ready) {
82
+ return {
83
+ gatewayStateAdapter: transactionalStateAdapter(GATEWAY_STATE_ADAPTER_SCHEMA, 'gateway', ready),
84
+ kmsSignerAdapter: {
85
+ schema: GATEWAY_KMS_SIGNER_ADAPTER_SCHEMA,
86
+ ref: 'fixture://gateway/kms-signer',
87
+ publicKey: 'fixture-public-key-not-used-by-readiness-smoke',
88
+ async isReady() { return ready; },
89
+ async createDecision() { throw new Error('readiness smoke does not request a gateway decision'); },
90
+ },
91
+ siemSinkAdapter: {
92
+ schema: GATEWAY_SIEM_SINK_ADAPTER_SCHEMA,
93
+ ref: 'fixture://gateway/siem-sink',
94
+ durable: true,
95
+ idempotent: true,
96
+ async isReady() { return ready; },
97
+ async appendBatch() {},
98
+ },
99
+ federation: federationFixture('gateway', ready),
100
+ };
101
+ }
102
+
24
103
 
25
104
  function parseArgs(argv = process.argv.slice(2)) {
26
105
  const flags = new Map();
@@ -38,7 +117,7 @@ function parseArgs(argv = process.argv.slice(2)) {
38
117
  }
39
118
 
40
119
  function usage() {
41
- return `Usage: node scripts/run-backend-readiness-smoke.mjs [--host 127.0.0.1]\n\nStarts in-process relay/gateway HTTP servers on loopback ephemeral ports, probes /livez and /readyz,\nand verifies fail-closed production readiness plus a fully referenced production-ready local fixture.\nIt does not expose admin/data routes, provision cloud resources, or prove hosted live infrastructure.\n`;
120
+ return `Usage: node scripts/run-backend-readiness-smoke.mjs [--host 127.0.0.1]\n\nStarts in-process relay/gateway HTTP servers on loopback ephemeral ports, probes /livez and /readyz,\nand verifies fail-closed production readiness plus an explicit operational-runtime fixture with durable state, KMS signer, SIEM sink, federation storage/authentication, and all evidence refs.\nIt does not expose credentials, provision cloud resources, or prove hosted live infrastructure.\n`;
42
121
  }
43
122
 
44
123
  function listen(server, host) {
@@ -53,13 +132,19 @@ function listen(server, host) {
53
132
  }
54
133
 
55
134
  async function close(server) {
135
+ await server.federationRuntime?.stop();
56
136
  if (!server.listening) return;
57
137
  server.close();
138
+ server.closeAllConnections?.();
58
139
  await once(server, 'close');
59
140
  }
60
141
 
61
142
  async function getJson(baseUrl, path) {
62
- const response = await fetch(`${baseUrl}${path}`, { method: 'GET', headers: { accept: 'application/json' } });
143
+ const response = await fetch(`${baseUrl}${path}`, {
144
+ method: 'GET',
145
+ headers: { accept: 'application/json' },
146
+ signal: AbortSignal.timeout(5_000),
147
+ });
63
148
  const text = await response.text();
64
149
  if (SECRET_OUTPUT_RE.test(text)) throw new Error(`${baseUrl}${path} emitted secret-looking output`);
65
150
  let body;
@@ -97,6 +182,7 @@ function relayReadyOptions() {
97
182
  monitoring_ref: 'relay-monitoring-smoke-ref',
98
183
  ...SHARED_READINESS_REFS,
99
184
  operator_acceptance: { decision: 'go', status: 'go', ref: 'relay-operator-acceptance-smoke-ref' },
185
+ ...relayRuntimeFixture(true),
100
186
  };
101
187
  }
102
188
 
@@ -115,6 +201,9 @@ function gatewayReadyOptions() {
115
201
  data_plane_auth_ref: 'gateway-data-plane-auth-smoke-ref',
116
202
  ...SHARED_READINESS_REFS,
117
203
  operator_acceptance: { decision: 'go', status: 'go', ref: 'gateway-operator-acceptance-smoke-ref' },
204
+ admin_auth_bearer_sha256: `sha256:${'a'.repeat(64)}`,
205
+ data_plane_auth_bearer_sha256: `sha256:${'b'.repeat(64)}`,
206
+ ...gatewayRuntimeFixture(true),
118
207
  };
119
208
  }
120
209
 
@@ -122,9 +211,18 @@ async function probeServer({ service, mode, serverFactory, host, expectedReadySt
122
211
  const server = serverFactory();
123
212
  try {
124
213
  const address = await listen(server, host);
214
+ await server.federationRuntime?.start();
125
215
  const baseUrl = `http://${address.address}:${address.port}`;
126
216
  const livez = await getJson(baseUrl, '/livez');
127
217
  const readyz = await getJson(baseUrl, '/readyz');
218
+ const failedChecks = Array.isArray(readyz.body?.checks)
219
+ ? readyz.body.checks
220
+ .filter((check) => check?.ok !== true && typeof (check?.check ?? check?.name) === 'string')
221
+ .map((check) => check.check ?? check.name)
222
+ : [];
223
+ const missingChecks = Array.isArray(readyz.body?.missing_checks) && readyz.body.missing_checks.length > 0
224
+ ? [...readyz.body.missing_checks]
225
+ : failedChecks;
128
226
  return {
129
227
  service,
130
228
  mode,
@@ -134,6 +232,10 @@ async function probeServer({ service, mode, serverFactory, host, expectedReadySt
134
232
  livez_ok: livez.body?.ok === true,
135
233
  readyz_status: readyz.status,
136
234
  readyz_ok: readyz.body?.ok === true,
235
+ readyz_missing_checks: missingChecks,
236
+ readyz_blocker_paths: missingChecks.length > 0
237
+ ? missingChecks.map((check) => `checks.${check}`)
238
+ : (readyz.body?.error !== undefined ? ['error'] : []),
137
239
  readyz_missing_evidence_ref_count: missingCount(readyz.body),
138
240
  readyz_all_checks_ok: allChecksOk(readyz.body),
139
241
  ok: livez.status === 200
@@ -157,7 +259,7 @@ export async function runBackendReadinessSmoke(options = {}) {
157
259
  host,
158
260
  expectedReadyStatus: 503,
159
261
  expectedReadyOk: false,
160
- serverFactory: () => createRelayServer({ mode: 'production', now: '1970-01-01T00:00:00.000Z' }),
262
+ serverFactory: () => createRelayServer({ mode: 'production', now: '1970-01-01T00:00:00.000Z', ...relayRuntimeFixture(false) }),
161
263
  }));
162
264
  checks.push(await probeServer({
163
265
  service: 'gateway',
@@ -165,11 +267,11 @@ export async function runBackendReadinessSmoke(options = {}) {
165
267
  host,
166
268
  expectedReadyStatus: 503,
167
269
  expectedReadyOk: false,
168
- serverFactory: () => createGatewayServer({ mode: 'production' }),
270
+ serverFactory: () => createGatewayServer({ mode: 'production', ...gatewayRuntimeFixture(false) }),
169
271
  }));
170
272
  checks.push(await probeServer({
171
273
  service: 'relay',
172
- mode: 'production-referenced-fixture',
274
+ mode: 'production-operational-fixture',
173
275
  host,
174
276
  expectedReadyStatus: 200,
175
277
  expectedReadyOk: true,
@@ -177,7 +279,7 @@ export async function runBackendReadinessSmoke(options = {}) {
177
279
  }));
178
280
  checks.push(await probeServer({
179
281
  service: 'gateway',
180
- mode: 'production-referenced-fixture',
282
+ mode: 'production-operational-fixture',
181
283
  host,
182
284
  expectedReadyStatus: 200,
183
285
  expectedReadyOk: true,
@@ -192,8 +294,8 @@ export async function runBackendReadinessSmoke(options = {}) {
192
294
  checks,
193
295
  claim_boundary: [
194
296
  'This smoke starts local in-process HTTP servers on loopback ephemeral ports only.',
195
- 'It verifies /livez and /readyz behavior, fail-closed production defaults, and fully referenced production fixture readiness.',
196
- 'It does not prove hosted DNS, TLS, Cloudflare, durable cloud storage, KMS, SIEM, backup, operator acceptance, or customer BYOC infrastructure is live.',
297
+ 'It verifies fail-closed production defaults and an explicit operational fixture with durable transactional state, gateway KMS/SIEM adapters, authenticated federation dependencies, and all readiness refs.',
298
+ 'Fixture adapters are test-scoped and do not prove hosted DNS, TLS, durable cloud storage, KMS, SIEM, backup, operator acceptance, or customer BYOC infrastructure is live.',
197
299
  ],
198
300
  };
199
301
  if (SECRET_OUTPUT_RE.test(JSON.stringify(result))) throw new Error('backend readiness smoke output appears to contain a secret');
@@ -30,6 +30,7 @@ const SKIP_DIRS = new Set([
30
30
  'tmp',
31
31
  '.vscode',
32
32
  '.idea',
33
+ '.next',
33
34
  ])
34
35
 
35
36
  const SKIP_EXTENSIONS = new Set([
@@ -13,6 +13,7 @@ import { fileURLToPath } from 'node:url'
13
13
 
14
14
  const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
15
15
  const DEFAULT_SECRETS_DIR = path.join(os.homedir(), '.enigma', 'simulation-secrets')
16
+ const DOCKER_READABLE_SECRET_MODE = 0o644
16
17
 
17
18
  const REQUIRED_SECRET_FILES = [
18
19
  'relay-signing-key',
@@ -109,7 +110,8 @@ const SECRET_GENERATORS = {
109
110
  }
110
111
 
111
112
  function ensureDir(dir) {
112
- fs.mkdirSync(dir, { recursive: true })
113
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 })
114
+ if (process.platform !== 'win32') fs.chmodSync(dir, 0o700)
113
115
  }
114
116
 
115
117
  function isMissingOrEmpty(filePath) {
@@ -200,8 +202,11 @@ function generateSecrets(secretsDir) {
200
202
  if (name === 'tls.crt' || name === 'tls.key') continue
201
203
  const filePath = path.join(secretsDir, name)
202
204
  if (isMissingOrEmpty(filePath)) {
203
- fs.writeFileSync(filePath, SECRET_GENERATORS[name](), { mode: 0o600 })
205
+ fs.writeFileSync(filePath, SECRET_GENERATORS[name](), { mode: DOCKER_READABLE_SECRET_MODE })
204
206
  }
207
+ // Compose file-backed secrets preserve host file bits. The parent directory
208
+ // remains owner-only while non-root simulation containers receive read access.
209
+ if (process.platform !== 'win32') fs.chmodSync(filePath, DOCKER_READABLE_SECRET_MODE)
205
210
  }
206
211
  const keyPath = path.join(secretsDir, 'tls.key')
207
212
  const certPath = path.join(secretsDir, 'tls.crt')
@@ -5,6 +5,9 @@ import { fileURLToPath } from 'node:url';
5
5
 
6
6
  export const HOSTED_BACKEND_LIVE_EVIDENCE_SCHEMA = 'enigma.hosted_backend_live_evidence.v1';
7
7
  export const HOSTED_BACKEND_LIVE_RESULT_SCHEMA = 'enigma.hosted_backend_live_result.v1';
8
+ export const HOSTED_BACKEND_RUNTIME_CAPABILITY_SCHEMA = 'enigma.hosted_backend_runtime_capability.v1';
9
+ export const HOSTED_BACKEND_AUTHENTICATED_DATA_PLANE_SCHEMA = 'enigma.hosted_backend_authenticated_data_plane.v1';
10
+ export const PRIVATE_DATA_PLANE_RUNTIME_MARKER = 'enigma.private_data_plane.runtime.v1';
8
11
 
9
12
  export const REQUIRED_REF_KEYS = Object.freeze([
10
13
  'backend_host',
@@ -35,6 +38,11 @@ export const REQUIRED_REF_KEYS = Object.freeze([
35
38
  ]);
36
39
 
37
40
  const REQUIRED_PROBES = Object.freeze(['relay_livez', 'relay_readyz', 'gateway_livez', 'gateway_readyz']);
41
+ const RUNTIME_SERVICES = Object.freeze(['relay', 'gateway']);
42
+ const DATA_PLANE_ROUTES = Object.freeze({
43
+ relay: Object.freeze(['/relay/records', '/pairing/challenge', '/pairing/complete']),
44
+ gateway: Object.freeze(['/policy', '/gateway/evaluate', '/gateway/decision', '/siem/export']),
45
+ });
38
46
  const ACCEPTED_STATUSES = new Set(['observed', 'verified', 'go', 'accepted']);
39
47
  const SECRET_VALUE_RE = /(?:Bearer\s+[A-Za-z0-9._~+/=-]{12,}|Basic\s+[A-Za-z0-9+/=-]{12,}|-----BEGIN [A-Z ]*PRIVATE KEY-----|https?:\/\/[^\s/@]+:[^\s/@]+@|raw memory|private prompt|full transcript|decrypted capsule|sk-[A-Za-z0-9_-]{16,}|AKIA[0-9A-Z]{16})/iu;
40
48
  const FORBIDDEN_KEY_RE = /(?:password|passwd|pwd|token|api[_-]?key|private[_-]?key|secret|raw[_-]?memory|plaintext|plain[_-]?text|prompt|completion|transcript|embedding|provider[_-]?response|cookie|session)/iu;
@@ -151,6 +159,12 @@ function validateEnvironment(environment, blockers) {
151
159
  for (const field of ['environment_id', 'cloud_provider', 'region', 'owner', 'status']) {
152
160
  if (!nonEmptyString(environment[field])) blockers.push(blocker(`environment.${field} is required`, `environment.${field}`));
153
161
  }
162
+ if (environment.local_simulation !== false) {
163
+ blockers.push(blocker('environment.local_simulation must be false for hosted production evidence', 'environment.local_simulation'));
164
+ }
165
+ if (nonEmptyString(environment.cloud_provider) && environment.cloud_provider.trim().toLowerCase() === 'local') {
166
+ blockers.push(blocker('environment.cloud_provider must identify a non-simulation production provider', 'environment.cloud_provider'));
167
+ }
154
168
  if (!statusAccepted(environment.status)) blockers.push(blocker('environment.status must be observed/verified/go/accepted', 'environment.status'));
155
169
  return { domain };
156
170
  }
@@ -179,6 +193,9 @@ function validateProbe(probe, expectedName, domain, blockers) {
179
193
  if (probe.body.hosted_probe_only === true || probe.body.pages_edge_probe_only === true) {
180
194
  blockers.push(blocker(`${path}.body must not be an edge-probe-only payload`, `${path}.body`));
181
195
  }
196
+ if (probe.body.hosted_backend_live === false || probe.body.private_data_plane_operational === false || probe.body.runtime_capability?.bootstrap_worker === true) {
197
+ blockers.push(blocker(`${path}.body declares the private data plane closed or bootstrap-only`, `${path}.body.runtime_capability`));
198
+ }
182
199
  if (probe.body.service !== expectedService) blockers.push(blocker(`${path}.body.service must be ${expectedService}`, `${path}.body.service`));
183
200
  if (probe.body.ok !== true) blockers.push(blocker(`${path}.body.ok must be true`, `${path}.body.ok`));
184
201
  if (expectedName.endsWith('readyz')) {
@@ -203,6 +220,94 @@ function validateProbes(probes, domain, blockers) {
203
220
  return { covered };
204
221
  }
205
222
 
223
+ function validateRuntimeCapability(capability, blockers) {
224
+ if (!isPlainObject(capability)) {
225
+ blockers.push(blocker('runtime_capability object is required', 'runtime_capability'));
226
+ return { covered: 0 };
227
+ }
228
+ if (capability.schema !== HOSTED_BACKEND_RUNTIME_CAPABILITY_SCHEMA) blockers.push(blocker(`runtime_capability.schema must be ${HOSTED_BACKEND_RUNTIME_CAPABILITY_SCHEMA}`, 'runtime_capability.schema'));
229
+ if (capability.marker !== PRIVATE_DATA_PLANE_RUNTIME_MARKER) blockers.push(blocker(`runtime_capability.marker must be ${PRIVATE_DATA_PLANE_RUNTIME_MARKER}`, 'runtime_capability.marker'));
230
+ if (!isoLike(capability.observed_at)) blockers.push(blocker('runtime_capability.observed_at must be ISO time', 'runtime_capability.observed_at'));
231
+ if (!isPlainObject(capability.services)) {
232
+ blockers.push(blocker('runtime_capability.services object is required', 'runtime_capability.services'));
233
+ return { covered: 0 };
234
+ }
235
+ let covered = 0;
236
+ for (const serviceKey of RUNTIME_SERVICES) {
237
+ const path = `runtime_capability.services.${serviceKey}`;
238
+ const service = capability.services[serviceKey];
239
+ if (!isPlainObject(service)) {
240
+ blockers.push(blocker(`${path} object is required`, path));
241
+ continue;
242
+ }
243
+ const expectedService = serviceKey === 'relay' ? 'enigma-relay' : 'enigma-gateway';
244
+ if (service.service !== expectedService) blockers.push(blocker(`${path}.service must be ${expectedService}`, `${path}.service`));
245
+ if (service.private_data_plane_operational !== true) blockers.push(blocker(`${path}.private_data_plane_operational must be true`, `${path}.private_data_plane_operational`));
246
+ if (service.authentication_enforced !== true) blockers.push(blocker(`${path}.authentication_enforced must be true`, `${path}.authentication_enforced`));
247
+ if (service.bootstrap_worker !== false) blockers.push(blocker(`${path}.bootstrap_worker must be false`, `${path}.bootstrap_worker`));
248
+ if (!nonEmptyString(service.evidence_ref)) blockers.push(blocker(`${path}.evidence_ref is required`, `${path}.evidence_ref`));
249
+ covered += 1;
250
+ }
251
+ return { covered };
252
+ }
253
+
254
+ function authenticatedDataPlaneUrl(value, serviceKey, domain, path, blockers) {
255
+ if (!nonEmptyString(value)) {
256
+ blockers.push(blocker(`${path} is required`, path));
257
+ return null;
258
+ }
259
+ try {
260
+ const url = new URL(value);
261
+ if (url.protocol !== 'https:') blockers.push(blocker(`${path} must use https`, path));
262
+ if (url.username || url.password) blockers.push(blocker(`${path} must not include credentials`, path));
263
+ if (url.search || url.hash) blockers.push(blocker(`${path} must not include query strings or fragments`, path));
264
+ if (isPrivateHost(url.hostname)) blockers.push(blocker(`${path} must not target localhost or private network host`, path));
265
+ const hostname = url.hostname.toLowerCase();
266
+ if (domain && hostname !== domain && !hostname.endsWith(`.${domain}`)) blockers.push(blocker(`${path} host must be the domain or a subdomain`, path));
267
+ if (!DATA_PLANE_ROUTES[serviceKey].includes(url.pathname)) blockers.push(blocker(`${path} must target a ${serviceKey} private data-plane route`, path));
268
+ return url;
269
+ } catch {
270
+ blockers.push(blocker(`${path} must be a valid URL`, path));
271
+ return null;
272
+ }
273
+ }
274
+
275
+ function validateAuthenticatedDataPlane(evidence, domain, blockers) {
276
+ if (!isPlainObject(evidence)) {
277
+ blockers.push(blocker('authenticated_data_plane object is required', 'authenticated_data_plane'));
278
+ return { covered: 0 };
279
+ }
280
+ if (evidence.schema !== HOSTED_BACKEND_AUTHENTICATED_DATA_PLANE_SCHEMA) blockers.push(blocker(`authenticated_data_plane.schema must be ${HOSTED_BACKEND_AUTHENTICATED_DATA_PLANE_SCHEMA}`, 'authenticated_data_plane.schema'));
281
+ if (!isoLike(evidence.observed_at)) blockers.push(blocker('authenticated_data_plane.observed_at must be ISO time', 'authenticated_data_plane.observed_at'));
282
+ if (!isPlainObject(evidence.proofs)) {
283
+ blockers.push(blocker('authenticated_data_plane.proofs object is required', 'authenticated_data_plane.proofs'));
284
+ return { covered: 0 };
285
+ }
286
+ let covered = 0;
287
+ for (const serviceKey of RUNTIME_SERVICES) {
288
+ const path = `authenticated_data_plane.proofs.${serviceKey}`;
289
+ const proof = evidence.proofs[serviceKey];
290
+ if (!isPlainObject(proof)) {
291
+ blockers.push(blocker(`${path} object is required`, path));
292
+ continue;
293
+ }
294
+ const expectedService = serviceKey === 'relay' ? 'enigma-relay' : 'enigma-gateway';
295
+ if (proof.service !== expectedService) blockers.push(blocker(`${path}.service must be ${expectedService}`, `${path}.service`));
296
+ authenticatedDataPlaneUrl(proof.url, serviceKey, domain, `${path}.url`, blockers);
297
+ if (!['GET', 'POST', 'PUT', 'DELETE'].includes(proof.method)) blockers.push(blocker(`${path}.method must be GET/POST/PUT/DELETE`, `${path}.method`));
298
+ if (!Number.isSafeInteger(proof.status_code) || proof.status_code < 200 || proof.status_code >= 300) blockers.push(blocker(`${path}.status_code must be a successful 2xx response`, `${path}.status_code`));
299
+ if (proof.authenticated !== true) blockers.push(blocker(`${path}.authenticated must be true`, `${path}.authenticated`));
300
+ if (proof.authorization_result !== 'allowed') blockers.push(blocker(`${path}.authorization_result must be allowed`, `${path}.authorization_result`));
301
+ if (!isoLike(proof.observed_at)) blockers.push(blocker(`${path}.observed_at must be ISO time`, `${path}.observed_at`));
302
+ for (const field of ['request_hash', 'response_hash']) {
303
+ if (!nonEmptyString(proof[field]) || !/^sha256:[a-f0-9]{64}$/i.test(proof[field])) blockers.push(blocker(`${path}.${field} must be sha256:<64 hex>`, `${path}.${field}`));
304
+ }
305
+ if (!nonEmptyString(proof.evidence_ref)) blockers.push(blocker(`${path}.evidence_ref is required`, `${path}.evidence_ref`));
306
+ covered += 1;
307
+ }
308
+ return { covered };
309
+ }
310
+
206
311
  function validateOperator(operatorAcceptance, blockers) {
207
312
  if (!isPlainObject(operatorAcceptance)) {
208
313
  blockers.push(blocker('operator_acceptance object is required', 'operator_acceptance'));
@@ -238,6 +343,8 @@ export function validateHostedBackendLiveEvidence(evidence, options = {}) {
238
343
  const env = validateEnvironment(evidence.environment, blockers);
239
344
  const refs = validateRefs(evidence.refs, blockers);
240
345
  const probes = validateProbes(evidence.probes, env.domain, blockers);
346
+ const runtimeCapability = validateRuntimeCapability(evidence.runtime_capability, blockers);
347
+ const authenticatedDataPlane = validateAuthenticatedDataPlane(evidence.authenticated_data_plane, env.domain, blockers);
241
348
  validateOperator(evidence.operator_acceptance, blockers);
242
349
  validateClaimBoundary(evidence.claim_boundary, blockers);
243
350
  const result = {
@@ -253,11 +360,15 @@ export function validateHostedBackendLiveEvidence(evidence, options = {}) {
253
360
  refs_missing: refs.missing,
254
361
  required_probes: REQUIRED_PROBES.length,
255
362
  probes_covered: probes.covered,
363
+ runtime_services_required: RUNTIME_SERVICES.length,
364
+ runtime_services_covered: runtimeCapability.covered,
365
+ authenticated_data_plane_proofs_required: RUNTIME_SERVICES.length,
366
+ authenticated_data_plane_proofs_covered: authenticatedDataPlane.covered,
256
367
  operator_decision: evidence.operator_acceptance?.decision ?? null,
257
368
  },
258
369
  claim_boundary: [
259
370
  'Hosted backend live validation checks supplied evidence only; it does not deploy infrastructure, mutate Cloudflare, create DNS records, or generate credentials.',
260
- 'A pass result requires public HTTPS /livez and /readyz probe evidence for relay and gateway plus all required production refs and operator acceptance go.',
371
+ 'A pass result requires public HTTPS /livez and /readyz probes, an explicit operational private-runtime capability marker, successful authenticated relay and gateway data-plane proofs, all required production refs, and operator acceptance go.',
261
372
  'Credentials, bearer tokens, API tokens, private memory payloads, prompts, transcripts, provider responses, and personal contact data must remain outside hosted backend live evidence.',
262
373
  ],
263
374
  };
@@ -0,0 +1,95 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.enigma.ai/antibody-pack-v1.schema.json",
4
+ "title": "Enigma Antibody Pack v1",
5
+ "type": "object",
6
+ "required": [
7
+ "schema",
8
+ "antibody_pack_id",
9
+ "created_at",
10
+ "version",
11
+ "policy_fingerprints",
12
+ "pack_root",
13
+ "signatures",
14
+ "public_payload_only",
15
+ "private_inputs_included"
16
+ ],
17
+ "additionalProperties": false,
18
+ "properties": {
19
+ "schema": { "const": "enigma.antibody_pack.v1" },
20
+ "antibody_pack_id": { "$ref": "#/$defs/publicId" },
21
+ "created_at": { "type": "string", "format": "date-time" },
22
+ "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:[-+][A-Za-z0-9.-]+)?$" },
23
+ "policy_fingerprints": {
24
+ "type": "array",
25
+ "minItems": 1,
26
+ "items": { "$ref": "#/$defs/policyFingerprint" }
27
+ },
28
+ "pack_root": { "$ref": "#/$defs/sha256Digest" },
29
+ "signatures": {
30
+ "type": "array",
31
+ "minItems": 1,
32
+ "items": { "$ref": "#/$defs/signatureRef" }
33
+ },
34
+ "public_payload_only": { "const": true },
35
+ "private_inputs_included": { "const": false }
36
+ },
37
+ "$defs": {
38
+ "sha256Digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
39
+ "publicId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._:-]{7,127}$" },
40
+ "publicRef": { "type": "string", "pattern": "^ref:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,255}$" },
41
+ "detectorId": { "type": "string", "pattern": "^detector:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,191}$" },
42
+ "policyId": { "type": "string", "pattern": "^policy:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,191}$" },
43
+ "signerRef": { "type": "string", "pattern": "^signer:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,191}$" },
44
+ "signaturePublicRef": { "type": "string", "pattern": "^sigref:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,191}$" },
45
+ "policyFingerprint": {
46
+ "type": "object",
47
+ "required": [
48
+ "policy_id",
49
+ "detector_id",
50
+ "detector_ref",
51
+ "policy_hash",
52
+ "risk_labels",
53
+ "threshold_commitment",
54
+ "private_inputs_included"
55
+ ],
56
+ "additionalProperties": false,
57
+ "properties": {
58
+ "policy_id": { "$ref": "#/$defs/policyId" },
59
+ "detector_id": { "$ref": "#/$defs/detectorId" },
60
+ "detector_ref": { "$ref": "#/$defs/publicRef" },
61
+ "policy_hash": { "$ref": "#/$defs/sha256Digest" },
62
+ "risk_labels": {
63
+ "type": "array",
64
+ "items": { "$ref": "#/$defs/riskLabel" },
65
+ "uniqueItems": true
66
+ },
67
+ "threshold_commitment": { "$ref": "#/$defs/sha256Digest" },
68
+ "private_inputs_included": { "const": false }
69
+ }
70
+ },
71
+ "signatureRef": {
72
+ "type": "object",
73
+ "required": ["signer_ref", "signature_ref", "signature_hash", "alg"],
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "signer_ref": { "$ref": "#/$defs/signerRef" },
77
+ "signature_ref": { "$ref": "#/$defs/signaturePublicRef" },
78
+ "signature_hash": { "$ref": "#/$defs/sha256Digest" },
79
+ "alg": { "type": "string", "enum": ["Ed25519", "ECDSA-P256-SHA256"] }
80
+ }
81
+ },
82
+ "riskLabel": {
83
+ "type": "string",
84
+ "enum": [
85
+ "untrusted_origin",
86
+ "prompt_injection",
87
+ "data_exfiltration",
88
+ "secret_material",
89
+ "memory_poisoning",
90
+ "policy_violation",
91
+ "unknown"
92
+ ]
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,81 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.enigma.ai/antigen-envelope-v1.schema.json",
4
+ "title": "Enigma Antigen Envelope v1",
5
+ "type": "object",
6
+ "required": [
7
+ "schema",
8
+ "envelope_id",
9
+ "created_at",
10
+ "content_commitment",
11
+ "source_refs",
12
+ "detector_refs",
13
+ "risk_labels",
14
+ "commitment_roots",
15
+ "public_payload_only",
16
+ "payload_included"
17
+ ],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "schema": { "const": "enigma.antigen_envelope.v1" },
21
+ "envelope_id": { "$ref": "#/$defs/publicId" },
22
+ "created_at": { "type": "string", "format": "date-time" },
23
+ "content_commitment": {
24
+ "type": "object",
25
+ "required": ["hash", "byte_count", "canonicalization"],
26
+ "additionalProperties": false,
27
+ "properties": {
28
+ "hash": { "$ref": "#/$defs/sha256Digest" },
29
+ "byte_count": { "type": "integer", "minimum": 0 },
30
+ "canonicalization": { "type": "string", "enum": ["json-c14n-sha256", "bytes-sha256", "utf8-nfc-sha256"] }
31
+ }
32
+ },
33
+ "source_refs": {
34
+ "type": "array",
35
+ "minItems": 1,
36
+ "items": { "$ref": "#/$defs/publicRef" },
37
+ "uniqueItems": true
38
+ },
39
+ "detector_refs": {
40
+ "type": "array",
41
+ "minItems": 1,
42
+ "items": { "$ref": "#/$defs/publicRef" },
43
+ "uniqueItems": true
44
+ },
45
+ "risk_labels": {
46
+ "type": "array",
47
+ "items": { "$ref": "#/$defs/riskLabel" },
48
+ "uniqueItems": true
49
+ },
50
+ "commitment_roots": {
51
+ "type": "object",
52
+ "required": ["antigen_root", "source_root", "detector_root"],
53
+ "additionalProperties": false,
54
+ "properties": {
55
+ "antigen_root": { "$ref": "#/$defs/sha256Digest" },
56
+ "source_root": { "$ref": "#/$defs/sha256Digest" },
57
+ "detector_root": { "$ref": "#/$defs/sha256Digest" }
58
+ }
59
+ },
60
+ "public_payload_only": { "const": true },
61
+ "payload_included": { "const": false }
62
+ },
63
+ "$defs": {
64
+ "sha256Digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
65
+ "publicId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._:-]{7,127}$" },
66
+ "publicRef": { "type": "string", "pattern": "^ref:[A-Za-z0-9][A-Za-z0-9._~:@#?=&%+-]{0,255}$" },
67
+ "riskLabel": {
68
+ "type": "string",
69
+ "enum": [
70
+ "benign",
71
+ "untrusted_origin",
72
+ "prompt_injection",
73
+ "data_exfiltration",
74
+ "secret_material",
75
+ "memory_poisoning",
76
+ "policy_violation",
77
+ "unknown"
78
+ ]
79
+ }
80
+ }
81
+ }