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.
Files changed (32) hide show
  1. package/README.md +36 -17
  2. package/apps/cli/bin/enigma.mjs +3126 -2848
  3. package/deploy/docker-compose.local-production-simulation.yml +12 -10
  4. package/docs/benchmark-attestation-network.md +487 -487
  5. package/docs/benchmark-reproducibility.md +228 -227
  6. package/docs/demo-proof-network.md +275 -275
  7. package/docs/developer-ecosystem.md +223 -223
  8. package/docs/developer-proof-quickstart.md +325 -325
  9. package/docs/enigma-memory-ready-conformance.md +376 -376
  10. package/docs/hosted-cloud-product.md +10 -0
  11. package/docs/install-anywhere.md +34 -17
  12. package/docs/installers-and-desktop.md +9 -7
  13. package/docs/proof-network-build-notes.md +240 -240
  14. package/docs/proof-network.md +257 -257
  15. package/docs/sdk-api.md +324 -324
  16. package/docs/solana-devnet-acceptance.md +48 -0
  17. package/docs/solana-proof-rail.md +453 -453
  18. package/examples/ci/github-actions.yml +6 -8
  19. package/package.json +272 -265
  20. package/packages/mcp-server/src/index.js +1185 -1185
  21. package/packages/passport/src/index.js +9 -5
  22. package/scripts/build-benchmark-proof-release.mjs +391 -0
  23. package/scripts/build-goal-completion-audit.mjs +11 -5
  24. package/scripts/build-hosted-api-key-lifecycle.mjs +274 -274
  25. package/scripts/build-hosted-customer-lifecycle.mjs +456 -456
  26. package/scripts/build-installer-assets.mjs +389 -273
  27. package/scripts/build-production-handoff-packet.mjs +7 -6
  28. package/scripts/build-production-unblocker.mjs +409 -0
  29. package/scripts/build-proof-network-packet.mjs +213 -213
  30. package/scripts/release-audit.mjs +71 -2
  31. package/scripts/run-standard-memory-benchmarks.mjs +1070 -1070
  32. package/scripts/wait-for-backend-ready.mjs +4 -2
