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,502 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { randomBytes } from 'node:crypto';
4
+ import { access, chmod, mkdir, mkdtemp, open, readFile, rm } from 'node:fs/promises';
5
+ import { homedir, tmpdir } from 'node:os';
6
+ import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ import { validateNodeVersion } from './install-enigma-local.mjs';
10
+
11
+ export const BOOTSTRAP_SCHEMA = 'enigma.bootstrap.v1';
12
+ export const DEFAULT_LAUNCH = 'desktop';
13
+
14
+ const SCRIPT_PATH = fileURLToPath(import.meta.url);
15
+ const DEFAULT_PACKAGE_DIR = resolve(dirname(SCRIPT_PATH), '..');
16
+ const CONTROL_CHARACTER_RE = /[\0\n\r]/u;
17
+
18
+ function readRequiredValue(argv, index, flag) {
19
+ const value = argv[index + 1];
20
+ if (value === undefined || value.startsWith('--')) throw new Error(`Missing value for ${flag}.`);
21
+ return value;
22
+ }
23
+
24
+ function rejectUnsafeValue(value, label) {
25
+ const text = String(value ?? '');
26
+ if (text.length === 0) throw new Error(`${label} must not be empty.`);
27
+ if (CONTROL_CHARACTER_RE.test(text)) throw new Error(`${label} contains an invalid control character.`);
28
+ return text;
29
+ }
30
+
31
+ export function usage() {
32
+ return `Install the complete Enigma harness, create an encrypted local vault, and open the desktop.\n\nUsage:\n npx --yes enigma-memory@latest\n enigma-memory [--desktop|--terminal|--no-launch] [--bundle <path>] [--passphrase-file <path>] [--prefix <path>] [--dry-run]\n\nDefaults:\n - Installs the exact package executing this bootstrap.\n - Creates ~/.enigma/passphrase with cryptographically random bytes when no vault exists.\n - Creates ~/.enigma/bundle.json with encrypted key custody.\n - Opens enigma-desktop with lexical embeddings, avoiding a first-run neural model download.\n\nExisting vaults are never overwritten. If a bundle exists without its passphrase file, bootstrap fails closed.\n`;
33
+ }
34
+
35
+ export function parseBootstrapArgs(argv = process.argv.slice(2)) {
36
+ const options = {
37
+ dryRun: false,
38
+ initialize: true,
39
+ launch: DEFAULT_LAUNCH,
40
+ };
41
+ let launchSelection;
42
+
43
+ for (let index = 0; index < argv.length; index += 1) {
44
+ const arg = argv[index];
45
+ if (arg === '--help' || arg === '-h') {
46
+ options.help = true;
47
+ } else if (arg === '--dry-run') {
48
+ options.dryRun = true;
49
+ } else if (arg === '--desktop') {
50
+ if (launchSelection && launchSelection !== 'desktop') throw new Error('Choose one launch mode.');
51
+ launchSelection = 'desktop';
52
+ options.launch = 'desktop';
53
+ } else if (arg === '--terminal') {
54
+ if (launchSelection && launchSelection !== 'terminal') throw new Error('Choose one launch mode.');
55
+ launchSelection = 'terminal';
56
+ options.launch = 'terminal';
57
+ } else if (arg === '--no-launch') {
58
+ if (launchSelection && launchSelection !== 'none') throw new Error('Choose one launch mode.');
59
+ launchSelection = 'none';
60
+ options.launch = 'none';
61
+ } else if (arg === '--no-init') {
62
+ options.initialize = false;
63
+ } else if (arg === '--bundle') {
64
+ options.bundlePath = readRequiredValue(argv, index, arg);
65
+ index += 1;
66
+ } else if (arg === '--passphrase-file') {
67
+ options.passphraseFile = readRequiredValue(argv, index, arg);
68
+ index += 1;
69
+ } else if (arg === '--prefix') {
70
+ options.prefix = readRequiredValue(argv, index, arg);
71
+ index += 1;
72
+ } else {
73
+ throw new Error(`Unknown bootstrap argument: ${arg}`);
74
+ }
75
+ }
76
+
77
+ return options;
78
+ }
79
+
80
+ function npmRuntime(runtime, platform) {
81
+ const nodeCommand = resolve(runtime.nodeCommand ?? process.execPath);
82
+ const npmCliPath = runtime.npmCliPath
83
+ ?? process.env.npm_execpath
84
+ ?? (platform === 'win32' ? join(dirname(nodeCommand), 'node_modules', 'npm', 'bin', 'npm-cli.js') : undefined);
85
+ return npmCliPath
86
+ ? { command: nodeCommand, argsPrefix: [resolve(npmCliPath)] }
87
+ : { command: 'npm', argsPrefix: [] };
88
+ }
89
+
90
+ function resolveRequestedPath(value, fallback, cwd) {
91
+ const requested = rejectUnsafeValue(value ?? fallback, 'Bootstrap path');
92
+ return isAbsolute(requested) ? resolve(requested) : resolve(cwd, requested);
93
+ }
94
+
95
+ export function buildBootstrapPlan(options = {}, runtime = {}) {
96
+ const platform = runtime.platform ?? process.platform;
97
+ const cwd = runtime.cwd ?? process.cwd();
98
+ const home = runtime.homeDir ?? homedir();
99
+ const packageDir = resolve(rejectUnsafeValue(runtime.packageDir ?? DEFAULT_PACKAGE_DIR, 'Package directory'));
100
+ const enigmaDir = resolve(runtime.enigmaDir ?? join(home, '.enigma'));
101
+ const bundlePath = resolveRequestedPath(options.bundlePath, join(enigmaDir, 'bundle.json'), cwd);
102
+ const passphraseFile = resolveRequestedPath(options.passphraseFile, join(enigmaDir, 'passphrase'), cwd);
103
+ const prefix = options.prefix === undefined ? undefined : resolveRequestedPath(options.prefix, options.prefix, cwd);
104
+ const archiveDir = runtime.archiveDir ?? '<temporary-pack-directory>';
105
+ const npm = npmRuntime(runtime, platform);
106
+ const npmArgs = (args) => [...npm.argsPrefix, ...args];
107
+ const installArgs = ['install', '--global', '<packed-tarball>'];
108
+ const globalRootArgs = ['root', '--global'];
109
+ if (prefix) {
110
+ installArgs.push('--prefix', prefix);
111
+ globalRootArgs.push('--prefix', prefix);
112
+ }
113
+ return {
114
+ schema: BOOTSTRAP_SCHEMA,
115
+ platform,
116
+ nodeCommand: resolve(runtime.nodeCommand ?? process.execPath),
117
+ packageDir,
118
+ bundlePath,
119
+ passphraseFile,
120
+ prefix,
121
+ dryRun: options.dryRun === true,
122
+ initialize: options.initialize !== false,
123
+ launch: options.launch ?? DEFAULT_LAUNCH,
124
+ archiveDir,
125
+ commands: {
126
+ pack: { command: npm.command, args: npmArgs(['pack', packageDir, '--json', '--pack-destination', archiveDir]), cwd: packageDir },
127
+ install: { command: npm.command, args: npmArgs(installArgs), cwd: packageDir },
128
+ globalRoot: { command: npm.command, args: npmArgs(globalRootArgs), cwd: packageDir },
129
+ },
130
+ };
131
+ }
132
+
133
+ export function installedHarnessCommands(plan, globalRoot) {
134
+ const root = rejectUnsafeValue(String(globalRoot ?? '').trim(), 'npm global root');
135
+ if (!isAbsolute(root)) throw new Error('npm global root must be absolute.');
136
+ const installedPackageDir = join(resolve(root), 'enigma-memory');
137
+ const entry = (path) => join(installedPackageDir, path);
138
+ return {
139
+ installedPackageDir,
140
+ version: {
141
+ command: plan.nodeCommand,
142
+ args: [entry('apps/cli/bin/enigma.mjs'), '--version'],
143
+ cwd: installedPackageDir,
144
+ },
145
+ setup: {
146
+ command: plan.nodeCommand,
147
+ args: [entry('apps/cli/bin/enigma.mjs'), 'setup', '--bundle', plan.bundlePath, '--out-dir', dirname(plan.bundlePath), '--passphrase-file', plan.passphraseFile],
148
+ cwd: installedPackageDir,
149
+ },
150
+ desktop: {
151
+ command: plan.nodeCommand,
152
+ args: [entry('apps/cli/bin/enigma-desktop.mjs'), '--bundle', plan.bundlePath, '--passphrase-file', plan.passphraseFile, '--embedding-model', 'lexical'],
153
+ cwd: installedPackageDir,
154
+ },
155
+ terminal: {
156
+ command: plan.nodeCommand,
157
+ args: [entry('apps/cli/bin/enigma-terminal.mjs'), '--bundle', plan.bundlePath],
158
+ cwd: installedPackageDir,
159
+ },
160
+ };
161
+ }
162
+
163
+ async function fileExists(path, accessImpl = access) {
164
+ try {
165
+ await accessImpl(path);
166
+ return true;
167
+ } catch {
168
+ return false;
169
+ }
170
+ }
171
+
172
+ export function windowsSidFromWhoami(stdout) {
173
+ const sid = String(stdout ?? '').match(/\bS-\d-(?:\d+-)+\d+\b/u)?.[0];
174
+ if (!sid) throw new Error('Unable to resolve the current Windows user SID.');
175
+ return sid;
176
+ }
177
+
178
+
179
+ function windowsSystemTools(runtime = {}) {
180
+ const systemRoot = rejectUnsafeValue(
181
+ runtime.windowsSystemRoot ?? process.env.SystemRoot ?? process.env.WINDIR,
182
+ 'Windows system root',
183
+ );
184
+ if (!isAbsolute(systemRoot)) throw new Error('Windows system root must be absolute.');
185
+ const system32 = join(systemRoot, 'System32');
186
+ return {
187
+ system32,
188
+ whoami: join(system32, 'whoami.exe'),
189
+ powershell: join(system32, 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
190
+ };
191
+ }
192
+
193
+ async function currentWindowsUserSid(runCommand, runtime) {
194
+ const tools = windowsSystemTools(runtime);
195
+ const whoami = await runCommand({
196
+ command: tools.whoami,
197
+ args: ['/user', '/fo', 'csv', '/nh'],
198
+ cwd: tools.system32,
199
+ }, { capture: true, step: 'resolve_windows_user' });
200
+ return windowsSidFromWhoami(whoami.stdout);
201
+ }
202
+
203
+ const WINDOWS_VERIFY_CURRENT_USER_ACL_SCRIPT = [
204
+ "$ErrorActionPreference = 'Stop'",
205
+ '$path = $env:ENIGMA_BOOTSTRAP_ACL_PATH',
206
+ '$expectedSid = [System.Security.Principal.SecurityIdentifier]::new($env:ENIGMA_BOOTSTRAP_ACL_SID)',
207
+ '$sections = [System.Security.AccessControl.AccessControlSections]::Access -bor [System.Security.AccessControl.AccessControlSections]::Owner',
208
+ '$acl = [System.IO.File]::GetAccessControl($path, $sections)',
209
+ '$owner = $acl.GetOwner([System.Security.Principal.SecurityIdentifier])',
210
+ '$rules = @($acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))',
211
+ '$valid = $owner.Value -eq $expectedSid.Value -and $acl.AreAccessRulesProtected -and $rules.Count -eq 1',
212
+ 'if ($valid) { $rule = $rules[0]; $valid = -not $rule.IsInherited -and $rule.IdentityReference.Value -eq $expectedSid.Value -and $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and $rule.FileSystemRights -eq [System.Security.AccessControl.FileSystemRights]::FullControl -and $rule.InheritanceFlags -eq [System.Security.AccessControl.InheritanceFlags]::None -and $rule.PropagationFlags -eq [System.Security.AccessControl.PropagationFlags]::None }',
213
+ "if (-not $valid) { throw 'Windows passphrase ACL is not current-user-only.' }",
214
+ '[Console]::Out.WriteLine($expectedSid.Value)',
215
+ ].join('; ');
216
+
217
+ async function verifyWindowsPassphraseAclForSid(path, sid, runCommand, runtime) {
218
+ const tools = windowsSystemTools(runtime);
219
+ let verification;
220
+ try {
221
+ verification = await runCommand({
222
+ command: tools.powershell,
223
+ args: ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', WINDOWS_VERIFY_CURRENT_USER_ACL_SCRIPT],
224
+ cwd: tools.system32,
225
+ }, {
226
+ capture: true,
227
+ step: 'verify_passphrase_acl',
228
+ env: {
229
+ ...process.env,
230
+ ENIGMA_BOOTSTRAP_ACL_PATH: path,
231
+ ENIGMA_BOOTSTRAP_ACL_SID: sid,
232
+ },
233
+ });
234
+ } catch (error) {
235
+ throw new Error(`Windows passphrase ACL is not current-user-only: ${String(error?.message ?? error)}`);
236
+ }
237
+ if (windowsSidFromWhoami(verification.stdout) !== sid) {
238
+ throw new Error('Windows passphrase ACL verification returned a different SID.');
239
+ }
240
+ return { verified: true, sid, ace_count: 1 };
241
+ }
242
+
243
+ export async function verifyWindowsPassphraseAcl(path, runtime = {}) {
244
+ const runCommand = runtime.runAclCommand ?? defaultRunCommand;
245
+ const sid = await currentWindowsUserSid(runCommand, runtime);
246
+ return verifyWindowsPassphraseAclForSid(path, sid, runCommand, runtime);
247
+ }
248
+
249
+ const WINDOWS_CREATE_CURRENT_USER_PASSPHRASE_SCRIPT = [
250
+ "$ErrorActionPreference = 'Stop'",
251
+ '$path = $env:ENIGMA_BOOTSTRAP_ACL_PATH',
252
+ '$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User',
253
+ '$acl = [System.Security.AccessControl.FileSecurity]::new()',
254
+ '$acl.SetOwner($sid)',
255
+ '$acl.SetAccessRuleProtection($true, $false)',
256
+ '$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($sid, [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.AccessControlType]::Allow)',
257
+ '$acl.SetAccessRule($rule)',
258
+ '$created = $false',
259
+ 'try { $stream = [System.IO.FileStream]::new($path, [System.IO.FileMode]::CreateNew, [System.Security.AccessControl.FileSystemRights]::Write, [System.IO.FileShare]::None, 4096, [System.IO.FileOptions]::WriteThrough, $acl); $created = $true; try { [Console]::OpenStandardInput().CopyTo($stream); $stream.Flush($true) } finally { $stream.Dispose() }; [Console]::Out.WriteLine($sid.Value) } catch { if ($created) { [System.IO.File]::Delete($path) }; throw }',
260
+ ].join('; ');
261
+
262
+ async function createWindowsPassphraseFile(path, secret, runtime = {}) {
263
+ const runCommand = runtime.runAclCommand ?? defaultRunCommand;
264
+ const tools = windowsSystemTools(runtime);
265
+ const creation = await runCommand({
266
+ command: tools.powershell,
267
+ args: ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', WINDOWS_CREATE_CURRENT_USER_PASSPHRASE_SCRIPT],
268
+ cwd: tools.system32,
269
+ }, {
270
+ capture: true,
271
+ input: Buffer.from(secret, 'utf8'),
272
+ step: 'create_secure_passphrase',
273
+ env: {
274
+ ...process.env,
275
+ ENIGMA_BOOTSTRAP_ACL_PATH: path,
276
+ },
277
+ });
278
+ const sid = windowsSidFromWhoami(creation.stdout);
279
+ try {
280
+ return await verifyWindowsPassphraseAclForSid(path, sid, runCommand, runtime);
281
+ } catch (error) {
282
+ await (runtime.rmImpl ?? rm)(path, { force: true });
283
+ throw error;
284
+ }
285
+ }
286
+
287
+ export async function ensureBootstrapPassphrase(plan, runtime = {}) {
288
+ const accessImpl = runtime.accessImpl ?? access;
289
+ const bundleExists = await fileExists(plan.bundlePath, accessImpl);
290
+ const passphraseExists = await fileExists(plan.passphraseFile, accessImpl);
291
+ if (bundleExists && !passphraseExists) {
292
+ throw new Error('An Enigma bundle already exists but its passphrase file is missing. Refusing to generate a replacement credential.');
293
+ }
294
+
295
+ const chmodImpl = runtime.chmodImpl ?? chmod;
296
+ if (passphraseExists) {
297
+ if (plan.platform === 'win32') {
298
+ try {
299
+ const acl = await verifyWindowsPassphraseAcl(plan.passphraseFile, runtime);
300
+ return { created: false, bundleExists, acl_verified: acl.verified };
301
+ } catch (error) {
302
+ throw new Error(`The existing Windows passphrase file is not current-user-only: ${String(error?.message ?? error)}`);
303
+ }
304
+ }
305
+ await chmodImpl(plan.passphraseFile, 0o600);
306
+ return { created: false, bundleExists };
307
+ }
308
+
309
+ const mkdirImpl = runtime.mkdirImpl ?? mkdir;
310
+ const randomBytesImpl = runtime.randomBytesImpl ?? randomBytes;
311
+ await mkdirImpl(dirname(plan.passphraseFile), { recursive: true });
312
+ const secret = `${randomBytesImpl(32).toString('base64')}\n`;
313
+ if (plan.platform === 'win32') {
314
+ try {
315
+ const acl = await createWindowsPassphraseFile(plan.passphraseFile, secret, runtime);
316
+ return { created: true, bundleExists, acl_verified: acl.verified };
317
+ } catch (error) {
318
+ throw new Error(`Unable to atomically create the generated Windows passphrase file: ${String(error?.message ?? error)}`);
319
+ }
320
+ }
321
+
322
+ const openImpl = runtime.openImpl ?? open;
323
+ const rmImpl = runtime.rmImpl ?? rm;
324
+ let passphraseHandle;
325
+ try {
326
+ passphraseHandle = await openImpl(plan.passphraseFile, 'wx', 0o600);
327
+ } catch (error) {
328
+ if (error?.code === 'EEXIST') {
329
+ throw new Error('The passphrase file appeared during bootstrap. Refusing to use an unverified credential.');
330
+ }
331
+ throw error;
332
+ }
333
+ try {
334
+ await chmodImpl(plan.passphraseFile, 0o600);
335
+ await passphraseHandle.writeFile(secret, { encoding: 'utf8' });
336
+ await passphraseHandle.sync();
337
+ await chmodImpl(plan.passphraseFile, 0o600);
338
+ await passphraseHandle.close();
339
+ passphraseHandle = undefined;
340
+ return { created: true, bundleExists };
341
+ } catch (error) {
342
+ if (passphraseHandle) await passphraseHandle.close().catch(() => {});
343
+ await rmImpl(plan.passphraseFile, { force: true });
344
+ throw error;
345
+ }
346
+ }
347
+
348
+ export function installerFailureCode(stderr) {
349
+ const match = String(stderr ?? '').match(/npm\s+(?:error|ERR!)\s+code\s+([A-Z0-9_-]+)/iu);
350
+ return match?.[1]?.toUpperCase();
351
+ }
352
+
353
+ async function defaultRunCommand(spec, options = {}) {
354
+ const capture = options.capture === true;
355
+ const hasInput = options.input !== undefined;
356
+ const child = spawn(spec.command, spec.args, {
357
+ cwd: spec.cwd,
358
+ env: options.env ?? process.env,
359
+ shell: false,
360
+ windowsHide: true,
361
+ stdio: capture
362
+ ? [hasInput ? 'pipe' : 'ignore', 'pipe', 'pipe']
363
+ : (hasInput ? ['pipe', 'inherit', 'inherit'] : 'inherit'),
364
+ });
365
+ let stdout = '';
366
+ let stderr = '';
367
+ if (capture) {
368
+ child.stdout.setEncoding('utf8');
369
+ child.stderr.setEncoding('utf8');
370
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
371
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
372
+ }
373
+ const exitPromise = new Promise((resolveExit, rejectExit) => {
374
+ child.once('error', rejectExit);
375
+ child.once('exit', (code) => resolveExit(code ?? 1));
376
+ });
377
+ if (hasInput) {
378
+ child.stdin.on('error', () => {});
379
+ child.stdin.end(options.input);
380
+ }
381
+ const exitCode = await exitPromise;
382
+ if (exitCode !== 0) {
383
+ const failureCode = installerFailureCode(stderr);
384
+ throw new Error(`Bootstrap command failed: ${options.step ?? 'unknown'}${failureCode ? ` (${failureCode})` : ''}.`);
385
+ }
386
+ return { exitCode, stdout, stderr };
387
+ }
388
+
389
+ export function packedTarballPath(stdout, archiveDir) {
390
+ let records;
391
+ try {
392
+ records = JSON.parse(String(stdout ?? ''));
393
+ } catch {
394
+ throw new Error('npm pack did not return valid JSON.');
395
+ }
396
+ const filename = records?.[0]?.filename;
397
+ if (typeof filename !== 'string' || basename(filename) !== filename || !filename.endsWith('.tgz')) {
398
+ throw new Error('npm pack returned an unsafe archive filename.');
399
+ }
400
+ return join(archiveDir, filename);
401
+ }
402
+
403
+ function publicPlan(plan) {
404
+ return {
405
+ schema: plan.schema,
406
+ ok: true,
407
+ mode: plan.dryRun ? 'dry-run' : 'execute',
408
+ package_source: 'currently executing package',
409
+ install_scope: plan.prefix ? 'explicit_prefix' : 'global_npm_prefix',
410
+ initialize_vault: plan.initialize,
411
+ launch: plan.launch,
412
+ encrypted: plan.initialize,
413
+ generated_credential: plan.initialize ? 'secure local passphrase file when absent' : null,
414
+ neural_model_download_required: false,
415
+ commands: ['install harness', 'verify enigma command', ...(plan.initialize ? ['initialize encrypted vault'] : []), ...(plan.launch === 'none' ? [] : [`launch ${plan.launch}`])],
416
+ };
417
+ }
418
+
419
+ export async function runBootstrap(argv = process.argv.slice(2), runtime = {}) {
420
+ const options = Array.isArray(argv) ? parseBootstrapArgs(argv) : { ...argv };
421
+ if (options.help) return { help: usage() };
422
+ validateNodeVersion(runtime.nodeVersion ?? process.versions.node);
423
+ const mkdtempImpl = runtime.mkdtempImpl ?? mkdtemp;
424
+ const archiveDir = options.dryRun === true
425
+ ? undefined
426
+ : await mkdtempImpl(join(runtime.tempDir ?? tmpdir(), 'enigma-bootstrap-'));
427
+ const plan = buildBootstrapPlan(options, { ...runtime, archiveDir });
428
+ if (plan.dryRun) return publicPlan(plan);
429
+
430
+ const runCommand = runtime.runCommand ?? defaultRunCommand;
431
+ let credential = { created: false, bundleExists: false };
432
+ if (plan.initialize) credential = await ensureBootstrapPassphrase(plan, runtime);
433
+
434
+ const rmImpl = runtime.rmImpl ?? rm;
435
+ try {
436
+ const packResult = await runCommand(plan.commands.pack, { capture: true, step: 'pack_harness' });
437
+ const tarball = packedTarballPath(packResult.stdout, plan.archiveDir);
438
+ const installSpec = {
439
+ ...plan.commands.install,
440
+ args: plan.commands.install.args.map((arg) => arg === '<packed-tarball>' ? tarball : arg),
441
+ };
442
+ await runCommand(installSpec, { capture: true, step: 'install_harness' });
443
+ } finally {
444
+ await rmImpl(plan.archiveDir, { recursive: true, force: true });
445
+ }
446
+ const globalRootResult = await runCommand(plan.commands.globalRoot, { capture: true, step: 'resolve_global_root' });
447
+ const harnessCommands = installedHarnessCommands(plan, globalRootResult.stdout);
448
+ const versionResult = await runCommand(harnessCommands.version, { capture: true, step: 'verify_install' });
449
+ const readFileImpl = runtime.readFileImpl ?? readFile;
450
+ const packageJson = JSON.parse(await readFileImpl(join(plan.packageDir, 'package.json'), 'utf8'));
451
+ if (!String(versionResult.stdout ?? '').includes(String(packageJson.version))) {
452
+ throw new Error('Installed Enigma version could not be verified.');
453
+ }
454
+
455
+ if (plan.initialize && !credential.bundleExists) {
456
+ await runCommand(harnessCommands.setup, { capture: true, step: 'initialize_vault' });
457
+ if (!(await fileExists(plan.bundlePath, runtime.accessImpl ?? access))) throw new Error('Enigma setup completed without creating the bundle.');
458
+ }
459
+
460
+ const result = {
461
+ ...publicPlan(plan),
462
+ mode: 'execute',
463
+ installed: true,
464
+ vault_initialized: plan.initialize,
465
+ passphrase_created: credential.created,
466
+ existing_bundle_reused: credential.bundleExists,
467
+ };
468
+
469
+ if (plan.launch === 'desktop') {
470
+ await runCommand(harnessCommands.desktop, { capture: false, step: 'launch_desktop' });
471
+ } else if (plan.launch === 'terminal') {
472
+ const passphrase = (await readFileImpl(plan.passphraseFile, 'utf8')).trim();
473
+ await runCommand(harnessCommands.terminal, {
474
+ capture: false,
475
+ step: 'launch_terminal',
476
+ env: { ...process.env, ENIGMA_PASSPHRASE: passphrase },
477
+ });
478
+ }
479
+ return result;
480
+ }
481
+
482
+ function renderResult(result) {
483
+ if (result.help) return result.help;
484
+ if (result.mode === 'dry-run') return `${JSON.stringify(result, null, 2)}\n`;
485
+ return [
486
+ 'Enigma harness installed.',
487
+ result.existing_bundle_reused ? 'Existing encrypted vault preserved.' : 'Encrypted local vault ready.',
488
+ result.launch === 'none' ? 'Run enigma-terminal or enigma-desktop to begin.' : `${result.launch === 'desktop' ? 'Desktop' : 'Terminal'} session closed. Run it again at any time.`,
489
+ ].join('\n') + '\n';
490
+ }
491
+
492
+ async function main() {
493
+ try {
494
+ const result = await runBootstrap();
495
+ process.stdout.write(renderResult(result));
496
+ } catch (error) {
497
+ process.stderr.write(`Enigma bootstrap failed: ${String(error?.message ?? error)}\n`);
498
+ process.exitCode = 1;
499
+ }
500
+ }
501
+
502
+ if (resolve(process.argv[1] ?? '') === SCRIPT_PATH) await main();
@@ -52,9 +52,9 @@ export const EDGE_BACKEND_REF_ENV_NAMES = Object.freeze({
52
52
  gateway_deployment: Object.freeze(['ENIGMA_GATEWAY_DEPLOYMENT_REF']),
53
53
  });
54
54
  const CLAIM_BOUNDARY = Object.freeze([
55
- 'Edge backend Workers provide public HTTPS liveness/readiness and fail-closed private-route boundaries for urgent bootstrap only.',
56
- 'Readiness is true only when operator-supplied evidence refs and operator acceptance are configured; the Worker does not create storage, KMS, SIEM, backups, legal approval, or acceptance evidence.',
57
- 'Private data-plane routes remain closed by default; raw memory, prompts, transcripts, provider responses, credentials, and private keys must not be returned by these Workers.',
55
+ 'Edge backend Workers provide public HTTPS liveness/readiness for urgent bootstrap only; hosted_backend_live is always false.',
56
+ 'Bootstrap readiness covers operator-supplied refs and binding checks, but the Worker does not implement the relay/gateway runtime or prove production readiness.',
57
+ 'The private data plane is closed and non-operational; raw memory, prompts, transcripts, provider responses, credentials, and private keys must not be returned by these Workers.',
58
58
  ]);
59
59
 
60
60
  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/@]+@|sk-[A-Za-z0-9_-]{16,}|AKIA[0-9A-Z]{16})/iu;
