enigma-memory 0.1.12 → 0.1.13

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.
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createHash } from 'node:crypto';
3
3
  import { createServer as createHttpServer } from 'node:http';
4
- import { realpathSync } from 'node:fs';
5
- import { access, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
4
+ import { constants as fsConstants, realpathSync } from 'node:fs';
5
+ import { access, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
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';
@@ -574,6 +574,86 @@ function minimumNodeMajor(range) {
574
574
  return match ? Number(match[1]) : 0;
575
575
  }
576
576
 
577
+ function npmUserAgentCheck(userAgent = process.env.npm_config_user_agent) {
578
+ const raw = typeof userAgent === 'string' ? userAgent.trim() : '';
579
+ const npmToken = raw.split(/\s+/).find((token) => token.startsWith('npm/'));
580
+ const version = npmToken ? npmToken.slice(4) : null;
581
+ return {
582
+ ok: true,
583
+ detected: version !== null,
584
+ name: version === null ? null : 'npm',
585
+ version,
586
+ source: version === null ? null : 'npm_config_user_agent',
587
+ };
588
+ }
589
+
590
+ async function statIfExists(path) {
591
+ try {
592
+ return await stat(path);
593
+ } catch (error) {
594
+ if (error?.code === 'ENOENT' || error?.code === 'ENOTDIR') return null;
595
+ throw error;
596
+ }
597
+ }
598
+
599
+ async function nearestExistingAncestor(path) {
600
+ let current = resolve(path);
601
+ for (;;) {
602
+ const stats = await statIfExists(current);
603
+ if (stats !== null) return { path: current, stats };
604
+ const parent = dirname(current);
605
+ if (parent === current) return null;
606
+ current = parent;
607
+ }
608
+ }
609
+
610
+ function publicParentDisplay(path, label) {
611
+ const value = String(path);
612
+ if (/^<[^>]+>$/.test(value)) return `<${label}>`;
613
+ const parent = dirname(value);
614
+ return parent === '' ? '.' : publicPathDisplay(parent, label);
615
+ }
616
+
617
+ async function writableVaultPathCheck(bundleInput, displayInput = bundleInput) {
618
+ const bundlePath = resolve(String(bundleInput));
619
+ const parentPath = dirname(bundlePath);
620
+ const targetStats = await statIfExists(bundlePath);
621
+ const nearest = await nearestExistingAncestor(parentPath);
622
+ let ok = false;
623
+ let reason = null;
624
+ let parentExists = false;
625
+ let nearestExistingParent = null;
626
+ if (targetStats?.isDirectory()) {
627
+ reason = 'target_is_directory';
628
+ } else if (nearest === null) {
629
+ reason = 'no_existing_parent';
630
+ } else if (!nearest.stats.isDirectory()) {
631
+ reason = 'nearest_parent_not_directory';
632
+ nearestExistingParent = '<existing-parent-path>';
633
+ } else {
634
+ parentExists = nearest.path === parentPath;
635
+ nearestExistingParent = parentExists ? publicParentDisplay(displayInput, 'bundle-dir') : '<existing-parent-dir>';
636
+ try {
637
+ await access(nearest.path, fsConstants.W_OK);
638
+ ok = true;
639
+ } catch {
640
+ reason = 'parent_not_writable';
641
+ }
642
+ }
643
+ return {
644
+ ok,
645
+ path: publicPathDisplay(displayInput, 'bundle-path'),
646
+ parent: publicParentDisplay(displayInput, 'bundle-dir'),
647
+ parent_exists: parentExists,
648
+ nearest_existing_parent: nearestExistingParent,
649
+ target_exists: targetStats !== null,
650
+ target_is_directory: targetStats?.isDirectory() === true,
651
+ writable: ok,
652
+ reason,
653
+ hint: ok ? null : 'Choose a writable --bundle path or create a writable parent directory.',
654
+ };
655
+ }
656
+
577
657
  async function schemaFiles() {
578
658
  return (await readdir(SPECS_URL)).filter((name) => name.endsWith('.schema.json')).sort();
579
659
  }
@@ -908,10 +988,19 @@ function setupNextCommands(bundleInput, exportDisplay, clients, writeConnectors)
908
988
  `enigma context --bundle ${commandPath(bundleInput)} --query "project context"`,
909
989
  `enigma verify --export ${commandPath(exportDisplay)}`,
910
990
  ];
911
- if (!writeConnectors) commands.push(`enigma connect ${primaryClient} --bundle ${commandPath(bundleInput)}`);
991
+ if (!writeConnectors) commands.push(`enigma connect ${primaryClient} --bundle ${commandPath(bundleInput)} --dry-run`);
912
992
  return commands;
913
993
  }
914
994
 
