@tradejs/cli 3.1.8 → 3.1.9-beta.214
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/dist/cli.js +856 -334
- package/dist/lib/runEnvironment.js +88 -48
- package/dist/lib/runtimeDebugEvidence.js +48 -12
- package/dist/lib/runtimeEvidenceDeployment.js +162 -0
- package/dist/lib/runtimeLineage.js +9 -1
- package/dist/lib/runtimeScorecard.js +119 -8
- package/dist/lib/runtimeSignalsLoader.js +8 -4
- package/dist/scripts/backtest.js +50 -49
- package/dist/scripts/replay.js +921 -648
- package/dist/scripts/replayRunner.js +921 -648
- package/dist/scripts/replayRuntimeEvidence.js +50 -13
- package/dist/scripts/runtimeEvidence.js +136 -18
- package/dist/scripts/runtimeScorecard.js +143 -44
- package/dist/scripts/signals.js +47 -8
- package/dist/scripts/signalsDaemon.js +47 -8
- package/dist/scripts/signalsSummary.js +12 -5
- package/package.json +7 -7
|
@@ -34,9 +34,9 @@ __export(runtimeScorecard_exports, {
|
|
|
34
34
|
runtimeScorecard: () => runtimeScorecard
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(runtimeScorecard_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
37
|
+
var import_promises6 = __toESM(require("fs/promises"));
|
|
38
|
+
var import_node_crypto5 = require("crypto");
|
|
39
|
+
var import_node_path6 = __toESM(require("path"));
|
|
40
40
|
var import_args = __toESM(require("args"));
|
|
41
41
|
var import_chalk = __toESM(require("chalk"));
|
|
42
42
|
|
|
@@ -192,6 +192,37 @@ var markRuntimeEvidenceBundleProcessed = async ({
|
|
|
192
192
|
return finalPath;
|
|
193
193
|
};
|
|
194
194
|
|
|
195
|
+
// src/lib/runtimeLineage.ts
|
|
196
|
+
var import_node_child_process2 = require("child_process");
|
|
197
|
+
var import_node_crypto3 = require("crypto");
|
|
198
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
199
|
+
var import_node_path4 = __toESM(require("path"));
|
|
200
|
+
var import_types = require("@tradejs/types");
|
|
201
|
+
var import_strategies = require("@tradejs/node/strategies");
|
|
202
|
+
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
203
|
+
|
|
204
|
+
// src/lib/strategyGateFingerprint.ts
|
|
205
|
+
var import_node_crypto2 = require("crypto");
|
|
206
|
+
var import_node_module = require("module");
|
|
207
|
+
var import_promises3 = __toESM(require("fs/promises"));
|
|
208
|
+
var import_node_path3 = __toESM(require("path"));
|
|
209
|
+
|
|
210
|
+
// src/lib/runtimeLineage.ts
|
|
211
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
212
|
+
"v2",
|
|
213
|
+
lineage.version,
|
|
214
|
+
lineage.strategyPackageVersion ?? "strategy:unknown",
|
|
215
|
+
lineage.runtimePackageVersion ?? "runtime:unknown"
|
|
216
|
+
].join(":") : [
|
|
217
|
+
lineage.schemaVersion,
|
|
218
|
+
lineage.compositionId ?? "unbound-composition",
|
|
219
|
+
lineage.gitSha ?? "unknown",
|
|
220
|
+
lineage.gitDirty == null ? "unknown" : lineage.gitDirty ? "dirty" : "clean",
|
|
221
|
+
lineage.gateFingerprint,
|
|
222
|
+
lineage.configFingerprint,
|
|
223
|
+
lineage.contextFingerprint
|
|
224
|
+
].join(":");
|
|
225
|
+
|
|
195
226
|
// src/lib/runtimeScorecard.ts
|
|
196
227
|
var asRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
197
228
|
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
@@ -213,15 +244,32 @@ var extractRuntimeRows = (artifact) => {
|
|
|
213
244
|
evaluations: unwrapRows(runtime.evaluations, "evaluation"),
|
|
214
245
|
signals: unwrapRows(runtime.signals, "signal"),
|
|
215
246
|
trades: unwrapRows(runtime.trades, "trade"),
|
|
247
|
+
lineageScopes: unwrapRows(runtime.lineageScopes, "lineageScope"),
|
|
216
248
|
statsBuckets: asArray(runtime.evaluationStatsBuckets).map(asRecord2).filter((item) => item != null)
|
|
217
249
|
};
|
|
218
250
|
};
|
|
219
251
|
var buildRuntimeLineageSummary = (rows) => {
|
|
220
|
-
const lineageRows = [
|
|
252
|
+
const lineageRows = [
|
|
253
|
+
...rows.evaluations,
|
|
254
|
+
...rows.signals,
|
|
255
|
+
...rows.trades,
|
|
256
|
+
...rows.lineageScopes.map((scope) => ({
|
|
257
|
+
runtimeLineage: scope.lineage
|
|
258
|
+
}))
|
|
259
|
+
];
|
|
221
260
|
const lineages = lineageRows.map((row) => asRecord2(row.runtimeLineage)).filter((lineage) => lineage != null);
|
|
222
261
|
const identities = /* @__PURE__ */ new Map();
|
|
223
262
|
for (const lineage of lineages) {
|
|
224
|
-
const identity2 = {
|
|
263
|
+
const identity2 = lineage.schemaVersion === 2 ? {
|
|
264
|
+
schemaVersion: 2,
|
|
265
|
+
version: finiteNumber(lineage.version),
|
|
266
|
+
strategyPackageVersion: finiteString(
|
|
267
|
+
lineage.strategyPackageVersion
|
|
268
|
+
),
|
|
269
|
+
runtimePackageVersion: finiteString(lineage.runtimePackageVersion),
|
|
270
|
+
maxLossValue: finiteNumber(lineage.maxLossValue)
|
|
271
|
+
} : {
|
|
272
|
+
schemaVersion: 1,
|
|
225
273
|
compositionId: finiteString(lineage.compositionId),
|
|
226
274
|
gitSha: finiteString(lineage.gitSha),
|
|
227
275
|
gitDirty: typeof lineage.gitDirty === "boolean" ? lineage.gitDirty : null,
|
|
@@ -233,12 +281,23 @@ var buildRuntimeLineageSummary = (rows) => {
|
|
|
233
281
|
identities.set(JSON.stringify(identity2), identity2);
|
|
234
282
|
}
|
|
235
283
|
const identity = identities.size === 1 ? [...identities.values()][0] : null;
|
|
236
|
-
const
|
|
284
|
+
const schemaVersion = finiteNumber(identity?.schemaVersion);
|
|
285
|
+
const identityComplete = lineages.length > 0 && identity != null && (schemaVersion === 2 && finiteNumber(identity.version) != null && finiteString(identity.strategyPackageVersion) != null && finiteString(identity.runtimePackageVersion) != null || schemaVersion === 1 && identity.compositionId != null && identity.gitSha != null && identity.gitDirty === false && identity.gateFingerprint != null && identity.configFingerprint != null && identity.contextFingerprint != null) && identity.maxLossValue != null;
|
|
286
|
+
const coverageComplete = lineageRows.length > 0 && lineages.length === lineageRows.length;
|
|
287
|
+
const complete = identityComplete && coverageComplete;
|
|
288
|
+
const lineageKey = identityComplete ? runtimeLineageKey(identity) : null;
|
|
237
289
|
return {
|
|
238
290
|
complete,
|
|
291
|
+
identityComplete,
|
|
292
|
+
coverageComplete,
|
|
239
293
|
conflicts: identities.size > 1,
|
|
240
294
|
rows: lineageRows.length,
|
|
241
295
|
rowsWithLineage: lineages.length,
|
|
296
|
+
schemaVersion,
|
|
297
|
+
lineageKey,
|
|
298
|
+
version: finiteNumber(identity?.version),
|
|
299
|
+
strategyPackageVersion: finiteString(identity?.strategyPackageVersion),
|
|
300
|
+
runtimePackageVersion: finiteString(identity?.runtimePackageVersion),
|
|
242
301
|
compositionId: finiteString(identity?.compositionId),
|
|
243
302
|
gitSha: finiteString(identity?.gitSha),
|
|
244
303
|
gitDirty: typeof identity?.gitDirty === "boolean" ? identity.gitDirty : null,
|
|
@@ -248,6 +307,20 @@ var buildRuntimeLineageSummary = (rows) => {
|
|
|
248
307
|
maxLossValue: finiteNumber(identity?.maxLossValue)
|
|
249
308
|
};
|
|
250
309
|
};
|
|
310
|
+
var belongsToRuntimeLineage = (row, summary) => {
|
|
311
|
+
if (!summary.identityComplete || !summary.lineageKey) return false;
|
|
312
|
+
const lineage = asRecord2(row.runtimeLineage);
|
|
313
|
+
if (!lineage) return false;
|
|
314
|
+
return runtimeLineageKey(lineage) === summary.lineageKey && finiteNumber(lineage.maxLossValue) === summary.maxLossValue;
|
|
315
|
+
};
|
|
316
|
+
var runtimeDeploymentBinding = (artifact) => {
|
|
317
|
+
const deployment = asRecord2(asRecord2(artifact)?.deployment);
|
|
318
|
+
return {
|
|
319
|
+
deploymentId: finiteString(deployment?.id),
|
|
320
|
+
accountId: finiteString(deployment?.accountId)
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
var belongsToRuntimeDeployment = (row, binding) => binding.deploymentId == null && binding.accountId == null ? true : finiteString(row.deploymentId) === binding.deploymentId && finiteString(row.accountId) === binding.accountId;
|
|
251
324
|
var belongsToStrategy = (row, strategy) => strategy == null || finiteString(row.strategy) === strategy;
|
|
252
325
|
var filterArtifactByStrategy = (artifact, strategy) => {
|
|
253
326
|
if (!strategy) return artifact;
|
|
@@ -275,6 +348,9 @@ var filterArtifactByStrategy = (artifact, strategy) => {
|
|
|
275
348
|
strategy
|
|
276
349
|
)
|
|
277
350
|
),
|
|
351
|
+
lineageScopes: asArray(runtime.lineageScopes).filter(
|
|
352
|
+
(item) => belongsToStrategy(asRecord2(item) ?? {}, strategy)
|
|
353
|
+
),
|
|
278
354
|
evaluationStatsBuckets: asArray(runtime.evaluationStatsBuckets).filter(
|
|
279
355
|
(item) => belongsToStrategy(asRecord2(item) ?? {}, strategy)
|
|
280
356
|
)
|
|
@@ -454,6 +530,7 @@ var buildRuntimeScorecard = ({
|
|
|
454
530
|
const scopedHistoryArtifacts = historyRuntimeArtifacts.map(
|
|
455
531
|
(artifact) => filterArtifactByStrategy(artifact, strategy)
|
|
456
532
|
);
|
|
533
|
+
const deploymentBinding = runtimeDeploymentBinding(runtimeArtifact);
|
|
457
534
|
const rows = extractRuntimeRows(scopedRuntimeArtifact);
|
|
458
535
|
const runtimeLineage = buildRuntimeLineageSummary(rows);
|
|
459
536
|
const window = runtimeWindow(runtimeArtifact);
|
|
@@ -516,6 +593,12 @@ var buildRuntimeScorecard = ({
|
|
|
516
593
|
...scopedHistoryArtifacts,
|
|
517
594
|
scopedRuntimeArtifact
|
|
518
595
|
]);
|
|
596
|
+
const comparableHistoryTrades = historyTrades.filter(
|
|
597
|
+
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && belongsToRuntimeLineage(trade, runtimeLineage)
|
|
598
|
+
);
|
|
599
|
+
const comparableCurrentClosedTrades = currentClosedTrades.filter(
|
|
600
|
+
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && belongsToRuntimeLineage(trade, runtimeLineage)
|
|
601
|
+
);
|
|
519
602
|
const currentDistributions = buildDistributions(rows);
|
|
520
603
|
const previousArtifact = scopedHistoryArtifacts.map((artifact) => ({ artifact, window: runtimeWindow(artifact) })).filter(({ window: candidateWindow }) => {
|
|
521
604
|
const candidateEndTime = finiteNumber(candidateWindow.endTime);
|
|
@@ -526,7 +609,7 @@ var buildRuntimeScorecard = ({
|
|
|
526
609
|
const previousDistributions = previousArtifact ? buildDistributions(extractRuntimeRows(previousArtifact.artifact)) : null;
|
|
527
610
|
const rolling = [7, 30, 90].map(
|
|
528
611
|
(days) => buildRollingPerformance({
|
|
529
|
-
trades: [...
|
|
612
|
+
trades: [...comparableHistoryTrades],
|
|
530
613
|
anchorTime: endTime,
|
|
531
614
|
days
|
|
532
615
|
})
|
|
@@ -540,6 +623,13 @@ var buildRuntimeScorecard = ({
|
|
|
540
623
|
message: lineageReason
|
|
541
624
|
});
|
|
542
625
|
}
|
|
626
|
+
if (!runtimeLineage.complete) {
|
|
627
|
+
reactions.push({
|
|
628
|
+
code: "RUNTIME_LINEAGE_INCOMPLETE",
|
|
629
|
+
severity: "blocking",
|
|
630
|
+
message: "Runtime rows do not share one complete composition lineage."
|
|
631
|
+
});
|
|
632
|
+
}
|
|
543
633
|
if (parityRatio != null && parityRatio < thresholds.minimumParityRatio) {
|
|
544
634
|
reactions.push({
|
|
545
635
|
code: "PARITY_REGRESSION",
|
|
@@ -577,6 +667,7 @@ var buildRuntimeScorecard = ({
|
|
|
577
667
|
generatedAt,
|
|
578
668
|
window: { startTime, endTime },
|
|
579
669
|
strategy,
|
|
670
|
+
deployment: deploymentBinding,
|
|
580
671
|
lineage: runtimeLineage,
|
|
581
672
|
promotionStatus,
|
|
582
673
|
thresholds,
|
|
@@ -621,17 +712,25 @@ var buildRuntimeScorecard = ({
|
|
|
621
712
|
)
|
|
622
713
|
).length,
|
|
623
714
|
fills: rows.trades.length,
|
|
624
|
-
closedTrades: currentClosedTrades.length
|
|
715
|
+
closedTrades: currentClosedTrades.length,
|
|
716
|
+
comparableClosedTrades: comparableCurrentClosedTrades.length,
|
|
717
|
+
nonComparableClosedTrades: currentClosedTrades.length - comparableCurrentClosedTrades.length
|
|
625
718
|
},
|
|
626
719
|
realized: {
|
|
627
720
|
pnl: sum(
|
|
628
|
-
|
|
721
|
+
comparableCurrentClosedTrades.map(
|
|
722
|
+
(trade) => finiteNumber(trade.closedPnl)
|
|
723
|
+
)
|
|
629
724
|
),
|
|
630
725
|
fees: sum(
|
|
631
|
-
|
|
726
|
+
comparableCurrentClosedTrades.map(
|
|
727
|
+
(trade) => finiteNumber(trade.totalFee)
|
|
728
|
+
)
|
|
632
729
|
),
|
|
633
730
|
funding: sum(
|
|
634
|
-
|
|
731
|
+
comparableCurrentClosedTrades.map(
|
|
732
|
+
(trade) => finiteNumber(trade.fundingFee)
|
|
733
|
+
)
|
|
635
734
|
)
|
|
636
735
|
},
|
|
637
736
|
gateComparison: {
|
|
@@ -749,14 +848,14 @@ ${reactions}
|
|
|
749
848
|
};
|
|
750
849
|
|
|
751
850
|
// src/lib/strategyRelease.ts
|
|
752
|
-
var
|
|
753
|
-
var
|
|
754
|
-
var
|
|
755
|
-
var
|
|
756
|
-
var
|
|
851
|
+
var import_node_crypto4 = require("crypto");
|
|
852
|
+
var import_promises5 = __toESM(require("fs/promises"));
|
|
853
|
+
var import_node_path5 = __toESM(require("path"));
|
|
854
|
+
var import_types3 = require("@tradejs/types");
|
|
855
|
+
var import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
757
856
|
|
|
758
857
|
// src/lib/strategyRelease/liveDiagnosis.ts
|
|
759
|
-
var
|
|
858
|
+
var import_types2 = require("@tradejs/types");
|
|
760
859
|
var buildStrategyLiveDiagnosis = (input) => {
|
|
761
860
|
const minimumClosedTrades = input.minimumClosedTrades ?? 20;
|
|
762
861
|
const minimumParityRatio = input.minimumParityRatio ?? 0.95;
|
|
@@ -784,7 +883,7 @@ var buildStrategyLiveDiagnosis = (input) => {
|
|
|
784
883
|
attributionIncomplete && verdict === "GENERALIZATION_FAILURE" ? "Collect matched shadow raw-core, deterministic-gate, and causal regime evidence without changing the composition." : "Collect more verified prospective outcomes without changing the composition."
|
|
785
884
|
];
|
|
786
885
|
return {
|
|
787
|
-
schema:
|
|
886
|
+
schema: import_types2.STRATEGY_LIVE_DIAGNOSIS_SCHEMA,
|
|
788
887
|
strategy: input.strategy,
|
|
789
888
|
compositionId: input.compositionId,
|
|
790
889
|
createdAt: input.createdAt,
|
|
@@ -861,10 +960,10 @@ var buildStrategyLiveDiagnosisFromScorecard = ({
|
|
|
861
960
|
// src/lib/strategyRelease.ts
|
|
862
961
|
var SHA256_RE = /^[a-f0-9]{64}$/;
|
|
863
962
|
var LINEAGE_FINGERPRINT_RE = /^[a-f0-9]{16}$/;
|
|
864
|
-
var safeSegment2 =
|
|
865
|
-
var compactTimestamp =
|
|
866
|
-
var canonicalStrategyReleaseJson = (value) => (0,
|
|
867
|
-
var strategyReleaseSha256 = (value) => (0,
|
|
963
|
+
var safeSegment2 = import_strategyReleaseEvidence2.safeStrategyEvidenceSegment;
|
|
964
|
+
var compactTimestamp = import_strategyReleaseEvidence2.compactStrategyEvidenceTimestamp;
|
|
965
|
+
var canonicalStrategyReleaseJson = (value) => (0, import_strategyReleaseEvidence2.canonicalStrategyEvidenceJson)(value);
|
|
966
|
+
var strategyReleaseSha256 = (value) => (0, import_strategyReleaseEvidence2.strategyEvidenceSha256)(value);
|
|
868
967
|
function assert(condition, message) {
|
|
869
968
|
if (!condition) throw new Error(`Invalid strategy release: ${message}`);
|
|
870
969
|
}
|
|
@@ -1233,7 +1332,7 @@ var createStrategyReleaseManifest = (input) => {
|
|
|
1233
1332
|
verdict
|
|
1234
1333
|
};
|
|
1235
1334
|
return {
|
|
1236
|
-
schema:
|
|
1335
|
+
schema: import_types3.STRATEGY_RELEASE_SCHEMA,
|
|
1237
1336
|
releaseId: `${safeSegment2(input.strategy, "strategy")}_${compactTimestamp(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
|
|
1238
1337
|
strategy: input.strategy,
|
|
1239
1338
|
createdAt: input.createdAt,
|
|
@@ -1252,7 +1351,7 @@ var createStrategyReleaseManifest = (input) => {
|
|
|
1252
1351
|
};
|
|
1253
1352
|
};
|
|
1254
1353
|
var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
1255
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
1354
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises5.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
1256
1355
|
const envelope = value;
|
|
1257
1356
|
assert(
|
|
1258
1357
|
envelope?.schema === "tradejs-strategy-release-envelope/v1",
|
|
@@ -1268,7 +1367,7 @@ var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
|
1268
1367
|
);
|
|
1269
1368
|
const manifest = envelope.manifest;
|
|
1270
1369
|
assert(
|
|
1271
|
-
manifest.schema ===
|
|
1370
|
+
manifest.schema === import_types3.STRATEGY_RELEASE_SCHEMA,
|
|
1272
1371
|
"manifest schema mismatch"
|
|
1273
1372
|
);
|
|
1274
1373
|
const rebuilt = createStrategyReleaseManifest({
|
|
@@ -1303,19 +1402,19 @@ var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
|
1303
1402
|
return envelope;
|
|
1304
1403
|
};
|
|
1305
1404
|
var verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
|
|
1306
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
1307
|
-
return (0,
|
|
1405
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises5.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
1406
|
+
return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
|
|
1308
1407
|
};
|
|
1309
1408
|
var writeJsonAtomic = async (filePath, value) => {
|
|
1310
1409
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
1311
|
-
await
|
|
1312
|
-
await
|
|
1410
|
+
await import_promises5.default.mkdir(import_node_path5.default.dirname(filePath), { recursive: true });
|
|
1411
|
+
await import_promises5.default.writeFile(
|
|
1313
1412
|
temporaryPath,
|
|
1314
1413
|
`${canonicalStrategyReleaseJson(value)}
|
|
1315
1414
|
`,
|
|
1316
1415
|
"utf8"
|
|
1317
1416
|
);
|
|
1318
|
-
await
|
|
1417
|
+
await import_promises5.default.rename(temporaryPath, filePath);
|
|
1319
1418
|
};
|
|
1320
1419
|
var publishStrategyLiveDiagnosis = async ({
|
|
1321
1420
|
rootDir,
|
|
@@ -1375,19 +1474,19 @@ var publishStrategyLiveDiagnosis = async ({
|
|
|
1375
1474
|
severity: diagnosis.verdict === "EXPECTED_DRAWDOWN" ? "info" : "warning"
|
|
1376
1475
|
}
|
|
1377
1476
|
];
|
|
1378
|
-
const markerEnvelope = (0,
|
|
1477
|
+
const markerEnvelope = (0, import_strategyReleaseEvidence2.createStrategyEvidenceMarkerEnvelope)({
|
|
1379
1478
|
strategy: diagnosis.strategy,
|
|
1380
1479
|
createdAt: diagnosis.createdAt,
|
|
1381
1480
|
markers,
|
|
1382
1481
|
sourceArtifacts
|
|
1383
1482
|
});
|
|
1384
|
-
const diagnosisPath =
|
|
1483
|
+
const diagnosisPath = import_node_path5.default.join(
|
|
1385
1484
|
rootDir,
|
|
1386
1485
|
"diagnoses",
|
|
1387
1486
|
safeSegment2(diagnosis.strategy, "strategy"),
|
|
1388
1487
|
`${diagnosisId}.json`
|
|
1389
1488
|
);
|
|
1390
|
-
const markerPath =
|
|
1489
|
+
const markerPath = import_node_path5.default.join(
|
|
1391
1490
|
rootDir,
|
|
1392
1491
|
"markers",
|
|
1393
1492
|
safeSegment2(diagnosis.strategy, "strategy"),
|
|
@@ -1459,15 +1558,15 @@ var flags = import_args.default.parse(process.argv);
|
|
|
1459
1558
|
var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
1460
1559
|
var resolveOptionalPath = (value) => {
|
|
1461
1560
|
const raw = String(value ?? "").trim();
|
|
1462
|
-
return raw ?
|
|
1561
|
+
return raw ? import_node_path6.default.resolve(projectRoot, raw) : null;
|
|
1463
1562
|
};
|
|
1464
|
-
var readJson = async (filePath) => filePath ? JSON.parse(await
|
|
1563
|
+
var readJson = async (filePath) => filePath ? JSON.parse(await import_promises6.default.readFile(filePath, "utf8")) : void 0;
|
|
1465
1564
|
var assertReportType = (artifact, expected, label) => {
|
|
1466
1565
|
if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
|
|
1467
1566
|
throw new Error(`${label} must be a ${expected} artifact`);
|
|
1468
1567
|
}
|
|
1469
1568
|
};
|
|
1470
|
-
var sha256File = async (filePath) => (0,
|
|
1569
|
+
var sha256File = async (filePath) => (0, import_node_crypto5.createHash)("sha256").update(await import_promises6.default.readFile(filePath)).digest("hex");
|
|
1471
1570
|
var loadHistoryArtifacts = async (historyDir) => {
|
|
1472
1571
|
if (!historyDir) return [];
|
|
1473
1572
|
const bundleDirs = await discoverRuntimeEvidenceBundles(historyDir);
|
|
@@ -1537,13 +1636,13 @@ var runtimeScorecard = async () => {
|
|
|
1537
1636
|
strategy: scorecardStrategy,
|
|
1538
1637
|
llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
|
|
1539
1638
|
});
|
|
1540
|
-
const outPath =
|
|
1639
|
+
const outPath = import_node_path6.default.resolve(projectRoot, String(flags.out));
|
|
1541
1640
|
const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
|
|
1542
|
-
await
|
|
1641
|
+
await import_promises6.default.mkdir(import_node_path6.default.dirname(outPath), { recursive: true });
|
|
1543
1642
|
await Promise.all([
|
|
1544
|
-
|
|
1643
|
+
import_promises6.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
|
|
1545
1644
|
`, "utf8"),
|
|
1546
|
-
|
|
1645
|
+
import_promises6.default.writeFile(
|
|
1547
1646
|
markdownPath,
|
|
1548
1647
|
formatRuntimeScorecardMarkdown(scorecard),
|
|
1549
1648
|
"utf8"
|
|
@@ -1557,7 +1656,7 @@ var runtimeScorecard = async () => {
|
|
|
1557
1656
|
const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
|
|
1558
1657
|
const strategyReleaseRoot = resolveOptionalPath(flags.strategyReleaseRoot);
|
|
1559
1658
|
if (diagnosis && diagnosisPath) {
|
|
1560
|
-
await
|
|
1659
|
+
await import_promises6.default.writeFile(
|
|
1561
1660
|
diagnosisPath,
|
|
1562
1661
|
`${JSON.stringify(diagnosis, null, 2)}
|
|
1563
1662
|
`,
|
|
@@ -1578,7 +1677,7 @@ var runtimeScorecard = async () => {
|
|
|
1578
1677
|
composition: verifiedRelease?.manifest.composition,
|
|
1579
1678
|
sourceArtifacts: await Promise.all(
|
|
1580
1679
|
sourcePaths.map(async (sourcePath) => ({
|
|
1581
|
-
artifactId:
|
|
1680
|
+
artifactId: import_node_path6.default.basename(sourcePath),
|
|
1582
1681
|
path: sourcePath,
|
|
1583
1682
|
sha256: await sha256File(sourcePath)
|
|
1584
1683
|
}))
|
|
@@ -1589,9 +1688,9 @@ var runtimeScorecard = async () => {
|
|
|
1589
1688
|
let receiptPath2 = null;
|
|
1590
1689
|
if (flags.markProcessed) {
|
|
1591
1690
|
receiptPath2 = await markRuntimeEvidenceBundleProcessed({
|
|
1592
|
-
evidenceRoot:
|
|
1691
|
+
evidenceRoot: import_node_path6.default.resolve(projectRoot, String(flags.evidenceDir)),
|
|
1593
1692
|
deploymentId: String(flags.deployment),
|
|
1594
|
-
bundleDir:
|
|
1693
|
+
bundleDir: import_node_path6.default.dirname(runtimeEvidencePath),
|
|
1595
1694
|
scorecardPath: outPath
|
|
1596
1695
|
});
|
|
1597
1696
|
}
|
package/dist/scripts/signals.js
CHANGED
|
@@ -4191,7 +4191,12 @@ async function buildRuntimeLineage({
|
|
|
4191
4191
|
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
4192
4192
|
};
|
|
4193
4193
|
}
|
|
4194
|
-
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
4194
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
4195
|
+
"v2",
|
|
4196
|
+
lineage.version,
|
|
4197
|
+
lineage.strategyPackageVersion ?? "strategy:unknown",
|
|
4198
|
+
lineage.runtimePackageVersion ?? "runtime:unknown"
|
|
4199
|
+
].join(":") : [
|
|
4195
4200
|
lineage.schemaVersion,
|
|
4196
4201
|
lineage.compositionId ?? "unbound-composition",
|
|
4197
4202
|
lineage.gitSha ?? "unknown",
|
|
@@ -4210,9 +4215,28 @@ var buildRuntimeSignalEvaluationId = ({
|
|
|
4210
4215
|
symbol,
|
|
4211
4216
|
timestamp,
|
|
4212
4217
|
runtimeConfigId,
|
|
4213
|
-
runtimeVersion
|
|
4214
|
-
|
|
4218
|
+
runtimeVersion,
|
|
4219
|
+
deploymentId,
|
|
4220
|
+
accountId
|
|
4221
|
+
}) => {
|
|
4222
|
+
const runtimeScope = deploymentId ? [deploymentId, accountId ?? "default-account"] : [];
|
|
4223
|
+
return runtimeVersion ? [
|
|
4224
|
+
...runtimeScope,
|
|
4225
|
+
strategyName,
|
|
4226
|
+
`v${runtimeVersion}`,
|
|
4227
|
+
symbol,
|
|
4228
|
+
timestamp
|
|
4229
|
+
].join(":") : runtimeConfigId && runtimeConfigId !== "config" ? [
|
|
4230
|
+
...runtimeScope,
|
|
4231
|
+
strategyName,
|
|
4232
|
+
runtimeConfigId,
|
|
4233
|
+
symbol,
|
|
4234
|
+
timestamp
|
|
4235
|
+
].join(":") : [...runtimeScope, strategyName, symbol, timestamp].join(":");
|
|
4236
|
+
};
|
|
4215
4237
|
var buildLineageField = (scope) => [
|
|
4238
|
+
scope.deploymentId ?? "default-deployment",
|
|
4239
|
+
scope.accountId ?? "default-account",
|
|
4216
4240
|
scope.strategy,
|
|
4217
4241
|
scope.runtimeConfigId ?? "config",
|
|
4218
4242
|
scope.runtimeVersion ? `v${scope.runtimeVersion}` : "legacy",
|
|
@@ -4254,6 +4278,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4254
4278
|
for (const evaluation of lineageEvaluations) {
|
|
4255
4279
|
const lineageField = buildLineageField({
|
|
4256
4280
|
strategy: evaluation.strategy,
|
|
4281
|
+
deploymentId: evaluation.deploymentId,
|
|
4282
|
+
accountId: evaluation.accountId,
|
|
4257
4283
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4258
4284
|
runtimeVersion: evaluation.runtimeVersion,
|
|
4259
4285
|
symbol: evaluation.symbol,
|
|
@@ -4264,6 +4290,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4264
4290
|
const scope = {
|
|
4265
4291
|
strategy: evaluation.strategy,
|
|
4266
4292
|
symbol: evaluation.symbol,
|
|
4293
|
+
...evaluation.deploymentId ? { deploymentId: evaluation.deploymentId } : {},
|
|
4294
|
+
...evaluation.accountId ? { accountId: evaluation.accountId } : {},
|
|
4267
4295
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4268
4296
|
runtimeVersion: evaluation.runtimeVersion,
|
|
4269
4297
|
lineage: evaluation.runtimeLineage,
|
|
@@ -4307,7 +4335,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4307
4335
|
const statsBucket = import_redis.redisKeys.runtimeSignalEvaluationStatsBucket(
|
|
4308
4336
|
evaluation.userName,
|
|
4309
4337
|
dayKey,
|
|
4310
|
-
evaluation.strategy
|
|
4338
|
+
evaluation.strategy,
|
|
4339
|
+
evaluation.deploymentId
|
|
4311
4340
|
);
|
|
4312
4341
|
const increments = statsIncrements.get(statsBucket) ?? {};
|
|
4313
4342
|
for (const [field, increment] of Object.entries(
|
|
@@ -4920,7 +4949,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4920
4949
|
symbol,
|
|
4921
4950
|
timestamp: lastCandle.timestamp,
|
|
4922
4951
|
runtimeConfigId: runtimeIdentity,
|
|
4923
|
-
runtimeVersion: version
|
|
4952
|
+
runtimeVersion: version,
|
|
4953
|
+
deploymentId,
|
|
4954
|
+
accountId
|
|
4924
4955
|
}),
|
|
4925
4956
|
userName,
|
|
4926
4957
|
strategy: strategyName,
|
|
@@ -4945,8 +4976,14 @@ var createSignalsTickerEvaluator = ({
|
|
|
4945
4976
|
signal.runtimeConfigId = runtimeIdentity;
|
|
4946
4977
|
signal.runtimeVersion = version;
|
|
4947
4978
|
signal.runtimeLineage = runtimeLineage;
|
|
4948
|
-
|
|
4949
|
-
|
|
4979
|
+
signal.deploymentId = deploymentId;
|
|
4980
|
+
signal.accountId = accountId;
|
|
4981
|
+
const signalRuntimeIdentity = [
|
|
4982
|
+
...deploymentId ? [deploymentId, accountId ?? "default-account"] : [],
|
|
4983
|
+
...version ? [`v${version}`] : []
|
|
4984
|
+
].join(":");
|
|
4985
|
+
if (signalRuntimeIdentity && !signal.signalId.endsWith(`:${signalRuntimeIdentity}`)) {
|
|
4986
|
+
signal.signalId = `${signal.signalId}:${signalRuntimeIdentity}`;
|
|
4950
4987
|
}
|
|
4951
4988
|
await (0, import_strategies4.enrichSignalWithBinanceMarketContext)({ signal, env: "CRON" });
|
|
4952
4989
|
if (signal.orderStatus === "skipped" && typeof signal.orderSkipReason === "string" && signal.orderSkipReason.trim()) {
|
|
@@ -4965,7 +5002,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4965
5002
|
symbol,
|
|
4966
5003
|
timestamp: lastCandle.timestamp,
|
|
4967
5004
|
runtimeConfigId: runtimeIdentity,
|
|
4968
|
-
runtimeVersion: version
|
|
5005
|
+
runtimeVersion: version,
|
|
5006
|
+
deploymentId,
|
|
5007
|
+
accountId
|
|
4969
5008
|
}),
|
|
4970
5009
|
userName,
|
|
4971
5010
|
strategy: strategyName,
|
|
@@ -4189,7 +4189,12 @@ async function buildRuntimeLineage({
|
|
|
4189
4189
|
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
4190
4190
|
};
|
|
4191
4191
|
}
|
|
4192
|
-
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
4192
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
4193
|
+
"v2",
|
|
4194
|
+
lineage.version,
|
|
4195
|
+
lineage.strategyPackageVersion ?? "strategy:unknown",
|
|
4196
|
+
lineage.runtimePackageVersion ?? "runtime:unknown"
|
|
4197
|
+
].join(":") : [
|
|
4193
4198
|
lineage.schemaVersion,
|
|
4194
4199
|
lineage.compositionId ?? "unbound-composition",
|
|
4195
4200
|
lineage.gitSha ?? "unknown",
|
|
@@ -4208,9 +4213,28 @@ var buildRuntimeSignalEvaluationId = ({
|
|
|
4208
4213
|
symbol,
|
|
4209
4214
|
timestamp,
|
|
4210
4215
|
runtimeConfigId,
|
|
4211
|
-
runtimeVersion
|
|
4212
|
-
|
|
4216
|
+
runtimeVersion,
|
|
4217
|
+
deploymentId,
|
|
4218
|
+
accountId
|
|
4219
|
+
}) => {
|
|
4220
|
+
const runtimeScope = deploymentId ? [deploymentId, accountId ?? "default-account"] : [];
|
|
4221
|
+
return runtimeVersion ? [
|
|
4222
|
+
...runtimeScope,
|
|
4223
|
+
strategyName,
|
|
4224
|
+
`v${runtimeVersion}`,
|
|
4225
|
+
symbol,
|
|
4226
|
+
timestamp
|
|
4227
|
+
].join(":") : runtimeConfigId && runtimeConfigId !== "config" ? [
|
|
4228
|
+
...runtimeScope,
|
|
4229
|
+
strategyName,
|
|
4230
|
+
runtimeConfigId,
|
|
4231
|
+
symbol,
|
|
4232
|
+
timestamp
|
|
4233
|
+
].join(":") : [...runtimeScope, strategyName, symbol, timestamp].join(":");
|
|
4234
|
+
};
|
|
4213
4235
|
var buildLineageField = (scope) => [
|
|
4236
|
+
scope.deploymentId ?? "default-deployment",
|
|
4237
|
+
scope.accountId ?? "default-account",
|
|
4214
4238
|
scope.strategy,
|
|
4215
4239
|
scope.runtimeConfigId ?? "config",
|
|
4216
4240
|
scope.runtimeVersion ? `v${scope.runtimeVersion}` : "legacy",
|
|
@@ -4252,6 +4276,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4252
4276
|
for (const evaluation of lineageEvaluations) {
|
|
4253
4277
|
const lineageField = buildLineageField({
|
|
4254
4278
|
strategy: evaluation.strategy,
|
|
4279
|
+
deploymentId: evaluation.deploymentId,
|
|
4280
|
+
accountId: evaluation.accountId,
|
|
4255
4281
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4256
4282
|
runtimeVersion: evaluation.runtimeVersion,
|
|
4257
4283
|
symbol: evaluation.symbol,
|
|
@@ -4262,6 +4288,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4262
4288
|
const scope = {
|
|
4263
4289
|
strategy: evaluation.strategy,
|
|
4264
4290
|
symbol: evaluation.symbol,
|
|
4291
|
+
...evaluation.deploymentId ? { deploymentId: evaluation.deploymentId } : {},
|
|
4292
|
+
...evaluation.accountId ? { accountId: evaluation.accountId } : {},
|
|
4265
4293
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4266
4294
|
runtimeVersion: evaluation.runtimeVersion,
|
|
4267
4295
|
lineage: evaluation.runtimeLineage,
|
|
@@ -4305,7 +4333,8 @@ var flushRuntimeSignalEvaluations = async (evaluations) => {
|
|
|
4305
4333
|
const statsBucket = import_redis.redisKeys.runtimeSignalEvaluationStatsBucket(
|
|
4306
4334
|
evaluation.userName,
|
|
4307
4335
|
dayKey,
|
|
4308
|
-
evaluation.strategy
|
|
4336
|
+
evaluation.strategy,
|
|
4337
|
+
evaluation.deploymentId
|
|
4309
4338
|
);
|
|
4310
4339
|
const increments = statsIncrements.get(statsBucket) ?? {};
|
|
4311
4340
|
for (const [field, increment] of Object.entries(
|
|
@@ -4918,7 +4947,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4918
4947
|
symbol,
|
|
4919
4948
|
timestamp: lastCandle.timestamp,
|
|
4920
4949
|
runtimeConfigId: runtimeIdentity,
|
|
4921
|
-
runtimeVersion: version
|
|
4950
|
+
runtimeVersion: version,
|
|
4951
|
+
deploymentId,
|
|
4952
|
+
accountId
|
|
4922
4953
|
}),
|
|
4923
4954
|
userName,
|
|
4924
4955
|
strategy: strategyName,
|
|
@@ -4943,8 +4974,14 @@ var createSignalsTickerEvaluator = ({
|
|
|
4943
4974
|
signal.runtimeConfigId = runtimeIdentity;
|
|
4944
4975
|
signal.runtimeVersion = version;
|
|
4945
4976
|
signal.runtimeLineage = runtimeLineage;
|
|
4946
|
-
|
|
4947
|
-
|
|
4977
|
+
signal.deploymentId = deploymentId;
|
|
4978
|
+
signal.accountId = accountId;
|
|
4979
|
+
const signalRuntimeIdentity = [
|
|
4980
|
+
...deploymentId ? [deploymentId, accountId ?? "default-account"] : [],
|
|
4981
|
+
...version ? [`v${version}`] : []
|
|
4982
|
+
].join(":");
|
|
4983
|
+
if (signalRuntimeIdentity && !signal.signalId.endsWith(`:${signalRuntimeIdentity}`)) {
|
|
4984
|
+
signal.signalId = `${signal.signalId}:${signalRuntimeIdentity}`;
|
|
4948
4985
|
}
|
|
4949
4986
|
await (0, import_strategies4.enrichSignalWithBinanceMarketContext)({ signal, env: "CRON" });
|
|
4950
4987
|
if (signal.orderStatus === "skipped" && typeof signal.orderSkipReason === "string" && signal.orderSkipReason.trim()) {
|
|
@@ -4963,7 +5000,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4963
5000
|
symbol,
|
|
4964
5001
|
timestamp: lastCandle.timestamp,
|
|
4965
5002
|
runtimeConfigId: runtimeIdentity,
|
|
4966
|
-
runtimeVersion: version
|
|
5003
|
+
runtimeVersion: version,
|
|
5004
|
+
deploymentId,
|
|
5005
|
+
accountId
|
|
4967
5006
|
}),
|
|
4968
5007
|
userName,
|
|
4969
5008
|
strategy: strategyName,
|
|
@@ -532,13 +532,17 @@ var parseBucketKey = (prefix, key) => {
|
|
|
532
532
|
return null;
|
|
533
533
|
}
|
|
534
534
|
const suffix = key.slice(prefix.length);
|
|
535
|
-
const
|
|
536
|
-
if (
|
|
535
|
+
const parts = suffix.split(":");
|
|
536
|
+
if (parts.length < 2 || parts.some((part) => !part)) {
|
|
537
537
|
return null;
|
|
538
538
|
}
|
|
539
|
+
const [dayKey, ...scopeParts] = parts;
|
|
540
|
+
const strategy = scopeParts.at(-1);
|
|
541
|
+
if (!dayKey || !strategy) return null;
|
|
539
542
|
return {
|
|
540
|
-
dayKey
|
|
541
|
-
|
|
543
|
+
dayKey,
|
|
544
|
+
...scopeParts.length > 1 ? { deploymentId: scopeParts.slice(0, -1).join(":") } : {},
|
|
545
|
+
strategy
|
|
542
546
|
};
|
|
543
547
|
};
|
|
544
548
|
var loadRuntimeSignalEvaluationStatsBuckets = async (userName) => {
|
|
@@ -598,7 +602,8 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
598
602
|
evaluations,
|
|
599
603
|
trades,
|
|
600
604
|
strategyConfigs,
|
|
601
|
-
evaluationStatsBuckets
|
|
605
|
+
evaluationStatsBuckets,
|
|
606
|
+
lineageScopes
|
|
602
607
|
}) => {
|
|
603
608
|
const signalById = new Map(
|
|
604
609
|
signals.map((signal) => [signal.signalId, signal])
|
|
@@ -726,6 +731,7 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
726
731
|
signals: signals.length,
|
|
727
732
|
evaluations: reportEvaluations.length,
|
|
728
733
|
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
734
|
+
lineageScopes: lineageScopes?.length ?? 0,
|
|
729
735
|
strategyConfigs: strategyConfigs?.length ?? 0
|
|
730
736
|
},
|
|
731
737
|
trades: debugTrades,
|
|
@@ -749,6 +755,7 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
749
755
|
evaluation
|
|
750
756
|
})),
|
|
751
757
|
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
758
|
+
lineageScopes: lineageScopes ?? [],
|
|
752
759
|
strategyConfigs: strategyConfigs ?? []
|
|
753
760
|
};
|
|
754
761
|
};
|