enigma-memory 0.1.2 → 0.1.3

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.
@@ -0,0 +1,113 @@
1
+ # Benchmark reproducibility
2
+
3
+ This guide explains how to reproduce the current local Enigma memory benchmark, save the public-safe JSON report, cite the external benchmark standards it is modeled after, and understand what is still required before publishing live third-party comparisons.
4
+
5
+ ## What is reproducible today
6
+
7
+ The current package is `enigma-memory@0.1.3`. The local benchmark is available through the package script and the script file it wraps:
8
+
9
+ ```sh
10
+ cd enigma
11
+ npm run benchmark:memory-suite
12
+ npm run benchmark:memory-suite -- --out benchmark-report.json
13
+ node scripts/run-memory-benchmarks.mjs --out benchmark-report.json
14
+ ```
15
+
16
+ The `--out` form writes the report to the requested path and prints only a small status object. Without `--out`, the command writes the full JSON report to stdout.
17
+
18
+ The report schema is `enigma.memory_benchmark_suite.v1`. It is designed to be public-safe: it contains aggregate metrics, commitments, citations, cross-provider profile labels, and claim boundaries. It does not include raw fixture memory, private question text, private answer text, provider transcripts, credentials, account ids, or local absolute paths.
19
+
20
+ ## Reproduce and save JSON
21
+
22
+ 1. Use a clean checkout containing `enigma-memory@0.1.3`.
23
+ 2. From a repository root that contains `enigma/package.json`, enter the package directory:
24
+
25
+ ```sh
26
+ cd enigma
27
+ ```
28
+
29
+ If your checkout already has `package.json` for `enigma-memory` at the current directory, skip this `cd`.
30
+
31
+ 3. Install the package dependencies with the reviewed package command:
32
+
33
+ ```sh
34
+ npm install
35
+ ```
36
+
37
+ 4. Run the benchmark and save the public-safe JSON report:
38
+
39
+ ```sh
40
+ npm run benchmark:memory-suite -- --out benchmark-report.json
41
+ ```
42
+
43
+ 5. Preserve the JSON file with the command, package version, operating system/runtime, and review context that produced it.
44
+ 6. When sharing the result publicly, share the generated JSON report only after confirming it still has `public_safe: true` and `schema: "enigma.memory_benchmark_suite.v1"`.
45
+
46
+ The local fixture measures Enigma-controlled operations only: vault remember/update, vault export/import, passport context-pack retrieval, optimizer token estimates and duplicate removal, bundle/context-pack verification, abstention behavior, exact-answer recall over the deterministic fixture, and p50/p95 operation latency from `performance.now`.
47
+
48
+ ## Local baseline rows in the report
49
+
50
+ The report now includes `metrics.local_baseline_comparisons`, which compares deterministic local baselines over the same private fixture questions. These rows are local package evidence only: they do not call hosted providers, use provider APIs, or support invoice savings, ROI, compliance, model-forgetting, or benchmark-leadership claims.
51
+
52
+ | Row | Local boundary |
53
+ | --- | --- |
54
+ | `full_context` | Supplies every active fixture memory without optimization or deduplication. |
55
+ | `recency_last_n` | Supplies the three most recently updated active fixture memories. |
56
+ | `keyword_filter` | Supplies active fixture memories whose content or tags match deterministic query terms. |
57
+ | `enigma_context_pack` | Uses the Enigma passport context-pack compiler and optimizer boundary. |
58
+
59
+ The report also includes `public_claims_allowed`; keep public copy within those local-fixture boundaries unless separate reviewed external evidence exists.
60
+
61
+ ## How to cite external benchmark standards
62
+
63
+ Use these standards as citations and task-category references, not as claimed Enigma results unless the exact external benchmark has been run and reviewed:
64
+
65
+ - LoCoMo: https://snap-research.github.io/locomo/ — cite for long-term conversational-memory QA, event summarization, and multimodal generation over long conversations.
66
+ - LongMemEval: https://arxiv.org/abs/2410.10813 — cite for information extraction, multi-session reasoning, temporal reasoning, knowledge updates, and abstention.
67
+
68
+ The current local report mirrors some task categories from those benchmarks, but it does not download LoCoMo or LongMemEval data, run their official evaluation pipelines, or claim leaderboard-equivalent results.
69
+
70
+ ## Why live third-party comparisons are not claimed yet
71
+
72
+ The current benchmark does not call external provider APIs, external SDKs, hosted memory services, ChatGPT native memory, Claude memory tooling, or third-party agent loops. Cross-provider rows in the report are profile labels that reuse the same Enigma context-pack boundary; they do not call or compare live provider models and are not live provider rankings.
73
+
74
+ Real comparisons require fixed adapters, fixed datasets, fixed agent/tool loops, explicit provider terms review, and reviewed handling of secrets and raw benchmark data. Memory quality can change with the surrounding agent framework and tool loop, so a fair comparison must document more than the memory store.
75
+
76
+ The current report must not be used as evidence of provider-side deletion, model forgetting, compliance certification, token ROI, provider invoice savings, benchmark leadership, hosted-cloud readiness, or “best in world” superiority.
77
+
78
+ ## External comparison requirements
79
+
80
+ Use placeholder environment names only. Do not commit real tokens, API keys, account ids, provider transcripts, raw benchmark conversations, or private memory.
81
+
82
+ The report field `external_competitor_adapters` is a requirements matrix, not a score table. External rows are expected to remain requirements-only until credentials, runtimes, and datasets are supplied and reviewed: `can_run_in_this_harness: false`, `scores_included: false`, and no recall, abstention, token, latency, or ranking scores.
83
+
84
+ | Target | Runtime or SDK needed | Placeholder secrets and local inputs | Dataset requirement | Adapter boundary before results can be claimed |
85
+ | --- | --- | --- | --- | --- |
86
+ | Letta | Letta SDK/runtime; documented SDK packages include `@letta-ai/letta-client` and `letta-client`; API-key-backed service access may be required. | `LETTA_API_KEY`, `LETTA_BASE_URL`, `LETTA_PROJECT_ID`, `BENCHMARK_DATASET_PATH` | Local reviewed LoCoMo/LongMemEval split or another reviewed local dataset file with license, version, split, and checksum metadata. | Build a Letta adapter that fixes the agent loop, memory write/read policy, model settings, and scoring path. Results may describe that configured Letta run only, not generic provider deletion or model forgetting. |
87
+ | LangGraph memory | LangGraph runtime with short-term checkpointer memory and long-term namespaced store. | `LANGGRAPH_CHECKPOINTER_URI`, `LANGGRAPH_STORE_URI`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split used for Enigma and every competitor. | Fix graph topology, checkpoint scope, namespace policy, retrieval policy, model/tool loop, and scorer. Do not attribute graph/tool behavior solely to the memory store. |
88
+ | Zep | Zep service/runtime positioned around temporal Context Graph and Context Lake retrieval. | `ZEP_API_KEY`, `ZEP_PROJECT_ID`, `ZEP_BASE_URL`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split; include source checksum and whether any provider-side graph state is reused or reset. | Build a Zep adapter that records ingest, session, retrieval, reset, and scoring policy. Zep’s sub-200ms retrieval positioning is a vendor/source fact, not an Enigma-measured claim until measured in the same harness. |
89
+ | Mem0 | Mem0 platform or open-source stack; positioned as a universal self-improving memory layer. | `MEM0_API_KEY`, `MEM0_BASE_URL`, `MEM0_PROJECT_ID`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split; record Mem0 deployment flavor/version. | Build a Mem0 adapter with fixed extraction, update, retrieval, reset, and scorer behavior. Self-improving or platform behavior must be bounded to the configured run. |
90
+ | OpenAI native ChatGPT memory | ChatGPT consumer-app/native memory environment. It is not directly available through a public API in this harness. | No usable harness secret; `OPENAI_API_KEY` alone is not sufficient to exercise ChatGPT native memory. | No fair automated dataset run until an approved interface can load/reset/query native memory reproducibly. | Do not claim live native ChatGPT memory comparison from this repository. A future adapter would need an approved public interface, reproducible memory reset/load semantics, and provider-policy review. |
91
+ | Claude memory tool | Client-side/provider-specific memory tool environment. | `CLAUDE_MEMORY_TOOL_CONFIG`, `ANTHROPIC_API_KEY`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split, plus reviewed tool-state reset/export rules. | Build an adapter around the exact client/tool environment, not generic Claude model behavior. Results can only cover that configured memory-tool setup. |
92
+
93
+ ## Source references for adapter planning
94
+
95
+ - Letta MemGPT concepts: https://docs.letta.com/concepts/memgpt/
96
+ - Zep documentation: https://help.getzep.com/
97
+ - Mem0 documentation: https://docs.mem0.ai/
98
+ - LangGraph memory documentation: https://docs.langchain.com/oss/python/langgraph/memory
99
+ - OpenAI ChatGPT memory FAQ: https://help.openai.com/en/articles/8590148-memory-faq
100
+ - Claude memory tool support article: https://support.anthropic.com/en/articles/11145838-using-claude-memory
101
+
102
+ ## Minimum evidence for a future live comparison
103
+
104
+ Before publishing external comparison language, capture all of the following in the benchmark report or an adjacent reviewed evidence file:
105
+
106
+ 1. Package version, benchmark schema, command, timestamp, OS/runtime, and adapter version.
107
+ 2. Dataset name, source URL, license review status, local file checksum, split, and record count.
108
+ 3. Secret names used as placeholders, with confirmation that no secret values are printed or persisted.
109
+ 4. Adapter configuration: SDK/runtime version, model where applicable, memory write/read policy, reset policy, context limits, retry policy, and scoring code.
110
+ 5. Per-target raw scoring inputs retained privately when license permits, with public reports limited to safe aggregates.
111
+ 6. Explicit boundaries separating memory-store behavior, agent-loop behavior, model behavior, provider-hosted state, and Enigma receipt verification.
112
+
113
+ Until that evidence exists, use only the local benchmark claim: Enigma can reproduce deterministic local memory-fixture operations and emit a public-safe `enigma.memory_benchmark_suite.v1` JSON report.
@@ -7,6 +7,7 @@ Enigma Memory is a local-first SDK, CLI, MCP server, and service-contract packag
7
7
  - SDK/API guide: [`docs/sdk-api.md`](./sdk-api.md)
