enigma-memory 0.1.15 → 0.1.17

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 (44) hide show
  1. package/README.md +70 -86
  2. package/apps/cli/bin/enigma.mjs +152 -15
  3. package/apps/native-host/README.md +20 -0
  4. package/deploy/SIMULATION.md +34 -38
  5. package/docs/benchmark-attestation-network.md +2 -2
  6. package/docs/benchmark-reproducibility.md +70 -9
  7. package/docs/blockchain-only-mechanisms.md +12 -0
  8. package/docs/browser-extension-install.md +9 -6
  9. package/docs/client-connectors.md +29 -55
  10. package/docs/demo-proof-network.md +3 -3
  11. package/docs/developer-ecosystem.md +207 -223
  12. package/docs/developer-proof-quickstart.md +3 -3
  13. package/docs/enigma-memory-ready-conformance.md +1 -1
  14. package/docs/hosted-cloud-product.md +31 -0
  15. package/docs/install-anywhere.md +68 -70
  16. package/docs/memory-benchmarks.md +21 -3
  17. package/docs/memory-drive-health-model.md +41 -0
  18. package/docs/proof-network-build-notes.md +2 -2
  19. package/docs/proof-network.md +90 -8
  20. package/docs/sdk-api.md +1 -1
  21. package/docs/solana-devnet-acceptance.md +1 -1
  22. package/docs/solana-proof-rail.md +1 -1
  23. package/package.json +7 -1
  24. package/packages/connectors/src/index.js +13 -0
  25. package/packages/hosted-cloud/src/index.js +470 -2
  26. package/packages/mcp-server/README.md +22 -0
  27. package/packages/mcp-server/src/index.js +1 -1
  28. package/packages/passport/src/index.js +730 -0
  29. package/packages/proof-network/src/index.js +139 -0
  30. package/scripts/build-benchmark-proof-release.mjs +119 -6
  31. package/scripts/build-cloudflare-token-policy.mjs +6 -2
  32. package/scripts/build-hosted-api-key-lifecycle.mjs +1 -1
  33. package/scripts/build-hosted-customer-lifecycle.mjs +23 -3
  34. package/scripts/build-installer-assets.mjs +1 -1
  35. package/scripts/build-production-handoff-packet.mjs +1 -1
  36. package/scripts/build-production-unblocker.mjs +409 -409
  37. package/scripts/build-production-workplan.mjs +3 -1
  38. package/scripts/build-proof-network-packet.mjs +1 -1
  39. package/scripts/check.mjs +3 -1
  40. package/scripts/cloudflare-ops.mjs +35 -0
  41. package/scripts/collect-hosted-backend-live-evidence.mjs +44 -2
  42. package/scripts/run-memory-benchmarks.mjs +5 -0
  43. package/scripts/run-standard-memory-benchmarks.mjs +287 -5
  44. package/scripts/stage-cloudflare-pages-artifact.mjs +145 -0
package/README.md CHANGED
@@ -2,112 +2,48 @@
2
2
 
3
3
  Enigma Memory is a local-first AI Memory Passport. It gives you one canonical local memory vault, receipt-backed proof for Enigma-controlled events, and MCP connections into assistants such as Claude Desktop, Cursor, Kimi Code, and generic MCP clients.
4
4
 
5
- Start with `enigma init --dry-run` below. You do not need to understand relay, gateway, mesh, browser, desktop, or hosted infrastructure before trying Enigma locally.
5
+ Start with the Memory Drive loop below — one install, one connect, then health and status verification. You do not need to understand relay, gateway, mesh, browser, desktop, hosted infrastructure, or the proof network before trying Enigma locally.
6
6
 
7
7
  The package path needs no database, provider credential, cloud credential, npm publishing token, or external account. Hosted cloud and BYOC operation are separate advanced modes that require real deployment credentials, domains, TLS, durable storage, KMS/secrets, monitoring, backups, and operator acceptance.
8
8
 
9
9
  Enigma does not claim that a closed provider deleted internal data, that model weights forgot, or that provider-native memory disappeared. It proves facts about Enigma-controlled vault state, receipts, checkpoints, and declared boundary operations.
10
10
 
