enigma-memory 0.1.0
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/LICENSE +55 -0
- package/README.md +379 -0
- package/apps/cli/bin/enigma.mjs +1117 -0
- package/apps/desktop/src/app.js +1327 -0
- package/apps/desktop/src/index.html +1373 -0
- package/apps/desktop/src/styles.css +386 -0
- package/apps/gateway/bin/enigma-gateway.mjs +52 -0
- package/apps/gateway/src/server.mjs +1403 -0
- package/apps/native-host/README.md +265 -0
- package/apps/native-host/bin/enigma-native-host.mjs +499 -0
- package/apps/native-host/manifests/com.enigma.native_host.chrome.json +9 -0
- package/apps/native-host/manifests/com.enigma.native_host.edge.json +9 -0
- package/apps/native-host/manifests/com.enigma.native_host.firefox.json +9 -0
- package/apps/relay/bin/enigma-relay.mjs +52 -0
- package/apps/relay/src/server.mjs +1571 -0
- package/apps/verifier/bin/enigma-verify.mjs +240 -0
- package/deploy/docker-compose.production.example.yml +150 -0
- package/deploy/kubernetes/enigma-backend.example.yaml +580 -0
- package/package.json +196 -0
- package/packages/adapters/PACKAGE_CONTRACT.md +47 -0
- package/packages/adapters/src/index.js +183 -0
- package/packages/boundary/src/index.js +468 -0
- package/packages/connectors/src/index.js +533 -0
- package/packages/core/src/index.js +766 -0
- package/packages/enterprise/src/index.js +505 -0
- package/packages/importers/src/index.js +1083 -0
- package/packages/mcp-server/bin/enigma-mcp.mjs +19 -0
- package/packages/mcp-server/src/index.js +1185 -0
- package/packages/mesh/src/index.js +531 -0
- package/packages/metering/PACKAGE_CONTRACT.md +20 -0
- package/packages/metering/src/index.js +246 -0
- package/packages/optimizer/src/index.js +707 -0
- package/packages/passport/src/index.js +651 -0
- package/packages/settlement/PACKAGE_CONTRACT.md +28 -0
- package/packages/settlement/src/index.js +369 -0
- package/packages/storage/PACKAGE_CONTRACT.md +23 -0
- package/packages/storage/src/index.js +392 -0
- package/packages/vault/src/index.js +904 -0
- package/scripts/build-ai-orchestration-plan.mjs +248 -0
- package/scripts/build-cloudflare-pages-release-packet.mjs +287 -0
- package/scripts/build-cloudflare-token-policy.mjs +239 -0
- package/scripts/build-cloudflare-token-request.mjs +314 -0
- package/scripts/build-demo-assets.mjs +263 -0
- package/scripts/build-edge-backend-workers.mjs +353 -0
- package/scripts/build-goal-completion-audit.mjs +398 -0
- package/scripts/build-hosted-probe-worker.mjs +191 -0
- package/scripts/build-operator-acceptance-packet.mjs +254 -0
- package/scripts/build-operator-evidence-starter.mjs +525 -0
- package/scripts/build-production-backend-env-kit.mjs +384 -0
- package/scripts/build-production-dependency-report.mjs +369 -0
- package/scripts/build-production-handoff-packet.mjs +475 -0
- package/scripts/build-production-readiness-manifest.mjs +209 -0
- package/scripts/build-production-status-board.mjs +297 -0
- package/scripts/build-production-storage-migration.mjs +86 -0
- package/scripts/build-production-workplan.mjs +371 -0
- package/scripts/build-review-packet.mjs +594 -0
- package/scripts/check.mjs +419 -0
- package/scripts/cloudflare-ops.mjs +1672 -0
- package/scripts/cloudflare-secret-env.mjs +128 -0
- package/scripts/collect-hosted-backend-live-evidence.mjs +263 -0
- package/scripts/infrastructure-readiness.mjs +944 -0
- package/scripts/install-enigma-local.mjs +270 -0
- package/scripts/memory-optimization-benchmark.mjs +242 -0
- package/scripts/monitor-live-endpoints.mjs +358 -0
- package/scripts/release-audit.mjs +5588 -0
- package/scripts/release-provenance.mjs +250 -0
- package/scripts/run-backend-readiness-smoke.mjs +220 -0
- package/scripts/validate-backup-restore-drill.mjs +166 -0
- package/scripts/validate-cloudflare-credentials.mjs +112 -0
- package/scripts/validate-cloudflare-worker-inspect.mjs +179 -0
- package/scripts/validate-domain-tls.mjs +248 -0
- package/scripts/validate-hosted-backend-live.mjs +319 -0
- package/scripts/validate-incident-drill.mjs +221 -0
- package/scripts/validate-kms-custody.mjs +235 -0
- package/scripts/validate-legal-compliance-approval.mjs +274 -0
- package/scripts/validate-monitoring-alerting.mjs +263 -0
- package/scripts/validate-network-access-policy.mjs +285 -0
- package/scripts/validate-operator-acceptance.mjs +298 -0
- package/scripts/validate-production-manifests.mjs +325 -0
- package/scripts/validate-public-site-security.mjs +252 -0
- package/scripts/validate-security-threat-model.mjs +285 -0
- package/scripts/validate-service-settlement.mjs +256 -0
- package/scripts/validate-support-sla.mjs +190 -0
- package/scripts/validate-tenant-policy-approval.mjs +228 -0
- package/scripts/validate-usage-metering.mjs +224 -0
- package/scripts/validate-whitepaper-claims.mjs +166 -0
- package/specs/boundary-manifest-v1.schema.json +35 -0
- package/specs/capsule-v1.schema.json +55 -0
- package/specs/claim-boundary-manifest-v1.schema.json +22 -0
- package/specs/connector-profile-v1.schema.json +62 -0
- package/specs/deletion-tombstone-v1.schema.json +26 -0
- package/specs/enterprise-policy-v1.schema.json +59 -0
- package/specs/gateway-request-v1.schema.json +32 -0
- package/specs/goal-completion-audit-v1.schema.json +70 -0
- package/specs/hosted-backend-live-evidence-v1.schema.json +147 -0
- package/specs/import-report-v1.schema.json +214 -0
- package/specs/infrastructure-readiness-manifest-v1.schema.json +130 -0
- package/specs/memory-event-v1.schema.json +42 -0
- package/specs/mesh-node-v1.schema.json +126 -0
- package/specs/passport-v1.schema.json +50 -0
- package/specs/production-handoff-packet-v1.schema.json +149 -0
- package/specs/receipt-v1.schema.json +61 -0
- package/specs/relay-record-v1.schema.json +43 -0
- package/specs/state-checkpoint-v1.schema.json +37 -0
- package/specs/trust-bundle-v1.schema.json +56 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
export const USAGE_EVENT_SCHEMA = 'enigma.usage_event.v1';
|
|
4
|
+
export const USAGE_AGGREGATE_SCHEMA = 'enigma.usage_aggregate.v1';
|
|
5
|
+
export const USAGE_METERING_PRODUCT_THESIS = 'Centralized high-performance memory service with permissionless access and settlement receipts; usage metering is deterministic, content-minimized, and does not claim token ROI or provider invoice savings.';
|
|
6
|
+
|
|
7
|
+
const SHA256_PREFIX = 'sha256:';
|
|
8
|
+
const SAFE_METRIC_KEYS = new Set([
|
|
9
|
+
'prompt_tokens',
|
|
10
|
+
'completion_tokens',
|
|
11
|
+
'input_tokens',
|
|
12
|
+
'output_tokens',
|
|
13
|
+
'baseline_prompt_tokens',
|
|
14
|
+
'optimized_prompt_tokens',
|
|
15
|
+
'memory_baseline_tokens',
|
|
16
|
+
'memory_optimized_tokens',
|
|
17
|
+
'memory_savings_tokens',
|
|
18
|
+
'billable_prompt_tokens',
|
|
19
|
+
'billable_completion_tokens',
|
|
20
|
+
'total_prompt_tokens',
|
|
21
|
+
'total_completion_tokens',
|
|
22
|
+
'total_memory_baseline_tokens',
|
|
23
|
+
'total_memory_optimized_tokens',
|
|
24
|
+
'total_memory_savings_tokens',
|
|
25
|
+
]);
|
|
26
|
+
const FORBIDDEN_KEY_RE = /(?:^|_)(?:raw|plaintext|plain_text|prompt|prompts|message|messages|text|content|document|documents|transcript|response|responses|provider_response|response_body|credential|credentials|api_key|secret|password|private_key)(?:$|_)/iu;
|
|
27
|
+
const SECRET_VALUE_RE = /(?:Bearer\s+[A-Za-z0-9._~+/=-]{12,}|Basic\s+[A-Za-z0-9+/=-]{12,}|-----BEGIN [A-Z ]*PRIVATE KEY-----|https?:\/\/[^\s/@]+:[^\s/@]+@|raw memory|private prompt|full transcript|decrypted capsule|sk-[A-Za-z0-9_-]{16,}|AKIA[0-9A-Z]{16})/iu;
|
|
28
|
+
|
|
29
|
+
function isPlainObject(value) {
|
|
30
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function requiredString(value, name) {
|
|
34
|
+
if (typeof value !== 'string' || value.trim() === '') throw new TypeError(`${name} must be a non-empty string`);
|
|
35
|
+
return value.trim();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function stringOrDefault(value, fallback) {
|
|
39
|
+
if (value === undefined || value === null || value === '') return fallback;
|
|
40
|
+
return requiredString(String(value), 'string');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function nonNegativeInteger(value, name) {
|
|
44
|
+
const number = Number(value ?? 0);
|
|
45
|
+
if (!Number.isSafeInteger(number) || number < 0) throw new TypeError(`${name} must be a non-negative integer`);
|
|
46
|
+
return number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function nonNegativeNumber(value, name) {
|
|
50
|
+
const number = Number(value ?? 0);
|
|
51
|
+
if (!Number.isFinite(number) || number < 0) throw new TypeError(`${name} must be a non-negative number`);
|
|
52
|
+
return number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isoTimestamp(value) {
|
|
56
|
+
const timestamp = stringOrDefault(value, new Date(0).toISOString());
|
|
57
|
+
if (Number.isNaN(Date.parse(timestamp))) throw new TypeError('timestamp must be ISO-parseable');
|
|
58
|
+
return timestamp;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function canonicalize(value) {
|
|
62
|
+
if (Array.isArray(value)) return value.map(canonicalize);
|
|
63
|
+
if (isPlainObject(value)) {
|
|
64
|
+
const out = {};
|
|
65
|
+
for (const key of Object.keys(value).sort()) out[key] = canonicalize(value[key]);
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function hashValue(value) {
|
|
72
|
+
return `${SHA256_PREFIX}${createHash('sha256').update(JSON.stringify(canonicalize(value))).digest('hex')}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function eventIdFrom(body) {
|
|
76
|
+
return `uevt_${hashValue(body).slice(SHA256_PREFIX.length, SHA256_PREFIX.length + 32)}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function aggregateIdFrom(body) {
|
|
80
|
+
return `uagg_${hashValue(body).slice(SHA256_PREFIX.length, SHA256_PREFIX.length + 32)}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function assertNoSensitivePayload(value, path = 'metering') {
|
|
84
|
+
if (typeof value === 'string') {
|
|
85
|
+
if (!/\.claim_boundary\[\d+\]$/.test(path) && SECRET_VALUE_RE.test(value)) throw new TypeError(`${path} contains secret-looking data`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
value.forEach((item, index) => assertNoSensitivePayload(item, `${path}[${index}]`));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (!isPlainObject(value)) return;
|
|
93
|
+
for (const [key, child] of Object.entries(value)) {
|
|
94
|
+
if (FORBIDDEN_KEY_RE.test(key) && !SAFE_METRIC_KEYS.has(key)) throw new TypeError(`${path}.${key} is not allowed in metering artifacts`);
|
|
95
|
+
assertNoSensitivePayload(child, `${path}.${key}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function normalizePricing(input = {}) {
|
|
100
|
+
const pricing = isPlainObject(input.pricing) ? input.pricing : input;
|
|
101
|
+
const inputPrice = nonNegativeNumber(
|
|
102
|
+
pricing.input_price_per_million_tokens ?? pricing.inputPricePerMillionTokens ?? pricing.price_per_million_tokens ?? pricing.pricePerMillionTokens,
|
|
103
|
+
'input_price_per_million_tokens'
|
|
104
|
+
);
|
|
105
|
+
const outputPrice = nonNegativeNumber(
|
|
106
|
+
pricing.output_price_per_million_tokens ?? pricing.outputPricePerMillionTokens ?? pricing.price_per_million_tokens ?? pricing.pricePerMillionTokens,
|
|
107
|
+
'output_price_per_million_tokens'
|
|
108
|
+
);
|
|
109
|
+
return Object.freeze({
|
|
110
|
+
currency: stringOrDefault(pricing.currency, 'USD'),
|
|
111
|
+
input_price_per_million_tokens: inputPrice,
|
|
112
|
+
output_price_per_million_tokens: outputPrice,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function costFor({ promptTokens, completionTokens, pricing }) {
|
|
117
|
+
return ((promptTokens / 1_000_000) * pricing.input_price_per_million_tokens)
|
|
118
|
+
+ ((completionTokens / 1_000_000) * pricing.output_price_per_million_tokens);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function createUsageEvent(input = {}) {
|
|
122
|
+
if (!isPlainObject(input)) throw new TypeError('createUsageEvent requires an options object');
|
|
123
|
+
assertNoSensitivePayload(input, 'input');
|
|
124
|
+
const tenantId = requiredString(input.tenant_id ?? input.tenantId, 'tenant_id');
|
|
125
|
+
const meterId = requiredString(input.meter_id ?? input.meterId ?? 'default', 'meter_id');
|
|
126
|
+
const provider = requiredString(input.provider, 'provider');
|
|
127
|
+
const model = requiredString(input.model, 'model');
|
|
128
|
+
const operation = requiredString(input.operation ?? 'memory.inference', 'operation');
|
|
129
|
+
const timestamp = isoTimestamp(input.timestamp ?? input.created_at ?? input.createdAt);
|
|
130
|
+
const promptTokens = nonNegativeInteger(input.prompt_tokens ?? input.promptTokens ?? input.input_tokens ?? input.inputTokens, 'prompt_tokens');
|
|
131
|
+
const completionTokens = nonNegativeInteger(input.completion_tokens ?? input.completionTokens ?? input.output_tokens ?? input.outputTokens, 'completion_tokens');
|
|
132
|
+
const memoryBaselineTokens = nonNegativeInteger(input.memory_baseline_tokens ?? input.memoryBaselineTokens ?? input.baseline_prompt_tokens ?? input.baselinePromptTokens ?? promptTokens, 'memory_baseline_tokens');
|
|
133
|
+
const memoryOptimizedTokens = nonNegativeInteger(input.memory_optimized_tokens ?? input.memoryOptimizedTokens ?? input.optimized_prompt_tokens ?? input.optimizedPromptTokens ?? promptTokens, 'memory_optimized_tokens');
|
|
134
|
+
if (memoryOptimizedTokens > memoryBaselineTokens) throw new RangeError('memory_optimized_tokens must be <= memory_baseline_tokens');
|
|
135
|
+
const pricing = normalizePricing(input.pricing ?? input);
|
|
136
|
+
const memorySavingsTokens = memoryBaselineTokens - memoryOptimizedTokens;
|
|
137
|
+
const costBeforeMemory = costFor({ promptTokens: memoryBaselineTokens, completionTokens, pricing });
|
|
138
|
+
const costAfterMemory = costFor({ promptTokens: memoryOptimizedTokens, completionTokens, pricing });
|
|
139
|
+
const eventBody = {
|
|
140
|
+
schema: USAGE_EVENT_SCHEMA,
|
|
141
|
+
product_thesis: USAGE_METERING_PRODUCT_THESIS,
|
|
142
|
+
tenant_id: tenantId,
|
|
143
|
+
meter_id: meterId,
|
|
144
|
+
provider,
|
|
145
|
+
model,
|
|
146
|
+
operation,
|
|
147
|
+
timestamp,
|
|
148
|
+
usage: {
|
|
149
|
+
prompt_tokens: promptTokens,
|
|
150
|
+
completion_tokens: completionTokens,
|
|
151
|
+
memory_baseline_tokens: memoryBaselineTokens,
|
|
152
|
+
memory_optimized_tokens: memoryOptimizedTokens,
|
|
153
|
+
memory_savings_tokens: memorySavingsTokens,
|
|
154
|
+
billable_prompt_tokens: memoryOptimizedTokens,
|
|
155
|
+
billable_completion_tokens: completionTokens,
|
|
156
|
+
},
|
|
157
|
+
pricing,
|
|
158
|
+
estimated_cost: {
|
|
159
|
+
currency: pricing.currency,
|
|
160
|
+
cost_before_memory: costBeforeMemory,
|
|
161
|
+
cost_after_memory: costAfterMemory,
|
|
162
|
+
estimated_memory_credit: costBeforeMemory - costAfterMemory,
|
|
163
|
+
},
|
|
164
|
+
settlement_boundary: {
|
|
165
|
+
permissionless_access: true,
|
|
166
|
+
settlement: 'external_or_offline_receipt_settlement',
|
|
167
|
+
proof_anchor: 'usage_hash_and_memory_commitments_only',
|
|
168
|
+
decentralized_inference_claim: false,
|
|
169
|
+
token_roi_claim: false,
|
|
170
|
+
provider_invoice_savings_claim: false,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
const event = Object.freeze({ ...eventBody, event_id: eventIdFrom(eventBody), event_hash: hashValue(eventBody) });
|
|
174
|
+
assertNoSensitivePayload(event, 'event');
|
|
175
|
+
return event;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function requireUsageEvent(event, index) {
|
|
179
|
+
if (!isPlainObject(event) || event.schema !== USAGE_EVENT_SCHEMA) throw new TypeError(`events[${index}] must be an enigma usage event`);
|
|
180
|
+
assertNoSensitivePayload(event, `events[${index}]`);
|
|
181
|
+
return event;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function addTotals(target, usage, cost) {
|
|
185
|
+
target.prompt_tokens += usage.prompt_tokens;
|
|
186
|
+
target.completion_tokens += usage.completion_tokens;
|
|
187
|
+
target.memory_baseline_tokens += usage.memory_baseline_tokens;
|
|
188
|
+
target.memory_optimized_tokens += usage.memory_optimized_tokens;
|
|
189
|
+
target.memory_savings_tokens += usage.memory_savings_tokens;
|
|
190
|
+
target.cost_before_memory += cost.cost_before_memory;
|
|
191
|
+
target.cost_after_memory += cost.cost_after_memory;
|
|
192
|
+
target.estimated_memory_credit += cost.estimated_memory_credit;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function emptyTotals(currency) {
|
|
196
|
+
return {
|
|
197
|
+
currency,
|
|
198
|
+
prompt_tokens: 0,
|
|
199
|
+
completion_tokens: 0,
|
|
200
|
+
memory_baseline_tokens: 0,
|
|
201
|
+
memory_optimized_tokens: 0,
|
|
202
|
+
memory_savings_tokens: 0,
|
|
203
|
+
cost_before_memory: 0,
|
|
204
|
+
cost_after_memory: 0,
|
|
205
|
+
estimated_memory_credit: 0,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function aggregateUsageEvents(input = {}) {
|
|
210
|
+
const args = Array.isArray(input) ? { events: input } : input;
|
|
211
|
+
if (!isPlainObject(args)) throw new TypeError('aggregateUsageEvents requires an options object or event array');
|
|
212
|
+
const events = Array.isArray(args.events) ? args.events.map(requireUsageEvent) : [];
|
|
213
|
+
if (events.length === 0) throw new TypeError('events must be non-empty');
|
|
214
|
+
const currency = events[0].estimated_cost.currency;
|
|
215
|
+
const tenantId = args.tenant_id ?? args.tenantId ?? (events.every((event) => event.tenant_id === events[0].tenant_id) ? events[0].tenant_id : 'mixed');
|
|
216
|
+
const totals = emptyTotals(currency);
|
|
217
|
+
const groups = new Map();
|
|
218
|
+
for (const event of events) {
|
|
219
|
+
if (event.estimated_cost.currency !== currency) throw new TypeError('all events must use the same currency');
|
|
220
|
+
addTotals(totals, event.usage, event.estimated_cost);
|
|
221
|
+
const key = `${event.provider}\u0000${event.model}`;
|
|
222
|
+
if (!groups.has(key)) groups.set(key, { provider: event.provider, model: event.model, event_count: 0, totals: emptyTotals(currency) });
|
|
223
|
+
const group = groups.get(key);
|
|
224
|
+
group.event_count += 1;
|
|
225
|
+
addTotals(group.totals, event.usage, event.estimated_cost);
|
|
226
|
+
}
|
|
227
|
+
const aggregateBody = {
|
|
228
|
+
schema: USAGE_AGGREGATE_SCHEMA,
|
|
229
|
+
product_thesis: USAGE_METERING_PRODUCT_THESIS,
|
|
230
|
+
tenant_id: requiredString(tenantId, 'tenant_id'),
|
|
231
|
+
meter_id: stringOrDefault(args.meter_id ?? args.meterId, 'aggregate'),
|
|
232
|
+
generated_at: isoTimestamp(args.generated_at ?? args.generatedAt),
|
|
233
|
+
event_count: events.length,
|
|
234
|
+
event_hashes: events.map((event) => event.event_hash),
|
|
235
|
+
totals,
|
|
236
|
+
by_provider_model: Array.from(groups.values()).sort((a, b) => (a.provider + a.model).localeCompare(b.provider + b.model)),
|
|
237
|
+
claim_boundary: [
|
|
238
|
+
'Estimated memory credit is deterministic metering math over supplied usage events, not a provider invoice guarantee.',
|
|
239
|
+
'No token ROI, token profit, decentralized inference, provider-side deletion, model forgetting, or compliance certification claim is made.',
|
|
240
|
+
'Usage events contain counts, commitments, and hashes only; raw prompts, completions, provider responses, transcripts, credentials, and decrypted memory are forbidden.',
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
const aggregate = Object.freeze({ ...aggregateBody, aggregate_id: aggregateIdFrom(aggregateBody), aggregate_hash: hashValue(aggregateBody) });
|
|
244
|
+
assertNoSensitivePayload(aggregate, 'aggregate');
|
|
245
|
+
return aggregate;
|
|
246
|
+
}
|