8
8
  - Node example app: [`examples/node-basic-memory.mjs`](../examples/node-basic-memory.mjs)
9
9
  - GitHub Actions example: [`examples/ci/github-actions.yml`](../examples/ci/github-actions.yml)
10
+ - Benchmark reproducibility guide: [`docs/benchmark-reproducibility.md`](./benchmark-reproducibility.md)
10
11
  - Generic MCP client template: [`templates/mcp-client-config.json`](../templates/mcp-client-config.json)
11
12
 
12
13
  ## Local SDK loop
@@ -24,16 +25,17 @@ The example app prints ids, counts, roots, and verification status only. It does
24
25
 
25
26
  ## CLI and CI loop
26
27
 
27
- The CI example installs Node 24, installs the published `enigma-memory` package, runs:
28
+ The CI example installs Node 24, installs the published `enigma-memory@0.1.3` package, runs:
28
29
 
29
30
  ```sh
30
31
  npx enigma quickstart --overwrite
31
32
  npx enigma doctor
33
+ npm run benchmark:memory-suite -- --out benchmark-report.json
32
34
  ```
33
35
 
34
- and then runs a small ESM import smoke. It does not require GitHub secrets, cloud provider credentials, npm tokens, private bundles, or local path assumptions.
36
+ and then runs a small ESM import smoke. It does not require GitHub secrets, cloud provider credentials, npm tokens, private bundles, or local path assumptions. The benchmark step writes a public-safe local JSON report using schema `enigma.memory_benchmark_suite.v1`; see the benchmark reproducibility guide for claim boundaries and the requirements for any future live third-party comparison.
35
37
 