11
- ## First run: install and inspect the safe local plan
12
-
13
- The top public path is the published npm package plus the first-run planner:
14
-
15
- ```sh
16
- npm install -g enigma-memory
17
- enigma init --dry-run
18
- ```
19
-
20
- `enigma init --dry-run` prints a public-safe JSON plan with exact next commands. It does not write local artifacts or third-party client configs, does not require provider credentials, hosted Enigma SaaS, Solana, or a browser extension, and states `provider_credentials_required:false`, `hosted_saas_live:false`, and `raw_memory_printed:false`.
21
-
22
- When the plan looks right, create the local Memory Passport artifacts:
23
-
24
- ```sh
25
- enigma init --overwrite
26
- ```
27
-
28
- The execute path writes only local Enigma artifacts under the workspace `.enigma` path by default. It still does not write Claude, Cursor, Kimi, or other third-party app configs unless you explicitly add `--connect`.
29
-
30
- Public demo path, preserved for reviewers who want the isolated proof/demo bundle:
31
-
32
- ```sh
33
- enigma test-drive --overwrite
34
- ```
35
-
36
- `enigma test-drive --overwrite` needs no database, provider API key, cloud credential, npm publishing token, package registry account, or hosted Enigma account. It runs entirely on the local filesystem, does not call OpenAI, Anthropic, Cloudflare, hosted Enigma, or other external providers, and does not write Claude, Cursor, Kimi, or other third-party client configs.
37
-
38
- By default the command writes an isolated demo under `.enigma/test-drive`. Use `--dry-run` to print the plan without writing, or `--out-dir <path>` to choose another isolated demo directory. The default bundle and proof artifacts live inside that directory.
39
-
40
- The test-drive output is a single public-safe JSON summary. It points to the local setup artifacts, search/status output, cross-model demo report, and benchmark pointers, and it prints exact next commands for testers without printing raw private memory plaintext. The proof is bounded to the local demo: Enigma-controlled vault state, receipts, checkpoints, committed roots, exported bundle shape, and declared boundary operations. It is not evidence that hosted SaaS is live, that a closed provider deleted internal data, that model weights forgot, or that provider-native memory disappeared.
41
-
42
- When you are ready to connect real local clients that are already installed or already configured:
43
-
44
- ```sh
45
- enigma init --connect --overwrite
46
- ```
47
-
48
- `--connect` is the explicit first-run client-config write path. With default client selection it skips missing client configs instead of creating every default client config.
49
-
50
- ## Enigma Proof Network
51
-
52
- Enigma Proof Network is the public proof layer for AI memory: local tools can package privacy-preserving roots, refs, counts, signatures, scoped capability grants, revocations, and benchmark attestations without exposing raw memory, prompts, transcripts, completions, embeddings, tenant names, private keys, provider responses, or provider credentials.
53
-
54
- The `enigma chain anchor|grant|revoke|attest|verify` commands are local planning and verification commands. They emit public-safe JSON with `transaction_submitted:false` and `raw_memory_on_chain:false`; they do not submit Solana transactions, deploy hosted SaaS, create accounts, or call external providers.
55
-
56
- Start with the category narrative in [`docs/market-category-narrative.md`](docs/market-category-narrative.md), then read the technical overview in [`docs/proof-network.md`](docs/proof-network.md), use its [Solana role](docs/proof-network.md#solana-role) section for the Solana-ready anchoring boundary, and read [`docs/proof-network-faq.md`](docs/proof-network-faq.md) for claim boundaries.
57
-
58
11
  ## Install once, use everywhere
59
12
 
60
13
  Prerequisites:
61
14
 
62
15
  - Node.js `>=24`
63
- - No database, package registry account, provider credential, or cloud credential for the local test-drive or setup paths
16
+ - No database, package registry account, provider credential, cloud credential, hosted Enigma account, or external account for the local setup path
64
17
  - Git only when you choose the advanced source-checkout path
65
18
 
66
- Use Enigma as a one-time AI Memory Passport setup: install the package, inspect the local plan, create the local Enigma workspace once, then use the same memory/search/context/verify/connect loop from any supported client.
19
+ Use Enigma as your private Memory Drive for AI: install once, connect the AI clients you already have, then inspect drive health and passport status before remembering, retrieving, packaging, and verifying context.
67
20
 
68
21
  ```sh
69
22
  npm install -g enigma-memory
70
- enigma init --dry-run
71
- enigma init --overwrite
72
- ```
73
-
74
- `enigma init --overwrite` is the safe default for creating a regular local workspace after reviewing the plan. It writes local Enigma artifacts under the workspace `.enigma` path and emits deterministic, public-safe JSON without printing raw memory plaintext. It does not write Claude, Cursor, Kimi, or other third-party app configs.
75
-
76
- To let first-run setup detect installed or already-configured clients and show the connector plan without mutating client configs:
77
-
78
- ```sh
79
- enigma init --client auto --dry-run
23
+ enigma init
24
+ enigma setup --client auto --connect-installed --overwrite
25
+ enigma drive health
26
+ enigma status
27
+ enigma remember --text-file ./memory.txt
28
+ enigma search --query "project context"
29
+ enigma context --query "project context" --optimize
30
+ enigma verify --export ./.enigma/export.json
80
31
  ```
81
32
 
82
- `--client auto` selects clients found by connector detection and falls back to the default setup client list when none are present. The init output lists which clients were selected, which were skipped, and why.
83
-
84
- Only when you are ready to explicitly write connector entries for installed/config-present clients:
85
-
86
- ```sh
87
- enigma init --connect --overwrite
88
- ```
33
+ `enigma init` is the credential-free first run: it creates the local `.enigma` workspace, bundle, and proof artifacts and emits public-safe JSON without provider or cloud credentials. `enigma setup --client auto --connect-installed --overwrite` then configures the drive and merges the `mcpServers.enigma` entry into every installed/config-present client it detects (Claude Desktop, Cursor, Kimi Code, VS Code/Cline, Roo, OpenCode, generic MCP). It skips clients that are not installed and never creates configs from scratch; preview with `--dry-run` first if you want to see which clients will be written. The same commands run on Windows PowerShell because the npm global install adds an `enigma.cmd` shim. Neither command prints raw memory plaintext.
89
34
 
90
- `--connect` implies installed/config-present client selection when no explicit `--client` is supplied and is an explicit client-config write flag. It skips missing client configs instead of creating every default client config. Existing setup commands remain available: `enigma setup --overwrite`, `enigma setup --client auto --overwrite`, and `enigma setup --connect-installed --overwrite`. Existing explicit connector writes remain available through `enigma connect <client>` without `--dry-run`; keep `--dry-run` while reviewing a single planned MCP entry.
35
+ `enigma drive health` reports a SMART-style memory-drive health packet freshness, duplicate rate, tombstone backlog, stale derived artifacts, receipt coverage, and connector health computed from local metadata only, with no network calls or private payloads. It is part of the Memory Drive surface in this release; in any build where it is unavailable, `enigma status` and `enigma doctor` cover the same local passport counts, roots, and connector readiness.
91
36
 
92
- After init or setup, use the same local vault from the CLI or connected clients:
37
+ `enigma status` shows passport counts, roots, owner display fields, and connector readiness. The local Enigma vault remains canonical. Provider-native memory is non-canonical and should be treated as a convenience cache only. Enigma receipts prove Enigma-controlled vault state, receipts, checkpoints, and declared boundary operations; they do not prove provider deletion, provider model forgetting, provider-native memory removal, hosted availability, ROI/savings, or compliance certification.
93
38
 
94
- ```sh
95
- enigma remember --text-file ./memory.txt
96
- enigma search --query "..."
97
- enigma context --query "..." --optimize
98
- enigma verify --export ./.enigma/export.json
99
- enigma connect claude-desktop --dry-run
100
- ```
39
+ ## Enigma Proof Network
101
40
 
102
- `enigma context --query ...` automatically applies local relevance scoring; `--optimize` is still accepted when you want explicit optimizer evidence or token/cost bounds.
41
+ Enigma Proof Network is the public proof layer for AI memory: local tools can package privacy-preserving roots, refs, counts, signatures, scoped capability grants, revocations, and benchmark attestations without exposing raw memory, prompts, transcripts, completions, embeddings, tenant names, private keys, provider responses, or provider credentials.
103
42
 
104
- The local Enigma vault remains canonical. Provider-native memory is non-canonical and should be treated as a convenience cache only. Enigma receipts prove Enigma-controlled vault state, receipts, checkpoints, and declared boundary operations; they do not prove provider deletion, provider model forgetting, provider-native memory removal, hosted availability, ROI/savings, or compliance certification.
43
+ The `enigma chain anchor|grant|revoke|attest|verify` commands are local planning and verification commands. They emit public-safe JSON with `transaction_submitted:false` and `raw_memory_on_chain:false`; they do not submit Solana transactions, deploy hosted SaaS, create accounts, or call external providers.
105
44
 
106
- One-off public test drive without a global install:
45
+ Start with the category narrative in [`docs/market-category-narrative.md`](docs/market-category-narrative.md), then read the technical overview in [`docs/proof-network.md`](docs/proof-network.md), use its [Solana role](docs/proof-network.md#solana-role) section for the Solana-ready anchoring boundary, and read [`docs/proof-network-faq.md`](docs/proof-network-faq.md) for claim boundaries.
107
46
 
108
- ```sh
109
- npx --yes --package enigma-memory enigma test-drive --overwrite
110
- ```
111
47
 
112
48
  ## Advanced/source-only path
113
49
 
@@ -214,7 +150,7 @@ Supported connector profiles are:
214
150
  - `opencode`
215
151
  - `generic-mcp`
216
152
 
217
- After `enigma init --dry-run` previews the local package path and `enigma init --overwrite` creates a regular local workspace, preview a client connection before writing anything:
153
+ The one-command path above (`enigma setup --client auto --connect-installed --overwrite`) already connects every installed/config-present client. To connect or preview a single client instead:
218
154
 
219
155
  ```sh
220
156
  enigma connect claude-desktop --dry-run
@@ -223,11 +159,59 @@ enigma connect kimi-code --dry-run
223
159
  enigma connect generic-mcp --dry-run
224
160
  ```
225
161
 
226
- For the one-time setup flow, `enigma init --client auto --dry-run` reports the installed/config-present clients that connector detection selected and the clients it skipped with reasons. It remains read-only for client configs. `enigma init --connect --overwrite` is the explicit init-time write path for installed/config-present clients by default; missing configs are skipped rather than created. The older `enigma setup --client auto --overwrite` and `enigma setup --connect-installed --overwrite` commands remain available.
162
+ Remove `--dry-run` from `enigma connect <client>` only after you are ready for Enigma to merge the `mcpServers.enigma` entry into that specific client config. Bare `enigma setup` without `--connect-installed` or `--write-connectors` never writes third-party app configs.
227
163
 
228
- Remove `--dry-run` from `enigma connect <client>` only after you are ready for Enigma to merge the `mcpServers.enigma` entry into that specific client config. The safe default init/setup command never writes third-party app configs.
164
+ Copy-paste MCP snippets:
165
+
166
+ Claude Desktop:
167
+
168
+ ```json
169
+ {
170
+ "mcpServers": {
171
+ "enigma": {
172
+ "command": "enigma-mcp",
173
+ "args": [],
174
+ "env": {
175
+ "ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
176
+ }
177
+ }
178
+ }
179
+ }
180
+ ```
181
+
182
+ Cursor:
183
+
184
+ ```json
185
+ {
186
+ "mcpServers": {
187
+ "enigma": {
188
+ "command": "enigma-mcp",
189
+ "args": [],
190
+ "env": {
191
+ "ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
192
+ }
193
+ }
194
+ }
195
+ }
196
+ ```
197
+
198
+ Kimi Code:
199
+
200
+ ```json
201
+ {
202
+ "mcpServers": {
203
+ "enigma": {
204
+ "command": "enigma-mcp",
205
+ "args": [],
206
+ "env": {
207
+ "ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
208
+ }
209
+ }
210
+ }
211
+ }
212
+ ```
229
213
 
230
- Manual MCP entry for Claude Desktop, Cursor, Kimi Code, or any generic MCP client:
214
+ Generic MCP:
231
215
 
232
216
  ```json
233
217
  {
@@ -6,7 +6,7 @@ import { access, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promi
6
6
  import { dirname, isAbsolute, join, resolve } from 'node:path';
7
7
  import { pathToFileURL } from 'node:url';
8
8
  import { createVault, remember, recall, updateMemory, deleteMemory, exportBundle } from '../../../packages/vault/src/index.js';
9
- import { createPassport, compileContextPack } from '../../../packages/passport/src/index.js';
9
+ import { createPassport, compileContextPack, createMemoryDriveHealthReport } from '../../../packages/passport/src/index.js';
10
10
  import { runBoundarySimulation } from '../../../packages/boundary/src/index.js';
11
11
  import { startStdioServer } from '../../../packages/mcp-server/src/index.js';
12
12
  import { runMeshDemo } from '../../../packages/mesh/src/index.js';
@@ -36,11 +36,15 @@ import {
36
36
  createCapabilityGrant,
37
37
  createCapabilityRevocation,
38
38
  createProofNetworkAnchorBatch,
39
+ createRegistryEntry,
40
+ createRegistryBatch,
39
41
  sha256Json as proofNetworkSha256Json,
40
42
  validateBenchmarkAttestation,
41
43
  validateCapabilityGrant,
42
44
  validateCapabilityRevocation,
43
45
  validateProofNetworkAnchorBatch,
46
+ validateRegistryEntry,
47
+ validateRegistryBatch,
44
48
  validateProofNetworkPacket,
45
49
  } from '../../../packages/proof-network/src/index.js';
46
50
 
@@ -53,7 +57,7 @@ export const DEFAULT_GATEWAY_PORT = 8797;
53
57
  const DEFAULT_QUICKSTART_MEMORY = 'Enigma quickstart demo memory: local proof bundles can be created and verified without provider or cloud credentials.';
54
58
  const DEFAULT_CROSS_MODEL_DEMO_BUNDLE = '.enigma/cross-model-demo-bundle.json';
55
59
  const DEFAULT_CROSS_MODEL_MEMORY = 'Enigma cross-model demo memory: a local encrypted memory can be packaged for ChatGPT, Claude, Kimi, Cursor, and a local LLM without provider credentials.';
56
- const DEFAULT_SETUP_CLIENTS = Object.freeze(['generic-mcp', 'claude-desktop', 'cursor', 'kimi-code']);
60
+ const DEFAULT_SETUP_CLIENTS = Object.freeze(['generic-mcp', 'claude-desktop', 'cursor', 'kimi-code', 'vscode-cline']);
57
61
  const SETUP_CLAIM_BOUNDARIES = Object.freeze({
58
62
  local_only: true,
59
63
  provider_credentials_required: false,
@@ -1043,15 +1047,32 @@ function publicSetupError(error, rawDisplays, publicDisplays) {
1043
1047
  return new Error(message);
1044
1048
  }
1045
1049
 
1050
+ function oneCommandInstallConnect(bundleDisplay = DEFAULT_BUNDLE, outDirDisplay = dirname(bundleDisplay)) {
1051
+ const parts = ['npm install -g enigma-memory && enigma setup'];
1052
+ if (bundleDisplay !== DEFAULT_BUNDLE) parts.push(`--bundle ${commandPath(bundleDisplay)}`);
1053
+ if (outDirDisplay !== dirname(bundleDisplay)) parts.push(`--out-dir ${commandPath(outDirDisplay)}`);
1054
+ const base = parts.join(' ');
1055
+ return {
1056
+ installed_clients: `${base} --client auto --connect-installed --overwrite`,
1057
+ claude_desktop: `${base} --client claude-desktop --write-connectors --overwrite`,
1058
+ cursor: `${base} --client cursor --write-connectors --overwrite`,
1059
+ kimi_code: `${base} --client kimi-code --write-connectors --overwrite`,
1060
+ vscode_cline: `${base} --client vscode-cline --write-connectors --overwrite`,
1061
+ };
1062
+ }
1063
+
1046
1064
  function setupNextCommands(bundleInput, exportDisplay, clients, writeConnectors) {
1047
1065
  const primaryClient = clients[0] ?? DEFAULT_SETUP_CLIENTS[0];
1066
+ const bundle = commandPath(bundleInput);
1048
1067
  const commands = [
1049
- `enigma remember --bundle ${commandPath(bundleInput)} --text-file ./memory.txt`,
1050
- `enigma search --bundle ${commandPath(bundleInput)} --query "project context"`,
1051
- `enigma context --bundle ${commandPath(bundleInput)} --query "project context"`,
1068
+ `enigma status --bundle ${bundle}`,
1069
+ `enigma drive health --bundle ${bundle}`,
1070
+ `enigma remember --bundle ${bundle} --text-file ./memory.txt`,
1071
+ `enigma search --bundle ${bundle} --query "project context"`,
1072
+ `enigma context --bundle ${bundle} --query "project context"`,
1052
1073
  `enigma verify --export ${commandPath(exportDisplay)}`,
1053
1074
  ];
1054
- if (!writeConnectors) commands.push(`enigma connect ${primaryClient} --bundle ${commandPath(bundleInput)} --dry-run`);
1075
+ if (!writeConnectors) commands.push(`enigma connect ${primaryClient} --bundle ${bundle} --dry-run`);
1055
1076
  return commands;
1056
1077
  }
1057
1078
 
@@ -1072,10 +1093,13 @@ function initNextCommands({ dryRun, bundleDisplay, outDirDisplay, exportDisplay,
1072
1093
 
1073
1094
  function doctorNextCommands(bundleDisplay, client) {
1074
1095
  const clientId = client ?? DEFAULT_SETUP_CLIENTS[0];
1096
+ const bundle = commandPath(bundleDisplay);
1075
1097
  return [
1076
- `enigma setup --bundle ${commandPath(bundleDisplay)}`,
1077
- `enigma doctor --bundle ${commandPath(bundleDisplay)} --client ${clientId}`,
1078
- `enigma connect ${clientId} --bundle ${commandPath(bundleDisplay)}`,
1098
+ `enigma status --bundle ${bundle}`,
1099
+ `enigma drive health --bundle ${bundle}`,
1100
+ `enigma setup --bundle ${bundle}`,
1101
+ `enigma doctor --bundle ${bundle} --client ${clientId}`,
1102
+ `enigma connect ${clientId} --bundle ${bundle}`,
1079
1103
  ];
1080
1104
  }
1081
1105
 
@@ -1297,6 +1321,7 @@ export async function setupCommand(flags, io) {
1297
1321
  client_selection: publicSetupClientSelection(selection),
1298
1322
  connector_write_skips: connectorWriteSkips(connectors),
1299
1323
  connectors,
1324
+ one_command_install_connect: oneCommandInstallConnect(displays.bundle, publicPathDisplay(outDirInput, 'out-dir')),
1300
1325
  mcp_config_snippets: Object.fromEntries(connectors.map((connector) => [connector.client_id, connector.mcp_config_snippet])),
1301
1326
  connect_plans: Object.fromEntries(connectors.map((connector) => [connector.client_id, connector.connect_plan])),
1302
1327
  next_commands: setupNextCommands(displays.bundle, displays.export, clients, connectorWritesRequested && (!connectInstalled || anyConnectorWritePerformed)),
@@ -1675,6 +1700,27 @@ async function statusCommand(flags, io) {
1675
1700
  print(passportStatusReport({ bundlePath, stored, vault, passport }), io);
1676
1701
  return 0;
1677
1702
  }
1703
+ async function readOptionalJsonInput(flags, names) {
1704
+ const path = getFlag(flags, names);
1705
+ if (!path) return null;
1706
+ if (!(await fileExists(path))) return null;
1707
+ return readJson(path);
1708
+ }
1709
+
1710
+ async function driveHealthCommand(flags, io) {
1711
+ const bundlePath = resolve(String(getFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE)));
1712
+ const { vault, passport } = await loadState(bundlePath);
1713
+ const benchmarkSummary = await readOptionalJsonInput(flags, ['benchmark-summary', 'benchmarkSummary']);
1714
+ const connectorSummary = await readOptionalJsonInput(flags, ['connector-summary', 'connectorSummary']);
1715
+ const replicas = await readOptionalJsonInput(flags, ['replicas']);
1716
+ const latestAnchorBatchRef = getFlag(flags, ['latest-anchor-batch-ref', 'latestAnchorBatchRef']);
1717
+ const now = getFlag(flags, ['now'], '2026-06-25T00:00:00.000Z');
1718
+ const report = createMemoryDriveHealthReport({ vault, passport, benchmarkSummary, connectorSummary, replicas, latestAnchorBatchRef, now });
1719
+ const outPath = getFlag(flags, ['out']);
1720
+ if (outPath) await writeJson(outPath, report);
1721
+ print(report, io);
1722
+ return 0;
1723
+ }
1678
1724
 
1679
1725
  function testDrivePathDisplay(outDirInput, name) {
1680
1726
  return isAbsolute(outDirInput) ? join(outDirInput, name) : quickstartPathDisplay(outDirInput, name);
@@ -1731,6 +1777,7 @@ function testDriveNextCommands(bundleDisplay, crossModelReportDisplay) {
1731
1777
  const quotedReport = commandPath(crossModelReportDisplay);
1732
1778
  return [
1733
1779
  `enigma status --bundle ${quotedBundle}`,
1780
+ `enigma drive health --bundle ${quotedBundle}`,
1734
1781
  `enigma search --bundle ${quotedBundle} --query "local proof bundle"`,
1735
1782
  `enigma demo cross-model --bundle ${quotedBundle} --out ${quotedReport}`,
1736
1783
  'enigma setup --overwrite',
@@ -1745,6 +1792,7 @@ function testDriveFlowCommands({ bundleDisplay, outDirInput, crossModelReportDis
1745
1792
  return [
1746
1793
  `enigma quickstart --bundle ${quotedBundle} --out-dir ${quotedOutDir}${overwriteSuffix}`,
1747
1794
  `enigma status --bundle ${quotedBundle}`,
1795
+ `enigma drive health --bundle ${quotedBundle}`,
1748
1796
  `enigma search --bundle ${quotedBundle} --query "local proof bundle"`,
1749
1797
  `enigma demo cross-model --bundle ${quotedBundle} --out ${quotedReport}`,
1750
1798
  ];
@@ -1938,7 +1986,7 @@ export async function testDriveCommand(flags, io) {
1938
1986
  out_dir: outDirInput,
1939
1987
  bundle: bundleInput,
1940
1988
  install_command: `npm install -g ${packageJson.name ?? 'enigma-memory'}`,
1941
- release_target: '0.1.15',
1989
+ release_target: '0.1.17',
1942
1990
  artifacts_written: !dryRun,
1943
1991
  client_configs_written: false,
1944
1992
  client_config_write_required: false,
@@ -2122,6 +2170,7 @@ export async function installCommand(flags, io) {
2122
2170
  mcp_command: connectorOptions(flags).mcpCommand ?? 'enigma-mcp',
2123
2171
  clients: profiles,
2124
2172
  mcp_config_snippets: snippets,
2173
+ one_command_install_connect: oneCommandInstallConnect(bundlePath, dirname(bundlePath)),
2125
2174
  out: out && out !== true ? resolve(String(out)) : undefined,
2126
2175
  }, io);
2127
2176
  return 0;
@@ -2389,6 +2438,8 @@ function chainArtifactValidator(artifact) {
2389
2438
  if (schema === 'enigma.proof_network.capability_revocation.v1') return [schema, validateCapabilityRevocation];
2390
2439
  if (schema === 'enigma.proof_network.benchmark_attestation.v1') return [schema, validateBenchmarkAttestation];
2391
2440
  if (schema === 'enigma.proof_network.packet.v1') return [schema, validateProofNetworkPacket];
2441
+ if (schema === 'enigma.proof_network.registry_entry.v1') return [schema, validateRegistryEntry];
2442
+ if (schema === 'enigma.proof_network.registry_batch.v1') return [schema, validateRegistryBatch];
2392
2443
  throw new Error(schema ? 'Unsupported proof-network artifact schema.' : 'Unsupported proof-network artifact schema: missing.');
2393
2444
  }
2394
2445
 
@@ -2445,11 +2496,11 @@ async function readSolanaKeypair(path) {
2445
2496
  } catch {
2446
2497
  throw new Error('Unable to read a valid Solana --keypair JSON array.');
2447
2498
  }
2448
- if (!Array.isArray(parsed) || parsed.length === 0) throw new Error('Solana --keypair must be a JSON array of secret-key bytes.');
2499
+ if (!Array.isArray(parsed) || parsed.length !== 64) throw new Error('Solana --keypair must be a JSON array of 64 secret-key bytes.');
2449
2500
  const bytes = new Uint8Array(parsed.length);
2450
2501
  for (let i = 0; i < parsed.length; i += 1) {
2451
2502
  const value = parsed[i];
2452
- if (!Number.isInteger(value) || value < 0 || value > 255) throw new Error('Solana --keypair must be a JSON array of secret-key bytes.');
2503
+ if (!Number.isInteger(value) || value < 0 || value > 255) throw new Error('Solana --keypair must be a JSON array of 64 secret-key bytes.');
2453
2504
  bytes[i] = value;
2454
2505
  }
2455
2506
  return bytes;
@@ -2686,6 +2737,60 @@ export async function chainVerifyCommand(flags, io, positionalFile = undefined)
2686
2737
  return result.ok === true ? 0 : 1;
2687
2738
  }
2688
2739
 
2740
+ export async function chainRegisterCommand(flags, io) {
2741
+ const entryType = requireFlag(flags, ['entry-type', 'entryType', 'type'], 'entry-type');
2742
+ const artifactHashFlag = getFlag(flags, ['artifact-hash', 'artifactHash', 'digest-ref', 'digestRef', 'artifact-ref', 'artifactRef']);
2743
+ const artifactFile = getFlag(flags, ['artifact-file', 'artifactFile']);
2744
+ const resolvedArtifactHash = artifactHashFlag || (artifactFile ? await sha256PublicFile(resolve(String(artifactFile))) : undefined);
2745
+ if (!resolvedArtifactHash) throw new Error('Missing required --artifact-hash or --artifact-file.');
2746
+ const digestRefs = flagValues(flags, ['digest-ref', 'digest-refs', 'digestRef', 'digestRefs', 'root', 'roots']);
2747
+ const entry = createRegistryEntry({
2748
+ entry_type: entryType,
2749
+ artifact_hash: resolvedArtifactHash,
2750
+ artifact_schema_ref: requireFlag(flags, ['artifact-schema-ref', 'artifactSchemaRef', 'schema-ref', 'schemaRef'], 'artifact-schema-ref'),
2751
+ digest_refs: digestRefs.length ? digestRefs : resolvedArtifactHash,
2752
+ signer_refs: flagValues(flags, ['signer', 'signers', 'signer-ref', 'signerRef', 'signer-refs', 'signerRefs', 'attestor', 'attestor-ref', 'attestorRef']),
2753
+ registry_ref: getFlag(flags, ['registry-ref', 'registryRef', 'marketplace-ref', 'marketplaceRef']),
2754
+ entry_ref: getFlag(flags, ['entry-ref', 'entryRef']),
2755
+ entry_count: getFlag(flags, ['entry-count', 'entryCount', 'count']),
2756
+ created_at: getFlag(flags, ['created-at', 'createdAt', 'registered-at', 'registeredAt']),
2757
+ transaction_submitted: false,
2758
+ raw_memory_on_chain: false,
2759
+ });
2760
+ assertChainArtifact(validateRegistryEntry, entry);
2761
+ return chainWriteOrPrint(flags, io, entry, {
2762
+ artifact_type: entry.schema,
2763
+ registry_entry_id: entry.registry_entry_id,
2764
+ registry_entry_hash: entry.registry_entry_hash ?? proofNetworkSha256Json(entry),
2765
+ });
2766
+ }
2767
+
2768
+ export async function chainRegistryCommand(flags, io, positionalFile = undefined) {
2769
+ const entryPaths = flagValues(flags, ['entry', 'entries', 'entry-file', 'entryFile']);
2770
+ const positionalEntry = positionalFile && !String(positionalFile).startsWith('--') ? positionalFile : undefined;
2771
+ const paths = entryPaths.length ? entryPaths : (positionalEntry ? [positionalEntry] : []);
2772
+ if (paths.length === 0) throw new Error('Missing required --entry <registry-entry.json>.');
2773
+ const entries = [];
2774
+ for (const entryPath of paths) {
2775
+ const entry = await readJson(resolve(entryPath));
2776
+ assertNoPrivateProofPayload(entry);
2777
+ entries.push(entry);
2778
+ }
2779
+ const batch = createRegistryBatch({
2780
+ entries,
2781
+ registry_ref: getFlag(flags, ['registry-ref', 'registryRef', 'marketplace-ref', 'marketplaceRef']),
2782
+ created_at: getFlag(flags, ['created-at', 'createdAt']),
2783
+ transaction_submitted: false,
2784
+ raw_memory_on_chain: false,
2785
+ });
2786
+ assertChainArtifact(validateRegistryBatch, batch);
2787
+ return chainWriteOrPrint(flags, io, batch, {
2788
+ artifact_type: batch.schema,
2789
+ registry_batch_id: batch.registry_batch_id,
2790
+ registry_batch_hash: batch.registry_batch_hash ?? proofNetworkSha256Json(batch),
2791
+ });
2792
+ }
2793
+
2689
2794
 
2690
2795
  export async function meterEventCommand(flags, io) {
2691
2796
  const event = createUsageEvent({
@@ -2911,6 +3016,9 @@ function usage() {
2911
3016
  'chain attest',
2912
3017
  'chain verify',
2913
3018
  'chain submit-solana',
3019
+ 'chain register',
3020
+ 'chain registry',
3021
+ 'drive health',
2914
3022
  ],
2915
3023
  connector_options: {
2916
3024
  '--bundle <path>': 'Absolute local Enigma vault bundle path rendered as ENIGMA_BUNDLE.',
@@ -2955,6 +3063,15 @@ function usage() {
2955
3063
  '--dry-run': 'Plan setup without writing local artifacts or client configs.',
2956
3064
  '--write-connectors': 'Also write selected client MCP config files. Defaults to false.',
2957
3065
  },
3066
+ install_options: {
3067
+ 'one-command installed clients': 'npm install -g enigma-memory && enigma setup --client auto --connect-installed --overwrite',
3068
+ 'one-command Claude Desktop': 'npm install -g enigma-memory && enigma setup --client claude-desktop --write-connectors --overwrite',
3069
+ 'one-command Cursor': 'npm install -g enigma-memory && enigma setup --client cursor --write-connectors --overwrite',
3070
+ 'one-command Kimi Code': 'npm install -g enigma-memory && enigma setup --client kimi-code --write-connectors --overwrite',
3071
+ 'one-command VS Code Cline': 'npm install -g enigma-memory && enigma setup --client vscode-cline --write-connectors --overwrite',
3072
+ '--client <id>': 'Limit generated MCP snippets to one supported client.',
3073
+ '--out <path>': 'Write generated MCP snippets to a JSON file for review without hand-editing client config JSON.',
3074
+ },
2958
3075
  quickstart_options: {
2959
3076
  '--bundle <path>': 'Bundle JSON to create. Defaults to .enigma/bundle.json.',
2960
3077
  '--out-dir <path>': 'Directory for context-pack.json, export.json, and verify-report.json. Defaults to the bundle directory.',
@@ -3022,9 +3139,26 @@ function usage() {
3022
3139
  revoke: 'enigma chain revoke --grant-hash <sha256:...> --reason <public-reason-code> [--revocation-ref <public-ref>] [--out <file>]',
3023
3140
  attest: 'enigma chain attest (--report-hash <sha256:...> | --report-file <report.json>) --dataset-ref <sha256:...> --runner-ref <public-runner-ref> --package-ref <public-package-ref> [--score name=value] [--out <file>]',
3024
3141
  verify: 'enigma chain verify --file <proof-artifact.json>',
3025
- submit_solana: 'enigma chain submit-solana --file <proof-artifact.json> --cluster <devnet|testnet|mainnet-beta|localnet> [--rpc <url>] [--execute --keypair <solana-keypair.json>]',
3142
+ register: 'enigma chain register --entry-type <anchor_batch|benchmark_attestation|connector_conformance|health_report|operator_receipt|settlement_job> (--artifact-hash <sha256:...> | --artifact-file <artifact.json>) --artifact-schema-ref <schema-id> [--digest-ref <sha256:...>] [--signer <public-ref>] [--registry-ref <public-ref>] [--entry-ref <public-ref>] [--entry-count <n>] [--out <file>]',
3143
+ registry: 'enigma chain registry --entry <registry-entry.json> [--entry <registry-entry.json>] [--registry-ref <public-ref>] [--out <file>]',
3144
+ submit_solana: 'enigma chain submit-solana --file <proof-artifact.json> --cluster <devnet|testnet|mainnet-beta|localnet> [--rpc <url>] [--execute --keypair <solana-cli-64-byte-keypair.json>]',
3026
3145
  boundary: 'Proof Network chain commands default to local planning and dry-run validation. submit-solana only submits a Solana Memo transaction when --execute is passed; it carries compact public-safe commitment/ref JSON, never raw memory or artifact bodies.',
3027
3146
  },
3147
+ memory_drive_health: {
3148
+ command: 'enigma drive health --bundle <path> [--now <iso>] [--benchmark-summary <path>] [--connector-summary <path>] [--replicas <path>] [--latest-anchor-batch-ref <ref>] [--out <file>]',
3149
+ schema: 'enigma.memory_drive_health_report.v1',
3150
+ output_shape: 'SMART-style report: overall_status/overall_score, ten metrics (freshness, duplicate_rate, tombstone_risk, stale_derived_artifacts, retrieval_hit_rate, token_reduction, leakage_scan, receipt_coverage, connector_health, sync_fork_risk), each with status/score/observed/thresholds/evidence_refs/recommended_actions, plus roots, privacy_boundaries, claim_boundaries, and a conservative proof_network_ready block.',
3151
+ options: {
3152
+ '--bundle <path>': 'Local Enigma vault bundle to inspect. Defaults to .enigma/bundle.json.',
3153
+ '--now <iso>': 'ISO-8601 timestamp used for age calculations. Defaults to a deterministic timestamp.',
3154
+ '--benchmark-summary <path>': 'Optional JSON file with public-safe retrieval probes (probe_count, top_k, hit_at_k, exact_coverage, abstention_correctness). Omit to default gracefully.',
3155
+ '--connector-summary <path>': 'Optional JSON file with public-safe connector health (connector_count, healthy_connector_count, lagging_connector_count, error_rate_24h, cursor_gap_count). Omit to default gracefully.',
3156
+ '--replicas <path>': 'Optional JSON file of replica root reports for sync fork risk.',
3157
+ '--latest-anchor-batch-ref <ref>': 'Optional public-safe proof-network anchor batch ref for receipt coverage.',
3158
+ '--out <path>': 'Write the JSON report to a file in addition to stdout.',
3159
+ },
3160
+ boundary: 'Computed locally from public-safe counters, roots, receipt metadata, tombstones, and derived/context-pack refs only. No network or chain calls; transaction_submitted and raw_memory_on_chain are always false. It is local operational evidence, not provider-deletion, model-forgetting, compliance, or live-chain-settlement proof.',
3161
+ },
3028
3162
  relay_gateway_options: {
3029
3163
  '--host <host>': 'Bind host. Defaults to 127.0.0.1.',
3030
3164
  '--port <port>': `Bind port. Defaults to ${DEFAULT_RELAY_PORT} for relay and ${DEFAULT_GATEWAY_PORT} for gateway.`,
@@ -3051,10 +3185,10 @@ export async function main(argv = process.argv.slice(2), io = { stdout: process.
3051
3185
  print(usage(), io);
3052
3186
  return 0;
3053
3187
  }
3054
- const twoPartCommands = ['boundary', 'mcp', 'mesh', 'enterprise', 'capsule', 'relay', 'gateway', 'connect', 'disconnect', 'import', 'native-host', 'meter', 'settlement', 'chain', 'demo', 'passport'];
3188
+ const twoPartCommands = ['boundary', 'mcp', 'mesh', 'enterprise', 'capsule', 'relay', 'gateway', 'connect', 'disconnect', 'import', 'native-host', 'meter', 'settlement', 'chain', 'demo', 'passport', 'drive'];
3055
3189
  const flags = parseArgs(twoPartCommands.includes(command) ? argv.slice(2) : argv.slice(1));
3056
3190
  const positionalFile = optionalPositional(argv[2]);
3057
- if ((command === 'chain' && (!subcommand || subcommand === '--help' || subcommand === '-h' || flags.has('help'))) || ((flags.has('help') || argv.includes('-h')) && (command === 'init' || command === 'setup' || command === 'test-drive' || command === 'search' || command === 'status' || (command === 'passport' && subcommand === 'status') || ((command === 'relay' || command === 'gateway') && (subcommand === 'serve' || subcommand === 'demo')) || (command === 'native-host' && (subcommand === 'manifest' || subcommand === 'install-plan')) || (command === 'demo' && subcommand === 'cross-model')))) {
3191
+ if ((command === 'chain' && (!subcommand || subcommand === '--help' || subcommand === '-h' || flags.has('help'))) || ((flags.has('help') || argv.includes('-h')) && (command === 'init' || command === 'setup' || command === 'test-drive' || command === 'search' || command === 'status' || (command === 'passport' && subcommand === 'status') || ((command === 'relay' || command === 'gateway') && (subcommand === 'serve' || subcommand === 'demo')) || (command === 'native-host' && (subcommand === 'manifest' || subcommand === 'install-plan')) || (command === 'demo' && subcommand === 'cross-model') || (command === 'drive' && subcommand === 'health')))) {
3058
3192
  print(usage(), io);
3059
3193
  return 0;
3060
3194
  }
@@ -3076,6 +3210,7 @@ export async function main(argv = process.argv.slice(2), io = { stdout: process.
3076
3210
  if (command === 'search') return await searchCommand(flags, io);
3077
3211
  if (command === 'status') return await statusCommand(flags, io);
3078
3212
  if (command === 'passport' && subcommand === 'status') return await statusCommand(flags, io);
3213
+ if (command === 'drive' && subcommand === 'health') return await driveHealthCommand(flags, io);
3079
3214
  if (command === 'export') return await exportCommand(flags, io);
3080
3215
  if (command === 'import') return await importCommand(subcommand, flags, io, positionalFile);
3081
3216
  if (command === 'capsule' && subcommand === 'export') return await capsuleExportCommand(flags, io, positionalFile);
@@ -3102,6 +3237,8 @@ export async function main(argv = process.argv.slice(2), io = { stdout: process.
3102
3237
  if (command === 'chain' && subcommand === 'attest') return await chainAttestCommand(flags, io);
3103
3238
  if (command === 'chain' && subcommand === 'verify') return await chainVerifyCommand(flags, io, positionalFile);
3104
3239
  if (command === 'chain' && subcommand === 'submit-solana') return await chainSubmitSolanaCommand(flags, io, positionalFile);
3240
+ if (command === 'chain' && subcommand === 'register') return await chainRegisterCommand(flags, io);
3241
+ if (command === 'chain' && subcommand === 'registry') return await chainRegistryCommand(flags, io, positionalFile);
3105
3242
  if (command === 'native-host' && subcommand === 'install-plan') return await nativeHostInstallPlanCommand(flags, io);
3106
3243
  if (command === 'mesh' && subcommand === 'demo') return await meshDemoCommand(flags, io);
3107
3244
  if (command === 'enterprise' && subcommand === 'demo') return await enterpriseDemoCommand(flags, io);
@@ -55,6 +55,26 @@ The CLI manifest generator and install-plan preview are the recommended path bec
55
55
 
56
56
  4. If your browser does not inherit the `ENIGMA_BUNDLE` user environment, create a small local wrapper that sets `ENIGMA_BUNDLE` and then execs the absolute `enigma-native-host` path. Point the manifest `path` to that wrapper. Keep the wrapper owner-writable only.
57
57
 
58
+
59
+ ## Fast MCP client setup
60
+
61
+ For Claude Desktop, Cursor, Kimi Code, and VS Code Cline, avoid hand-editing MCP JSON. After installing the package, use the CLI to create the local bundle and merge only the Enigma MCP server entry into the selected client config:
62
+
63
+ ```sh
64
+ npm install -g enigma-memory && enigma setup --client claude-desktop --write-connectors --overwrite
65
+ npm install -g enigma-memory && enigma setup --client cursor --write-connectors --overwrite
66
+ npm install -g enigma-memory && enigma setup --client kimi-code --write-connectors --overwrite
67
+ npm install -g enigma-memory && enigma setup --client vscode-cline --write-connectors --overwrite
68
+ ```
69
+
70
+ To connect only clients whose config files already exist, use:
71
+
72
+ ```sh
73
+ npm install -g enigma-memory && enigma setup --client auto --connect-installed --overwrite
74
+ ```
75
+
76
+ The generated MCP entry uses `enigma-mcp` with `ENIGMA_BUNDLE` pointing at the local bundle. Existing sibling MCP servers are preserved; changed configs are backed up by `enigma connect`.
77
+
58
78
  ## Generate a manifest
59
79
 
60
80
  Use the CLI generator instead of hand-editing JSON: