@tradejs/cli 3.1.16 → 3.1.17

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.
@@ -31,9 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var runtimeEvidenceSync_exports = {};
32
32
  __export(runtimeEvidenceSync_exports, {
33
33
  buildRuntimeEvidenceRsyncArgs: () => buildRuntimeEvidenceRsyncArgs,
34
- inspectRuntimeEvidenceBundleSupport: () => inspectRuntimeEvidenceBundleSupport,
35
34
  listPendingRuntimeEvidenceBundles: () => listPendingRuntimeEvidenceBundles,
36
- listRuntimeEvidenceBundleStatuses: () => listRuntimeEvidenceBundleStatuses,
37
35
  markRuntimeEvidenceBundleProcessed: () => markRuntimeEvidenceBundleProcessed,
38
36
  syncRuntimeEvidenceBundles: () => syncRuntimeEvidenceBundles
39
37
  });
@@ -47,6 +45,166 @@ var import_node_util = require("util");
47
45
  var import_node_crypto = require("crypto");
48
46
  var import_promises = __toESM(require("fs/promises"));
49
47
  var import_node_path = __toESM(require("path"));
48
+
49
+ // src/lib/runtimeEvidenceDeployment.ts
50
+ var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
51
+ var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
52
+ var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
53
+ var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
54
+ ([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
55
+ );
56
+ var INTERVALS = /* @__PURE__ */ new Set([
57
+ "1",
58
+ "3",
59
+ "5",
60
+ "15",
61
+ "30",
62
+ "60",
63
+ "120",
64
+ "240",
65
+ "360",
66
+ "720",
67
+ "D",
68
+ "W",
69
+ "M"
70
+ ]);
71
+ var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
72
+ var isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
73
+ var samePackageVersions = (left, right) => {
74
+ if (!left || !right) return false;
75
+ const leftEntries = Object.entries(left).sort(
76
+ ([a], [b]) => a.localeCompare(b)
77
+ );
78
+ const rightEntries = Object.entries(right).sort(
79
+ ([a], [b]) => a.localeCompare(b)
80
+ );
81
+ return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
82
+ };
83
+ var runtimeLineageMatchesStrategySnapshot = ({
84
+ lineage,
85
+ deployment,
86
+ strategy
87
+ }) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
88
+ lineage.strategyDependencyVersions,
89
+ strategy.strategyDependencyVersions
90
+ );
91
+ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
92
+ if (!isRecord(value) || value.schemaVersion !== 2 || !isNonEmptyString(value.id) || !isNonEmptyString(value.deploymentCompositionId) || !/^dc1:[a-f0-9]{16}$/.test(value.deploymentCompositionId) || !isNonEmptyString(value.label) || !isNonEmptyString(value.connectorName) || !isNonEmptyString(value.provider) || !isNonEmptyString(value.accountId) || typeof value.enabled !== "boolean" || !Array.isArray(value.strategies)) {
93
+ throw new Error(
94
+ "Runtime evidence deployment snapshot is missing or invalid"
95
+ );
96
+ }
97
+ const strategies = value.strategies.map((candidate) => {
98
+ if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !isNonEmptyString(candidate.strategyRevision) || !/^sr1:[a-f0-9]{16}$/.test(candidate.strategyRevision) || typeof candidate.enabled !== "boolean" || !["active", "entries_paused"].includes(String(candidate.controlState)) || !INTERVALS.has(String(candidate.interval)) || !UNIVERSES.has(String(candidate.universe)) || !isNonEmptyString(candidate.strategyPackage) || !isNonEmptyString(candidate.strategyPackageVersion) || !isPackageVersionMap(candidate.strategyDependencyVersions) || !isNonEmptyString(candidate.runtimePackageVersion) || !isRecord(candidate.strategyConfig) || !isRuntimeStrategySelection(candidate.selection)) {
99
+ throw new Error(
100
+ "Runtime evidence deployment strategy snapshot is invalid"
101
+ );
102
+ }
103
+ if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
104
+ throw new Error(
105
+ `Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
106
+ );
107
+ }
108
+ if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
109
+ throw new Error(
110
+ `Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
111
+ );
112
+ }
113
+ return candidate;
114
+ });
115
+ const identities = /* @__PURE__ */ new Set();
116
+ for (const strategy of strategies) {
117
+ if (identities.has(strategy.strategyName)) {
118
+ throw new Error(
119
+ `Duplicate runtime evidence strategy: ${strategy.strategyName}`
120
+ );
121
+ }
122
+ identities.add(strategy.strategyName);
123
+ }
124
+ return {
125
+ ...value,
126
+ strategies
127
+ };
128
+ };
129
+ var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
130
+ var unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
131
+ const record = isRecord(candidate) ? candidate : null;
132
+ const nested = record && isRecord(record[field]) ? record[field] : null;
133
+ return nested ?? record;
134
+ }).filter((record) => record != null);
135
+ var assertCurrentRuntimeEvidenceArtifact = (artifact) => {
136
+ if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
137
+ throw new Error("Invalid runtime evidence artifact");
138
+ }
139
+ const deployment = parseRuntimeEvidenceDeploymentSnapshot(
140
+ artifact.deployment
141
+ );
142
+ const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
143
+ if (activeStrategies.length === 0) {
144
+ throw new Error("Runtime evidence deployment has no enabled strategies");
145
+ }
146
+ const runtime = isRecord(artifact.runtime) ? artifact.runtime : null;
147
+ if (!runtime) {
148
+ throw new Error("Runtime evidence payload is missing");
149
+ }
150
+ if ("strategyConfigs" in runtime) {
151
+ throw new Error(
152
+ "Runtime evidence payload contains removed strategyConfigs data"
153
+ );
154
+ }
155
+ const rowFields = [
156
+ "trades",
157
+ "signals",
158
+ "evaluations",
159
+ "lineageScopes"
160
+ ];
161
+ for (const field of rowFields) {
162
+ if (!Array.isArray(runtime[field])) {
163
+ throw new Error(`Runtime evidence payload ${field} must be an array`);
164
+ }
165
+ }
166
+ const snapshots = new Map(
167
+ activeStrategies.map((strategy) => [strategy.strategyName, strategy])
168
+ );
169
+ const assertRows = (label, rows, lineageField) => {
170
+ for (const row of rows) {
171
+ const strategyName = String(row.strategy ?? "").trim();
172
+ const strategy = snapshots.get(strategyName);
173
+ if (!strategy || row.deploymentId !== deployment.id || row.accountId !== deployment.accountId || !runtimeLineageMatchesStrategySnapshot({
174
+ lineage: isRecord(row[lineageField]) ? row[lineageField] : void 0,
175
+ deployment,
176
+ strategy
177
+ })) {
178
+ throw new Error(
179
+ `Runtime evidence ${label} row is outside the current embedded deployment lineage`
180
+ );
181
+ }
182
+ }
183
+ };
184
+ assertRows(
185
+ "trade",
186
+ unwrapRuntimeEvidenceRows(runtime.trades, "trade"),
187
+ "runtimeLineage"
188
+ );
189
+ assertRows(
190
+ "signal",
191
+ unwrapRuntimeEvidenceRows(runtime.signals, "signal"),
192
+ "runtimeLineage"
193
+ );
194
+ assertRows(
195
+ "evaluation",
196
+ unwrapRuntimeEvidenceRows(runtime.evaluations, "evaluation"),
197
+ "runtimeLineage"
198
+ );
199
+ assertRows(
200
+ "lineage scope",
201
+ unwrapRuntimeEvidenceRows(runtime.lineageScopes, "lineageScope"),
202
+ "lineage"
203
+ );
204
+ return deployment;
205
+ };
206
+
207
+ // src/lib/runtimeEvidenceArtifacts.ts
50
208
  var RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
51
209
  var RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
52
210
  var RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
@@ -116,6 +274,10 @@ var verifyRuntimeEvidenceBundle = async (bundleDir) => {
116
274
  if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
117
275
  throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
118
276
  }
277
+ const deployment = assertCurrentRuntimeEvidenceArtifact(artifact);
278
+ if (deployment.id !== manifest.deploymentId) {
279
+ throw new Error(`Runtime evidence deployment mismatch in ${bundleDir}`);
280
+ }
119
281
  return {
120
282
  bundleDir,
121
283
  manifestPath,
@@ -150,70 +312,6 @@ var discoverRuntimeEvidenceBundles = async (rootDir) => {
150
312
  return bundles.sort();
151
313
  };
152
314
 
153
- // src/lib/runtimeEvidenceDeployment.ts
154
- var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
155
- var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
156
- var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
157
- var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
158
- ([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
159
- );
160
- var INTERVALS = /* @__PURE__ */ new Set([
161
- "1",
162
- "3",
163
- "5",
164
- "15",
165
- "30",
166
- "60",
167
- "120",
168
- "240",
169
- "360",
170
- "720",
171
- "D",
172
- "W",
173
- "M"
174
- ]);
175
- var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
176
- var isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
177
- var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
178
- if (!isRecord(value) || value.schemaVersion !== 2 || !isNonEmptyString(value.id) || !isNonEmptyString(value.deploymentCompositionId) || !/^dc1:[a-f0-9]{16}$/.test(value.deploymentCompositionId) || !isNonEmptyString(value.label) || !isNonEmptyString(value.connectorName) || !isNonEmptyString(value.provider) || !isNonEmptyString(value.accountId) || typeof value.enabled !== "boolean" || !Array.isArray(value.strategies)) {
179
- throw new Error(
180
- "Runtime evidence deployment snapshot is missing or invalid"
181
- );
182
- }
183
- const strategies = value.strategies.map((candidate) => {
184
- if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !isNonEmptyString(candidate.strategyRevision) || !/^sr1:[a-f0-9]{16}$/.test(candidate.strategyRevision) || typeof candidate.enabled !== "boolean" || !["active", "entries_paused"].includes(String(candidate.controlState)) || !INTERVALS.has(String(candidate.interval)) || !UNIVERSES.has(String(candidate.universe)) || !isNonEmptyString(candidate.strategyPackage) || !isNonEmptyString(candidate.strategyPackageVersion) || !isPackageVersionMap(candidate.strategyDependencyVersions) || !isNonEmptyString(candidate.runtimePackageVersion) || !isRecord(candidate.strategyConfig) || !isRuntimeStrategySelection(candidate.selection)) {
185
- throw new Error(
186
- "Runtime evidence deployment strategy snapshot is invalid"
187
- );
188
- }
189
- if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
190
- throw new Error(
191
- `Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
192
- );
193
- }
194
- if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
195
- throw new Error(
196
- `Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
197
- );
198
- }
199
- return candidate;
200
- });
201
- const identities = /* @__PURE__ */ new Set();
202
- for (const strategy of strategies) {
203
- if (identities.has(strategy.strategyName)) {
204
- throw new Error(
205
- `Duplicate runtime evidence strategy: ${strategy.strategyName}`
206
- );
207
- }
208
- identities.add(strategy.strategyName);
209
- }
210
- return {
211
- ...value,
212
- strategies
213
- };
214
- };
215
- var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
216
-
217
315
  // src/lib/runtimeEvidenceSync.ts