36
- Use the workflow as a template in a consumer repository. It is intentionally limited to install/import/doctor smoke coverage and local proof generation; it does not publish packages, deploy infrastructure, or contact hosted Enigma cloud.
38
+ Use the workflow as a template in a consumer repository. It is intentionally limited to install/import/doctor smoke coverage, local proof generation, and deterministic local benchmark evidence; it does not publish packages, deploy infrastructure, contact hosted Enigma cloud, or call external memory providers.
37
39
 
38
40
  ## MCP client loop
39
41
 
@@ -29,15 +29,46 @@ The harness measures local Enigma operations only:
29
29
  - context-pack retrieval through the passport package;
30
30
  - optimizer plan token estimates and duplicate removal;
31
31
  - bundle and context-pack verification;
32
+ - local baseline comparisons over the same deterministic fixture questions;
32
33
  - p50/p95 latency with `performance.now`.
33
34
 
34
- Reported metrics include exact-answer recall, abstention correctness, context-token reduction versus a full-context baseline, duplicate candidates removed, operation latency summaries, verification status, and same-boundary cross-provider profile rows.
35
+ Reported metrics include exact-answer recall, abstention correctness, estimated prompt tokens, duplicate candidates removed where applicable, operation latency summaries, verification status, and same-boundary cross-provider profile rows.
36
+
37
+ ## Local baseline comparison
38
+
39
+ `metrics.local_baseline_comparisons` compares Enigma against deterministic local baselines only. Every row scores the same private fixture questions and keeps raw memory, question text, and answer text out of the report.
40
+
41
+ | Row | Boundary | Reported fields |
42
+ | --- | --- | --- |
43
+ | `full_context` | Supplies every active fixture memory without optimization or deduplication. | Recall, abstention correctness, estimated prompt tokens, selected memory count, p50/p95 local latency. |
44
+ | `recency_last_n` | Supplies the three most recently updated active fixture memories. | Same fields; duplicate removal is marked not applicable. |
45
+ | `keyword_filter` | Supplies active fixture memories whose content or tags match deterministic query terms. | Same fields; duplicate removal is marked not applicable. |
46
+ | `enigma_context_pack` | Uses the Enigma passport context-pack compiler and optimizer boundary. | Same fields plus duplicate-removal counts from the Enigma optimizer plan. |
47
+
48
+ These rows are local package evidence only. They do not compare hosted providers, do not use provider APIs, and do not support invoice savings, ROI, compliance, model-forgetting, or benchmark-leadership claims.
49
+
50
+ ## External competitor adapter requirements
51
+
52
+ `external_competitor_adapters` is a requirements matrix, not a score table. Each row has `status: "not_run_requires_credentials_or_runtime"`, `can_run_in_this_harness: false`, `required_artifacts`, `official_doc`, an exact `boundary_reason`, and `scores_included: false`.
53
+
54
+ | Adapter | Official source | Required artifacts before scoring | Boundary reason |
55
+ | --- | --- | --- | --- |
56
+ | Letta / MemGPT | https://docs.letta.com/concepts/memgpt/ | Letta API key or self-hosted runtime; pinned SDK such as `@letta-ai/letta-client` or `letta-client`; fixed agent/tools/model/memory config; operator-supplied dataset mapping. | This harness has no Letta credentials, SDK installation, runtime, fixed agent loop, or approved external dataset. |
57
+ | LangGraph memory | https://docs.langchain.com/oss/python/langgraph/memory | Pinned LangGraph runtime; short-term checkpointer config; namespaced long-term store config; fixed graph/model/tools/dataset mapping. | This Node local package harness does not execute a LangGraph runtime, checkpointer, store, graph, model, or adapter. |
58
+ | Zep | https://help.getzep.com/ | Zep credentials or endpoint; pinned client; temporal Context Graph or Context Lake config; ingestion and retrieval mapping. | This harness has no Zep credentials, client package, Context Graph/Context Lake runtime, ingestion job, or retrieval dataset. |
59
+ | Mem0 | https://docs.mem0.ai/ | Mem0 platform credentials or open-source runtime; pinned SDK/package versions; extraction/update/retrieval/model/tool config; dataset mapping. | This harness has no Mem0 credentials, runtime, configured memory loop, model/tool environment, or external dataset adapter. |
60
+ | OpenAI ChatGPT native memory | https://help.openai.com/en/articles/8590148-memory-faq | ChatGPT account/runtime with native memory enabled; account-safe evaluation protocol; dataset prompts; evidence capture that excludes personal data and credentials. | ChatGPT native memory is a consumer-app feature rather than a public API surface available to this local package harness. |
61
+ | Claude memory tool | https://support.anthropic.com/en/articles/11145838-using-claude-memory | Claude/provider runtime with the memory tool available; client-side tool configuration; fixed model/tool-use policy/prompts/dataset mapping; safe evidence capture. | The memory tool is provider/client-side and requires a Claude runtime plus tool environment that this benchmark does not control. |
62
+
63
+ No external adapter row contains recall, abstention, token, latency, or ranking scores. Third-party claims stay blocked until the required credentials, runtimes, and datasets are supplied and reviewed.
35
64
 
