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,369 @@
|
|
|
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_DEPENDENCY_REPORT_SCHEMA = 'enigma.production_dependency_report.v1';
|
|
7
|
+
|
|
8
|
+
const SECRET_RE = /(?:Bearer\s+[A-Za-z0-9._~+/=-]{12,}|-----BEGIN [A-Z ]*PRIVATE KEY-----|sk-[A-Za-z0-9_-]{16,}|https?:\/\/[^\s/@]+:[^\s/@]+@|\b[0-9a-f]{32}\b|[A-Z]:\\Users\\|\/Users\/|\/home\/|raw memory|private prompt|full transcript|decrypted capsule)/iu;
|
|
9
|
+
const FORBIDDEN_KEY_RE = /(?:password|api[_-]?key|private[_-]?key|secret|token|account[_-]?id|raw[_-]?memory|plaintext|prompt|transcript|provider[_-]?response|cookie|session)/iu;
|
|
10
|
+
const SAFE_KEY_RE = /^(?:tokenPrinted|token_printed|token_policy_ready|cloudflare_token_policy|account_id_redacted|account_id_printed|token_value_printed|raw_memory_on_chain)$/u;
|
|
11
|
+
const SAFE_METRIC_KEY_RE = /(?:^token_roi_claim$|^token_value_printed$|^tokenPrinted$|^token_printed$|^token_created$|tokens$|token_count$|prompt_count$|_present$|_findings$)/iu;
|
|
12
|
+
|
|
13
|
+
function assertPublicSafe(value, path = 'dependency_report') {
|
|
14
|
+
if (typeof value === 'string') {
|
|
15
|
+
if (SECRET_RE.test(value)) throw new Error(`${path} contains non-public material`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
value.forEach((item, index) => assertPublicSafe(item, `${path}[${index}]`));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (value === null || typeof value !== 'object') return;
|
|
23
|
+
for (const [key, child] of Object.entries(value)) {
|
|
24
|
+
const safeMetric = SAFE_METRIC_KEY_RE.test(key) && (typeof child === 'number' || typeof child === 'boolean');
|
|
25
|
+
if (FORBIDDEN_KEY_RE.test(key) && !SAFE_KEY_RE.test(key) && !safeMetric) throw new Error(`${path}.${key} is not allowed in public dependency report`);
|
|
26
|
+
assertPublicSafe(child, `${path}.${key}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function requireObject(value, label) {
|
|
31
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} must be an object`);
|
|
32
|
+
assertPublicSafe(value, label);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function requirePlainObject(value, label) {
|
|
37
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} must be an object`);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function requireEdgeLiveEvidence(value) {
|
|
42
|
+
const edgeLive = requirePlainObject(value, 'edge_live');
|
|
43
|
+
const { claim_boundary: _claimBoundary, ...publicFields } = edgeLive;
|
|
44
|
+
assertPublicSafe(publicFields, 'edge_live');
|
|
45
|
+
return edgeLive;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function requireStorageBootstrapEvidence(value) {
|
|
49
|
+
const storage = requirePlainObject(value, 'storage_bootstrap');
|
|
50
|
+
const { claim_boundary: _claimBoundary, cost_boundary: _costBoundary, ...publicFields } = storage;
|
|
51
|
+
assertPublicSafe(publicFields, 'storage_bootstrap');
|
|
52
|
+
return storage;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function requireEdgeDeploymentEvidence(value) {
|
|
56
|
+
const deployment = requirePlainObject(value, 'edge_deploy');
|
|
57
|
+
const { claim_boundary: _claimBoundary, cost_boundary: _costBoundary, provision_secrets: _provisionSecrets, secret_values_printed: _secretValuesPrinted, tokenPrinted: _tokenPrinted, token_printed: _tokenPrintedSnake, accountIdPrinted: _accountIdPrinted, account_id_printed: _accountIdPrintedSnake, resourceIdsPrinted: _resourceIdsPrinted, resource_ids_printed: _resourceIdsPrintedSnake, services, ...rest } = deployment;
|
|
58
|
+
const publicFields = { ...rest, services: Array.isArray(services) ? services.map(({ secrets: _secrets, ...service }) => service) : services };
|
|
59
|
+
assertPublicSafe(publicFields, 'edge_deploy');
|
|
60
|
+
return deployment;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async function readJson(path, label) {
|
|
66
|
+
const parsed = JSON.parse(await readFile(resolve(path), 'utf8'));
|
|
67
|
+
if (label === 'release_audit') return requirePlainObject(parsed, label);
|
|
68
|
+
if (label === 'edge_deploy') return requireEdgeDeploymentEvidence(parsed);
|
|
69
|
+
if (label === 'edge_live') return requireEdgeLiveEvidence(parsed);
|
|
70
|
+
if (label === 'storage_bootstrap') return requireStorageBootstrapEvidence(parsed);
|
|
71
|
+
return requireObject(parsed, label);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function byId(deliverables = []) {
|
|
75
|
+
const out = new Map();
|
|
76
|
+
for (const item of Array.isArray(deliverables) ? deliverables : []) {
|
|
77
|
+
if (typeof item?.id === 'string') out.set(item.id, item);
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function group(name, ready, evidence, blockers, nextCommand) {
|
|
83
|
+
const isReady = ready === true;
|
|
84
|
+
return {
|
|
85
|
+
name,
|
|
86
|
+
ready: isReady,
|
|
87
|
+
evidence: evidence.filter(Boolean),
|
|
88
|
+
blocker_count: blockers.length,
|
|
89
|
+
blockers: blockers.slice(0, 40),
|
|
90
|
+
next_command: isReady ? null : nextCommand,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function firstActionIndex(actions, ids) {
|
|
95
|
+
const wanted = new Set(ids);
|
|
96
|
+
return actions.findIndex((item) => wanted.has(item?.id));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function orderedNextActions(actions) {
|
|
100
|
+
const priority = new Map([
|
|
101
|
+
['generate-operator-evidence-starter', 10],
|
|
102
|
+
['optional-standalone-worker-probe', 5],
|
|
103
|
+
['generate-backend-env-kit', 20],
|
|
104
|
+
['provision-hosted-backend', 30],
|
|
105
|
+
['validate-hosted-backend-live-evidence', 40],
|
|
106
|
+
['complete-operator-acceptance', 50],
|
|
107
|
+
]);
|
|
108
|
+
return actions
|
|
109
|
+
.map((action, index) => ({ action, index }))
|
|
110
|
+
.sort((left, right) => {
|
|
111
|
+
const leftPriority = priority.get(left.action?.id) ?? (100 + left.index);
|
|
112
|
+
const rightPriority = priority.get(right.action?.id) ?? (100 + right.index);
|
|
113
|
+
return leftPriority - rightPriority || left.index - right.index;
|
|
114
|
+
})
|
|
115
|
+
.map((entry) => entry.action);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function buildProductionDependencyReport(inputs = {}, options = {}) {
|
|
119
|
+
const goalAudit = requireObject(inputs.goalAudit, 'goal_audit');
|
|
120
|
+
const releaseAudit = requirePlainObject(inputs.releaseAudit, 'release_audit');
|
|
121
|
+
const workerInspect = requireObject(inputs.workerInspect, 'worker_inspect');
|
|
122
|
+
const whitepaper = requireObject(inputs.whitepaper, 'whitepaper');
|
|
123
|
+
const credentialEvidence = inputs.cloudflareCredentials === undefined || inputs.cloudflareCredentials === null
|
|
124
|
+
? null
|
|
125
|
+
: requireObject(inputs.cloudflareCredentials, 'cloudflare_credentials');
|
|
126
|
+
if (goalAudit.schema !== 'enigma.goal_completion_audit.v1') throw new Error('goal audit schema mismatch');
|
|
127
|
+
if (releaseAudit.schema !== 'enigma.release_audit.v1') throw new Error('release audit schema mismatch');
|
|
128
|
+
if (workerInspect.schema !== 'enigma.cloudflare_worker_inspection_result.v1') throw new Error('worker inspect schema mismatch');
|
|
129
|
+
if (whitepaper.schema !== 'enigma.whitepaper_claims_result.v1') throw new Error('whitepaper schema mismatch');
|
|
130
|
+
if (credentialEvidence !== null && credentialEvidence.schema !== 'enigma.cloudflare_credentials_result.v1') throw new Error('Cloudflare credential schema mismatch');
|
|
131
|
+
const edgeDeploy = inputs.edgeDeploy === undefined || inputs.edgeDeploy === null
|
|
132
|
+
? null
|
|
133
|
+
: requireEdgeDeploymentEvidence(inputs.edgeDeploy);
|
|
134
|
+
if (edgeDeploy !== null && edgeDeploy.schema !== 'enigma.edge_backend_deployment.v1') throw new Error('edge deploy schema mismatch');
|
|
135
|
+
const edgeLive = inputs.edgeLive === undefined || inputs.edgeLive === null
|
|
136
|
+
? null
|
|
137
|
+
: requireEdgeLiveEvidence(inputs.edgeLive);
|
|
138
|
+
const storageBootstrap = inputs.storageBootstrap === undefined || inputs.storageBootstrap === null
|
|
139
|
+
? null
|
|
140
|
+
: requireStorageBootstrapEvidence(inputs.storageBootstrap);
|
|
141
|
+
if (storageBootstrap !== null && storageBootstrap.schema !== 'enigma.cloudflare_storage_bootstrap.v1') throw new Error('storage bootstrap schema mismatch');
|
|
142
|
+
if (edgeLive !== null && edgeLive.schema !== 'enigma.edge_backend_bootstrap_live_evidence.v1') throw new Error('edge live schema mismatch');
|
|
143
|
+
|
|
144
|
+
const deliverables = byId(goalAudit.deliverables);
|
|
145
|
+
const hosted = deliverables.get('hosted-backend-live');
|
|
146
|
+
const operator = deliverables.get('operator-acceptance-go');
|
|
147
|
+
const liveSite = deliverables.get('live-domain-current-site');
|
|
148
|
+
const whitepaperDeliverable = deliverables.get('whitepaper-math-diagrams');
|
|
149
|
+
const cloudflareCredentials = credentialEvidence ?? deliverables.get('cloudflare-credentials-present');
|
|
150
|
+
const releaseGateNames = new Set(Array.isArray(releaseAudit.gates) ? releaseAudit.gates.map((gate) => gate?.name).filter((name) => typeof name === 'string') : []);
|
|
151
|
+
assertPublicSafe([...releaseGateNames], 'release_audit.gate_names');
|
|
152
|
+
const groups = [
|
|
153
|
+
group(
|
|
154
|
+
'static_site',
|
|
155
|
+
liveSite?.ok === true,
|
|
156
|
+
liveSite?.evidence ?? [],
|
|
157
|
+
liveSite?.blockers ?? ['live domain evidence missing'],
|
|
158
|
+
'npm run production:goal-audit -- --site <public-site-dir> --domain enigmamemory.com --release-audit .enigma/release-audit-current.json',
|
|
159
|
+
),
|
|
160
|
+
group(
|
|
161
|
+
'release_gates',
|
|
162
|
+
releaseAudit.ok === true && Array.isArray(releaseAudit.required_failed) && releaseAudit.required_failed.length === 0,
|
|
163
|
+
['npm run check', 'npm test', 'npm run release:audit'],
|
|
164
|
+
Array.isArray(releaseAudit.required_failed) ? releaseAudit.required_failed.map(String) : ['release audit required_failed missing'],
|
|
165
|
+
'npm run check && npm test && npm run release:audit -- --out .enigma/release-audit-current.json',
|
|
166
|
+
),
|
|
167
|
+
group(
|
|
168
|
+
'whitepaper_claims',
|
|
169
|
+
whitepaper.ok === true && whitepaperDeliverable?.ok === true && releaseGateNames.has('whitepaper-claims-validator'),
|
|
170
|
+
['npm run production:whitepaper', 'release audit gate whitepaper-claims-validator'],
|
|
171
|
+
[
|
|
172
|
+
...(whitepaper.blockers ?? []),
|
|
173
|
+
...(whitepaperDeliverable?.blockers ?? []),
|
|
174
|
+
...(releaseGateNames.has('whitepaper-claims-validator') ? [] : ['release audit missing whitepaper-claims-validator gate']),
|
|
175
|
+
],
|
|
176
|
+
'npm run production:whitepaper -- --file docs/enigma-memory-technical-whitepaper.md --out .enigma/whitepaper-claims-current.json',
|
|
177
|
+
),
|
|
178
|
+
group(
|
|
179
|
+
'cloudflare_credentials',
|
|
180
|
+
credentialEvidence !== null ? credentialEvidence.credentials_present === true : cloudflareCredentials?.ok === true,
|
|
181
|
+
credentialEvidence !== null ? ['npm run production:cloudflare-credentials', ...(credentialEvidence.present_keys ?? [])] : (cloudflareCredentials?.evidence ?? ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_ACCOUNT_ID']),
|
|
182
|
+
credentialEvidence !== null ? credentialEvidence.blockers ?? [] : (cloudflareCredentials?.blockers ?? ['Cloudflare credential deliverable missing']),
|
|
183
|
+
'Inject CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID out-of-band, then rerun production:cloudflare-credentials, production:goal-audit, and production:dependencies.',
|
|
184
|
+
),
|
|
185
|
+
group(
|
|
186
|
+
'cloudflare_worker_permission',
|
|
187
|
+
workerInspect.worker_permission_ready === true,
|
|
188
|
+
['npm run cloudflare:ops -- workers inspect-probe --out .enigma/worker-inspect-current.json', 'npm run production:worker-inspect -- --evidence .enigma/worker-inspect-current.json'],
|
|
189
|
+
workerInspect.worker_permission_ready === true ? [] : (workerInspect.permission_blockers ?? ['Worker permission not ready']),
|
|
190
|
+
'Fix Cloudflare token/account Workers Scripts scope, then rerun worker inspect and deploy-probe.',
|
|
191
|
+
),
|
|
192
|
+
...(edgeDeploy === null ? [] : [group(
|
|
193
|
+
'edge_backend_deployment',
|
|
194
|
+
edgeDeploy.ok === true && edgeDeploy.status === 'deployed',
|
|
195
|
+
[
|
|
196
|
+
'npm run production:edge-deploy',
|
|
197
|
+
...((edgeDeploy.services ?? []).map((service) => service.hostname).filter(Boolean)),
|
|
198
|
+
],
|
|
199
|
+
edgeDeploy.ok === true && edgeDeploy.status === 'deployed' ? [] : (edgeDeploy.blockers ?? ['edge backend deployment missing or not deployed']),
|
|
200
|
+
'npm run production:edge-deploy -- --execute --provision-secrets --out .enigma/edge-backend-deployment-current.json',
|
|
201
|
+
)]),
|
|
202
|
+
...(edgeLive === null ? [] : [group(
|
|
203
|
+
'edge_backend_bootstrap',
|
|
204
|
+
edgeLive.ok === true,
|
|
205
|
+
[
|
|
206
|
+
'npm run production:edge-live',
|
|
207
|
+
'https://relay.enigmamemory.com/livez',
|
|
208
|
+
'https://gateway.enigmamemory.com/livez',
|
|
209
|
+
],
|
|
210
|
+
edgeLive.ok === true ? [] : (edgeLive.blockers ?? ['edge backend bootstrap evidence missing or blocked']),
|
|
211
|
+
'npm run production:edge-live -- --domain enigmamemory.com --out .enigma/edge-backend-bootstrap-live-current.json',
|
|
212
|
+
)]),
|
|
213
|
+
...(storageBootstrap === null ? [] : [group(
|
|
214
|
+
'cloudflare_storage_bootstrap',
|
|
215
|
+
storageBootstrap.ok === true,
|
|
216
|
+
[
|
|
217
|
+
'npm run production:storage-bootstrap',
|
|
218
|
+
...((storageBootstrap.resources ?? []).map((resource) => resource.ref).filter(Boolean)),
|
|
219
|
+
],
|
|
220
|
+
storageBootstrap.ok === true ? [] : (storageBootstrap.blockers ?? ['cloudflare storage bootstrap missing or blocked']),
|
|
221
|
+
'npm run production:storage-bootstrap -- --execute --out .enigma/cloudflare-storage-bootstrap-current.json',
|
|
222
|
+
)]),
|
|
223
|
+
group(
|
|
224
|
+
'hosted_backend_live',
|
|
225
|
+
hosted?.ok === true,
|
|
226
|
+
hosted?.evidence ?? [],
|
|
227
|
+
hosted?.blockers ?? ['hosted backend deliverable missing'],
|
|
228
|
+
'Provision relay/gateway/storage/KMS/SIEM/backup refs, then run infrastructure:readiness -- --live --cloudflare-live required.',
|
|
229
|
+
),
|
|
230
|
+
group(
|
|
231
|
+
'operator_acceptance',
|
|
232
|
+
operator?.ok === true,
|
|
233
|
+
operator?.evidence ?? [],
|
|
234
|
+
operator?.blockers ?? ['operator acceptance deliverable missing'],
|
|
235
|
+
'npm run production:acceptance:packet -- --out <evidence-dir>/operator-acceptance-packet.json --owners-json <evidence-dir>/owner-approval-refs.json --evidence-refs <evidence-dir>/evidence-refs.json --readiness <evidence-dir>/infrastructure-readiness-live.json --manifest <evidence-dir>/infrastructure-readiness-manifest.json --storage <evidence-dir>/production-storage-migration.json --release-audit .enigma/release-audit-current.json --production-manifests <evidence-dir>/production-manifests.json --decision go --tenant <tenant-id> --target-regions <regions> --requested-go-live-date <date> --evidence-repository <evidence-repository> --packet-owner <operator> --validate && npm run production:acceptance -- --packet <evidence-dir>/operator-acceptance-packet.json',
|
|
236
|
+
),
|
|
237
|
+
];
|
|
238
|
+
const blockers = groups.flatMap((item) => item.blockers.map((text) => `${item.name}: ${text}`));
|
|
239
|
+
const readyGroupNames = new Set(groups.filter((item) => item.ready === true).map((item) => item.name));
|
|
240
|
+
const skippedActionIds = new Set([
|
|
241
|
+
...(readyGroupNames.has('cloudflare_worker_permission') ? ['optional-standalone-worker-probe'] : []),
|
|
242
|
+
]);
|
|
243
|
+
const nextActions = Array.isArray(goalAudit.next_actions)
|
|
244
|
+
? goalAudit.next_actions.filter((item) => !skippedActionIds.has(item?.id)).map((item) => ({ id: item.id, owner: item.owner, command: item.command, evidence: item.evidence }))
|
|
245
|
+
: [];
|
|
246
|
+
if (!readyGroupNames.has('cloudflare_worker_permission') && !nextActions.some((item) => item.id === 'optional-standalone-worker-probe')) {
|
|
247
|
+
nextActions.push({
|
|
248
|
+
id: 'optional-standalone-worker-probe',
|
|
249
|
+
owner: 'operator-or-ai-with-token',
|
|
250
|
+
command: 'npm run production:hosted-probe -- --out-dir <probe-worker-dir> && npm run cloudflare:ops -- workers deploy-probe --script <probe-worker-dir>/worker.mjs --name enigma-hosted-probe --execute && npm run cloudflare:ops -- workers inspect-probe --name enigma-hosted-probe --out .enigma/worker-inspect-current.json && npm run production:worker-inspect -- --evidence .enigma/worker-inspect-current.json',
|
|
251
|
+
evidence: '.enigma/worker-inspect-current.json accepted by production:worker-inspect; this is permission evidence only, not hosted backend readiness',
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (!readyGroupNames.has('hosted_backend_live') && !nextActions.some((item) => item.id === 'generate-backend-env-kit')) {
|
|
255
|
+
const insertAt = nextActions.findIndex((item) => item.id === 'provision-hosted-backend');
|
|
256
|
+
const backendEnvAction = {
|
|
257
|
+
id: 'generate-backend-env-kit',
|
|
258
|
+
owner: 'operator-or-reviewer',
|
|
259
|
+
command: 'npm run production:backend-env -- --out-dir <backend-env-kit-dir> --domain enigmamemory.com --tenant <tenant-id> --environment production',
|
|
260
|
+
evidence: '<backend-env-kit-dir>/PRODUCTION_BACKEND_ENV_KIT_SUMMARY.json plus private operator-env/operator-secrets filled outside public artifacts',
|
|
261
|
+
};
|
|
262
|
+
if (insertAt >= 0) nextActions.splice(insertAt, 0, backendEnvAction);
|
|
263
|
+
else nextActions.push(backendEnvAction);
|
|
264
|
+
}
|
|
265
|
+
if (operator?.ok !== true && !nextActions.some((item) => item.id === 'generate-operator-evidence-starter')) {
|
|
266
|
+
const insertAt = firstActionIndex(nextActions, ['generate-backend-env-kit', 'provision-hosted-backend', 'validate-hosted-backend-live-evidence', 'complete-operator-acceptance']);
|
|
267
|
+
const starterAction = {
|
|
268
|
+
id: 'generate-operator-evidence-starter',
|
|
269
|
+
owner: 'operator-or-reviewer',
|
|
270
|
+
command: 'npm run production:evidence-starter -- --out-dir <evidence-dir> --domain enigmamemory.com --tenant <tenant-id>',
|
|
271
|
+
evidence: '<evidence-dir>/hosted-refs.template.json, hosted-backend-live.template.json, owner-approval-refs.template.json, evidence-refs.template.json, hosted-backend-live-collection.json/hosted-backend-live.json flow, acceptance-fill-plan.json, plus production:acceptance:packet and production:acceptance validation',
|
|
272
|
+
};
|
|
273
|
+
if (insertAt >= 0) nextActions.splice(insertAt, 0, starterAction);
|
|
274
|
+
else nextActions.push(starterAction);
|
|
275
|
+
}
|
|
276
|
+
const report = {
|
|
277
|
+
schema: PRODUCTION_DEPENDENCY_REPORT_SCHEMA,
|
|
278
|
+
generated_at: options.generated_at ?? options.generatedAt ?? new Date(0).toISOString(),
|
|
279
|
+
status: blockers.length === 0 ? 'ready' : 'blocked',
|
|
280
|
+
launch_ready: blockers.length === 0 && goalAudit.complete === true && goalAudit.go_live_ready === true,
|
|
281
|
+
goal_complete: goalAudit.complete === true,
|
|
282
|
+
release_posture: goalAudit.release_posture ?? null,
|
|
283
|
+
group_count: groups.length,
|
|
284
|
+
blocked_group_count: groups.filter((item) => item.ready !== true).length,
|
|
285
|
+
groups,
|
|
286
|
+
blockers,
|
|
287
|
+
next_actions: orderedNextActions(nextActions),
|
|
288
|
+
claim_boundary: [
|
|
289
|
+
'This report is a public-safe dependency tracker. It does not create accounts, provision infrastructure, deploy Workers, or certify launch readiness.',
|
|
290
|
+
'launch_ready:true requires the goal audit to be complete and every dependency group to be ready with direct evidence.',
|
|
291
|
+
'Blocked groups are intentional until hosted relay/gateway evidence and operator acceptance go exist.',
|
|
292
|
+
],
|
|
293
|
+
};
|
|
294
|
+
assertPublicSafe(report);
|
|
295
|
+
return report;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function parseArgs(argv = process.argv.slice(2)) {
|
|
299
|
+
const out = {
|
|
300
|
+
goalAudit: '.enigma/goal-audit-current.json',
|
|
301
|
+
releaseAudit: '.enigma/release-audit-current.json',
|
|
302
|
+
workerInspect: '.enigma/worker-inspect-result-current.json',
|
|
303
|
+
whitepaper: '.enigma/whitepaper-claims-current.json',
|
|
304
|
+
cloudflareCredentials: null,
|
|
305
|
+
edgeLive: null,
|
|
306
|
+
edgeDeploy: null,
|
|
307
|
+
storageBootstrap: null,
|
|
308
|
+
out: null,
|
|
309
|
+
help: false,
|
|
310
|
+
};
|
|
311
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
312
|
+
const token = argv[index];
|
|
313
|
+
if (token === '--help' || token === '-h') { out.help = true; continue; }
|
|
314
|
+
const readValue = () => {
|
|
315
|
+
const value = argv[index + 1];
|
|
316
|
+
if (typeof value !== 'string' || value.length === 0 || value.startsWith('--')) throw new Error(`${token} requires a value`);
|
|
317
|
+
index += 1;
|
|
318
|
+
return value;
|
|
319
|
+
};
|
|
320
|
+
if (token === '--goal-audit') out.goalAudit = readValue();
|
|
321
|
+
else if (token === '--release-audit') out.releaseAudit = readValue();
|
|
322
|
+
else if (token === '--worker-inspect') out.workerInspect = readValue();
|
|
323
|
+
else if (token === '--whitepaper') out.whitepaper = readValue();
|
|
324
|
+
else if (token === '--cloudflare-credentials') out.cloudflareCredentials = readValue();
|
|
325
|
+
else if (token === '--edge-deploy') out.edgeDeploy = readValue();
|
|
326
|
+
else if (token === '--edge-live') out.edgeLive = readValue();
|
|
327
|
+
else if (token === '--storage-bootstrap') out.storageBootstrap = readValue();
|
|
328
|
+
else if (token === '--out') out.out = readValue();
|
|
329
|
+
else throw new Error(`unknown option ${token}`);
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function usage() {
|
|
335
|
+
return 'Usage: node scripts/build-production-dependency-report.mjs --goal-audit <goal.json> --release-audit <release.json> --worker-inspect <worker-result.json> --whitepaper <whitepaper-result.json> [--cloudflare-credentials <credentials-result.json>] [--edge-deploy <edge-backend-deployment.json>] [--edge-live <edge-backend-bootstrap-live.json>] [--storage-bootstrap <cloudflare-storage-bootstrap.json>] [--out <file>]\\n\\nBuilds a public-safe launch dependency report from current evidence artifacts.\\n';
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async function runCli(argv = process.argv.slice(2)) {
|
|
339
|
+
const args = parseArgs(argv);
|
|
340
|
+
if (args.help) return { text: usage(), code: 0 };
|
|
341
|
+
const report = buildProductionDependencyReport({
|
|
342
|
+
goalAudit: await readJson(args.goalAudit, 'goal_audit'),
|
|
343
|
+
releaseAudit: await readJson(args.releaseAudit, 'release_audit'),
|
|
344
|
+
workerInspect: await readJson(args.workerInspect, 'worker_inspect'),
|
|
345
|
+
whitepaper: await readJson(args.whitepaper, 'whitepaper'),
|
|
346
|
+
cloudflareCredentials: args.cloudflareCredentials ? await readJson(args.cloudflareCredentials, 'cloudflare_credentials') : null,
|
|
347
|
+
edgeDeploy: args.edgeDeploy ? await readJson(args.edgeDeploy, 'edge_deploy') : null,
|
|
348
|
+
edgeLive: args.edgeLive ? await readJson(args.edgeLive, 'edge_live') : null,
|
|
349
|
+
storageBootstrap: args.storageBootstrap ? await readJson(args.storageBootstrap, 'storage_bootstrap') : null,
|
|
350
|
+
}, { generated_at: new Date().toISOString() });
|
|
351
|
+
const json = `${JSON.stringify(report, null, 2)}\n`;
|
|
352
|
+
if (args.out) {
|
|
353
|
+
const outPath = resolve(args.out);
|
|
354
|
+
await mkdir(dirname(outPath), { recursive: true });
|
|
355
|
+
await writeFile(outPath, json, 'utf8');
|
|
356
|
+
}
|
|
357
|
+
return { text: json, code: report.launch_ready ? 0 : 1 };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
361
|
+
try {
|
|
362
|
+
const { text, code } = await runCli();
|
|
363
|
+
process.stdout.write(text);
|
|
364
|
+
process.exitCode = code;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
367
|
+
process.exitCode = 2;
|
|
368
|
+
}
|
|
369
|
+
}
|