@tradejs/cli 3.1.11-beta.216 → 3.1.12-beta.217
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 +149 -78
- package/dist/lib/runEnvironment.js +6 -2
- package/dist/lib/runtimeEvidenceDeployment.js +16 -9
- package/dist/lib/runtimeLineage.js +32 -11
- package/dist/lib/runtimeScorecard.js +49 -10
- package/dist/lib/runtimeSignalsStorage.js +1 -1
- package/dist/lib/strategyRelease.js +4 -2
- package/dist/scripts/replay.js +77 -36
- package/dist/scripts/replayRunner.js +77 -36
- package/dist/scripts/runtimeControl.js +3 -2
- package/dist/scripts/runtimeEvidence.js +29 -10
- package/dist/scripts/runtimeScorecard.js +49 -10
- package/dist/scripts/signals.js +58 -36
- package/dist/scripts/signalsDaemon.js +58 -36
- package/dist/scripts/strategyRelease.js +4 -2
- package/package.json +12 -8
|
@@ -523,17 +523,21 @@ var loadDeploymentReplayStrategies = async ({
|
|
|
523
523
|
const strategies = deployment.enabled ? runtimeStrategies.filter((strategy) => strategy.enabled).map(
|
|
524
524
|
({
|
|
525
525
|
strategyName,
|
|
526
|
-
|
|
526
|
+
strategyRevision,
|
|
527
|
+
deploymentCompositionId,
|
|
527
528
|
strategyPackage,
|
|
528
529
|
strategyPackageVersion,
|
|
530
|
+
strategyDependencyVersions,
|
|
529
531
|
runtimePackageVersion,
|
|
530
532
|
sourceStrategyConfig,
|
|
531
533
|
selection
|
|
532
534
|
}) => ({
|
|
533
535
|
strategyName,
|
|
534
|
-
|
|
536
|
+
strategyRevision,
|
|
537
|
+
deploymentCompositionId,
|
|
535
538
|
strategyPackage,
|
|
536
539
|
strategyPackageVersion,
|
|
540
|
+
strategyDependencyVersions,
|
|
537
541
|
runtimePackageVersion,
|
|
538
542
|
strategyConfig: sourceStrategyConfig,
|
|
539
543
|
...selection ? { selection } : {}
|
|
@@ -29,6 +29,9 @@ module.exports = __toCommonJS(runtimeEvidenceDeployment_exports);
|
|
|
29
29
|
var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
30
30
|
var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
31
31
|
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
32
|
+
var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
33
|
+
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
34
|
+
);
|
|
32
35
|
var INTERVALS = /* @__PURE__ */ new Set([
|
|
33
36
|
"1",
|
|
34
37
|
"3",
|
|
@@ -47,13 +50,13 @@ var INTERVALS = /* @__PURE__ */ new Set([
|
|
|
47
50
|
var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
48
51
|
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));
|
|
49
52
|
var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
50
|
-
if (!isRecord(value) || value.schemaVersion !==
|
|
53
|
+
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)) {
|
|
51
54
|
throw new Error(
|
|
52
55
|
"Runtime evidence deployment snapshot is missing or invalid"
|
|
53
56
|
);
|
|
54
57
|
}
|
|
55
58
|
const strategies = value.strategies.map((candidate) => {
|
|
56
|
-
if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !
|
|
59
|
+
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)) {
|
|
57
60
|
throw new Error(
|
|
58
61
|
"Runtime evidence deployment strategy snapshot is invalid"
|
|
59
62
|
);
|
|
@@ -87,15 +90,16 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
|
87
90
|
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
88
91
|
var runtimeDeploymentFromEvidence = (deployment) => ({
|
|
89
92
|
id: deployment.id,
|
|
93
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
90
94
|
label: deployment.label,
|
|
91
95
|
connectorName: deployment.connectorName,
|
|
92
96
|
provider: deployment.provider,
|
|
93
97
|
accountId: deployment.accountId,
|
|
94
98
|
enabled: deployment.enabled,
|
|
95
99
|
strategies: deployment.strategies.map(
|
|
96
|
-
({ strategyName,
|
|
100
|
+
({ strategyName, strategyRevision, enabled, controlState, selection }) => ({
|
|
97
101
|
strategyName,
|
|
98
|
-
|
|
102
|
+
strategyRevision,
|
|
99
103
|
enabled,
|
|
100
104
|
controlState,
|
|
101
105
|
...selection ? { selection } : {}
|
|
@@ -117,8 +121,9 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
|
117
121
|
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
118
122
|
}
|
|
119
123
|
return {
|
|
120
|
-
schemaVersion:
|
|
124
|
+
schemaVersion: 2,
|
|
121
125
|
id: deployment.id,
|
|
126
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
122
127
|
label: deployment.label,
|
|
123
128
|
connectorName: deployment.connectorName,
|
|
124
129
|
provider: deployment.provider,
|
|
@@ -127,7 +132,7 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
|
127
132
|
strategies: strategies.map(
|
|
128
133
|
({
|
|
129
134
|
strategyName,
|
|
130
|
-
|
|
135
|
+
strategyRevision,
|
|
131
136
|
enabled,
|
|
132
137
|
controlState,
|
|
133
138
|
interval,
|
|
@@ -135,12 +140,13 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
|
135
140
|
accountId,
|
|
136
141
|
strategyPackage,
|
|
137
142
|
strategyPackageVersion,
|
|
143
|
+
strategyDependencyVersions,
|
|
138
144
|
runtimePackageVersion,
|
|
139
|
-
|
|
145
|
+
strategyConfig,
|
|
140
146
|
selection
|
|
141
147
|
}) => ({
|
|
142
148
|
strategyName,
|
|
143
|
-
|
|
149
|
+
strategyRevision,
|
|
144
150
|
enabled,
|
|
145
151
|
controlState,
|
|
146
152
|
interval,
|
|
@@ -148,8 +154,9 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
|
148
154
|
...accountId ? { accountId } : {},
|
|
149
155
|
strategyPackage,
|
|
150
156
|
strategyPackageVersion,
|
|
157
|
+
strategyDependencyVersions,
|
|
151
158
|
runtimePackageVersion,
|
|
152
|
-
strategyConfig
|
|
159
|
+
strategyConfig,
|
|
153
160
|
...selection ? { selection } : {}
|
|
154
161
|
})
|
|
155
162
|
),
|
|
@@ -277,21 +277,38 @@ async function buildRuntimeLineage({
|
|
|
277
277
|
projectRoot,
|
|
278
278
|
strategyName,
|
|
279
279
|
compositionId,
|
|
280
|
-
|
|
280
|
+
strategyRevision,
|
|
281
|
+
deploymentCompositionId,
|
|
281
282
|
strategyPackageVersion,
|
|
283
|
+
strategyDependencyVersions,
|
|
282
284
|
runtimePackageVersion,
|
|
283
285
|
config,
|
|
284
286
|
runContext,
|
|
285
287
|
env = process.env
|
|
286
288
|
}) {
|
|
287
|
-
if (
|
|
288
|
-
if (
|
|
289
|
-
throw new Error(`Invalid
|
|
289
|
+
if (strategyRevision != null) {
|
|
290
|
+
if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
|
|
291
|
+
throw new Error(`Invalid strategy revision: ${strategyRevision}`);
|
|
292
|
+
}
|
|
293
|
+
if (typeof deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`Invalid deployment composition id: ${String(deploymentCompositionId)}`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
if (typeof strategyPackageVersion !== "string" || !strategyPackageVersion.trim() || typeof runtimePackageVersion !== "string" || !runtimePackageVersion.trim()) {
|
|
299
|
+
throw new Error("Invalid revision package versions");
|
|
300
|
+
}
|
|
301
|
+
if (!strategyDependencyVersions || Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
|
|
302
|
+
([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
|
|
303
|
+
)) {
|
|
304
|
+
throw new Error("Invalid strategy dependency versions");
|
|
290
305
|
}
|
|
291
306
|
return {
|
|
292
|
-
schemaVersion:
|
|
293
|
-
|
|
307
|
+
schemaVersion: 3,
|
|
308
|
+
strategyRevision,
|
|
309
|
+
deploymentCompositionId,
|
|
294
310
|
strategyPackageVersion,
|
|
311
|
+
strategyDependencyVersions,
|
|
295
312
|
runtimePackageVersion,
|
|
296
313
|
maxLossValue: resolveRuntimeMaxLossValue(config)
|
|
297
314
|
};
|
|
@@ -331,11 +348,15 @@ async function buildRuntimeLineage({
|
|
|
331
348
|
maxLossValue: resolveRuntimeMaxLossValue(config)
|
|
332
349
|
};
|
|
333
350
|
}
|
|
334
|
-
var runtimeLineageKey = (lineage) => lineage.schemaVersion ===
|
|
335
|
-
"
|
|
336
|
-
lineage.
|
|
337
|
-
lineage.
|
|
338
|
-
lineage.
|
|
351
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 3 ? [
|
|
352
|
+
"v3",
|
|
353
|
+
lineage.deploymentCompositionId,
|
|
354
|
+
lineage.strategyRevision,
|
|
355
|
+
lineage.strategyPackageVersion,
|
|
356
|
+
`deps:${fingerprintRuntimeValue(
|
|
357
|
+
lineage.strategyDependencyVersions
|
|
358
|
+
).slice(0, 16)}`,
|
|
359
|
+
lineage.runtimePackageVersion
|
|
339
360
|
].join(":") : [
|
|
340
361
|
lineage.schemaVersion,
|
|
341
362
|
lineage.compositionId ?? "unbound-composition",
|
|
@@ -51,11 +51,27 @@ var import_promises = __toESM(require("fs/promises"));
|
|
|
51
51
|
var import_node_path = __toESM(require("path"));
|
|
52
52
|
|
|
53
53
|
// src/lib/runtimeLineage.ts
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
var normalizeForStableJson = (value) => {
|
|
55
|
+
if (Array.isArray(value)) {
|
|
56
|
+
return value.map(normalizeForStableJson);
|
|
57
|
+
}
|
|
58
|
+
if (value && typeof value === "object") {
|
|
59
|
+
return Object.fromEntries(
|
|
60
|
+
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, normalizeForStableJson(entry)])
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
};
|
|
65
|
+
var fingerprintRuntimeValue = (value) => (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
66
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 3 ? [
|
|
67
|
+
"v3",
|
|
68
|
+
lineage.deploymentCompositionId,
|
|
69
|
+
lineage.strategyRevision,
|
|
70
|
+
lineage.strategyPackageVersion,
|
|
71
|
+
`deps:${fingerprintRuntimeValue(
|
|
72
|
+
lineage.strategyDependencyVersions
|
|
73
|
+
).slice(0, 16)}`,
|
|
74
|
+
lineage.runtimePackageVersion
|
|
59
75
|
].join(":") : [
|
|
60
76
|
lineage.schemaVersion,
|
|
61
77
|
lineage.compositionId ?? "unbound-composition",
|
|
@@ -71,6 +87,19 @@ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(v
|
|
|
71
87
|
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
72
88
|
var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
73
89
|
var finiteString = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
90
|
+
var packageVersionMap = (value) => {
|
|
91
|
+
const record = asRecord(value);
|
|
92
|
+
if (!record || Object.keys(record).length === 0) return null;
|
|
93
|
+
const entries = Object.entries(record);
|
|
94
|
+
if (entries.some(
|
|
95
|
+
([name, version]) => !name.startsWith("@tradejs/") || finiteString(version) == null
|
|
96
|
+
)) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return Object.fromEntries(
|
|
100
|
+
entries.map(([name, version]) => [name, String(version).trim()]).sort(([left], [right]) => left.localeCompare(right))
|
|
101
|
+
);
|
|
102
|
+
};
|
|
74
103
|
var round = (value, decimals = 6) => Number(value.toFixed(decimals));
|
|
75
104
|
var unwrapRows = (value, key) => asArray(value).map((item) => asRecord(asRecord(item)?.[key]) ?? asRecord(item)).filter((item) => item != null);
|
|
76
105
|
var runtimePayload = (artifact) => {
|
|
@@ -103,12 +132,18 @@ var buildRuntimeLineageSummary = (rows) => {
|
|
|
103
132
|
const lineages = lineageRows.map((row) => asRecord(row.runtimeLineage)).filter((lineage) => lineage != null);
|
|
104
133
|
const identities = /* @__PURE__ */ new Map();
|
|
105
134
|
for (const lineage of lineages) {
|
|
106
|
-
const identity2 = lineage.schemaVersion ===
|
|
107
|
-
schemaVersion:
|
|
108
|
-
|
|
135
|
+
const identity2 = lineage.schemaVersion === 3 ? {
|
|
136
|
+
schemaVersion: 3,
|
|
137
|
+
strategyRevision: finiteString(lineage.strategyRevision),
|
|
138
|
+
deploymentCompositionId: finiteString(
|
|
139
|
+
lineage.deploymentCompositionId
|
|
140
|
+
),
|
|
109
141
|
strategyPackageVersion: finiteString(
|
|
110
142
|
lineage.strategyPackageVersion
|
|
111
143
|
),
|
|
144
|
+
strategyDependencyVersions: packageVersionMap(
|
|
145
|
+
lineage.strategyDependencyVersions
|
|
146
|
+
),
|
|
112
147
|
runtimePackageVersion: finiteString(lineage.runtimePackageVersion),
|
|
113
148
|
maxLossValue: finiteNumber(lineage.maxLossValue)
|
|
114
149
|
} : {
|
|
@@ -125,7 +160,7 @@ var buildRuntimeLineageSummary = (rows) => {
|
|
|
125
160
|
}
|
|
126
161
|
const identity = identities.size === 1 ? [...identities.values()][0] : null;
|
|
127
162
|
const schemaVersion = finiteNumber(identity?.schemaVersion);
|
|
128
|
-
const identityComplete = lineages.length > 0 && identity != null && (schemaVersion ===
|
|
163
|
+
const identityComplete = lineages.length > 0 && identity != null && (schemaVersion === 3 && finiteString(identity.strategyRevision) != null && finiteString(identity.deploymentCompositionId) != null && finiteString(identity.strategyPackageVersion) != null && packageVersionMap(identity.strategyDependencyVersions) != 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;
|
|
129
164
|
const coverageComplete = lineageRows.length > 0 && lineages.length === lineageRows.length;
|
|
130
165
|
const complete = identityComplete && coverageComplete;
|
|
131
166
|
const lineageKey = identityComplete ? runtimeLineageKey(identity) : null;
|
|
@@ -138,8 +173,12 @@ var buildRuntimeLineageSummary = (rows) => {
|
|
|
138
173
|
rowsWithLineage: lineages.length,
|
|
139
174
|
schemaVersion,
|
|
140
175
|
lineageKey,
|
|
141
|
-
|
|
176
|
+
strategyRevision: finiteString(identity?.strategyRevision),
|
|
177
|
+
deploymentCompositionId: finiteString(identity?.deploymentCompositionId),
|
|
142
178
|
strategyPackageVersion: finiteString(identity?.strategyPackageVersion),
|
|
179
|
+
strategyDependencyVersions: packageVersionMap(
|
|
180
|
+
identity?.strategyDependencyVersions
|
|
181
|
+
),
|
|
143
182
|
runtimePackageVersion: finiteString(identity?.runtimePackageVersion),
|
|
144
183
|
compositionId: finiteString(identity?.compositionId),
|
|
145
184
|
gitSha: finiteString(identity?.gitSha),
|
|
@@ -64,7 +64,7 @@ var toRuntimeSignalBucketRef = (signal) => ({
|
|
|
64
64
|
strategy: signal.strategy,
|
|
65
65
|
timestamp: signal.timestamp,
|
|
66
66
|
...signal.runtimeConfigId && signal.runtimeConfigId !== "config" ? { runtimeConfigId: signal.runtimeConfigId } : {},
|
|
67
|
-
...signal.
|
|
67
|
+
...signal.strategyRevision ? { strategyRevision: signal.strategyRevision } : {}
|
|
68
68
|
});
|
|
69
69
|
var shouldStoreRuntimeSignalDiagnostics = (signal) => signal.orderStatus === "completed" || signal.orderStatus === "failed";
|
|
70
70
|
var toStoredRuntimeSignal = (signal) => {
|
|
@@ -279,6 +279,8 @@ var planStrategyEvidenceRetention = ({
|
|
|
279
279
|
// src/lib/strategyRelease.ts
|
|
280
280
|
var SHA256_RE = /^[a-f0-9]{64}$/;
|
|
281
281
|
var LINEAGE_FINGERPRINT_RE = /^[a-f0-9]{16}$/;
|
|
282
|
+
var STRATEGY_REVISION_RE = /^sr1:[a-f0-9]{16}$/;
|
|
283
|
+
var DEPLOYMENT_COMPOSITION_ID_RE = /^dc1:[a-f0-9]{16}$/;
|
|
282
284
|
var REQUIRED_LONG_WINDOWS = [1095, 1460, 1825];
|
|
283
285
|
var REQUIRED_STABLE_TERMINAL_WINDOWS = [365, 180, 90];
|
|
284
286
|
var MIN_RECENT_DIRECTION_REPAIR_TRADES = 20;
|
|
@@ -301,7 +303,7 @@ var verifyFullPeriodChartArtifact = async (input) => {
|
|
|
301
303
|
}
|
|
302
304
|
};
|
|
303
305
|
var hasExactRuntimeTarget = (target, strategyName) => Boolean(
|
|
304
|
-
target?.userName.trim() && target.deploymentId.trim() && target.accountId.trim() && target.strategyName.trim() === strategyName.trim() &&
|
|
306
|
+
target?.userName.trim() && target.deploymentId.trim() && target.accountId.trim() && target.strategyName.trim() === strategyName.trim() && STRATEGY_REVISION_RE.test(target.strategyRevision) && DEPLOYMENT_COMPOSITION_ID_RE.test(target.deploymentCompositionId)
|
|
305
307
|
);
|
|
306
308
|
var deriveStrategyReleaseResearchDecision = async (input) => {
|
|
307
309
|
const blockers = [];
|
|
@@ -402,7 +404,7 @@ var deriveStrategyReleaseResearchDecision = async (input) => {
|
|
|
402
404
|
maxLossValue: 1,
|
|
403
405
|
requiresRuntimeBinding: true,
|
|
404
406
|
blockers: [],
|
|
405
|
-
summary: "The portable micro-forward handoff is ready. Commit its deployment, account binding, complete config
|
|
407
|
+
summary: "The portable micro-forward handoff is ready. Commit its deployment, account binding, and complete config in TradeJS-Project; runtime revisions are computed from the installed packages and parsed config."
|
|
406
408
|
};
|
|
407
409
|
}
|
|
408
410
|
return {
|
package/dist/scripts/replay.js
CHANGED
|
@@ -526,17 +526,21 @@ var loadDeploymentReplayStrategies = async ({
|
|
|
526
526
|
const strategies = deployment.enabled ? runtimeStrategies.filter((strategy) => strategy.enabled).map(
|
|
527
527
|
({
|
|
528
528
|
strategyName,
|
|
529
|
-
|
|
529
|
+
strategyRevision,
|
|
530
|
+
deploymentCompositionId,
|
|
530
531
|
strategyPackage,
|
|
531
532
|
strategyPackageVersion,
|
|
533
|
+
strategyDependencyVersions,
|
|
532
534
|
runtimePackageVersion,
|
|
533
535
|
sourceStrategyConfig,
|
|
534
536
|
selection
|
|
535
537
|
}) => ({
|
|
536
538
|
strategyName,
|
|
537
|
-
|
|
539
|
+
strategyRevision,
|
|
540
|
+
deploymentCompositionId,
|
|
538
541
|
strategyPackage,
|
|
539
542
|
strategyPackageVersion,
|
|
543
|
+
strategyDependencyVersions,
|
|
540
544
|
runtimePackageVersion,
|
|
541
545
|
strategyConfig: sourceStrategyConfig,
|
|
542
546
|
...selection ? { selection } : {}
|
|
@@ -4586,21 +4590,38 @@ async function buildRuntimeLineage({
|
|
|
4586
4590
|
projectRoot,
|
|
4587
4591
|
strategyName,
|
|
4588
4592
|
compositionId,
|
|
4589
|
-
|
|
4593
|
+
strategyRevision,
|
|
4594
|
+
deploymentCompositionId,
|
|
4590
4595
|
strategyPackageVersion,
|
|
4596
|
+
strategyDependencyVersions,
|
|
4591
4597
|
runtimePackageVersion,
|
|
4592
4598
|
config,
|
|
4593
4599
|
runContext,
|
|
4594
4600
|
env = process.env
|
|
4595
4601
|
}) {
|
|
4596
|
-
if (
|
|
4597
|
-
if (
|
|
4598
|
-
throw new Error(`Invalid
|
|
4602
|
+
if (strategyRevision != null) {
|
|
4603
|
+
if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
|
|
4604
|
+
throw new Error(`Invalid strategy revision: ${strategyRevision}`);
|
|
4605
|
+
}
|
|
4606
|
+
if (typeof deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
|
|
4607
|
+
throw new Error(
|
|
4608
|
+
`Invalid deployment composition id: ${String(deploymentCompositionId)}`
|
|
4609
|
+
);
|
|
4610
|
+
}
|
|
4611
|
+
if (typeof strategyPackageVersion !== "string" || !strategyPackageVersion.trim() || typeof runtimePackageVersion !== "string" || !runtimePackageVersion.trim()) {
|
|
4612
|
+
throw new Error("Invalid revision package versions");
|
|
4613
|
+
}
|
|
4614
|
+
if (!strategyDependencyVersions || Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
|
|
4615
|
+
([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
|
|
4616
|
+
)) {
|
|
4617
|
+
throw new Error("Invalid strategy dependency versions");
|
|
4599
4618
|
}
|
|
4600
4619
|
return {
|
|
4601
|
-
schemaVersion:
|
|
4602
|
-
|
|
4620
|
+
schemaVersion: 3,
|
|
4621
|
+
strategyRevision,
|
|
4622
|
+
deploymentCompositionId,
|
|
4603
4623
|
strategyPackageVersion,
|
|
4624
|
+
strategyDependencyVersions,
|
|
4604
4625
|
runtimePackageVersion,
|
|
4605
4626
|
maxLossValue: resolveRuntimeMaxLossValue(config)
|
|
4606
4627
|
};
|
|
@@ -4640,11 +4661,15 @@ async function buildRuntimeLineage({
|
|
|
4640
4661
|
maxLossValue: resolveRuntimeMaxLossValue(config)
|
|
4641
4662
|
};
|
|
4642
4663
|
}
|
|
4643
|
-
var runtimeLineageKey = (lineage) => lineage.schemaVersion ===
|
|
4644
|
-
"
|
|
4645
|
-
lineage.
|
|
4646
|
-
lineage.
|
|
4647
|
-
lineage.
|
|
4664
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 3 ? [
|
|
4665
|
+
"v3",
|
|
4666
|
+
lineage.deploymentCompositionId,
|
|
4667
|
+
lineage.strategyRevision,
|
|
4668
|
+
lineage.strategyPackageVersion,
|
|
4669
|
+
`deps:${fingerprintRuntimeValue(
|
|
4670
|
+
lineage.strategyDependencyVersions
|
|
4671
|
+
).slice(0, 16)}`,
|
|
4672
|
+
lineage.runtimePackageVersion
|
|
4648
4673
|
].join(":") : [
|
|
4649
4674
|
lineage.schemaVersion,
|
|
4650
4675
|
lineage.compositionId ?? "unbound-composition",
|
|
@@ -4661,6 +4686,9 @@ var runtimeLineagesComparable = (left, right) => runtimeLineagesMatch(left, righ
|
|
|
4661
4686
|
var import_runtimeStrategies2 = require("@tradejs/node/runtimeStrategies");
|
|
4662
4687
|
var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
4663
4688
|
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
4689
|
+
var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
4690
|
+
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
4691
|
+
);
|
|
4664
4692
|
var INTERVALS = /* @__PURE__ */ new Set([
|
|
4665
4693
|
"1",
|
|
4666
4694
|
"3",
|
|
@@ -4679,13 +4707,13 @@ var INTERVALS = /* @__PURE__ */ new Set([
|
|
|
4679
4707
|
var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
4680
4708
|
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));
|
|
4681
4709
|
var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
4682
|
-
if (!isRecord(value) || value.schemaVersion !==
|
|
4710
|
+
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)) {
|
|
4683
4711
|
throw new Error(
|
|
4684
4712
|
"Runtime evidence deployment snapshot is missing or invalid"
|
|
4685
4713
|
);
|
|
4686
4714
|
}
|
|
4687
4715
|
const strategies = value.strategies.map((candidate) => {
|
|
4688
|
-
if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !
|
|
4716
|
+
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)) {
|
|
4689
4717
|
throw new Error(
|
|
4690
4718
|
"Runtime evidence deployment strategy snapshot is invalid"
|
|
4691
4719
|
);
|
|
@@ -4719,15 +4747,16 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
|
4719
4747
|
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
4720
4748
|
var runtimeDeploymentFromEvidence = (deployment) => ({
|
|
4721
4749
|
id: deployment.id,
|
|
4750
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
4722
4751
|
label: deployment.label,
|
|
4723
4752
|
connectorName: deployment.connectorName,
|
|
4724
4753
|
provider: deployment.provider,
|
|
4725
4754
|
accountId: deployment.accountId,
|
|
4726
4755
|
enabled: deployment.enabled,
|
|
4727
4756
|
strategies: deployment.strategies.map(
|
|
4728
|
-
({ strategyName,
|
|
4757
|
+
({ strategyName, strategyRevision, enabled, controlState, selection }) => ({
|
|
4729
4758
|
strategyName,
|
|
4730
|
-
|
|
4759
|
+
strategyRevision,
|
|
4731
4760
|
enabled,
|
|
4732
4761
|
controlState,
|
|
4733
4762
|
...selection ? { selection } : {}
|
|
@@ -4807,7 +4836,7 @@ var buildRuntimeEvidenceLineageScopes = ({
|
|
|
4807
4836
|
deploymentId,
|
|
4808
4837
|
accountId,
|
|
4809
4838
|
runtimeConfigId,
|
|
4810
|
-
|
|
4839
|
+
strategyRevision,
|
|
4811
4840
|
timestamp,
|
|
4812
4841
|
lineage
|
|
4813
4842
|
}) => {
|
|
@@ -4822,7 +4851,7 @@ var buildRuntimeEvidenceLineageScopes = ({
|
|
|
4822
4851
|
...deploymentId ? { deploymentId } : {},
|
|
4823
4852
|
...accountId ? { accountId } : {},
|
|
4824
4853
|
...runtimeConfigId ? { runtimeConfigId } : {},
|
|
4825
|
-
...
|
|
4854
|
+
...strategyRevision ? { strategyRevision } : {},
|
|
4826
4855
|
lineage,
|
|
4827
4856
|
firstTimestamp: existing ? Math.min(existing.firstTimestamp, timestamp) : timestamp,
|
|
4828
4857
|
lastTimestamp: existing ? Math.max(existing.lastTimestamp, timestamp) : timestamp
|
|
@@ -4835,7 +4864,7 @@ var buildRuntimeEvidenceLineageScopes = ({
|
|
|
4835
4864
|
deploymentId: signal.deploymentId,
|
|
4836
4865
|
accountId: signal.accountId,
|
|
4837
4866
|
runtimeConfigId: signal.runtimeConfigId,
|
|
4838
|
-
|
|
4867
|
+
strategyRevision: signal.strategyRevision,
|
|
4839
4868
|
timestamp: signal.timestamp,
|
|
4840
4869
|
lineage: signal.runtimeLineage
|
|
4841
4870
|
});
|
|
@@ -4847,7 +4876,7 @@ var buildRuntimeEvidenceLineageScopes = ({
|
|
|
4847
4876
|
deploymentId: evaluation.deploymentId,
|
|
4848
4877
|
accountId: evaluation.accountId,
|
|
4849
4878
|
runtimeConfigId: evaluation.runtimeConfigId,
|
|
4850
|
-
|
|
4879
|
+
strategyRevision: evaluation.strategyRevision,
|
|
4851
4880
|
timestamp: evaluation.timestamp,
|
|
4852
4881
|
lineage: evaluation.runtimeLineage
|
|
4853
4882
|
});
|
|
@@ -5491,9 +5520,11 @@ var loadRuntimeStrategies = async (runtimeStrategies) => {
|
|
|
5491
5520
|
runtimeStrategies.map(async (runtimeStrategy) => {
|
|
5492
5521
|
const {
|
|
5493
5522
|
strategyName,
|
|
5494
|
-
|
|
5523
|
+
strategyRevision,
|
|
5524
|
+
deploymentCompositionId,
|
|
5495
5525
|
strategyPackage,
|
|
5496
5526
|
strategyPackageVersion,
|
|
5527
|
+
strategyDependencyVersions,
|
|
5497
5528
|
runtimePackageVersion,
|
|
5498
5529
|
strategyConfig,
|
|
5499
5530
|
selection
|
|
@@ -5509,7 +5540,7 @@ var loadRuntimeStrategies = async (runtimeStrategies) => {
|
|
|
5509
5540
|
strategyName,
|
|
5510
5541
|
projectRoot: replayProjectRoot
|
|
5511
5542
|
});
|
|
5512
|
-
if (installed.strategyPackage !== strategyPackage || installed.strategyPackageVersion !== strategyPackageVersion || installed.runtimePackageVersion !== runtimePackageVersion) {
|
|
5543
|
+
if (installed.strategyPackage !== strategyPackage || installed.strategyPackageVersion !== strategyPackageVersion || JSON.stringify(installed.strategyDependencyVersions) !== JSON.stringify(strategyDependencyVersions) || installed.runtimePackageVersion !== runtimePackageVersion) {
|
|
5513
5544
|
throw new Error(
|
|
5514
5545
|
`Runtime evidence package mismatch for ${strategyName}: expected=${strategyPackage}@${strategyPackageVersion}/@tradejs/node@${runtimePackageVersion}, installed=${installed.strategyPackage ?? "missing"}@${installed.strategyPackageVersion ?? "missing"}/@tradejs/node@${installed.runtimePackageVersion ?? "missing"}`
|
|
5515
5546
|
);
|
|
@@ -5520,9 +5551,11 @@ var loadRuntimeStrategies = async (runtimeStrategies) => {
|
|
|
5520
5551
|
);
|
|
5521
5552
|
return {
|
|
5522
5553
|
strategyName,
|
|
5523
|
-
|
|
5554
|
+
strategyRevision,
|
|
5555
|
+
deploymentCompositionId,
|
|
5524
5556
|
strategyPackage,
|
|
5525
5557
|
strategyPackageVersion,
|
|
5558
|
+
strategyDependencyVersions,
|
|
5526
5559
|
runtimePackageVersion,
|
|
5527
5560
|
strategyCreator,
|
|
5528
5561
|
strategyConfig,
|
|
@@ -5726,8 +5759,10 @@ var runHistoricalSignalsReplay = async ({
|
|
|
5726
5759
|
loadedStrategies.filter((strategy) => strategyIncludesSymbol(strategy, symbol)).map(
|
|
5727
5760
|
async ({
|
|
5728
5761
|
strategyName,
|
|
5729
|
-
|
|
5762
|
+
strategyRevision,
|
|
5763
|
+
deploymentCompositionId,
|
|
5730
5764
|
strategyPackageVersion,
|
|
5765
|
+
strategyDependencyVersions,
|
|
5731
5766
|
runtimePackageVersion,
|
|
5732
5767
|
strategyCreator,
|
|
5733
5768
|
strategyConfig,
|
|
@@ -5736,11 +5771,13 @@ var runHistoricalSignalsReplay = async ({
|
|
|
5736
5771
|
const runtimeLineage = await buildRuntimeLineage({
|
|
5737
5772
|
projectRoot: replayProjectRoot,
|
|
5738
5773
|
strategyName,
|
|
5739
|
-
|
|
5774
|
+
strategyRevision,
|
|
5775
|
+
deploymentCompositionId,
|
|
5740
5776
|
strategyPackageVersion,
|
|
5777
|
+
strategyDependencyVersions,
|
|
5741
5778
|
runtimePackageVersion,
|
|
5742
5779
|
config: {
|
|
5743
|
-
configId:
|
|
5780
|
+
configId: strategyRevision,
|
|
5744
5781
|
strategyConfig,
|
|
5745
5782
|
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
5746
5783
|
},
|
|
@@ -5764,7 +5801,8 @@ var runHistoricalSignalsReplay = async ({
|
|
|
5764
5801
|
run: await strategyCreator({
|
|
5765
5802
|
userName: replayUserName,
|
|
5766
5803
|
connectorName,
|
|
5767
|
-
runtimeConfigId:
|
|
5804
|
+
runtimeConfigId: strategyRevision,
|
|
5805
|
+
strategyRevision,
|
|
5768
5806
|
runtimeLineage,
|
|
5769
5807
|
universe: preparedRun.universe,
|
|
5770
5808
|
accountId: preparedRun.accountId,
|
|
@@ -8810,15 +8848,15 @@ var renderLineageRows = (runtimeComparison) => {
|
|
|
8810
8848
|
contexts: /* @__PURE__ */ new Set()
|
|
8811
8849
|
};
|
|
8812
8850
|
existing.scopes += 1;
|
|
8813
|
-
if (record.lineage.schemaVersion ===
|
|
8814
|
-
existing.gitShas.add(
|
|
8851
|
+
if (record.lineage.schemaVersion === 3) {
|
|
8852
|
+
existing.gitShas.add(record.lineage.deploymentCompositionId);
|
|
8815
8853
|
existing.dirty.add("n/a");
|
|
8816
|
-
existing.gates.add("
|
|
8817
|
-
existing.configs.add(
|
|
8854
|
+
existing.gates.add("package-owned");
|
|
8855
|
+
existing.configs.add(record.lineage.strategyRevision);
|
|
8818
8856
|
existing.contexts.add(
|
|
8819
8857
|
[
|
|
8820
|
-
record.lineage.strategyPackageVersion
|
|
8821
|
-
record.lineage.runtimePackageVersion
|
|
8858
|
+
record.lineage.strategyPackageVersion,
|
|
8859
|
+
record.lineage.runtimePackageVersion
|
|
8822
8860
|
].join("/")
|
|
8823
8861
|
);
|
|
8824
8862
|
} else {
|
|
@@ -9126,17 +9164,20 @@ var replayBacktest = async () => {
|
|
|
9126
9164
|
).map(
|
|
9127
9165
|
({
|
|
9128
9166
|
strategyName,
|
|
9129
|
-
|
|
9167
|
+
strategyRevision,
|
|
9130
9168
|
strategyPackage,
|
|
9131
9169
|
strategyPackageVersion,
|
|
9170
|
+
strategyDependencyVersions,
|
|
9132
9171
|
runtimePackageVersion,
|
|
9133
9172
|
strategyConfig,
|
|
9134
9173
|
selection
|
|
9135
9174
|
}) => ({
|
|
9136
9175
|
strategyName,
|
|
9137
|
-
|
|
9176
|
+
strategyRevision,
|
|
9177
|
+
deploymentCompositionId: evidenceMetadata.deployment.deploymentCompositionId,
|
|
9138
9178
|
strategyPackage,
|
|
9139
9179
|
strategyPackageVersion,
|
|
9180
|
+
strategyDependencyVersions,
|
|
9140
9181
|
runtimePackageVersion,
|
|
9141
9182
|
strategyConfig,
|
|
9142
9183
|
...selection ? { selection } : {}
|