218
316
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
219
317
  var isExistingDestinationError = (error) => {
@@ -247,25 +345,7 @@ var buildRuntimeEvidenceRsyncArgs = ({
247
345
  ];
248
346
  var receiptPath = (receiptsRoot, artifactId) => import_node_path2.default.join(receiptsRoot, `${safeSegment(artifactId, "artifact")}.json`);
249
347
  var compareBundles = (left, right) => left.manifest.window.endTime - right.manifest.window.endTime || left.manifest.createdAt - right.manifest.createdAt;
250
- var inspectRuntimeEvidenceBundleSupport = (bundle) => {
251
- try {
252
- const deployment = parseRuntimeEvidenceDeploymentSnapshot(
253
- bundle.artifact.deployment
254
- );
255
- if (activeRuntimeEvidenceStrategies(deployment).length === 0) {
256
- throw new Error(
257
- "Runtime evidence deployment has no enabled active strategies"
258
- );
259
- }
260
- return { supported: true };
261
- } catch (error) {
262
- return {
263
- supported: false,
264
- reason: error instanceof Error ? error.message : String(error)
265
- };
266
- }
267
- };
268
- var listRuntimeEvidenceBundleStatuses = async ({
348
+ var listPendingRuntimeEvidenceBundles = async ({
269
349
  evidenceRoot,
270
350
  deploymentId
271
351
  }) => {
@@ -274,39 +354,19 @@ var listRuntimeEvidenceBundleStatuses = async ({
274
354
  const receiptsRoot = import_node_path2.default.join(evidenceRoot, "receipts", safeDeploymentId);
275
355
  const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
276
356
  const pending = [];
277
- const unsupported = [];
278
357
  for (const bundleDir of bundles) {
279
358
  const verified = await verifyRuntimeEvidenceBundle(bundleDir);
280
359
  if (verified.manifest.deploymentId !== safeDeploymentId) continue;
360
+ assertCurrentRuntimeEvidenceArtifact(verified.artifact);
281
361
  try {
282
362
  await import_promises2.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
283
363
  continue;
284
364
  } catch (error) {
285
365
  if (error.code !== "ENOENT") throw error;
286
366
  }
287
- const support = inspectRuntimeEvidenceBundleSupport(verified);
288
- if (support.supported) {
289
- pending.push(verified);
290
- } else {
291
- unsupported.push({ bundle: verified, reason: support.reason });
292
- }
367
+ pending.push(verified);
293
368
  }
294
- return {
295
- pending: pending.sort(compareBundles),
296
- unsupported: unsupported.sort(
297
- (left, right) => compareBundles(left.bundle, right.bundle)
298
- )
299
- };
300
- };
301
- var listPendingRuntimeEvidenceBundles = async ({
302
- evidenceRoot,
303
- deploymentId
304
- }) => {
305
- const { pending } = await listRuntimeEvidenceBundleStatuses({
306
- evidenceRoot,
307
- deploymentId
308
- });
309
- return pending;
369
+ return pending.sort(compareBundles);
310
370
  };
311
371
  var markRuntimeEvidenceBundleProcessed = async ({
312
372
  evidenceRoot,
@@ -373,6 +433,7 @@ var syncRuntimeEvidenceBundles = async ({
373
433
  `Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
374
434
  );
375
435
  }
436
+ assertCurrentRuntimeEvidenceArtifact(verified.artifact);
376
437
  const destinationDir = import_node_path2.default.join(
377
438
  artifactsRoot,
378
439
  ...dateParts(verified.manifest.window.endTime),
@@ -393,7 +454,7 @@ var syncRuntimeEvidenceBundles = async ({
393
454
  }
394
455
  received.push(await verifyRuntimeEvidenceBundle(destinationDir));
395
456
  }
396
- const statuses = await listRuntimeEvidenceBundleStatuses({
457
+ const pending = await listPendingRuntimeEvidenceBundles({
397
458
  evidenceRoot,
398
459
  deploymentId: safeDeploymentId
399
460
  });
@@ -402,15 +463,13 @@ var syncRuntimeEvidenceBundles = async ({
402
463
  stdout: String(transfer.stdout ?? ""),
403
464
  stderr: String(transfer.stderr ?? ""),
404
465
  received,
405
- ...statuses
466
+ pending
406
467
  };
407
468
  };
408
469
  // Annotate the CommonJS export names for ESM import in node:
409
470
  0 && (module.exports = {
410
471
  buildRuntimeEvidenceRsyncArgs,
411
- inspectRuntimeEvidenceBundleSupport,
412
472
  listPendingRuntimeEvidenceBundles,
413
- listRuntimeEvidenceBundleStatuses,
414
473
  markRuntimeEvidenceBundleProcessed,
415
474
  syncRuntimeEvidenceBundles
416
475
  });