enigma-memory 0.1.17 → 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 +85 -27
- package/apps/cli/bin/enigma-desktop.mjs +140 -0
- package/apps/cli/bin/enigma-terminal.mjs +78 -0
- package/apps/cli/bin/enigma.mjs +4979 -3263
- 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/SIMULATION.md +14 -9
- package/deploy/docker-compose.local-production-simulation.yml +54 -12
- package/docs/benchmark-attestation-network.md +487 -487
- package/docs/benchmark-reproducibility.md +289 -289
- package/docs/blockchain-only-mechanisms.md +400 -400
- package/docs/browser-extension-install.md +8 -6
- package/docs/client-connectors.md +16 -12
- package/docs/demo-proof-network.md +275 -275
- package/docs/developer-ecosystem.md +15 -13
- package/docs/developer-proof-quickstart.md +325 -325
- package/docs/enigma-memory-ready-conformance.md +378 -376
- package/docs/install-anywhere.md +64 -30
- package/docs/installers-and-desktop.md +8 -7
- package/docs/memory-benchmarks.md +1 -1
- package/docs/memory-drive-health-model.md +690 -690
- package/docs/novelty-invention-candidates.md +161 -161
- package/docs/proof-network-build-notes.md +240 -240
- package/docs/proof-network-claim-boundaries.md +320 -318
- package/docs/proof-network.md +339 -339
- package/docs/sdk-api.md +324 -324
- package/docs/solana-proof-rail.md +453 -453
- 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 +410 -278
- 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 +249 -2
- 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 +2498 -1185
- 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 +436 -7
- 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 +1150 -125
- 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 +292 -274
- package/scripts/build-hosted-customer-lifecycle.mjs +493 -476
- package/scripts/build-hosted-probe-worker.mjs +19 -4
- package/scripts/build-installer-assets.mjs +409 -389
- 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 +4 -1
- package/scripts/build-proof-network-packet.mjs +213 -213
- package/scripts/check.mjs +25 -4
- package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
- package/scripts/install-enigma-local.mjs +18 -5
- package/scripts/release-audit.mjs +74 -115
- package/scripts/release-provenance.mjs +12 -2
- package/scripts/run-backend-readiness-smoke.mjs +112 -10
- package/scripts/run-standard-memory-benchmarks.mjs +1354 -1352
- package/scripts/scan-secrets.mjs +178 -0
- package/scripts/simulate-production-env.mjs +71 -10
- 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,253 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateKeyPairSync,
|
|
3
|
+
hkdfSync,
|
|
4
|
+
randomBytes,
|
|
5
|
+
randomFillSync,
|
|
6
|
+
randomUUID,
|
|
7
|
+
timingSafeEqual,
|
|
8
|
+
} from 'node:crypto';
|
|
9
|
+
import { createAttestation, sha256Hex } from './attestation.mjs';
|
|
10
|
+
import { createZeroizationReceipt } from './zeroization-proof.mjs';
|
|
11
|
+
|
|
12
|
+
export const VOLATILE_OVERWRITE_PROFILE = Object.freeze({
|
|
13
|
+
name: 'ENIGMA_THREE_PASS_VOLATILE_BUFFER_V1',
|
|
14
|
+
passes: Object.freeze(['cryptographic-random', '0xff', '0x00']),
|
|
15
|
+
standards_compliance_claimed: false,
|
|
16
|
+
hardware_ram_zeroization_proved: false,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export function generateEphemeralSessionKey(length = 32) {
|
|
20
|
+
if (!Number.isSafeInteger(length) || length < 16 || length > 1024) {
|
|
21
|
+
throw new RangeError('Ephemeral key length must be an integer between 16 and 1024 bytes.');
|
|
22
|
+
}
|
|
23
|
+
return randomBytes(length);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isZeroFilled(buffer) {
|
|
27
|
+
const view = asBufferView(buffer);
|
|
28
|
+
let aggregate = 0;
|
|
29
|
+
for (let index = 0; index < view.length; index += 1) aggregate |= view[index];
|
|
30
|
+
return aggregate === 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function overwriteVolatileBuffer(buffer) {
|
|
34
|
+
const view = asBufferView(buffer);
|
|
35
|
+
if (view.length === 0) throw new RangeError('Cannot zeroize an empty buffer.');
|
|
36
|
+
const overwritePasses = [];
|
|
37
|
+
|
|
38
|
+
randomFillSync(view);
|
|
39
|
+
overwritePasses.push({
|
|
40
|
+
pass: 1,
|
|
41
|
+
pattern: 'cryptographic-random',
|
|
42
|
+
post_pass_commitment: `sha256:${sha256Hex(view)}`,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
view.fill(0xff);
|
|
46
|
+
overwritePasses.push({
|
|
47
|
+
pass: 2,
|
|
48
|
+
pattern: '0xff',
|
|
49
|
+
post_pass_commitment: `sha256:${sha256Hex(view)}`,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
view.fill(0x00);
|
|
53
|
+
overwritePasses.push({
|
|
54
|
+
pass: 3,
|
|
55
|
+
pattern: '0x00',
|
|
56
|
+
post_pass_commitment: `sha256:${sha256Hex(view)}`,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const postWipeZeroCheck = isZeroFilled(view);
|
|
60
|
+
if (!postWipeZeroCheck) throw new Error('VOLATILE_BUFFER_POST_WIPE_CHECK_FAILED');
|
|
61
|
+
return {
|
|
62
|
+
profile: VOLATILE_OVERWRITE_PROFILE,
|
|
63
|
+
byte_length: view.length,
|
|
64
|
+
overwrite_passes: overwritePasses,
|
|
65
|
+
post_wipe_commitment: `sha256:${sha256Hex(view)}`,
|
|
66
|
+
post_wipe_zero_check: true,
|
|
67
|
+
claim_boundary: {
|
|
68
|
+
retained_buffer_instance_only: true,
|
|
69
|
+
hardware_ram_zeroization_proved: false,
|
|
70
|
+
runtime_copies_gc_caches_in_scope: false,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const zeroizeBuffer = overwriteVolatileBuffer;
|
|
76
|
+
|
|
77
|
+
export class EnclaveSessionManager {
|
|
78
|
+
#activeSessions = new Map();
|
|
79
|
+
#tombstones = new Map();
|
|
80
|
+
#privateKey;
|
|
81
|
+
#publicKey;
|
|
82
|
+
|
|
83
|
+
constructor({ signingKeyPair } = {}) {
|
|
84
|
+
const pair = signingKeyPair ?? generateKeyPairSync('ed25519');
|
|
85
|
+
if (!pair.privateKey || !pair.publicKey) throw new TypeError('An Ed25519 signing key pair is required.');
|
|
86
|
+
this.#privateKey = pair.privateKey;
|
|
87
|
+
this.#publicKey = pair.publicKey;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get publicKeySpkiBase64() {
|
|
91
|
+
return this.#publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
initializeSession({ bundle, bundleHash, sessionId = randomUUID(), now = new Date().toISOString(), metadata = {} } = {}) {
|
|
95
|
+
if (this.#activeSessions.has(sessionId) || this.#tombstones.has(sessionId)) {
|
|
96
|
+
throw new Error(`SESSION_ID_ALREADY_USED: ${sessionId}`);
|
|
97
|
+
}
|
|
98
|
+
const masterKey = generateEphemeralSessionKey(32);
|
|
99
|
+
const attestation = createAttestation({ bundle, bundleHash, now, nonce: sessionId });
|
|
100
|
+
const session = {
|
|
101
|
+
sessionId,
|
|
102
|
+
createdAt: now,
|
|
103
|
+
status: 'active',
|
|
104
|
+
masterKey,
|
|
105
|
+
derivedKeys: new Map(),
|
|
106
|
+
attestation,
|
|
107
|
+
metadata: sanitizeMetadata(metadata),
|
|
108
|
+
};
|
|
109
|
+
this.#activeSessions.set(sessionId, session);
|
|
110
|
+
return this.#snapshot(session);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
createSession(options) {
|
|
114
|
+
return this.initializeSession(options);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
hasActiveSession(sessionId) {
|
|
118
|
+
return this.#activeSessions.has(String(sessionId));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
listActiveSessions() {
|
|
122
|
+
return [...this.#activeSessions.values()].map((session) => this.#snapshot(session));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getSession(sessionId) {
|
|
126
|
+
const session = this.#activeSessions.get(String(sessionId));
|
|
127
|
+
if (session) return this.#snapshot(session);
|
|
128
|
+
const tombstone = this.#tombstones.get(String(sessionId));
|
|
129
|
+
return tombstone ? structuredClone(tombstone) : null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
deriveSessionKey(sessionId, purpose, { length = 32, context = '' } = {}) {
|
|
133
|
+
const session = this.#requireActive(sessionId);
|
|
134
|
+
const purposeString = String(purpose ?? '').trim();
|
|
135
|
+
if (!purposeString) throw new TypeError('A non-empty derivation purpose is required.');
|
|
136
|
+
if (!Number.isSafeInteger(length) || length < 16 || length > 1024) {
|
|
137
|
+
throw new RangeError('Derived key length must be an integer between 16 and 1024 bytes.');
|
|
138
|
+
}
|
|
139
|
+
const handle = `${purposeString}:${String(context)}:${length}`;
|
|
140
|
+
const existing = session.derivedKeys.get(handle);
|
|
141
|
+
if (existing) return existing;
|
|
142
|
+
const salt = Buffer.from(session.attestation.measurement_hash.slice(7), 'hex');
|
|
143
|
+
const info = Buffer.from(`enigma-session-key-v1\0${purposeString}\0${String(context)}`);
|
|
144
|
+
const derived = Buffer.from(hkdfSync('sha256', session.masterKey, salt, info, length));
|
|
145
|
+
session.derivedKeys.set(handle, derived);
|
|
146
|
+
return derived;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
withDerivedSessionKey(sessionId, purpose, options, callback) {
|
|
150
|
+
if (typeof options === 'function') return this.withDerivedSessionKey(sessionId, purpose, {}, options);
|
|
151
|
+
if (typeof callback !== 'function') throw new TypeError('A callback is required.');
|
|
152
|
+
const key = this.deriveSessionKey(sessionId, purpose, options);
|
|
153
|
+
return callback(key);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
attestSession(sessionId) {
|
|
157
|
+
return structuredClone(this.#requireActive(sessionId).attestation);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
zeroizeSession(sessionId, { now = new Date().toISOString() } = {}) {
|
|
161
|
+
const session = this.#requireActive(sessionId);
|
|
162
|
+
const buffers = [
|
|
163
|
+
['master', session.masterKey],
|
|
164
|
+
...[...session.derivedKeys.entries()].map(([handle, key]) => [`derived:${handle}`, key]),
|
|
165
|
+
];
|
|
166
|
+
const entries = buffers.map(([keyRef, buffer]) => {
|
|
167
|
+
const preWipeCommitment = `sha256:${sha256Hex(buffer)}`;
|
|
168
|
+
const result = overwriteVolatileBuffer(buffer);
|
|
169
|
+
return {
|
|
170
|
+
key_ref: keyRef,
|
|
171
|
+
byte_length: result.byte_length,
|
|
172
|
+
pre_wipe_commitment: preWipeCommitment,
|
|
173
|
+
post_wipe_commitment: result.post_wipe_commitment,
|
|
174
|
+
overwrite_passes: result.overwrite_passes,
|
|
175
|
+
post_wipe_zero_check: result.post_wipe_zero_check,
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
session.status = 'zeroized';
|
|
180
|
+
session.derivedKeys.clear();
|
|
181
|
+
this.#activeSessions.delete(session.sessionId);
|
|
182
|
+
const tombstone = {
|
|
183
|
+
session_id: session.sessionId,
|
|
184
|
+
status: 'zeroized',
|
|
185
|
+
created_at: session.createdAt,
|
|
186
|
+
zeroized_at: now,
|
|
187
|
+
attestation_measurement_hash: session.attestation.measurement_hash,
|
|
188
|
+
active_session_removed: true,
|
|
189
|
+
enigma_key_handles_invalidated: true,
|
|
190
|
+
};
|
|
191
|
+
this.#tombstones.set(session.sessionId, tombstone);
|
|
192
|
+
|
|
193
|
+
const receipt = createZeroizationReceipt({
|
|
194
|
+
sessionId: session.sessionId,
|
|
195
|
+
entries,
|
|
196
|
+
attestation: session.attestation,
|
|
197
|
+
privateKey: this.#privateKey,
|
|
198
|
+
publicKey: this.#publicKey,
|
|
199
|
+
sessionRemovedFromActiveSet: !this.#activeSessions.has(session.sessionId),
|
|
200
|
+
now,
|
|
201
|
+
});
|
|
202
|
+
tombstone.receipt_hash = receipt.receipt_hash;
|
|
203
|
+
return receipt;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
zeroizeAll({ now = new Date().toISOString() } = {}) {
|
|
207
|
+
return [...this.#activeSessions.keys()].map((sessionId) => this.zeroizeSession(sessionId, { now }));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
#requireActive(sessionId) {
|
|
211
|
+
const normalized = String(sessionId ?? '');
|
|
212
|
+
const session = this.#activeSessions.get(normalized);
|
|
213
|
+
if (!session) throw new Error(`SESSION_NOT_ACTIVE: ${normalized || '<missing>'}`);
|
|
214
|
+
return session;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
#snapshot(session) {
|
|
218
|
+
return {
|
|
219
|
+
schema: 'enigma.enclave.session.v1',
|
|
220
|
+
session_id: session.sessionId,
|
|
221
|
+
status: session.status,
|
|
222
|
+
created_at: session.createdAt,
|
|
223
|
+
derived_key_count: session.derivedKeys.size,
|
|
224
|
+
attestation: structuredClone(session.attestation),
|
|
225
|
+
metadata: structuredClone(session.metadata),
|
|
226
|
+
claim_boundary: {
|
|
227
|
+
keys_process_local: true,
|
|
228
|
+
key_material_exported: false,
|
|
229
|
+
hardware_enclave_claimed: false,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export const SessionManager = EnclaveSessionManager;
|
|
236
|
+
export const defaultSessionManager = new EnclaveSessionManager();
|
|
237
|
+
|
|
238
|
+
function asBufferView(value) {
|
|
239
|
+
if (Buffer.isBuffer(value)) return value;
|
|
240
|
+
if (value instanceof Uint8Array) return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
241
|
+
throw new TypeError('Expected a Buffer or Uint8Array.');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function sanitizeMetadata(metadata) {
|
|
245
|
+
if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) return {};
|
|
246
|
+
return Object.fromEntries(Object.entries(metadata).map(([key, value]) => [String(key), String(value)]));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function buffersEqual(left, right) {
|
|
250
|
+
const a = asBufferView(left);
|
|
251
|
+
const b = asBufferView(right);
|
|
252
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
253
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { randomUUID, sign, verify, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { canonicalJson, sha256Hex, verifyAttestation } from './attestation.mjs';
|
|
3
|
+
|
|
4
|
+
const HEX_COMMITMENT = /^sha256:[a-f0-9]{64}$/;
|
|
5
|
+
|
|
6
|
+
function normalizeCommitment(value) {
|
|
7
|
+
const normalized = String(value).startsWith('sha256:') ? String(value) : `sha256:${value}`;
|
|
8
|
+
if (!HEX_COMMITMENT.test(normalized)) throw new TypeError('Expected a SHA-256 commitment.');
|
|
9
|
+
return normalized;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function merkleRoot(commitments) {
|
|
13
|
+
let level = commitments.map((value) => Buffer.from(normalizeCommitment(value).slice(7), 'hex'));
|
|
14
|
+
if (level.length === 0) return `sha256:${sha256Hex('enigma-empty-merkle-tree-v1')}`;
|
|
15
|
+
while (level.length > 1) {
|
|
16
|
+
if (level.length % 2 === 1) level.push(level[level.length - 1]);
|
|
17
|
+
const next = [];
|
|
18
|
+
for (let index = 0; index < level.length; index += 2) {
|
|
19
|
+
next.push(Buffer.from(sha256Hex(Buffer.concat([level[index], level[index + 1]])), 'hex'));
|
|
20
|
+
}
|
|
21
|
+
level = next;
|
|
22
|
+
}
|
|
23
|
+
return `sha256:${level[0].toString('hex')}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function createZeroizationReceipt({
|
|
27
|
+
sessionId,
|
|
28
|
+
entries,
|
|
29
|
+
attestation,
|
|
30
|
+
privateKey,
|
|
31
|
+
publicKey,
|
|
32
|
+
sessionRemovedFromActiveSet,
|
|
33
|
+
now = new Date().toISOString(),
|
|
34
|
+
receiptId = randomUUID(),
|
|
35
|
+
}) {
|
|
36
|
+
if (!sessionId) throw new TypeError('sessionId is required.');
|
|
37
|
+
if (!Array.isArray(entries) || entries.length === 0) throw new TypeError('At least one zeroization entry is required.');
|
|
38
|
+
if (!privateKey || !publicKey) throw new TypeError('An Ed25519 signing key pair is required.');
|
|
39
|
+
|
|
40
|
+
const normalizedEntries = entries.map((entry, index) => ({
|
|
41
|
+
key_ref: String(entry.key_ref ?? `key-${index}`),
|
|
42
|
+
byte_length: Number(entry.byte_length),
|
|
43
|
+
pre_wipe_commitment: normalizeCommitment(entry.pre_wipe_commitment),
|
|
44
|
+
post_wipe_commitment: normalizeCommitment(entry.post_wipe_commitment),
|
|
45
|
+
overwrite_passes: Array.isArray(entry.overwrite_passes) ? entry.overwrite_passes.map((pass) => ({
|
|
46
|
+
pass: Number(pass.pass),
|
|
47
|
+
pattern: String(pass.pattern),
|
|
48
|
+
post_pass_commitment: normalizeCommitment(pass.post_pass_commitment),
|
|
49
|
+
})) : [],
|
|
50
|
+
post_wipe_zero_check: entry.post_wipe_zero_check === true,
|
|
51
|
+
}));
|
|
52
|
+
const allZero = normalizedEntries.every((entry) => entry.post_wipe_zero_check);
|
|
53
|
+
const removed = sessionRemovedFromActiveSet === true;
|
|
54
|
+
const payload = {
|
|
55
|
+
schema: 'enigma.enclave.zeroization-receipt.v1',
|
|
56
|
+
receipt_id: receiptId,
|
|
57
|
+
session_id: String(sessionId),
|
|
58
|
+
created_at: now,
|
|
59
|
+
operation: 'BEST_EFFORT_VOLATILE_BUFFER_OVERWRITE',
|
|
60
|
+
overwrite_profile: {
|
|
61
|
+
name: 'ENIGMA_THREE_PASS_VOLATILE_BUFFER_V1',
|
|
62
|
+
patterns: ['cryptographic-random', '0xff', '0x00'],
|
|
63
|
+
standards_compliance_claimed: false,
|
|
64
|
+
},
|
|
65
|
+
pre_wipe_merkle_root: merkleRoot(normalizedEntries.map((entry) => entry.pre_wipe_commitment)),
|
|
66
|
+
post_wipe_merkle_root: merkleRoot(normalizedEntries.map((entry) => entry.post_wipe_commitment)),
|
|
67
|
+
entries: normalizedEntries,
|
|
68
|
+
attestation,
|
|
69
|
+
state_nullification: {
|
|
70
|
+
active_session_removed: removed,
|
|
71
|
+
retained_buffers_zero_checked: allZero,
|
|
72
|
+
enigma_key_handles_invalidated: removed && allZero,
|
|
73
|
+
all_external_copies_unrecoverable: false,
|
|
74
|
+
proved: removed && allZero,
|
|
75
|
+
},
|
|
76
|
+
claim_boundary: {
|
|
77
|
+
proof_scope: 'Enigma-managed session state and retained Buffer instances only.',
|
|
78
|
+
hardware_ram_zeroization_proved: false,
|
|
79
|
+
external_buffer_copies_proved: false,
|
|
80
|
+
runtime_copies_gc_caches_in_scope: false,
|
|
81
|
+
physical_ram_in_scope: false,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
const canonical = canonicalJson(payload);
|
|
85
|
+
const receiptHash = `sha256:${sha256Hex(canonical)}`;
|
|
86
|
+
const signature = sign(null, Buffer.from(canonical), privateKey).toString('base64');
|
|
87
|
+
const publicKeyDer = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
88
|
+
return {
|
|
89
|
+
...payload,
|
|
90
|
+
receipt_hash: receiptHash,
|
|
91
|
+
signature: {
|
|
92
|
+
algorithm: 'Ed25519',
|
|
93
|
+
public_key_spki_base64: publicKeyDer,
|
|
94
|
+
value_base64: signature,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function verifyZeroizationReceipt(receipt, { expectedSessionId, expectedPublicKey } = {}) {
|
|
100
|
+
const errors = [];
|
|
101
|
+
if (!receipt || typeof receipt !== 'object') return invalid(['RECEIPT_REQUIRED']);
|
|
102
|
+
if (receipt.schema !== 'enigma.enclave.zeroization-receipt.v1') errors.push('INVALID_SCHEMA');
|
|
103
|
+
if (expectedSessionId && !safeStringEqual(receipt.session_id, expectedSessionId)) errors.push('SESSION_ID_MISMATCH');
|
|
104
|
+
if (receipt.operation !== 'BEST_EFFORT_VOLATILE_BUFFER_OVERWRITE') errors.push('INVALID_OPERATION');
|
|
105
|
+
if (receipt.overwrite_profile?.standards_compliance_claimed !== false) errors.push('INVALID_COMPLIANCE_CLAIM');
|
|
106
|
+
|
|
107
|
+
const entries = receipt.entries;
|
|
108
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
109
|
+
errors.push('ZEROIZATION_ENTRIES_REQUIRED');
|
|
110
|
+
} else {
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const validLength = Number.isSafeInteger(entry.byte_length)
|
|
113
|
+
&& entry.byte_length > 0
|
|
114
|
+
&& entry.byte_length <= 1024;
|
|
115
|
+
if (!validLength) errors.push('INVALID_BUFFER_LENGTH');
|
|
116
|
+
if (!HEX_COMMITMENT.test(String(entry.pre_wipe_commitment ?? ''))) errors.push('INVALID_PRE_WIPE_COMMITMENT');
|
|
117
|
+
if (!HEX_COMMITMENT.test(String(entry.post_wipe_commitment ?? ''))) errors.push('INVALID_POST_WIPE_COMMITMENT');
|
|
118
|
+
if (entry.post_wipe_zero_check !== true) errors.push('POST_WIPE_ZERO_CHECK_FAILED');
|
|
119
|
+
const passes = entry.overwrite_passes;
|
|
120
|
+
const validPassShape = Array.isArray(passes) && passes.length === 3
|
|
121
|
+
&& passes[0]?.pass === 1 && passes[0]?.pattern === 'cryptographic-random'
|
|
122
|
+
&& passes[1]?.pass === 2 && passes[1]?.pattern === '0xff'
|
|
123
|
+
&& passes[2]?.pass === 3 && passes[2]?.pattern === '0x00';
|
|
124
|
+
if (!validPassShape) errors.push('INVALID_OVERWRITE_TRANSCRIPT');
|
|
125
|
+
if (validLength) {
|
|
126
|
+
const zeroDigest = `sha256:${sha256Hex(Buffer.alloc(entry.byte_length))}`;
|
|
127
|
+
const ffDigest = `sha256:${sha256Hex(Buffer.alloc(entry.byte_length, 0xff))}`;
|
|
128
|
+
if (!safeStringEqual(zeroDigest, entry.post_wipe_commitment)) errors.push('POST_WIPE_COMMITMENT_NOT_ZERO');
|
|
129
|
+
if (validPassShape && (!safeStringEqual(ffDigest, passes[1].post_pass_commitment)
|
|
130
|
+
|| !safeStringEqual(zeroDigest, passes[2].post_pass_commitment)
|
|
131
|
+
|| !safeStringEqual(passes[2].post_pass_commitment, entry.post_wipe_commitment))) {
|
|
132
|
+
errors.push('OVERWRITE_TRANSCRIPT_COMMITMENT_MISMATCH');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
if (!safeStringEqual(receipt.pre_wipe_merkle_root, merkleRoot(entries.map((entry) => entry.pre_wipe_commitment)))) {
|
|
138
|
+
errors.push('PRE_WIPE_ROOT_MISMATCH');
|
|
139
|
+
}
|
|
140
|
+
if (!safeStringEqual(receipt.post_wipe_merkle_root, merkleRoot(entries.map((entry) => entry.post_wipe_commitment)))) {
|
|
141
|
+
errors.push('POST_WIPE_ROOT_MISMATCH');
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
errors.push('INVALID_MERKLE_COMMITMENT');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const state = receipt.state_nullification;
|
|
149
|
+
if (state?.active_session_removed !== true
|
|
150
|
+
|| state?.retained_buffers_zero_checked !== true
|
|
151
|
+
|| state?.enigma_key_handles_invalidated !== true
|
|
152
|
+
|| state?.all_external_copies_unrecoverable !== false
|
|
153
|
+
|| state?.proved !== true) {
|
|
154
|
+
errors.push('STATE_NULLIFICATION_NOT_PROVED');
|
|
155
|
+
}
|
|
156
|
+
const boundary = receipt.claim_boundary;
|
|
157
|
+
if (boundary?.hardware_ram_zeroization_proved !== false
|
|
158
|
+
|| boundary?.external_buffer_copies_proved !== false
|
|
159
|
+
|| boundary?.runtime_copies_gc_caches_in_scope !== false
|
|
160
|
+
|| boundary?.physical_ram_in_scope !== false) {
|
|
161
|
+
errors.push('INVALID_CLAIM_BOUNDARY');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const attestationResult = verifyAttestation(receipt.attestation);
|
|
165
|
+
if (!attestationResult.valid) errors.push(...attestationResult.errors.map((error) => `ATTESTATION_${error}`));
|
|
166
|
+
|
|
167
|
+
const { receipt_hash: claimedHash, signature, ...payload } = receipt;
|
|
168
|
+
const canonical = canonicalJson(payload);
|
|
169
|
+
const computedHash = `sha256:${sha256Hex(canonical)}`;
|
|
170
|
+
if (!safeStringEqual(claimedHash, computedHash)) errors.push('RECEIPT_HASH_MISMATCH');
|
|
171
|
+
if (signature?.algorithm !== 'Ed25519' || !signature.public_key_spki_base64 || !signature.value_base64) {
|
|
172
|
+
errors.push('SIGNATURE_REQUIRED');
|
|
173
|
+
} else {
|
|
174
|
+
if (expectedPublicKey) {
|
|
175
|
+
const expectedDer = typeof expectedPublicKey === 'string'
|
|
176
|
+
? expectedPublicKey
|
|
177
|
+
: expectedPublicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
178
|
+
if (!safeStringEqual(signature.public_key_spki_base64, expectedDer)) errors.push('UNTRUSTED_SIGNER');
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const validSignature = verify(
|
|
182
|
+
null,
|
|
183
|
+
Buffer.from(canonical),
|
|
184
|
+
{ key: Buffer.from(signature.public_key_spki_base64, 'base64'), type: 'spki', format: 'der' },
|
|
185
|
+
Buffer.from(signature.value_base64, 'base64'),
|
|
186
|
+
);
|
|
187
|
+
if (!validSignature) errors.push('INVALID_SIGNATURE');
|
|
188
|
+
} catch {
|
|
189
|
+
errors.push('INVALID_SIGNATURE');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
valid: errors.length === 0,
|
|
195
|
+
errors: [...new Set(errors)],
|
|
196
|
+
receipt_hash: computedHash,
|
|
197
|
+
session_id: receipt.session_id,
|
|
198
|
+
state_nullification_proved: errors.length === 0 && state?.proved === true,
|
|
199
|
+
state_nullification_scope: 'Enigma-managed session state and retained Buffer instances only.',
|
|
200
|
+
claim_boundary: boundary,
|
|
201
|
+
attestation: attestationResult,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function verifyStateNullification(receipt, options) {
|
|
206
|
+
const verification = verifyZeroizationReceipt(receipt, options);
|
|
207
|
+
return {
|
|
208
|
+
...verification,
|
|
209
|
+
proved: verification.valid && verification.state_nullification_proved,
|
|
210
|
+
scope: 'Enigma-managed session state and retained Buffer instances only.',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function invalid(errors) {
|
|
215
|
+
return {
|
|
216
|
+
valid: false,
|
|
217
|
+
errors,
|
|
218
|
+
state_nullification_proved: false,
|
|
219
|
+
state_nullification_scope: 'Enigma-managed session state and retained Buffer instances only.',
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function safeStringEqual(left, right) {
|
|
224
|
+
const a = Buffer.from(String(left ?? ''));
|
|
225
|
+
const b = Buffer.from(String(right ?? ''));
|
|
226
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
227
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@enigma/cortex-reflex",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Agent recovery supervisor, stateful benchmark, and LoRA training infrastructure for Enigma Cortex.",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.js"
|
|
10
|
+
},
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=24"
|
|
13
|
+
}
|
|
14
|
+
}
|