@tradejs/cli 3.1.16-beta.230 → 3.1.17-beta.231
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 +581 -839
- package/dist/lib/runtimeDebugEvidence.js +7 -20
- package/dist/lib/runtimeEvidenceArtifacts.js +165 -0
- package/dist/lib/runtimeEvidenceDeployment.js +84 -4
- package/dist/lib/runtimeEvidenceSync.js +171 -112
- package/dist/lib/runtimeLineage.js +28 -306
- package/dist/lib/runtimeRedis.js +1 -3
- package/dist/lib/runtimeScorecard.js +177 -135
- package/dist/lib/strategyRelease.js +1 -1
- package/dist/scripts/replay.js +165 -370
- package/dist/scripts/replayRunner.js +165 -370
- package/dist/scripts/replayRuntimeEvidence.js +5 -16
- package/dist/scripts/runtimeEvidence.js +319 -187
- package/dist/scripts/runtimeEvidenceSync.js +172 -106
- package/dist/scripts/runtimeParity.js +1 -3
- package/dist/scripts/runtimeScorecard.js +220 -167
- package/dist/scripts/signals.js +47 -316
- package/dist/scripts/signalsDaemon.js +47 -316
- package/dist/scripts/signalsSummary.js +3 -8
- package/package.json +7 -7
package/dist/cli.js
CHANGED
|
@@ -2185,9 +2185,9 @@ var init_features = __esm({
|
|
|
2185
2185
|
"targetsymbol",
|
|
2186
2186
|
"universe"
|
|
2187
2187
|
]);
|
|
2188
|
-
normalizeFeaturePath = (
|
|
2189
|
-
classifyAiPocketCoverageFeaturePath = (
|
|
2190
|
-
const segments = normalizeFeaturePath(
|
|
2188
|
+
normalizeFeaturePath = (path35) => (Array.isArray(path35) ? path35 : path35.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
|
|
2189
|
+
classifyAiPocketCoverageFeaturePath = (path35) => {
|
|
2190
|
+
const segments = normalizeFeaturePath(path35);
|
|
2191
2191
|
const normalizedPath = segments.join(".");
|
|
2192
2192
|
if (segments.some(
|
|
2193
2193
|
(segment) => segment.includes("cmc") || segment.includes("coinmarketcap")
|
|
@@ -2361,8 +2361,8 @@ var init_features = __esm({
|
|
|
2361
2361
|
"volumeusd",
|
|
2362
2362
|
"vwap"
|
|
2363
2363
|
]);
|
|
2364
|
-
classifyAiPocketFeaturePath = (
|
|
2365
|
-
const segments = (Array.isArray(
|
|
2364
|
+
classifyAiPocketFeaturePath = (path35) => {
|
|
2365
|
+
const segments = (Array.isArray(path35) ? path35 : path35.split(".")).filter(
|
|
2366
2366
|
Boolean
|
|
2367
2367
|
);
|
|
2368
2368
|
const normalized = segments.map((segment) => segment.toLowerCase());
|
|
@@ -10693,27 +10693,27 @@ var init_coinMarketCapContextBackfill = __esm({
|
|
|
10693
10693
|
totalCredits: 0,
|
|
10694
10694
|
byPath: /* @__PURE__ */ new Map()
|
|
10695
10695
|
});
|
|
10696
|
-
getCoinMarketCapPathLabel = (
|
|
10697
|
-
if (
|
|
10698
|
-
if (
|
|
10699
|
-
if (
|
|
10700
|
-
if (
|
|
10701
|
-
if (
|
|
10702
|
-
if (
|
|
10703
|
-
return
|
|
10704
|
-
};
|
|
10705
|
-
recordCoinMarketCapFetchStats = (stats,
|
|
10696
|
+
getCoinMarketCapPathLabel = (path35) => {
|
|
10697
|
+
if (path35.includes("global-metrics")) return "global";
|
|
10698
|
+
if (path35.includes("cryptocurrency/quotes")) return "reference";
|
|
10699
|
+
if (path35.includes("exchange/quotes")) return "exchangeLiquidity";
|
|
10700
|
+
if (path35.includes("fear-and-greed")) return "fearGreed";
|
|
10701
|
+
if (path35.includes("cmc100")) return "cmc100";
|
|
10702
|
+
if (path35.includes("cmc20")) return "cmc20";
|
|
10703
|
+
return path35;
|
|
10704
|
+
};
|
|
10705
|
+
recordCoinMarketCapFetchStats = (stats, path35, creditCount) => {
|
|
10706
10706
|
if (!stats) return;
|
|
10707
|
-
const existing = stats.byPath.get(
|
|
10707
|
+
const existing = stats.byPath.get(path35) ?? { requests: 0, credits: 0 };
|
|
10708
10708
|
existing.requests += 1;
|
|
10709
10709
|
existing.credits += creditCount ?? 0;
|
|
10710
10710
|
stats.requests += 1;
|
|
10711
10711
|
stats.totalCredits += creditCount ?? 0;
|
|
10712
|
-
stats.byPath.set(
|
|
10712
|
+
stats.byPath.set(path35, existing);
|
|
10713
10713
|
};
|
|
10714
10714
|
formatCoinMarketCapFetchStats = (stats) => {
|
|
10715
10715
|
const byPath = [...stats.byPath.entries()].map(
|
|
10716
|
-
([
|
|
10716
|
+
([path35, item]) => `${getCoinMarketCapPathLabel(path35)}=${item.requests}req/${item.credits}cr`
|
|
10717
10717
|
).join(" ");
|
|
10718
10718
|
return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
|
|
10719
10719
|
};
|
|
@@ -12235,9 +12235,7 @@ var init_runtimeRedis = __esm({
|
|
|
12235
12235
|
dedupedBucketTrades.set(trade.orderId, trade);
|
|
12236
12236
|
}
|
|
12237
12237
|
const windowedTrades = [...dedupedBucketTrades.values()].filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
12238
|
-
|
|
12239
|
-
return windowedTrades;
|
|
12240
|
-
}
|
|
12238
|
+
return windowedTrades;
|
|
12241
12239
|
}
|
|
12242
12240
|
const tradePrefix = import_redis4.redisKeys.runtimeTrades(userName3);
|
|
12243
12241
|
const bucketPrefix = import_redis4.redisKeys.runtimeTradeBuckets(userName3);
|
|
@@ -24348,16 +24346,14 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24348
24346
|
signals2,
|
|
24349
24347
|
evaluations,
|
|
24350
24348
|
evaluationStatsBuckets,
|
|
24351
|
-
lineageScopes
|
|
24352
|
-
configs
|
|
24349
|
+
lineageScopes
|
|
24353
24350
|
] = await Promise.all([
|
|
24354
24351
|
loadRuntimeTrades(userName3, { startTime, endTime }),
|
|
24355
24352
|
loadRuntimeClosedTrades(userName3, { startTime, endTime }),
|
|
24356
24353
|
loadRuntimeSignals(userName3, { startTime, endTime }),
|
|
24357
24354
|
loadRuntimeSignalEvaluations(userName3, { startTime, endTime }),
|
|
24358
24355
|
loadRuntimeSignalEvaluationStatsBuckets(userName3),
|
|
24359
|
-
loadRuntimeLineageScopes(userName3, { startTime, endTime })
|
|
24360
|
-
(0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName3)
|
|
24356
|
+
loadRuntimeLineageScopes(userName3, { startTime, endTime })
|
|
24361
24357
|
]);
|
|
24362
24358
|
const tradesByOrderId = new Map(
|
|
24363
24359
|
entryTrades.map((trade) => [trade.orderId, trade])
|
|
@@ -24382,9 +24378,6 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24382
24378
|
evaluationStatsBuckets: filteredStats,
|
|
24383
24379
|
lineageScopes: lineageScopes.filter(matchesDeployment).filter(
|
|
24384
24380
|
(scope) => !strategies?.length || strategies.includes(scope.strategy)
|
|
24385
|
-
),
|
|
24386
|
-
strategyConfigs: deploymentId ? [] : configs.filter(
|
|
24387
|
-
(config2) => !strategies?.length || strategies.includes(config2.strategyName)
|
|
24388
24381
|
)
|
|
24389
24382
|
};
|
|
24390
24383
|
};
|
|
@@ -24395,7 +24388,6 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24395
24388
|
signals: signals2,
|
|
24396
24389
|
evaluations,
|
|
24397
24390
|
trades,
|
|
24398
|
-
strategyConfigs,
|
|
24399
24391
|
evaluationStatsBuckets,
|
|
24400
24392
|
lineageScopes
|
|
24401
24393
|
}) => {
|
|
@@ -24525,8 +24517,7 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24525
24517
|
signals: signals2.length,
|
|
24526
24518
|
evaluations: reportEvaluations.length,
|
|
24527
24519
|
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
24528
|
-
lineageScopes: lineageScopes?.length ?? 0
|
|
24529
|
-
strategyConfigs: strategyConfigs?.length ?? 0
|
|
24520
|
+
lineageScopes: lineageScopes?.length ?? 0
|
|
24530
24521
|
},
|
|
24531
24522
|
trades: debugTrades,
|
|
24532
24523
|
signals: signals2.map((signal) => ({
|
|
@@ -24549,8 +24540,7 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24549
24540
|
evaluation
|
|
24550
24541
|
})),
|
|
24551
24542
|
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
24552
|
-
lineageScopes: lineageScopes ?? []
|
|
24553
|
-
strategyConfigs: strategyConfigs ?? []
|
|
24543
|
+
lineageScopes: lineageScopes ?? []
|
|
24554
24544
|
};
|
|
24555
24545
|
};
|
|
24556
24546
|
buildRuntimeEvidenceReportPayload = ({
|
|
@@ -24560,7 +24550,6 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24560
24550
|
signals: signals2,
|
|
24561
24551
|
evaluations,
|
|
24562
24552
|
trades,
|
|
24563
|
-
strategyConfigs,
|
|
24564
24553
|
evaluationStatsBuckets,
|
|
24565
24554
|
lineageScopes
|
|
24566
24555
|
}) => ({
|
|
@@ -24579,15 +24568,13 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
24579
24568
|
signals: signals2.length,
|
|
24580
24569
|
evaluations: evaluations.length,
|
|
24581
24570
|
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
24582
|
-
lineageScopes: lineageScopes?.length ?? 0
|
|
24583
|
-
strategyConfigs: strategyConfigs?.length ?? 0
|
|
24571
|
+
lineageScopes: lineageScopes?.length ?? 0
|
|
24584
24572
|
},
|
|
24585
24573
|
trades: trades.map((trade) => ({ trade })),
|
|
24586
24574
|
signals: signals2.map((signal) => ({ signal })),
|
|
24587
24575
|
evaluations: evaluations.map((evaluation) => ({ evaluation })),
|
|
24588
24576
|
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
24589
|
-
lineageScopes: lineageScopes ?? []
|
|
24590
|
-
strategyConfigs: strategyConfigs ?? []
|
|
24577
|
+
lineageScopes: lineageScopes ?? []
|
|
24591
24578
|
});
|
|
24592
24579
|
buildRuntimeDebugReportAttachment = async (params) => {
|
|
24593
24580
|
const payload = await buildRuntimeDebugReportPayload(params);
|
|
@@ -25017,7 +25004,6 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
25017
25004
|
signals: runtimeEvidence2.signals,
|
|
25018
25005
|
evaluations: runtimeEvidence2.evaluations,
|
|
25019
25006
|
trades: runtimeEvidence2.trades,
|
|
25020
|
-
strategyConfigs: runtimeEvidence2.strategyConfigs,
|
|
25021
25007
|
evaluationStatsBuckets: runtimeEvidence2.evaluationStatsBuckets,
|
|
25022
25008
|
lineageScopes: runtimeEvidence2.lineageScopes
|
|
25023
25009
|
})
|
|
@@ -25099,6 +25085,294 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
25099
25085
|
}
|
|
25100
25086
|
});
|
|
25101
25087
|
|
|
25088
|
+
// src/lib/runtimeEvidenceDeployment.ts
|
|
25089
|
+
var import_runtimeStrategies3, isRecord, isNonEmptyString, isPackageVersionMap, INTERVALS, UNIVERSES, isRuntimeStrategySelection, samePackageVersions, runtimeLineageMatchesStrategySnapshot, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, unwrapRuntimeEvidenceRows, assertCurrentRuntimeEvidenceArtifact, resolveRuntimeEvidenceTickerUniverse, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
|
|
25090
|
+
var init_runtimeEvidenceDeployment = __esm({
|
|
25091
|
+
"src/lib/runtimeEvidenceDeployment.ts"() {
|
|
25092
|
+
"use strict";
|
|
25093
|
+
import_runtimeStrategies3 = require("@tradejs/node/runtimeStrategies");
|
|
25094
|
+
isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
25095
|
+
isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
25096
|
+
isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
25097
|
+
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
25098
|
+
);
|
|
25099
|
+
INTERVALS = /* @__PURE__ */ new Set([
|
|
25100
|
+
"1",
|
|
25101
|
+
"3",
|
|
25102
|
+
"5",
|
|
25103
|
+
"15",
|
|
25104
|
+
"30",
|
|
25105
|
+
"60",
|
|
25106
|
+
"120",
|
|
25107
|
+
"240",
|
|
25108
|
+
"360",
|
|
25109
|
+
"720",
|
|
25110
|
+
"D",
|
|
25111
|
+
"W",
|
|
25112
|
+
"M"
|
|
25113
|
+
]);
|
|
25114
|
+
UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
25115
|
+
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));
|
|
25116
|
+
samePackageVersions = (left, right) => {
|
|
25117
|
+
if (!left || !right) return false;
|
|
25118
|
+
const leftEntries = Object.entries(left).sort(
|
|
25119
|
+
([a], [b]) => a.localeCompare(b)
|
|
25120
|
+
);
|
|
25121
|
+
const rightEntries = Object.entries(right).sort(
|
|
25122
|
+
([a], [b]) => a.localeCompare(b)
|
|
25123
|
+
);
|
|
25124
|
+
return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
|
|
25125
|
+
};
|
|
25126
|
+
runtimeLineageMatchesStrategySnapshot = ({
|
|
25127
|
+
lineage,
|
|
25128
|
+
deployment,
|
|
25129
|
+
strategy
|
|
25130
|
+
}) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
|
|
25131
|
+
lineage.strategyDependencyVersions,
|
|
25132
|
+
strategy.strategyDependencyVersions
|
|
25133
|
+
);
|
|
25134
|
+
parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
25135
|
+
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)) {
|
|
25136
|
+
throw new Error(
|
|
25137
|
+
"Runtime evidence deployment snapshot is missing or invalid"
|
|
25138
|
+
);
|
|
25139
|
+
}
|
|
25140
|
+
const strategies = value.strategies.map((candidate) => {
|
|
25141
|
+
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)) {
|
|
25142
|
+
throw new Error(
|
|
25143
|
+
"Runtime evidence deployment strategy snapshot is invalid"
|
|
25144
|
+
);
|
|
25145
|
+
}
|
|
25146
|
+
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
25147
|
+
throw new Error(
|
|
25148
|
+
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
25149
|
+
);
|
|
25150
|
+
}
|
|
25151
|
+
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
25152
|
+
throw new Error(
|
|
25153
|
+
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
25154
|
+
);
|
|
25155
|
+
}
|
|
25156
|
+
return candidate;
|
|
25157
|
+
});
|
|
25158
|
+
const identities = /* @__PURE__ */ new Set();
|
|
25159
|
+
for (const strategy of strategies) {
|
|
25160
|
+
if (identities.has(strategy.strategyName)) {
|
|
25161
|
+
throw new Error(
|
|
25162
|
+
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
25163
|
+
);
|
|
25164
|
+
}
|
|
25165
|
+
identities.add(strategy.strategyName);
|
|
25166
|
+
}
|
|
25167
|
+
return {
|
|
25168
|
+
...value,
|
|
25169
|
+
strategies
|
|
25170
|
+
};
|
|
25171
|
+
};
|
|
25172
|
+
activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
25173
|
+
unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
25174
|
+
const record = isRecord(candidate) ? candidate : null;
|
|
25175
|
+
const nested = record && isRecord(record[field]) ? record[field] : null;
|
|
25176
|
+
return nested ?? record;
|
|
25177
|
+
}).filter((record) => record != null);
|
|
25178
|
+
assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
25179
|
+
if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
25180
|
+
throw new Error("Invalid runtime evidence artifact");
|
|
25181
|
+
}
|
|
25182
|
+
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
25183
|
+
artifact.deployment
|
|
25184
|
+
);
|
|
25185
|
+
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
25186
|
+
if (activeStrategies.length === 0) {
|
|
25187
|
+
throw new Error("Runtime evidence deployment has no enabled strategies");
|
|
25188
|
+
}
|
|
25189
|
+
const runtime = isRecord(artifact.runtime) ? artifact.runtime : null;
|
|
25190
|
+
if (!runtime) {
|
|
25191
|
+
throw new Error("Runtime evidence payload is missing");
|
|
25192
|
+
}
|
|
25193
|
+
if ("strategyConfigs" in runtime) {
|
|
25194
|
+
throw new Error(
|
|
25195
|
+
"Runtime evidence payload contains removed strategyConfigs data"
|
|
25196
|
+
);
|
|
25197
|
+
}
|
|
25198
|
+
const rowFields = [
|
|
25199
|
+
"trades",
|
|
25200
|
+
"signals",
|
|
25201
|
+
"evaluations",
|
|
25202
|
+
"lineageScopes"
|
|
25203
|
+
];
|
|
25204
|
+
for (const field of rowFields) {
|
|
25205
|
+
if (!Array.isArray(runtime[field])) {
|
|
25206
|
+
throw new Error(`Runtime evidence payload ${field} must be an array`);
|
|
25207
|
+
}
|
|
25208
|
+
}
|
|
25209
|
+
const snapshots = new Map(
|
|
25210
|
+
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
25211
|
+
);
|
|
25212
|
+
const assertRows = (label, rows, lineageField) => {
|
|
25213
|
+
for (const row of rows) {
|
|
25214
|
+
const strategyName = String(row.strategy ?? "").trim();
|
|
25215
|
+
const strategy = snapshots.get(strategyName);
|
|
25216
|
+
if (!strategy || row.deploymentId !== deployment.id || row.accountId !== deployment.accountId || !runtimeLineageMatchesStrategySnapshot({
|
|
25217
|
+
lineage: isRecord(row[lineageField]) ? row[lineageField] : void 0,
|
|
25218
|
+
deployment,
|
|
25219
|
+
strategy
|
|
25220
|
+
})) {
|
|
25221
|
+
throw new Error(
|
|
25222
|
+
`Runtime evidence ${label} row is outside the current embedded deployment lineage`
|
|
25223
|
+
);
|
|
25224
|
+
}
|
|
25225
|
+
}
|
|
25226
|
+
};
|
|
25227
|
+
assertRows(
|
|
25228
|
+
"trade",
|
|
25229
|
+
unwrapRuntimeEvidenceRows(runtime.trades, "trade"),
|
|
25230
|
+
"runtimeLineage"
|
|
25231
|
+
);
|
|
25232
|
+
assertRows(
|
|
25233
|
+
"signal",
|
|
25234
|
+
unwrapRuntimeEvidenceRows(runtime.signals, "signal"),
|
|
25235
|
+
"runtimeLineage"
|
|
25236
|
+
);
|
|
25237
|
+
assertRows(
|
|
25238
|
+
"evaluation",
|
|
25239
|
+
unwrapRuntimeEvidenceRows(runtime.evaluations, "evaluation"),
|
|
25240
|
+
"runtimeLineage"
|
|
25241
|
+
);
|
|
25242
|
+
assertRows(
|
|
25243
|
+
"lineage scope",
|
|
25244
|
+
unwrapRuntimeEvidenceRows(runtime.lineageScopes, "lineageScope"),
|
|
25245
|
+
"lineage"
|
|
25246
|
+
);
|
|
25247
|
+
return deployment;
|
|
25248
|
+
};
|
|
25249
|
+
resolveRuntimeEvidenceTickerUniverse = ({
|
|
25250
|
+
deployment,
|
|
25251
|
+
lineageScopes
|
|
25252
|
+
}) => {
|
|
25253
|
+
const declaredTickers = deployment.tickers?.filter(isNonEmptyString) ?? [];
|
|
25254
|
+
if (declaredTickers.length > 0) {
|
|
25255
|
+
return {
|
|
25256
|
+
...deployment,
|
|
25257
|
+
tickers: [
|
|
25258
|
+
...new Set(declaredTickers.map((ticker) => ticker.trim()))
|
|
25259
|
+
].sort()
|
|
25260
|
+
};
|
|
25261
|
+
}
|
|
25262
|
+
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
25263
|
+
if (activeStrategies.length > 0 && activeStrategies.every((strategy) => strategy.selection?.tickers?.length)) {
|
|
25264
|
+
return {
|
|
25265
|
+
...deployment,
|
|
25266
|
+
tickers: [
|
|
25267
|
+
...new Set(
|
|
25268
|
+
activeStrategies.flatMap(
|
|
25269
|
+
(strategy) => strategy.selection?.tickers ?? []
|
|
25270
|
+
)
|
|
25271
|
+
)
|
|
25272
|
+
].sort()
|
|
25273
|
+
};
|
|
25274
|
+
}
|
|
25275
|
+
const strategiesByName = new Map(
|
|
25276
|
+
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
25277
|
+
);
|
|
25278
|
+
const tickers = /* @__PURE__ */ new Set();
|
|
25279
|
+
for (const scope of lineageScopes) {
|
|
25280
|
+
const strategy = strategiesByName.get(scope.strategy);
|
|
25281
|
+
if (!strategy || scope.deploymentId !== deployment.id || scope.accountId !== deployment.accountId || !isNonEmptyString(scope.symbol) || !runtimeLineageMatchesStrategySnapshot({
|
|
25282
|
+
lineage: scope.lineage,
|
|
25283
|
+
deployment,
|
|
25284
|
+
strategy
|
|
25285
|
+
})) {
|
|
25286
|
+
continue;
|
|
25287
|
+
}
|
|
25288
|
+
tickers.add(scope.symbol.trim());
|
|
25289
|
+
}
|
|
25290
|
+
if (tickers.size === 0) {
|
|
25291
|
+
throw new Error(
|
|
25292
|
+
"Runtime evidence has no immutable ticker universe for the embedded deployment composition"
|
|
25293
|
+
);
|
|
25294
|
+
}
|
|
25295
|
+
return { ...deployment, tickers: [...tickers].sort() };
|
|
25296
|
+
};
|
|
25297
|
+
runtimeDeploymentFromEvidence = (deployment) => ({
|
|
25298
|
+
id: deployment.id,
|
|
25299
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
25300
|
+
label: deployment.label,
|
|
25301
|
+
connectorName: deployment.connectorName,
|
|
25302
|
+
provider: deployment.provider,
|
|
25303
|
+
accountId: deployment.accountId,
|
|
25304
|
+
enabled: deployment.enabled,
|
|
25305
|
+
strategies: deployment.strategies.map(
|
|
25306
|
+
({ strategyName, strategyRevision, enabled, controlState, selection }) => ({
|
|
25307
|
+
strategyName,
|
|
25308
|
+
strategyRevision,
|
|
25309
|
+
enabled,
|
|
25310
|
+
controlState,
|
|
25311
|
+
...selection ? { selection } : {}
|
|
25312
|
+
})
|
|
25313
|
+
),
|
|
25314
|
+
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
25315
|
+
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
25316
|
+
});
|
|
25317
|
+
resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
25318
|
+
userName: userName3,
|
|
25319
|
+
projectRoot: projectRoot15,
|
|
25320
|
+
deploymentId
|
|
25321
|
+
}) => {
|
|
25322
|
+
const [deployment, strategies] = await Promise.all([
|
|
25323
|
+
(0, import_runtimeStrategies3.getRuntimeDeployment)({ userName: userName3, projectRoot: projectRoot15, deploymentId }),
|
|
25324
|
+
(0, import_runtimeStrategies3.loadResolvedRuntimeStrategies)({ userName: userName3, projectRoot: projectRoot15, deploymentId })
|
|
25325
|
+
]);
|
|
25326
|
+
if (!deployment) {
|
|
25327
|
+
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
25328
|
+
}
|
|
25329
|
+
return {
|
|
25330
|
+
schemaVersion: 2,
|
|
25331
|
+
id: deployment.id,
|
|
25332
|
+
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
25333
|
+
label: deployment.label,
|
|
25334
|
+
connectorName: deployment.connectorName,
|
|
25335
|
+
provider: deployment.provider,
|
|
25336
|
+
accountId: deployment.accountId,
|
|
25337
|
+
enabled: deployment.enabled,
|
|
25338
|
+
strategies: strategies.map(
|
|
25339
|
+
({
|
|
25340
|
+
strategyName,
|
|
25341
|
+
strategyRevision,
|
|
25342
|
+
enabled,
|
|
25343
|
+
controlState,
|
|
25344
|
+
interval: interval4,
|
|
25345
|
+
universe,
|
|
25346
|
+
accountId,
|
|
25347
|
+
strategyPackage,
|
|
25348
|
+
strategyPackageVersion,
|
|
25349
|
+
strategyDependencyVersions,
|
|
25350
|
+
runtimePackageVersion,
|
|
25351
|
+
strategyConfig,
|
|
25352
|
+
selection
|
|
25353
|
+
}) => ({
|
|
25354
|
+
strategyName,
|
|
25355
|
+
strategyRevision,
|
|
25356
|
+
enabled,
|
|
25357
|
+
controlState,
|
|
25358
|
+
interval: interval4,
|
|
25359
|
+
universe,
|
|
25360
|
+
...accountId ? { accountId } : {},
|
|
25361
|
+
strategyPackage,
|
|
25362
|
+
strategyPackageVersion,
|
|
25363
|
+
strategyDependencyVersions,
|
|
25364
|
+
runtimePackageVersion,
|
|
25365
|
+
strategyConfig,
|
|
25366
|
+
...selection ? { selection } : {}
|
|
25367
|
+
})
|
|
25368
|
+
),
|
|
25369
|
+
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
25370
|
+
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
25371
|
+
};
|
|
25372
|
+
};
|
|
25373
|
+
}
|
|
25374
|
+
});
|
|
25375
|
+
|
|
25102
25376
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
25103
25377
|
var import_node_crypto10, import_promises22, import_node_path16, RUNTIME_EVIDENCE_MANIFEST_FILE, RUNTIME_EVIDENCE_PAYLOAD_FILE, RUNTIME_EVIDENCE_COMPLETE_FILE, asRecord5, sha256, runtimeEvidenceIdentitySha256, isExistingDestinationError, safeSegment, compactTimestamp, dateParts, assertFiniteTimestamp, parseManifest, publishRuntimeEvidenceBundle, verifyRuntimeEvidenceBundle, discoverRuntimeEvidenceBundles;
|
|
25104
25378
|
var init_runtimeEvidenceArtifacts = __esm({
|
|
@@ -25107,6 +25381,7 @@ var init_runtimeEvidenceArtifacts = __esm({
|
|
|
25107
25381
|
import_node_crypto10 = require("crypto");
|
|
25108
25382
|
import_promises22 = __toESM(require("fs/promises"));
|
|
25109
25383
|
import_node_path16 = __toESM(require("path"));
|
|
25384
|
+
init_runtimeEvidenceDeployment();
|
|
25110
25385
|
RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
|
|
25111
25386
|
RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
|
|
25112
25387
|
RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
|
|
@@ -25190,6 +25465,7 @@ var init_runtimeEvidenceArtifacts = __esm({
|
|
|
25190
25465
|
counts,
|
|
25191
25466
|
lineageKeys
|
|
25192
25467
|
}) => {
|
|
25468
|
+
assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
25193
25469
|
const payload = `${JSON.stringify(artifact, null, 2)}
|
|
25194
25470
|
`;
|
|
25195
25471
|
const payloadSha256 = sha256(payload);
|
|
@@ -25289,6 +25565,10 @@ var init_runtimeEvidenceArtifacts = __esm({
|
|
|
25289
25565
|
if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
|
|
25290
25566
|
throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
|
|
25291
25567
|
}
|
|
25568
|
+
const deployment = assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
25569
|
+
if (deployment.id !== manifest.deploymentId) {
|
|
25570
|
+
throw new Error(`Runtime evidence deployment mismatch in ${bundleDir}`);
|
|
25571
|
+
}
|
|
25292
25572
|
return {
|
|
25293
25573
|
bundleDir,
|
|
25294
25574
|
manifestPath,
|
|
@@ -25326,131 +25606,11 @@ var init_runtimeEvidenceArtifacts = __esm({
|
|
|
25326
25606
|
});
|
|
25327
25607
|
|
|
25328
25608
|
// src/lib/runtimeLineage.ts
|
|
25329
|
-
|
|
25330
|
-
projectRoot: projectRoot15,
|
|
25331
|
-
strategyName,
|
|
25332
|
-
compositionId,
|
|
25333
|
-
strategyRevision,
|
|
25334
|
-
deploymentCompositionId,
|
|
25335
|
-
strategyPackageVersion,
|
|
25336
|
-
strategyDependencyVersions,
|
|
25337
|
-
runtimePackageVersion,
|
|
25338
|
-
config: config2,
|
|
25339
|
-
runContext,
|
|
25340
|
-
env = process.env
|
|
25341
|
-
}) {
|
|
25342
|
-
if (strategyRevision != null) {
|
|
25343
|
-
if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
|
|
25344
|
-
throw new Error(`Invalid strategy revision: ${strategyRevision}`);
|
|
25345
|
-
}
|
|
25346
|
-
if (typeof deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
|
|
25347
|
-
throw new Error(
|
|
25348
|
-
`Invalid deployment composition id: ${String(deploymentCompositionId)}`
|
|
25349
|
-
);
|
|
25350
|
-
}
|
|
25351
|
-
if (typeof strategyPackageVersion !== "string" || !strategyPackageVersion.trim() || typeof runtimePackageVersion !== "string" || !runtimePackageVersion.trim()) {
|
|
25352
|
-
throw new Error("Invalid revision package versions");
|
|
25353
|
-
}
|
|
25354
|
-
if (!strategyDependencyVersions || Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
|
|
25355
|
-
([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
|
|
25356
|
-
)) {
|
|
25357
|
-
throw new Error("Invalid strategy dependency versions");
|
|
25358
|
-
}
|
|
25359
|
-
return {
|
|
25360
|
-
schemaVersion: 3,
|
|
25361
|
-
strategyRevision,
|
|
25362
|
-
deploymentCompositionId,
|
|
25363
|
-
strategyPackageVersion,
|
|
25364
|
-
strategyDependencyVersions,
|
|
25365
|
-
runtimePackageVersion,
|
|
25366
|
-
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
25367
|
-
};
|
|
25368
|
-
}
|
|
25369
|
-
const git = resolveGitLineage(projectRoot15);
|
|
25370
|
-
const hyperliquidPerpUniverseFingerprint = typeof import_strategies10.getHyperliquidPerpUniverseSnapshot === "function" ? (0, import_strategies10.getHyperliquidPerpUniverseSnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
25371
|
-
projectRoot15,
|
|
25372
|
-
"packages/node/src/config/hyperliquidPerpUniverse.json"
|
|
25373
|
-
);
|
|
25374
|
-
const hyperliquidWhaleRegistryFingerprint = typeof import_strategies10.getHyperliquidWhaleRegistrySnapshot === "function" ? (0, import_strategies10.getHyperliquidWhaleRegistrySnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
25375
|
-
projectRoot15,
|
|
25376
|
-
"packages/node/src/config/hyperliquidWhales.json"
|
|
25377
|
-
);
|
|
25378
|
-
const context = {
|
|
25379
|
-
...Object.fromEntries(
|
|
25380
|
-
RUNTIME_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
|
|
25381
|
-
),
|
|
25382
|
-
...RUNTIME_CONTEXT_DATA_MODEL,
|
|
25383
|
-
binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(projectRoot15),
|
|
25384
|
-
hyperliquidPerpUniverseFingerprint,
|
|
25385
|
-
hyperliquidWhaleRegistryFingerprint,
|
|
25386
|
-
...runContext
|
|
25387
|
-
};
|
|
25388
|
-
return {
|
|
25389
|
-
schemaVersion: 1,
|
|
25390
|
-
compositionId: compositionId?.trim() || null,
|
|
25391
|
-
...git,
|
|
25392
|
-
gateFingerprint: (await resolveRuntimeGateFingerprint({
|
|
25393
|
-
projectRoot: projectRoot15,
|
|
25394
|
-
strategyName,
|
|
25395
|
-
gitSha: git.gitSha
|
|
25396
|
-
})).gateFingerprint,
|
|
25397
|
-
// Position risk is tracked separately so changing trade size does not
|
|
25398
|
-
// masquerade as a change to the core + gate decision logic.
|
|
25399
|
-
configFingerprint: (0, import_strategyReleaseEvidence2.strategyLogicConfigFingerprint)(config2),
|
|
25400
|
-
contextFingerprint: fingerprintRuntimeValue(context),
|
|
25401
|
-
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
25402
|
-
};
|
|
25403
|
-
}
|
|
25404
|
-
var import_node_child_process6, import_node_crypto11, import_promises23, import_node_path17, import_types8, import_strategies10, import_strategyReleaseEvidence2, RUNTIME_CONTEXT_ENV_KEYS, RUNTIME_CONTEXT_DATA_MODEL, normalizeForStableJson2, resolveRuntimeMaxLossValue, fingerprintRuntimeValue, gitLineageCache, gateFingerprintCache, binanceBreadthFingerprintCache, snapshotFingerprintCache, resolveGitLineage, readOptionalFile, resolveBinanceBreadthFingerprint, resolveSnapshotFingerprint, resolveRuntimeGateFingerprint, runtimeLineageKey, runtimeLineagesMatch, runtimeLineagesComparable;
|
|
25609
|
+
var import_node_crypto11, normalizeForStableJson2, resolveRuntimeMaxLossValue, fingerprintRuntimeValue, buildRuntimeLineage, runtimeLineageKey, runtimeLineagesMatch, runtimeLineagesComparable;
|
|
25405
25610
|
var init_runtimeLineage = __esm({
|
|
25406
25611
|
"src/lib/runtimeLineage.ts"() {
|
|
25407
25612
|
"use strict";
|
|
25408
|
-
import_node_child_process6 = require("child_process");
|
|
25409
25613
|
import_node_crypto11 = require("crypto");
|
|
25410
|
-
import_promises23 = __toESM(require("fs/promises"));
|
|
25411
|
-
import_node_path17 = __toESM(require("path"));
|
|
25412
|
-
import_types8 = require("@tradejs/types");
|
|
25413
|
-
import_strategies10 = require("@tradejs/node/strategies");
|
|
25414
|
-
import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
25415
|
-
init_strategyGateFingerprint();
|
|
25416
|
-
RUNTIME_CONTEXT_ENV_KEYS = [
|
|
25417
|
-
"AI_MODE",
|
|
25418
|
-
"MIN_AI_QUALITY",
|
|
25419
|
-
"INTERVAL",
|
|
25420
|
-
"DERIVATIVES_CONTEXT_ENABLED",
|
|
25421
|
-
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
25422
|
-
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
25423
|
-
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
25424
|
-
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|
|
25425
|
-
"COINMARKETCAP_CONTEXT_ENABLED",
|
|
25426
|
-
"COINMARKETCAP_CONTEXT_MAX_AGE_MS",
|
|
25427
|
-
"COINMARKETCAP_CONTEXT_EXCHANGE_LIQUIDITY_ENABLED",
|
|
25428
|
-
"COINMARKETCAP_CONTEXT_EXCHANGE_SLUGS",
|
|
25429
|
-
"COINMARKETCAP_CONTEXT_FEAR_GREED_ENABLED",
|
|
25430
|
-
"COINMARKETCAP_CONTEXT_HISTORICAL_ACCESS_MONTHS",
|
|
25431
|
-
"COINMARKETCAP_CONTEXT_BACKFILL_ENABLED",
|
|
25432
|
-
"COINMARKETCAP_CONTEXT_BACKFILL_MAX_DAYS",
|
|
25433
|
-
"COINMARKETCAP_CONTEXT_BACKFILL_WARMUP_DAYS",
|
|
25434
|
-
"HYPERLIQUID_WHALE_CONTEXT_ENABLED",
|
|
25435
|
-
"HYPERLIQUID_WHALE_BACKFILL_ENABLED",
|
|
25436
|
-
"HYPERLIQUID_WHALE_MIN_COVERAGE_PCT",
|
|
25437
|
-
"HYPERLIQUID_WHALE_CONCURRENCY",
|
|
25438
|
-
"HYPERLIQUID_WHALE_RATE_LIMIT_WEIGHT"
|
|
25439
|
-
];
|
|
25440
|
-
RUNTIME_CONTEXT_DATA_MODEL = {
|
|
25441
|
-
derivativesSourceIntervals: "15m",
|
|
25442
|
-
derivativesDerivedIntervals: "1h",
|
|
25443
|
-
derivativesHourlyFallback: "stored-1h",
|
|
25444
|
-
derivativesDataModelVersion: 2,
|
|
25445
|
-
coinMarketCapAvailabilityModel: "closed-interval-all-daily",
|
|
25446
|
-
coinMarketCapDataModelVersion: 3,
|
|
25447
|
-
binanceBreadthUniverseModel: "fixed-versioned-top5-top10-top30-top50-top100",
|
|
25448
|
-
binanceBreadthDataModelVersion: 2,
|
|
25449
|
-
hyperliquidWhaleCanonicalInterval: "1m",
|
|
25450
|
-
hyperliquidWhaleGateMinNotionalUsd: 5e4,
|
|
25451
|
-
hyperliquidWhaleMinCoveragePct: 0.8,
|
|
25452
|
-
hyperliquidWhaleDataModelVersion: import_types8.HYPERLIQUID_WHALE_DATA_MODEL_VERSION
|
|
25453
|
-
};
|
|
25454
25614
|
normalizeForStableJson2 = (value) => {
|
|
25455
25615
|
if (Array.isArray(value)) {
|
|
25456
25616
|
return value.map(normalizeForStableJson2);
|
|
@@ -25476,364 +25636,65 @@ var init_runtimeLineage = __esm({
|
|
|
25476
25636
|
return Number.isFinite(maxLossValue) ? maxLossValue : null;
|
|
25477
25637
|
};
|
|
25478
25638
|
fingerprintRuntimeValue = (value) => (0, import_node_crypto11.createHash)("sha256").update(JSON.stringify(normalizeForStableJson2(value))).digest("hex").slice(0, 16);
|
|
25479
|
-
|
|
25480
|
-
|
|
25481
|
-
|
|
25482
|
-
|
|
25483
|
-
|
|
25484
|
-
|
|
25485
|
-
|
|
25486
|
-
|
|
25487
|
-
}
|
|
25488
|
-
|
|
25489
|
-
if (envSha && envSha !== "unknown") {
|
|
25490
|
-
const result = {
|
|
25491
|
-
gitSha: envSha,
|
|
25492
|
-
gitDirty: false
|
|
25493
|
-
};
|
|
25494
|
-
gitLineageCache.set(projectRoot15, result);
|
|
25495
|
-
return result;
|
|
25496
|
-
}
|
|
25497
|
-
try {
|
|
25498
|
-
const gitSha = (0, import_node_child_process6.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
25499
|
-
cwd: projectRoot15,
|
|
25500
|
-
encoding: "utf8",
|
|
25501
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
25502
|
-
}).trim();
|
|
25503
|
-
const status = (0, import_node_child_process6.execFileSync)(
|
|
25504
|
-
"git",
|
|
25505
|
-
["status", "--porcelain", "--untracked-files=normal"],
|
|
25506
|
-
{
|
|
25507
|
-
cwd: projectRoot15,
|
|
25508
|
-
encoding: "utf8",
|
|
25509
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
25510
|
-
}
|
|
25511
|
-
).trim();
|
|
25512
|
-
const result = {
|
|
25513
|
-
gitSha: gitSha || null,
|
|
25514
|
-
gitDirty: status.length > 0
|
|
25515
|
-
};
|
|
25516
|
-
gitLineageCache.set(projectRoot15, result);
|
|
25517
|
-
return result;
|
|
25518
|
-
} catch {
|
|
25519
|
-
const result = {
|
|
25520
|
-
gitSha: null,
|
|
25521
|
-
gitDirty: null
|
|
25522
|
-
};
|
|
25523
|
-
gitLineageCache.set(projectRoot15, result);
|
|
25524
|
-
return result;
|
|
25525
|
-
}
|
|
25526
|
-
};
|
|
25527
|
-
readOptionalFile = async (filePath) => {
|
|
25528
|
-
try {
|
|
25529
|
-
return await import_promises23.default.readFile(filePath);
|
|
25530
|
-
} catch {
|
|
25531
|
-
return null;
|
|
25532
|
-
}
|
|
25533
|
-
};
|
|
25534
|
-
resolveBinanceBreadthFingerprint = async (projectRoot15) => {
|
|
25535
|
-
if (binanceBreadthFingerprintCache.has(projectRoot15)) {
|
|
25536
|
-
return binanceBreadthFingerprintCache.get(projectRoot15) ?? null;
|
|
25639
|
+
buildRuntimeLineage = async ({
|
|
25640
|
+
strategyRevision,
|
|
25641
|
+
deploymentCompositionId,
|
|
25642
|
+
strategyPackageVersion,
|
|
25643
|
+
strategyDependencyVersions,
|
|
25644
|
+
runtimePackageVersion,
|
|
25645
|
+
config: config2
|
|
25646
|
+
}) => {
|
|
25647
|
+
if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
|
|
25648
|
+
throw new Error(`Invalid strategy revision: ${strategyRevision}`);
|
|
25537
25649
|
}
|
|
25538
|
-
|
|
25539
|
-
|
|
25540
|
-
|
|
25541
|
-
|
|
25542
|
-
)
|
|
25543
|
-
);
|
|
25544
|
-
let result = null;
|
|
25545
|
-
if (content) {
|
|
25546
|
-
try {
|
|
25547
|
-
const parsed = JSON.parse(content.toString("utf8"));
|
|
25548
|
-
result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
|
|
25549
|
-
} catch {
|
|
25550
|
-
result = null;
|
|
25551
|
-
}
|
|
25650
|
+
if (!/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
|
|
25651
|
+
throw new Error(
|
|
25652
|
+
`Invalid deployment composition id: ${deploymentCompositionId}`
|
|
25653
|
+
);
|
|
25552
25654
|
}
|
|
25553
|
-
|
|
25554
|
-
|
|
25555
|
-
};
|
|
25556
|
-
resolveSnapshotFingerprint = async (projectRoot15, relativePath) => {
|
|
25557
|
-
const cacheKey = `${projectRoot15}:${relativePath}`;
|
|
25558
|
-
if (snapshotFingerprintCache.has(cacheKey)) {
|
|
25559
|
-
return snapshotFingerprintCache.get(cacheKey) ?? null;
|
|
25655
|
+
if (!strategyPackageVersion.trim() || !runtimePackageVersion.trim()) {
|
|
25656
|
+
throw new Error("Invalid revision package versions");
|
|
25560
25657
|
}
|
|
25561
|
-
|
|
25562
|
-
|
|
25563
|
-
|
|
25564
|
-
|
|
25565
|
-
const parsed = JSON.parse(content.toString("utf8"));
|
|
25566
|
-
result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
|
|
25567
|
-
} catch {
|
|
25568
|
-
result = null;
|
|
25569
|
-
}
|
|
25658
|
+
if (Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
|
|
25659
|
+
([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
|
|
25660
|
+
)) {
|
|
25661
|
+
throw new Error("Invalid strategy dependency versions");
|
|
25570
25662
|
}
|
|
25571
|
-
|
|
25572
|
-
|
|
25573
|
-
|
|
25574
|
-
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
|
|
25578
|
-
|
|
25579
|
-
|
|
25580
|
-
const cached = gateFingerprintCache.get(cacheKey);
|
|
25581
|
-
if (cached) return cached;
|
|
25582
|
-
const result = await resolveStrategyGateFingerprint({
|
|
25583
|
-
projectRoot: projectRoot15,
|
|
25584
|
-
strategyName,
|
|
25585
|
-
gitSha
|
|
25586
|
-
});
|
|
25587
|
-
gateFingerprintCache.set(cacheKey, result);
|
|
25588
|
-
return result;
|
|
25663
|
+
return {
|
|
25664
|
+
schemaVersion: 3,
|
|
25665
|
+
strategyRevision,
|
|
25666
|
+
deploymentCompositionId,
|
|
25667
|
+
strategyPackageVersion,
|
|
25668
|
+
strategyDependencyVersions,
|
|
25669
|
+
runtimePackageVersion,
|
|
25670
|
+
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
25671
|
+
};
|
|
25589
25672
|
};
|
|
25590
|
-
runtimeLineageKey = (lineage) =>
|
|
25673
|
+
runtimeLineageKey = (lineage) => [
|
|
25591
25674
|
"v3",
|
|
25592
25675
|
lineage.deploymentCompositionId,
|
|
25593
25676
|
lineage.strategyRevision,
|
|
25594
25677
|
lineage.strategyPackageVersion,
|
|
25595
|
-
`deps:${fingerprintRuntimeValue(
|
|
25596
|
-
lineage.strategyDependencyVersions
|
|
25597
|
-
).slice(0, 16)}`,
|
|
25678
|
+
`deps:${fingerprintRuntimeValue(lineage.strategyDependencyVersions).slice(0, 16)}`,
|
|
25598
25679
|
lineage.runtimePackageVersion
|
|
25599
|
-
].join(":") : [
|
|
25600
|
-
lineage.schemaVersion,
|
|
25601
|
-
lineage.compositionId ?? "unbound-composition",
|
|
25602
|
-
lineage.gitSha ?? "unknown",
|
|
25603
|
-
lineage.gitDirty == null ? "unknown" : lineage.gitDirty ? "dirty" : "clean",
|
|
25604
|
-
lineage.gateFingerprint,
|
|
25605
|
-
lineage.configFingerprint,
|
|
25606
|
-
lineage.contextFingerprint
|
|
25607
25680
|
].join(":");
|
|
25608
25681
|
runtimeLineagesMatch = (left, right) => left != null && right != null && runtimeLineageKey(left) === runtimeLineageKey(right);
|
|
25609
25682
|
runtimeLineagesComparable = (left, right) => runtimeLineagesMatch(left, right) && typeof left?.maxLossValue === "number" && Number.isFinite(left.maxLossValue) && typeof right?.maxLossValue === "number" && Number.isFinite(right.maxLossValue) && left.maxLossValue === right.maxLossValue;
|
|
25610
25683
|
}
|
|
25611
25684
|
});
|
|
25612
25685
|
|
|
25613
|
-
// src/lib/runtimeEvidenceDeployment.ts
|
|
25614
|
-
var import_runtimeStrategies3, isRecord, isNonEmptyString, isPackageVersionMap, INTERVALS, UNIVERSES, isRuntimeStrategySelection, samePackageVersions, lineageMatchesStrategySnapshot, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, resolveRuntimeEvidenceTickerUniverse, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
|
|
25615
|
-
var init_runtimeEvidenceDeployment = __esm({
|
|
25616
|
-
"src/lib/runtimeEvidenceDeployment.ts"() {
|
|
25617
|
-
"use strict";
|
|
25618
|
-
import_runtimeStrategies3 = require("@tradejs/node/runtimeStrategies");
|
|
25619
|
-
isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
25620
|
-
isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
25621
|
-
isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
25622
|
-
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
25623
|
-
);
|
|
25624
|
-
INTERVALS = /* @__PURE__ */ new Set([
|
|
25625
|
-
"1",
|
|
25626
|
-
"3",
|
|
25627
|
-
"5",
|
|
25628
|
-
"15",
|
|
25629
|
-
"30",
|
|
25630
|
-
"60",
|
|
25631
|
-
"120",
|
|
25632
|
-
"240",
|
|
25633
|
-
"360",
|
|
25634
|
-
"720",
|
|
25635
|
-
"D",
|
|
25636
|
-
"W",
|
|
25637
|
-
"M"
|
|
25638
|
-
]);
|
|
25639
|
-
UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
25640
|
-
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));
|
|
25641
|
-
samePackageVersions = (left, right) => {
|
|
25642
|
-
if (!left || !right) return false;
|
|
25643
|
-
const leftEntries = Object.entries(left).sort(
|
|
25644
|
-
([a], [b]) => a.localeCompare(b)
|
|
25645
|
-
);
|
|
25646
|
-
const rightEntries = Object.entries(right).sort(
|
|
25647
|
-
([a], [b]) => a.localeCompare(b)
|
|
25648
|
-
);
|
|
25649
|
-
return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
|
|
25650
|
-
};
|
|
25651
|
-
lineageMatchesStrategySnapshot = ({
|
|
25652
|
-
lineage,
|
|
25653
|
-
deployment,
|
|
25654
|
-
strategy
|
|
25655
|
-
}) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
|
|
25656
|
-
lineage.strategyDependencyVersions,
|
|
25657
|
-
strategy.strategyDependencyVersions
|
|
25658
|
-
);
|
|
25659
|
-
parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
25660
|
-
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)) {
|
|
25661
|
-
throw new Error(
|
|
25662
|
-
"Runtime evidence deployment snapshot is missing or invalid"
|
|
25663
|
-
);
|
|
25664
|
-
}
|
|
25665
|
-
const strategies = value.strategies.map((candidate) => {
|
|
25666
|
-
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)) {
|
|
25667
|
-
throw new Error(
|
|
25668
|
-
"Runtime evidence deployment strategy snapshot is invalid"
|
|
25669
|
-
);
|
|
25670
|
-
}
|
|
25671
|
-
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
25672
|
-
throw new Error(
|
|
25673
|
-
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
25674
|
-
);
|
|
25675
|
-
}
|
|
25676
|
-
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
25677
|
-
throw new Error(
|
|
25678
|
-
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
25679
|
-
);
|
|
25680
|
-
}
|
|
25681
|
-
return candidate;
|
|
25682
|
-
});
|
|
25683
|
-
const identities = /* @__PURE__ */ new Set();
|
|
25684
|
-
for (const strategy of strategies) {
|
|
25685
|
-
if (identities.has(strategy.strategyName)) {
|
|
25686
|
-
throw new Error(
|
|
25687
|
-
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
25688
|
-
);
|
|
25689
|
-
}
|
|
25690
|
-
identities.add(strategy.strategyName);
|
|
25691
|
-
}
|
|
25692
|
-
return {
|
|
25693
|
-
...value,
|
|
25694
|
-
strategies
|
|
25695
|
-
};
|
|
25696
|
-
};
|
|
25697
|
-
activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
25698
|
-
resolveRuntimeEvidenceTickerUniverse = ({
|
|
25699
|
-
deployment,
|
|
25700
|
-
lineageScopes
|
|
25701
|
-
}) => {
|
|
25702
|
-
const declaredTickers = deployment.tickers?.filter(isNonEmptyString) ?? [];
|
|
25703
|
-
if (declaredTickers.length > 0) {
|
|
25704
|
-
return {
|
|
25705
|
-
...deployment,
|
|
25706
|
-
tickers: [
|
|
25707
|
-
...new Set(declaredTickers.map((ticker) => ticker.trim()))
|
|
25708
|
-
].sort()
|
|
25709
|
-
};
|
|
25710
|
-
}
|
|
25711
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
25712
|
-
if (activeStrategies.length > 0 && activeStrategies.every((strategy) => strategy.selection?.tickers?.length)) {
|
|
25713
|
-
return {
|
|
25714
|
-
...deployment,
|
|
25715
|
-
tickers: [
|
|
25716
|
-
...new Set(
|
|
25717
|
-
activeStrategies.flatMap(
|
|
25718
|
-
(strategy) => strategy.selection?.tickers ?? []
|
|
25719
|
-
)
|
|
25720
|
-
)
|
|
25721
|
-
].sort()
|
|
25722
|
-
};
|
|
25723
|
-
}
|
|
25724
|
-
const strategiesByName = new Map(
|
|
25725
|
-
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
25726
|
-
);
|
|
25727
|
-
const tickers = /* @__PURE__ */ new Set();
|
|
25728
|
-
for (const scope of lineageScopes) {
|
|
25729
|
-
const strategy = strategiesByName.get(scope.strategy);
|
|
25730
|
-
if (!strategy || scope.deploymentId !== deployment.id || scope.accountId !== deployment.accountId || !isNonEmptyString(scope.symbol) || !lineageMatchesStrategySnapshot({
|
|
25731
|
-
lineage: scope.lineage,
|
|
25732
|
-
deployment,
|
|
25733
|
-
strategy
|
|
25734
|
-
})) {
|
|
25735
|
-
continue;
|
|
25736
|
-
}
|
|
25737
|
-
tickers.add(scope.symbol.trim());
|
|
25738
|
-
}
|
|
25739
|
-
if (tickers.size === 0) {
|
|
25740
|
-
throw new Error(
|
|
25741
|
-
"Runtime evidence has no immutable ticker universe for the embedded deployment composition"
|
|
25742
|
-
);
|
|
25743
|
-
}
|
|
25744
|
-
return { ...deployment, tickers: [...tickers].sort() };
|
|
25745
|
-
};
|
|
25746
|
-
runtimeDeploymentFromEvidence = (deployment) => ({
|
|
25747
|
-
id: deployment.id,
|
|
25748
|
-
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
25749
|
-
label: deployment.label,
|
|
25750
|
-
connectorName: deployment.connectorName,
|
|
25751
|
-
provider: deployment.provider,
|
|
25752
|
-
accountId: deployment.accountId,
|
|
25753
|
-
enabled: deployment.enabled,
|
|
25754
|
-
strategies: deployment.strategies.map(
|
|
25755
|
-
({ strategyName, strategyRevision, enabled, controlState, selection }) => ({
|
|
25756
|
-
strategyName,
|
|
25757
|
-
strategyRevision,
|
|
25758
|
-
enabled,
|
|
25759
|
-
controlState,
|
|
25760
|
-
...selection ? { selection } : {}
|
|
25761
|
-
})
|
|
25762
|
-
),
|
|
25763
|
-
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
25764
|
-
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
25765
|
-
});
|
|
25766
|
-
resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
25767
|
-
userName: userName3,
|
|
25768
|
-
projectRoot: projectRoot15,
|
|
25769
|
-
deploymentId
|
|
25770
|
-
}) => {
|
|
25771
|
-
const [deployment, strategies] = await Promise.all([
|
|
25772
|
-
(0, import_runtimeStrategies3.getRuntimeDeployment)({ userName: userName3, projectRoot: projectRoot15, deploymentId }),
|
|
25773
|
-
(0, import_runtimeStrategies3.loadResolvedRuntimeStrategies)({ userName: userName3, projectRoot: projectRoot15, deploymentId })
|
|
25774
|
-
]);
|
|
25775
|
-
if (!deployment) {
|
|
25776
|
-
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
25777
|
-
}
|
|
25778
|
-
return {
|
|
25779
|
-
schemaVersion: 2,
|
|
25780
|
-
id: deployment.id,
|
|
25781
|
-
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
25782
|
-
label: deployment.label,
|
|
25783
|
-
connectorName: deployment.connectorName,
|
|
25784
|
-
provider: deployment.provider,
|
|
25785
|
-
accountId: deployment.accountId,
|
|
25786
|
-
enabled: deployment.enabled,
|
|
25787
|
-
strategies: strategies.map(
|
|
25788
|
-
({
|
|
25789
|
-
strategyName,
|
|
25790
|
-
strategyRevision,
|
|
25791
|
-
enabled,
|
|
25792
|
-
controlState,
|
|
25793
|
-
interval: interval4,
|
|
25794
|
-
universe,
|
|
25795
|
-
accountId,
|
|
25796
|
-
strategyPackage,
|
|
25797
|
-
strategyPackageVersion,
|
|
25798
|
-
strategyDependencyVersions,
|
|
25799
|
-
runtimePackageVersion,
|
|
25800
|
-
strategyConfig,
|
|
25801
|
-
selection
|
|
25802
|
-
}) => ({
|
|
25803
|
-
strategyName,
|
|
25804
|
-
strategyRevision,
|
|
25805
|
-
enabled,
|
|
25806
|
-
controlState,
|
|
25807
|
-
interval: interval4,
|
|
25808
|
-
universe,
|
|
25809
|
-
...accountId ? { accountId } : {},
|
|
25810
|
-
strategyPackage,
|
|
25811
|
-
strategyPackageVersion,
|
|
25812
|
-
strategyDependencyVersions,
|
|
25813
|
-
runtimePackageVersion,
|
|
25814
|
-
strategyConfig,
|
|
25815
|
-
...selection ? { selection } : {}
|
|
25816
|
-
})
|
|
25817
|
-
),
|
|
25818
|
-
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
25819
|
-
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
25820
|
-
};
|
|
25821
|
-
};
|
|
25822
|
-
}
|
|
25823
|
-
});
|
|
25824
|
-
|
|
25825
25686
|
// src/scripts/runtimeEvidence.ts
|
|
25826
25687
|
var runtimeEvidence_exports = {};
|
|
25827
25688
|
__export(runtimeEvidence_exports, {
|
|
25828
25689
|
main: () => main34,
|
|
25829
25690
|
runtimeEvidence: () => runtimeEvidence
|
|
25830
25691
|
});
|
|
25831
|
-
var
|
|
25692
|
+
var import_promises23, import_node_path17, import_args26, import_chalk39, flags25, projectRoot9, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main34;
|
|
25832
25693
|
var init_runtimeEvidence = __esm({
|
|
25833
25694
|
"src/scripts/runtimeEvidence.ts"() {
|
|
25834
25695
|
"use strict";
|
|
25835
|
-
|
|
25836
|
-
|
|
25696
|
+
import_promises23 = __toESM(require("fs/promises"));
|
|
25697
|
+
import_node_path17 = __toESM(require("path"));
|
|
25837
25698
|
import_args26 = __toESM(require("args"));
|
|
25838
25699
|
import_chalk39 = __toESM(require("chalk"));
|
|
25839
25700
|
init_runtimeDebugEvidence();
|
|
@@ -25947,20 +25808,46 @@ var init_runtimeEvidence = __esm({
|
|
|
25947
25808
|
strategies,
|
|
25948
25809
|
deploymentId
|
|
25949
25810
|
});
|
|
25811
|
+
const activeSnapshots = new Map(
|
|
25812
|
+
activeRuntimeEvidenceStrategies(deploymentSnapshot).map((strategy) => [
|
|
25813
|
+
strategy.strategyName,
|
|
25814
|
+
strategy
|
|
25815
|
+
])
|
|
25816
|
+
);
|
|
25817
|
+
const belongsToCurrentDeployment = (row) => {
|
|
25818
|
+
const snapshot = activeSnapshots.get(row.strategy);
|
|
25819
|
+
return Boolean(
|
|
25820
|
+
snapshot && row.deploymentId === deploymentSnapshot.id && row.accountId === deploymentSnapshot.accountId && runtimeLineageMatchesStrategySnapshot({
|
|
25821
|
+
lineage: row.runtimeLineage,
|
|
25822
|
+
deployment: deploymentSnapshot,
|
|
25823
|
+
strategy: snapshot
|
|
25824
|
+
})
|
|
25825
|
+
);
|
|
25826
|
+
};
|
|
25827
|
+
const currentSignals = evidence.signals.filter(belongsToCurrentDeployment);
|
|
25828
|
+
const currentEvaluations = evidence.evaluations.filter(
|
|
25829
|
+
belongsToCurrentDeployment
|
|
25830
|
+
);
|
|
25831
|
+
const currentTrades = evidence.trades.filter(belongsToCurrentDeployment);
|
|
25832
|
+
const currentLineageScopes = evidence.lineageScopes.filter(
|
|
25833
|
+
(scope) => belongsToCurrentDeployment({
|
|
25834
|
+
...scope,
|
|
25835
|
+
runtimeLineage: scope.lineage
|
|
25836
|
+
})
|
|
25837
|
+
);
|
|
25950
25838
|
const runtime = buildRuntimeEvidenceReportPayload({
|
|
25951
25839
|
userName: flags25.user,
|
|
25952
25840
|
startTime,
|
|
25953
25841
|
endTime,
|
|
25954
|
-
signals:
|
|
25955
|
-
evaluations:
|
|
25956
|
-
trades:
|
|
25957
|
-
strategyConfigs: evidence.strategyConfigs,
|
|
25842
|
+
signals: currentSignals,
|
|
25843
|
+
evaluations: currentEvaluations,
|
|
25844
|
+
trades: currentTrades,
|
|
25958
25845
|
evaluationStatsBuckets: evidence.evaluationStatsBuckets,
|
|
25959
|
-
lineageScopes:
|
|
25846
|
+
lineageScopes: currentLineageScopes
|
|
25960
25847
|
});
|
|
25961
25848
|
const deployment = resolveRuntimeEvidenceTickerUniverse({
|
|
25962
25849
|
deployment: deploymentSnapshot,
|
|
25963
|
-
lineageScopes:
|
|
25850
|
+
lineageScopes: currentLineageScopes
|
|
25964
25851
|
});
|
|
25965
25852
|
const artifact = {
|
|
25966
25853
|
reportType: "runtime-evidence",
|
|
@@ -25977,13 +25864,13 @@ var init_runtimeEvidence = __esm({
|
|
|
25977
25864
|
deployment,
|
|
25978
25865
|
runtime
|
|
25979
25866
|
};
|
|
25980
|
-
const outPath =
|
|
25981
|
-
await
|
|
25982
|
-
await
|
|
25867
|
+
const outPath = import_node_path17.default.resolve(projectRoot9, String(flags25.out));
|
|
25868
|
+
await import_promises23.default.mkdir(import_node_path17.default.dirname(outPath), { recursive: true });
|
|
25869
|
+
await import_promises23.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
25983
25870
|
`, "utf8");
|
|
25984
25871
|
const publishDir = String(flags25.publishDir ?? "").trim();
|
|
25985
25872
|
const published = publishDir ? await publishRuntimeEvidenceBundle({
|
|
25986
|
-
publishRoot:
|
|
25873
|
+
publishRoot: import_node_path17.default.resolve(projectRoot9, publishDir),
|
|
25987
25874
|
deploymentId,
|
|
25988
25875
|
userName: String(flags25.user),
|
|
25989
25876
|
startTime,
|
|
@@ -25991,12 +25878,10 @@ var init_runtimeEvidence = __esm({
|
|
|
25991
25878
|
artifact,
|
|
25992
25879
|
counts: artifact.runtime.counts,
|
|
25993
25880
|
lineageKeys: [
|
|
25994
|
-
...
|
|
25995
|
-
...
|
|
25996
|
-
|
|
25997
|
-
)
|
|
25998
|
-
...evidence.trades.map((trade) => trade.runtimeLineage),
|
|
25999
|
-
...evidence.lineageScopes.map((scope) => scope.lineage)
|
|
25881
|
+
...currentSignals.map((signal) => signal.runtimeLineage),
|
|
25882
|
+
...currentEvaluations.map((evaluation) => evaluation.runtimeLineage),
|
|
25883
|
+
...currentTrades.map((trade) => trade.runtimeLineage),
|
|
25884
|
+
...currentLineageScopes.map((scope) => scope.lineage)
|
|
26000
25885
|
].filter((lineage) => lineage != null).map(runtimeLineageKey).filter((key, index, values) => values.indexOf(key) === index)
|
|
26001
25886
|
}) : null;
|
|
26002
25887
|
console.log(import_chalk39.default.green(`Wrote ${outPath}`));
|
|
@@ -26019,17 +25904,17 @@ var init_runtimeEvidence = __esm({
|
|
|
26019
25904
|
});
|
|
26020
25905
|
|
|
26021
25906
|
// src/lib/runtimeEvidenceSync.ts
|
|
26022
|
-
var
|
|
25907
|
+
var import_node_child_process6, import_promises24, import_node_path18, import_node_util, execFileAsync, isExistingDestinationError2, safeSegment2, withTrailingSlash, dateParts2, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
|
|
26023
25908
|
var init_runtimeEvidenceSync = __esm({
|
|
26024
25909
|
"src/lib/runtimeEvidenceSync.ts"() {
|
|
26025
25910
|
"use strict";
|
|
26026
|
-
|
|
26027
|
-
|
|
26028
|
-
|
|
25911
|
+
import_node_child_process6 = require("child_process");
|
|
25912
|
+
import_promises24 = __toESM(require("fs/promises"));
|
|
25913
|
+
import_node_path18 = __toESM(require("path"));
|
|
26029
25914
|
import_node_util = require("util");
|
|
26030
25915
|
init_runtimeEvidenceArtifacts();
|
|
26031
25916
|
init_runtimeEvidenceDeployment();
|
|
26032
|
-
execFileAsync = (0, import_node_util.promisify)(
|
|
25917
|
+
execFileAsync = (0, import_node_util.promisify)(import_node_child_process6.execFile);
|
|
26033
25918
|
isExistingDestinationError2 = (error) => {
|
|
26034
25919
|
const code = error.code;
|
|
26035
25920
|
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
@@ -26059,58 +25944,30 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26059
25944
|
withTrailingSlash(source),
|
|
26060
25945
|
withTrailingSlash(destination)
|
|
26061
25946
|
];
|
|
26062
|
-
receiptPath = (receiptsRoot, artifactId) =>
|
|
25947
|
+
receiptPath = (receiptsRoot, artifactId) => import_node_path18.default.join(receiptsRoot, `${safeSegment2(artifactId, "artifact")}.json`);
|
|
26063
25948
|
compareBundles = (left, right) => left.manifest.window.endTime - right.manifest.window.endTime || left.manifest.createdAt - right.manifest.createdAt;
|
|
26064
|
-
|
|
26065
|
-
try {
|
|
26066
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
26067
|
-
bundle.artifact.deployment
|
|
26068
|
-
);
|
|
26069
|
-
if (activeRuntimeEvidenceStrategies(deployment).length === 0) {
|
|
26070
|
-
throw new Error(
|
|
26071
|
-
"Runtime evidence deployment has no enabled active strategies"
|
|
26072
|
-
);
|
|
26073
|
-
}
|
|
26074
|
-
return { supported: true };
|
|
26075
|
-
} catch (error) {
|
|
26076
|
-
return {
|
|
26077
|
-
supported: false,
|
|
26078
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
26079
|
-
};
|
|
26080
|
-
}
|
|
26081
|
-
};
|
|
26082
|
-
listRuntimeEvidenceBundleStatuses = async ({
|
|
25949
|
+
listPendingRuntimeEvidenceBundles = async ({
|
|
26083
25950
|
evidenceRoot,
|
|
26084
25951
|
deploymentId
|
|
26085
25952
|
}) => {
|
|
26086
25953
|
const safeDeploymentId = safeSegment2(deploymentId, "production");
|
|
26087
|
-
const artifactsRoot =
|
|
26088
|
-
const receiptsRoot =
|
|
25954
|
+
const artifactsRoot = import_node_path18.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
25955
|
+
const receiptsRoot = import_node_path18.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
26089
25956
|
const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
|
|
26090
25957
|
const pending = [];
|
|
26091
|
-
const unsupported = [];
|
|
26092
25958
|
for (const bundleDir of bundles) {
|
|
26093
25959
|
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
26094
25960
|
if (verified.manifest.deploymentId !== safeDeploymentId) continue;
|
|
25961
|
+
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
26095
25962
|
try {
|
|
26096
|
-
await
|
|
25963
|
+
await import_promises24.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
|
|
26097
25964
|
continue;
|
|
26098
25965
|
} catch (error) {
|
|
26099
25966
|
if (error.code !== "ENOENT") throw error;
|
|
26100
25967
|
}
|
|
26101
|
-
|
|
26102
|
-
if (support.supported) {
|
|
26103
|
-
pending.push(verified);
|
|
26104
|
-
} else {
|
|
26105
|
-
unsupported.push({ bundle: verified, reason: support.reason });
|
|
26106
|
-
}
|
|
25968
|
+
pending.push(verified);
|
|
26107
25969
|
}
|
|
26108
|
-
return
|
|
26109
|
-
pending: pending.sort(compareBundles),
|
|
26110
|
-
unsupported: unsupported.sort(
|
|
26111
|
-
(left, right) => compareBundles(left.bundle, right.bundle)
|
|
26112
|
-
)
|
|
26113
|
-
};
|
|
25970
|
+
return pending.sort(compareBundles);
|
|
26114
25971
|
};
|
|
26115
25972
|
markRuntimeEvidenceBundleProcessed = async ({
|
|
26116
25973
|
evidenceRoot,
|
|
@@ -26125,7 +25982,7 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26125
25982
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
26126
25983
|
);
|
|
26127
25984
|
}
|
|
26128
|
-
const receiptsRoot =
|
|
25985
|
+
const receiptsRoot = import_node_path18.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
26129
25986
|
const finalPath = receiptPath(receiptsRoot, verified.manifest.artifactId);
|
|
26130
25987
|
const temporaryPath = `${finalPath}.tmp-${process.pid}`;
|
|
26131
25988
|
const receipt = {
|
|
@@ -26135,14 +25992,14 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26135
25992
|
processedAt: Date.now(),
|
|
26136
25993
|
scorecardPath: scorecardPath ?? null
|
|
26137
25994
|
};
|
|
26138
|
-
await
|
|
26139
|
-
await
|
|
25995
|
+
await import_promises24.default.mkdir(receiptsRoot, { recursive: true });
|
|
25996
|
+
await import_promises24.default.writeFile(
|
|
26140
25997
|
temporaryPath,
|
|
26141
25998
|
`${JSON.stringify(receipt, null, 2)}
|
|
26142
25999
|
`,
|
|
26143
26000
|
"utf8"
|
|
26144
26001
|
);
|
|
26145
|
-
await
|
|
26002
|
+
await import_promises24.default.rename(temporaryPath, finalPath);
|
|
26146
26003
|
return finalPath;
|
|
26147
26004
|
};
|
|
26148
26005
|
syncRuntimeEvidenceBundles = async ({
|
|
@@ -26157,11 +26014,11 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26157
26014
|
}
|
|
26158
26015
|
}) => {
|
|
26159
26016
|
const safeDeploymentId = safeSegment2(deploymentId, "production");
|
|
26160
|
-
const inboxRoot =
|
|
26161
|
-
const artifactsRoot =
|
|
26017
|
+
const inboxRoot = import_node_path18.default.join(evidenceRoot, "inbox", safeDeploymentId);
|
|
26018
|
+
const artifactsRoot = import_node_path18.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
26162
26019
|
await Promise.all([
|
|
26163
|
-
|
|
26164
|
-
|
|
26020
|
+
import_promises24.default.mkdir(inboxRoot, { recursive: true }),
|
|
26021
|
+
import_promises24.default.mkdir(artifactsRoot, { recursive: true })
|
|
26165
26022
|
]);
|
|
26166
26023
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
26167
26024
|
source,
|
|
@@ -26177,14 +26034,15 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26177
26034
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
26178
26035
|
);
|
|
26179
26036
|
}
|
|
26180
|
-
|
|
26037
|
+
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
26038
|
+
const destinationDir = import_node_path18.default.join(
|
|
26181
26039
|
artifactsRoot,
|
|
26182
26040
|
...dateParts2(verified.manifest.window.endTime),
|
|
26183
26041
|
safeSegment2(verified.manifest.artifactId, "artifact")
|
|
26184
26042
|
);
|
|
26185
|
-
await
|
|
26043
|
+
await import_promises24.default.mkdir(import_node_path18.default.dirname(destinationDir), { recursive: true });
|
|
26186
26044
|
try {
|
|
26187
|
-
await
|
|
26045
|
+
await import_promises24.default.rename(bundleDir, destinationDir);
|
|
26188
26046
|
} catch (error) {
|
|
26189
26047
|
if (!isExistingDestinationError2(error)) throw error;
|
|
26190
26048
|
const existing = await verifyRuntimeEvidenceBundle(destinationDir);
|
|
@@ -26193,11 +26051,11 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26193
26051
|
`Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
|
|
26194
26052
|
);
|
|
26195
26053
|
}
|
|
26196
|
-
await
|
|
26054
|
+
await import_promises24.default.rm(bundleDir, { recursive: true, force: true });
|
|
26197
26055
|
}
|
|
26198
26056
|
received.push(await verifyRuntimeEvidenceBundle(destinationDir));
|
|
26199
26057
|
}
|
|
26200
|
-
const
|
|
26058
|
+
const pending = await listPendingRuntimeEvidenceBundles({
|
|
26201
26059
|
evidenceRoot,
|
|
26202
26060
|
deploymentId: safeDeploymentId
|
|
26203
26061
|
});
|
|
@@ -26206,7 +26064,7 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
26206
26064
|
stdout: String(transfer.stdout ?? ""),
|
|
26207
26065
|
stderr: String(transfer.stderr ?? ""),
|
|
26208
26066
|
received,
|
|
26209
|
-
|
|
26067
|
+
pending
|
|
26210
26068
|
};
|
|
26211
26069
|
};
|
|
26212
26070
|
}
|
|
@@ -26218,11 +26076,11 @@ __export(runtimeEvidenceSync_exports, {
|
|
|
26218
26076
|
main: () => main35,
|
|
26219
26077
|
runtimeEvidenceSync: () => runtimeEvidenceSync
|
|
26220
26078
|
});
|
|
26221
|
-
var
|
|
26079
|
+
var import_node_path19, import_args27, import_chalk40, flags26, projectRoot10, runtimeEvidenceSync, main35;
|
|
26222
26080
|
var init_runtimeEvidenceSync2 = __esm({
|
|
26223
26081
|
"src/scripts/runtimeEvidenceSync.ts"() {
|
|
26224
26082
|
"use strict";
|
|
26225
|
-
|
|
26083
|
+
import_node_path19 = __toESM(require("path"));
|
|
26226
26084
|
import_args27 = __toESM(require("args"));
|
|
26227
26085
|
import_chalk40 = __toESM(require("chalk"));
|
|
26228
26086
|
init_runtimeEvidenceSync();
|
|
@@ -26250,7 +26108,7 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
26250
26108
|
"Provide --source or RUNTIME_EVIDENCE_RSYNC_SOURCE for runtime evidence sync."
|
|
26251
26109
|
);
|
|
26252
26110
|
}
|
|
26253
|
-
const evidenceRoot =
|
|
26111
|
+
const evidenceRoot = import_node_path19.default.resolve(projectRoot10, String(flags26.dir));
|
|
26254
26112
|
const result = await syncRuntimeEvidenceBundles({
|
|
26255
26113
|
source,
|
|
26256
26114
|
evidenceRoot,
|
|
@@ -26258,7 +26116,7 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
26258
26116
|
});
|
|
26259
26117
|
console.log(
|
|
26260
26118
|
import_chalk40.default.green(
|
|
26261
|
-
`Runtime evidence sync completed: received=${result.received.length} pending=${result.pending.length}
|
|
26119
|
+
`Runtime evidence sync completed: received=${result.received.length} pending=${result.pending.length}`
|
|
26262
26120
|
)
|
|
26263
26121
|
);
|
|
26264
26122
|
console.log(
|
|
@@ -26275,13 +26133,6 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
26275
26133
|
bundleDir: bundle.bundleDir,
|
|
26276
26134
|
payloadPath: bundle.payloadPath,
|
|
26277
26135
|
window: bundle.manifest.window
|
|
26278
|
-
})),
|
|
26279
|
-
unsupported: result.unsupported.map(({ bundle, reason }) => ({
|
|
26280
|
-
artifactId: bundle.manifest.artifactId,
|
|
26281
|
-
bundleDir: bundle.bundleDir,
|
|
26282
|
-
payloadPath: bundle.payloadPath,
|
|
26283
|
-
window: bundle.manifest.window,
|
|
26284
|
-
reason
|
|
26285
26136
|
}))
|
|
26286
26137
|
},
|
|
26287
26138
|
null,
|
|
@@ -26294,11 +26145,12 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
26294
26145
|
});
|
|
26295
26146
|
|
|
26296
26147
|
// src/lib/runtimeScorecard.ts
|
|
26297
|
-
var asRecord6, asArray3, finiteNumber5, finiteString2, packageVersionMap, round, unwrapRows, runtimePayload, runtimeWindow, extractRuntimeRows,
|
|
26148
|
+
var asRecord6, asArray3, finiteNumber5, finiteString2, packageVersionMap, round, unwrapRows, runtimePayload, runtimeWindow, extractRuntimeRows, buildEmbeddedLineageScope, runtimeDeploymentBinding, belongsToRuntimeDeployment, belongsToStrategy, filterArtifactByStrategy, countBy2, buildDistributions, buildDistributionDelta, sum2, statsCount, tradeTimestamp, dedupeTrades, maxDrawdown, buildRollingPerformance, getReplayComparison, replayCountsForStrategy, getProspectiveSummary, buildRuntimeScorecard, formatRuntimeScorecardMarkdown;
|
|
26298
26149
|
var init_runtimeScorecard = __esm({
|
|
26299
26150
|
"src/lib/runtimeScorecard.ts"() {
|
|
26300
26151
|
"use strict";
|
|
26301
26152
|
init_runtimeLineage();
|
|
26153
|
+
init_runtimeEvidenceDeployment();
|
|
26302
26154
|
asRecord6 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
26303
26155
|
asArray3 = (value) => Array.isArray(value) ? value : [];
|
|
26304
26156
|
finiteNumber5 = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
@@ -26336,75 +26188,6 @@ var init_runtimeScorecard = __esm({
|
|
|
26336
26188
|
statsBuckets: asArray3(runtime.evaluationStatsBuckets).map(asRecord6).filter((item) => item != null)
|
|
26337
26189
|
};
|
|
26338
26190
|
};
|
|
26339
|
-
buildRuntimeLineageSummary = (rows) => {
|
|
26340
|
-
const lineageRows = [
|
|
26341
|
-
...rows.evaluations,
|
|
26342
|
-
...rows.signals,
|
|
26343
|
-
...rows.trades,
|
|
26344
|
-
...rows.lineageScopes.map((scope) => ({
|
|
26345
|
-
runtimeLineage: scope.lineage
|
|
26346
|
-
}))
|
|
26347
|
-
];
|
|
26348
|
-
const lineages = lineageRows.map((row) => asRecord6(row.runtimeLineage)).filter((lineage) => lineage != null);
|
|
26349
|
-
const identities = /* @__PURE__ */ new Map();
|
|
26350
|
-
for (const lineage of lineages) {
|
|
26351
|
-
const identity2 = lineage.schemaVersion === 3 ? {
|
|
26352
|
-
schemaVersion: 3,
|
|
26353
|
-
strategyRevision: finiteString2(lineage.strategyRevision),
|
|
26354
|
-
deploymentCompositionId: finiteString2(
|
|
26355
|
-
lineage.deploymentCompositionId
|
|
26356
|
-
),
|
|
26357
|
-
strategyPackageVersion: finiteString2(
|
|
26358
|
-
lineage.strategyPackageVersion
|
|
26359
|
-
),
|
|
26360
|
-
strategyDependencyVersions: packageVersionMap(
|
|
26361
|
-
lineage.strategyDependencyVersions
|
|
26362
|
-
),
|
|
26363
|
-
runtimePackageVersion: finiteString2(lineage.runtimePackageVersion),
|
|
26364
|
-
maxLossValue: finiteNumber5(lineage.maxLossValue)
|
|
26365
|
-
} : {
|
|
26366
|
-
schemaVersion: 1,
|
|
26367
|
-
compositionId: finiteString2(lineage.compositionId),
|
|
26368
|
-
gitSha: finiteString2(lineage.gitSha),
|
|
26369
|
-
gitDirty: typeof lineage.gitDirty === "boolean" ? lineage.gitDirty : null,
|
|
26370
|
-
gateFingerprint: finiteString2(lineage.gateFingerprint),
|
|
26371
|
-
configFingerprint: finiteString2(lineage.configFingerprint),
|
|
26372
|
-
contextFingerprint: finiteString2(lineage.contextFingerprint),
|
|
26373
|
-
maxLossValue: finiteNumber5(lineage.maxLossValue)
|
|
26374
|
-
};
|
|
26375
|
-
identities.set(JSON.stringify(identity2), identity2);
|
|
26376
|
-
}
|
|
26377
|
-
const identity = identities.size === 1 ? [...identities.values()][0] : null;
|
|
26378
|
-
const schemaVersion = finiteNumber5(identity?.schemaVersion);
|
|
26379
|
-
const identityComplete = lineages.length > 0 && identity != null && (schemaVersion === 3 && finiteString2(identity.strategyRevision) != null && finiteString2(identity.deploymentCompositionId) != null && finiteString2(identity.strategyPackageVersion) != null && packageVersionMap(identity.strategyDependencyVersions) != null && finiteString2(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;
|
|
26380
|
-
const coverageComplete = lineageRows.length > 0 && lineages.length === lineageRows.length;
|
|
26381
|
-
const complete = identityComplete && coverageComplete;
|
|
26382
|
-
const lineageKey = identityComplete ? runtimeLineageKey(identity) : null;
|
|
26383
|
-
return {
|
|
26384
|
-
complete,
|
|
26385
|
-
identityComplete,
|
|
26386
|
-
coverageComplete,
|
|
26387
|
-
conflicts: identities.size > 1,
|
|
26388
|
-
rows: lineageRows.length,
|
|
26389
|
-
rowsWithLineage: lineages.length,
|
|
26390
|
-
schemaVersion,
|
|
26391
|
-
lineageKey,
|
|
26392
|
-
strategyRevision: finiteString2(identity?.strategyRevision),
|
|
26393
|
-
deploymentCompositionId: finiteString2(identity?.deploymentCompositionId),
|
|
26394
|
-
strategyPackageVersion: finiteString2(identity?.strategyPackageVersion),
|
|
26395
|
-
strategyDependencyVersions: packageVersionMap(
|
|
26396
|
-
identity?.strategyDependencyVersions
|
|
26397
|
-
),
|
|
26398
|
-
runtimePackageVersion: finiteString2(identity?.runtimePackageVersion),
|
|
26399
|
-
compositionId: finiteString2(identity?.compositionId),
|
|
26400
|
-
gitSha: finiteString2(identity?.gitSha),
|
|
26401
|
-
gitDirty: typeof identity?.gitDirty === "boolean" ? identity.gitDirty : null,
|
|
26402
|
-
gateFingerprint: finiteString2(identity?.gateFingerprint),
|
|
26403
|
-
configFingerprint: finiteString2(identity?.configFingerprint),
|
|
26404
|
-
contextFingerprint: finiteString2(identity?.contextFingerprint),
|
|
26405
|
-
maxLossValue: finiteNumber5(identity?.maxLossValue)
|
|
26406
|
-
};
|
|
26407
|
-
};
|
|
26408
26191
|
buildEmbeddedLineageScope = ({
|
|
26409
26192
|
artifact,
|
|
26410
26193
|
rows,
|
|
@@ -26516,12 +26299,6 @@ var init_runtimeScorecard = __esm({
|
|
|
26516
26299
|
strategyPackageVersion: singleTarget?.strategyPackageVersion ?? null,
|
|
26517
26300
|
strategyDependencyVersions: singleTarget?.strategyDependencyVersions ?? null,
|
|
26518
26301
|
runtimePackageVersion: singleTarget?.runtimePackageVersion ?? null,
|
|
26519
|
-
compositionId: null,
|
|
26520
|
-
gitSha: null,
|
|
26521
|
-
gitDirty: null,
|
|
26522
|
-
gateFingerprint: null,
|
|
26523
|
-
configFingerprint: null,
|
|
26524
|
-
contextFingerprint: null,
|
|
26525
26302
|
maxLossValue: commonRiskValues.size === 1 ? [...commonRiskValues][0] : null,
|
|
26526
26303
|
strategyScopes: Object.fromEntries(
|
|
26527
26304
|
targetValues.map((target) => [
|
|
@@ -26537,12 +26314,6 @@ var init_runtimeScorecard = __esm({
|
|
|
26537
26314
|
}
|
|
26538
26315
|
};
|
|
26539
26316
|
};
|
|
26540
|
-
belongsToRuntimeLineage = (row, summary) => {
|
|
26541
|
-
if (!summary.identityComplete || !summary.lineageKey) return false;
|
|
26542
|
-
const lineage = asRecord6(row.runtimeLineage);
|
|
26543
|
-
if (!lineage) return false;
|
|
26544
|
-
return runtimeLineageKey(lineage) === summary.lineageKey && finiteNumber5(lineage.maxLossValue) === summary.maxLossValue;
|
|
26545
|
-
};
|
|
26546
26317
|
runtimeDeploymentBinding = (artifact) => {
|
|
26547
26318
|
const deployment = asRecord6(asRecord6(artifact)?.deployment);
|
|
26548
26319
|
return {
|
|
@@ -26724,10 +26495,6 @@ var init_runtimeScorecard = __esm({
|
|
|
26724
26495
|
runtimeOnly: finiteNumber5(counts?.runtimeOnly) ?? 0
|
|
26725
26496
|
};
|
|
26726
26497
|
};
|
|
26727
|
-
getCalibrationSummary = (artifact) => {
|
|
26728
|
-
const root = asRecord6(artifact) ?? {};
|
|
26729
|
-
return asRecord6(asRecord6(root.summary)?.all) ?? null;
|
|
26730
|
-
};
|
|
26731
26498
|
getProspectiveSummary = (artifact) => {
|
|
26732
26499
|
const root = asRecord6(artifact);
|
|
26733
26500
|
if (!root || root.reportType !== "strategy-prospective-evidence") return null;
|
|
@@ -26753,6 +26520,10 @@ var init_runtimeScorecard = __esm({
|
|
|
26753
26520
|
strategy = null,
|
|
26754
26521
|
llmComparatorPolicy = "ai_approved_only"
|
|
26755
26522
|
}) => {
|
|
26523
|
+
assertCurrentRuntimeEvidenceArtifact(runtimeArtifact);
|
|
26524
|
+
for (const artifact of historyRuntimeArtifacts) {
|
|
26525
|
+
assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
26526
|
+
}
|
|
26756
26527
|
const scopedRuntimeArtifact = filterArtifactByStrategy(
|
|
26757
26528
|
runtimeArtifact,
|
|
26758
26529
|
strategy
|
|
@@ -26767,7 +26538,12 @@ var init_runtimeScorecard = __esm({
|
|
|
26767
26538
|
rows,
|
|
26768
26539
|
strategy
|
|
26769
26540
|
});
|
|
26770
|
-
|
|
26541
|
+
if (!embeddedLineageScope) {
|
|
26542
|
+
throw new Error(
|
|
26543
|
+
"Runtime scorecard requires the current embedded deployment lineage"
|
|
26544
|
+
);
|
|
26545
|
+
}
|
|
26546
|
+
const runtimeLineage = embeddedLineageScope.summary;
|
|
26771
26547
|
const window = runtimeWindow(runtimeArtifact);
|
|
26772
26548
|
const startTime = finiteNumber5(window.startTime) ?? generatedAt - 864e5;
|
|
26773
26549
|
const endTime = finiteNumber5(window.endTime) ?? generatedAt;
|
|
@@ -26815,32 +26591,26 @@ var init_runtimeScorecard = __esm({
|
|
|
26815
26591
|
const lineage = asRecord6(replayComparison?.lineage);
|
|
26816
26592
|
const lineageReason = finiteString2(lineage?.reason);
|
|
26817
26593
|
const calibrationRoot = asRecord6(calibrationArtifact) ?? {};
|
|
26818
|
-
const
|
|
26819
|
-
const calibrationSamples = asArray3(calibrationRoot.samples).map(asRecord6).filter((item) => item != null).filter((item) => !strategy || finiteString2(item.strategy) === strategy).filter(
|
|
26820
|
-
(item) => !embeddedLineageScope || embeddedLineageScope.belongs(item)
|
|
26821
|
-
);
|
|
26594
|
+
const calibrationSamples = asArray3(calibrationRoot.samples).map(asRecord6).filter((item) => item != null).filter((item) => !strategy || finiteString2(item.strategy) === strategy).filter((item) => embeddedLineageScope.belongs(item));
|
|
26822
26595
|
const averageSampleMetric = (field) => {
|
|
26823
26596
|
const values = calibrationSamples.map((sample) => finiteNumber5(sample[field])).filter((value) => value != null);
|
|
26824
26597
|
return values.length ? round(sum2(values) / values.length) : null;
|
|
26825
26598
|
};
|
|
26826
|
-
const
|
|
26827
|
-
const
|
|
26828
|
-
const residualVsModelBps = embeddedLineageScope ? averageSampleMetric("residualVsCurrentModelBps") : finiteNumber5(
|
|
26829
|
-
asRecord6(fallbackCalibration?.residualVsCurrentModelBps)?.avg
|
|
26830
|
-
);
|
|
26599
|
+
const actualSlippageBps = averageSampleMetric("signalToFillAdverseBps");
|
|
26600
|
+
const residualVsModelBps = averageSampleMetric("residualVsCurrentModelBps");
|
|
26831
26601
|
const prospective = getProspectiveSummary(prospectiveEvidenceArtifact);
|
|
26832
26602
|
const historyTrades = dedupeTrades([
|
|
26833
26603
|
...scopedHistoryArtifacts,
|
|
26834
26604
|
scopedRuntimeArtifact
|
|
26835
26605
|
]);
|
|
26836
26606
|
const comparableHistoryTrades = historyTrades.filter(
|
|
26837
|
-
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) &&
|
|
26607
|
+
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && embeddedLineageScope.belongs(trade)
|
|
26838
26608
|
);
|
|
26839
26609
|
const comparableCurrentClosedTrades = currentClosedTrades.filter(
|
|
26840
|
-
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) &&
|
|
26610
|
+
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && embeddedLineageScope.belongs(trade)
|
|
26841
26611
|
);
|
|
26842
26612
|
const comparableFills = rows.trades.filter(
|
|
26843
|
-
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) &&
|
|
26613
|
+
(trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && embeddedLineageScope.belongs(trade)
|
|
26844
26614
|
);
|
|
26845
26615
|
const currentDistributions = buildDistributions(rows);
|
|
26846
26616
|
const previousArtifact = scopedHistoryArtifacts.map((artifact) => ({ artifact, window: runtimeWindow(artifact) })).filter(({ window: candidateWindow }) => {
|
|
@@ -27094,11 +26864,11 @@ ${reactions}
|
|
|
27094
26864
|
});
|
|
27095
26865
|
|
|
27096
26866
|
// src/lib/strategyRelease/liveDiagnosis.ts
|
|
27097
|
-
var
|
|
26867
|
+
var import_types8, buildStrategyLiveDiagnosis, buildStrategyLiveDiagnosisFromScorecard;
|
|
27098
26868
|
var init_liveDiagnosis = __esm({
|
|
27099
26869
|
"src/lib/strategyRelease/liveDiagnosis.ts"() {
|
|
27100
26870
|
"use strict";
|
|
27101
|
-
|
|
26871
|
+
import_types8 = require("@tradejs/types");
|
|
27102
26872
|
buildStrategyLiveDiagnosis = (input) => {
|
|
27103
26873
|
const minimumClosedTrades = input.minimumClosedTrades ?? 20;
|
|
27104
26874
|
const minimumParityRatio = input.minimumParityRatio ?? 0.95;
|
|
@@ -27126,7 +26896,7 @@ var init_liveDiagnosis = __esm({
|
|
|
27126
26896
|
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."
|
|
27127
26897
|
];
|
|
27128
26898
|
return {
|
|
27129
|
-
schema:
|
|
26899
|
+
schema: import_types8.STRATEGY_LIVE_DIAGNOSIS_SCHEMA,
|
|
27130
26900
|
strategy: input.strategy,
|
|
27131
26901
|
compositionId: input.compositionId,
|
|
27132
26902
|
createdAt: input.createdAt,
|
|
@@ -27166,7 +26936,7 @@ var init_liveDiagnosis = __esm({
|
|
|
27166
26936
|
);
|
|
27167
26937
|
const orderFailureRate = scorecard.funnel.orderAttempts ? scorecard.funnel.orderFailures / scorecard.funnel.orderAttempts : null;
|
|
27168
26938
|
const lineage = scorecard.lineage;
|
|
27169
|
-
const lineageComparable = scorecard.parity.lineageReason == null && lineage?.complete === true && lineage.conflicts === false && lineage.
|
|
26939
|
+
const lineageComparable = scorecard.parity.lineageReason == null && lineage?.complete === true && lineage.conflicts === false && lineage.schemaVersion === 3 && lineage.strategyRevision != null && lineage.deploymentCompositionId != null && lineage.strategyPackageVersion != null && lineage.strategyDependencyVersions != null && lineage.runtimePackageVersion != null;
|
|
27170
26940
|
const releaseMaxLossValue = manifest.composition.maxLossValue;
|
|
27171
26941
|
const runtimeMaxLossValue = lineage?.maxLossValue ?? null;
|
|
27172
26942
|
const riskScaleComparable = Number.isFinite(releaseMaxLossValue) && releaseMaxLossValue > 0 && runtimeMaxLossValue != null && Number.isFinite(runtimeMaxLossValue) && runtimeMaxLossValue > 0;
|
|
@@ -27341,7 +27111,7 @@ function assert3(condition, message) {
|
|
|
27341
27111
|
async function collectReleaseEvidenceReferences(references) {
|
|
27342
27112
|
return Promise.all(
|
|
27343
27113
|
references.map(async (reference) => {
|
|
27344
|
-
const actualSha256 = await (0,
|
|
27114
|
+
const actualSha256 = await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(reference.path);
|
|
27345
27115
|
assert3(
|
|
27346
27116
|
actualSha256 === reference.sha256,
|
|
27347
27117
|
`evidence ${reference.artifactId} checksum mismatch`
|
|
@@ -27349,7 +27119,7 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
27349
27119
|
let artifact;
|
|
27350
27120
|
try {
|
|
27351
27121
|
const parsed = JSON.parse(
|
|
27352
|
-
await
|
|
27122
|
+
await import_promises25.default.readFile(reference.path, "utf8")
|
|
27353
27123
|
);
|
|
27354
27124
|
assert3(
|
|
27355
27125
|
parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
|
|
@@ -27496,15 +27266,15 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
27496
27266
|
})
|
|
27497
27267
|
);
|
|
27498
27268
|
}
|
|
27499
|
-
var import_node_crypto12,
|
|
27269
|
+
var import_node_crypto12, import_promises25, import_node_path20, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_STABLE_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, MIN_SELECTION_GRADE_TERMINAL_EVENTS, safeSegment3, compactTimestamp2, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber6, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
|
|
27500
27270
|
var init_strategyRelease = __esm({
|
|
27501
27271
|
"src/lib/strategyRelease.ts"() {
|
|
27502
27272
|
"use strict";
|
|
27503
27273
|
import_node_crypto12 = require("crypto");
|
|
27504
|
-
|
|
27505
|
-
|
|
27506
|
-
|
|
27507
|
-
|
|
27274
|
+
import_promises25 = __toESM(require("fs/promises"));
|
|
27275
|
+
import_node_path20 = __toESM(require("path"));
|
|
27276
|
+
import_types9 = require("@tradejs/types");
|
|
27277
|
+
import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
27508
27278
|
init_liveDiagnosis();
|
|
27509
27279
|
init_monitoringProfile();
|
|
27510
27280
|
init_evidenceRetention();
|
|
@@ -27516,17 +27286,17 @@ var init_strategyRelease = __esm({
|
|
|
27516
27286
|
REQUIRED_STABLE_TERMINAL_WINDOWS = [365, 180, 90];
|
|
27517
27287
|
MIN_RECENT_DIRECTION_REPAIR_EVENTS = 20;
|
|
27518
27288
|
MIN_SELECTION_GRADE_TERMINAL_EVENTS = 50;
|
|
27519
|
-
safeSegment3 =
|
|
27520
|
-
compactTimestamp2 =
|
|
27289
|
+
safeSegment3 = import_strategyReleaseEvidence2.safeStrategyEvidenceSegment;
|
|
27290
|
+
compactTimestamp2 = import_strategyReleaseEvidence2.compactStrategyEvidenceTimestamp;
|
|
27521
27291
|
verifyFullPeriodChartArtifact = async (input) => {
|
|
27522
27292
|
const artifact = input.chartArtifact;
|
|
27523
27293
|
if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return false;
|
|
27524
27294
|
try {
|
|
27525
|
-
const artifactPath =
|
|
27526
|
-
if (await (0,
|
|
27295
|
+
const artifactPath = import_node_path20.default.resolve(artifact.path);
|
|
27296
|
+
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
27527
27297
|
return false;
|
|
27528
27298
|
}
|
|
27529
|
-
const report = JSON.parse(await
|
|
27299
|
+
const report = JSON.parse(await import_promises25.default.readFile(artifactPath, "utf8"));
|
|
27530
27300
|
return Boolean(
|
|
27531
27301
|
report.chart?.persisted === true && report.chart.cardIds?.length && report.errors?.failed === 0 && report.run?.strategy === input.strategy && report.run.mode === "local-deterministic" && report.run.recent === 0 && report.run.since == null && report.run.until == null && Number(report.run.sourceRows) > 0
|
|
27532
27302
|
);
|
|
@@ -27537,11 +27307,11 @@ var init_strategyRelease = __esm({
|
|
|
27537
27307
|
readVerifiedJsonArtifact = async (artifact) => {
|
|
27538
27308
|
if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return null;
|
|
27539
27309
|
try {
|
|
27540
|
-
const artifactPath =
|
|
27541
|
-
if (await (0,
|
|
27310
|
+
const artifactPath = import_node_path20.default.resolve(artifact.path);
|
|
27311
|
+
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
27542
27312
|
return null;
|
|
27543
27313
|
}
|
|
27544
|
-
return JSON.parse(await
|
|
27314
|
+
return JSON.parse(await import_promises25.default.readFile(artifactPath, "utf8"));
|
|
27545
27315
|
} catch {
|
|
27546
27316
|
return null;
|
|
27547
27317
|
}
|
|
@@ -27694,8 +27464,8 @@ var init_strategyRelease = __esm({
|
|
|
27694
27464
|
summary: "Start the exact frozen composition as a micro-forward test at MAX_LOSS_VALUE=1; do not retune an underpowered or exposed recent tail."
|
|
27695
27465
|
};
|
|
27696
27466
|
};
|
|
27697
|
-
canonicalStrategyReleaseJson = (value) => (0,
|
|
27698
|
-
strategyReleaseSha256 = (value) => (0,
|
|
27467
|
+
canonicalStrategyReleaseJson = (value) => (0, import_strategyReleaseEvidence2.canonicalStrategyEvidenceJson)(value);
|
|
27468
|
+
strategyReleaseSha256 = (value) => (0, import_strategyReleaseEvidence2.strategyEvidenceSha256)(value);
|
|
27699
27469
|
assertFingerprint = (value, label) => assert3(SHA256_RE2.test(value), `${label} must be a lowercase SHA-256`);
|
|
27700
27470
|
assertLineageFingerprint = (value, label) => assert3(
|
|
27701
27471
|
LINEAGE_FINGERPRINT_RE.test(value),
|
|
@@ -28061,7 +27831,7 @@ var init_strategyRelease = __esm({
|
|
|
28061
27831
|
verdict
|
|
28062
27832
|
};
|
|
28063
27833
|
return {
|
|
28064
|
-
schema:
|
|
27834
|
+
schema: import_types9.STRATEGY_RELEASE_SCHEMA,
|
|
28065
27835
|
releaseId: `${safeSegment3(input.strategy, "strategy")}_${compactTimestamp2(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
|
|
28066
27836
|
strategy: input.strategy,
|
|
28067
27837
|
createdAt: input.createdAt,
|
|
@@ -28086,7 +27856,7 @@ var init_strategyRelease = __esm({
|
|
|
28086
27856
|
manifest
|
|
28087
27857
|
});
|
|
28088
27858
|
verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
28089
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
27859
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises25.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
28090
27860
|
const envelope = value;
|
|
28091
27861
|
assert3(
|
|
28092
27862
|
envelope?.schema === "tradejs-strategy-release-envelope/v1",
|
|
@@ -28102,7 +27872,7 @@ var init_strategyRelease = __esm({
|
|
|
28102
27872
|
);
|
|
28103
27873
|
const manifest = envelope.manifest;
|
|
28104
27874
|
assert3(
|
|
28105
|
-
manifest.schema ===
|
|
27875
|
+
manifest.schema === import_types9.STRATEGY_RELEASE_SCHEMA,
|
|
28106
27876
|
"manifest schema mismatch"
|
|
28107
27877
|
);
|
|
28108
27878
|
const rebuilt = createStrategyReleaseManifest({
|
|
@@ -28137,8 +27907,8 @@ var init_strategyRelease = __esm({
|
|
|
28137
27907
|
return envelope;
|
|
28138
27908
|
};
|
|
28139
27909
|
verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
|
|
28140
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
28141
|
-
return (0,
|
|
27910
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises25.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
27911
|
+
return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
|
|
28142
27912
|
};
|
|
28143
27913
|
releaseMarkers = (manifest) => {
|
|
28144
27914
|
const common = {
|
|
@@ -28199,21 +27969,21 @@ var init_strategyRelease = __esm({
|
|
|
28199
27969
|
};
|
|
28200
27970
|
writeJsonAtomic2 = async (filePath, value) => {
|
|
28201
27971
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
28202
|
-
await
|
|
28203
|
-
await
|
|
27972
|
+
await import_promises25.default.mkdir(import_node_path20.default.dirname(filePath), { recursive: true });
|
|
27973
|
+
await import_promises25.default.writeFile(
|
|
28204
27974
|
temporaryPath,
|
|
28205
27975
|
`${canonicalStrategyReleaseJson(value)}
|
|
28206
27976
|
`,
|
|
28207
27977
|
"utf8"
|
|
28208
27978
|
);
|
|
28209
|
-
await
|
|
27979
|
+
await import_promises25.default.rename(temporaryPath, filePath);
|
|
28210
27980
|
};
|
|
28211
27981
|
publishStrategyRelease = async ({
|
|
28212
27982
|
rootDir,
|
|
28213
27983
|
manifest
|
|
28214
27984
|
}) => {
|
|
28215
27985
|
const envelope = createStrategyReleaseEnvelope(manifest);
|
|
28216
|
-
const markerEnvelope = (0,
|
|
27986
|
+
const markerEnvelope = (0, import_strategyReleaseEvidence2.createStrategyEvidenceMarkerEnvelope)({
|
|
28217
27987
|
strategy: manifest.strategy,
|
|
28218
27988
|
createdAt: manifest.createdAt,
|
|
28219
27989
|
markers: releaseMarkers(manifest),
|
|
@@ -28223,13 +27993,13 @@ var init_strategyRelease = __esm({
|
|
|
28223
27993
|
path: entry.path
|
|
28224
27994
|
}))
|
|
28225
27995
|
});
|
|
28226
|
-
const releasePath =
|
|
27996
|
+
const releasePath = import_node_path20.default.join(
|
|
28227
27997
|
rootDir,
|
|
28228
27998
|
"releases",
|
|
28229
27999
|
safeSegment3(manifest.strategy, "strategy"),
|
|
28230
28000
|
`${manifest.releaseId}.json`
|
|
28231
28001
|
);
|
|
28232
|
-
const markerPath =
|
|
28002
|
+
const markerPath = import_node_path20.default.join(
|
|
28233
28003
|
rootDir,
|
|
28234
28004
|
"markers",
|
|
28235
28005
|
safeSegment3(manifest.strategy, "strategy"),
|
|
@@ -28303,19 +28073,19 @@ var init_strategyRelease = __esm({
|
|
|
28303
28073
|
severity: diagnosis.verdict === "EXPECTED_DRAWDOWN" ? "info" : "warning"
|
|
28304
28074
|
}
|
|
28305
28075
|
];
|
|
28306
|
-
const markerEnvelope = (0,
|
|
28076
|
+
const markerEnvelope = (0, import_strategyReleaseEvidence2.createStrategyEvidenceMarkerEnvelope)({
|
|
28307
28077
|
strategy: diagnosis.strategy,
|
|
28308
28078
|
createdAt: diagnosis.createdAt,
|
|
28309
28079
|
markers,
|
|
28310
28080
|
sourceArtifacts
|
|
28311
28081
|
});
|
|
28312
|
-
const diagnosisPath =
|
|
28082
|
+
const diagnosisPath = import_node_path20.default.join(
|
|
28313
28083
|
rootDir,
|
|
28314
28084
|
"diagnoses",
|
|
28315
28085
|
safeSegment3(diagnosis.strategy, "strategy"),
|
|
28316
28086
|
`${diagnosisId}.json`
|
|
28317
28087
|
);
|
|
28318
|
-
const markerPath =
|
|
28088
|
+
const markerPath = import_node_path20.default.join(
|
|
28319
28089
|
rootDir,
|
|
28320
28090
|
"markers",
|
|
28321
28091
|
safeSegment3(diagnosis.strategy, "strategy"),
|
|
@@ -28505,11 +28275,11 @@ var init_strategyRelease = __esm({
|
|
|
28505
28275
|
const specSha256 = finiteString3(artifact.specSha256);
|
|
28506
28276
|
assert3(researchId != null, "core result researchId is required");
|
|
28507
28277
|
assert3(specSha256 != null, "core result specSha256 is required");
|
|
28508
|
-
const researchDir =
|
|
28509
|
-
const manifestPath =
|
|
28510
|
-
const specPath =
|
|
28511
|
-
const manifestBytes = await
|
|
28512
|
-
const specBytes = await
|
|
28278
|
+
const researchDir = import_node_path20.default.dirname(resultPath);
|
|
28279
|
+
const manifestPath = import_node_path20.default.join(researchDir, "manifest.json");
|
|
28280
|
+
const specPath = import_node_path20.default.join(researchDir, "spec.json");
|
|
28281
|
+
const manifestBytes = await import_promises25.default.readFile(manifestPath).catch(() => null);
|
|
28282
|
+
const specBytes = await import_promises25.default.readFile(specPath).catch(() => null);
|
|
28513
28283
|
assert3(
|
|
28514
28284
|
manifestBytes != null && specBytes != null,
|
|
28515
28285
|
"core result must belong to a completed core research bundle"
|
|
@@ -28525,15 +28295,15 @@ var init_strategyRelease = __esm({
|
|
|
28525
28295
|
artifactHashes ?? {}
|
|
28526
28296
|
)) {
|
|
28527
28297
|
assert3(
|
|
28528
|
-
!
|
|
28298
|
+
!import_node_path20.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
|
|
28529
28299
|
`core bundle artifact ${relativePath} escapes its research directory`
|
|
28530
28300
|
);
|
|
28531
28301
|
assert3(
|
|
28532
28302
|
typeof expectedSha256 === "string" && SHA256_RE2.test(expectedSha256),
|
|
28533
28303
|
`core bundle artifact ${relativePath} has an invalid checksum`
|
|
28534
28304
|
);
|
|
28535
|
-
const actualSha256 = await (0,
|
|
28536
|
-
|
|
28305
|
+
const actualSha256 = await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(
|
|
28306
|
+
import_node_path20.default.join(researchDir, relativePath)
|
|
28537
28307
|
);
|
|
28538
28308
|
assert3(
|
|
28539
28309
|
actualSha256 === expectedSha256,
|
|
@@ -28550,13 +28320,13 @@ __export(runtimeScorecard_exports, {
|
|
|
28550
28320
|
main: () => main36,
|
|
28551
28321
|
runtimeScorecard: () => runtimeScorecard
|
|
28552
28322
|
});
|
|
28553
|
-
var
|
|
28323
|
+
var import_promises26, import_node_crypto13, import_node_path21, import_args28, import_chalk41, flags27, projectRoot11, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main36;
|
|
28554
28324
|
var init_runtimeScorecard2 = __esm({
|
|
28555
28325
|
"src/scripts/runtimeScorecard.ts"() {
|
|
28556
28326
|
"use strict";
|
|
28557
|
-
|
|
28327
|
+
import_promises26 = __toESM(require("fs/promises"));
|
|
28558
28328
|
import_node_crypto13 = require("crypto");
|
|
28559
|
-
|
|
28329
|
+
import_node_path21 = __toESM(require("path"));
|
|
28560
28330
|
import_args28 = __toESM(require("args"));
|
|
28561
28331
|
import_chalk41 = __toESM(require("chalk"));
|
|
28562
28332
|
init_runtimeEvidenceArtifacts();
|
|
@@ -28620,15 +28390,15 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28620
28390
|
projectRoot11 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
28621
28391
|
resolveOptionalPath = (value) => {
|
|
28622
28392
|
const raw = String(value ?? "").trim();
|
|
28623
|
-
return raw ?
|
|
28393
|
+
return raw ? import_node_path21.default.resolve(projectRoot11, raw) : null;
|
|
28624
28394
|
};
|
|
28625
|
-
readJson = async (filePath) => filePath ? JSON.parse(await
|
|
28395
|
+
readJson = async (filePath) => filePath ? JSON.parse(await import_promises26.default.readFile(filePath, "utf8")) : void 0;
|
|
28626
28396
|
assertReportType = (artifact, expected, label) => {
|
|
28627
28397
|
if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
|
|
28628
28398
|
throw new Error(`${label} must be a ${expected} artifact`);
|
|
28629
28399
|
}
|
|
28630
28400
|
};
|
|
28631
|
-
sha256File2 = async (filePath) => (0, import_node_crypto13.createHash)("sha256").update(await
|
|
28401
|
+
sha256File2 = async (filePath) => (0, import_node_crypto13.createHash)("sha256").update(await import_promises26.default.readFile(filePath)).digest("hex");
|
|
28632
28402
|
loadHistoryArtifacts = async (historyDir) => {
|
|
28633
28403
|
if (!historyDir) return [];
|
|
28634
28404
|
const bundleDirs = await discoverRuntimeEvidenceBundles(historyDir);
|
|
@@ -28698,13 +28468,13 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28698
28468
|
strategy: scorecardStrategy,
|
|
28699
28469
|
llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
|
|
28700
28470
|
});
|
|
28701
|
-
const outPath =
|
|
28471
|
+
const outPath = import_node_path21.default.resolve(projectRoot11, String(flags27.out));
|
|
28702
28472
|
const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
|
|
28703
|
-
await
|
|
28473
|
+
await import_promises26.default.mkdir(import_node_path21.default.dirname(outPath), { recursive: true });
|
|
28704
28474
|
await Promise.all([
|
|
28705
|
-
|
|
28475
|
+
import_promises26.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
|
|
28706
28476
|
`, "utf8"),
|
|
28707
|
-
|
|
28477
|
+
import_promises26.default.writeFile(
|
|
28708
28478
|
markdownPath,
|
|
28709
28479
|
formatRuntimeScorecardMarkdown(scorecard),
|
|
28710
28480
|
"utf8"
|
|
@@ -28718,7 +28488,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28718
28488
|
const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
|
|
28719
28489
|
const strategyReleaseRoot = resolveOptionalPath(flags27.strategyReleaseRoot);
|
|
28720
28490
|
if (diagnosis && diagnosisPath) {
|
|
28721
|
-
await
|
|
28491
|
+
await import_promises26.default.writeFile(
|
|
28722
28492
|
diagnosisPath,
|
|
28723
28493
|
`${JSON.stringify(diagnosis, null, 2)}
|
|
28724
28494
|
`,
|
|
@@ -28739,7 +28509,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28739
28509
|
composition: verifiedRelease?.manifest.composition,
|
|
28740
28510
|
sourceArtifacts: await Promise.all(
|
|
28741
28511
|
sourcePaths.map(async (sourcePath) => ({
|
|
28742
|
-
artifactId:
|
|
28512
|
+
artifactId: import_node_path21.default.basename(sourcePath),
|
|
28743
28513
|
path: sourcePath,
|
|
28744
28514
|
sha256: await sha256File2(sourcePath)
|
|
28745
28515
|
}))
|
|
@@ -28750,9 +28520,9 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28750
28520
|
let receiptPath2 = null;
|
|
28751
28521
|
if (flags27.markProcessed) {
|
|
28752
28522
|
receiptPath2 = await markRuntimeEvidenceBundleProcessed({
|
|
28753
|
-
evidenceRoot:
|
|
28523
|
+
evidenceRoot: import_node_path21.default.resolve(projectRoot11, String(flags27.evidenceDir)),
|
|
28754
28524
|
deploymentId: String(flags27.deployment),
|
|
28755
|
-
bundleDir:
|
|
28525
|
+
bundleDir: import_node_path21.default.dirname(runtimeEvidencePath),
|
|
28756
28526
|
scorecardPath: outPath
|
|
28757
28527
|
});
|
|
28758
28528
|
}
|
|
@@ -28945,14 +28715,14 @@ __export(strategyRelease_exports, {
|
|
|
28945
28715
|
main: () => main38,
|
|
28946
28716
|
runStrategyReleaseCommand: () => runStrategyReleaseCommand
|
|
28947
28717
|
});
|
|
28948
|
-
var
|
|
28718
|
+
var import_promises27, import_node_fs5, import_node_readline2, import_node_path22, import_chalk42, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main38;
|
|
28949
28719
|
var init_strategyRelease2 = __esm({
|
|
28950
28720
|
"src/scripts/strategyRelease.ts"() {
|
|
28951
28721
|
"use strict";
|
|
28952
|
-
|
|
28722
|
+
import_promises27 = __toESM(require("fs/promises"));
|
|
28953
28723
|
import_node_fs5 = require("fs");
|
|
28954
28724
|
import_node_readline2 = require("readline");
|
|
28955
|
-
|
|
28725
|
+
import_node_path22 = __toESM(require("path"));
|
|
28956
28726
|
import_chalk42 = __toESM(require("chalk"));
|
|
28957
28727
|
init_strategyRelease();
|
|
28958
28728
|
valueAfter2 = (argv2, name) => {
|
|
@@ -28965,17 +28735,17 @@ var init_strategyRelease2 = __esm({
|
|
|
28965
28735
|
};
|
|
28966
28736
|
writeJsonAtomic3 = async (filePath, value) => {
|
|
28967
28737
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
28968
|
-
await
|
|
28969
|
-
await
|
|
28738
|
+
await import_promises27.default.mkdir(import_node_path22.default.dirname(filePath), { recursive: true });
|
|
28739
|
+
await import_promises27.default.writeFile(
|
|
28970
28740
|
temporaryPath,
|
|
28971
28741
|
`${JSON.stringify(value, null, 2)}
|
|
28972
28742
|
`,
|
|
28973
28743
|
"utf8"
|
|
28974
28744
|
);
|
|
28975
|
-
await
|
|
28745
|
+
await import_promises27.default.rename(temporaryPath, filePath);
|
|
28976
28746
|
};
|
|
28977
28747
|
runStrategyReleaseCommand = async (options) => {
|
|
28978
|
-
const inputPath =
|
|
28748
|
+
const inputPath = import_node_path22.default.resolve(options.inputPath);
|
|
28979
28749
|
if (options.command === "verify") {
|
|
28980
28750
|
const envelope = await verifyStrategyReleaseEnvelope(inputPath);
|
|
28981
28751
|
return {
|
|
@@ -29013,7 +28783,7 @@ var init_strategyRelease2 = __esm({
|
|
|
29013
28783
|
endTime,
|
|
29014
28784
|
days: options.days?.length ? options.days : [7, 30, 90]
|
|
29015
28785
|
});
|
|
29016
|
-
const outputPath =
|
|
28786
|
+
const outputPath = import_node_path22.default.resolve(
|
|
29017
28787
|
options.outputPath ?? "output/strategy-monitoring-profile.json"
|
|
29018
28788
|
);
|
|
29019
28789
|
await writeJsonAtomic3(outputPath, profile);
|
|
@@ -29024,22 +28794,22 @@ var init_strategyRelease2 = __esm({
|
|
|
29024
28794
|
profile
|
|
29025
28795
|
};
|
|
29026
28796
|
}
|
|
29027
|
-
const input = JSON.parse(await
|
|
28797
|
+
const input = JSON.parse(await import_promises27.default.readFile(inputPath, "utf8"));
|
|
29028
28798
|
if (options.command === "decide") {
|
|
29029
28799
|
const decision = await deriveStrategyReleaseResearchDecision(input);
|
|
29030
28800
|
if (options.outputPath) {
|
|
29031
|
-
await writeJsonAtomic3(
|
|
28801
|
+
await writeJsonAtomic3(import_node_path22.default.resolve(options.outputPath), decision);
|
|
29032
28802
|
}
|
|
29033
28803
|
return {
|
|
29034
28804
|
kind: "decided",
|
|
29035
28805
|
...decision,
|
|
29036
|
-
outputPath: options.outputPath ?
|
|
28806
|
+
outputPath: options.outputPath ? import_node_path22.default.resolve(options.outputPath) : null
|
|
29037
28807
|
};
|
|
29038
28808
|
}
|
|
29039
28809
|
if (options.command === "retention") {
|
|
29040
28810
|
const plan = planStrategyEvidenceRetention(input);
|
|
29041
28811
|
if (options.apply) {
|
|
29042
|
-
await Promise.all(plan.delete.map((entry) =>
|
|
28812
|
+
await Promise.all(plan.delete.map((entry) => import_promises27.default.rm(entry.path)));
|
|
29043
28813
|
}
|
|
29044
28814
|
return {
|
|
29045
28815
|
kind: "retention",
|
|
@@ -29052,12 +28822,12 @@ var init_strategyRelease2 = __esm({
|
|
|
29052
28822
|
}
|
|
29053
28823
|
if (options.command === "diagnose") {
|
|
29054
28824
|
const diagnosis = buildStrategyLiveDiagnosis(input);
|
|
29055
|
-
const outputPath =
|
|
28825
|
+
const outputPath = import_node_path22.default.resolve(
|
|
29056
28826
|
options.outputPath ?? "output/strategy-live-diagnosis.json"
|
|
29057
28827
|
);
|
|
29058
28828
|
await writeJsonAtomic3(outputPath, diagnosis);
|
|
29059
28829
|
const published2 = options.rootDir ? await publishStrategyLiveDiagnosis({
|
|
29060
|
-
rootDir:
|
|
28830
|
+
rootDir: import_node_path22.default.resolve(options.rootDir),
|
|
29061
28831
|
diagnosis,
|
|
29062
28832
|
sourceArtifacts: input.sourceArtifacts ?? []
|
|
29063
28833
|
}) : null;
|
|
@@ -29074,7 +28844,7 @@ var init_strategyRelease2 = __esm({
|
|
|
29074
28844
|
evidence: await collectReleaseEvidenceReferences(input.evidence ?? [])
|
|
29075
28845
|
});
|
|
29076
28846
|
const published = await publishStrategyRelease({
|
|
29077
|
-
rootDir:
|
|
28847
|
+
rootDir: import_node_path22.default.resolve(options.rootDir ?? "data/strategy-release"),
|
|
29078
28848
|
manifest
|
|
29079
28849
|
});
|
|
29080
28850
|
return {
|
|
@@ -29134,12 +28904,12 @@ __export(serverHealth_exports, {
|
|
|
29134
28904
|
main: () => main39,
|
|
29135
28905
|
resolveServerHealthThresholds: () => resolveServerHealthThresholds
|
|
29136
28906
|
});
|
|
29137
|
-
var import_config10,
|
|
28907
|
+
var import_config10, import_node_child_process7, import_node_os3, import_node_fs6, import_args29, import_redis16, DEFAULT_STATE, DEFAULT_THRESHOLDS, escapeHtml4, formatPctValue, formatLoadPerCore, formatGiB, formatDuration2, readDiskUsage, parseMeminfoBytes, readMemorySnapshot, runDiagnosticCommand, runDiagnosticCommands, collectServerHealthSnapshot, buildHumanSummaryLines, evaluateServerHealth, shouldRecover, buildAlertMessage, buildRecoveryMessage, buildServerHealthDiagnostics, getStateKey, toFiniteNumber3, resolveServerHealthThresholds, main39;
|
|
29138
28908
|
var init_serverHealth = __esm({
|
|
29139
28909
|
"src/scripts/serverHealth.ts"() {
|
|
29140
28910
|
"use strict";
|
|
29141
28911
|
import_config10 = require("dotenv/config");
|
|
29142
|
-
|
|
28912
|
+
import_node_child_process7 = require("child_process");
|
|
29143
28913
|
import_node_os3 = __toESM(require("os"));
|
|
29144
28914
|
import_node_fs6 = require("fs");
|
|
29145
28915
|
import_args29 = __toESM(require("args"));
|
|
@@ -29176,21 +28946,21 @@ var init_serverHealth = __esm({
|
|
|
29176
28946
|
}
|
|
29177
28947
|
return `${minutes}m`;
|
|
29178
28948
|
};
|
|
29179
|
-
readDiskUsage = (
|
|
28949
|
+
readDiskUsage = (path35) => {
|
|
29180
28950
|
try {
|
|
29181
|
-
const stats = (0, import_node_fs6.statfsSync)(
|
|
28951
|
+
const stats = (0, import_node_fs6.statfsSync)(path35);
|
|
29182
28952
|
const totalBlocks = Number(stats.blocks ?? 0);
|
|
29183
28953
|
const availableBlocks = Number(stats.bavail ?? 0);
|
|
29184
28954
|
if (totalBlocks <= 0) {
|
|
29185
|
-
return { path:
|
|
28955
|
+
return { path: path35, usedPct: null };
|
|
29186
28956
|
}
|
|
29187
28957
|
const usedPct = (totalBlocks - Math.max(0, availableBlocks)) / totalBlocks * 100;
|
|
29188
28958
|
return {
|
|
29189
|
-
path:
|
|
28959
|
+
path: path35,
|
|
29190
28960
|
usedPct: Number.isFinite(usedPct) ? usedPct : null
|
|
29191
28961
|
};
|
|
29192
28962
|
} catch {
|
|
29193
|
-
return { path:
|
|
28963
|
+
return { path: path35, usedPct: null };
|
|
29194
28964
|
}
|
|
29195
28965
|
};
|
|
29196
28966
|
parseMeminfoBytes = (value) => {
|
|
@@ -29255,7 +29025,7 @@ var init_serverHealth = __esm({
|
|
|
29255
29025
|
}
|
|
29256
29026
|
};
|
|
29257
29027
|
runDiagnosticCommand = (command, args35) => {
|
|
29258
|
-
const output = (0,
|
|
29028
|
+
const output = (0, import_node_child_process7.execFileSync)(command, args35, {
|
|
29259
29029
|
encoding: "utf8",
|
|
29260
29030
|
timeout: 5e3,
|
|
29261
29031
|
maxBuffer: 1024 * 1024,
|
|
@@ -32481,11 +32251,11 @@ var init_klineFeed = __esm({
|
|
|
32481
32251
|
});
|
|
32482
32252
|
|
|
32483
32253
|
// src/lib/signals/tickerEvaluator.ts
|
|
32484
|
-
var
|
|
32254
|
+
var import_strategies10, import_logger9, createSignalsTickerEvaluator;
|
|
32485
32255
|
var init_tickerEvaluator = __esm({
|
|
32486
32256
|
"src/lib/signals/tickerEvaluator.ts"() {
|
|
32487
32257
|
"use strict";
|
|
32488
|
-
|
|
32258
|
+
import_strategies10 = require("@tradejs/node/strategies");
|
|
32489
32259
|
import_logger9 = require("@tradejs/infra/logger");
|
|
32490
32260
|
init_windows();
|
|
32491
32261
|
init_runtimeLineage();
|
|
@@ -32496,7 +32266,6 @@ var init_tickerEvaluator = __esm({
|
|
|
32496
32266
|
createSignalsTickerEvaluator = ({
|
|
32497
32267
|
userName: userName3,
|
|
32498
32268
|
makeOrders,
|
|
32499
|
-
projectRoot: projectRoot15,
|
|
32500
32269
|
context
|
|
32501
32270
|
}) => async (symbol, instrument) => {
|
|
32502
32271
|
const {
|
|
@@ -32568,19 +32337,12 @@ var init_tickerEvaluator = __esm({
|
|
|
32568
32337
|
makeOrders
|
|
32569
32338
|
});
|
|
32570
32339
|
const runtimeLineage = await buildRuntimeLineage({
|
|
32571
|
-
projectRoot: projectRoot15,
|
|
32572
|
-
strategyName,
|
|
32573
32340
|
strategyRevision,
|
|
32574
32341
|
deploymentCompositionId,
|
|
32575
32342
|
strategyPackageVersion,
|
|
32576
32343
|
strategyDependencyVersions,
|
|
32577
32344
|
runtimePackageVersion,
|
|
32578
|
-
config: { strategyConfig }
|
|
32579
|
-
runContext: {
|
|
32580
|
-
connectorName: connectorName.toLowerCase(),
|
|
32581
|
-
interval: String(interval4),
|
|
32582
|
-
universe
|
|
32583
|
-
}
|
|
32345
|
+
config: { strategyConfig }
|
|
32584
32346
|
});
|
|
32585
32347
|
const lifecycleKey = buildSignalsStrategyLifecycleKey({
|
|
32586
32348
|
connectorName,
|
|
@@ -32706,7 +32468,7 @@ var init_tickerEvaluator = __esm({
|
|
|
32706
32468
|
if (signalRuntimeIdentity && !signal.signalId.endsWith(`:${signalRuntimeIdentity}`)) {
|
|
32707
32469
|
signal.signalId = `${signal.signalId}:${signalRuntimeIdentity}`;
|
|
32708
32470
|
}
|
|
32709
|
-
await (0,
|
|
32471
|
+
await (0, import_strategies10.enrichSignalWithBinanceMarketContext)({ signal, env: "CRON" });
|
|
32710
32472
|
if (signal.orderStatus === "skipped" && typeof signal.orderSkipReason === "string" && signal.orderSkipReason.trim()) {
|
|
32711
32473
|
recordStrategyReason(
|
|
32712
32474
|
strategyStats,
|
|
@@ -32839,7 +32601,7 @@ var init_configuredScopes = __esm({
|
|
|
32839
32601
|
});
|
|
32840
32602
|
|
|
32841
32603
|
// src/lib/signals/runner.ts
|
|
32842
|
-
var import_progress11, import_chalk45, import_connectors16, import_cli12, import_async5,
|
|
32604
|
+
var import_progress11, import_chalk45, import_connectors16, import_cli12, import_async5, import_strategies11, import_constants16, import_time8, import_logger10, import_runtimeHeartbeats, import_runtimeStrategies6, SLOW_SIGNALS_WARNING_MS, formatDuration3, resolvePositiveInteger2, resolveNonNegativeInteger, createSignalsRunner;
|
|
32843
32605
|
var init_runner = __esm({
|
|
32844
32606
|
"src/lib/signals/runner.ts"() {
|
|
32845
32607
|
"use strict";
|
|
@@ -32848,7 +32610,7 @@ var init_runner = __esm({
|
|
|
32848
32610
|
import_connectors16 = require("@tradejs/node/connectors");
|
|
32849
32611
|
import_cli12 = require("@tradejs/node/cli");
|
|
32850
32612
|
import_async5 = require("@tradejs/core/async");
|
|
32851
|
-
|
|
32613
|
+
import_strategies11 = require("@tradejs/core/strategies");
|
|
32852
32614
|
import_constants16 = require("@tradejs/core/constants");
|
|
32853
32615
|
import_time8 = require("@tradejs/core/time");
|
|
32854
32616
|
import_logger10 = require("@tradejs/infra/logger");
|
|
@@ -32906,7 +32668,7 @@ var init_runner = __esm({
|
|
|
32906
32668
|
const createDefaultSignalsLifecycle = (runtimeInterval = interval4) => createSignalsStrategyLifecycle({
|
|
32907
32669
|
intervalMs: Number(runtimeInterval) * 6e4,
|
|
32908
32670
|
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
32909
|
-
releaseState:
|
|
32671
|
+
releaseState: import_strategies11.releaseStrategyReplayCache
|
|
32910
32672
|
});
|
|
32911
32673
|
const timeOperation3 = (label, operation) => timeOperation(
|
|
32912
32674
|
label,
|
|
@@ -33258,7 +33020,6 @@ var init_runner = __esm({
|
|
|
33258
33020
|
const evaluateTicker = createSignalsTickerEvaluator({
|
|
33259
33021
|
userName: config2.userName,
|
|
33260
33022
|
makeOrders: config2.makeOrders,
|
|
33261
|
-
projectRoot: projectRoot15,
|
|
33262
33023
|
context: {
|
|
33263
33024
|
connectorName,
|
|
33264
33025
|
connector: marketConnector,
|
|
@@ -33312,7 +33073,7 @@ var init_runner = __esm({
|
|
|
33312
33073
|
new Map(
|
|
33313
33074
|
runtimeStrategies.map(({ strategyName, strategyConfig }) => [
|
|
33314
33075
|
strategyName,
|
|
33315
|
-
(0,
|
|
33076
|
+
(0, import_strategies11.mapAiRuntimeFromConfig)({
|
|
33316
33077
|
AI_ENABLED: strategyConfig.AI_ENABLED,
|
|
33317
33078
|
AI_MODE: strategyConfig.AI_MODE,
|
|
33318
33079
|
MIN_AI_QUALITY: strategyConfig.MIN_AI_QUALITY
|
|
@@ -33788,12 +33549,12 @@ var init_cliConfig2 = __esm({
|
|
|
33788
33549
|
});
|
|
33789
33550
|
|
|
33790
33551
|
// src/lib/replay/runtimeEvidenceSource.ts
|
|
33791
|
-
var
|
|
33552
|
+
var import_promises28, import_node_path23, asRecord7, asFiniteNumber, unwrapRows2, assertRuntimeRowsMatchDeployment, readRuntimeEvidenceArtifact, loadReplayRuntimeEvidenceMetadata, buildRuntimeEvidenceLineageScopes, loadReplayRuntimeEvidenceSource;
|
|
33792
33553
|
var init_runtimeEvidenceSource = __esm({
|
|
33793
33554
|
"src/lib/replay/runtimeEvidenceSource.ts"() {
|
|
33794
33555
|
"use strict";
|
|
33795
|
-
|
|
33796
|
-
|
|
33556
|
+
import_promises28 = __toESM(require("fs/promises"));
|
|
33557
|
+
import_node_path23 = __toESM(require("path"));
|
|
33797
33558
|
init_runtimeLineage();
|
|
33798
33559
|
init_runtimeEvidenceDeployment();
|
|
33799
33560
|
asRecord7 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -33824,14 +33585,15 @@ var init_runtimeEvidenceSource = __esm({
|
|
|
33824
33585
|
filePath,
|
|
33825
33586
|
projectRoot: projectRoot15
|
|
33826
33587
|
}) => {
|
|
33827
|
-
const resolvedPath =
|
|
33588
|
+
const resolvedPath = import_node_path23.default.resolve(projectRoot15, filePath);
|
|
33828
33589
|
const root = asRecord7(
|
|
33829
|
-
JSON.parse(await
|
|
33590
|
+
JSON.parse(await import_promises28.default.readFile(resolvedPath, "utf8"))
|
|
33830
33591
|
);
|
|
33831
33592
|
const runtime = asRecord7(root?.runtime) ?? root;
|
|
33832
33593
|
if (!root || !runtime) {
|
|
33833
33594
|
throw new Error(`Invalid runtime evidence JSON: ${resolvedPath}`);
|
|
33834
33595
|
}
|
|
33596
|
+
assertCurrentRuntimeEvidenceArtifact(root);
|
|
33835
33597
|
const rootWindow = asRecord7(root.window);
|
|
33836
33598
|
const runtimeWindow2 = asRecord7(runtime.window);
|
|
33837
33599
|
return {
|
|
@@ -34394,20 +34156,20 @@ var init_portfolioReplayConnector = __esm({
|
|
|
34394
34156
|
});
|
|
34395
34157
|
|
|
34396
34158
|
// src/lib/replay/historicalSignalsReplay.ts
|
|
34397
|
-
var import_chalk46, import_progress12, import_backtest4,
|
|
34159
|
+
var import_chalk46, import_progress12, import_backtest4, import_strategies12, import_time9, import_logger11, import_redis19, import_connectors17, import_cli13, import_strategies13, import_runtimeStrategies8, loadRuntimeStrategies, loadReferenceConnector, buildPreparedData, buildAfterSignalsContext, strategyIncludesSymbol, buildSymbolSharedReplayKey, runHistoricalSignalsReplay;
|
|
34398
34160
|
var init_historicalSignalsReplay = __esm({
|
|
34399
34161
|
"src/lib/replay/historicalSignalsReplay.ts"() {
|
|
34400
34162
|
"use strict";
|
|
34401
34163
|
import_chalk46 = __toESM(require("chalk"));
|
|
34402
34164
|
import_progress12 = __toESM(require("progress"));
|
|
34403
34165
|
import_backtest4 = require("@tradejs/core/backtest");
|
|
34404
|
-
|
|
34166
|
+
import_strategies12 = require("@tradejs/core/strategies");
|
|
34405
34167
|
import_time9 = require("@tradejs/core/time");
|
|
34406
34168
|
import_logger11 = require("@tradejs/infra/logger");
|
|
34407
34169
|
import_redis19 = require("@tradejs/infra/redis");
|
|
34408
34170
|
import_connectors17 = require("@tradejs/node/connectors");
|
|
34409
34171
|
import_cli13 = require("@tradejs/node/cli");
|
|
34410
|
-
|
|
34172
|
+
import_strategies13 = require("@tradejs/node/strategies");
|
|
34411
34173
|
import_runtimeStrategies8 = require("@tradejs/node/runtimeStrategies");
|
|
34412
34174
|
init_cliConfig2();
|
|
34413
34175
|
init_support();
|
|
@@ -34429,7 +34191,7 @@ var init_historicalSignalsReplay = __esm({
|
|
|
34429
34191
|
strategyConfig,
|
|
34430
34192
|
selection
|
|
34431
34193
|
} = runtimeStrategy;
|
|
34432
|
-
const strategyCreator = await (0,
|
|
34194
|
+
const strategyCreator = await (0, import_strategies13.getStrategyCreator)(
|
|
34433
34195
|
strategyName,
|
|
34434
34196
|
replayProjectRoot
|
|
34435
34197
|
);
|
|
@@ -34668,8 +34430,6 @@ var init_historicalSignalsReplay = __esm({
|
|
|
34668
34430
|
strategyResults
|
|
34669
34431
|
}) => {
|
|
34670
34432
|
const runtimeLineage = await buildRuntimeLineage({
|
|
34671
|
-
projectRoot: replayProjectRoot,
|
|
34672
|
-
strategyName,
|
|
34673
34433
|
strategyRevision,
|
|
34674
34434
|
deploymentCompositionId,
|
|
34675
34435
|
strategyPackageVersion,
|
|
@@ -34679,11 +34439,6 @@ var init_historicalSignalsReplay = __esm({
|
|
|
34679
34439
|
configId: strategyRevision,
|
|
34680
34440
|
strategyConfig,
|
|
34681
34441
|
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
34682
|
-
},
|
|
34683
|
-
runContext: {
|
|
34684
|
-
connectorName: connectorName.toLowerCase(),
|
|
34685
|
-
interval: String(interval4),
|
|
34686
|
-
universe: preparedRun.universe ?? null
|
|
34687
34442
|
}
|
|
34688
34443
|
});
|
|
34689
34444
|
runtimeLineages.push({
|
|
@@ -34814,7 +34569,7 @@ var init_historicalSignalsReplay = __esm({
|
|
|
34814
34569
|
);
|
|
34815
34570
|
if (result && typeof result !== "string") {
|
|
34816
34571
|
result.runtimeLineage = strategyRuntime.runtimeLineage;
|
|
34817
|
-
await (0,
|
|
34572
|
+
await (0, import_strategies13.enrichSignalWithBinanceMarketContext)({
|
|
34818
34573
|
signal: result,
|
|
34819
34574
|
env: "PARITY"
|
|
34820
34575
|
});
|
|
@@ -34838,8 +34593,8 @@ var init_historicalSignalsReplay = __esm({
|
|
|
34838
34593
|
}
|
|
34839
34594
|
} finally {
|
|
34840
34595
|
for (const keyPrefix of sharedReplayKeyPrefixes) {
|
|
34841
|
-
(0,
|
|
34842
|
-
(0,
|
|
34596
|
+
(0, import_strategies12.releaseStrategyIndicatorsReplayCache)(keyPrefix);
|
|
34597
|
+
(0, import_strategies12.releaseStrategyReplayCache)(keyPrefix);
|
|
34843
34598
|
}
|
|
34844
34599
|
}
|
|
34845
34600
|
const artifacts = replayConnector.getReplayArtifacts();
|
|
@@ -37106,12 +36861,12 @@ var init_runtimeComparison = __esm({
|
|
|
37106
36861
|
});
|
|
37107
36862
|
|
|
37108
36863
|
// src/lib/replay/outputReport.ts
|
|
37109
|
-
var
|
|
36864
|
+
var import_promises29, import_node_path24, import_data4, formatMsk, formatNumber5, formatMoney2, formatPct, tableCell, createMarkdownTable2, entryStrategy, entryKey, buildDrilldownMap, buildPerTradeAnalysis, renderMatchedRows, renderRuntimeOnlyRows, renderOrderFailedRows, renderBacktestOnlyRows, renderStrategyRows, renderLineageRows, writeReplayOutputReport;
|
|
37110
36865
|
var init_outputReport = __esm({
|
|
37111
36866
|
"src/lib/replay/outputReport.ts"() {
|
|
37112
36867
|
"use strict";
|
|
37113
|
-
|
|
37114
|
-
|
|
36868
|
+
import_promises29 = __toESM(require("fs/promises"));
|
|
36869
|
+
import_node_path24 = __toESM(require("path"));
|
|
37115
36870
|
import_data4 = require("@tradejs/core/data");
|
|
37116
36871
|
init_support();
|
|
37117
36872
|
formatMsk = (timestamp) => typeof timestamp === "number" && Number.isFinite(timestamp) ? new Intl.DateTimeFormat("ru-RU", {
|
|
@@ -37351,33 +37106,20 @@ var init_outputReport = __esm({
|
|
|
37351
37106
|
const existing = grouped.get(record.strategy) ?? {
|
|
37352
37107
|
strategy: record.strategy,
|
|
37353
37108
|
scopes: 0,
|
|
37354
|
-
|
|
37355
|
-
|
|
37356
|
-
|
|
37357
|
-
|
|
37358
|
-
|
|
37109
|
+
deploymentCompositions: /* @__PURE__ */ new Set(),
|
|
37110
|
+
strategyRevisions: /* @__PURE__ */ new Set(),
|
|
37111
|
+
strategyPackages: /* @__PURE__ */ new Set(),
|
|
37112
|
+
dependencySets: /* @__PURE__ */ new Set(),
|
|
37113
|
+
runtimePackages: /* @__PURE__ */ new Set()
|
|
37359
37114
|
};
|
|
37360
37115
|
existing.scopes += 1;
|
|
37361
|
-
|
|
37362
|
-
|
|
37363
|
-
|
|
37364
|
-
|
|
37365
|
-
|
|
37366
|
-
|
|
37367
|
-
|
|
37368
|
-
record.lineage.strategyPackageVersion,
|
|
37369
|
-
record.lineage.runtimePackageVersion
|
|
37370
|
-
].join("/")
|
|
37371
|
-
);
|
|
37372
|
-
} else {
|
|
37373
|
-
existing.gitShas.add(record.lineage.gitSha ?? "unknown");
|
|
37374
|
-
existing.dirty.add(
|
|
37375
|
-
record.lineage.gitDirty == null ? "unknown" : String(record.lineage.gitDirty)
|
|
37376
|
-
);
|
|
37377
|
-
existing.gates.add(record.lineage.gateFingerprint);
|
|
37378
|
-
existing.configs.add(record.lineage.configFingerprint);
|
|
37379
|
-
existing.contexts.add(record.lineage.contextFingerprint);
|
|
37380
|
-
}
|
|
37116
|
+
existing.deploymentCompositions.add(record.lineage.deploymentCompositionId);
|
|
37117
|
+
existing.strategyRevisions.add(record.lineage.strategyRevision);
|
|
37118
|
+
existing.strategyPackages.add(record.lineage.strategyPackageVersion);
|
|
37119
|
+
existing.dependencySets.add(
|
|
37120
|
+
Object.entries(record.lineage.strategyDependencyVersions).sort(([left], [right]) => left.localeCompare(right)).map(([name, version]) => `${name}@${version}`).join(", ")
|
|
37121
|
+
);
|
|
37122
|
+
existing.runtimePackages.add(record.lineage.runtimePackageVersion);
|
|
37381
37123
|
grouped.set(record.strategy, existing);
|
|
37382
37124
|
}
|
|
37383
37125
|
const formatSet = (values) => {
|
|
@@ -37388,29 +37130,29 @@ var init_outputReport = __esm({
|
|
|
37388
37130
|
[
|
|
37389
37131
|
"Strategy",
|
|
37390
37132
|
"Scopes",
|
|
37391
|
-
"
|
|
37392
|
-
"
|
|
37393
|
-
"
|
|
37394
|
-
"
|
|
37395
|
-
"
|
|
37133
|
+
"Deployment composition",
|
|
37134
|
+
"Strategy revision",
|
|
37135
|
+
"Strategy package",
|
|
37136
|
+
"Dependencies",
|
|
37137
|
+
"Runtime package"
|
|
37396
37138
|
],
|
|
37397
37139
|
[...grouped.values()].sort((left, right) => left.strategy.localeCompare(right.strategy)).map(
|
|
37398
37140
|
({
|
|
37399
37141
|
strategy,
|
|
37400
37142
|
scopes,
|
|
37401
|
-
|
|
37402
|
-
|
|
37403
|
-
|
|
37404
|
-
|
|
37405
|
-
|
|
37143
|
+
deploymentCompositions,
|
|
37144
|
+
strategyRevisions,
|
|
37145
|
+
strategyPackages,
|
|
37146
|
+
dependencySets,
|
|
37147
|
+
runtimePackages
|
|
37406
37148
|
}) => [
|
|
37407
37149
|
strategy,
|
|
37408
37150
|
scopes,
|
|
37409
|
-
formatSet(
|
|
37410
|
-
formatSet(
|
|
37411
|
-
formatSet(
|
|
37412
|
-
|
|
37413
|
-
formatSet(
|
|
37151
|
+
formatSet(deploymentCompositions),
|
|
37152
|
+
formatSet(strategyRevisions),
|
|
37153
|
+
formatSet(strategyPackages),
|
|
37154
|
+
formatSet(dependencySets),
|
|
37155
|
+
formatSet(runtimePackages)
|
|
37414
37156
|
]
|
|
37415
37157
|
)
|
|
37416
37158
|
) : "_No replay lineage records._";
|
|
@@ -37429,8 +37171,8 @@ var init_outputReport = __esm({
|
|
|
37429
37171
|
strategySnapshot,
|
|
37430
37172
|
runtimeComparison
|
|
37431
37173
|
}) => {
|
|
37432
|
-
const outputDir =
|
|
37433
|
-
await
|
|
37174
|
+
const outputDir = import_node_path24.default.resolve(projectRoot15, "data/replay/output");
|
|
37175
|
+
await import_promises29.default.mkdir(outputDir, { recursive: true });
|
|
37434
37176
|
const perTradeAnalysis = buildPerTradeAnalysis(runtimeComparison);
|
|
37435
37177
|
const report = {
|
|
37436
37178
|
reportType: "replay-output",
|
|
@@ -37465,8 +37207,8 @@ var init_outputReport = __esm({
|
|
|
37465
37207
|
runtimeComparison,
|
|
37466
37208
|
perTradeAnalysis
|
|
37467
37209
|
};
|
|
37468
|
-
const markdownPath =
|
|
37469
|
-
const jsonPath =
|
|
37210
|
+
const markdownPath = import_node_path24.default.join(outputDir, `${timestamp}-replay-report.md`);
|
|
37211
|
+
const jsonPath = import_node_path24.default.join(outputDir, `${timestamp}-replay-report.json`);
|
|
37470
37212
|
const lines = [
|
|
37471
37213
|
"# Replay Report",
|
|
37472
37214
|
"",
|
|
@@ -37532,8 +37274,8 @@ var init_outputReport = __esm({
|
|
|
37532
37274
|
""
|
|
37533
37275
|
];
|
|
37534
37276
|
await Promise.all([
|
|
37535
|
-
|
|
37536
|
-
|
|
37277
|
+
import_promises29.default.writeFile(markdownPath, lines.join("\n"), "utf8"),
|
|
37278
|
+
import_promises29.default.writeFile(jsonPath, `${(0, import_data4.toJson)(report, true)}
|
|
37537
37279
|
`, "utf8")
|
|
37538
37280
|
]);
|
|
37539
37281
|
return {
|