enigma-memory 0.1.18 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -24
- package/apps/cli/bin/enigma-desktop.mjs +140 -0
- package/apps/cli/bin/enigma-terminal.mjs +78 -0
- package/apps/cli/bin/enigma.mjs +1923 -285
- package/apps/desktop/electron-main.cjs +217 -0
- package/apps/desktop/package.json +12 -0
- package/apps/desktop/src/app.js +264 -7
- package/apps/desktop/src/index.html +3514 -1373
- package/apps/desktop/src/launch-electron.mjs +51 -0
- package/apps/desktop/src/server.mjs +2914 -0
- package/apps/desktop/src/styles.css +2972 -260
- package/apps/desktop/src/zk-browser-prove.mjs +53 -0
- package/apps/desktop/src/zk-state.mjs +1789 -0
- package/apps/gateway/bin/enigma-gateway.mjs +102 -5
- package/apps/gateway/src/server.mjs +271 -8
- package/apps/ios/EnigmaCore/Package.swift +12 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
- package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
- package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
- package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
- package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
- package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
- package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
- package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
- package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
- package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
- package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
- package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
- package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
- package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
- package/apps/native-host/README.md +19 -8
- package/apps/native-host/bin/enigma-native-host.mjs +229 -13
- package/apps/relay/bin/enigma-relay.mjs +103 -5
- package/apps/relay/src/federation-runtime.mjs +618 -0
- package/apps/relay/src/server.mjs +310 -9
- package/apps/verifier/bin/enigma-verify.mjs +327 -11
- package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/vk_bytes.json +32 -0
- package/cortex-v3/proving-assets.json +64 -0
- package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
- package/cortex-v3/zk/action-transition-vk.json +119 -0
- package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
- package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
- package/cortex-v3/zk/intent-witness.mjs +365 -0
- package/cortex-v3/zk/intent-witness.test.mjs +485 -0
- package/cortex-v3/zk/proving-assets.mjs +203 -0
- package/cortex-v3/zk/sale-witness.mjs +783 -0
- package/cortex-v3/zk/sale-witness.test.mjs +784 -0
- package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
- package/cortex-v3/zk/settlement-evidence.mjs +722 -0
- package/cortex-v3/zk/setup-intent.mjs +688 -0
- package/cortex-v3/zk/setup-sale.mjs +666 -0
- package/cortex-v3/zk/setup.mjs +594 -0
- package/cortex-v3/zk/witness.mjs +184 -0
- package/cortex-v3/zk/zk-codec.mjs +232 -0
- package/cortex-v3/zk/zk-codec.test.mjs +293 -0
- package/cortex-v3/zk/zk-settle.mjs +370 -0
- package/cortex-v3/zk/zk-tree.mjs +256 -0
- package/cortex-v3/zk/zk-tree.test.mjs +419 -0
- package/deploy/docker-compose.local-production-simulation.yml +36 -0
- package/docs/browser-extension-install.md +8 -6
- package/docs/client-connectors.md +15 -11
- package/docs/developer-ecosystem.md +15 -13
- package/docs/enigma-memory-ready-conformance.md +11 -9
- package/docs/install-anywhere.md +61 -28
- package/docs/installers-and-desktop.md +8 -7
- package/docs/novelty-invention-candidates.md +161 -161
- package/docs/proof-network-claim-boundaries.md +320 -318
- package/examples/01-quickstart-agent/index.mjs +49 -0
- package/examples/01_agent_memory_quickstart.mjs +57 -0
- package/examples/02-multi-agent-swarm/index.mjs +57 -0
- package/examples/02_cross_model_passport.mjs +64 -0
- package/examples/03-langchain-memory/index.mjs +41 -0
- package/examples/03_poseidon_commitment_verification.mjs +71 -0
- package/examples/04-python-trading-agent/trader.py +49 -0
- package/examples/README.md +27 -0
- package/examples/ci/github-actions.yml +7 -2
- package/package.json +142 -11
- package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
- package/packages/connectors/src/index.js +196 -4
- package/packages/connectors/swarm-router.mjs +168 -0
- package/packages/core/src/index.js +248 -1
- package/packages/core/src/version.mjs +7 -0
- package/packages/dev-tools/package.json +19 -0
- package/packages/dev-tools/src/index.js +4 -0
- package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
- package/packages/dev-tools/src/swarm-simulator.js +101 -0
- package/packages/dev-tools/src/vault-inspector.js +114 -0
- package/packages/dev-tools/src/vector-benchmark.js +100 -0
- package/packages/developer-platform/src/access-credentials.js +341 -0
- package/packages/developer-platform/src/http.js +132 -0
- package/packages/developer-platform/src/index.js +4 -0
- package/packages/developer-platform/src/usage-http.js +60 -0
- package/packages/developer-platform/src/usage.js +295 -0
- package/packages/enclave-runtime/attestation.mjs +159 -0
- package/packages/enclave-runtime/index.mjs +47 -0
- package/packages/enclave-runtime/session-manager.mjs +253 -0
- package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
- package/packages/enigma-reflex/package.json +14 -0
- package/packages/enigma-reflex/src/index.js +204 -0
- package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
- package/packages/enigma-reflex/training/requirements.txt +8 -0
- package/packages/enigma-reflex/training/train.py +314 -0
- package/packages/enigma-weave/LICENSE +22 -0
- package/packages/enigma-weave/UPSTREAM.json +21 -0
- package/packages/enigma-weave/package.json +14 -0
- package/packages/enigma-weave/src/index.js +286 -0
- package/packages/hosted-cloud/src/index.js +80 -5
- package/packages/importers/src/index.js +432 -0
- package/packages/inference-runtime/src/browser.js +401 -0
- package/packages/inference-runtime/src/chat.js +265 -0
- package/packages/inference-runtime/src/code.js +407 -0
- package/packages/inference-runtime/src/contracts.js +162 -0
- package/packages/inference-runtime/src/http.js +232 -0
- package/packages/inference-runtime/src/image.js +186 -0
- package/packages/inference-runtime/src/index.js +10 -0
- package/packages/inference-runtime/src/model-router.js +320 -0
- package/packages/inference-runtime/src/platform.js +125 -0
- package/packages/inference-runtime/src/privacy.js +400 -0
- package/packages/inference-runtime/src/video.js +253 -0
- package/packages/mcp-server/README.md +22 -6
- package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
- package/packages/mcp-server/src/index.js +1418 -105
- package/packages/mcp-server/src/oauth.js +561 -0
- package/packages/mcp-server/src/private-handoff.js +84 -0
- package/packages/mcp-server/src/remote-http.js +273 -0
- package/packages/mcp-server/src/remote-policy.js +72 -0
- package/packages/mcp-server/swarm-bridge.mjs +361 -0
- package/packages/mesh/index.d.ts +283 -0
- package/packages/mesh/package.json +23 -0
- package/packages/mesh/src/crypto.js +189 -0
- package/packages/mesh/src/federation-packets.js +353 -0
- package/packages/mesh/src/gossip.js +311 -0
- package/packages/mesh/src/index.js +6 -0
- package/packages/mesh/src/protocol.js +255 -0
- package/packages/mesh/src/router.js +279 -0
- package/packages/mesh/src/transport.js +306 -0
- package/packages/passport/src/index.js +426 -1
- package/packages/private-economy/src/credits-http.js +100 -0
- package/packages/private-economy/src/credits.js +447 -0
- package/packages/private-economy/src/index.js +5 -0
- package/packages/private-economy/src/payments-http.js +120 -0
- package/packages/private-economy/src/payments.js +509 -0
- package/packages/private-economy/src/x402.js +346 -0
- package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
- package/packages/rag/index.d.ts +182 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
- package/packages/rag/package.json +27 -0
- package/packages/rag/src/blinded-search.js +109 -0
- package/packages/rag/src/bm25.js +169 -0
- package/packages/rag/src/embeddings.js +459 -0
- package/packages/rag/src/hybrid.js +76 -0
- package/packages/rag/src/index.js +38 -0
- package/packages/rag/src/reranker.js +61 -0
- package/packages/rag/src/research.js +107 -0
- package/packages/rag/src/vector-store.js +430 -0
- package/packages/rag/src/verify-model-artifacts.mjs +4 -0
- package/packages/sdk/index.d.ts +760 -0
- package/packages/sdk/package.json +33 -0
- package/packages/sdk/python/README.md +24 -0
- package/packages/sdk/python/enigma_sdk.py +250 -0
- package/packages/sdk/python/pyproject.toml +34 -0
- package/packages/sdk/python/requirements.txt +1 -0
- package/packages/sdk/python/setup.py +20 -0
- package/packages/sdk/src/federation/capability-grant.js +389 -0
- package/packages/sdk/src/federation/federation-router.js +360 -0
- package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
- package/packages/sdk/src/federation/index.js +3 -0
- package/packages/sdk/src/index.js +1796 -0
- package/packages/sdk/src/intelligence/contradiction.js +337 -0
- package/packages/sdk/src/intelligence/decision-engine.js +155 -0
- package/packages/sdk/src/intelligence/index.js +4 -0
- package/packages/sdk/src/intelligence/ontology.js +122 -0
- package/packages/sdk/src/intelligence/temporal.js +123 -0
- package/packages/sdk/src/market-client.js +142 -0
- package/packages/sdk/src/mesh-client.js +110 -0
- package/packages/sdk/src/middleware/index.js +3 -0
- package/packages/sdk/src/middleware/langchain.js +159 -0
- package/packages/sdk/src/middleware/llamaindex.js +101 -0
- package/packages/sdk/src/middleware/vercel-ai.js +112 -0
- package/packages/sdk/src/rag-client.js +85 -0
- package/packages/sdk/src/swarm-orchestrator.js +260 -0
- package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
- package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
- package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
- package/packages/snapcompact/index.d.ts +284 -0
- package/packages/snapcompact/package.json +25 -0
- package/packages/snapcompact/src/index.js +716 -0
- package/packages/storage/PACKAGE_CONTRACT.md +1 -1
- package/packages/terminal-console/animations.mjs +240 -0
- package/packages/terminal-console/auto-anchor.mjs +220 -0
- package/packages/terminal-console/banner.mjs +91 -0
- package/packages/terminal-console/commands.mjs +459 -0
- package/packages/terminal-console/delegation.mjs +152 -0
- package/packages/terminal-console/index.mjs +5 -0
- package/packages/terminal-console/outbox.mjs +143 -0
- package/packages/terminal-console/phantom-bridge.mjs +637 -0
- package/packages/terminal-console/repl.mjs +136 -0
- package/packages/terminal-console/signer-store.mjs +130 -0
- package/packages/terminal-console/solana-rpc.mjs +214 -0
- package/packages/terminal-console/solana-transport.mjs +189 -0
- package/packages/terminal-tui/dashboard.mjs +214 -0
- package/packages/terminal-tui/index.mjs +28 -0
- package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
- package/packages/terminal-tui/telemetry-hud.mjs +137 -0
- package/packages/vault/index.d.ts +449 -0
- package/packages/vault/package.json +27 -0
- package/packages/vault/src/e2ee.mjs +393 -0
- package/packages/vault/src/enclave.js +481 -0
- package/packages/vault/src/erasure.js +207 -0
- package/packages/vault/src/index.js +1018 -155
- package/packages/vault/src/persistence.js +307 -0
- package/packages/vault/src/poseidon.js +354 -0
- package/packages/vault/src/receipt.js +459 -0
- package/scripts/benchmark-optical-context.mjs +166 -0
- package/scripts/bootstrap-enigma.mjs +502 -0
- package/scripts/build-edge-backend-workers.mjs +20 -5
- package/scripts/build-goal-completion-audit.mjs +72 -25
- package/scripts/build-hosted-api-key-lifecycle.mjs +26 -8
- package/scripts/build-hosted-customer-lifecycle.mjs +20 -3
- package/scripts/build-hosted-probe-worker.mjs +19 -4
- package/scripts/build-installer-assets.mjs +41 -21
- package/scripts/build-operator-evidence-starter.mjs +59 -1
- package/scripts/build-production-backend-env-kit.mjs +2 -0
- package/scripts/build-production-unblocker.mjs +3 -0
- package/scripts/check.mjs +17 -3
- package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
- package/scripts/install-enigma-local.mjs +18 -5
- package/scripts/release-audit.mjs +65 -109
- package/scripts/release-provenance.mjs +6 -0
- package/scripts/run-backend-readiness-smoke.mjs +112 -10
- package/scripts/scan-secrets.mjs +1 -0
- package/scripts/simulate-production-env.mjs +7 -2
- package/scripts/validate-hosted-backend-live.mjs +112 -1
- package/specs/antibody-pack-v1.schema.json +95 -0
- package/specs/antigen-envelope-v1.schema.json +81 -0
- package/specs/boundary-manifest-v1.schema.json +35 -35
- package/specs/capsule-v1.schema.json +55 -55
- package/specs/claim-boundary-manifest-v1.schema.json +22 -22
- package/specs/claim-ledger-v1.schema.json +291 -0
- package/specs/context-passport-v1.schema.json +59 -0
- package/specs/deletion-tombstone-v1.schema.json +26 -26
- package/specs/evidence-packet-v1.schema.json +177 -0
- package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
- package/specs/immune-scan-report-v1.schema.json +112 -0
- package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
- package/specs/memory-atom-v1.schema.json +59 -0
- package/specs/memory-event-v1.schema.json +42 -42
- package/specs/passport-v1.schema.json +50 -50
- package/specs/proof-of-non-use-v1.schema.json +65 -0
- package/specs/quarantine-record-v1.schema.json +126 -0
- package/specs/receipt-v1.schema.json +61 -61
- package/specs/state-checkpoint-v1.schema.json +37 -37
- package/specs/trust-bundle-v1.schema.json +56 -56
- package/specs/trust-card-v1.schema.json +119 -0
- package/docs/proof-network-launch-plan.md +0 -421
- package/packages/metering/PACKAGE_CONTRACT.md +0 -20
- package/scripts/build-ai-orchestration-plan.mjs +0 -248
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { access, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import {
|
|
4
|
+
createSwarmBridge,
|
|
5
|
+
projectSwarmCommitmentAtom,
|
|
6
|
+
SWARM_PERMISSIONS,
|
|
7
|
+
validateSwarmCommitmentAtom,
|
|
8
|
+
} from '../mcp-server/swarm-bridge.mjs';
|
|
9
|
+
|
|
10
|
+
const pathQueues = new Map();
|
|
11
|
+
|
|
12
|
+
async function exists(path) {
|
|
13
|
+
try { await access(path); return true; } catch { return false; }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function statePathFor(bundlePath) {
|
|
17
|
+
return `${resolve(bundlePath)}.swarm.json`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function readJson(path) {
|
|
21
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function writeJsonAtomic(path, value) {
|
|
25
|
+
await mkdir(dirname(path), { recursive: true });
|
|
26
|
+
const temporary = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
27
|
+
await writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
28
|
+
await rename(temporary, path);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function persistenceSafeState(bridge) {
|
|
32
|
+
const state = bridge.exportState();
|
|
33
|
+
for (const atoms of Object.values(state.namespaces)) {
|
|
34
|
+
for (let index = 0; index < atoms.length; index += 1) {
|
|
35
|
+
atoms[index] = projectSwarmCommitmentAtom(atoms[index]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return state;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function enqueue(path, operation) {
|
|
42
|
+
const prior = pathQueues.get(path) ?? Promise.resolve();
|
|
43
|
+
const current = prior.catch(() => {}).then(operation);
|
|
44
|
+
pathQueues.set(path, current);
|
|
45
|
+
return current.finally(() => { if (pathQueues.get(path) === current) pathQueues.delete(path); });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function loadBridge(bundlePath, requestedSwarmId) {
|
|
49
|
+
const statePath = statePathFor(bundlePath);
|
|
50
|
+
if (await exists(statePath)) {
|
|
51
|
+
const state = await readJson(statePath);
|
|
52
|
+
if (state.schema !== 'enigma.swarm_bridge_state.v1') throw new Error(`unsupported swarm state schema: ${state.schema ?? '<missing>'}`);
|
|
53
|
+
for (const atoms of Object.values(state.namespaces ?? {})) {
|
|
54
|
+
if (!Array.isArray(atoms)) throw new Error('persisted swarm namespace must contain an atom array');
|
|
55
|
+
atoms.forEach(validateSwarmCommitmentAtom);
|
|
56
|
+
}
|
|
57
|
+
if (requestedSwarmId && requestedSwarmId !== state.swarm_id) throw new Error('swarm domain does not match persisted bundle swarm');
|
|
58
|
+
return { bridge: createSwarmBridge(state), statePath };
|
|
59
|
+
}
|
|
60
|
+
return { bridge: createSwarmBridge(requestedSwarmId ? { swarm_id: requestedSwarmId } : {}), statePath };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function bundleAtoms(bundlePath) {
|
|
64
|
+
if (!(await exists(resolve(bundlePath)))) return [];
|
|
65
|
+
const bundle = await readJson(resolve(bundlePath));
|
|
66
|
+
if (bundle.schema !== 'enigma.vault_bundle.v1') throw new Error(`unsupported Enigma bundle schema: ${bundle.schema ?? '<missing>'}`);
|
|
67
|
+
const active = new Set(Array.isArray(bundle.active_memory_addresses) ? bundle.active_memory_addresses : []);
|
|
68
|
+
return (Array.isArray(bundle.memory_objects) ? bundle.memory_objects : []).filter((atom) => active.has(atom.memory_addr));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function runPersisted(bundlePath, swarmId, operation) {
|
|
72
|
+
const statePath = statePathFor(bundlePath);
|
|
73
|
+
return enqueue(statePath, async () => {
|
|
74
|
+
const loaded = await loadBridge(bundlePath, swarmId);
|
|
75
|
+
const result = await operation(loaded.bridge);
|
|
76
|
+
await writeJsonAtomic(loaded.statePath, persistenceSafeState(loaded.bridge));
|
|
77
|
+
return result;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function hydrateSuppliedAtoms(bridge, input, permission) {
|
|
82
|
+
const atoms = input.atoms ?? input.memories;
|
|
83
|
+
if (!Array.isArray(atoms) || atoms.length === 0) return;
|
|
84
|
+
const { namespace } = bridge.requireAgent(input.agent_id, permission, input.namespace);
|
|
85
|
+
bridge.hydrateCanonicalMemories(namespace, atoms);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function enigma_swarm_register_agent(input = {}) {
|
|
89
|
+
const bundlePath = input.bundlePath ?? input.bundle_path ?? '.enigma/bundle.json';
|
|
90
|
+
return runPersisted(bundlePath, input.swarm_id ?? input.swarmId, (bridge) => ({
|
|
91
|
+
ok: true,
|
|
92
|
+
agent: bridge.registerAgent(input),
|
|
93
|
+
status: bridge.status(),
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function enigma_graph_query(input = {}) {
|
|
98
|
+
const bundlePath = input.bundlePath ?? input.bundle_path ?? '.enigma/bundle.json';
|
|
99
|
+
return runPersisted(bundlePath, input.swarm_id ?? input.swarmId, (bridge) => {
|
|
100
|
+
hydrateSuppliedAtoms(bridge, input, SWARM_PERMISSIONS.GRAPH);
|
|
101
|
+
return bridge.graphQuery(input);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const enigma_graph_search = enigma_graph_query;
|
|
106
|
+
|
|
107
|
+
export async function enigma_cluster_memories(input = {}) {
|
|
108
|
+
const bundlePath = input.bundlePath ?? input.bundle_path ?? '.enigma/bundle.json';
|
|
109
|
+
return runPersisted(bundlePath, input.swarm_id ?? input.swarmId, (bridge) => {
|
|
110
|
+
hydrateSuppliedAtoms(bridge, input, SWARM_PERMISSIONS.CLUSTER);
|
|
111
|
+
return bridge.clusterMemories(input);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function enigma_swarm_sync(input = {}) {
|
|
116
|
+
const bundlePath = input.bundlePath ?? input.bundle_path ?? '.enigma/bundle.json';
|
|
117
|
+
return runPersisted(bundlePath, input.swarm_id ?? input.swarmId, (bridge) => {
|
|
118
|
+
hydrateSuppliedAtoms(bridge, input, SWARM_PERMISSIONS.SYNC);
|
|
119
|
+
if (input.snapshot ?? input.peer_snapshot ?? input.peerSnapshot) return bridge.sync(input);
|
|
120
|
+
return bridge.createSnapshot(input);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function routeSwarmTool(name, input = {}) {
|
|
125
|
+
const handlers = { enigma_swarm_register_agent, enigma_graph_query, enigma_graph_search, enigma_cluster_memories, enigma_swarm_sync };
|
|
126
|
+
const handler = handlers[name];
|
|
127
|
+
if (!handler) throw new Error(`unknown swarm tool: ${name}`);
|
|
128
|
+
return handler(input);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function swarmStatusFromBundle(bundlePath = '.enigma/bundle.json') {
|
|
132
|
+
const resolved = resolve(bundlePath);
|
|
133
|
+
const { bridge } = await loadBridge(resolved);
|
|
134
|
+
const status = bridge.status();
|
|
135
|
+
const atoms = await bundleAtoms(resolved);
|
|
136
|
+
return {
|
|
137
|
+
...status,
|
|
138
|
+
bundle: resolved,
|
|
139
|
+
active_bundle_memory_count: atoms.length,
|
|
140
|
+
state_path: statePathFor(resolved),
|
|
141
|
+
claim_boundaries: {
|
|
142
|
+
local_simulator_only: true,
|
|
143
|
+
network_transmission: false,
|
|
144
|
+
decentralized_network_claim: false,
|
|
145
|
+
raw_memory_replicated_by_default: false,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export async function swarmGraphFromBundle(bundlePath = '.enigma/bundle.json') {
|
|
151
|
+
const resolved = resolve(bundlePath);
|
|
152
|
+
const loaded = await loadBridge(resolved);
|
|
153
|
+
const bridge = loaded.bridge;
|
|
154
|
+
const atoms = await bundleAtoms(resolved);
|
|
155
|
+
const inspectorId = '__enigma_cli_swarm_inspector__';
|
|
156
|
+
const namespace = '__enigma_bundle_active_set__';
|
|
157
|
+
bridge.registerAgent({ agent_id: inspectorId, namespace, permission_mask: SWARM_PERMISSIONS.ADMIN });
|
|
158
|
+
if (atoms.length > 0) bridge.ingestMemories({ agent_id: inspectorId, namespace, atoms });
|
|
159
|
+
const query = bridge.graphQuery({ agent_id: inspectorId, namespace, max_depth: 12, limit: 500 });
|
|
160
|
+
return {
|
|
161
|
+
...query,
|
|
162
|
+
bundle: resolved,
|
|
163
|
+
active_bundle_memory_count: atoms.length,
|
|
164
|
+
content_redacted: true,
|
|
165
|
+
local_only: true,
|
|
166
|
+
network_transmission: false,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
@@ -16,6 +16,37 @@ const ED25519 = 'Ed25519';
|
|
|
16
16
|
const GENESIS = 'GENESIS';
|
|
17
17
|
const ROOT_RE = /^sha256:[a-f0-9]{64}$/;
|
|
18
18
|
const HASH_RE = /^[a-f0-9]{64}$/;
|
|
19
|
+
const NULLIFIER_RE = /^nullifier:hmac-sha256:[a-f0-9]{64}$/;
|
|
20
|
+
const SECRET_VALUE_RE = /(?:-----BEGIN [A-Z ]*PRIVATE KEY-----|(?:sk|pk|rk)_(?:live|test|proj)_[A-Za-z0-9_-]{12,}|gh[pousr]_[A-Za-z0-9_]{20,}|xox[baprs]-[A-Za-z0-9-]{20,}|bearer\s+[A-Za-z0-9._~+/=-]{20,})/i;
|
|
21
|
+
const LOCAL_PATH_RE = /^(?:[A-Za-z]:[\\/]|\\\\|\/(?:Users|home|tmp|var|etc|private|Volumes)\/)/;
|
|
22
|
+
const FORBIDDEN_PUBLIC_CLAIM_RE = /\b(?:provider(?:-native)?\s+(?:deletion|memory\s+control)|model\s+forgetting|compliance\s+certification|certif(?:y|ies|ied)\s+compliance|benchmark\s+superiority|hosted\s+(?:saas|cloud)\s+ready|byoc\s+ready|patent(?:ability|able)|legal\s+conclusion|raw\s+embeddings?\s+(?:are\s+)?safe|hardware\s+tamper[-\s]?proof|tamper[-\s]?proof\s+hardware)\b/i;
|
|
23
|
+
const PUBLIC_FORBIDDEN_KEYS = new Set([
|
|
24
|
+
'api_key',
|
|
25
|
+
'authorization',
|
|
26
|
+
'body',
|
|
27
|
+
'content',
|
|
28
|
+
'cookie',
|
|
29
|
+
'credential',
|
|
30
|
+
'credentials',
|
|
31
|
+
'embedding',
|
|
32
|
+
'embeddings',
|
|
33
|
+
'file_path',
|
|
34
|
+
'local_path',
|
|
35
|
+
'password',
|
|
36
|
+
'plaintext',
|
|
37
|
+
'private_key',
|
|
38
|
+
'prompt',
|
|
39
|
+
'provider_response',
|
|
40
|
+
'raw',
|
|
41
|
+
'raw_memory',
|
|
42
|
+
'response',
|
|
43
|
+
'secret',
|
|
44
|
+
'text',
|
|
45
|
+
'token',
|
|
46
|
+
'transcript',
|
|
47
|
+
'vector',
|
|
48
|
+
'vectors'
|
|
49
|
+
]);
|
|
19
50
|
const RECEIPT_TOP_LEVEL_FIELDS = new Set([
|
|
20
51
|
'schema',
|
|
21
52
|
'receipt_id',
|
|
@@ -80,7 +111,7 @@ function canonicalizeValue(value, seen) {
|
|
|
80
111
|
}
|
|
81
112
|
|
|
82
113
|
const prototype = Object.getPrototypeOf(value);
|
|
83
|
-
if (prototype !== Object.prototype && prototype !== null) {
|
|
114
|
+
if (prototype !== Object.prototype && prototype !== null && prototype.constructor?.name !== 'Object') {
|
|
84
115
|
throw new TypeError('canonical JSON only accepts plain objects, arrays, and primitives');
|
|
85
116
|
}
|
|
86
117
|
|
|
@@ -503,6 +534,132 @@ export function createMemoryAddress(args = {}, maybeValue, maybeOptions = {}) {
|
|
|
503
534
|
return `${prefix}:hmac-sha256:${digest}`;
|
|
504
535
|
}
|
|
505
536
|
|
|
537
|
+
export function sha256Root(value) {
|
|
538
|
+
return prefixedSha256(value);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export function publicSafeHash(value, options = {}) {
|
|
542
|
+
assertPublicSafeFields(value, options);
|
|
543
|
+
return prefixedSha256(canonicalize(value));
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export function merkleSetRoot(values = []) {
|
|
547
|
+
if (!Array.isArray(values)) throw new TypeError('merkleSetRoot requires an array');
|
|
548
|
+
return new MerkleSet(values).root();
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export function createMerkleRoot(values = []) {
|
|
552
|
+
return merkleSetRoot(values);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export function createMerkleMembershipProof(valuesOrArgs, maybeValue) {
|
|
556
|
+
const args = Array.isArray(valuesOrArgs) ? { values: valuesOrArgs, value: maybeValue } : valuesOrArgs ?? {};
|
|
557
|
+
if (!Array.isArray(args.values)) throw new TypeError('createMerkleMembershipProof requires values');
|
|
558
|
+
return new MerkleSet(args.values).proveMembership(args.value);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export function verifyMerkleMembershipProof(proofOrArgs, maybeExpectedRoot) {
|
|
562
|
+
const args = isPlainRecord(proofOrArgs) && Object.prototype.hasOwnProperty.call(proofOrArgs, 'proof')
|
|
563
|
+
? proofOrArgs
|
|
564
|
+
: { proof: proofOrArgs, expectedRoot: maybeExpectedRoot };
|
|
565
|
+
return MerkleSet.verifyMembership(args.proof, args.expectedRoot ?? args.expected_root ?? args.proof?.root);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export function createMerkleProof(valuesOrArgs, maybeValue) {
|
|
569
|
+
return createMerkleMembershipProof(valuesOrArgs, maybeValue);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function verifyMerkleProof(proofOrArgs, maybeExpectedRoot) {
|
|
573
|
+
return verifyMerkleMembershipProof(proofOrArgs, maybeExpectedRoot);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export function createMerkleNonMembershipProof(valuesOrArgs, maybeValue) {
|
|
577
|
+
const args = Array.isArray(valuesOrArgs) ? { values: valuesOrArgs, value: maybeValue } : valuesOrArgs ?? {};
|
|
578
|
+
if (!Array.isArray(args.values)) throw new TypeError('createMerkleNonMembershipProof requires values');
|
|
579
|
+
return new MerkleSet(args.values).proveNonMembership(args.value);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
export function verifyMerkleNonMembershipProof(proofOrArgs, maybeExpectedRoot) {
|
|
583
|
+
const args = isPlainRecord(proofOrArgs) && Object.prototype.hasOwnProperty.call(proofOrArgs, 'proof')
|
|
584
|
+
? proofOrArgs
|
|
585
|
+
: { proof: proofOrArgs, expectedRoot: maybeExpectedRoot };
|
|
586
|
+
return MerkleSet.verifyNonMembership(args.proof, args.expectedRoot ?? args.expected_root ?? args.proof?.root);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export function deriveNullifier(args = {}, maybeValue, maybeOptions = {}) {
|
|
590
|
+
const options = isPlainRecord(args) && (Object.prototype.hasOwnProperty.call(args, 'secret') || Object.prototype.hasOwnProperty.call(args, 'key'))
|
|
591
|
+
? args
|
|
592
|
+
: { secret: args, value: maybeValue, ...maybeOptions };
|
|
593
|
+
const secret = options.secret ?? options.key;
|
|
594
|
+
if (secret === undefined) throw new TypeError('deriveNullifier requires a secret key');
|
|
595
|
+
const payload = {
|
|
596
|
+
domain: 'enigma.nullifier.v1',
|
|
597
|
+
scope: options.scope ?? options.namespace ?? 'memory-boundary',
|
|
598
|
+
subject_ref: options.subject_ref ?? options.subjectRef ?? null,
|
|
599
|
+
capability_id: options.capability_id ?? options.capabilityId ?? null,
|
|
600
|
+
policy_id: options.policy_id ?? options.policyId ?? null,
|
|
601
|
+
value: options.value ?? options.claim ?? options.ref ?? options.components ?? null
|
|
602
|
+
};
|
|
603
|
+
return `nullifier:hmac-sha256:${hmacSha256Hex({ key: secret, value: payload })}`;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export function isSha256Root(value) {
|
|
607
|
+
return ROOT_RE.test(value ?? '');
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function isNullifier(value) {
|
|
611
|
+
return NULLIFIER_RE.test(value ?? '');
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export function verifySha256Root(value, field = 'root') {
|
|
615
|
+
const ok = isSha256Root(value);
|
|
616
|
+
return verificationResult(ok, ok ? [] : [`${field} must be a sha256 root`]);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
export function verifyNullifier(value, field = 'nullifier') {
|
|
620
|
+
const ok = isNullifier(value);
|
|
621
|
+
return verificationResult(ok, ok ? [] : [`${field} must be a nullifier`]);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export function scanPublicSafeFields(value, options = {}) {
|
|
625
|
+
const errors = [];
|
|
626
|
+
const forbidden_paths = [];
|
|
627
|
+
scanPublicSafeValue(value, '$', errors, forbidden_paths, new WeakSet(), options);
|
|
628
|
+
return verificationResult(errors.length === 0, errors, { forbidden_paths });
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export function assertPublicSafeFields(value, options = {}) {
|
|
632
|
+
const result = scanPublicSafeFields(value, options);
|
|
633
|
+
if (!result.ok) throw new TypeError(`public-safe scan failed: ${result.errors.join('; ')}`);
|
|
634
|
+
return value;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export function verifyPublicSafeArtifact(value, options = {}) {
|
|
638
|
+
const result = scanPublicSafeFields(value, options);
|
|
639
|
+
return verificationResult(result.ok, result.errors, {
|
|
640
|
+
forbidden_paths: result.forbidden_paths,
|
|
641
|
+
public_hash: result.ok ? prefixedSha256(canonicalize(value)) : null
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
export function verifyPublicSafeHash(value, maybeExpectedHash, options = {}) {
|
|
646
|
+
const expected = options.expected_hash ?? options.expectedHash ?? options.hash ?? options.public_hash ?? options.publicHash ?? maybeExpectedHash;
|
|
647
|
+
const scan = scanPublicSafeFields(value, options);
|
|
648
|
+
if (!scan.ok) {
|
|
649
|
+
return verificationResult(false, scan.errors, { forbidden_paths: scan.forbidden_paths, public_hash: null });
|
|
650
|
+
}
|
|
651
|
+
const publicHash = prefixedSha256(canonicalize(value));
|
|
652
|
+
const errors = [];
|
|
653
|
+
if (expected !== undefined) {
|
|
654
|
+
try {
|
|
655
|
+
if (normalizeSha256Root(expected, 'expectedHash') !== publicHash) errors.push('public hash mismatch');
|
|
656
|
+
} catch {
|
|
657
|
+
errors.push('expectedHash must be a sha256 root');
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return verificationResult(errors.length === 0, errors, { forbidden_paths: [], public_hash: publicHash });
|
|
661
|
+
}
|
|
662
|
+
|
|
506
663
|
function bytesForHash(value) {
|
|
507
664
|
if (typeof value === 'string') return value;
|
|
508
665
|
if (Buffer.isBuffer(value) || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return value;
|
|
@@ -761,6 +918,96 @@ function withoutUndefinedFields(record) {
|
|
|
761
918
|
return cleaned;
|
|
762
919
|
}
|
|
763
920
|
|
|
921
|
+
function scanPublicSafeValue(value, path, errors, forbiddenPaths, seen, options) {
|
|
922
|
+
if (value === null) return;
|
|
923
|
+
if (value === undefined) {
|
|
924
|
+
addPublicSafeError(errors, forbiddenPaths, path, 'undefined is not public-safe JSON');
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
const type = typeof value;
|
|
928
|
+
if (type === 'string') {
|
|
929
|
+
scanPublicSafeString(value, path, errors, forbiddenPaths, options);
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
if (type === 'number') {
|
|
933
|
+
if (!Number.isFinite(value)) addPublicSafeError(errors, forbiddenPaths, path, 'number must be finite');
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
if (type === 'boolean') return;
|
|
937
|
+
if (type !== 'object') {
|
|
938
|
+
addPublicSafeError(errors, forbiddenPaths, path, `${type} is not public-safe JSON`);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (seen.has(value)) {
|
|
942
|
+
addPublicSafeError(errors, forbiddenPaths, path, 'value must not be circular');
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
seen.add(value);
|
|
946
|
+
try {
|
|
947
|
+
if (Array.isArray(value)) {
|
|
948
|
+
if (looksLikeEmbeddingVector(value)) addPublicSafeError(errors, forbiddenPaths, path, 'numeric vector-like arrays are not public-safe');
|
|
949
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
950
|
+
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
951
|
+
addPublicSafeError(errors, forbiddenPaths, `${path}[${index}]`, 'sparse arrays are not public-safe');
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
scanPublicSafeValue(value[index], `${path}[${index}]`, errors, forbiddenPaths, seen, options);
|
|
955
|
+
}
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
if (!isPlainRecord(value)) {
|
|
959
|
+
addPublicSafeError(errors, forbiddenPaths, path, 'unsupported object is not public-safe JSON');
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
for (const key of Object.keys(value)) {
|
|
963
|
+
const childPath = `${path}.${key}`;
|
|
964
|
+
if (isForbiddenPublicKey(key)) addPublicSafeError(errors, forbiddenPaths, childPath, 'field name is not public-safe');
|
|
965
|
+
scanPublicSafeValue(value[key], childPath, errors, forbiddenPaths, seen, options);
|
|
966
|
+
}
|
|
967
|
+
} finally {
|
|
968
|
+
seen.delete(value);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function scanPublicSafeString(value, path, errors, forbiddenPaths, options) {
|
|
973
|
+
if (SECRET_VALUE_RE.test(value)) addPublicSafeError(errors, forbiddenPaths, path, 'secret-shaped string is not public-safe');
|
|
974
|
+
if (LOCAL_PATH_RE.test(value)) addPublicSafeError(errors, forbiddenPaths, path, 'local absolute path is not public-safe');
|
|
975
|
+
if (FORBIDDEN_PUBLIC_CLAIM_RE.test(value)) addPublicSafeError(errors, forbiddenPaths, path, 'forbidden public claim is not allowed');
|
|
976
|
+
if (options.strictStrings === true && !isPublicSafeString(value)) {
|
|
977
|
+
addPublicSafeError(errors, forbiddenPaths, path, 'string is outside public artifact grammar');
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
function isForbiddenPublicKey(key) {
|
|
982
|
+
const normalized = key.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
|
|
983
|
+
if (PUBLIC_FORBIDDEN_KEYS.has(normalized)) return true;
|
|
984
|
+
return /(?:^|_)(?:plaintext|prompt|response|transcript|embedding|embeddings|vector|vectors|private_key|token|secret|password|api_key|credential|credentials|cookie|authorization)$/.test(normalized);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
function looksLikeEmbeddingVector(value) {
|
|
988
|
+
if (value.length < 32) return false;
|
|
989
|
+
let numeric = 0;
|
|
990
|
+
for (const item of value) {
|
|
991
|
+
if (typeof item === 'number' && Number.isFinite(item)) numeric += 1;
|
|
992
|
+
else return false;
|
|
993
|
+
}
|
|
994
|
+
return numeric === value.length;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
function isPublicSafeString(value) {
|
|
998
|
+
if (value.length === 0) return true;
|
|
999
|
+
if (ROOT_RE.test(value) || HASH_RE.test(value) || NULLIFIER_RE.test(value)) return true;
|
|
1000
|
+
if (/^[a-z][a-z0-9_]*(?:\.[a-z0-9_]+)*\.v\d+$/u.test(value)) return true;
|
|
1001
|
+
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/u.test(value)) return true;
|
|
1002
|
+
if (/^(?:ok|valid|invalid|active|quarantine|quarantined|tombstone|tombstoned|revoked|granted|omitted|selected|provided|missing|blocked|pass|fail|unknown)$/u.test(value)) return true;
|
|
1003
|
+
return /^[a-z][a-z0-9+.-]*:[A-Za-z0-9._~:@/+?#[\]!$&'()*%,;=-]{1,256}$/u.test(value);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function addPublicSafeError(errors, forbiddenPaths, path, message) {
|
|
1007
|
+
errors.push(`${path}: ${message}`);
|
|
1008
|
+
forbiddenPaths.push(path);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
764
1011
|
function isPlainRecord(value) {
|
|
765
1012
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
766
1013
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Single source of truth for the package version at runtime.
|
|
2
|
+
// Derived from the repository root package.json — never hard-code versions elsewhere.
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
const PACKAGE_JSON_URL = new URL('../../../package.json', import.meta.url);
|
|
6
|
+
|
|
7
|
+
export const ENIGMA_VERSION = JSON.parse(readFileSync(PACKAGE_JSON_URL, 'utf8')).version;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@enigma/dev-tools",
|
|
3
|
+
"version": "0.1.22",
|
|
4
|
+
"description": "Enigma Developer Tooling: Vector Benchmarks, Vault Inspectors, and Swarm Simulators",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.js",
|
|
9
|
+
"./benchmark": "./src/vector-benchmark.js",
|
|
10
|
+
"./inspector": "./src/vault-inspector.js",
|
|
11
|
+
"./simulator": "./src/swarm-simulator.js"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@enigma/core": "workspace:*",
|
|
15
|
+
"@enigma/rag": "workspace:*",
|
|
16
|
+
"@enigma/mesh": "workspace:*",
|
|
17
|
+
"@enigma/vault": "workspace:*"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Enigma Developer Tooling: Comprehensive Quantitative Memory Benchmark Suite.
|
|
2
|
+
// Evaluates Recall@10, Temporal Accuracy, Contradiction Resolution,
|
|
3
|
+
// Search Latency Percentiles (P50/P95/P99), and RAM Efficiency.
|
|
4
|
+
import { Enigma } from '../../sdk/src/index.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {Object} [options]
|
|
8
|
+
* @param {number} [options.corpusSize]
|
|
9
|
+
* @param {(options: Object) => Promise<Enigma>} [options.enigmaFactory]
|
|
10
|
+
*/
|
|
11
|
+
export async function runMemoryBenchmarkSuite(options = {}) {
|
|
12
|
+
const corpusSize = Math.max(10, Math.min(options.corpusSize || 50, 1000));
|
|
13
|
+
const enigmaFactory = options.enigmaFactory || ((connectOptions) => Enigma.connect(connectOptions));
|
|
14
|
+
const enigma = await enigmaFactory({ scope: 'benchmark.eval.suite' });
|
|
15
|
+
|
|
16
|
+
// 1. Ingest Synthetic Ground Truth Benchmark Dataset
|
|
17
|
+
const startIngest = Date.now();
|
|
18
|
+
const testFacts = [
|
|
19
|
+
// Standard semantic facts
|
|
20
|
+
{ text: 'Solana block production slot duration is targeted at 400 milliseconds.', query: 'What is the slot time on Solana?', expect: true },
|
|
21
|
+
{ text: 'Enigma vaults utilize AES-256-GCM authenticated encryption at rest.', query: 'How does Enigma encrypt vault data?', expect: true },
|
|
22
|
+
{ text: 'GhostMesh implements ephemeral X25519 ECDH session key agreement.', query: 'What key exchange does GhostMesh use?', expect: true },
|
|
23
|
+
{ text: 'The Sealed Sale marketplace compiles an 87,422-constraint Groth16 circuit.', query: 'How many constraints are in the Sealed Sale circuit?', expect: true },
|
|
24
|
+
{ text: 'Aztec-style Indexed Merkle Trees prevent double-spend of revoked nullifiers.', query: 'How does Enigma handle nullifier revocations?', expect: true },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
for (let i = 0; i < corpusSize; i++) {
|
|
28
|
+
const fact = testFacts[i % testFacts.length];
|
|
29
|
+
await enigma.remember(`${fact.text} [Fact #${i + 1}]`, {
|
|
30
|
+
type: i % 3 === 0 ? 'policy' : (i % 2 === 0 ? 'preference' : 'semantic'),
|
|
31
|
+
importance: 1.0 + (i % 5) * 0.2,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const ingestDurationMs = Date.now() - startIngest;
|
|
35
|
+
const ingestThroughput = Math.round((corpusSize / (ingestDurationMs / 1000 || 0.001)) * 10) / 10;
|
|
36
|
+
|
|
37
|
+
// 2. Measure Recall@10 & Latency Percentiles
|
|
38
|
+
const queryLatencies = [];
|
|
39
|
+
let recallHits = 0;
|
|
40
|
+
|
|
41
|
+
for (const item of testFacts) {
|
|
42
|
+
const qStart = performance.now();
|
|
43
|
+
const results = await enigma.recall(item.query, { topK: 10 });
|
|
44
|
+
const qDuration = performance.now() - qStart;
|
|
45
|
+
queryLatencies.push(qDuration);
|
|
46
|
+
|
|
47
|
+
const hit = results.some(r => r.text.toLowerCase().includes(item.text.slice(0, 20).toLowerCase()));
|
|
48
|
+
if (hit) recallHits++;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
queryLatencies.sort((a, b) => a - b);
|
|
52
|
+
const p50 = Math.round(queryLatencies[Math.floor(queryLatencies.length * 0.5)] * 100) / 100;
|
|
53
|
+
const p95 = Math.round(queryLatencies[Math.floor(queryLatencies.length * 0.95)] * 100) / 100;
|
|
54
|
+
const p99 = Math.round(queryLatencies[queryLatencies.length - 1] * 100) / 100;
|
|
55
|
+
const recallAt10Percent = Math.round((recallHits / testFacts.length) * 100);
|
|
56
|
+
|
|
57
|
+
// 3. Measure Temporal Accuracy
|
|
58
|
+
// Add historical memory vs current memory
|
|
59
|
+
const t1 = Date.parse('2026-01-01T00:00:00Z');
|
|
60
|
+
const t2 = Date.parse('2026-08-01T00:00:00Z');
|
|
61
|
+
|
|
62
|
+
const oldLoc = await enigma.remember('User primary residence is Austin, Texas.', {
|
|
63
|
+
validFrom: t1,
|
|
64
|
+
validUntil: t2,
|
|
65
|
+
observedAt: t1,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const newLoc = await enigma.remember('User moved and current primary residence is Dallas, Texas.', {
|
|
69
|
+
validFrom: t2,
|
|
70
|
+
validUntil: null,
|
|
71
|
+
observedAt: t2,
|
|
72
|
+
supersedes: [oldLoc.id],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Query as of Jan 2026 (historical) vs August 2026 (current)
|
|
76
|
+
const currentRecall = await enigma.recall('primary residence', { asOfTime: Date.parse('2026-08-15T00:00:00Z') });
|
|
77
|
+
const temporalAccuracy = currentRecall.length > 0 && currentRecall[0].text.includes('Dallas') ? 100 : 0;
|
|
78
|
+
|
|
79
|
+
// 4. Measure Contradiction Resolution Rate
|
|
80
|
+
const activeRecall = await enigma.recall('primary residence', { filterSuperseded: true });
|
|
81
|
+
const contradictionResolved = activeRecall.every(r => !r.text.includes('Austin')) ? 100 : 0;
|
|
82
|
+
|
|
83
|
+
// 5. Memory Footprint Calculation
|
|
84
|
+
const uncompressedBytes = corpusSize * 384 * 4; // Float32
|
|
85
|
+
const quantizedBytes = corpusSize * 384 * 1; // Int8
|
|
86
|
+
const memoryReductionPercent = Math.round(((uncompressedBytes - quantizedBytes) / uncompressedBytes) * 100);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
ok: true,
|
|
90
|
+
benchmark: 'enigma_memory_intelligence_v1',
|
|
91
|
+
corpusSize,
|
|
92
|
+
ingest: {
|
|
93
|
+
totalDurationMs: ingestDurationMs,
|
|
94
|
+
throughputPerSecond: ingestThroughput,
|
|
95
|
+
},
|
|
96
|
+
retrieval: {
|
|
97
|
+
queriesEvaluated: testFacts.length,
|
|
98
|
+
recallAt10Percent,
|
|
99
|
+
latencyMs: {
|
|
100
|
+
p50,
|
|
101
|
+
p95,
|
|
102
|
+
p99,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
intelligence: {
|
|
106
|
+
temporalAccuracyPercent: temporalAccuracy,
|
|
107
|
+
contradictionResolutionRatePercent: contradictionResolved,
|
|
108
|
+
memoryReductionPercent,
|
|
109
|
+
},
|
|
110
|
+
timestamp: Date.now(),
|
|
111
|
+
};
|
|
112
|
+
}
|