@@ -344,6 +344,13 @@ export async function buildProductionHandoffPacket(input = {}, options = {}) {
344
344
  const liveUrl = optionalText(input.liveUrl, domain ? `https://${domain}/` : null);
345
345
  const expectTitle = optionalText(input.expectTitle, 'Enigma');
346
346
 
347
+ const providedInfrastructure = requireInfrastructureReadinessResult(await loadInfrastructureReadiness(input));
348
+ const operatorPacket = await loadOperatorAcceptancePacket(input) ?? await buildOperatorAcceptancePacket({ generated_at: generatedAt });
349
+ assertNoSecretOutput('operator acceptance packet', operatorPacket);
350
+ const operatorAcceptance = validateOperatorAcceptancePacket(operatorPacket, { generated_at: generatedAt });
351
+ if (operatorAcceptance.ok === true) requireInfrastructureReadinessResult(operatorPacket.readiness);
352
+ const providedReleaseAudit = requireReleaseAuditResult(await loadReleaseAudit(input));
353
+
347
354
  const pages = await buildCloudflarePagesReleasePacket({
348
355
  site,
349
356
  projectName,
@@ -356,7 +363,6 @@ export async function buildProductionHandoffPacket(input = {}, options = {}) {
356
363
  fetchImpl: options.fetchImpl ?? globalThis.fetch,
357
364
  });
358
365
 
359
- const providedInfrastructure = requireInfrastructureReadinessResult(await loadInfrastructureReadiness(input));
360
366
  const infrastructure = providedInfrastructure ?? await runInfrastructureReadiness({
361
367
  manifest: await buildProductionReadinessManifest({
362
368
  env,
@@ -369,11 +375,6 @@ export async function buildProductionHandoffPacket(input = {}, options = {}) {
369
375
  now: new Date(generatedAt),
370
376
  fetchImpl: options.fetchImpl ?? globalThis.fetch,
371
377
  });
372
- const operatorPacket = await loadOperatorAcceptancePacket(input) ?? await buildOperatorAcceptancePacket({ generated_at: generatedAt });
373
- assertNoSecretOutput('operator acceptance packet', operatorPacket);
374
- const operatorAcceptance = validateOperatorAcceptancePacket(operatorPacket, { generated_at: generatedAt });
375
- if (operatorAcceptance.ok === true) requireInfrastructureReadinessResult(operatorPacket.readiness);
376
- const providedReleaseAudit = requireReleaseAuditResult(await loadReleaseAudit(input));
377
378
 
378
379
  const hostedProbe = buildHostedProbeWorkerBundle({ generated_at: generatedAt });
379
380
  const pageSummary = summarizePages(pages);
@@ -0,0 +1,409 @@
1
+ #!/usr/bin/env node
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ export const PRODUCTION_UNBLOCKER_SCHEMA = 'enigma.production_unblocker.v1';
7
+ export const CURRENT_PUBLIC_PACKAGE_VERSION = '0.1.14';
8
+
9
+ const STATUS_VALUES = Object.freeze([
10
+ 'ready_now',
11
+ 'contract_ready',
12
+ 'blocked_external_dependency',
13
+ 'operator_evidence_required',
14
+ ]);
15
+
16
+ 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}|cf-[A-Za-z0-9_-]{12,})/iu;
17
+ const LOCAL_PATH_RE = /(?<![A-Za-z])(?:[A-Za-z]:[\\/]|\\\\[^\\/]+[\\/][^\\/]+|\/(?:Users|home|tmp|var|etc|mnt|Volumes)\/[^\s"']+)/u;
18
+ const FORBIDDEN_KEY_RE = /(?:password|passwd|pwd|api[_-]?key|private[_-]?key|secret|token|account[_-]?id|raw[_-]?memory|plaintext|plain[_-]?text|prompt|completion|transcript|embedding|provider[_-]?response|cookie|session|seed|mnemonic|wallet[_-]?private|private[_-]?path|customer[_-]?name|tenant[_-]?name)/iu;
19
+ const SAFE_FIELD_NAMES = new Set([
20
+ 'credentials_required',
21
+ 'credentials_used',
22
+ 'requires_credentials',
23
+ 'secret_values_printed',
24
+ 'transaction_submitted',
25
+ 'raw_memory_on_chain',
26
+ 'raw_memory_in_public_artifacts',
27
+ 'hosted_saas_live',
28
+ 'hosted_cloud_live_claim',
29
+ 'solana_mainnet_live_claim',
30
+ 'solana_transaction_claim',
31
+ 'provider_response_claim',
32
+ 'model_forgetting_claim',
33
+ 'provider_deletion_claim',
34
+ 'benchmark_leadership_claim',
35
+ 'token_roi_claim',
36
+ 'token_profit_claim',
37
+ 'provider_invoice_savings_claim',
38
+ 'external_provider_called',
39
+ ]);
40
+
41
+ class UsageError extends Error {
42
+ constructor(message) {
43
+ super(message);
44
+ this.name = 'UsageError';
45
+ }
46
+ }
47
+
48
+ function isPlainObject(value) {
49
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
50
+ }
51
+
52
+ function assertPublicSafe(value, path = 'production_unblocker') {
53
+ if (typeof value === 'string') {
54
+ if (SECRET_VALUE_RE.test(value)) throw new Error(`${path} contains secret-looking material`);
55
+ if (LOCAL_PATH_RE.test(value)) throw new Error(`${path} contains a local absolute path`);
56
+ return;
57
+ }
58
+ if (Array.isArray(value)) {
59
+ value.forEach((item, index) => assertPublicSafe(item, `${path}[${index}]`));
60
+ return;
61
+ }
62
+ if (!isPlainObject(value)) return;
63
+ for (const [key, child] of Object.entries(value)) {
64
+ if (FORBIDDEN_KEY_RE.test(key) && !SAFE_FIELD_NAMES.has(key)) throw new Error(`${path}.${key} is not allowed in public production unblocker input`);
65
+ assertPublicSafe(child, `${path}.${key}`);
66
+ }
67
+ }
68
+
69
+ function publicPackageSummary(packageJson = {}, options = {}) {
70
+ const bins = isPlainObject(packageJson.bin) ? Object.keys(packageJson.bin).sort() : [];
71
+ const sourceVersion = typeof packageJson.version === 'string' ? packageJson.version : null;
72
+ const currentPublicVersion = typeof options.currentPublicVersion === 'string' ? options.currentPublicVersion : CURRENT_PUBLIC_PACKAGE_VERSION;
73
+ return {
74
+ name: typeof packageJson.name === 'string' ? packageJson.name : 'enigma-memory',
75
+ version: sourceVersion,
76
+ source_version: sourceVersion,
77
+ current_public_version: currentPublicVersion,
78
+ node: typeof packageJson.engines?.node === 'string' ? packageJson.engines.node : '>=24',
79
+ bins,
80
+ };
81
+ }
82
+
83
+ const ALLOWED_INPUT_KEYS = new Set(['packageJson', 'currentPublicVersion', 'evidence']);
84
+
85
+ function assertKnownInputs(inputs) {
86
+ if (!isPlainObject(inputs)) throw new Error('production unblocker inputs must be an object');
87
+ for (const key of Object.keys(inputs)) {
88
+ if (!ALLOWED_INPUT_KEYS.has(key)) throw new Error(`unsupported production unblocker input field: ${key}`);
89
+ }
90
+ }
91
+
92
+
93
+ function command(id, purpose, value, options = {}) {
94
+ return {
95
+ id,
96
+ purpose,
97
+ command: value,
98
+ mode: options.mode ?? 'dry_run_or_planning',
99
+ requires_credentials: options.requires_credentials === true,
100
+ mutates_external_systems: options.mutates_external_systems === true,
101
+ };
102
+ }
103
+
104
+ function section(id, title, status, summary, details) {
105
+ if (!STATUS_VALUES.includes(status)) throw new Error(`invalid unblocker status for ${id}`);
106
+ return {
107
+ id,
108
+ title,
109
+ status,
110
+ summary,
111
+ evidence_available: details.evidence_available ?? [],
112
+ blockers: details.blockers ?? [],
113
+ non_claims: details.non_claims ?? [],
114
+ next_commands: details.next_commands ?? [],
115
+ };
116
+ }
117
+
118
+ function buildSections(packageSummary) {
119
+ const packageRef = `${packageSummary.name}@${packageSummary.version ?? '<version>'}`;
120
+ return [
121
+ section(
122
+ 'npm_install_readiness',
123
+ 'npm install readiness',
124
+ 'ready_now',
125
+ 'The npm install path is the current supported production install tier; this report distinguishes the current public package from the local source release candidate.',
126
+ {
127
+ evidence_available: [
128
+ `Current public install baseline: ${packageSummary.name}@${packageSummary.current_public_version}.`,
129
+ `Local source release candidate: ${packageSummary.name}@${packageSummary.source_version ?? '<unknown>'}.`,
130
+ `Package metadata requires Node ${packageSummary.node}.`,
131
+ `CLI bins listed in package metadata: ${packageSummary.bins.join(', ') || 'none listed'}.`,
132
+ ],
133
+ blockers: [],
134
+ non_claims: [
135
+ 'npm install readiness does not mean the source release candidate has already been published.',
136
+ 'Installing the package does not make hosted cloud live.',
137
+ 'Installing the package does not submit Solana transactions.',
138
+ 'Installing the package does not prove provider deletion, model forgetting, compliance, ROI, or provider invoice savings.',
139
+ ],
140
+ next_commands: [
141
+ command('build-unblocker-report', 'Regenerate this consolidated public-safe unblocker report.', 'npm run production:unblocker -- --out .enigma/production-unblocker.json'),
142
+ command('registry-install-plan-current', 'Validate the current public registry install plan without network install.', `npm run registry:verify -- --package ${packageSummary.name} --version ${packageSummary.current_public_version} --skip-network`),
143
+ command('registry-install-execute-current', 'Collect real current public registry install evidence in an isolated temporary prefix.', `npm run registry:verify -- --package ${packageSummary.name} --version ${packageSummary.current_public_version} --execute`, { mode: 'explicit_execute_network', mutates_external_systems: false }),
144
+ command('registry-install-execute-candidate', 'After release publication only, collect registry install evidence for the local source release candidate.', `npm run registry:verify -- --package ${packageSummary.name} --version ${packageSummary.source_version ?? '<candidate-version>'} --execute`, { mode: 'explicit_execute_network_after_publish', mutates_external_systems: false }),
145
+ ],
146
+ },
147
+ ),
148
+ section(
149
+ 'hosted_cloud_external_blockers',
150
+ 'Hosted cloud external blockers',
151
+ 'blocked_external_dependency',
152
+ 'Hosted-cloud package contracts exist, but sellable hosted SaaS remains blocked on real provider wiring, legal/security approvals, operations ownership, and operator go-live evidence.',
153
+ {
154
+ evidence_available: [
155
+ 'Hosted-cloud builders and validators can produce public-safe customer lifecycle and API-key lifecycle packets.',
156
+ 'Operator evidence starter and backend env kit commands can generate templates and public-safe fill plans.',
157
+ ],
158
+ blockers: [
159
+ 'Auth provider, billing provider, legal terms, data-processing terms, support ownership, and external security review evidence are not created by the package.',
160
+ 'Hosted relay/gateway/storage/KMS/SIEM/backup/monitoring/domain/TLS evidence must be supplied by an operator.',
161
+ 'Operator go-live approval is required before hosted_cloud_sellable can be true.',
162
+ ],
163
+ non_claims: [
164
+ 'No hosted account, customer tenant, customer API key, invoice, support ticket, Cloudflare resource, provider resource, or deployment is created by this report.',
165
+ 'Contract readiness is not live hosted SaaS readiness.',
166
+ ],
167
+ next_commands: [
168
+ command('operator-evidence-starter', 'Generate public-safe hosted evidence templates and fill order.', 'npm run production:evidence-starter -- --out-dir .enigma/operator-evidence --domain enigmamemory.com --tenant <tenant-id>'),
169
+ command('backend-env-kit', 'Generate the backend environment kit and public summary for operator completion outside public artifacts.', 'npm run production:backend-env -- --out-dir .enigma/backend-env-kit --domain enigmamemory.com --tenant <tenant-id> --environment production'),
170
+ command('hosted-live-validate', 'Validate completed hosted live evidence after real operator refs exist.', 'npm run production:hosted-live -- --evidence .enigma/operator-evidence/hosted-backend-live.json', { mode: 'operator_evidence_validation' }),
171
+ command('hosted-customer-lifecycle', 'Build hosted customer lifecycle contract evidence from public-safe refs.', 'npm run production:hosted-customer -- --tenant <tenant-id> --domain enigmamemory.com --environment production --out .enigma/hosted-customer-lifecycle.json'),
172
+ command('hosted-api-key-lifecycle', 'Build customer API-key lifecycle contract evidence from refs, not key material.', 'npm run production:hosted-api-key -- --tenant <tenant-id> --subject <opaque-subject-ref> --operation issue --out .enigma/hosted-api-key-lifecycle.json'),
173
+ ],
174
+ },
175
+ ),
176
+ section(
177
+ 'solana_proof_rail_status',
178
+ 'Solana proof rail status',
179
+ 'contract_ready',
180
+ 'The proof rail is local planning and verification: artifacts are Solana-ready commitments, not submitted transactions or live mainnet infrastructure.',
181
+ {
182
+ evidence_available: [
183
+ 'Local chain CLI commands create anchor, grant, revocation, benchmark-attestation, and verification artifacts with transaction_submitted:false.',
184
+ 'The proof packet builder hashes benchmark reports and emits public-safe proof-network packets.',
185
+ ],
186
+ blockers: [
187
+ 'Devnet/mainnet program deployment, transaction submission, program security review, governance, indexer evidence, and operational ownership are separate external work.',
188
+ 'Any future network mutation must be explicit and must not be implied by local planning artifacts.',
189
+ ],
190
+ non_claims: [
191
+ 'No Solana transaction is submitted by this report or by default local proof commands.',
192
+ 'Raw memory is not placed on-chain.',
193
+ 'No token ROI, profit, provider invoice savings, provider deletion, model-forgetting, compliance, or hosted SaaS claim is created by proof artifacts.',
194
+ ],
195
+ next_commands: [
196
+ command('chain-attest-local', 'Create a local benchmark attestation from a reviewed report hash/file and public refs.', `enigma chain attest --report-file .enigma/standard-memory-benchmark-sample.json --dataset-ref sha256:<dataset-manifest-hash> --runner-ref run-standard-memory-benchmarks.mjs@<reviewed-revision> --package-ref ${packageRef} --score retrieval_evidence_proxy=<value-copied-from-report> --out .enigma/standard-memory-benchmark-attestation.json`),
197
+ command('chain-verify-local', 'Verify a local proof-network artifact offline.', 'enigma chain verify --file .enigma/standard-memory-benchmark-attestation.json'),
198
+ command('proof-packet-local', 'Bundle public-safe roots and a benchmark report hash into a local proof packet.', 'npm run proof:packet -- --active-root sha256:<active-root> --receipt-root sha256:<receipt-root> --benchmark-report .enigma/standard-memory-benchmark-sample.json --dataset-hash sha256:<dataset-manifest-hash> --runner-hash sha256:<runner-hash> --operator-ref operator:<public-ref> --out .enigma/proof-network-packet.json'),
199
+ ],
200
+ },
201
+ ),
202
+ section(
203
+ 'benchmark_claim_status',
204
+ 'Benchmark claim status',
205
+ 'operator_evidence_required',
206
+ 'Local and official-dataset retrieval/evidence proxy benchmark commands exist; public claims require exact report, dataset manifest, runner/package refs, and claim-boundary review.',
207
+ {
208
+ evidence_available: [
209
+ 'The local deterministic memory suite can produce enigma.memory_benchmark_suite.v1 without provider credentials.',
210
+ 'The standard runner can score local LoCoMo/LongMemEval files as retrieval/evidence proxy evidence only.',
211
+ ],
212
+ blockers: [
213
+ 'Official dataset files and hashes must be collected locally before standard benchmark claims.',
214
+ 'Provider answer-accuracy, competitor, leaderboard, savings, compliance, model-forgetting, and provider-deletion claims require separate reviewed runs and are not present by default.',
215
+ ],
216
+ non_claims: [
217
+ 'No provider API, hosted memory service, competitor SDK, ChatGPT native memory, or Claude memory tool is called by the local default benchmark paths.',
218
+ 'Retrieval/evidence proxy metrics are not LLM answer accuracy or benchmark leadership.',
219
+ ],
220
+ next_commands: [
221
+ command('benchmark-dataset-plan', 'Preview dataset fetches without downloading raw data.', 'npm run benchmark:datasets -- --dry-run'),
222
+ command('benchmark-dataset-download', 'Download supported official datasets and write a public-safe manifest.', 'npm run benchmark:datasets -- --execute --dataset all --out-dir .enigma/benchmarks/datasets --manifest .enigma/benchmarks/dataset-manifest.json', { mode: 'explicit_execute_network' }),
223
+ command('benchmark-standard-sample', 'Run a bounded standard retrieval/evidence proxy benchmark from local dataset files.', 'npm run benchmark:standard -- --locomo .enigma/benchmarks/datasets/locomo10.json --longmemeval .enigma/benchmarks/datasets/longmemeval_s_cleaned.json --max-locomo-qa 25 --max-longmemeval-items 25 --top-k 5 --out .enigma/standard-memory-benchmark-sample.json'),
224
+ command('benchmark-local-suite', 'Run the local deterministic package benchmark suite.', 'npm run benchmark:memory-suite -- --out .enigma/memory-benchmark-suite.json'),
225
+ ],
226
+ },
227
+ ),
228
+ section(
229
+ 'installer_distribution_status',
230
+ 'Installer distribution status',
231
+ 'blocked_external_dependency',
232
+ 'npm is the production install tier now; native signed installer distribution remains blocked on external signing, notarization, release runners, and review evidence.',
233
+ {
234
+ evidence_available: [
235
+ 'The installer asset generator can produce reviewable source installer assets with dry-run/planning defaults.',
236
+ 'Generated source installer assets do not by themselves publish a Homebrew tap, signed Windows executable, or signed/notarized macOS package.',
237
+ ],
238
+ blockers: [
239
+ 'Windows distribution needs installer builder selection, code-signing certificate, signing workflow, and release review.',
240
+ 'macOS distribution needs package build runner, Developer ID Installer certificate, notarization workflow, and release review.',
241
+ 'Homebrew distribution needs a real release archive URL/SHA and tap workflow approval.',
242
+ ],
243
+ non_claims: [
244
+ 'No signed native installer exists from this report.',
245
+ 'Installer source assets are not a completed OS-native distribution channel.',
246
+ ],
247
+ next_commands: [
248
+ command('installer-assets-preview', 'Preview reviewable installer source assets.', 'npm run installer:assets -- --out-dir dist/installer-assets'),
249
+ command('installer-assets-write', 'Write reviewable installer source assets for release engineering.', 'npm run installer:assets -- --out-dir dist/installer-assets --write', { mode: 'local_write_explicit' }),
250
+ ],
251
+ },
252
+ ),
253
+ section(
254
+ 'monitoring_ops_status',
255
+ 'Monitoring and operations status',
256
+ 'operator_evidence_required',
257
+ 'Ops validators and dry-run monitors exist, but production monitoring, alert routing, backup/restore, incident drill, support/SLA, and acceptance evidence must be supplied by operators.',
258
+ {
259
+ evidence_available: [
260
+ 'Live endpoint monitoring has a dry-run mode and public-safe endpoint constraints.',
261
+ 'Production validators exist for monitoring/alerting, backup/restore drill, incident drill, support/SLA, legal/compliance, network, KMS, usage, settlement, site security, and threat model evidence.',
262
+ ],
263
+ blockers: [
264
+ 'Monitoring provider, alert routing, on-call ownership, incident commander, support escalation, backup target, restore rehearsal, and legal/security approvals are external operator evidence.',
265
+ 'Public site health is not hosted backend readiness; relay/gateway readiness requires exact live endpoint and operator acceptance evidence.',
266
+ ],
267
+ non_claims: [
268
+ 'Dry-run monitoring does not prove future availability or contractual SLA performance.',
269
+ 'Validator acceptance of a ref packet is not a compliance certification.',
270
+ ],
271
+ next_commands: [
272
+ command('live-monitor-dry-run', 'Validate default public endpoint monitor configuration without network probes.', 'npm run production:live-monitor:dry-run'),
273
+ command('live-monitor-public-safe', 'Collect live endpoint monitoring evidence only after endpoints are intentionally public and secret-free.', 'npm run production:live-monitor -- --endpoint public_site=https://enigmamemory.com/ --endpoint relay_readyz=https://relay.enigmamemory.com/readyz --endpoint gateway_readyz=https://gateway.enigmamemory.com/readyz --out .enigma/live-endpoint-monitor.json', { mode: 'operator_network_observation' }),
274
+ command('monitoring-validator', 'Validate operator monitoring/alerting evidence packet.', 'npm run production:monitoring -- --monitoring .enigma/operator-evidence/monitoring-alerting.json --out .enigma/monitoring-alerting-result.json', { mode: 'operator_evidence_validation' }),
275
+ command('backup-drill-validator', 'Validate operator backup/restore drill evidence packet.', 'npm run production:backup-drill -- --drill .enigma/operator-evidence/backup-restore-drill.json --out .enigma/backup-restore-drill-result.json', { mode: 'operator_evidence_validation' }),
276
+ command('incident-drill-validator', 'Validate operator incident drill evidence packet.', 'npm run production:incident-drill -- --drill .enigma/operator-evidence/incident-drill.json --out .enigma/incident-drill-result.json', { mode: 'operator_evidence_validation' }),
277
+ ],
278
+ },
279
+ ),
280
+ ];
281
+ }
282
+
283
+ function statusCounts(sections) {
284
+ const counts = Object.fromEntries(STATUS_VALUES.map((status) => [status, 0]));
285
+ for (const item of sections) counts[item.status] += 1;
286
+ return counts;
287
+ }
288
+
289
+ function flattenCommands(sections) {
290
+ return sections.flatMap((item) => item.next_commands.map((entry) => ({ section: item.id, ...entry })));
291
+ }
292
+
293
+ export function buildProductionUnblocker(inputs = {}, options = {}) {
294
+ assertKnownInputs(inputs);
295
+ if (inputs.evidence !== undefined) assertPublicSafe(inputs.evidence, 'production_unblocker.evidence');
296
+ const generatedAt = options.generated_at ?? options.generatedAt ?? new Date().toISOString();
297
+ const packageSummary = publicPackageSummary(inputs.packageJson ?? {}, { currentPublicVersion: inputs.currentPublicVersion ?? options.current_public_version ?? options.currentPublicVersion });
298
+ const sections = buildSections(packageSummary);
299
+ const blockers = sections.flatMap((item) => item.blockers.map((blocker) => ({ section: item.id, status: item.status, blocker })));
300
+ const report = {
301
+ schema: PRODUCTION_UNBLOCKER_SCHEMA,
302
+ generated_at: generatedAt,
303
+ mode: 'dry_run_planning',
304
+ credentials_required: false,
305
+ credentials_used: false,
306
+ mutates_external_systems: false,
307
+ overall_status: blockers.length === 0 ? 'ready_now' : 'blocked_external_dependency',
308
+ package: packageSummary,
309
+ status_legend: {
310
+ ready_now: 'Usable now within the stated local/package boundary.',
311
+ contract_ready: 'Interfaces, validators, or local planning artifacts exist, but live external operation is not claimed.',
312
+ blocked_external_dependency: 'External provider, credential, signing, deployment, legal, security, or operator system is required.',
313
+ operator_evidence_required: 'The repository supplies the command or validator, but an operator must provide current public-safe evidence.',
314
+ },
315
+ status_counts: statusCounts(sections),
316
+ sections,
317
+ go_live_blockers: blockers,
318
+ operator_next_commands: flattenCommands(sections),
319
+ live_claims: {
320
+ hosted_saas_live: false,
321
+ hosted_cloud_live_claim: false,
322
+ solana_mainnet_live_claim: false,
323
+ solana_transaction_claim: false,
324
+ transaction_submitted: false,
325
+ raw_memory_on_chain: false,
326
+ raw_memory_in_public_artifacts: false,
327
+ external_provider_called: false,
328
+ provider_response_claim: false,
329
+ model_forgetting_claim: false,
330
+ provider_deletion_claim: false,
331
+ benchmark_leadership_claim: false,
332
+ token_roi_claim: false,
333
+ token_profit_claim: false,
334
+ provider_invoice_savings_claim: false,
335
+ },
336
+ claim_boundary: [
337
+ 'This report is public-safe planning evidence. It does not publish, deploy, create accounts, submit transactions, create credentials, call model providers, or mutate external systems.',
338
+ 'ready_now means ready within the named local/package boundary only; it does not imply hosted SaaS, Solana mainnet, benchmark leadership, compliance, provider deletion, model forgetting, ROI, profit, or provider invoice savings.',
339
+ 'contract_ready means schemas, validators, CLI planning, or local proof artifacts exist; an operator must still supply external evidence before live or sellable claims.',
340
+ 'Commands marked explicit_execute_network or operator_network_observation should only be run by an operator with approval for that environment.',
341
+ ],
342
+ };
343
+ assertPublicSafe(report);
344
+ return report;
345
+ }
346
+
347
+ function parseArgs(argv = process.argv.slice(2)) {
348
+ const args = {
349
+ out: null,
350
+ generatedAt: null,
351
+ help: false,
352
+ };
353
+ for (let index = 0; index < argv.length; index += 1) {
354
+ const token = argv[index];
355
+ if (token === '--help' || token === '-h') {
356
+ args.help = true;
357
+ continue;
358
+ }
359
+ const readValue = () => {
360
+ const value = argv[index + 1];
361
+ if (typeof value !== 'string' || value.length === 0 || value.startsWith('--')) throw new UsageError(`${token} requires a value`);
362
+ index += 1;
363
+ return value;
364
+ };
365
+ if (token === '--out') args.out = readValue();
366
+ else if (token === '--generated-at' || token === '--generatedAt') args.generatedAt = readValue();
367
+ else throw new UsageError(`unknown production unblocker option: ${token}`);
368
+ }
369
+ return args;
370
+ }
371
+
372
+ function usage() {
373
+ return `Usage: node scripts/build-production-unblocker.mjs [--out <file>] [--generated-at <iso>]
374
+
375
+ Builds a dependency-free public-safe production unblocker report. The command is dry-run/planning by default: it requires no credentials, does not publish, does not deploy, does not submit Solana transactions, does not call providers, and does not mutate external systems.
376
+ `;
377
+ }
378
+
379
+ async function readPackageJson() {
380
+ const packageUrl = new URL('../package.json', import.meta.url);
381
+ try {
382
+ return JSON.parse(await readFile(packageUrl, 'utf8'));
383
+ } catch {
384
+ return {};
385
+ }
386
+ }
387
+
388
+ export async function main(argv = process.argv.slice(2)) {
389
+ const args = parseArgs(argv);
390
+ if (args.help) return { text: usage(), code: 0 };
391
+ const report = buildProductionUnblocker({ packageJson: await readPackageJson() }, { generated_at: args.generatedAt ?? new Date().toISOString() });
392
+ const text = `${JSON.stringify(report, null, 2)}\n`;
393
+ if (args.out) {
394
+ const outPath = resolve(args.out);
395
+ await mkdir(dirname(outPath), { recursive: true });
396
+ await writeFile(outPath, text, 'utf8');
397
+ }
398
+ return { text, code: 0 };
399
+ }
400
+
401
+ if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
402
+ main().then(({ text, code }) => {
403
+ process.stdout.write(text);
404
+ process.exitCode = code;
405
+ }).catch((error) => {
406
+ process.stderr.write(`${error.name ?? 'Error'}: ${error.message ?? 'failed to build production unblocker'}\n`);
407
+ process.exitCode = 2;
408
+ });
409
+ }