36
65
  ## Claim limits
37
66
 
38
67
  The benchmark report is evidence for this local deterministic fixture only. It is not provider deletion proof, model forgetting proof, compliance certification, ROI evidence, provider invoice savings evidence, benchmark leadership proof, hosted cloud readiness, or a substitute for external LoCoMo/LongMemEval evaluation.
39
68
 
40
- Cross-provider rows are profile labels using the same Enigma context-pack boundary. They do not call or rank live provider models.
69
+ Cross-provider rows are profile labels using the same Enigma context-pack boundary. External competitor rows are adapter requirements only; they do not call, score, or rank live provider models.
70
+
71
+ `public_claims_allowed` is intentionally narrow: deterministic local fixture execution, local recall/abstention metrics, local baseline comparison, local token estimates, duplicate removal where applicable, p50/p95 local latency, Enigma bundle/context-pack verification, and explicit withholding of third-party scores until the required external artifacts exist.
41
72
 
42
73
  ## Extending with external datasets later
43
74
 
package/docs/sdk-api.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SDK and API guide
2
2
 
3
- This guide covers the public package imports for `enigma-memory@0.1.2`. The SDK runs locally by default: vaults, passports, context packs, receipts, relay/gateway demo state, storage contracts, metering artifacts, and settlement artifacts are package-level developer surfaces. They are not evidence of hosted Enigma cloud, provider-side deletion, provider model forgetting, token ROI, invoice savings, compliance certification, or benchmark leadership.
3
+ This guide covers the public package imports for `enigma-memory@0.1.3`. The SDK runs locally by default: vaults, passports, context packs, receipts, relay/gateway demo state, storage contracts, metering artifacts, and settlement artifacts are package-level developer surfaces. They are not evidence of hosted Enigma cloud, provider-side deletion, provider model forgetting, token ROI, invoice savings, compliance certification, or benchmark leadership.
4
4
 
5
5
  ## Install and import style
6
6
 
@@ -22,7 +22,18 @@ jobs:
22
22
  run: npm init -y
23
23
 
24
24
  - name: Install Enigma Memory
25
- run: npm install enigma-memory@0.1.1
25
+ run: npm install enigma-memory@0.1.3
26
+
27
+ - name: Expose local benchmark script
28
+ run: |
29
+ node --input-type=module <<'JS'
30
+ import { readFile, writeFile } from 'node:fs/promises';
31
+
32
+ const pkg = JSON.parse(await readFile('package.json', 'utf8'));
33
+ pkg.scripts ??= {};
34
+ pkg.scripts['benchmark:memory-suite'] = 'node ./node_modules/enigma-memory/scripts/run-memory-benchmarks.mjs';
35
+ await writeFile('package.json', `${JSON.stringify(pkg, null, 2)}\n`, 'utf8');
36
+ JS
26
37
 
27
38
  - name: Run Enigma quickstart
28
39
  run: npx enigma quickstart --overwrite
@@ -30,6 +41,23 @@ jobs:
30
41
  - name: Run Enigma doctor
31
42
  run: npx enigma doctor
32
43
 
44
+ - name: Run local memory benchmark
45
+ run: |
46
+ npm run benchmark:memory-suite -- --out benchmark-report.json
47
+ mkdir -p artifacts
48
+ cp benchmark-report.json artifacts/benchmark-report.json
49
+ echo "Saved public-safe benchmark report placeholder at artifacts/benchmark-report.json"
50
+
51
+ # Optional artifact upload placeholder:
52
+ # If your repository already permits actions/upload-artifact, uncomment a
53
+ # reviewed upload step like this. The example keeps the report saved in the
54
+ # workspace without requiring that action.
55
+ # - name: Upload benchmark report
56
+ # uses: actions/upload-artifact@v4
57
+ # with:
58
+ # name: enigma-memory-benchmark-report
59
+ # path: artifacts/benchmark-report.json
60
+
33
61
  - name: Smoke test package imports