995
+ function doctorNextCommands(bundleDisplay, client) {
996
+ const clientId = client ?? DEFAULT_SETUP_CLIENTS[0];
997
+ return [
998
+ `enigma setup --bundle ${commandPath(bundleDisplay)}`,
999
+ `enigma doctor --bundle ${commandPath(bundleDisplay)} --client ${clientId}`,
1000
+ `enigma connect ${clientId} --bundle ${commandPath(bundleDisplay)}`,
1001
+ ];
1002
+ }
1003
+
915
1004
  async function setupDoctorChecks(flags, artifacts, clients, displays) {
916
1005
  const packageJson = await readPackageJson();
917
1006
  const requiredNodeMajor = minimumNodeMajor(packageJson.engines?.node);
@@ -938,12 +1027,15 @@ async function setupDoctorChecks(flags, artifacts, clients, displays) {
938
1027
  const doctor = await doctorConnectors({ ...connectorBaseOptions, clientId: client });
939
1028
  connectorClients.push(...doctor.clients);
940
1029
  }
1030
+ const vaultPath = await writableVaultPathCheck(artifacts.bundlePath, displays.bundle);
941
1031
  const checks = {
942
1032
  node: {
943
1033
  ok: requiredNodeMajor === 0 || currentNodeMajor >= requiredNodeMajor,
944
1034
  current: process.versions.node,
945
1035
  required: packageJson.engines?.node ?? null,
946
1036
  },
1037
+ npm: npmUserAgentCheck(),
1038
+ vault_path: vaultPath,
947
1039
  package_bins: {
948
1040
  ok: binEntries.every((entry) => entry.declared && entry.exists),
949
1041
  required: REQUIRED_PACKAGE_BINS,
@@ -1531,7 +1623,7 @@ function testDriveNextCommands(bundleDisplay, crossModelReportDisplay) {
1531
1623
  `enigma status --bundle ${quotedBundle}`,
1532
1624
  `enigma search --bundle ${quotedBundle} --query "local proof bundle"`,
1533
1625
  `enigma demo cross-model --bundle ${quotedBundle} --out ${quotedReport}`,
1534
- 'node scripts/run-memory-benchmarks.mjs',
1626
+ 'enigma setup --overwrite',
1535
1627
  ];
1536
1628
  }
1537
1629
 
@@ -1736,7 +1828,7 @@ export async function testDriveCommand(flags, io) {
1736
1828
  out_dir: outDirInput,
1737
1829
  bundle: bundleInput,
1738
1830
  install_command: `npm install -g ${packageJson.name ?? 'enigma-memory'}`,
1739
- release_target: '0.1.12',
1831
+ release_target: '0.1.13',
1740
1832
  artifacts_written: !dryRun,
1741
1833
  client_configs_written: false,
1742
1834
  client_config_write_required: false,
@@ -1842,10 +1934,11 @@ export async function doctorCommand(flags, io) {
1842
1934
  };
1843
1935
  }));
1844
1936
  const schemas = await schemaFiles();
1937
+ const bundleInput = pathFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE);
1845
1938
  const selectedClient = getFlag(flags, ['client']);
1846
1939
  const doctorOptions = selectedClient && selectedClient !== true
1847
- ? { ...connectorOptions(flags), clientId: String(selectedClient) }
1848
- : { ...connectorOptions(flags), clientId: undefined };
1940
+ ? { ...connectorOptions(flags), clientId: String(selectedClient), redactPaths: true }
1941
+ : { ...connectorOptions(flags), clientId: undefined, redactPaths: true };
1849
1942
  const connectorDoctor = await doctorConnectors(doctorOptions);
1850
1943
  const profile = getClientProfile(String(selectedClient && selectedClient !== true ? selectedClient : 'generic-mcp'), connectorOptions(flags));