@@ -98,6 +98,12 @@ const REQUIRED_REFS = ${requiredRefs};
98
98
  const REF_ENV_NAMES = ${refEnvNames};
99
99
  const PRIVATE_ROUTES = ${privateRoutes};
100
100
  const CLAIM_BOUNDARY = ${boundary};
101
+ const RUNTIME_CAPABILITY = Object.freeze({
102
+ marker: 'enigma.private_data_plane.runtime.v1',
103
+ bootstrap_worker: true,
104
+ private_data_plane_operational: false,
105
+ authenticated_data_plane_supported: false
106
+ });
101
107
 
102
108
  function json(body, status = 200) {
103
109
  return new Response(JSON.stringify(body, null, 2), {
@@ -194,6 +200,9 @@ async function readiness(env) {
194
200
  service_kind: SERVICE_KIND,
195
201
  runtime: 'cloudflare-workers',
196
202
  generated_at: GENERATED_AT,
203
+ hosted_backend_live: false,
204
+ private_data_plane_operational: false,
205
+ runtime_capability: RUNTIME_CAPABILITY,
197
206
  status: ok ? 'ready' : 'blocked',
198
207
  evidence_refs: refs,
199
208
  evidence_ref_count: configured.length,
@@ -210,7 +219,7 @@ async function readiness(env) {
210
219
  }
211
220
 
212
221
  function error(code, message) {
213
- return { ok: false, service: SERVICE_NAME, error: { code, message }, claim_boundary: CLAIM_BOUNDARY };
222
+ return { ok: false, service: SERVICE_NAME, hosted_backend_live: false, private_data_plane_operational: false, runtime_capability: RUNTIME_CAPABILITY, error: { code, message }, claim_boundary: CLAIM_BOUNDARY };
214
223
  }
215
224
 
216
225
  function plaintextLooking(value, seen = new WeakSet()) {
@@ -239,7 +248,7 @@ export default {
239
248
  async fetch(request, env) {
240
249
  const url = new URL(request.url);
241
250
  if (request.method !== 'GET' && request.method !== 'HEAD' && request.method !== 'POST') return json(error('METHOD_NOT_ALLOWED', 'Only GET, HEAD, and POST are allowed.'), 405);
242
- if (url.pathname === '/livez') return json({ ok: true, service: SERVICE_NAME, service_kind: SERVICE_KIND, runtime: 'cloudflare-workers', claim_boundary: CLAIM_BOUNDARY });
251
+ if (url.pathname === '/livez') return json({ ok: true, service: SERVICE_NAME, service_kind: SERVICE_KIND, runtime: 'cloudflare-workers', hosted_backend_live: false, private_data_plane_operational: false, runtime_capability: RUNTIME_CAPABILITY, claim_boundary: CLAIM_BOUNDARY });
243
252
  if (url.pathname === '/readyz') {
244
253
  const body = await readiness(env);
245
254
  return json(body, body.ok ? 200 : 503);
@@ -264,6 +273,10 @@ export function validateEdgeBackendWorkerSource(source, configInput) {
264
273
  if (!text.includes("url.pathname === '/readyz'")) blockers.push({ path: 'source.readyz', message: 'worker must route /readyz' });
265
274
  if (!text.includes('PRIVATE_ROUTE_CLOSED')) blockers.push({ path: 'source.private_routes', message: 'worker must fail closed for private routes' });
266
275
  if (text.includes('hosted_probe_only') || text.includes('pages_edge_probe_only')) blockers.push({ path: 'source.claim', message: 'edge backend worker must not masquerade as probe-only payload' });
276
+ if (!text.includes('hosted_backend_live: false')) blockers.push({ path: 'source.claim', message: 'bootstrap worker must explicitly declare hosted_backend_live false' });
277
+ if (!text.includes('private_data_plane_operational: false')) blockers.push({ path: 'source.capability', message: 'bootstrap worker must explicitly declare the private data plane non-operational' });
278
+ if (!text.includes('authenticated_data_plane_supported: false')) blockers.push({ path: 'source.capability', message: 'bootstrap worker must explicitly declare authenticated data-plane support unavailable' });
279
+ if (/hosted_backend_live\s*:\s*true/u.test(text)) blockers.push({ path: 'source.claim', message: 'bootstrap worker must never declare hosted_backend_live true' });
267
280
  if (SECRET_VALUE_RE.test(text)) blockers.push({ path: 'source.secret', message: 'worker source contains secret-looking literal' });
268
281
  for (const key of REQUIRED_REF_KEYS) if (!text.includes(key)) blockers.push({ path: `source.refs.${key}`, message: `worker source missing ${key}` });
269
282
  return {
@@ -286,6 +299,8 @@ export function buildEdgeBackendWorkerBundle(options = {}) {
286
299
  hostname: `${config.hostPrefix}.${domain}`,
287
300
  default_routes: ['/livez', '/readyz'],
288
301
  private_routes: [...config.privateRoutes],
302
+ hosted_backend_live: false,
303
+ private_data_plane_operational: false,
289
304
  validation: validateEdgeBackendWorkerSource(source, config),
290
305
  files: {
291
306
  'worker.mjs': source,