enigma-memory 0.1.13 → 0.1.15
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 +36 -17
- package/apps/cli/bin/enigma.mjs +3126 -2848
- package/deploy/docker-compose.local-production-simulation.yml +12 -10
- package/docs/benchmark-attestation-network.md +487 -487
- package/docs/benchmark-reproducibility.md +228 -227
- package/docs/demo-proof-network.md +275 -275
- package/docs/developer-ecosystem.md +223 -223
- package/docs/developer-proof-quickstart.md +325 -325
- package/docs/enigma-memory-ready-conformance.md +376 -376
- package/docs/hosted-cloud-product.md +10 -0
- package/docs/install-anywhere.md +34 -17
- package/docs/installers-and-desktop.md +9 -7
- package/docs/proof-network-build-notes.md +240 -240
- package/docs/proof-network.md +257 -257
- package/docs/sdk-api.md +324 -324
- package/docs/solana-devnet-acceptance.md +48 -0
- package/docs/solana-proof-rail.md +453 -453
- package/examples/ci/github-actions.yml +6 -8
- package/package.json +272 -265
- package/packages/mcp-server/src/index.js +1185 -1185
- package/packages/passport/src/index.js +9 -5
- package/scripts/build-benchmark-proof-release.mjs +391 -0
- package/scripts/build-goal-completion-audit.mjs +11 -5
- package/scripts/build-hosted-api-key-lifecycle.mjs +274 -274
- package/scripts/build-hosted-customer-lifecycle.mjs +456 -456
- package/scripts/build-installer-assets.mjs +389 -273
- package/scripts/build-production-handoff-packet.mjs +7 -6
- package/scripts/build-production-unblocker.mjs +409 -0
- package/scripts/build-proof-network-packet.mjs +213 -213
- package/scripts/release-audit.mjs +71 -2
- package/scripts/run-standard-memory-benchmarks.mjs +1070 -1070
- package/scripts/wait-for-backend-ready.mjs +4 -2
|
@@ -123,11 +123,14 @@ function candidateRelevanceTokens(candidate) {
|
|
|
123
123
|
return tokens;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
|
|
127
|
+
function tokenOverlapScore(queryTokens, memoryTokens) {
|
|
128
|
+
if (queryTokens.size === 0) return 0;
|
|
129
|
+
let overlap = 0;
|
|
130
|
+
for (const token of queryTokens) {
|
|
131
|
+
if (memoryTokens.has(token)) overlap += 1;
|
|
129
132
|
}
|
|
130
|
-
return
|
|
133
|
+
return overlap / queryTokens.size;
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
function strictQueryRelevance(args) {
|
|
@@ -148,7 +151,8 @@ function relevanceCandidateSet(args, candidates) {
|
|
|
148
151
|
|
|
149
152
|
const relevant = [];
|
|
150
153
|
for (const candidate of candidates) {
|
|
151
|
-
|
|
154
|
+
const relevance = tokenOverlapScore(queryTokens, candidateRelevanceTokens(candidate));
|
|
155
|
+
if (relevance > 0) relevant.push({ ...candidate, importance: Math.max(candidate.importance ?? 0, relevance) });
|
|
152
156
|
}
|
|
153
157
|
if (relevant.length > 0) return relevant;
|
|
154
158
|
return strictQueryRelevance(args) ? [] : candidates;
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { basename, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
createBenchmarkAttestation,
|
|
9
|
+
createProofNetworkPacket,
|
|
10
|
+
sha256Json,
|
|
11
|
+
validateBenchmarkAttestation,
|
|
12
|
+
validateProofNetworkPacket,
|
|
13
|
+
} from '../packages/proof-network/src/index.js';
|
|
14
|
+
|
|
15
|
+
export const BENCHMARK_PROOF_RELEASE_SCHEMA = 'enigma.benchmark_proof_release.v1';
|
|
16
|
+
export const SCORE_COMMITMENT_SCHEMA = 'enigma.benchmark_proof_release.score_commitment.v1';
|
|
17
|
+
export const DEFAULT_BENCHMARK_PROOF_OUT_DIR = '.enigma/benchmark-proof-release';
|
|
18
|
+
|
|
19
|
+
const ATTESTATION_FILE = 'benchmark-attestation.json';
|
|
20
|
+
const PROOF_PACKET_FILE = 'benchmark-proof-packet.json';
|
|
21
|
+
const RELEASE_MANIFEST_FILE = 'benchmark-proof-release.json';
|
|
22
|
+
const SHA256_PREFIX = 'sha256:';
|
|
23
|
+
const PUBLIC_REF_RE = /^[a-z0-9][a-z0-9._:/@+-]{2,191}$/u;
|
|
24
|
+
const SCORE_KEY_RE = /^[a-z][a-z0-9_.:-]{1,63}$/u;
|
|
25
|
+
const PRIVATE_REPORT_KEY_RE = /(?:^|_)(?:raw_memory|memory_plaintext|plaintext|plain_text|prompt|prompts|conversation|conversations|message|messages|content|body|payload|payloads|document|documents|transcript|transcripts|completion|completions|embedding|embeddings|provider_response|provider_responses|response_body|credential|credentials|api_key|secret|password|private_key|seed|seed_phrase|mnemonic|tenant_name|customer_name|organization_name|org_name|account_id)(?:$|_)/iu;
|
|
26
|
+
const ALLOWED_FALSE_REPORT_KEYS = new Set([
|
|
27
|
+
'raw_private_memory_plaintext_included',
|
|
28
|
+
'raw_question_text_included',
|
|
29
|
+
'raw_answer_text_included',
|
|
30
|
+
'raw_conversation_text_included',
|
|
31
|
+
'public_question_text_included',
|
|
32
|
+
'public_answer_text_included',
|
|
33
|
+
'provider_deletion_claim',
|
|
34
|
+
'model_forgetting_claim',
|
|
35
|
+
'roi_or_provider_invoice_savings_claim',
|
|
36
|
+
'compliance_certification_claim',
|
|
37
|
+
'benchmark_leadership_claim',
|
|
38
|
+
'external_provider_calls',
|
|
39
|
+
'llm_answer_accuracy_scored',
|
|
40
|
+
'raw_benchmark_body_included',
|
|
41
|
+
'report_body_copied',
|
|
42
|
+
'raw_memory_included',
|
|
43
|
+
'prompts_included',
|
|
44
|
+
'transcripts_included',
|
|
45
|
+
'provider_responses_included',
|
|
46
|
+
'provider_answer_accuracy_claim',
|
|
47
|
+
'competitor_performance_claim',
|
|
48
|
+
'solana_submission_claim',
|
|
49
|
+
'roi_or_profit_claim',
|
|
50
|
+
'provider_invoice_savings_claim',
|
|
51
|
+
'hosted_saas_claim',
|
|
52
|
+
]);
|
|
53
|
+
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/@]+@|sk-[A-Za-z0-9_-]{16,}|AKIA[0-9A-Z]{16}|(?:seed phrase|mnemonic phrase|raw memory|private prompt|full transcript|provider response|embedding vector))/iu;
|
|
54
|
+
const ABSOLUTE_LOCAL_PATH_RE = /^(?:[A-Za-z]:[\\/]|\\\\|\/(?:Users|home|tmp|var|etc|mnt|Volumes)\b)/u;
|
|
55
|
+
const CLAIM_SCORE_KEY_RE = /(?:provider|competitor|roi|profit|savings|solana|transaction|answer_accuracy|leaderboard)/iu;
|
|
56
|
+
|
|
57
|
+
class UsageError extends Error {
|
|
58
|
+
constructor(message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = 'UsageError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function readRequiredValue(argv, index, flag) {
|
|
65
|
+
const value = argv[index + 1];
|
|
66
|
+
if (value === undefined || value.startsWith('--')) throw new UsageError(`${flag} requires a value`);
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function publicString(value, label) {
|
|
71
|
+
if (typeof value !== 'string' || value.trim() === '') throw new UsageError(`${label} must be a non-empty public value`);
|
|
72
|
+
const normalized = value.trim();
|
|
73
|
+
if (SECRET_VALUE_RE.test(normalized)) throw new UsageError(`${label} contains private or secret-looking material`);
|
|
74
|
+
if (ABSOLUTE_LOCAL_PATH_RE.test(normalized)) throw new UsageError(`${label} must not be a local absolute path`);
|
|
75
|
+
return normalized;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function pathString(value, label) {
|
|
79
|
+
if (typeof value !== 'string' || value.trim() === '') throw new UsageError(`${label} must be a non-empty path`);
|
|
80
|
+
const normalized = value.trim();
|
|
81
|
+
if (SECRET_VALUE_RE.test(normalized)) throw new UsageError(`${label} contains private or secret-looking material`);
|
|
82
|
+
return normalized;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function publicRef(value, label) {
|
|
86
|
+
const normalized = publicString(value, label);
|
|
87
|
+
if (!PUBLIC_REF_RE.test(normalized)) throw new UsageError(`${label} must be a lowercase public ref using letters, numbers, . _ : / @ + or -`);
|
|
88
|
+
return normalized;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function parseScore(raw) {
|
|
92
|
+
const normalized = publicString(raw, 'score');
|
|
93
|
+
const equals = normalized.indexOf('=');
|
|
94
|
+
if (equals <= 0 || equals === normalized.length - 1) throw new UsageError('--score must use key=value');
|
|
95
|
+
const key = normalized.slice(0, equals).trim();
|
|
96
|
+
const value = normalized.slice(equals + 1).trim();
|
|
97
|
+
if (!SCORE_KEY_RE.test(key)) throw new UsageError('score key must be lowercase and use letters, numbers, . _ : or -');
|
|
98
|
+
if (CLAIM_SCORE_KEY_RE.test(key)) throw new UsageError('score key must not imply provider accuracy, competitor performance, Solana submission, ROI, savings, profit, or leaderboard claims');
|
|
99
|
+
publicString(value, `score ${key}`);
|
|
100
|
+
return Object.freeze({ key, value });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function parseArgs(argv = process.argv.slice(2)) {
|
|
104
|
+
const args = {
|
|
105
|
+
report: undefined,
|
|
106
|
+
datasetRef: undefined,
|
|
107
|
+
runnerRef: undefined,
|
|
108
|
+
packageRef: undefined,
|
|
109
|
+
scores: [],
|
|
110
|
+
outDir: DEFAULT_BENCHMARK_PROOF_OUT_DIR,
|
|
111
|
+
help: false,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
115
|
+
const raw = argv[index];
|
|
116
|
+
const equalsIndex = raw.indexOf('=');
|
|
117
|
+
const flag = equalsIndex > 0 ? raw.slice(0, equalsIndex) : raw;
|
|
118
|
+
const inlineValue = equalsIndex > 0 ? raw.slice(equalsIndex + 1) : undefined;
|
|
119
|
+
const value = () => {
|
|
120
|
+
if (inlineValue !== undefined) return inlineValue;
|
|
121
|
+
const next = readRequiredValue(argv, index, flag);
|
|
122
|
+
index += 1;
|
|
123
|
+
return next;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
if (flag === '--help' || flag === '-h') args.help = true;
|
|
127
|
+
else if (flag === '--report') args.report = pathString(value(), 'report path');
|
|
128
|
+
else if (flag === '--dataset-ref') args.datasetRef = publicRef(value(), 'dataset ref');
|
|
129
|
+
else if (flag === '--runner-ref') args.runnerRef = publicRef(value(), 'runner ref');
|
|
130
|
+
else if (flag === '--package-ref') args.packageRef = publicRef(value(), 'package ref');
|
|
131
|
+
else if (flag === '--score') args.scores.push(parseScore(value()));
|
|
132
|
+
else if (flag === '--out-dir') args.outDir = pathString(value(), 'out dir');
|
|
133
|
+
else throw new UsageError(`unknown option ${raw}; use --help`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return Object.freeze({ ...args, scores: Object.freeze(args.scores) });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function usage() {
|
|
140
|
+
return `Usage: node scripts/build-benchmark-proof-release.mjs --report <path> --dataset-ref <ref> --runner-ref <ref> --package-ref <ref> [--score key=value ...] [--out-dir <dir>]
|
|
141
|
+
|
|
142
|
+
Builds a dependency-free, local benchmark proof release from an existing public-safe benchmark report. The report file is parsed for public-safety checks and hashed, but its body and local path are never copied into the attestation or proof packet. The generated artifacts are local benchmark attestation/proof only: no API calls, provider answer-accuracy claims, competitor performance claims, Solana submissions, hosted SaaS claims, ROI/profit/savings claims, raw memory, prompts, transcripts, embeddings, credentials, account ids, private keys, or provider responses are written.
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function requireArgs(args) {
|
|
147
|
+
const missing = [];
|
|
148
|
+
if (args.report === undefined) missing.push('--report');
|
|
149
|
+
if (args.datasetRef === undefined) missing.push('--dataset-ref');
|
|
150
|
+
if (args.runnerRef === undefined) missing.push('--runner-ref');
|
|
151
|
+
if (args.packageRef === undefined) missing.push('--package-ref');
|
|
152
|
+
if (missing.length > 0) throw new UsageError(`missing required option(s): ${missing.join(', ')}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function sha256Buffer(buffer) {
|
|
156
|
+
return `${SHA256_PREFIX}${createHash('sha256').update(buffer).digest('hex')}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function isPlainObject(value) {
|
|
160
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function assertPublicReportPayload(value, path = 'report') {
|
|
164
|
+
if (typeof value === 'string') {
|
|
165
|
+
if (SECRET_VALUE_RE.test(value)) throw new UsageError(`${path} contains private or secret-looking material`);
|
|
166
|
+
if (ABSOLUTE_LOCAL_PATH_RE.test(value)) throw new UsageError(`${path} contains a local absolute path`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (Array.isArray(value)) {
|
|
170
|
+
value.forEach((item, index) => assertPublicReportPayload(item, `${path}[${index}]`));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (!isPlainObject(value)) return;
|
|
174
|
+
for (const [key, child] of Object.entries(value)) {
|
|
175
|
+
if (PRIVATE_REPORT_KEY_RE.test(key)) {
|
|
176
|
+
if (!ALLOWED_FALSE_REPORT_KEYS.has(key) || child !== false) throw new UsageError(`${path}.${key} is not allowed in public benchmark proof artifacts`);
|
|
177
|
+
}
|
|
178
|
+
assertPublicReportPayload(child, `${path}.${key}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function parseJsonReport(bytes) {
|
|
183
|
+
try {
|
|
184
|
+
return JSON.parse(bytes.toString('utf8'));
|
|
185
|
+
} catch {
|
|
186
|
+
throw new UsageError('report must be valid JSON');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function reportSchema(report) {
|
|
191
|
+
if (!isPlainObject(report)) throw new UsageError('report must be a JSON object');
|
|
192
|
+
if (typeof report.schema !== 'string' || report.schema.trim() === '') throw new UsageError('report.schema must be a non-empty string');
|
|
193
|
+
if (report.public_safe !== true) throw new UsageError('report.public_safe must be true');
|
|
194
|
+
assertPublicReportPayload(report);
|
|
195
|
+
return report.schema;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function nonNegativeInteger(value) {
|
|
199
|
+
return Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function sampleCountFromReport(report) {
|
|
203
|
+
if (Array.isArray(report.datasets)) {
|
|
204
|
+
let total = 0;
|
|
205
|
+
for (const row of report.datasets) {
|
|
206
|
+
total += nonNegativeInteger(row?.question_count) ?? nonNegativeInteger(row?.item_count) ?? 0;
|
|
207
|
+
}
|
|
208
|
+
if (total > 0) return total;
|
|
209
|
+
}
|
|
210
|
+
return nonNegativeInteger(report.metrics?.qa?.question_count)
|
|
211
|
+
?? nonNegativeInteger(report.fixture?.question_count)
|
|
212
|
+
?? nonNegativeInteger(report.fixture?.session_count)
|
|
213
|
+
?? 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function slugRefPart(value) {
|
|
217
|
+
return String(value).toLowerCase().replace(/[^a-z0-9._:/@+-]+/gu, '-').replace(/^-+|-+$/gu, '') || 'benchmark-report';
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function scoreCommitments(scores, reportHash) {
|
|
221
|
+
if (scores.length === 0) {
|
|
222
|
+
const fallback = Object.freeze({
|
|
223
|
+
schema: SCORE_COMMITMENT_SCHEMA,
|
|
224
|
+
key: 'report_hash_only',
|
|
225
|
+
value: reportHash,
|
|
226
|
+
report_body_copied: false,
|
|
227
|
+
});
|
|
228
|
+
return Object.freeze([{ ...fallback, score_hash: sha256Json(fallback) }]);
|
|
229
|
+
}
|
|
230
|
+
return Object.freeze(scores.map((score) => {
|
|
231
|
+
const body = Object.freeze({
|
|
232
|
+
schema: SCORE_COMMITMENT_SCHEMA,
|
|
233
|
+
key: score.key,
|
|
234
|
+
value: score.value,
|
|
235
|
+
report_body_copied: false,
|
|
236
|
+
});
|
|
237
|
+
return Object.freeze({ ...body, score_hash: sha256Json(body) });
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function assertValidation(validation, label) {
|
|
242
|
+
if (validation?.ok !== true) throw new Error(`${label} validation failed: ${(validation?.errors ?? ['unknown error']).join('; ')}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function releaseManifest({ generatedAt, reportHash, schema, args, commitments, attestation, packet }) {
|
|
246
|
+
const manifest = {
|
|
247
|
+
schema: BENCHMARK_PROOF_RELEASE_SCHEMA,
|
|
248
|
+
generated_at: generatedAt,
|
|
249
|
+
local_benchmark_attestation_only: true,
|
|
250
|
+
api_calls_made: false,
|
|
251
|
+
report: {
|
|
252
|
+
report_hash: reportHash,
|
|
253
|
+
report_schema: schema,
|
|
254
|
+
report_public_safe: true,
|
|
255
|
+
report_body_copied: false,
|
|
256
|
+
report_path_copied: false,
|
|
257
|
+
},
|
|
258
|
+
refs: {
|
|
259
|
+
dataset_ref: args.datasetRef,
|
|
260
|
+
runner_ref: args.runnerRef,
|
|
261
|
+
package_ref: args.packageRef,
|
|
262
|
+
},
|
|
263
|
+
score_commitments: commitments,
|
|
264
|
+
claim_boundaries: {
|
|
265
|
+
provider_answer_accuracy_claim: false,
|
|
266
|
+
competitor_performance_claim: false,
|
|
267
|
+
solana_submission_claim: false,
|
|
268
|
+
transaction_submitted: false,
|
|
269
|
+
roi_or_profit_claim: false,
|
|
270
|
+
provider_invoice_savings_claim: false,
|
|
271
|
+
hosted_saas_claim: false,
|
|
272
|
+
raw_benchmark_body_included: false,
|
|
273
|
+
raw_memory_included: false,
|
|
274
|
+
prompts_included: false,
|
|
275
|
+
transcripts_included: false,
|
|
276
|
+
provider_responses_included: false,
|
|
277
|
+
},
|
|
278
|
+
artifacts: {
|
|
279
|
+
attestation_file: ATTESTATION_FILE,
|
|
280
|
+
attestation_hash: attestation.benchmark_attestation_hash,
|
|
281
|
+
proof_packet_file: PROOF_PACKET_FILE,
|
|
282
|
+
proof_packet_hash: packet.proof_network_packet_hash,
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
return manifest;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function outputLabel(outDir) {
|
|
289
|
+
const normalized = outDir.replace(/\\/gu, '/');
|
|
290
|
+
if (ABSOLUTE_LOCAL_PATH_RE.test(outDir) || normalized.split('/').includes('..')) return '<redacted-out-dir>';
|
|
291
|
+
return normalized;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function readReportBytes(path) {
|
|
295
|
+
try {
|
|
296
|
+
return await readFile(path);
|
|
297
|
+
} catch {
|
|
298
|
+
throw new Error('failed to read benchmark report');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export async function buildBenchmarkProofRelease(args, options = {}) {
|
|
303
|
+
requireArgs(args);
|
|
304
|
+
const generatedAt = options.generated_at ?? options.generatedAt ?? new Date().toISOString();
|
|
305
|
+
const bytes = await readReportBytes(args.report);
|
|
306
|
+
const reportHash = sha256Buffer(bytes);
|
|
307
|
+
const report = parseJsonReport(bytes);
|
|
308
|
+
const schema = reportSchema(report);
|
|
309
|
+
const commitments = scoreCommitments(args.scores, reportHash);
|
|
310
|
+
const metricRoots = commitments.map((score) => score.score_hash);
|
|
311
|
+
|
|
312
|
+
const attestation = createBenchmarkAttestation({
|
|
313
|
+
attested_at: generatedAt,
|
|
314
|
+
benchmark_ref: `benchmark:${slugRefPart(schema)}`,
|
|
315
|
+
dataset_ref: args.datasetRef,
|
|
316
|
+
runner_ref: args.runnerRef,
|
|
317
|
+
package_ref: args.packageRef,
|
|
318
|
+
report_hash: reportHash,
|
|
319
|
+
metric_roots: metricRoots,
|
|
320
|
+
sample_count: sampleCountFromReport(report),
|
|
321
|
+
run_count: 1,
|
|
322
|
+
});
|
|
323
|
+
assertValidation(validateBenchmarkAttestation(attestation), 'benchmark attestation');
|
|
324
|
+
|
|
325
|
+
const packet = createProofNetworkPacket({
|
|
326
|
+
attestations: [attestation],
|
|
327
|
+
packet_ref: `benchmark-proof-release:${sha256Json([attestation.benchmark_attestation_hash, reportHash]).slice(SHA256_PREFIX.length, SHA256_PREFIX.length + 32)}`,
|
|
328
|
+
created_at: generatedAt,
|
|
329
|
+
});
|
|
330
|
+
assertValidation(validateProofNetworkPacket(packet), 'proof packet');
|
|
331
|
+
|
|
332
|
+
const manifest = releaseManifest({ generatedAt, reportHash, schema, args, commitments, attestation, packet });
|
|
333
|
+
assertPublicReportPayload(manifest, 'manifest');
|
|
334
|
+
|
|
335
|
+
return Object.freeze({
|
|
336
|
+
schema: BENCHMARK_PROOF_RELEASE_SCHEMA,
|
|
337
|
+
generated_at: generatedAt,
|
|
338
|
+
report_hash: reportHash,
|
|
339
|
+
report_schema: schema,
|
|
340
|
+
attestation,
|
|
341
|
+
packet,
|
|
342
|
+
manifest,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export async function writeBenchmarkProofRelease(release, outDir) {
|
|
347
|
+
const root = resolve(outDir);
|
|
348
|
+
try {
|
|
349
|
+
await mkdir(root, { recursive: true });
|
|
350
|
+
const attestationPath = resolve(root, ATTESTATION_FILE);
|
|
351
|
+
const packetPath = resolve(root, PROOF_PACKET_FILE);
|
|
352
|
+
const manifestPath = resolve(root, RELEASE_MANIFEST_FILE);
|
|
353
|
+
await writeFile(attestationPath, `${JSON.stringify(release.attestation, null, 2)}\n`, 'utf8');
|
|
354
|
+
await writeFile(packetPath, `${JSON.stringify(release.packet, null, 2)}\n`, 'utf8');
|
|
355
|
+
await writeFile(manifestPath, `${JSON.stringify(release.manifest, null, 2)}\n`, 'utf8');
|
|
356
|
+
return Object.freeze({
|
|
357
|
+
attestation_file: basename(attestationPath),
|
|
358
|
+
proof_packet_file: basename(packetPath),
|
|
359
|
+
release_manifest_file: basename(manifestPath),
|
|
360
|
+
});
|
|
361
|
+
} catch {
|
|
362
|
+
throw new Error('failed to write benchmark proof release artifacts');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
367
|
+
const args = parseArgs(argv);
|
|
368
|
+
if (args.help) {
|
|
369
|
+
process.stdout.write(usage());
|
|
370
|
+
return 0;
|
|
371
|
+
}
|
|
372
|
+
const release = await buildBenchmarkProofRelease(args);
|
|
373
|
+
const files = await writeBenchmarkProofRelease(release, args.outDir);
|
|
374
|
+
process.stdout.write(`${JSON.stringify({
|
|
375
|
+
ok: true,
|
|
376
|
+
schema: BENCHMARK_PROOF_RELEASE_SCHEMA,
|
|
377
|
+
out_dir: outputLabel(args.outDir),
|
|
378
|
+
...files,
|
|
379
|
+
report_hash: release.report_hash,
|
|
380
|
+
report_body_copied: false,
|
|
381
|
+
api_calls_made: false,
|
|
382
|
+
}, null, 2)}\n`);
|
|
383
|
+
return 0;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
387
|
+
main().catch((error) => {
|
|
388
|
+
process.stderr.write(`${error.name ?? 'Error'}: ${error.message ?? 'failed to build benchmark proof release'}\n`);
|
|
389
|
+
process.exitCode = 1;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
@@ -119,9 +119,14 @@ async function readText(path) {
|
|
|
119
119
|
return await readFile(path, 'utf8');
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
async function readJsonPath(path) {
|
|
122
|
+
async function readJsonPath(path, label = 'JSON input') {
|
|
123
123
|
if (!path) return null;
|
|
124
|
-
|
|
124
|
+
try {
|
|
125
|
+
return JSON.parse(await readFile(resolve(path), 'utf8'));
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (error instanceof SyntaxError) throw new UsageError(`${label} JSON is invalid`);
|
|
128
|
+
throw new UsageError(`${label} JSON could not be read`);
|
|
129
|
+
}
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
function nextActionsForGoalAudit(nextActions, workerInspect) {
|
|
@@ -312,13 +317,13 @@ export async function buildGoalCompletionAudit(input = {}, options = {}) {
|
|
|
312
317
|
const liveUrl = optionalText(input.liveUrl, domain ? `https://${domain}/` : null);
|
|
313
318
|
const expectTitle = optionalText(input.expectTitle, 'Enigma');
|
|
314
319
|
const accountId = optionalText(input.accountId, '<cloudflare-account-id>');
|
|
320
|
+
const workerInspect = await readJsonPath(input.workerInspect, 'worker inspection');
|
|
315
321
|
const docs = await inspectDocs();
|
|
316
322
|
const handoff = await buildProductionHandoffPacket({ site, projectName, domain, liveUrl, expectTitle, infrastructureReadiness: input.infrastructureReadiness, operatorAcceptancePacket: input.operatorAcceptancePacket, releaseAudit: input.releaseAudit }, {
|
|
317
323
|
env,
|
|
318
324
|
generated_at: generatedAt,
|
|
319
325
|
fetchImpl: options.fetchImpl ?? globalThis.fetch,
|
|
320
326
|
});
|
|
321
|
-
const workerInspect = await readJsonPath(input.workerInspect);
|
|
322
327
|
const tokenPolicy = buildCloudflareTokenPolicy({
|
|
323
328
|
mode: 'all',
|
|
324
329
|
accountId,
|
|
@@ -392,7 +397,8 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
392
397
|
else process.stdout.write(`${JSON.stringify(result.json, null, 2)}\n`);
|
|
393
398
|
} catch (error) {
|
|
394
399
|
const message = error instanceof Error ? error.message : String(error);
|
|
395
|
-
|
|
396
|
-
process.
|
|
400
|
+
const usageError = error instanceof UsageError || error?.name === 'UsageError';
|
|
401
|
+
process.stdout.write(`${JSON.stringify({ schema: GOAL_COMPLETION_AUDIT_SCHEMA, ok: false, error: { code: usageError ? 'USAGE_ERROR' : 'GOAL_COMPLETION_AUDIT_ERROR', message } }, null, 2)}\n`);
|
|
402
|
+
process.exitCode = usageError ? 2 : 1;
|
|
397
403
|
}
|
|
398
404
|
}
|