1851
1944
  const checks = {
@@ -1854,6 +1947,7 @@ export async function doctorCommand(flags, io) {
1854
1947
  current: process.versions.node,
1855
1948
  required: packageJson.engines?.node ?? null,
1856
1949
  },
1950
+ npm: npmUserAgentCheck(),
1857
1951
  package_bins: {
1858
1952
  ok: binEntries.every((entry) => entry.declared && entry.exists),
1859
1953
  required: REQUIRED_PACKAGE_BINS,
@@ -1864,8 +1958,9 @@ export async function doctorCommand(flags, io) {
1864
1958
  bundle_default_path: {
1865
1959
  ok: DEFAULT_BUNDLE === '.enigma/bundle.json',
1866
1960
  path: DEFAULT_BUNDLE,
1867
- resolved: resolve(String(getFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE))),
1961
+ resolved: publicPathDisplay(resolve(bundleInput), 'bundle-path'),
1868
1962
  },
1963
+ vault_path: await writableVaultPathCheck(resolve(bundleInput), publicPathDisplay(bundleInput, 'bundle-path')),
1869
1964
  schemas: {
1870
1965
  ok: schemas.length > 0,
1871
1966
  count: schemas.length,
@@ -1883,11 +1978,14 @@ export async function doctorCommand(flags, io) {
1883
1978
  ok,
1884
1979
  node: checks.node,
1885
1980
  package_bins: checks.package_bins,
1981
+ npm: checks.npm,
1982
+ vault_path: checks.vault_path,
1886
1983
  bundle_default_path: checks.bundle_default_path,
1887
1984
  schema_count: checks.schemas.count,
1888
1985
  schemas: checks.schemas,
1889
1986
  mcp_command_name: checks.mcp_command_name.command,
1890
1987
  connectors: checks.connectors,
1988
+ next_commands: doctorNextCommands(checks.vault_path.path, String(selectedClient && selectedClient !== true ? selectedClient : 'generic-mcp')),
1891
1989
  checks,
1892
1990
  }, io);
1893
1991
  return ok ? 0 : 1;
@@ -169,7 +169,7 @@ Minimum public-safe attestation skeleton:
169
169
  "track": "public_practice",
170
170
  "program": {
171
171
  "name": "enigma_benchmark_attestation_network",
172
- "version": "0.1.12",
172
+ "version": "0.1.13",
173
173
  "policy_ref": "sha256:policy-root"
174
174
  },
175
175
  "run": {
@@ -177,7 +177,7 @@ Minimum public-safe attestation skeleton:
177
177
  "nonce": "sha256:run-nonce-commitment",
178
178
  "status": "completed",
179
179
  "runner_ref": "sha256:runner-root",
180
- "package_ref": "npm:enigma-memory@0.1.12",
180
+ "package_ref": "npm:enigma-memory@0.1.13",
181
181
  "adapter_ref": "local:enigma-relevance",
182
182
  "environment_ref": "sha256:environment-summary-root"
183
183
  },
@@ -4,7 +4,7 @@ This guide explains how to reproduce the current local Enigma memory benchmark,
4
4
 
5
5
  ## What is reproducible today
6
6
 
7
- The current planned package is `enigma-memory@0.1.12`. Two benchmark paths are reproducible without provider credentials:
7
+ The current planned package is `enigma-memory@0.1.13`. Two benchmark paths are reproducible without provider credentials:
8
8
 
9
9
  1. The local deterministic memory suite, available through the package script and the script file it wraps:
10
10
 
@@ -64,7 +64,7 @@ Do not commit downloaded files or raw benchmark conversations. The package `.git
64
64
 
65
65
  ## Reproduce and save local fixture JSON
66
66
 
67
- 1. Use a clean checkout containing `enigma-memory@0.1.12`.
67
+ 1. Use a clean checkout containing `enigma-memory@0.1.13`.
68
68
  2. From a repository root that contains `enigma/package.json`, enter the package directory:
69
69
 
70
70
  ```sh
@@ -130,7 +130,7 @@ Public sharing should include the generated benchmark report JSON and generated
130
130
 
131
131
  ## Proof-network benchmark attestations
132
132
 
133
- For the planned 0.1.12 proof-network layer, benchmark results should be represented as a public-safe local attestation rather than by publishing raw benchmark inputs. The attestation JSON uses `schema: "enigma.proof_network.benchmark_attestation.v1"` and may be bundled in `enigma.proof_network.packet.v1` for review. The benchmark attestation flow is local planning only: it does not submit transactions, and generated artifacts must keep `transaction_submitted: false` and `raw_memory_on_chain: false`.
133
+ For the planned 0.1.13 proof-network layer, benchmark results should be represented as a public-safe local attestation rather than by publishing raw benchmark inputs. The attestation JSON uses `schema: "enigma.proof_network.benchmark_attestation.v1"` and may be bundled in `enigma.proof_network.packet.v1` for review. The benchmark attestation flow is local planning only: it does not submit transactions, and generated artifacts must keep `transaction_submitted: false` and `raw_memory_on_chain: false`.
134
134
 
135
135
  Hash the generated benchmark report and companion dataset manifest, then attest only the hashes, schema names, dataset refs, runner refs, package refs, aggregate metric names/values copied from the report, record counts, top-k/sample bounds, timestamps, and signatures or signer refs needed for review. The public artifact must not contain raw dataset rows, raw conversations, prompts, private questions, private answers, provider responses, embeddings, credentials, tenant names, account ids, local absolute paths, or unpublished benchmark scores.
136
136
 
@@ -139,7 +139,7 @@ Use a `sha256:<hex>` commitment for the report and manifest. If the CLI derives
139
139
  After running one of the benchmark commands above and confirming the report is public-safe, create a local planning attestation with placeholder hashes and metric values replaced from the generated report and manifest:
140
140
 
141
141
  ```sh
142
- enigma chain attest --report-file .enigma/standard-memory-benchmark-sample.json --dataset-ref "sha256:<public-dataset-or-manifest-hash>" --runner-ref "run-standard-memory-benchmarks.mjs@<reviewed-revision>" --package-ref "enigma-memory@0.1.12" --score "retrieval_evidence_proxy=<value-copied-from-report>" --out .enigma/standard-memory-benchmark-attestation.json
142
+ enigma chain attest --report-file .enigma/standard-memory-benchmark-sample.json --dataset-ref "sha256:<public-dataset-or-manifest-hash>" --runner-ref "run-standard-memory-benchmarks.mjs@<reviewed-revision>" --package-ref "enigma-memory@0.1.13" --score "retrieval_evidence_proxy=<value-copied-from-report>" --out .enigma/standard-memory-benchmark-attestation.json
143
143
  enigma chain verify --file .enigma/standard-memory-benchmark-attestation.json
144
144
  ```
145
145