34
62
  run: |
35
63
  node --input-type=module <<'JS'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigma-memory",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Provider-agnostic AI memory passport and offline-verifiable proof layer.",
6
6
  "license": "Apache-2.0",
@@ -112,6 +112,7 @@
112
112
  "docs/sdk-api.md",
113
113
  "docs/developer-ecosystem.md",
114
114
  "docs/memory-benchmarks.md",
115
+ "docs/benchmark-reproducibility.md",
115
116
  "docs/installers-and-desktop.md",
116
117
  "docs/browser-extension-install.md",
117
118
  "docs/hosted-cloud-product.md",
@@ -17,7 +17,7 @@ import {
17
17
  const DEFAULT_BUNDLE = '.enigma/bundle.json';
18
18
  const JSONRPC_VERSION = '2.0';
19
19
  const MCP_PROTOCOL_VERSION = '2024-11-05';
20
- const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.2' });
20
+ const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.3' });
21
21
  const JSON_RPC_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
22
22
  const JSON_RPC_ERROR = Object.freeze({
23
23
  INVALID_REQUEST: -32600,
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
6
6
 
7
7
  export const INSTALLER_ASSET_SCHEMA = 'enigma.installer_assets.v1';
8
8
  export const INSTALLER_ASSET_PACKAGE = 'enigma-memory';
9
- export const INSTALLER_ASSET_VERSION = '0.1.2';
9
+ export const INSTALLER_ASSET_VERSION = '0.1.3';
10
10
  export const INSTALLER_ASSET_GENERATED_AT = '1970-01-01T00:00:00.000Z';
11
11
 
12
12
  const SCRIPT_PATH = fileURLToPath(import.meta.url);
@@ -16,7 +16,7 @@ import {
16
16
  compileContextPack,
17
17
  verifyContextPack,
18
18
  } from '../packages/passport/src/index.js';
19
- import { createMemoryOptimizationPlan } from '../packages/optimizer/src/index.js';
19
+ import { createMemoryOptimizationPlan, estimateTextTokens } from '../packages/optimizer/src/index.js';
20
20
  import { verifyBundle } from '../apps/verifier/bin/enigma-verify.mjs';
21
21
 
22
22
  export const MEMORY_BENCHMARK_SUITE_SCHEMA = 'enigma.memory_benchmark_suite.v1';
@@ -34,6 +34,131 @@ const CONTEXT_BOUNDARY = Object.freeze({
34
34
 
35
35
  const PROVIDER_PROFILES = Object.freeze(['chatgpt', 'claude', 'kimi', 'cursor', 'local-llm']);
36
36
 
37
+ const LOCAL_BASELINES = Object.freeze([
38
+ {
39
+ id: 'full_context',
40
+ label: 'Full active context',
41
+ boundary: 'All active fixture memories are supplied without optimization or deduplication.',
42
+ },
43
+ {
44
+ id: 'recency_last_n',
45
+ label: 'Recency last N',
46
+ boundary: 'The three most recently updated active fixture memories are supplied.',
47
+ },
48
+ {
49
+ id: 'keyword_filter',
50
+ label: 'Keyword filter',
51
+ boundary: 'Active fixture memories are supplied when deterministic query terms match content or tags.',
52
+ },
53
+ {
54
+ id: 'enigma_context_pack',
55
+ label: 'Enigma context pack',
56
+ boundary: 'The Enigma passport context-pack compiler and optimizer boundary are used locally.',
57
+ },
58
+ ]);
59
+
60
+ const EXTERNAL_COMPETITOR_ADAPTERS = Object.freeze([
61
+ {
62
+ id: 'letta_memgpt',
63
+ name: 'Letta / MemGPT',
64
+ status: 'not_run_requires_credentials_or_runtime',
65
+ required_artifacts: [
66
+ 'Letta API key or self-hosted Letta runtime',
67
+ 'Pinned Letta SDK package and version such as @letta-ai/letta-client or letta-client',
68
+ 'Agent, tools, model, and memory configuration',
69
+ 'Operator-supplied benchmark dataset or fixture mapping',
70
+ ],
71
+ official_doc: 'https://docs.letta.com/concepts/memgpt/',
72
+ can_run_in_this_harness: false,
73
+ boundary_reason: 'This local harness has no Letta credentials, SDK installation, hosted/self-hosted Letta runtime, fixed agent loop, or approved external dataset, so no Letta score is produced.',
74
+ scores_included: false,
75
+ },
76
+ {
77
+ id: 'langgraph_memory',
78
+ name: 'LangGraph memory',
79
+ status: 'not_run_requires_credentials_or_runtime',
80
+ required_artifacts: [
81
+ 'Pinned LangGraph runtime and package versions',
82
+ 'Checkpointer configuration for short-term memory',
83
+ 'Namespaced long-term store configuration',
84
+ 'Fixed graph, model, tools, and dataset mapping',
85
+ ],
86
+ official_doc: 'https://docs.langchain.com/oss/python/langgraph/memory',
87
+ can_run_in_this_harness: false,
88
+ boundary_reason: 'This Node local package harness does not install or execute a LangGraph runtime, checkpointer, namespaced store, graph, model, or dataset adapter, so no LangGraph score is produced.',
89
+ scores_included: false,
90
+ },
91
+ {
92
+ id: 'zep',
93
+ name: 'Zep',
94
+ status: 'not_run_requires_credentials_or_runtime',
95
+ required_artifacts: [
96
+ 'Zep credentials or local/runtime endpoint',
97
+ 'Pinned Zep client and version',
98
+ 'Temporal Context Graph or Context Lake configuration',
99
+ 'Dataset ingestion and retrieval mapping',
100
+ ],
101
+ official_doc: 'https://help.getzep.com/',
102
+ can_run_in_this_harness: false,
103
+ boundary_reason: 'This local harness has no Zep credentials, client package, Context Graph or Context Lake runtime, ingestion job, or provider-approved retrieval dataset, so no Zep score or latency claim is produced.',
104
+ scores_included: false,
105
+ },
106
+ {
107
+ id: 'mem0',
108
+ name: 'Mem0',
109
+ status: 'not_run_requires_credentials_or_runtime',
110
+ required_artifacts: [
111
+ 'Mem0 platform credentials or open-source stack runtime',
112
+ 'Pinned Mem0 SDK/package versions',
113
+ 'Memory extraction, update, retrieval, model, and tool configuration',
114
+ 'Dataset ingestion and scoring mapping',
115
+ ],
116
+ official_doc: 'https://docs.mem0.ai/',
117
+ can_run_in_this_harness: false,
118
+ boundary_reason: 'This local harness has no Mem0 credentials, SDK/runtime, configured extraction/retrieval loop, model/tool environment, or external dataset adapter, so no Mem0 score is produced.',
119
+ scores_included: false,
120
+ },
121
+ {
122
+ id: 'openai_native_memory',
123
+ name: 'OpenAI ChatGPT native memory',
124
+ status: 'not_run_requires_credentials_or_runtime',
125
+ required_artifacts: [
126
+ 'Consumer ChatGPT account/runtime with native memory enabled',
127
+ 'Account-safe evaluation protocol and export/review process',
128
+ 'Dataset prompts and operator approval for non-public app interaction',
129
+ 'Evidence capture that excludes personal data and credentials',
130
+ ],
131
+ official_doc: 'https://help.openai.com/en/articles/8590148-memory-faq',
132
+ can_run_in_this_harness: false,
133
+ boundary_reason: 'ChatGPT native memory is a consumer-app feature rather than a public API surface available to this local package harness, so no OpenAI native-memory score is produced.',
134
+ scores_included: false,
135
+ },
136
+ {
137
+ id: 'claude_memory_tool',
138
+ name: 'Claude memory tool',
139
+ status: 'not_run_requires_credentials_or_runtime',
140
+ required_artifacts: [
141
+ 'Claude/provider runtime with the memory tool available',
142
+ 'Client-side tool configuration and storage boundary',
143
+ 'Fixed model, tool-use policy, prompts, and dataset mapping',
144
+ 'Evidence capture that excludes personal data and credentials',
145
+ ],
146
+ official_doc: 'https://support.anthropic.com/en/articles/11145838-using-claude-memory',
147
+ can_run_in_this_harness: false,
148
+ boundary_reason: 'The Claude memory tool is provider/client-side and requires a Claude runtime plus tool environment that this local package benchmark does not control, so no Claude memory-tool score is produced.',
149
+ scores_included: false,
150
+ },
151
+ ]);
152
+
153
+ const PUBLIC_CLAIMS_ALLOWED = Object.freeze([
154
+ 'Runs a deterministic local Enigma memory fixture without external provider calls.',
155
+ 'Reports local exact-answer recall and abstention correctness for the fixture questions.',
156
+ 'Compares Enigma context packs with full-context, recency, and keyword local baselines on the same fixture.',
157
+ 'Reports local estimated prompt tokens, duplicate-removal counts where applicable, and p50/p95 local latency.',
158
+ 'Verifies Enigma-controlled bundles and context packs without exposing raw fixture memory, questions, or answers.',
159
+ 'Lists external competitor adapter requirements and withholds third-party scores until credentials, runtimes, and datasets are supplied.',
160
+ ]);
161
+
37
162
  const BENCHMARK_CITATIONS = Object.freeze([
38
163
  {
39
164
  id: 'locomo',
@@ -402,6 +527,188 @@ function activeOptimizationPlan(vault, query) {
402
527
  });
403
528
  }
404
529
 
530
+ function activeBenchmarkMemories(vault) {
531
+ const memories = [];
532
+ for (const memoryAddr of vault.activeAddresses ?? []) {
533
+ const record = vault.__getRecord(memoryAddr);
534
+ if (!record || record.state !== 'active') continue;
535
+ memories.push({
536
+ memory_addr: memoryAddr,
537
+ content: vault.__getPlaintext(memoryAddr),
538
+ updated_at: record.updated_at ?? record.created_at,
539
+ created_at: record.created_at,
540
+ purpose_tags: Array.isArray(record.purpose_tags) ? [...record.purpose_tags] : [],
541
+ });
542
+ }
543
+ return memories;
544
+ }
545
+
546
+ function estimatePromptTokens(query, memories) {
547
+ let tokens = estimateTextTokens(query);
548
+ for (const memory of memories) tokens += estimateTextTokens(memory.content);
549
+ return tokens;
550
+ }
551
+
552
+ function localLatencySummary(values) {
553
+ return {
554
+ samples: values.length,
555
+ p50_ms: Number(percentile(values, 0.5).toFixed(6)),
556
+ p95_ms: Number(percentile(values, 0.95).toFixed(6)),
557
+ };
558
+ }
559
+
560
+ function compareUpdatedDesc(left, right) {
561
+ const leftTime = Date.parse(left.updated_at ?? left.created_at ?? '');
562
+ const rightTime = Date.parse(right.updated_at ?? right.created_at ?? '');
563
+ if (leftTime !== rightTime) return rightTime - leftTime;
564
+ return String(left.memory_addr).localeCompare(String(right.memory_addr));
565
+ }
566
+
567
+ function queryTerms(query) {
568
+ const stopwords = new Set([
569
+ 'after',
570
+ 'should',
571
+ 'the',
572
+ 'use',
573
+ 'what',
574
+ 'which',
575
+ 'who',
576
+ ]);
577
+ const terms = [];
578
+ for (const match of String(query).toLowerCase().matchAll(/[a-z0-9_-]{3,}/gu)) {
579
+ const term = match[0];
580
+ if (!stopwords.has(term)) terms.push(term);
581
+ }
582
+ return terms;
583
+ }
584
+
585
+ function keywordFilteredMemories(memories, query) {
586
+ const terms = queryTerms(query);
587
+ if (terms.length === 0) return [];
588
+ return memories.filter((memory) => {
589
+ const haystack = `${memory.content} ${(memory.purpose_tags ?? []).join(' ')}`.toLowerCase();
590
+ return terms.some((term) => haystack.includes(term));
591
+ });
592
+ }
593
+
594
+ function selectLocalBaselineMemories(baselineId, vault, passport, question) {
595
+ const memories = activeBenchmarkMemories(vault);
596
+ if (baselineId === 'full_context') {
597
+ return {
598
+ memories,
599
+ estimatedPromptTokens: estimatePromptTokens(question.query, memories),
600
+ duplicateCandidatesRemoved: 0,
601
+ duplicateRemovalApplicable: false,
602
+ };
603
+ }
604
+ if (baselineId === 'recency_last_n') {
605
+ const selected = [...memories].sort(compareUpdatedDesc).slice(0, 3);
606
+ return {
607
+ memories: selected,
608
+ estimatedPromptTokens: estimatePromptTokens(question.query, selected),
609
+ duplicateCandidatesRemoved: 0,
610
+ duplicateRemovalApplicable: false,
611
+ };
612
+ }
613
+ if (baselineId === 'keyword_filter') {
614
+ const selected = keywordFilteredMemories(memories, question.query);
615
+ return {
616
+ memories: selected,
617
+ estimatedPromptTokens: estimatePromptTokens(question.query, selected),
618
+ duplicateCandidatesRemoved: 0,
619
+ duplicateRemovalApplicable: false,
620
+ };
621
+ }
622
+ if (baselineId === 'enigma_context_pack') {
623
+ const fullPlan = activeOptimizationPlan(vault, question.query);
624
+ const pack = compileContextPack({
625
+ vault,
626
+ passport,
627
+ query: question.query,
628
+ context_pack_id: `ctx_benchmark_local_baseline_${question.id}`,
629
+ ...packOptions('local-llm'),
630
+ });
631
+ return {
632
+ memories: pack.memories,
633
+ estimatedPromptTokens: pack.optimization_plan?.optimized_prompt_tokens ?? estimatePromptTokens(question.query, pack.memories),
634
+ duplicateCandidatesRemoved: fullPlan.totals.duplicates_removed,
635
+ duplicateRemovalApplicable: true,
636
+ };
637
+ }
638
+ throw new Error(`unknown local baseline ${baselineId}`);
639
+ }
640
+
641
+ function compareLocalBaselines(vault, passport) {
642
+ const rows = [];
643
+ for (const baseline of LOCAL_BASELINES) {
644
+ let exactTotal = 0;
645
+ let exactCorrect = 0;
646
+ let abstainTotal = 0;
647
+ let abstainCorrect = 0;
648
+ let totalEstimatedPromptTokens = 0;
649
+ let selectedMemoryTotal = 0;
650
+ let maxDuplicateCandidatesRemoved = 0;
651
+ let totalDuplicateCandidatesRemoved = 0;
652
+ let duplicateRemovalApplicable = false;
653
+ const latencies = [];
654
+
655
+ for (const question of PRIVATE_FIXTURE.questions) {
656
+ const start = performance.now();
657
+ const selected = selectLocalBaselineMemories(baseline.id, vault, passport, question);
658
+ const result = chooseAnswer(question, { memories: selected.memories });
659
+ latencies.push(Math.max(0, performance.now() - start));
660
+
661
+ totalEstimatedPromptTokens += selected.estimatedPromptTokens;
662
+ selectedMemoryTotal += selected.memories.length;
663
+ maxDuplicateCandidatesRemoved = Math.max(maxDuplicateCandidatesRemoved, selected.duplicateCandidatesRemoved);
664
+ totalDuplicateCandidatesRemoved += selected.duplicateCandidatesRemoved;
665
+ duplicateRemovalApplicable = duplicateRemovalApplicable || selected.duplicateRemovalApplicable;
666
+
667
+ if (question.category === 'abstention') {
668
+ abstainTotal += 1;
669
+ if (result.abstained && result.correct) abstainCorrect += 1;
670
+ } else {
671
+ exactTotal += 1;
672
+ if (!result.abstained && result.correct) exactCorrect += 1;
673
+ }
674
+ }
675
+
676
+ rows.push({
677
+ id: baseline.id,
678
+ label: baseline.label,
679
+ boundary: baseline.boundary,
680
+ local_fixture_only: true,
681
+ external_provider_called: false,
682
+ deterministic_fixture: true,
683
+ question_count: PRIVATE_FIXTURE.questions.length,
684
+ exact_answer_questions: exactTotal,
685
+ exact_answer_correct: exactCorrect,
686
+ exact_answer_recall: exactTotal === 0 ? 0 : Number((exactCorrect / exactTotal).toFixed(6)),
687
+ abstention_questions: abstainTotal,
688
+ abstention_correct: abstainCorrect,
689
+ abstention_correctness: abstainTotal === 0 ? 0 : Number((abstainCorrect / abstainTotal).toFixed(6)),
690
+ estimated_prompt_tokens: {
691
+ total: totalEstimatedPromptTokens,
692
+ mean_per_question: Number((totalEstimatedPromptTokens / PRIVATE_FIXTURE.questions.length).toFixed(6)),
693
+ estimator: 'estimateTextTokens deterministic local estimator',
694
+ },
695
+ selected_memory_count: {
696
+ total: selectedMemoryTotal,
697
+ mean_per_question: Number((selectedMemoryTotal / PRIVATE_FIXTURE.questions.length).toFixed(6)),
698
+ },
699
+ duplicate_removal: {
700
+ applicable: duplicateRemovalApplicable,
701
+ max_duplicate_candidates_removed: maxDuplicateCandidatesRemoved,
702
+ total_duplicate_candidates_removed: totalDuplicateCandidatesRemoved,
703
+ },
704
+ latency: localLatencySummary(latencies),
705
+ public_question_text_included: false,
706
+ public_answer_text_included: false,
707
+ });
708
+ }
709
+ return rows;
710
+ }
711
+
405
712
  function summarizeContextReduction(plan) {
406
713
  const baseline = plan?.baseline_prompt_tokens ?? 0;
407
714
  const optimized = plan?.optimized_prompt_tokens ?? 0;
@@ -489,6 +796,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
489
796
  const passport = createPassport({ vault: importedVault, now: generatedAt });
490
797
 
491
798
  const scored = scoreQuestions(importedVault, passport, samples);
799
+ const localBaselineRows = compareLocalBaselines(importedVault, passport);
492
800
  const fullOptimizationPlan = activeOptimizationPlan(importedVault, 'Use the benchmark memory boundary for recall and abstention evaluation.');
493
801
  const providerRows = compareProviders(importedVault, passport, samples);
494
802
  const verificationBundleResults = [];
@@ -522,7 +830,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
522
830
  benchmark_leadership_claim: false,
523
831
  claim_boundary: [
524
832
  'This suite measures deterministic local Enigma fixture operations only.',
525
- 'Cross-provider rows use profile labels and the same Enigma context-pack boundary; they do not call or compare live provider models.',
833
+ 'Cross-provider profile rows remain same-boundary Enigma labels; external competitor adapter rows are requirements only and contain no third-party scores.',
526
834
  'Token reduction is a local estimator result against this fixture, not a provider invoice, ROI, guaranteed savings, or benchmark-leadership claim.',
527
835
  'Verification proves Enigma-controlled receipts/bundles/context packs only; it is not provider deletion, provider forgetting, model forgetting, or compliance certification evidence.',
528
836
  ],
@@ -536,6 +844,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
536
844
  optimizer_plan_token_estimates: true,
537
845
  bundle_verification: true,
538
846
  context_pack_verification: true,
847
+ local_baseline_comparison: true,
539
848
  latency_clock: 'performance.now',
540
849
  },
541
850
  metrics: {
@@ -546,6 +855,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
546
855
  deduped_candidates: fullOptimizationPlan.totals.deduped_candidates,
547
856
  duplicate_candidates_removed: fullOptimizationPlan.totals.duplicates_removed,
548
857
  },
858
+ local_baseline_comparisons: localBaselineRows,
549
859
  latency: latencySummary(samples),
550
860
  verification: {
551
861
  bundle_verify_runs: verificationBundleResults.length,
@@ -554,6 +864,8 @@ export function runMemoryBenchmarkSuite(options = {}) {
554
864
  },
555
865
  },
556
866
  cross_provider_profiles: providerRows,
867
+ external_competitor_adapters: EXTERNAL_COMPETITOR_ADAPTERS,
868
+ public_claims_allowed: PUBLIC_CLAIMS_ALLOWED,
557
869
  };
558
870
 
559
871
  return assertNoRawFixtureLeak(report);