@tradejs/cli 3.1.29-beta.262 → 3.1.29-beta.264
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 +864 -1424
- package/dist/lib/runtimeEvidenceArtifacts.js +3 -416
- package/dist/lib/runtimeEvidenceCompositionSnapshots.js +42 -211
- package/dist/lib/runtimeEvidenceCompositions.js +33 -310
- package/dist/lib/runtimeEvidenceDeployment.js +3 -315
- package/dist/lib/runtimeEvidenceProducer.js +3 -77
- package/dist/lib/runtimeEvidenceSync.js +32 -299
- package/dist/lib/runtimeFeedbackArtifacts.js +3 -545
- package/dist/lib/runtimeFeedbackNotification.js +7 -195
- package/dist/lib/runtimeFeedbackReplay.js +26 -525
- package/dist/lib/runtimeFeedbackSync.js +26 -219
- package/dist/lib/runtimeScorecard.js +5 -163
- package/dist/scripts/backtest.js +6 -1
- package/dist/scripts/mcpWorker.js +273 -0
- package/dist/scripts/replay.js +14 -250
- package/dist/scripts/replayRunner.js +14 -250
- package/dist/scripts/runtimeEvidence.js +47 -597
- package/dist/scripts/runtimeEvidenceSync.js +29 -296
- package/dist/scripts/runtimeFeedbackNotify.js +10 -188
- package/dist/scripts/runtimeFeedbackReplay.js +29 -528
- package/dist/scripts/runtimeFeedbackSync.js +28 -221
- package/dist/scripts/runtimeScorecard.js +88 -503
- package/dist/scripts/signals.js +55 -224
- package/dist/scripts/signalsDaemon.js +55 -224
- package/package.json +7 -7
package/dist/cli.js
CHANGED
|
@@ -26,6 +26,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
26
26
|
}
|
|
27
27
|
return to;
|
|
28
28
|
};
|
|
29
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
29
30
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
31
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
32
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -2207,9 +2208,9 @@ var init_features = __esm({
|
|
|
2207
2208
|
"targetsymbol",
|
|
2208
2209
|
"universe"
|
|
2209
2210
|
]);
|
|
2210
|
-
normalizeFeaturePath = (
|
|
2211
|
-
classifyAiPocketCoverageFeaturePath = (
|
|
2212
|
-
const segments = normalizeFeaturePath(
|
|
2211
|
+
normalizeFeaturePath = (path44) => (Array.isArray(path44) ? path44 : path44.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
|
|
2212
|
+
classifyAiPocketCoverageFeaturePath = (path44) => {
|
|
2213
|
+
const segments = normalizeFeaturePath(path44);
|
|
2213
2214
|
const normalizedPath = segments.join(".");
|
|
2214
2215
|
if (segments.some(
|
|
2215
2216
|
(segment) => segment.includes("cmc") || segment.includes("coinmarketcap")
|
|
@@ -2383,8 +2384,8 @@ var init_features = __esm({
|
|
|
2383
2384
|
"volumeusd",
|
|
2384
2385
|
"vwap"
|
|
2385
2386
|
]);
|
|
2386
|
-
classifyAiPocketFeaturePath = (
|
|
2387
|
-
const segments = (Array.isArray(
|
|
2387
|
+
classifyAiPocketFeaturePath = (path44) => {
|
|
2388
|
+
const segments = (Array.isArray(path44) ? path44 : path44.split(".")).filter(
|
|
2388
2389
|
Boolean
|
|
2389
2390
|
);
|
|
2390
2391
|
const normalized = segments.map((segment) => segment.toLowerCase());
|
|
@@ -2701,11 +2702,11 @@ var init_features = __esm({
|
|
|
2701
2702
|
excludeFeaturePattern.source,
|
|
2702
2703
|
excludeFeaturePattern.flags.replace(/[gy]/g, "")
|
|
2703
2704
|
) : void 0;
|
|
2704
|
-
const isOperatorExcluded = (
|
|
2705
|
-
if (!exclusion?.test(
|
|
2705
|
+
const isOperatorExcluded = (path44) => {
|
|
2706
|
+
if (!exclusion?.test(path44)) {
|
|
2706
2707
|
return false;
|
|
2707
2708
|
}
|
|
2708
|
-
onFeatureExcluded?.({ path:
|
|
2709
|
+
onFeatureExcluded?.({ path: path44, classification: "operator-excluded" });
|
|
2709
2710
|
return true;
|
|
2710
2711
|
};
|
|
2711
2712
|
const signal = payload.signal ?? {};
|
|
@@ -11156,27 +11157,27 @@ var init_coinMarketCapContextBackfill = __esm({
|
|
|
11156
11157
|
totalCredits: 0,
|
|
11157
11158
|
byPath: /* @__PURE__ */ new Map()
|
|
11158
11159
|
});
|
|
11159
|
-
getCoinMarketCapPathLabel = (
|
|
11160
|
-
if (
|
|
11161
|
-
if (
|
|
11162
|
-
if (
|
|
11163
|
-
if (
|
|
11164
|
-
if (
|
|
11165
|
-
if (
|
|
11166
|
-
return
|
|
11167
|
-
};
|
|
11168
|
-
recordCoinMarketCapFetchStats = (stats,
|
|
11160
|
+
getCoinMarketCapPathLabel = (path44) => {
|
|
11161
|
+
if (path44.includes("global-metrics")) return "global";
|
|
11162
|
+
if (path44.includes("cryptocurrency/quotes")) return "reference";
|
|
11163
|
+
if (path44.includes("exchange/quotes")) return "exchangeLiquidity";
|
|
11164
|
+
if (path44.includes("fear-and-greed")) return "fearGreed";
|
|
11165
|
+
if (path44.includes("cmc100")) return "cmc100";
|
|
11166
|
+
if (path44.includes("cmc20")) return "cmc20";
|
|
11167
|
+
return path44;
|
|
11168
|
+
};
|
|
11169
|
+
recordCoinMarketCapFetchStats = (stats, path44, creditCount) => {
|
|
11169
11170
|
if (!stats) return;
|
|
11170
|
-
const existing = stats.byPath.get(
|
|
11171
|
+
const existing = stats.byPath.get(path44) ?? { requests: 0, credits: 0 };
|
|
11171
11172
|
existing.requests += 1;
|
|
11172
11173
|
existing.credits += creditCount ?? 0;
|
|
11173
11174
|
stats.requests += 1;
|
|
11174
11175
|
stats.totalCredits += creditCount ?? 0;
|
|
11175
|
-
stats.byPath.set(
|
|
11176
|
+
stats.byPath.set(path44, existing);
|
|
11176
11177
|
};
|
|
11177
11178
|
formatCoinMarketCapFetchStats = (stats) => {
|
|
11178
11179
|
const byPath = [...stats.byPath.entries()].map(
|
|
11179
|
-
([
|
|
11180
|
+
([path44, item]) => `${getCoinMarketCapPathLabel(path44)}=${item.requests}req/${item.credits}cr`
|
|
11180
11181
|
).join(" ");
|
|
11181
11182
|
return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
|
|
11182
11183
|
};
|
|
@@ -13563,6 +13564,11 @@ var init_cliConfig = __esm({
|
|
|
13563
13564
|
"Skip per-test artifact persistence and keep only in-memory summary/AI-ML dataset output",
|
|
13564
13565
|
false
|
|
13565
13566
|
);
|
|
13567
|
+
import_args6.default.option(
|
|
13568
|
+
["Y", "persistResults"],
|
|
13569
|
+
"Persist lightweight result summaries even in fast mode",
|
|
13570
|
+
false
|
|
13571
|
+
);
|
|
13566
13572
|
import_args6.default.option(
|
|
13567
13573
|
"researchTrace",
|
|
13568
13574
|
"Write compact setup/entry/exit/skip research trace JSONL",
|
|
@@ -14806,7 +14812,7 @@ var init_backtest = __esm({
|
|
|
14806
14812
|
}
|
|
14807
14813
|
console.log(import_chalk15.default.gray(`full report: ${markdownReportPath}`));
|
|
14808
14814
|
console.log("");
|
|
14809
|
-
if (!isFastMode) {
|
|
14815
|
+
if (!isFastMode || flags5.persistResults) {
|
|
14810
14816
|
await (0, import_redis7.setData)(
|
|
14811
14817
|
import_redis7.redisKeys.backtestResults(userName, flags5.config, timestamp),
|
|
14812
14818
|
{
|
|
@@ -15235,305 +15241,11 @@ var init_runtimeLineage = __esm({
|
|
|
15235
15241
|
});
|
|
15236
15242
|
|
|
15237
15243
|
// src/lib/runtimeEvidenceDeployment.ts
|
|
15238
|
-
var
|
|
15244
|
+
var runtimeEvidenceDeployment_exports = {};
|
|
15239
15245
|
var init_runtimeEvidenceDeployment = __esm({
|
|
15240
15246
|
"src/lib/runtimeEvidenceDeployment.ts"() {
|
|
15241
15247
|
"use strict";
|
|
15242
|
-
|
|
15243
|
-
isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
15244
|
-
isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
15245
|
-
isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
15246
|
-
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
15247
|
-
);
|
|
15248
|
-
INTERVALS = /* @__PURE__ */ new Set([
|
|
15249
|
-
"1",
|
|
15250
|
-
"3",
|
|
15251
|
-
"5",
|
|
15252
|
-
"15",
|
|
15253
|
-
"30",
|
|
15254
|
-
"60",
|
|
15255
|
-
"120",
|
|
15256
|
-
"240",
|
|
15257
|
-
"360",
|
|
15258
|
-
"720",
|
|
15259
|
-
"D",
|
|
15260
|
-
"W",
|
|
15261
|
-
"M"
|
|
15262
|
-
]);
|
|
15263
|
-
UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
15264
|
-
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));
|
|
15265
|
-
samePackageVersions = (left, right) => {
|
|
15266
|
-
if (!left || !right) return false;
|
|
15267
|
-
const leftEntries = Object.entries(left).sort(
|
|
15268
|
-
([a], [b]) => a.localeCompare(b)
|
|
15269
|
-
);
|
|
15270
|
-
const rightEntries = Object.entries(right).sort(
|
|
15271
|
-
([a], [b]) => a.localeCompare(b)
|
|
15272
|
-
);
|
|
15273
|
-
return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
|
|
15274
|
-
};
|
|
15275
|
-
runtimeLineageMatchesStrategySnapshot = ({
|
|
15276
|
-
lineage,
|
|
15277
|
-
deployment,
|
|
15278
|
-
strategy
|
|
15279
|
-
}) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
|
|
15280
|
-
lineage.strategyDependencyVersions,
|
|
15281
|
-
strategy.strategyDependencyVersions
|
|
15282
|
-
);
|
|
15283
|
-
parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
15284
|
-
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)) {
|
|
15285
|
-
throw new Error(
|
|
15286
|
-
"Runtime evidence deployment snapshot is missing or invalid"
|
|
15287
|
-
);
|
|
15288
|
-
}
|
|
15289
|
-
const strategies = value.strategies.map((candidate) => {
|
|
15290
|
-
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)) {
|
|
15291
|
-
throw new Error(
|
|
15292
|
-
"Runtime evidence deployment strategy snapshot is invalid"
|
|
15293
|
-
);
|
|
15294
|
-
}
|
|
15295
|
-
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
15296
|
-
throw new Error(
|
|
15297
|
-
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
15298
|
-
);
|
|
15299
|
-
}
|
|
15300
|
-
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
15301
|
-
throw new Error(
|
|
15302
|
-
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
15303
|
-
);
|
|
15304
|
-
}
|
|
15305
|
-
return candidate;
|
|
15306
|
-
});
|
|
15307
|
-
const identities = /* @__PURE__ */ new Set();
|
|
15308
|
-
for (const strategy of strategies) {
|
|
15309
|
-
if (identities.has(strategy.strategyName)) {
|
|
15310
|
-
throw new Error(
|
|
15311
|
-
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
15312
|
-
);
|
|
15313
|
-
}
|
|
15314
|
-
identities.add(strategy.strategyName);
|
|
15315
|
-
}
|
|
15316
|
-
return {
|
|
15317
|
-
...value,
|
|
15318
|
-
strategies
|
|
15319
|
-
};
|
|
15320
|
-
};
|
|
15321
|
-
activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
15322
|
-
unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
15323
|
-
const record = isRecord(candidate) ? candidate : null;
|
|
15324
|
-
const nested = record && isRecord(record[field]) ? record[field] : null;
|
|
15325
|
-
return nested ?? record;
|
|
15326
|
-
}).filter((record) => record != null);
|
|
15327
|
-
assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
15328
|
-
if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
15329
|
-
throw new Error("Invalid runtime evidence artifact");
|
|
15330
|
-
}
|
|
15331
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
15332
|
-
artifact.deployment
|
|
15333
|
-
);
|
|
15334
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
15335
|
-
if (activeStrategies.length === 0) {
|
|
15336
|
-
throw new Error("Runtime evidence deployment has no enabled strategies");
|
|
15337
|
-
}
|
|
15338
|
-
const runtime = isRecord(artifact.runtime) ? artifact.runtime : null;
|
|
15339
|
-
if (!runtime) {
|
|
15340
|
-
throw new Error("Runtime evidence payload is missing");
|
|
15341
|
-
}
|
|
15342
|
-
if ("strategyConfigs" in runtime) {
|
|
15343
|
-
throw new Error(
|
|
15344
|
-
"Runtime evidence payload contains removed strategyConfigs data"
|
|
15345
|
-
);
|
|
15346
|
-
}
|
|
15347
|
-
if ("evaluationStatsBuckets" in runtime) {
|
|
15348
|
-
throw new Error(
|
|
15349
|
-
"Runtime evidence payload contains removed lineage-less evaluationStatsBuckets data"
|
|
15350
|
-
);
|
|
15351
|
-
}
|
|
15352
|
-
const rowFields = [
|
|
15353
|
-
"trades",
|
|
15354
|
-
"signals",
|
|
15355
|
-
"evaluations",
|
|
15356
|
-
"lineageScopes"
|
|
15357
|
-
];
|
|
15358
|
-
for (const field of rowFields) {
|
|
15359
|
-
if (!Array.isArray(runtime[field])) {
|
|
15360
|
-
throw new Error(`Runtime evidence payload ${field} must be an array`);
|
|
15361
|
-
}
|
|
15362
|
-
}
|
|
15363
|
-
const snapshots = new Map(
|
|
15364
|
-
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
15365
|
-
);
|
|
15366
|
-
const assertRows = (label, rows, lineageField) => {
|
|
15367
|
-
for (const row of rows) {
|
|
15368
|
-
const strategyName = String(row.strategy ?? "").trim();
|
|
15369
|
-
const strategy = snapshots.get(strategyName);
|
|
15370
|
-
if (!strategy || row.deploymentId !== deployment.id || row.accountId !== deployment.accountId || !runtimeLineageMatchesStrategySnapshot({
|
|
15371
|
-
lineage: isRecord(row[lineageField]) ? row[lineageField] : void 0,
|
|
15372
|
-
deployment,
|
|
15373
|
-
strategy
|
|
15374
|
-
})) {
|
|
15375
|
-
throw new Error(
|
|
15376
|
-
`Runtime evidence ${label} row is outside the current embedded deployment lineage`
|
|
15377
|
-
);
|
|
15378
|
-
}
|
|
15379
|
-
}
|
|
15380
|
-
};
|
|
15381
|
-
assertRows(
|
|
15382
|
-
"trade",
|
|
15383
|
-
unwrapRuntimeEvidenceRows(runtime.trades, "trade"),
|
|
15384
|
-
"runtimeLineage"
|
|
15385
|
-
);
|
|
15386
|
-
assertRows(
|
|
15387
|
-
"signal",
|
|
15388
|
-
unwrapRuntimeEvidenceRows(runtime.signals, "signal"),
|
|
15389
|
-
"runtimeLineage"
|
|
15390
|
-
);
|
|
15391
|
-
assertRows(
|
|
15392
|
-
"evaluation",
|
|
15393
|
-
unwrapRuntimeEvidenceRows(runtime.evaluations, "evaluation"),
|
|
15394
|
-
"runtimeLineage"
|
|
15395
|
-
);
|
|
15396
|
-
assertRows(
|
|
15397
|
-
"lineage scope",
|
|
15398
|
-
unwrapRuntimeEvidenceRows(runtime.lineageScopes, "lineageScope"),
|
|
15399
|
-
"lineage"
|
|
15400
|
-
);
|
|
15401
|
-
return deployment;
|
|
15402
|
-
};
|
|
15403
|
-
resolveRuntimeEvidenceTickerUniverse = ({
|
|
15404
|
-
deployment,
|
|
15405
|
-
lineageScopes,
|
|
15406
|
-
fallbackTickers
|
|
15407
|
-
}) => {
|
|
15408
|
-
const declaredTickers = deployment.tickers?.filter(isNonEmptyString) ?? [];
|
|
15409
|
-
if (declaredTickers.length > 0) {
|
|
15410
|
-
return {
|
|
15411
|
-
...deployment,
|
|
15412
|
-
tickers: [
|
|
15413
|
-
...new Set(declaredTickers.map((ticker) => ticker.trim()))
|
|
15414
|
-
].sort()
|
|
15415
|
-
};
|
|
15416
|
-
}
|
|
15417
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
15418
|
-
if (activeStrategies.length > 0 && activeStrategies.every((strategy) => strategy.selection?.tickers?.length)) {
|
|
15419
|
-
return {
|
|
15420
|
-
...deployment,
|
|
15421
|
-
tickers: [
|
|
15422
|
-
...new Set(
|
|
15423
|
-
activeStrategies.flatMap(
|
|
15424
|
-
(strategy) => strategy.selection?.tickers ?? []
|
|
15425
|
-
)
|
|
15426
|
-
)
|
|
15427
|
-
].sort()
|
|
15428
|
-
};
|
|
15429
|
-
}
|
|
15430
|
-
const strategiesByName = new Map(
|
|
15431
|
-
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
15432
|
-
);
|
|
15433
|
-
const tickers = /* @__PURE__ */ new Set();
|
|
15434
|
-
for (const scope of lineageScopes) {
|
|
15435
|
-
const strategy = strategiesByName.get(scope.strategy);
|
|
15436
|
-
if (!strategy || scope.deploymentId !== deployment.id || scope.accountId !== deployment.accountId || !isNonEmptyString(scope.symbol) || !runtimeLineageMatchesStrategySnapshot({
|
|
15437
|
-
lineage: scope.lineage,
|
|
15438
|
-
deployment,
|
|
15439
|
-
strategy
|
|
15440
|
-
})) {
|
|
15441
|
-
continue;
|
|
15442
|
-
}
|
|
15443
|
-
tickers.add(scope.symbol.trim());
|
|
15444
|
-
}
|
|
15445
|
-
if (tickers.size === 0) {
|
|
15446
|
-
const verifiedFallbackTickers = fallbackTickers?.filter(isNonEmptyString) ?? [];
|
|
15447
|
-
if (verifiedFallbackTickers.length > 0) {
|
|
15448
|
-
return {
|
|
15449
|
-
...deployment,
|
|
15450
|
-
tickers: [
|
|
15451
|
-
...new Set(verifiedFallbackTickers.map((ticker) => ticker.trim()))
|
|
15452
|
-
].sort()
|
|
15453
|
-
};
|
|
15454
|
-
}
|
|
15455
|
-
throw new Error(
|
|
15456
|
-
"Runtime evidence has no immutable ticker universe for the embedded deployment composition"
|
|
15457
|
-
);
|
|
15458
|
-
}
|
|
15459
|
-
return { ...deployment, tickers: [...tickers].sort() };
|
|
15460
|
-
};
|
|
15461
|
-
runtimeDeploymentFromEvidence = (deployment) => ({
|
|
15462
|
-
id: deployment.id,
|
|
15463
|
-
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
15464
|
-
label: deployment.label,
|
|
15465
|
-
connectorName: deployment.connectorName,
|
|
15466
|
-
provider: deployment.provider,
|
|
15467
|
-
accountId: deployment.accountId,
|
|
15468
|
-
enabled: deployment.enabled,
|
|
15469
|
-
strategies: deployment.strategies.map(
|
|
15470
|
-
({ strategyName, strategyRevision, enabled, controlState, selection }) => ({
|
|
15471
|
-
strategyName,
|
|
15472
|
-
strategyRevision,
|
|
15473
|
-
enabled,
|
|
15474
|
-
controlState,
|
|
15475
|
-
...selection ? { selection } : {}
|
|
15476
|
-
})
|
|
15477
|
-
),
|
|
15478
|
-
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
15479
|
-
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
15480
|
-
});
|
|
15481
|
-
resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
15482
|
-
userName: userName3,
|
|
15483
|
-
projectRoot: projectRoot18,
|
|
15484
|
-
deploymentId
|
|
15485
|
-
}) => {
|
|
15486
|
-
const [deployment, strategies] = await Promise.all([
|
|
15487
|
-
(0, import_runtimeStrategies3.getRuntimeDeployment)({ userName: userName3, projectRoot: projectRoot18, deploymentId }),
|
|
15488
|
-
(0, import_runtimeStrategies3.loadResolvedRuntimeStrategies)({ userName: userName3, projectRoot: projectRoot18, deploymentId })
|
|
15489
|
-
]);
|
|
15490
|
-
if (!deployment) {
|
|
15491
|
-
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
15492
|
-
}
|
|
15493
|
-
return {
|
|
15494
|
-
schemaVersion: 2,
|
|
15495
|
-
id: deployment.id,
|
|
15496
|
-
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
15497
|
-
label: deployment.label,
|
|
15498
|
-
connectorName: deployment.connectorName,
|
|
15499
|
-
provider: deployment.provider,
|
|
15500
|
-
accountId: deployment.accountId,
|
|
15501
|
-
enabled: deployment.enabled,
|
|
15502
|
-
strategies: strategies.map(
|
|
15503
|
-
({
|
|
15504
|
-
strategyName,
|
|
15505
|
-
strategyRevision,
|
|
15506
|
-
enabled,
|
|
15507
|
-
controlState,
|
|
15508
|
-
interval: interval4,
|
|
15509
|
-
universe,
|
|
15510
|
-
accountId,
|
|
15511
|
-
strategyPackage,
|
|
15512
|
-
strategyPackageVersion,
|
|
15513
|
-
strategyDependencyVersions,
|
|
15514
|
-
runtimePackageVersion,
|
|
15515
|
-
strategyConfig,
|
|
15516
|
-
selection
|
|
15517
|
-
}) => ({
|
|
15518
|
-
strategyName,
|
|
15519
|
-
strategyRevision,
|
|
15520
|
-
enabled,
|
|
15521
|
-
controlState,
|
|
15522
|
-
interval: interval4,
|
|
15523
|
-
universe,
|
|
15524
|
-
...accountId ? { accountId } : {},
|
|
15525
|
-
strategyPackage,
|
|
15526
|
-
strategyPackageVersion,
|
|
15527
|
-
strategyDependencyVersions,
|
|
15528
|
-
runtimePackageVersion,
|
|
15529
|
-
strategyConfig,
|
|
15530
|
-
...selection ? { selection } : {}
|
|
15531
|
-
})
|
|
15532
|
-
),
|
|
15533
|
-
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
15534
|
-
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
15535
|
-
};
|
|
15536
|
-
};
|
|
15248
|
+
__reExport(runtimeEvidenceDeployment_exports, require("@tradejs/node/diagnostics"));
|
|
15537
15249
|
}
|
|
15538
15250
|
});
|
|
15539
15251
|
|
|
@@ -15558,7 +15270,7 @@ var init_runtimeEvidenceSource = __esm({
|
|
|
15558
15270
|
deployment
|
|
15559
15271
|
}) => {
|
|
15560
15272
|
const activeStrategies = new Set(
|
|
15561
|
-
activeRuntimeEvidenceStrategies(deployment).map(
|
|
15273
|
+
(0, runtimeEvidenceDeployment_exports.activeRuntimeEvidenceStrategies)(deployment).map(
|
|
15562
15274
|
({ strategyName }) => strategyName
|
|
15563
15275
|
)
|
|
15564
15276
|
);
|
|
@@ -15582,7 +15294,7 @@ var init_runtimeEvidenceSource = __esm({
|
|
|
15582
15294
|
if (!root || !runtime) {
|
|
15583
15295
|
throw new Error(`Invalid runtime evidence JSON: ${resolvedPath}`);
|
|
15584
15296
|
}
|
|
15585
|
-
assertCurrentRuntimeEvidenceArtifact(root);
|
|
15297
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(root);
|
|
15586
15298
|
const rootWindow = asRecord2(root.window);
|
|
15587
15299
|
const runtimeWindow2 = asRecord2(runtime.window);
|
|
15588
15300
|
return {
|
|
@@ -15592,8 +15304,8 @@ var init_runtimeEvidenceSource = __esm({
|
|
|
15592
15304
|
userName: String(root.userName ?? runtime.userName ?? "").trim(),
|
|
15593
15305
|
startTime: asFiniteNumber(rootWindow?.startTime) ?? asFiniteNumber(runtimeWindow2?.startTime),
|
|
15594
15306
|
endTime: asFiniteNumber(rootWindow?.endTime) ?? asFiniteNumber(runtimeWindow2?.endTime),
|
|
15595
|
-
deployment: resolveRuntimeEvidenceTickerUniverse({
|
|
15596
|
-
deployment: parseRuntimeEvidenceDeploymentSnapshot(root.deployment),
|
|
15307
|
+
deployment: (0, runtimeEvidenceDeployment_exports.resolveRuntimeEvidenceTickerUniverse)({
|
|
15308
|
+
deployment: (0, runtimeEvidenceDeployment_exports.parseRuntimeEvidenceDeploymentSnapshot)(root.deployment),
|
|
15597
15309
|
lineageScopes: unwrapRows(
|
|
15598
15310
|
runtime.lineageScopes,
|
|
15599
15311
|
"lineageScope"
|
|
@@ -16857,7 +16569,7 @@ var init_historicalSignalsReplayResults = __esm({
|
|
|
16857
16569
|
});
|
|
16858
16570
|
|
|
16859
16571
|
// src/lib/replay/historicalSignalsReplay.ts
|
|
16860
|
-
var import_chalk17, import_progress8, import_node_path8, import_node_module2, import_strategies5, import_time4, import_logger, import_redis8, import_connectors6, import_cli5, import_strategies6,
|
|
16572
|
+
var import_chalk17, import_progress8, import_node_path8, import_node_module2, import_strategies5, import_time4, import_logger, import_redis8, import_connectors6, import_cli5, import_strategies6, import_runtimeStrategies3, projectReplayCacheReleasers, getProjectReplayCacheReleasers, releaseReplayCacheCopies, loadRuntimeStrategies, loadReferenceConnector, buildAfterSignalsContext, getConnectorName, loadHistoricalReplayReferences, runHistoricalSignalsReplay;
|
|
16861
16573
|
var init_historicalSignalsReplay = __esm({
|
|
16862
16574
|
"src/lib/replay/historicalSignalsReplay.ts"() {
|
|
16863
16575
|
"use strict";
|
|
@@ -16872,7 +16584,7 @@ var init_historicalSignalsReplay = __esm({
|
|
|
16872
16584
|
import_connectors6 = require("@tradejs/node/connectors");
|
|
16873
16585
|
import_cli5 = require("@tradejs/node/cli");
|
|
16874
16586
|
import_strategies6 = require("@tradejs/node/strategies");
|
|
16875
|
-
|
|
16587
|
+
import_runtimeStrategies3 = require("@tradejs/node/runtimeStrategies");
|
|
16876
16588
|
init_cliConfig2();
|
|
16877
16589
|
init_portfolioReplayConnector();
|
|
16878
16590
|
init_hooks();
|
|
@@ -16925,7 +16637,7 @@ var init_historicalSignalsReplay = __esm({
|
|
|
16925
16637
|
if (!strategyCreator) {
|
|
16926
16638
|
throw new Error(`Unknown strategy: ${strategyName}`);
|
|
16927
16639
|
}
|
|
16928
|
-
const installed = await (0,
|
|
16640
|
+
const installed = await (0, import_runtimeStrategies3.getRuntimeStrategyPackageMetadata)({
|
|
16929
16641
|
strategyName,
|
|
16930
16642
|
projectRoot: replayProjectRoot,
|
|
16931
16643
|
strategyModule
|
|
@@ -20986,7 +20698,7 @@ ${markdownTable2(strategyRows)}
|
|
|
20986
20698
|
});
|
|
20987
20699
|
|
|
20988
20700
|
// src/scripts/replayRunner.ts
|
|
20989
|
-
var import_chalk21, import_constants14, import_data5, import_time8, import_redis11, import_candles,
|
|
20701
|
+
var import_chalk21, import_constants14, import_data5, import_time8, import_redis11, import_candles, import_runtimeStrategies4, import_strategies7, prepareReplayBinanceMarketContext, replayMarketContextInterval, cachedTickerSymbols, finishReplay, replayBacktest;
|
|
20990
20702
|
var init_replayRunner = __esm({
|
|
20991
20703
|
"src/scripts/replayRunner.ts"() {
|
|
20992
20704
|
"use strict";
|
|
@@ -20996,7 +20708,7 @@ var init_replayRunner = __esm({
|
|
|
20996
20708
|
import_time8 = require("@tradejs/core/time");
|
|
20997
20709
|
import_redis11 = require("@tradejs/infra/redis");
|
|
20998
20710
|
import_candles = require("@tradejs/infra/timescale/candles");
|
|
20999
|
-
|
|
20711
|
+
import_runtimeStrategies4 = require("@tradejs/node/runtimeStrategies");
|
|
21000
20712
|
import_strategies7 = require("@tradejs/node/strategies");
|
|
21001
20713
|
init_runFormatting();
|
|
21002
20714
|
init_runEnvironment();
|
|
@@ -21184,8 +20896,8 @@ var init_replayRunner = __esm({
|
|
|
21184
20896
|
);
|
|
21185
20897
|
}
|
|
21186
20898
|
const replayComposition = evidenceMetadata ? {
|
|
21187
|
-
deployment: runtimeDeploymentFromEvidence(evidenceMetadata.deployment),
|
|
21188
|
-
strategies: activeRuntimeEvidenceStrategies(
|
|
20899
|
+
deployment: (0, runtimeEvidenceDeployment_exports.runtimeDeploymentFromEvidence)(evidenceMetadata.deployment),
|
|
20900
|
+
strategies: (0, runtimeEvidenceDeployment_exports.activeRuntimeEvidenceStrategies)(
|
|
21189
20901
|
evidenceMetadata.deployment
|
|
21190
20902
|
).map(
|
|
21191
20903
|
({
|
|
@@ -21237,7 +20949,7 @@ var init_replayRunner = __esm({
|
|
|
21237
20949
|
return {
|
|
21238
20950
|
...strategy,
|
|
21239
20951
|
strategyConfig,
|
|
21240
|
-
strategyRevision: (0,
|
|
20952
|
+
strategyRevision: (0, import_runtimeStrategies4.computeStrategyRevision)({
|
|
21241
20953
|
strategyName: strategy.strategyName,
|
|
21242
20954
|
strategyPackage: strategy.strategyPackage,
|
|
21243
20955
|
strategyPackageVersion: strategy.strategyPackageVersion,
|
|
@@ -21247,7 +20959,7 @@ var init_replayRunner = __esm({
|
|
|
21247
20959
|
})
|
|
21248
20960
|
};
|
|
21249
20961
|
});
|
|
21250
|
-
const researchDeploymentCompositionId = (0,
|
|
20962
|
+
const researchDeploymentCompositionId = (0, import_runtimeStrategies4.computeDeploymentCompositionId)({
|
|
21251
20963
|
deploymentId: deployment.id,
|
|
21252
20964
|
connectorName: deployment.connectorName,
|
|
21253
20965
|
provider: deployment.provider,
|
|
@@ -24658,12 +24370,268 @@ var init_marketWs = __esm({
|
|
|
24658
24370
|
}
|
|
24659
24371
|
});
|
|
24660
24372
|
|
|
24373
|
+
// src/scripts/mcpWorker.ts
|
|
24374
|
+
var mcpWorker_exports = {};
|
|
24375
|
+
__export(mcpWorker_exports, {
|
|
24376
|
+
main: () => main26
|
|
24377
|
+
});
|
|
24378
|
+
var import_node_child_process4, import_node_crypto8, import_promises17, import_redis15, import_mcp, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main26;
|
|
24379
|
+
var init_mcpWorker = __esm({
|
|
24380
|
+
"src/scripts/mcpWorker.ts"() {
|
|
24381
|
+
"use strict";
|
|
24382
|
+
import_node_child_process4 = require("child_process");
|
|
24383
|
+
import_node_crypto8 = require("crypto");
|
|
24384
|
+
import_promises17 = require("fs/promises");
|
|
24385
|
+
import_redis15 = require("@tradejs/infra/redis");
|
|
24386
|
+
import_mcp = require("@tradejs/node/mcp");
|
|
24387
|
+
pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
24388
|
+
leaseKey = "worker:lease";
|
|
24389
|
+
LEASE_SECONDS = 15;
|
|
24390
|
+
JOB_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
24391
|
+
main26 = async (options = {}) => {
|
|
24392
|
+
const owner = (0, import_node_crypto8.randomUUID)();
|
|
24393
|
+
if (!await import_redis15.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
|
|
24394
|
+
throw new Error("Another MCP worker owns this storage");
|
|
24395
|
+
let stopping = false;
|
|
24396
|
+
let child;
|
|
24397
|
+
let renewing = false;
|
|
24398
|
+
let leaseLost = false;
|
|
24399
|
+
let manifestHash = "";
|
|
24400
|
+
const signalChild = (signal) => {
|
|
24401
|
+
if (!child?.pid) return;
|
|
24402
|
+
try {
|
|
24403
|
+
process.kill(
|
|
24404
|
+
process.platform === "win32" ? child.pid : -child.pid,
|
|
24405
|
+
signal
|
|
24406
|
+
);
|
|
24407
|
+
} catch {
|
|
24408
|
+
}
|
|
24409
|
+
};
|
|
24410
|
+
const heartbeatValue = () => ({
|
|
24411
|
+
observedAt: Date.now(),
|
|
24412
|
+
packageManifestSha256: manifestHash,
|
|
24413
|
+
replayAvailable: Boolean(process.env.MCP_REPLAY_REDIS_HOST)
|
|
24414
|
+
});
|
|
24415
|
+
const stop = () => {
|
|
24416
|
+
stopping = true;
|
|
24417
|
+
signalChild("SIGTERM");
|
|
24418
|
+
};
|
|
24419
|
+
options.signal?.addEventListener("abort", stop, { once: true });
|
|
24420
|
+
if (options.signal?.aborted) stop();
|
|
24421
|
+
process.once("SIGINT", stop);
|
|
24422
|
+
process.once("SIGTERM", stop);
|
|
24423
|
+
const heartbeat = setInterval(async () => {
|
|
24424
|
+
if (renewing || leaseLost) return;
|
|
24425
|
+
renewing = true;
|
|
24426
|
+
try {
|
|
24427
|
+
if (!await import_redis15.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
|
|
24428
|
+
throw new Error("Worker lease lost");
|
|
24429
|
+
await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
24430
|
+
} catch {
|
|
24431
|
+
leaseLost = true;
|
|
24432
|
+
stop();
|
|
24433
|
+
} finally {
|
|
24434
|
+
renewing = false;
|
|
24435
|
+
}
|
|
24436
|
+
}, 2e3);
|
|
24437
|
+
try {
|
|
24438
|
+
manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
|
|
24439
|
+
await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
24440
|
+
let cursor = "0";
|
|
24441
|
+
do {
|
|
24442
|
+
const page = await import_redis15.mcpStorage.scan("jobs:", cursor);
|
|
24443
|
+
cursor = page.cursor;
|
|
24444
|
+
for (const key of page.ids) {
|
|
24445
|
+
const job = await import_redis15.mcpStorage.get(key);
|
|
24446
|
+
if (job?.status === "running")
|
|
24447
|
+
await import_redis15.mcpStorage.compare(
|
|
24448
|
+
key,
|
|
24449
|
+
job,
|
|
24450
|
+
{
|
|
24451
|
+
...job,
|
|
24452
|
+
status: "failed",
|
|
24453
|
+
error: "Worker restarted; this job was not replayed",
|
|
24454
|
+
finishedAt: Date.now(),
|
|
24455
|
+
updatedAt: Date.now()
|
|
24456
|
+
},
|
|
24457
|
+
import_mcp.MCP_JOB_TTL
|
|
24458
|
+
);
|
|
24459
|
+
}
|
|
24460
|
+
} while (cursor !== "0" && !stopping);
|
|
24461
|
+
console.log(
|
|
24462
|
+
"MCP worker ready (one job at a time, cached history, no live order commands)"
|
|
24463
|
+
);
|
|
24464
|
+
while (!stopping) {
|
|
24465
|
+
let queued;
|
|
24466
|
+
cursor = "0";
|
|
24467
|
+
do {
|
|
24468
|
+
const page = await import_redis15.mcpStorage.scan("jobs:", cursor);
|
|
24469
|
+
cursor = page.cursor;
|
|
24470
|
+
for (const key of page.ids) {
|
|
24471
|
+
const job = await import_redis15.mcpStorage.get(key);
|
|
24472
|
+
if (job?.status === "queued" && (!queued || job.createdAt < queued.createdAt))
|
|
24473
|
+
queued = job;
|
|
24474
|
+
}
|
|
24475
|
+
} while (cursor !== "0" && !stopping);
|
|
24476
|
+
if (!queued) {
|
|
24477
|
+
await pause(1e3);
|
|
24478
|
+
continue;
|
|
24479
|
+
}
|
|
24480
|
+
const jobKey = (0, import_mcp.mcpJobStorageId)(queued.userName, queued.id);
|
|
24481
|
+
const started = {
|
|
24482
|
+
...queued,
|
|
24483
|
+
status: "running",
|
|
24484
|
+
startedAt: Date.now(),
|
|
24485
|
+
updatedAt: Date.now()
|
|
24486
|
+
};
|
|
24487
|
+
if (!await import_redis15.mcpStorage.compare(jobKey, queued, started, import_mcp.MCP_JOB_TTL))
|
|
24488
|
+
continue;
|
|
24489
|
+
if (started.packageManifestSha256 !== manifestHash) {
|
|
24490
|
+
await import_redis15.mcpStorage.compare(
|
|
24491
|
+
jobKey,
|
|
24492
|
+
started,
|
|
24493
|
+
{
|
|
24494
|
+
...started,
|
|
24495
|
+
status: "failed",
|
|
24496
|
+
error: "Package composition changed since submission",
|
|
24497
|
+
finishedAt: Date.now()
|
|
24498
|
+
},
|
|
24499
|
+
import_mcp.MCP_JOB_TTL
|
|
24500
|
+
);
|
|
24501
|
+
continue;
|
|
24502
|
+
}
|
|
24503
|
+
await (0, import_promises17.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
|
|
24504
|
+
if (started.kind === "backtest")
|
|
24505
|
+
await (0, import_redis15.setDataStrict)(
|
|
24506
|
+
import_redis15.redisKeys.backtestConfig(
|
|
24507
|
+
started.userName,
|
|
24508
|
+
String(started.request.frozenConfigId)
|
|
24509
|
+
),
|
|
24510
|
+
started.request.resolvedConfig,
|
|
24511
|
+
{ expire: import_mcp.MCP_JOB_TTL }
|
|
24512
|
+
);
|
|
24513
|
+
const jobEnv = {
|
|
24514
|
+
...process.env,
|
|
24515
|
+
NODE_OPTIONS: "--max-old-space-size=1024",
|
|
24516
|
+
MCP_WORKER: "true",
|
|
24517
|
+
BACKTEST_WORKER_HEAP_MB: "768",
|
|
24518
|
+
BACKTEST_MAX_PARALLEL: "1",
|
|
24519
|
+
AI_ENABLED: "false",
|
|
24520
|
+
ML_ENABLED: "false",
|
|
24521
|
+
MAKE_ORDERS: "false",
|
|
24522
|
+
TRADEJS_EXTERNAL_ORDER_PLACEMENT: "false"
|
|
24523
|
+
};
|
|
24524
|
+
if (started.kind === "runtime-feedback-replay") {
|
|
24525
|
+
for (const name of Object.keys(jobEnv)) {
|
|
24526
|
+
if (/secret|token|api.?key|private.?key|cookie|credential/i.test(name))
|
|
24527
|
+
delete jobEnv[name];
|
|
24528
|
+
}
|
|
24529
|
+
Object.assign(jobEnv, {
|
|
24530
|
+
DOTENV_CONFIG_PATH: "/dev/null",
|
|
24531
|
+
REDIS_HOST: process.env.MCP_REPLAY_REDIS_HOST,
|
|
24532
|
+
REDIS_PORT: "6379",
|
|
24533
|
+
REDIS_DB: "0",
|
|
24534
|
+
RUNTIME_FEEDBACK_ISOLATED_REDIS: "true",
|
|
24535
|
+
PGOPTIONS: "-c default_transaction_read_only=on",
|
|
24536
|
+
TRADEJS_TIMESCALE_READ_ONLY: "true"
|
|
24537
|
+
});
|
|
24538
|
+
}
|
|
24539
|
+
child = (0, import_node_child_process4.spawn)(process.execPath, [process.argv[1], ...started.args], {
|
|
24540
|
+
cwd: process.env.PROJECT_CWD || process.cwd(),
|
|
24541
|
+
env: jobEnv,
|
|
24542
|
+
detached: process.platform !== "win32",
|
|
24543
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
24544
|
+
});
|
|
24545
|
+
const currentChild = child;
|
|
24546
|
+
let timedOut = false;
|
|
24547
|
+
const timeout = setTimeout(() => {
|
|
24548
|
+
timedOut = true;
|
|
24549
|
+
signalChild("SIGTERM");
|
|
24550
|
+
}, JOB_TIMEOUT_MS);
|
|
24551
|
+
const logs = [];
|
|
24552
|
+
const log = (chunk) => {
|
|
24553
|
+
const lines = chunk.toString().replace(/\u001b\[[0-9;]*m/g, "").split(/[\r\n]+/).filter(Boolean);
|
|
24554
|
+
logs.push(
|
|
24555
|
+
...lines.map(
|
|
24556
|
+
(line) => line.slice(0, 1e3).replace(
|
|
24557
|
+
/((?:secret|password|api.?key|token|authorization)\s*[:=]\s*)\S+/gi,
|
|
24558
|
+
"$1[redacted]"
|
|
24559
|
+
)
|
|
24560
|
+
)
|
|
24561
|
+
);
|
|
24562
|
+
if (logs.length > 150) logs.splice(0, logs.length - 150);
|
|
24563
|
+
};
|
|
24564
|
+
currentChild.stdout?.on("data", log);
|
|
24565
|
+
currentChild.stderr?.on("data", log);
|
|
24566
|
+
let killAt;
|
|
24567
|
+
const monitor = setInterval(async () => {
|
|
24568
|
+
try {
|
|
24569
|
+
const latest = await import_redis15.mcpStorage.get(jobKey);
|
|
24570
|
+
if (!latest || latest.cancelRequested || stopping || timedOut) {
|
|
24571
|
+
killAt ??= Date.now();
|
|
24572
|
+
signalChild(Date.now() - killAt > 8e3 ? "SIGKILL" : "SIGTERM");
|
|
24573
|
+
}
|
|
24574
|
+
if (latest && !leaseLost)
|
|
24575
|
+
await import_redis15.mcpStorage.compare(
|
|
24576
|
+
jobKey,
|
|
24577
|
+
latest,
|
|
24578
|
+
{ ...latest, logs: [...logs], updatedAt: Date.now() },
|
|
24579
|
+
import_mcp.MCP_JOB_TTL
|
|
24580
|
+
);
|
|
24581
|
+
} catch {
|
|
24582
|
+
leaseLost = true;
|
|
24583
|
+
stop();
|
|
24584
|
+
}
|
|
24585
|
+
}, 1e3);
|
|
24586
|
+
const outcome = await new Promise((resolve) => {
|
|
24587
|
+
currentChild.once(
|
|
24588
|
+
"error",
|
|
24589
|
+
() => resolve({ code: null, error: "Unable to start research process" })
|
|
24590
|
+
);
|
|
24591
|
+
currentChild.once("exit", (code) => resolve({ code }));
|
|
24592
|
+
});
|
|
24593
|
+
clearTimeout(timeout);
|
|
24594
|
+
clearInterval(monitor);
|
|
24595
|
+
child = void 0;
|
|
24596
|
+
if (!leaseLost) {
|
|
24597
|
+
for (let attempt = 0; attempt < 4; attempt++) {
|
|
24598
|
+
const latest = await import_redis15.mcpStorage.get(jobKey);
|
|
24599
|
+
if (!latest) break;
|
|
24600
|
+
const cancelled = latest.cancelRequested;
|
|
24601
|
+
const next = {
|
|
24602
|
+
...latest,
|
|
24603
|
+
logs,
|
|
24604
|
+
status: cancelled ? "cancelled" : outcome.code === 0 && !timedOut && !stopping ? "completed" : "failed",
|
|
24605
|
+
exitCode: outcome.code,
|
|
24606
|
+
updatedAt: Date.now(),
|
|
24607
|
+
finishedAt: Date.now(),
|
|
24608
|
+
...cancelled ? {} : timedOut ? { error: "Job exceeded one hour" } : stopping ? { error: "Worker stopped; this job was not replayed" } : outcome.code !== 0 ? { error: outcome.error || "Research process failed" } : {}
|
|
24609
|
+
};
|
|
24610
|
+
if (await import_redis15.mcpStorage.compare(jobKey, latest, next, import_mcp.MCP_JOB_TTL))
|
|
24611
|
+
break;
|
|
24612
|
+
}
|
|
24613
|
+
}
|
|
24614
|
+
}
|
|
24615
|
+
} finally {
|
|
24616
|
+
clearInterval(heartbeat);
|
|
24617
|
+
options.signal?.removeEventListener("abort", stop);
|
|
24618
|
+
process.removeListener("SIGINT", stop);
|
|
24619
|
+
process.removeListener("SIGTERM", stop);
|
|
24620
|
+
if (await import_redis15.mcpStorage.release(leaseKey, owner))
|
|
24621
|
+
await import_redis15.mcpStorage.remove("worker:heartbeat");
|
|
24622
|
+
}
|
|
24623
|
+
if (leaseLost)
|
|
24624
|
+
throw new Error("Worker lease lost; active computation was stopped");
|
|
24625
|
+
};
|
|
24626
|
+
}
|
|
24627
|
+
});
|
|
24628
|
+
|
|
24661
24629
|
// src/scripts/hyperliquidWhaleBackfill.ts
|
|
24662
24630
|
var hyperliquidWhaleBackfill_exports = {};
|
|
24663
24631
|
__export(hyperliquidWhaleBackfill_exports, {
|
|
24664
|
-
main: () =>
|
|
24632
|
+
main: () => main27
|
|
24665
24633
|
});
|
|
24666
|
-
var import_args20, flags18, parseTime,
|
|
24634
|
+
var import_args20, flags18, parseTime, main27;
|
|
24667
24635
|
var init_hyperliquidWhaleBackfill2 = __esm({
|
|
24668
24636
|
"src/scripts/hyperliquidWhaleBackfill.ts"() {
|
|
24669
24637
|
"use strict";
|
|
@@ -24683,7 +24651,7 @@ var init_hyperliquidWhaleBackfill2 = __esm({
|
|
|
24683
24651
|
if (!Number.isFinite(parsed)) throw new Error(`Invalid timestamp: ${value}`);
|
|
24684
24652
|
return parsed;
|
|
24685
24653
|
};
|
|
24686
|
-
|
|
24654
|
+
main27 = async () => {
|
|
24687
24655
|
const toMs = parseTime(flags18.to, Date.now());
|
|
24688
24656
|
const days = Number(flags18.days);
|
|
24689
24657
|
const lookbackMs = (Number.isFinite(days) && days > 0 ? days : 1) * 864e5;
|
|
@@ -24892,14 +24860,14 @@ var init_hyperliquidWhaleStream = __esm({
|
|
|
24892
24860
|
// src/scripts/hyperliquidWhaleIngest.ts
|
|
24893
24861
|
var hyperliquidWhaleIngest_exports = {};
|
|
24894
24862
|
__export(hyperliquidWhaleIngest_exports, {
|
|
24895
|
-
main: () =>
|
|
24863
|
+
main: () => main28
|
|
24896
24864
|
});
|
|
24897
|
-
var
|
|
24865
|
+
var main28;
|
|
24898
24866
|
var init_hyperliquidWhaleIngest = __esm({
|
|
24899
24867
|
"src/scripts/hyperliquidWhaleIngest.ts"() {
|
|
24900
24868
|
"use strict";
|
|
24901
24869
|
init_hyperliquidWhaleStream();
|
|
24902
|
-
|
|
24870
|
+
main28 = async () => {
|
|
24903
24871
|
const controller = new AbortController();
|
|
24904
24872
|
const stop = () => controller.abort();
|
|
24905
24873
|
process.once("SIGINT", stop);
|
|
@@ -25011,15 +24979,15 @@ var init_hyperliquidWhaleSelection = __esm({
|
|
|
25011
24979
|
// src/scripts/hyperliquidWhalesUpdate.ts
|
|
25012
24980
|
var hyperliquidWhalesUpdate_exports = {};
|
|
25013
24981
|
__export(hyperliquidWhalesUpdate_exports, {
|
|
25014
|
-
main: () =>
|
|
24982
|
+
main: () => main29
|
|
25015
24983
|
});
|
|
25016
|
-
var import_config8, import_args21,
|
|
24984
|
+
var import_config8, import_args21, import_node_crypto9, import_strategies12, LEADERBOARD_URL, DAY_MS10, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main29;
|
|
25017
24985
|
var init_hyperliquidWhalesUpdate = __esm({
|
|
25018
24986
|
"src/scripts/hyperliquidWhalesUpdate.ts"() {
|
|
25019
24987
|
"use strict";
|
|
25020
24988
|
import_config8 = require("dotenv/config");
|
|
25021
24989
|
import_args21 = __toESM(require("args"));
|
|
25022
|
-
|
|
24990
|
+
import_node_crypto9 = require("crypto");
|
|
25023
24991
|
import_strategies12 = require("@tradejs/node/strategies");
|
|
25024
24992
|
init_hyperliquidWhaleBackfill();
|
|
25025
24993
|
init_hyperliquidRateLimiter();
|
|
@@ -25033,7 +25001,7 @@ var init_hyperliquidWhalesUpdate = __esm({
|
|
|
25033
25001
|
);
|
|
25034
25002
|
import_args21.default.option(["d", "days"], "Calibration window in days", 7);
|
|
25035
25003
|
flags19 = import_args21.default.parse(process.argv);
|
|
25036
|
-
fingerprint = (addresses) => (0,
|
|
25004
|
+
fingerprint = (addresses) => (0, import_node_crypto9.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
|
|
25037
25005
|
runConcurrent2 = async (params) => {
|
|
25038
25006
|
let nextIndex = 0;
|
|
25039
25007
|
await Promise.all(
|
|
@@ -25047,7 +25015,7 @@ var init_hyperliquidWhalesUpdate = __esm({
|
|
|
25047
25015
|
})
|
|
25048
25016
|
);
|
|
25049
25017
|
};
|
|
25050
|
-
|
|
25018
|
+
main29 = async () => {
|
|
25051
25019
|
const explicitTo = flags19.to == null ? Number.NaN : Date.parse(String(flags19.to));
|
|
25052
25020
|
const calibrationToMs = Number.isFinite(explicitTo) ? explicitTo : Math.floor(Date.now() / DAY_MS10) * DAY_MS10;
|
|
25053
25021
|
const calibrationDays = Math.max(1, Number(flags19.days) || 7);
|
|
@@ -25140,15 +25108,15 @@ var init_hyperliquidWhalesUpdate = __esm({
|
|
|
25140
25108
|
// src/scripts/mlExport.ts
|
|
25141
25109
|
var mlExport_exports = {};
|
|
25142
25110
|
__export(mlExport_exports, {
|
|
25143
|
-
main: () =>
|
|
25111
|
+
main: () => main30
|
|
25144
25112
|
});
|
|
25145
|
-
var import_args22, import_chalk37,
|
|
25113
|
+
var import_args22, import_chalk37, import_promises18, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main30;
|
|
25146
25114
|
var init_mlExport = __esm({
|
|
25147
25115
|
"src/scripts/mlExport.ts"() {
|
|
25148
25116
|
"use strict";
|
|
25149
25117
|
import_args22 = __toESM(require("args"));
|
|
25150
25118
|
import_chalk37 = __toESM(require("chalk"));
|
|
25151
|
-
|
|
25119
|
+
import_promises18 = __toESM(require("fs/promises"));
|
|
25152
25120
|
import_path8 = __toESM(require("path"));
|
|
25153
25121
|
import_ml = require("@tradejs/infra/ml");
|
|
25154
25122
|
init_checkpoint();
|
|
@@ -25197,9 +25165,9 @@ var init_mlExport = __esm({
|
|
|
25197
25165
|
completedAttemptKeys: buildCompletedBacktestDatasetAttemptKeys(completed)
|
|
25198
25166
|
};
|
|
25199
25167
|
};
|
|
25200
|
-
|
|
25168
|
+
main30 = async () => {
|
|
25201
25169
|
const outDir = String(flags20.outDir || "data/ml/export");
|
|
25202
|
-
await
|
|
25170
|
+
await import_promises18.default.mkdir(outDir, { recursive: true });
|
|
25203
25171
|
const strategyName = await resolveExportStrategy({
|
|
25204
25172
|
explicitStrategy: String(flags20.strategy || ""),
|
|
25205
25173
|
outDir,
|
|
@@ -25244,7 +25212,7 @@ var init_mlExport = __esm({
|
|
|
25244
25212
|
const shouldDeleteChunks = !Boolean(flags20.keepChunks);
|
|
25245
25213
|
if (shouldDeleteChunks) {
|
|
25246
25214
|
for (const filePath of chunkFiles) {
|
|
25247
|
-
await
|
|
25215
|
+
await import_promises18.default.rm(filePath, { force: true });
|
|
25248
25216
|
}
|
|
25249
25217
|
}
|
|
25250
25218
|
console.log(import_chalk37.default.green(`Merged dataset saved: ${mergedPath}`));
|
|
@@ -25263,15 +25231,15 @@ var init_mlExport = __esm({
|
|
|
25263
25231
|
// src/scripts/mlInspect.ts
|
|
25264
25232
|
var mlInspect_exports = {};
|
|
25265
25233
|
__export(mlInspect_exports, {
|
|
25266
|
-
main: () =>
|
|
25234
|
+
main: () => main31
|
|
25267
25235
|
});
|
|
25268
|
-
var import_args23, import_chalk38,
|
|
25236
|
+
var import_args23, import_chalk38, import_promises19, import_fs3, import_path9, import_readline2, import_child_process2, flags21, toMode, toInspectTool, selectInspectTool, asPositiveInt, readRowsHead, readRowsTail, readRowsSample, quantileSorted, mean2, std, findLatestDataset, buildNumericStats, formatNumber5, runQuickInspect, runYDataInspect, main31;
|
|
25269
25237
|
var init_mlInspect = __esm({
|
|
25270
25238
|
"src/scripts/mlInspect.ts"() {
|
|
25271
25239
|
"use strict";
|
|
25272
25240
|
import_args23 = __toESM(require("args"));
|
|
25273
25241
|
import_chalk38 = __toESM(require("chalk"));
|
|
25274
|
-
|
|
25242
|
+
import_promises19 = __toESM(require("fs/promises"));
|
|
25275
25243
|
import_fs3 = require("fs");
|
|
25276
25244
|
import_path9 = __toESM(require("path"));
|
|
25277
25245
|
import_readline2 = __toESM(require("readline"));
|
|
@@ -25448,7 +25416,7 @@ var init_mlInspect = __esm({
|
|
|
25448
25416
|
};
|
|
25449
25417
|
findLatestDataset = async (params) => {
|
|
25450
25418
|
const { dir, strategy } = params;
|
|
25451
|
-
const entries = await
|
|
25419
|
+
const entries = await import_promises19.default.readdir(dir, { withFileTypes: true });
|
|
25452
25420
|
const strategyToken = strategy.trim().toLowerCase();
|
|
25453
25421
|
const files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.endsWith(".jsonl")).filter(
|
|
25454
25422
|
(name) => !name.includes(".train.") && !name.includes(".test.")
|
|
@@ -25460,7 +25428,7 @@ var init_mlInspect = __esm({
|
|
|
25460
25428
|
}
|
|
25461
25429
|
const withMtime = await Promise.all(
|
|
25462
25430
|
files.map(async (name) => {
|
|
25463
|
-
const stat = await
|
|
25431
|
+
const stat = await import_promises19.default.stat(import_path9.default.join(dir, name));
|
|
25464
25432
|
return { name, mtime: stat.mtimeMs };
|
|
25465
25433
|
})
|
|
25466
25434
|
);
|
|
@@ -25705,7 +25673,7 @@ var init_mlInspect = __esm({
|
|
|
25705
25673
|
const relToData = import_path9.default.relative(dataRoot, absDatasetPath);
|
|
25706
25674
|
const inputInContainer = `/app/data/${relToData}`;
|
|
25707
25675
|
const reportDir = import_path9.default.dirname(absDatasetPath);
|
|
25708
|
-
await
|
|
25676
|
+
await import_promises19.default.mkdir(reportDir, { recursive: true });
|
|
25709
25677
|
const reportPath = import_path9.default.join(
|
|
25710
25678
|
reportDir,
|
|
25711
25679
|
`${import_path9.default.basename(datasetPath, import_path9.default.extname(datasetPath))}.profile.html`
|
|
@@ -25757,7 +25725,7 @@ var init_mlInspect = __esm({
|
|
|
25757
25725
|
}
|
|
25758
25726
|
console.log(import_chalk38.default.green(`Profile report saved: ${reportPath}`));
|
|
25759
25727
|
};
|
|
25760
|
-
|
|
25728
|
+
main31 = async () => {
|
|
25761
25729
|
const dir = String(flags21.dir || "data/ml/export");
|
|
25762
25730
|
const rowsToInspect = asPositiveInt(flags21.rows, 1e4);
|
|
25763
25731
|
const mode = toMode(flags21.mode);
|
|
@@ -25799,14 +25767,14 @@ var init_mlInspect = __esm({
|
|
|
25799
25767
|
// src/scripts/mlTrainLatestSelect.ts
|
|
25800
25768
|
var mlTrainLatestSelect_exports = {};
|
|
25801
25769
|
__export(mlTrainLatestSelect_exports, {
|
|
25802
|
-
main: () =>
|
|
25770
|
+
main: () => main32
|
|
25803
25771
|
});
|
|
25804
|
-
var import_path10,
|
|
25772
|
+
var import_path10, import_promises20, import_fs4, import_crypto2, import_child_process3, import_events, import_readline3, import_args24, import_chalk39, import_ml2, toFileToken6, asBool, asInt7, asNonNegativeInt, formatBytes, getMlContainerMemUsage, MODEL_TYPES, STRATEGIES, flags22, parseStrategy, parseModelType, selectModelType, listDatasetFiles, concatFiles, pipeNormalized, DAY_MS11, SPLIT_PROGRESS_EVERY, parseTimestampMs, scanMaxLabeledTimestampMs, scanMaxTrainTimestampMs, hashFileNameSha1, prepareTrainWindowFiles, main32;
|
|
25805
25773
|
var init_mlTrainLatestSelect = __esm({
|
|
25806
25774
|
"src/scripts/mlTrainLatestSelect.ts"() {
|
|
25807
25775
|
"use strict";
|
|
25808
25776
|
import_path10 = __toESM(require("path"));
|
|
25809
|
-
|
|
25777
|
+
import_promises20 = __toESM(require("fs/promises"));
|
|
25810
25778
|
import_fs4 = require("fs");
|
|
25811
25779
|
import_crypto2 = require("crypto");
|
|
25812
25780
|
import_child_process3 = require("child_process");
|
|
@@ -25935,7 +25903,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
25935
25903
|
return defaultModel;
|
|
25936
25904
|
};
|
|
25937
25905
|
listDatasetFiles = async (dir, strategyName) => {
|
|
25938
|
-
const entries = await
|
|
25906
|
+
const entries = await import_promises20.default.readdir(dir, { withFileTypes: true });
|
|
25939
25907
|
const prefix = `ml-dataset-${toFileToken6(strategyName)}-`;
|
|
25940
25908
|
const legacyPrefix = "ml-dataset-";
|
|
25941
25909
|
const fileNames = entries.filter((entry) => entry.isFile()).map((entry) => entry.name);
|
|
@@ -25946,7 +25914,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
25946
25914
|
).filter((name) => !name.includes(".train.") && !name.includes(".test.")).filter((name) => !name.includes(".holdout-train.")).filter((name) => !name.includes(".holdout-test.")).filter((name) => !name.includes(".walk-forward.")).filter((name) => !name.includes(".prod."));
|
|
25947
25915
|
const withMtime = await Promise.all(
|
|
25948
25916
|
jsonlFiles.map(async (name) => {
|
|
25949
|
-
const stat = await
|
|
25917
|
+
const stat = await import_promises20.default.stat(import_path10.default.join(dir, name));
|
|
25950
25918
|
return { name, mtime: stat.mtimeMs };
|
|
25951
25919
|
})
|
|
25952
25920
|
);
|
|
@@ -26122,13 +26090,13 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26122
26090
|
const metaPath = import_path10.default.join(dir, `${parsed.name}.windows.${key}.meta.json`);
|
|
26123
26091
|
try {
|
|
26124
26092
|
const [metaRaw] = await Promise.all([
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26128
|
-
|
|
26093
|
+
import_promises20.default.readFile(metaPath, "utf8"),
|
|
26094
|
+
import_promises20.default.access(holdoutTrainPath),
|
|
26095
|
+
import_promises20.default.access(holdoutTestPath),
|
|
26096
|
+
import_promises20.default.access(prodPath),
|
|
26129
26097
|
...walkForwardFoldDefs.flatMap((entry) => [
|
|
26130
|
-
|
|
26131
|
-
|
|
26098
|
+
import_promises20.default.access(entry.trainPath),
|
|
26099
|
+
import_promises20.default.access(entry.testPath)
|
|
26132
26100
|
])
|
|
26133
26101
|
]);
|
|
26134
26102
|
const meta2 = JSON.parse(metaRaw);
|
|
@@ -26495,7 +26463,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26495
26463
|
},
|
|
26496
26464
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26497
26465
|
};
|
|
26498
|
-
await
|
|
26466
|
+
await import_promises20.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
|
|
26499
26467
|
`, "utf8");
|
|
26500
26468
|
return {
|
|
26501
26469
|
holdoutTrainPath,
|
|
@@ -26522,7 +26490,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26522
26490
|
}
|
|
26523
26491
|
};
|
|
26524
26492
|
};
|
|
26525
|
-
|
|
26493
|
+
main32 = async () => {
|
|
26526
26494
|
const selectedFromCli = parseStrategy(flags22.strategy);
|
|
26527
26495
|
const selected = selectedFromCli ?? await selectStrategy();
|
|
26528
26496
|
const envModelType = (process.env.ML_MODEL_TYPE ?? "random_forest").trim().toLowerCase();
|
|
@@ -26553,7 +26521,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26553
26521
|
process.exit(1);
|
|
26554
26522
|
}
|
|
26555
26523
|
try {
|
|
26556
|
-
const inputStat = await
|
|
26524
|
+
const inputStat = await import_promises20.default.stat(inputPath);
|
|
26557
26525
|
const totalInputBytes = inputStat.size;
|
|
26558
26526
|
const autoIncrementalThresholdGb = asInt7(
|
|
26559
26527
|
process.env.ML_TRAIN_INCREMENTAL_THRESHOLD_GB,
|
|
@@ -26742,7 +26710,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26742
26710
|
const modelDir = import_path10.default.join(modelDirRoot, "models");
|
|
26743
26711
|
let savedModels = [];
|
|
26744
26712
|
try {
|
|
26745
|
-
const entries = await
|
|
26713
|
+
const entries = await import_promises20.default.readdir(modelDir, { withFileTypes: true });
|
|
26746
26714
|
savedModels = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter(
|
|
26747
26715
|
(name) => name === `${selected}.joblib` || /^.+\.model\d+\.joblib$/.test(name)
|
|
26748
26716
|
).filter((name) => name.startsWith(`${selected}.`)).sort();
|
|
@@ -26764,7 +26732,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26764
26732
|
process.exitCode = finalCode;
|
|
26765
26733
|
} finally {
|
|
26766
26734
|
for (const file of cleanupFiles) {
|
|
26767
|
-
await
|
|
26735
|
+
await import_promises20.default.rm(file, { force: true });
|
|
26768
26736
|
}
|
|
26769
26737
|
}
|
|
26770
26738
|
process.exit(process.exitCode ?? 1);
|
|
@@ -26786,7 +26754,7 @@ __export(researchAuto_exports, {
|
|
|
26786
26754
|
isProcessAlive: () => isProcessAlive,
|
|
26787
26755
|
listMergedFiles: () => listMergedFiles3,
|
|
26788
26756
|
listRuntimeStrategyNames: () => listRuntimeStrategyNames,
|
|
26789
|
-
main: () =>
|
|
26757
|
+
main: () => main33,
|
|
26790
26758
|
parseJsonOutput: () => parseJsonOutput,
|
|
26791
26759
|
releaseResearchAutoLock: () => releaseResearchAutoLock,
|
|
26792
26760
|
resolveHeapMbFromEnv: () => resolveHeapMbFromEnv,
|
|
@@ -26796,20 +26764,20 @@ __export(researchAuto_exports, {
|
|
|
26796
26764
|
toStrategyConfigGrid: () => toStrategyConfigGrid2,
|
|
26797
26765
|
trimTextTail: () => trimTextTail2
|
|
26798
26766
|
});
|
|
26799
|
-
var import_args25, import_chalk40,
|
|
26767
|
+
var import_args25, import_chalk40, import_node_child_process5, import_promises21, import_node_os2, import_node_path14, import_constants18, import_ai8, import_logger6, import_redis16, import_registry4, flags23, projectRoot8, dotenvPath, getResearchAutoLockPath, readResearchAutoLock, isProcessAlive, acquireResearchAutoLock, releaseResearchAutoLock, resolvePositiveInteger, resolveHeapMbFromEnv, buildNodeOptions, RESEARCH_AUTO_PARENT_HEAP_MB, RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB, RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB, RESEARCH_AUTO_AGENT_PARENT_HEAP_MB, trimTextTail2, escapeHtml3, createEmptySteps, saveRun, listMergedFiles3, getBacktestResultsPrefix, listRuntimeStrategyNames, toStrategyConfigGrid2, formatMskDateTime, buildTelegramReport, runCliCommand, resolveTarget, parseJsonOutput, logResearch, executeNonBlockingStep, main33;
|
|
26800
26768
|
var init_researchAuto = __esm({
|
|
26801
26769
|
"src/scripts/researchAuto.ts"() {
|
|
26802
26770
|
"use strict";
|
|
26803
26771
|
import_args25 = __toESM(require("args"));
|
|
26804
26772
|
import_chalk40 = __toESM(require("chalk"));
|
|
26805
|
-
|
|
26806
|
-
|
|
26773
|
+
import_node_child_process5 = require("child_process");
|
|
26774
|
+
import_promises21 = __toESM(require("fs/promises"));
|
|
26807
26775
|
import_node_os2 = __toESM(require("os"));
|
|
26808
26776
|
import_node_path14 = __toESM(require("path"));
|
|
26809
26777
|
import_constants18 = require("@tradejs/core/constants");
|
|
26810
26778
|
import_ai8 = require("@tradejs/infra/ai");
|
|
26811
26779
|
import_logger6 = require("@tradejs/infra/logger");
|
|
26812
|
-
|
|
26780
|
+
import_redis16 = require("@tradejs/infra/redis");
|
|
26813
26781
|
import_registry4 = require("@tradejs/node/registry");
|
|
26814
26782
|
init_runtimeRedis();
|
|
26815
26783
|
init_runtimeStrategyBacktest();
|
|
@@ -26850,7 +26818,7 @@ var init_researchAuto = __esm({
|
|
|
26850
26818
|
);
|
|
26851
26819
|
readResearchAutoLock = async (lockPath) => {
|
|
26852
26820
|
try {
|
|
26853
|
-
const raw = await
|
|
26821
|
+
const raw = await import_promises21.default.readFile(lockPath, "utf8");
|
|
26854
26822
|
return JSON.parse(raw);
|
|
26855
26823
|
} catch {
|
|
26856
26824
|
return null;
|
|
@@ -26885,9 +26853,9 @@ var init_researchAuto = __esm({
|
|
|
26885
26853
|
startedAt,
|
|
26886
26854
|
argv: [...process.argv]
|
|
26887
26855
|
};
|
|
26888
|
-
await
|
|
26856
|
+
await import_promises21.default.mkdir(import_node_path14.default.dirname(lockPath), { recursive: true });
|
|
26889
26857
|
const writeLock = async () => {
|
|
26890
|
-
await
|
|
26858
|
+
await import_promises21.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
|
|
26891
26859
|
flag: "wx"
|
|
26892
26860
|
});
|
|
26893
26861
|
};
|
|
@@ -26906,7 +26874,7 @@ var init_researchAuto = __esm({
|
|
|
26906
26874
|
`research:auto is already running for user ${userName3} (runId=${existingLock.runId}, strategy=${existingLock.strategy}, pid=${existingLock.pid}, ppid=${existingLock.ppid}, startedAt=${existingLock.startedAt}, host=${existingLock.hostname})`
|
|
26907
26875
|
);
|
|
26908
26876
|
}
|
|
26909
|
-
await
|
|
26877
|
+
await import_promises21.default.unlink(lockPath).catch(() => void 0);
|
|
26910
26878
|
await writeLock();
|
|
26911
26879
|
return lockPath;
|
|
26912
26880
|
};
|
|
@@ -26918,7 +26886,7 @@ var init_researchAuto = __esm({
|
|
|
26918
26886
|
if (existingLock && existingLock.pid !== process.pid) {
|
|
26919
26887
|
return;
|
|
26920
26888
|
}
|
|
26921
|
-
await
|
|
26889
|
+
await import_promises21.default.unlink(lockPath).catch(() => void 0);
|
|
26922
26890
|
};
|
|
26923
26891
|
resolvePositiveInteger = (value, fallback) => {
|
|
26924
26892
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
@@ -27011,16 +26979,16 @@ var init_researchAuto = __esm({
|
|
|
27011
26979
|
}
|
|
27012
26980
|
});
|
|
27013
26981
|
saveRun = async (run) => {
|
|
27014
|
-
await (0,
|
|
26982
|
+
await (0, import_redis16.setData)(import_redis16.redisKeys.researchRun(run.userName, run.runId), run, {
|
|
27015
26983
|
expire: import_constants18.TTL_1M
|
|
27016
26984
|
});
|
|
27017
|
-
await (0,
|
|
26985
|
+
await (0, import_redis16.setData)(import_redis16.redisKeys.researchLatestRun(run.userName, run.strategy), run, {
|
|
27018
26986
|
expire: import_constants18.TTL_1M
|
|
27019
26987
|
});
|
|
27020
26988
|
};
|
|
27021
26989
|
listMergedFiles3 = async (outDir, strategyName) => {
|
|
27022
26990
|
try {
|
|
27023
|
-
const entries = await
|
|
26991
|
+
const entries = await import_promises21.default.readdir(outDir);
|
|
27024
26992
|
const prefix = `ai-dataset-${(0, import_ai8.toFileToken)(strategyName)}-merged-`;
|
|
27025
26993
|
return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).sort().map((name) => import_node_path14.default.join(outDir, name));
|
|
27026
26994
|
} catch {
|
|
@@ -27154,7 +27122,7 @@ var init_researchAuto = __esm({
|
|
|
27154
27122
|
} : {}
|
|
27155
27123
|
};
|
|
27156
27124
|
return new Promise((resolve, reject) => {
|
|
27157
|
-
const child = (0,
|
|
27125
|
+
const child = (0, import_node_child_process5.spawn)(
|
|
27158
27126
|
process.execPath,
|
|
27159
27127
|
[import_node_path14.default.resolve(process.argv[1]), params.command, ...params.args],
|
|
27160
27128
|
{
|
|
@@ -27244,8 +27212,8 @@ var init_researchAuto = __esm({
|
|
|
27244
27212
|
const candidates = [];
|
|
27245
27213
|
for (const strategy of availableStrategies) {
|
|
27246
27214
|
const config2 = `${strategy}:research`;
|
|
27247
|
-
const latestRun = await (0,
|
|
27248
|
-
|
|
27215
|
+
const latestRun = await (0, import_redis16.getData)(
|
|
27216
|
+
import_redis16.redisKeys.researchLatestRun(userName3, strategy),
|
|
27249
27217
|
null
|
|
27250
27218
|
);
|
|
27251
27219
|
const lastFinishedAt = latestRun?.finishedAt ? Date.parse(latestRun.finishedAt) : 0;
|
|
@@ -27321,7 +27289,7 @@ var init_researchAuto = __esm({
|
|
|
27321
27289
|
);
|
|
27322
27290
|
return result;
|
|
27323
27291
|
};
|
|
27324
|
-
|
|
27292
|
+
main33 = async () => {
|
|
27325
27293
|
resolveRequiredResearchRoots({ projectRoot: projectRoot8 });
|
|
27326
27294
|
const userName3 = String(flags23.user || "root").trim() || "root";
|
|
27327
27295
|
const connector = String(flags23.connector || "bybit").trim() || "bybit";
|
|
@@ -27424,13 +27392,13 @@ var init_researchAuto = __esm({
|
|
|
27424
27392
|
startedAt
|
|
27425
27393
|
};
|
|
27426
27394
|
await saveRun(run);
|
|
27427
|
-
const strategyConfigKey =
|
|
27395
|
+
const strategyConfigKey = import_redis16.redisKeys.strategyConfig(
|
|
27428
27396
|
userName3,
|
|
27429
27397
|
target.strategy
|
|
27430
27398
|
);
|
|
27431
|
-
const backtestConfigKey =
|
|
27399
|
+
const backtestConfigKey = import_redis16.redisKeys.backtestConfig(userName3, target.config);
|
|
27432
27400
|
const defaults = await (0, import_registry4.getStrategyDefaults)(target.strategy, projectRoot8) || {};
|
|
27433
|
-
const userStrategyConfig = await (0,
|
|
27401
|
+
const userStrategyConfig = await (0, import_redis16.getData)(
|
|
27434
27402
|
strategyConfigKey,
|
|
27435
27403
|
{}
|
|
27436
27404
|
);
|
|
@@ -27444,7 +27412,7 @@ var init_researchAuto = __esm({
|
|
|
27444
27412
|
);
|
|
27445
27413
|
}
|
|
27446
27414
|
const backtestConfig = toStrategyConfigGrid2(strategyConfig);
|
|
27447
|
-
await (0,
|
|
27415
|
+
await (0, import_redis16.setData)(backtestConfigKey, backtestConfig, { expire: 0 });
|
|
27448
27416
|
logResearch(
|
|
27449
27417
|
`stored backtest config at ${backtestConfigKey} with ${Object.keys(strategyConfig).length} top-level fields`
|
|
27450
27418
|
);
|
|
@@ -27484,7 +27452,7 @@ var init_researchAuto = __esm({
|
|
|
27484
27452
|
`resource knobs: researchAutoHeapMb=${RESEARCH_AUTO_PARENT_HEAP_MB}, backtestParentHeapMb=${RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB}, aiTrainParentHeapMb=${RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB}, agentParentHeapMb=${RESEARCH_AUTO_AGENT_PARENT_HEAP_MB}, backtestWorkerHeapMb=${process.env.BACKTEST_WORKER_HEAP_MB || "auto"}, backtestMaxParallel=${process.env.BACKTEST_MAX_PARALLEL || "auto"}, klineConcurrency=${process.env.KLINE_CONCURRENCY_LIMIT || "default"}`
|
|
27485
27453
|
);
|
|
27486
27454
|
const backtestKeysBefore = new Set(
|
|
27487
|
-
await (0,
|
|
27455
|
+
await (0, import_redis16.getKeys)(getBacktestResultsPrefix(userName3, target.config))
|
|
27488
27456
|
);
|
|
27489
27457
|
const aiFilesBefore = new Set(
|
|
27490
27458
|
await listMergedFiles3(outDir, target.strategy)
|
|
@@ -27546,14 +27514,14 @@ var init_researchAuto = __esm({
|
|
|
27546
27514
|
captureMode: "full"
|
|
27547
27515
|
}
|
|
27548
27516
|
);
|
|
27549
|
-
const backtestKeysAfter = await (0,
|
|
27517
|
+
const backtestKeysAfter = await (0, import_redis16.getKeys)(
|
|
27550
27518
|
getBacktestResultsPrefix(userName3, target.config)
|
|
27551
27519
|
);
|
|
27552
27520
|
const newBacktestKeys = backtestKeysAfter.filter((key) => !backtestKeysBefore.has(key)).sort();
|
|
27553
27521
|
const backtestResultKey = newBacktestKeys[newBacktestKeys.length - 1] || backtestKeysAfter.sort().at(-1);
|
|
27554
27522
|
if (backtestResultKey) {
|
|
27555
27523
|
logResearch(`detected backtest result key ${backtestResultKey}`);
|
|
27556
|
-
const backtestResult = await (0,
|
|
27524
|
+
const backtestResult = await (0, import_redis16.getData)(backtestResultKey, null);
|
|
27557
27525
|
run.artifacts.backtestResultKey = backtestResultKey;
|
|
27558
27526
|
run.artifacts.backtestResult = backtestResult ? {
|
|
27559
27527
|
finishedAt: backtestResult.finishedAt,
|
|
@@ -27688,13 +27656,13 @@ var init_types = __esm({
|
|
|
27688
27656
|
function assert(condition, message) {
|
|
27689
27657
|
if (!condition) throw new Error(`Invalid core research spec: ${message}`);
|
|
27690
27658
|
}
|
|
27691
|
-
var
|
|
27659
|
+
var import_node_crypto10, import_node_fs3, import_promises22, import_backtest5, import_node_path15, RESEARCH_ID_RE, SHA256_RE, canonicalJson, sha256Text, sha256Json, sha256File, assertFinite, validateCoreResearchSpec, loadCoreResearchSpec, resolveCoreResearchPaths, writeJsonAtomic, buildLedgerRecordHash, readCoreResearchLedger, verifyCoreResearchLedger, appendCoreResearchLedger, validateCoreResearchParentLineage, prepareCoreResearch, verifyCoreResearchArtifacts, scanCoreResearchStages, writeCoreResearchStageIndex;
|
|
27692
27660
|
var init_io = __esm({
|
|
27693
27661
|
"src/lib/coreResearch/io.ts"() {
|
|
27694
27662
|
"use strict";
|
|
27695
|
-
|
|
27663
|
+
import_node_crypto10 = require("crypto");
|
|
27696
27664
|
import_node_fs3 = require("fs");
|
|
27697
|
-
|
|
27665
|
+
import_promises22 = __toESM(require("fs/promises"));
|
|
27698
27666
|
import_backtest5 = require("@tradejs/core/backtest");
|
|
27699
27667
|
import_node_path15 = __toESM(require("path"));
|
|
27700
27668
|
init_types();
|
|
@@ -27712,10 +27680,10 @@ var init_io = __esm({
|
|
|
27712
27680
|
};
|
|
27713
27681
|
return JSON.stringify(normalize(value));
|
|
27714
27682
|
};
|
|
27715
|
-
sha256Text = (value) => (0,
|
|
27683
|
+
sha256Text = (value) => (0, import_node_crypto10.createHash)("sha256").update(value).digest("hex");
|
|
27716
27684
|
sha256Json = (value) => sha256Text(canonicalJson(value));
|
|
27717
27685
|
sha256File = async (filePath) => {
|
|
27718
|
-
const hash = (0,
|
|
27686
|
+
const hash = (0, import_node_crypto10.createHash)("sha256");
|
|
27719
27687
|
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
27720
27688
|
for await (const chunk of input) hash.update(chunk);
|
|
27721
27689
|
return hash.digest("hex");
|
|
@@ -27956,7 +27924,7 @@ var init_io = __esm({
|
|
|
27956
27924
|
};
|
|
27957
27925
|
loadCoreResearchSpec = async (specPath) => {
|
|
27958
27926
|
const resolvedPath = import_node_path15.default.resolve(specPath);
|
|
27959
|
-
const parsed = JSON.parse(await
|
|
27927
|
+
const parsed = JSON.parse(await import_promises22.default.readFile(resolvedPath, "utf8"));
|
|
27960
27928
|
const spec = validateCoreResearchSpec(parsed);
|
|
27961
27929
|
return { resolvedPath, spec, specSha256: sha256Json(spec) };
|
|
27962
27930
|
};
|
|
@@ -27978,17 +27946,17 @@ var init_io = __esm({
|
|
|
27978
27946
|
};
|
|
27979
27947
|
};
|
|
27980
27948
|
writeJsonAtomic = async (filePath, value) => {
|
|
27981
|
-
await
|
|
27949
|
+
await import_promises22.default.mkdir(import_node_path15.default.dirname(filePath), { recursive: true });
|
|
27982
27950
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
27983
|
-
await
|
|
27951
|
+
await import_promises22.default.writeFile(temporaryPath, `${canonicalJson(value)}
|
|
27984
27952
|
`, "utf8");
|
|
27985
|
-
await
|
|
27953
|
+
await import_promises22.default.rename(temporaryPath, filePath);
|
|
27986
27954
|
};
|
|
27987
27955
|
buildLedgerRecordHash = (record) => sha256Json(record);
|
|
27988
27956
|
readCoreResearchLedger = async (ledgerPath) => {
|
|
27989
27957
|
let text = "";
|
|
27990
27958
|
try {
|
|
27991
|
-
text = await
|
|
27959
|
+
text = await import_promises22.default.readFile(ledgerPath, "utf8");
|
|
27992
27960
|
} catch (error) {
|
|
27993
27961
|
if (error.code === "ENOENT") return [];
|
|
27994
27962
|
throw error;
|
|
@@ -28025,11 +27993,11 @@ var init_io = __esm({
|
|
|
28025
27993
|
};
|
|
28026
27994
|
appendCoreResearchLedger = async (params) => {
|
|
28027
27995
|
const { ledgerPath } = params;
|
|
28028
|
-
await
|
|
27996
|
+
await import_promises22.default.mkdir(import_node_path15.default.dirname(ledgerPath), { recursive: true });
|
|
28029
27997
|
const lockPath = `${ledgerPath}.lock`;
|
|
28030
27998
|
let lock = null;
|
|
28031
27999
|
try {
|
|
28032
|
-
lock = await
|
|
28000
|
+
lock = await import_promises22.default.open(lockPath, "wx");
|
|
28033
28001
|
const records = await readCoreResearchLedger(ledgerPath);
|
|
28034
28002
|
const verified = verifyCoreResearchLedger(records);
|
|
28035
28003
|
const payload = {
|
|
@@ -28048,7 +28016,7 @@ var init_io = __esm({
|
|
|
28048
28016
|
...payload,
|
|
28049
28017
|
recordHash: buildLedgerRecordHash(payload)
|
|
28050
28018
|
};
|
|
28051
|
-
await
|
|
28019
|
+
await import_promises22.default.appendFile(ledgerPath, `${canonicalJson(record)}
|
|
28052
28020
|
`, "utf8");
|
|
28053
28021
|
return record;
|
|
28054
28022
|
} catch (error) {
|
|
@@ -28058,7 +28026,7 @@ var init_io = __esm({
|
|
|
28058
28026
|
throw error;
|
|
28059
28027
|
} finally {
|
|
28060
28028
|
await lock?.close();
|
|
28061
|
-
await
|
|
28029
|
+
await import_promises22.default.rm(lockPath, { force: true });
|
|
28062
28030
|
}
|
|
28063
28031
|
};
|
|
28064
28032
|
validateCoreResearchParentLineage = async (spec) => {
|
|
@@ -28069,9 +28037,9 @@ var init_io = __esm({
|
|
|
28069
28037
|
for (const parentResearchId of spec.parentResearchIds ?? []) {
|
|
28070
28038
|
const parentDir = import_node_path15.default.join(rootDir, parentResearchId);
|
|
28071
28039
|
const [parentSpec, parentManifest, parentResult] = await Promise.all([
|
|
28072
|
-
|
|
28073
|
-
|
|
28074
|
-
|
|
28040
|
+
import_promises22.default.readFile(import_node_path15.default.join(parentDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28041
|
+
import_promises22.default.readFile(import_node_path15.default.join(parentDir, "manifest.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28042
|
+
import_promises22.default.readFile(import_node_path15.default.join(parentDir, "result.json"), "utf8").then((text) => JSON.parse(text))
|
|
28075
28043
|
]);
|
|
28076
28044
|
validateCoreResearchSpec(parentSpec);
|
|
28077
28045
|
if (parentManifest.status !== "completed") {
|
|
@@ -28118,12 +28086,12 @@ var init_io = __esm({
|
|
|
28118
28086
|
await validateCoreResearchParentLineage(spec);
|
|
28119
28087
|
const specSha256 = sha256Json(spec);
|
|
28120
28088
|
const paths = resolveCoreResearchPaths(spec);
|
|
28121
|
-
await
|
|
28089
|
+
await import_promises22.default.mkdir(paths.researchDir, { recursive: true });
|
|
28122
28090
|
let existing = null;
|
|
28123
28091
|
let existingManifest = null;
|
|
28124
28092
|
try {
|
|
28125
28093
|
existing = JSON.parse(
|
|
28126
|
-
await
|
|
28094
|
+
await import_promises22.default.readFile(paths.specPath, "utf8")
|
|
28127
28095
|
);
|
|
28128
28096
|
} catch (error) {
|
|
28129
28097
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -28136,7 +28104,7 @@ var init_io = __esm({
|
|
|
28136
28104
|
if (existing) {
|
|
28137
28105
|
try {
|
|
28138
28106
|
existingManifest = JSON.parse(
|
|
28139
|
-
await
|
|
28107
|
+
await import_promises22.default.readFile(paths.manifestPath, "utf8")
|
|
28140
28108
|
);
|
|
28141
28109
|
} catch (error) {
|
|
28142
28110
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -28175,7 +28143,7 @@ var init_io = __esm({
|
|
|
28175
28143
|
verifyCoreResearchArtifacts = async (spec) => {
|
|
28176
28144
|
const paths = resolveCoreResearchPaths(spec);
|
|
28177
28145
|
const manifest = JSON.parse(
|
|
28178
|
-
await
|
|
28146
|
+
await import_promises22.default.readFile(paths.manifestPath, "utf8")
|
|
28179
28147
|
);
|
|
28180
28148
|
if (manifest.specSha256 !== sha256Json(spec)) {
|
|
28181
28149
|
throw new Error("Manifest spec hash does not match the supplied spec");
|
|
@@ -28203,7 +28171,7 @@ var init_io = __esm({
|
|
|
28203
28171
|
const resolvedRoot = import_node_path15.default.resolve(rootDir);
|
|
28204
28172
|
let entries = [];
|
|
28205
28173
|
try {
|
|
28206
|
-
entries = await
|
|
28174
|
+
entries = await import_promises22.default.readdir(resolvedRoot);
|
|
28207
28175
|
} catch (error) {
|
|
28208
28176
|
if (error.code === "ENOENT") {
|
|
28209
28177
|
return {
|
|
@@ -28219,14 +28187,14 @@ var init_io = __esm({
|
|
|
28219
28187
|
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
28220
28188
|
)) {
|
|
28221
28189
|
const researchDir = import_node_path15.default.join(resolvedRoot, entry);
|
|
28222
|
-
const stats = await
|
|
28190
|
+
const stats = await import_promises22.default.stat(researchDir);
|
|
28223
28191
|
if (!stats.isDirectory()) continue;
|
|
28224
28192
|
let spec;
|
|
28225
28193
|
let manifest;
|
|
28226
28194
|
try {
|
|
28227
28195
|
[spec, manifest] = await Promise.all([
|
|
28228
|
-
|
|
28229
|
-
|
|
28196
|
+
import_promises22.default.readFile(import_node_path15.default.join(researchDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28197
|
+
import_promises22.default.readFile(import_node_path15.default.join(researchDir, "manifest.json"), "utf8").then((text) => JSON.parse(text))
|
|
28230
28198
|
]);
|
|
28231
28199
|
} catch (error) {
|
|
28232
28200
|
if (error.code === "ENOENT") continue;
|
|
@@ -28236,7 +28204,7 @@ var init_io = __esm({
|
|
|
28236
28204
|
if (manifest.specSha256 !== sha256Json(spec)) {
|
|
28237
28205
|
throw new Error(`Stage index found a spec hash mismatch for ${entry}`);
|
|
28238
28206
|
}
|
|
28239
|
-
const result = manifest.status === "completed" ? await
|
|
28207
|
+
const result = manifest.status === "completed" ? await import_promises22.default.readFile(import_node_path15.default.join(researchDir, "result.json"), "utf8").then((text) => JSON.parse(text)) : null;
|
|
28240
28208
|
familyByResearch.set(spec.researchId, spec.hypothesis.family);
|
|
28241
28209
|
experiments.push({
|
|
28242
28210
|
researchId: spec.researchId,
|
|
@@ -28291,13 +28259,13 @@ var init_io = __esm({
|
|
|
28291
28259
|
});
|
|
28292
28260
|
|
|
28293
28261
|
// src/lib/coreResearch/artifacts.ts
|
|
28294
|
-
var import_node_fs4, import_node_events,
|
|
28262
|
+
var import_node_fs4, import_node_events, import_promises23, import_node_path16, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades;
|
|
28295
28263
|
var init_artifacts = __esm({
|
|
28296
28264
|
"src/lib/coreResearch/artifacts.ts"() {
|
|
28297
28265
|
"use strict";
|
|
28298
28266
|
import_node_fs4 = require("fs");
|
|
28299
28267
|
import_node_events = require("events");
|
|
28300
|
-
|
|
28268
|
+
import_promises23 = __toESM(require("fs/promises"));
|
|
28301
28269
|
import_node_path16 = __toESM(require("path"));
|
|
28302
28270
|
init_io();
|
|
28303
28271
|
csv = (value) => {
|
|
@@ -28312,7 +28280,7 @@ var init_artifacts = __esm({
|
|
|
28312
28280
|
await (0, import_node_events.once)(output, "close");
|
|
28313
28281
|
};
|
|
28314
28282
|
writeCoreResearchMatches = async (params) => {
|
|
28315
|
-
await
|
|
28283
|
+
await import_promises23.default.mkdir(import_node_path16.default.dirname(params.filePath), { recursive: true });
|
|
28316
28284
|
const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
|
|
28317
28285
|
await writeLine(
|
|
28318
28286
|
output,
|
|
@@ -28353,7 +28321,7 @@ var init_artifacts = __esm({
|
|
|
28353
28321
|
await closeOutput(output);
|
|
28354
28322
|
};
|
|
28355
28323
|
writeCoreResearchTrades = async (params) => {
|
|
28356
|
-
await
|
|
28324
|
+
await import_promises23.default.mkdir(import_node_path16.default.dirname(params.filePath), { recursive: true });
|
|
28357
28325
|
const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
|
|
28358
28326
|
for (const variant of params.variants) {
|
|
28359
28327
|
for (const trade of variant.trades) {
|
|
@@ -28593,14 +28561,14 @@ var init_rules = __esm({
|
|
|
28593
28561
|
});
|
|
28594
28562
|
|
|
28595
28563
|
// src/lib/coreResearch/statistics.ts
|
|
28596
|
-
var
|
|
28564
|
+
var import_node_crypto11, createSeededRandom, percentile, calendarClusterBootstrap, applyHolmCorrection, inverseNormalCdf, erf, normalCdf, deflatedSharpeDiagnostic, combinations, probabilityOfBacktestOverfitting;
|
|
28597
28565
|
var init_statistics = __esm({
|
|
28598
28566
|
"src/lib/coreResearch/statistics.ts"() {
|
|
28599
28567
|
"use strict";
|
|
28600
|
-
|
|
28568
|
+
import_node_crypto11 = require("crypto");
|
|
28601
28569
|
init_metrics();
|
|
28602
28570
|
createSeededRandom = (seedText) => {
|
|
28603
|
-
const digest = (0,
|
|
28571
|
+
const digest = (0, import_node_crypto11.createHash)("sha256").update(seedText).digest();
|
|
28604
28572
|
let state = digest.readUInt32LE(0) || 1;
|
|
28605
28573
|
return () => {
|
|
28606
28574
|
state ^= state << 13;
|
|
@@ -29066,11 +29034,11 @@ var init_comparison = __esm({
|
|
|
29066
29034
|
});
|
|
29067
29035
|
|
|
29068
29036
|
// src/lib/coreResearch/dataset.ts
|
|
29069
|
-
var
|
|
29037
|
+
var import_node_crypto12, import_node_fs5, import_node_path17, import_node_readline2, asRecord4, finiteNumber4, normalizeDirection, findStrategySetupIdentity, classifyBreadth, classifyDerivatives, resolveCoreResearchRegime, normalizeCompletedTrade, completedTradeIdentity, positionCycleIdentity, sumBy, weightedPrice, aggregatePositionCycles, compareText, compareTrades, readCoreResearchVariant;
|
|
29070
29038
|
var init_dataset2 = __esm({
|
|
29071
29039
|
"src/lib/coreResearch/dataset.ts"() {
|
|
29072
29040
|
"use strict";
|
|
29073
|
-
|
|
29041
|
+
import_node_crypto12 = require("crypto");
|
|
29074
29042
|
import_node_fs5 = require("fs");
|
|
29075
29043
|
import_node_path17 = __toESM(require("path"));
|
|
29076
29044
|
import_node_readline2 = __toESM(require("readline"));
|
|
@@ -29284,7 +29252,7 @@ var init_dataset2 = __esm({
|
|
|
29284
29252
|
for (const inputPath of variant.files) {
|
|
29285
29253
|
const filePath = import_node_path17.default.resolve(inputPath);
|
|
29286
29254
|
const input = (0, import_node_fs5.createReadStream)(filePath);
|
|
29287
|
-
const hash = (0,
|
|
29255
|
+
const hash = (0, import_node_crypto12.createHash)("sha256");
|
|
29288
29256
|
input.on("data", (chunk) => hash.update(chunk));
|
|
29289
29257
|
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
29290
29258
|
const fileTrades = [];
|
|
@@ -29774,18 +29742,18 @@ var init_selection = __esm({
|
|
|
29774
29742
|
});
|
|
29775
29743
|
|
|
29776
29744
|
// src/lib/coreResearch/trace.ts
|
|
29777
|
-
var
|
|
29745
|
+
var import_promises24, import_node_path18, summarizeCoreResearchTrace;
|
|
29778
29746
|
var init_trace = __esm({
|
|
29779
29747
|
"src/lib/coreResearch/trace.ts"() {
|
|
29780
29748
|
"use strict";
|
|
29781
|
-
|
|
29749
|
+
import_promises24 = __toESM(require("fs/promises"));
|
|
29782
29750
|
import_node_path18 = __toESM(require("path"));
|
|
29783
29751
|
summarizeCoreResearchTrace = async (filePaths = []) => {
|
|
29784
29752
|
const events = {};
|
|
29785
29753
|
const skipCounts = {};
|
|
29786
29754
|
for (const inputPath of filePaths) {
|
|
29787
29755
|
const filePath = import_node_path18.default.resolve(inputPath);
|
|
29788
|
-
const text = await
|
|
29756
|
+
const text = await import_promises24.default.readFile(filePath, "utf8");
|
|
29789
29757
|
for (const [index, line] of text.split("\n").entries()) {
|
|
29790
29758
|
if (!line.trim()) continue;
|
|
29791
29759
|
let event;
|
|
@@ -29817,14 +29785,14 @@ var init_trace = __esm({
|
|
|
29817
29785
|
});
|
|
29818
29786
|
|
|
29819
29787
|
// src/lib/coreResearch/orchestrator.ts
|
|
29820
|
-
var
|
|
29788
|
+
var import_promises25, import_node_path19, import_node_child_process6, import_node_crypto13, import_coreResearch, summarizeSupplementalFiles, analyzeCoreResearchPrepared, analyzeCoreResearch, createCoreResearchSpecTemplate, runCommand2, commandValue, commandHas, validateCoreResearchRunCommand, runCoreResearch;
|
|
29821
29789
|
var init_orchestrator = __esm({
|
|
29822
29790
|
"src/lib/coreResearch/orchestrator.ts"() {
|
|
29823
29791
|
"use strict";
|
|
29824
|
-
|
|
29792
|
+
import_promises25 = __toESM(require("fs/promises"));
|
|
29825
29793
|
import_node_path19 = __toESM(require("path"));
|
|
29826
|
-
|
|
29827
|
-
|
|
29794
|
+
import_node_child_process6 = require("child_process");
|
|
29795
|
+
import_node_crypto13 = require("crypto");
|
|
29828
29796
|
import_coreResearch = require("@tradejs/infra/coreResearch");
|
|
29829
29797
|
init_artifacts();
|
|
29830
29798
|
init_io();
|
|
@@ -30113,7 +30081,7 @@ var init_orchestrator = __esm({
|
|
|
30113
30081
|
const tradesByVariant = new Map(
|
|
30114
30082
|
windowed.map((entry) => [entry.variant.id, entry.trades])
|
|
30115
30083
|
);
|
|
30116
|
-
await
|
|
30084
|
+
await import_promises25.default.writeFile(
|
|
30117
30085
|
paths.reportPath,
|
|
30118
30086
|
buildCoreResearchHtml({ spec, result, tradesByVariant }),
|
|
30119
30087
|
"utf8"
|
|
@@ -30133,7 +30101,7 @@ var init_orchestrator = __esm({
|
|
|
30133
30101
|
if (error.code !== "ENOENT") throw error;
|
|
30134
30102
|
}
|
|
30135
30103
|
try {
|
|
30136
|
-
for (const name of await
|
|
30104
|
+
for (const name of await import_promises25.default.readdir(paths.runLogDir)) {
|
|
30137
30105
|
if (!name.endsWith(".log")) continue;
|
|
30138
30106
|
artifactHashes[`runs/${name}`] = await sha256File(
|
|
30139
30107
|
import_node_path19.default.join(paths.runLogDir, name)
|
|
@@ -30199,12 +30167,12 @@ var init_orchestrator = __esm({
|
|
|
30199
30167
|
).replace(/\\/g, "/");
|
|
30200
30168
|
const lineage = (() => {
|
|
30201
30169
|
try {
|
|
30202
|
-
const gitSha = (0,
|
|
30170
|
+
const gitSha = (0, import_node_child_process6.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
30203
30171
|
cwd: params.sourceRepositoryRoot,
|
|
30204
30172
|
encoding: "utf8",
|
|
30205
30173
|
stdio: ["ignore", "pipe", "ignore"]
|
|
30206
30174
|
}).trim();
|
|
30207
|
-
const dirtyDiff = (0,
|
|
30175
|
+
const dirtyDiff = (0, import_node_child_process6.execFileSync)(
|
|
30208
30176
|
"git",
|
|
30209
30177
|
["diff", "--binary", "--no-ext-diff", "HEAD"],
|
|
30210
30178
|
{
|
|
@@ -30213,7 +30181,7 @@ var init_orchestrator = __esm({
|
|
|
30213
30181
|
stdio: ["ignore", "pipe", "ignore"]
|
|
30214
30182
|
}
|
|
30215
30183
|
);
|
|
30216
|
-
const sourceRepository = (0,
|
|
30184
|
+
const sourceRepository = (0, import_node_child_process6.execFileSync)(
|
|
30217
30185
|
"git",
|
|
30218
30186
|
["remote", "get-url", "origin"],
|
|
30219
30187
|
{
|
|
@@ -30226,7 +30194,7 @@ var init_orchestrator = __esm({
|
|
|
30226
30194
|
gitSha,
|
|
30227
30195
|
...sourceRepository ? { sourceRepository } : {},
|
|
30228
30196
|
...dirtyDiff ? {
|
|
30229
|
-
dirtyDiffSha256: (0,
|
|
30197
|
+
dirtyDiffSha256: (0, import_node_crypto13.createHash)("sha256").update(dirtyDiff).digest("hex")
|
|
30230
30198
|
} : {}
|
|
30231
30199
|
};
|
|
30232
30200
|
} catch {
|
|
@@ -30333,9 +30301,9 @@ var init_orchestrator = __esm({
|
|
|
30333
30301
|
};
|
|
30334
30302
|
runCommand2 = async (params) => {
|
|
30335
30303
|
if (!params.command.length) throw new Error("Cannot run an empty command");
|
|
30336
|
-
await
|
|
30304
|
+
await import_promises25.default.mkdir(import_node_path19.default.dirname(params.logPath), { recursive: true });
|
|
30337
30305
|
const chunks = [];
|
|
30338
|
-
const child = (0,
|
|
30306
|
+
const child = (0, import_node_child_process6.spawn)(params.command[0], params.command.slice(1), {
|
|
30339
30307
|
cwd: params.cwd,
|
|
30340
30308
|
env: { ...process.env, ...params.env },
|
|
30341
30309
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -30353,7 +30321,7 @@ var init_orchestrator = __esm({
|
|
|
30353
30321
|
child.once("close", (code) => resolve(code ?? 1));
|
|
30354
30322
|
});
|
|
30355
30323
|
const output = chunks.join("");
|
|
30356
|
-
await
|
|
30324
|
+
await import_promises25.default.writeFile(params.logPath, output, "utf8");
|
|
30357
30325
|
if (exitCode !== 0) {
|
|
30358
30326
|
throw new Error(
|
|
30359
30327
|
`Command failed with exit ${exitCode}: ${params.command.join(" ")}`
|
|
@@ -30556,13 +30524,13 @@ var init_orchestrator = __esm({
|
|
|
30556
30524
|
// src/scripts/coreResearch.ts
|
|
30557
30525
|
var coreResearch_exports = {};
|
|
30558
30526
|
__export(coreResearch_exports, {
|
|
30559
|
-
main: () =>
|
|
30527
|
+
main: () => main34
|
|
30560
30528
|
});
|
|
30561
|
-
var
|
|
30529
|
+
var import_promises26, import_node_path20, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main34;
|
|
30562
30530
|
var init_coreResearch = __esm({
|
|
30563
30531
|
"src/scripts/coreResearch.ts"() {
|
|
30564
30532
|
"use strict";
|
|
30565
|
-
|
|
30533
|
+
import_promises26 = __toESM(require("fs/promises"));
|
|
30566
30534
|
import_node_path20 = __toESM(require("path"));
|
|
30567
30535
|
import_chalk41 = __toESM(require("chalk"));
|
|
30568
30536
|
init_io();
|
|
@@ -30587,7 +30555,7 @@ var init_coreResearch = __esm({
|
|
|
30587
30555
|
const symbolsFile = valueAfter(argv2, "--symbolsFile");
|
|
30588
30556
|
if (symbolsFile) {
|
|
30589
30557
|
const parsed = JSON.parse(
|
|
30590
|
-
await
|
|
30558
|
+
await import_promises26.default.readFile(import_node_path20.default.resolve(projectRoot18, symbolsFile), "utf8")
|
|
30591
30559
|
);
|
|
30592
30560
|
if (!Array.isArray(parsed) || parsed.some((symbol) => typeof symbol !== "string")) {
|
|
30593
30561
|
throw new Error("--symbolsFile must contain a JSON string array");
|
|
@@ -30607,7 +30575,7 @@ var init_coreResearch = __esm({
|
|
|
30607
30575
|
|
|
30608
30576
|
The run command executes only variants with an explicit command[] in the preregistered spec. Variants with files[] are analyzed without starting a backtest.`);
|
|
30609
30577
|
};
|
|
30610
|
-
|
|
30578
|
+
main34 = async () => {
|
|
30611
30579
|
const roots = resolveResearchRoots();
|
|
30612
30580
|
process.chdir(roots.projectRoot);
|
|
30613
30581
|
const argv2 = process.argv.slice(2);
|
|
@@ -30699,10 +30667,10 @@ The run command executes only variants with an explicit command[] in the preregi
|
|
|
30699
30667
|
// src/scripts/results.ts
|
|
30700
30668
|
var results_exports = {};
|
|
30701
30669
|
__export(results_exports, {
|
|
30702
|
-
main: () =>
|
|
30670
|
+
main: () => main35,
|
|
30703
30671
|
results: () => results
|
|
30704
30672
|
});
|
|
30705
|
-
var import_args26, import_chalk42, import_connectors14, import_cli11,
|
|
30673
|
+
var import_args26, import_chalk42, import_connectors14, import_cli11, import_redis17, ListIt4, flags24, MIN_PROFIT, MIN_WIN_RATE, MIN_ORDERS_PER_MONTH, createListIt4, formatPercent4, getMonthlyReturn, toStrategyResultEntry, toStrategyResults, getTestConfigs, buildBestResults, getSavedProfitsBySymbol, getCoverageRow, results, main35;
|
|
30706
30674
|
var init_results = __esm({
|
|
30707
30675
|
"src/scripts/results.ts"() {
|
|
30708
30676
|
"use strict";
|
|
@@ -30710,7 +30678,7 @@ var init_results = __esm({
|
|
|
30710
30678
|
import_chalk42 = __toESM(require("chalk"));
|
|
30711
30679
|
import_connectors14 = require("@tradejs/connectors");
|
|
30712
30680
|
import_cli11 = require("@tradejs/node/cli");
|
|
30713
|
-
|
|
30681
|
+
import_redis17 = require("@tradejs/infra/redis");
|
|
30714
30682
|
ListIt4 = require("list-it");
|
|
30715
30683
|
import_args26.default.example(
|
|
30716
30684
|
"yarn results --strategy TrendLine --coverage",
|
|
@@ -30750,8 +30718,8 @@ var init_results = __esm({
|
|
|
30750
30718
|
[...rows].map((row) => [row.symbol, toStrategyResultEntry(row)])
|
|
30751
30719
|
);
|
|
30752
30720
|
getTestConfigs = async (userName3) => {
|
|
30753
|
-
const testSummariesKey = typeof
|
|
30754
|
-
const indexedItems = testSummariesKey ? await (0,
|
|
30721
|
+
const testSummariesKey = typeof import_redis17.redisKeys.testSummaries === "function" ? import_redis17.redisKeys.testSummaries(userName3) : null;
|
|
30722
|
+
const indexedItems = testSummariesKey ? await (0, import_redis17.getData)(testSummariesKey, null) : null;
|
|
30755
30723
|
if (Array.isArray(indexedItems) && indexedItems.length) {
|
|
30756
30724
|
return indexedItems.map((item) => {
|
|
30757
30725
|
const testName = typeof item?.value === "string" ? item.value : null;
|
|
@@ -30762,8 +30730,8 @@ var init_results = __esm({
|
|
|
30762
30730
|
return { strategyName, testName };
|
|
30763
30731
|
}).filter(Boolean);
|
|
30764
30732
|
}
|
|
30765
|
-
const testsPrefix =
|
|
30766
|
-
const keys = await (0,
|
|
30733
|
+
const testsPrefix = import_redis17.redisKeys.tests(userName3);
|
|
30734
|
+
const keys = await (0, import_redis17.getKeys)(testsPrefix);
|
|
30767
30735
|
const configKeys = keys.filter((key) => key.endsWith(":config"));
|
|
30768
30736
|
return configKeys.map((key) => {
|
|
30769
30737
|
const parts = key.split(":");
|
|
@@ -30782,15 +30750,15 @@ var init_results = __esm({
|
|
|
30782
30750
|
testName,
|
|
30783
30751
|
strategyName: strategyFromIndex
|
|
30784
30752
|
} of testConfigs) {
|
|
30785
|
-
const config2 = await (0,
|
|
30786
|
-
|
|
30753
|
+
const config2 = await (0, import_redis17.getData)(
|
|
30754
|
+
import_redis17.redisKeys.testConfig(userName3, strategyFromIndex, testName),
|
|
30787
30755
|
null
|
|
30788
30756
|
);
|
|
30789
30757
|
if (!config2 || config2.strategyName !== strategyName) {
|
|
30790
30758
|
continue;
|
|
30791
30759
|
}
|
|
30792
|
-
const stat = await (0,
|
|
30793
|
-
|
|
30760
|
+
const stat = await (0, import_redis17.getData)(
|
|
30761
|
+
import_redis17.redisKeys.testStat(userName3, strategyFromIndex, testName),
|
|
30794
30762
|
null
|
|
30795
30763
|
);
|
|
30796
30764
|
if (!stat) {
|
|
@@ -30835,8 +30803,8 @@ var init_results = __esm({
|
|
|
30835
30803
|
return savedProfitBySymbol;
|
|
30836
30804
|
};
|
|
30837
30805
|
getCoverageRow = async (strategyName, userName3, goodSymbols) => {
|
|
30838
|
-
const currentResults = await (0,
|
|
30839
|
-
|
|
30806
|
+
const currentResults = await (0, import_redis17.getData)(
|
|
30807
|
+
import_redis17.redisKeys.strategyResults(userName3, strategyName),
|
|
30840
30808
|
{}
|
|
30841
30809
|
);
|
|
30842
30810
|
const existingSymbols = new Set(Object.keys(currentResults));
|
|
@@ -30870,8 +30838,8 @@ var init_results = __esm({
|
|
|
30870
30838
|
const strategyName = flags24.strategy;
|
|
30871
30839
|
const userName3 = flags24.user;
|
|
30872
30840
|
if (flags24.clear) {
|
|
30873
|
-
const cleared = await (0,
|
|
30874
|
-
|
|
30841
|
+
const cleared = await (0, import_redis17.delKey)(
|
|
30842
|
+
import_redis17.redisKeys.strategyResults(userName3, strategyName)
|
|
30875
30843
|
);
|
|
30876
30844
|
console.log(
|
|
30877
30845
|
cleared ? import_chalk42.default.green(`Cleared results:${strategyName}`) : import_chalk42.default.yellow(`No results to clear for ${strategyName}`)
|
|
@@ -30919,8 +30887,8 @@ var init_results = __esm({
|
|
|
30919
30887
|
console.log(import_chalk42.default.yellow("No good results to merge."));
|
|
30920
30888
|
process.exit(0);
|
|
30921
30889
|
}
|
|
30922
|
-
const current = await (0,
|
|
30923
|
-
|
|
30890
|
+
const current = await (0, import_redis17.getData)(
|
|
30891
|
+
import_redis17.redisKeys.strategyResults(userName3, strategyName),
|
|
30924
30892
|
{}
|
|
30925
30893
|
);
|
|
30926
30894
|
const savedProfitBySymbol = await getSavedProfitsBySymbol(current);
|
|
@@ -30942,7 +30910,7 @@ var init_results = __esm({
|
|
|
30942
30910
|
...current,
|
|
30943
30911
|
...toStrategyResults(updates)
|
|
30944
30912
|
};
|
|
30945
|
-
await (0,
|
|
30913
|
+
await (0, import_redis17.setData)(import_redis17.redisKeys.strategyResults(userName3, strategyName), merged, {
|
|
30946
30914
|
expire: 0
|
|
30947
30915
|
});
|
|
30948
30916
|
if (flags24.verbose) {
|
|
@@ -30983,8 +30951,8 @@ var init_results = __esm({
|
|
|
30983
30951
|
);
|
|
30984
30952
|
process.exit(0);
|
|
30985
30953
|
}
|
|
30986
|
-
await (0,
|
|
30987
|
-
|
|
30954
|
+
await (0, import_redis17.setData)(
|
|
30955
|
+
import_redis17.redisKeys.strategyResults(userName3, strategyName),
|
|
30988
30956
|
resultsConfig,
|
|
30989
30957
|
{
|
|
30990
30958
|
expire: 0
|
|
@@ -30998,16 +30966,16 @@ var init_results = __esm({
|
|
|
30998
30966
|
}
|
|
30999
30967
|
process.exit();
|
|
31000
30968
|
};
|
|
31001
|
-
|
|
30969
|
+
main35 = results;
|
|
31002
30970
|
}
|
|
31003
30971
|
});
|
|
31004
30972
|
|
|
31005
30973
|
// src/lib/runtimeDebugEvidence.ts
|
|
31006
|
-
var
|
|
30974
|
+
var import_redis18, RUNTIME_DEBUG_TIMEZONE, RUNTIME_DEBUG_TIMEZONE_LABEL, formatRuntimeDebugDateTime, getRuntimeDebugDateParts, formatRuntimeDebugIsoDayKey, buildRuntimeDebugEvaluationId, filterByStrategies, collectRuntimeDebugEvidence, buildRuntimeDebugReportPayload, buildRuntimeEvidenceReportPayload, buildRuntimeDebugReportAttachment;
|
|
31007
30975
|
var init_runtimeDebugEvidence = __esm({
|
|
31008
30976
|
"src/lib/runtimeDebugEvidence.ts"() {
|
|
31009
30977
|
"use strict";
|
|
31010
|
-
|
|
30978
|
+
import_redis18 = require("@tradejs/infra/redis");
|
|
31011
30979
|
init_runtimeRedis();
|
|
31012
30980
|
init_runtimeSignalsLoader();
|
|
31013
30981
|
init_runtimeSignalsStorage();
|
|
@@ -31131,24 +31099,24 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
31131
31099
|
const tradeDayKey = (0, import_time5.getRuntimeStorageDayKey)(trade.entryTimestamp);
|
|
31132
31100
|
const signalDayKey = signal != null ? (0, import_time5.getRuntimeStorageDayKey)(signal.timestamp) : tradeDayKey;
|
|
31133
31101
|
const evaluationDayKey = knownEvaluation != null ? (0, import_time5.getRuntimeStorageDayKey)(knownEvaluation.timestamp) : signalDayKey;
|
|
31134
|
-
const tradeKey =
|
|
31135
|
-
const tradeBucketKey =
|
|
31102
|
+
const tradeKey = import_redis18.redisKeys.runtimeTrade(userName3, trade.orderId);
|
|
31103
|
+
const tradeBucketKey = import_redis18.redisKeys.runtimeTradeBucket(
|
|
31136
31104
|
userName3,
|
|
31137
31105
|
tradeDayKey
|
|
31138
31106
|
);
|
|
31139
|
-
const activeTradeKey =
|
|
31107
|
+
const activeTradeKey = import_redis18.redisKeys.runtimeActiveTrade(
|
|
31140
31108
|
userName3,
|
|
31141
31109
|
trade.symbol,
|
|
31142
31110
|
trade.deploymentId ?? trade.accountId
|
|
31143
31111
|
);
|
|
31144
|
-
const signalKey = trade.signalId != null ?
|
|
31145
|
-
const evaluationBucketKey =
|
|
31112
|
+
const signalKey = trade.signalId != null ? import_redis18.redisKeys.storeSignal(trade.symbol, trade.signalId) : null;
|
|
31113
|
+
const evaluationBucketKey = import_redis18.redisKeys.runtimeSignalEvaluationBucket(
|
|
31146
31114
|
userName3,
|
|
31147
31115
|
evaluationDayKey,
|
|
31148
31116
|
knownEvaluation?.strategy ?? trade.strategy
|
|
31149
31117
|
);
|
|
31150
31118
|
const evaluationField = knownEvaluation?.evaluationId ?? evaluationId;
|
|
31151
|
-
const evaluationKey =
|
|
31119
|
+
const evaluationKey = import_redis18.redisKeys.runtimeSignalEvaluation(
|
|
31152
31120
|
userName3,
|
|
31153
31121
|
evaluationField
|
|
31154
31122
|
);
|
|
@@ -31159,11 +31127,11 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
31159
31127
|
directEvaluationValue,
|
|
31160
31128
|
bucketEvaluationValue
|
|
31161
31129
|
] = await Promise.all([
|
|
31162
|
-
(0,
|
|
31163
|
-
(0,
|
|
31164
|
-
signalKey ? (0,
|
|
31165
|
-
(0,
|
|
31166
|
-
knownEvaluation ? Promise.resolve(knownEvaluation) : (0,
|
|
31130
|
+
(0, import_redis18.getData)(tradeKey, null),
|
|
31131
|
+
(0, import_redis18.getData)(activeTradeKey, null),
|
|
31132
|
+
signalKey ? (0, import_redis18.getData)(signalKey, null) : Promise.resolve(null),
|
|
31133
|
+
(0, import_redis18.getData)(evaluationKey, null),
|
|
31134
|
+
knownEvaluation ? Promise.resolve(knownEvaluation) : (0, import_redis18.getHashJsonField)(
|
|
31167
31135
|
evaluationBucketKey,
|
|
31168
31136
|
evaluationField,
|
|
31169
31137
|
null
|
|
@@ -31220,12 +31188,12 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
31220
31188
|
dayKeys
|
|
31221
31189
|
},
|
|
31222
31190
|
redisPrefixes: {
|
|
31223
|
-
runtimeTrades:
|
|
31224
|
-
runtimeTradeBuckets:
|
|
31225
|
-
runtimeActiveTrades:
|
|
31226
|
-
runtimeSignals:
|
|
31227
|
-
runtimeSignalEvaluations:
|
|
31228
|
-
runtimeSignalEvaluationStats:
|
|
31191
|
+
runtimeTrades: import_redis18.redisKeys.runtimeTrades(userName3),
|
|
31192
|
+
runtimeTradeBuckets: import_redis18.redisKeys.runtimeTradeBuckets(userName3),
|
|
31193
|
+
runtimeActiveTrades: import_redis18.redisKeys.runtimeActiveTrades(userName3),
|
|
31194
|
+
runtimeSignals: import_redis18.redisKeys.runtimeSignalBuckets(userName3),
|
|
31195
|
+
runtimeSignalEvaluations: import_redis18.redisKeys.runtimeSignalEvaluationBuckets(userName3),
|
|
31196
|
+
runtimeSignalEvaluationStats: import_redis18.redisKeys.runtimeSignalEvaluationStatsBuckets(userName3)
|
|
31229
31197
|
},
|
|
31230
31198
|
counts: {
|
|
31231
31199
|
trades: trades.length,
|
|
@@ -31236,18 +31204,18 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
31236
31204
|
},
|
|
31237
31205
|
trades: debugTrades,
|
|
31238
31206
|
signals: signals2.map((signal) => ({
|
|
31239
|
-
redisKey:
|
|
31207
|
+
redisKey: import_redis18.redisKeys.storeSignal(signal.symbol, signal.signalId),
|
|
31240
31208
|
signal
|
|
31241
31209
|
})),
|
|
31242
31210
|
evaluations: reportEvaluations.map((evaluation) => ({
|
|
31243
31211
|
redisDebug: {
|
|
31244
|
-
key:
|
|
31212
|
+
key: import_redis18.redisKeys.runtimeSignalEvaluationBucket(
|
|
31245
31213
|
userName3,
|
|
31246
31214
|
(0, import_time5.getRuntimeStorageDayKey)(evaluation.timestamp),
|
|
31247
31215
|
evaluation.strategy
|
|
31248
31216
|
),
|
|
31249
31217
|
field: evaluation.evaluationId,
|
|
31250
|
-
directKey:
|
|
31218
|
+
directKey: import_redis18.redisKeys.runtimeSignalEvaluation(
|
|
31251
31219
|
userName3,
|
|
31252
31220
|
evaluation.evaluationId
|
|
31253
31221
|
)
|
|
@@ -31308,19 +31276,19 @@ var init_runtimeDebugEvidence = __esm({
|
|
|
31308
31276
|
// src/scripts/replayRuntimeEvidence.ts
|
|
31309
31277
|
var replayRuntimeEvidence_exports = {};
|
|
31310
31278
|
__export(replayRuntimeEvidence_exports, {
|
|
31311
|
-
main: () =>
|
|
31279
|
+
main: () => main36,
|
|
31312
31280
|
replayRuntimeEvidence: () => replayRuntimeEvidence,
|
|
31313
31281
|
summarizeReplayComparison: () => summarizeReplayComparison
|
|
31314
31282
|
});
|
|
31315
|
-
var
|
|
31283
|
+
var import_promises27, import_node_path21, import_args27, import_chalk43, import_redis19, toEpochMs2, resolveWindow, parseStrategyFilter, asRecord5, asArray2, sum, groupCount, compactMatched, resolveItemStrategy, summarizeReplayComparison, loadReplayResult, getReplayStrategies, loadRuntimePayload, replayRuntimeEvidence, main36;
|
|
31316
31284
|
var init_replayRuntimeEvidence = __esm({
|
|
31317
31285
|
"src/scripts/replayRuntimeEvidence.ts"() {
|
|
31318
31286
|
"use strict";
|
|
31319
|
-
|
|
31287
|
+
import_promises27 = __toESM(require("fs/promises"));
|
|
31320
31288
|
import_node_path21 = __toESM(require("path"));
|
|
31321
31289
|
import_args27 = __toESM(require("args"));
|
|
31322
31290
|
import_chalk43 = __toESM(require("chalk"));
|
|
31323
|
-
|
|
31291
|
+
import_redis19 = require("@tradejs/infra/redis");
|
|
31324
31292
|
init_runtimeDebugEvidence();
|
|
31325
31293
|
init_support();
|
|
31326
31294
|
import_args27.default.option(["u", "user"], "Use user config", "root");
|
|
@@ -31540,18 +31508,18 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
31540
31508
|
return {
|
|
31541
31509
|
key: replayKey,
|
|
31542
31510
|
availableKeys: void 0,
|
|
31543
|
-
value: await (0,
|
|
31511
|
+
value: await (0, import_redis19.getData)(replayKey, null)
|
|
31544
31512
|
};
|
|
31545
31513
|
}
|
|
31546
|
-
const prefix =
|
|
31547
|
-
const keys = (await (0,
|
|
31514
|
+
const prefix = import_redis19.redisKeys.backtestResults(userName3, REPLAY_RESULTS_CONFIG, "");
|
|
31515
|
+
const keys = (await (0, import_redis19.getKeys)(prefix)).sort(
|
|
31548
31516
|
(left, right) => left.localeCompare(right)
|
|
31549
31517
|
);
|
|
31550
31518
|
const key = keys[keys.length - 1] ?? null;
|
|
31551
31519
|
return {
|
|
31552
31520
|
key,
|
|
31553
31521
|
availableKeys: keys.slice(-10),
|
|
31554
|
-
value: key ? await (0,
|
|
31522
|
+
value: key ? await (0, import_redis19.getData)(key, null) : null
|
|
31555
31523
|
};
|
|
31556
31524
|
};
|
|
31557
31525
|
getReplayStrategies = (replayValue) => {
|
|
@@ -31579,7 +31547,7 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
31579
31547
|
const runtimeEvidencePath = typeof runtimeEvidenceFile === "string" && runtimeEvidenceFile.trim() ? import_node_path21.default.resolve(projectRoot18, runtimeEvidenceFile.trim()) : null;
|
|
31580
31548
|
if (runtimeEvidencePath) {
|
|
31581
31549
|
const artifact = JSON.parse(
|
|
31582
|
-
await
|
|
31550
|
+
await import_promises27.default.readFile(runtimeEvidencePath, "utf8")
|
|
31583
31551
|
);
|
|
31584
31552
|
return {
|
|
31585
31553
|
source: "file",
|
|
@@ -31666,8 +31634,8 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
31666
31634
|
runtime: runtime.payload
|
|
31667
31635
|
};
|
|
31668
31636
|
const outPath = import_node_path21.default.resolve(projectRoot18, String(flags35.out));
|
|
31669
|
-
await
|
|
31670
|
-
await
|
|
31637
|
+
await import_promises27.default.mkdir(import_node_path21.default.dirname(outPath), { recursive: true });
|
|
31638
|
+
await import_promises27.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
31671
31639
|
`, "utf8");
|
|
31672
31640
|
console.log(import_chalk43.default.green(`Wrote ${outPath}`));
|
|
31673
31641
|
console.log(
|
|
@@ -31685,574 +31653,45 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
31685
31653
|
)
|
|
31686
31654
|
);
|
|
31687
31655
|
};
|
|
31688
|
-
|
|
31656
|
+
main36 = replayRuntimeEvidence;
|
|
31689
31657
|
}
|
|
31690
31658
|
});
|
|
31691
31659
|
|
|
31692
31660
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
31693
|
-
var
|
|
31661
|
+
var runtimeEvidenceArtifacts_exports = {};
|
|
31694
31662
|
var init_runtimeEvidenceArtifacts = __esm({
|
|
31695
31663
|
"src/lib/runtimeEvidenceArtifacts.ts"() {
|
|
31696
31664
|
"use strict";
|
|
31697
|
-
|
|
31698
|
-
import_promises27 = __toESM(require("fs/promises"));
|
|
31699
|
-
import_node_path22 = __toESM(require("path"));
|
|
31700
|
-
init_runtimeEvidenceDeployment();
|
|
31701
|
-
RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
|
|
31702
|
-
RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
|
|
31703
|
-
RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
|
|
31704
|
-
asRecord6 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
31705
|
-
sha256 = (value) => (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex");
|
|
31706
|
-
runtimeEvidenceIdentitySha256 = (artifact) => {
|
|
31707
|
-
const identityArtifact = { ...artifact };
|
|
31708
|
-
delete identityArtifact.generatedAt;
|
|
31709
|
-
const runtime = asRecord6(identityArtifact.runtime);
|
|
31710
|
-
if (runtime) {
|
|
31711
|
-
const identityRuntime = { ...runtime };
|
|
31712
|
-
delete identityRuntime.generatedAt;
|
|
31713
|
-
identityArtifact.runtime = identityRuntime;
|
|
31714
|
-
}
|
|
31715
|
-
return sha256(JSON.stringify(identityArtifact));
|
|
31716
|
-
};
|
|
31717
|
-
isExistingDestinationError = (error) => {
|
|
31718
|
-
const code = error.code;
|
|
31719
|
-
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
31720
|
-
};
|
|
31721
|
-
safeSegment = (value, fallback) => {
|
|
31722
|
-
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
31723
|
-
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
31724
|
-
};
|
|
31725
|
-
compactTimestamp = (timestamp) => new Date(timestamp).toISOString().replace(/[-:]/g, "").replace(/\.000Z$/, "Z");
|
|
31726
|
-
dateParts = (timestamp) => {
|
|
31727
|
-
const date = new Date(timestamp);
|
|
31728
|
-
return [
|
|
31729
|
-
String(date.getUTCFullYear()),
|
|
31730
|
-
String(date.getUTCMonth() + 1).padStart(2, "0"),
|
|
31731
|
-
String(date.getUTCDate()).padStart(2, "0")
|
|
31732
|
-
];
|
|
31733
|
-
};
|
|
31734
|
-
assertFiniteTimestamp = (value, label) => {
|
|
31735
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
31736
|
-
throw new Error(`Invalid runtime evidence ${label}`);
|
|
31737
|
-
}
|
|
31738
|
-
return value;
|
|
31739
|
-
};
|
|
31740
|
-
parseManifest = (value) => {
|
|
31741
|
-
const manifest = asRecord6(value);
|
|
31742
|
-
const window = asRecord6(manifest?.window);
|
|
31743
|
-
const payload = asRecord6(manifest?.payload);
|
|
31744
|
-
const counts = asRecord6(manifest?.counts);
|
|
31745
|
-
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence" || typeof manifest.artifactId !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.userName !== "string" || typeof manifest.createdAt !== "number" || payload?.file !== RUNTIME_EVIDENCE_PAYLOAD_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number" || !Array.isArray(manifest.lineageKeys)) {
|
|
31746
|
-
throw new Error("Invalid runtime evidence manifest");
|
|
31747
|
-
}
|
|
31748
|
-
return {
|
|
31749
|
-
schemaVersion: 1,
|
|
31750
|
-
artifactId: manifest.artifactId,
|
|
31751
|
-
reportType: "runtime-evidence",
|
|
31752
|
-
deploymentId: manifest.deploymentId,
|
|
31753
|
-
userName: manifest.userName,
|
|
31754
|
-
createdAt: manifest.createdAt,
|
|
31755
|
-
window: {
|
|
31756
|
-
startTime: assertFiniteTimestamp(window?.startTime, "window.startTime"),
|
|
31757
|
-
endTime: assertFiniteTimestamp(window?.endTime, "window.endTime")
|
|
31758
|
-
},
|
|
31759
|
-
payload: {
|
|
31760
|
-
file: RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
31761
|
-
sha256: payload.sha256,
|
|
31762
|
-
bytes: payload.bytes
|
|
31763
|
-
},
|
|
31764
|
-
counts: Object.fromEntries(
|
|
31765
|
-
Object.entries(counts ?? {}).filter(
|
|
31766
|
-
(entry) => typeof entry[1] === "number" && Number.isFinite(entry[1])
|
|
31767
|
-
)
|
|
31768
|
-
),
|
|
31769
|
-
lineageKeys: manifest.lineageKeys.filter(
|
|
31770
|
-
(value2) => typeof value2 === "string" && value2.length > 0
|
|
31771
|
-
)
|
|
31772
|
-
};
|
|
31773
|
-
};
|
|
31774
|
-
publishRuntimeEvidenceBundle = async ({
|
|
31775
|
-
publishRoot,
|
|
31776
|
-
deploymentId,
|
|
31777
|
-
userName: userName3,
|
|
31778
|
-
startTime,
|
|
31779
|
-
endTime,
|
|
31780
|
-
artifact,
|
|
31781
|
-
counts,
|
|
31782
|
-
lineageKeys
|
|
31783
|
-
}) => {
|
|
31784
|
-
assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
31785
|
-
const payload = `${JSON.stringify(artifact, null, 2)}
|
|
31786
|
-
`;
|
|
31787
|
-
const payloadSha256 = sha256(payload);
|
|
31788
|
-
const identitySha256 = runtimeEvidenceIdentitySha256(artifact);
|
|
31789
|
-
const safeDeploymentId = safeSegment(deploymentId, "default");
|
|
31790
|
-
const artifactId = [
|
|
31791
|
-
compactTimestamp(startTime),
|
|
31792
|
-
compactTimestamp(endTime),
|
|
31793
|
-
identitySha256.slice(0, 16)
|
|
31794
|
-
].join("_");
|
|
31795
|
-
const createdAt = Date.now();
|
|
31796
|
-
const manifest = {
|
|
31797
|
-
schemaVersion: 1,
|
|
31798
|
-
artifactId,
|
|
31799
|
-
reportType: "runtime-evidence",
|
|
31800
|
-
deploymentId: safeDeploymentId,
|
|
31801
|
-
userName: userName3,
|
|
31802
|
-
createdAt,
|
|
31803
|
-
window: { startTime, endTime },
|
|
31804
|
-
payload: {
|
|
31805
|
-
file: RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
31806
|
-
sha256: payloadSha256,
|
|
31807
|
-
bytes: Buffer.byteLength(payload)
|
|
31808
|
-
},
|
|
31809
|
-
counts,
|
|
31810
|
-
lineageKeys: [...new Set(lineageKeys)].sort()
|
|
31811
|
-
};
|
|
31812
|
-
const incomingRoot = import_node_path22.default.join(publishRoot, "incoming");
|
|
31813
|
-
const readyRoot = import_node_path22.default.join(
|
|
31814
|
-
publishRoot,
|
|
31815
|
-
"ready",
|
|
31816
|
-
safeDeploymentId,
|
|
31817
|
-
...dateParts(endTime)
|
|
31818
|
-
);
|
|
31819
|
-
const bundleDir = import_node_path22.default.join(readyRoot, artifactId);
|
|
31820
|
-
const temporaryDir = import_node_path22.default.join(
|
|
31821
|
-
incomingRoot,
|
|
31822
|
-
`${artifactId}.tmp-${(0, import_node_crypto13.randomUUID)()}`
|
|
31823
|
-
);
|
|
31824
|
-
await import_promises27.default.mkdir(temporaryDir, { recursive: true });
|
|
31825
|
-
try {
|
|
31826
|
-
await Promise.all([
|
|
31827
|
-
import_promises27.default.writeFile(
|
|
31828
|
-
import_node_path22.default.join(temporaryDir, RUNTIME_EVIDENCE_PAYLOAD_FILE),
|
|
31829
|
-
payload,
|
|
31830
|
-
"utf8"
|
|
31831
|
-
),
|
|
31832
|
-
import_promises27.default.writeFile(
|
|
31833
|
-
import_node_path22.default.join(temporaryDir, RUNTIME_EVIDENCE_MANIFEST_FILE),
|
|
31834
|
-
`${JSON.stringify(manifest, null, 2)}
|
|
31835
|
-
`,
|
|
31836
|
-
"utf8"
|
|
31837
|
-
)
|
|
31838
|
-
]);
|
|
31839
|
-
await import_promises27.default.writeFile(
|
|
31840
|
-
import_node_path22.default.join(temporaryDir, RUNTIME_EVIDENCE_COMPLETE_FILE),
|
|
31841
|
-
`${artifactId}
|
|
31842
|
-
`,
|
|
31843
|
-
"utf8"
|
|
31844
|
-
);
|
|
31845
|
-
await import_promises27.default.mkdir(readyRoot, { recursive: true });
|
|
31846
|
-
try {
|
|
31847
|
-
await import_promises27.default.rename(temporaryDir, bundleDir);
|
|
31848
|
-
} catch (error) {
|
|
31849
|
-
if (!isExistingDestinationError(error)) {
|
|
31850
|
-
throw error;
|
|
31851
|
-
}
|
|
31852
|
-
await import_promises27.default.rm(temporaryDir, { recursive: true, force: true });
|
|
31853
|
-
}
|
|
31854
|
-
} catch (error) {
|
|
31855
|
-
await import_promises27.default.rm(temporaryDir, { recursive: true, force: true });
|
|
31856
|
-
throw error;
|
|
31857
|
-
}
|
|
31858
|
-
return verifyRuntimeEvidenceBundle(bundleDir);
|
|
31859
|
-
};
|
|
31860
|
-
verifyRuntimeEvidenceBundle = async (bundleDir) => {
|
|
31861
|
-
const manifestPath = import_node_path22.default.join(bundleDir, RUNTIME_EVIDENCE_MANIFEST_FILE);
|
|
31862
|
-
const payloadPath = import_node_path22.default.join(bundleDir, RUNTIME_EVIDENCE_PAYLOAD_FILE);
|
|
31863
|
-
const completePath = import_node_path22.default.join(bundleDir, RUNTIME_EVIDENCE_COMPLETE_FILE);
|
|
31864
|
-
const [manifestText, payload, completeText] = await Promise.all([
|
|
31865
|
-
import_promises27.default.readFile(manifestPath, "utf8"),
|
|
31866
|
-
import_promises27.default.readFile(payloadPath),
|
|
31867
|
-
import_promises27.default.readFile(completePath, "utf8")
|
|
31868
|
-
]);
|
|
31869
|
-
const manifest = parseManifest(JSON.parse(manifestText));
|
|
31870
|
-
if (completeText.trim() !== manifest.artifactId) {
|
|
31871
|
-
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
31872
|
-
}
|
|
31873
|
-
if (payload.byteLength !== manifest.payload.bytes) {
|
|
31874
|
-
throw new Error(`Runtime evidence size mismatch in ${bundleDir}`);
|
|
31875
|
-
}
|
|
31876
|
-
if (sha256(payload) !== manifest.payload.sha256) {
|
|
31877
|
-
throw new Error(`Runtime evidence checksum mismatch in ${bundleDir}`);
|
|
31878
|
-
}
|
|
31879
|
-
const artifact = asRecord6(JSON.parse(payload.toString("utf8")));
|
|
31880
|
-
const artifactWindow = asRecord6(artifact?.window);
|
|
31881
|
-
if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
|
|
31882
|
-
throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
|
|
31883
|
-
}
|
|
31884
|
-
const deployment = assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
31885
|
-
if (deployment.id !== manifest.deploymentId) {
|
|
31886
|
-
throw new Error(`Runtime evidence deployment mismatch in ${bundleDir}`);
|
|
31887
|
-
}
|
|
31888
|
-
return {
|
|
31889
|
-
bundleDir,
|
|
31890
|
-
manifestPath,
|
|
31891
|
-
payloadPath,
|
|
31892
|
-
manifest,
|
|
31893
|
-
artifact
|
|
31894
|
-
};
|
|
31895
|
-
};
|
|
31896
|
-
discoverRuntimeEvidenceBundles = async (rootDir) => {
|
|
31897
|
-
const bundles = [];
|
|
31898
|
-
const visit = async (directory, depth) => {
|
|
31899
|
-
if (depth > 8) return;
|
|
31900
|
-
let entries;
|
|
31901
|
-
try {
|
|
31902
|
-
entries = await import_promises27.default.readdir(directory, { withFileTypes: true });
|
|
31903
|
-
} catch (error) {
|
|
31904
|
-
if (error.code === "ENOENT") return;
|
|
31905
|
-
throw error;
|
|
31906
|
-
}
|
|
31907
|
-
const names = new Set(entries.map((entry) => entry.name));
|
|
31908
|
-
if (names.has(RUNTIME_EVIDENCE_MANIFEST_FILE) && names.has(RUNTIME_EVIDENCE_PAYLOAD_FILE) && names.has(RUNTIME_EVIDENCE_COMPLETE_FILE)) {
|
|
31909
|
-
bundles.push(directory);
|
|
31910
|
-
return;
|
|
31911
|
-
}
|
|
31912
|
-
await Promise.all(
|
|
31913
|
-
entries.filter(
|
|
31914
|
-
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
31915
|
-
).map((entry) => visit(import_node_path22.default.join(directory, entry.name), depth + 1))
|
|
31916
|
-
);
|
|
31917
|
-
};
|
|
31918
|
-
await visit(rootDir, 0);
|
|
31919
|
-
return bundles.sort();
|
|
31920
|
-
};
|
|
31665
|
+
__reExport(runtimeEvidenceArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
31921
31666
|
}
|
|
31922
31667
|
});
|
|
31923
31668
|
|
|
31924
31669
|
// src/lib/runtimeEvidenceProducer.ts
|
|
31925
|
-
var
|
|
31670
|
+
var runtimeEvidenceProducer_exports = {};
|
|
31926
31671
|
var init_runtimeEvidenceProducer = __esm({
|
|
31927
31672
|
"src/lib/runtimeEvidenceProducer.ts"() {
|
|
31928
31673
|
"use strict";
|
|
31929
|
-
|
|
31930
|
-
import_promises28 = __toESM(require("fs/promises"));
|
|
31931
|
-
import_node_path23 = __toESM(require("path"));
|
|
31932
|
-
isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
31933
|
-
sha2562 = (value) => (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex");
|
|
31934
|
-
parseRuntimeEvidenceProducer = (value) => {
|
|
31935
|
-
const producer = isRecord2(value) ? value : null;
|
|
31936
|
-
const runtimePackageManifest = isRecord2(producer?.runtimePackageManifest) ? producer.runtimePackageManifest : null;
|
|
31937
|
-
if (producer?.schemaVersion !== 1 || typeof producer.projectSha !== "string" || !/^[a-f0-9]{40}$/.test(producer.projectSha) || typeof producer.imageDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(producer.imageDigest) || runtimePackageManifest?.file !== "runtime-package-manifest.json" || typeof runtimePackageManifest.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(runtimePackageManifest.sha256)) {
|
|
31938
|
-
throw new Error("Runtime evidence producer image identity is invalid");
|
|
31939
|
-
}
|
|
31940
|
-
return producer;
|
|
31941
|
-
};
|
|
31942
|
-
resolveRuntimeEvidenceProducer = async ({
|
|
31943
|
-
projectRoot: projectRoot18,
|
|
31944
|
-
required: required4
|
|
31945
|
-
}) => {
|
|
31946
|
-
const projectSha = String(process.env.TRADEJS_PROJECT_SHA ?? "").trim();
|
|
31947
|
-
const imageDigest = String(
|
|
31948
|
-
process.env.TRADEJS_PROJECT_IMAGE_DIGEST ?? ""
|
|
31949
|
-
).trim();
|
|
31950
|
-
if (!projectSha && !imageDigest && !required4) {
|
|
31951
|
-
return null;
|
|
31952
|
-
}
|
|
31953
|
-
if (!/^[a-f0-9]{40}$/.test(projectSha)) {
|
|
31954
|
-
throw new Error(
|
|
31955
|
-
"TRADEJS_PROJECT_SHA must be a full lowercase Git SHA before publishing runtime evidence"
|
|
31956
|
-
);
|
|
31957
|
-
}
|
|
31958
|
-
if (!/^sha256:[a-f0-9]{64}$/.test(imageDigest)) {
|
|
31959
|
-
throw new Error(
|
|
31960
|
-
"TRADEJS_PROJECT_IMAGE_DIGEST must be an immutable sha256 digest before publishing runtime evidence"
|
|
31961
|
-
);
|
|
31962
|
-
}
|
|
31963
|
-
const manifestPath = import_node_path23.default.join(projectRoot18, "runtime-package-manifest.json");
|
|
31964
|
-
let manifest;
|
|
31965
|
-
try {
|
|
31966
|
-
manifest = await import_promises28.default.readFile(manifestPath);
|
|
31967
|
-
} catch (error) {
|
|
31968
|
-
if (!required4 && error.code === "ENOENT") {
|
|
31969
|
-
return null;
|
|
31970
|
-
}
|
|
31971
|
-
throw new Error(
|
|
31972
|
-
`Runtime package manifest is required for runtime evidence: ${manifestPath}`,
|
|
31973
|
-
{ cause: error }
|
|
31974
|
-
);
|
|
31975
|
-
}
|
|
31976
|
-
return {
|
|
31977
|
-
schemaVersion: 1,
|
|
31978
|
-
projectSha,
|
|
31979
|
-
imageDigest,
|
|
31980
|
-
runtimePackageManifest: {
|
|
31981
|
-
file: "runtime-package-manifest.json",
|
|
31982
|
-
sha256: sha2562(manifest)
|
|
31983
|
-
}
|
|
31984
|
-
};
|
|
31985
|
-
};
|
|
31674
|
+
__reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
|
|
31986
31675
|
}
|
|
31987
31676
|
});
|
|
31988
31677
|
|
|
31989
31678
|
// src/lib/runtimeFeedbackArtifacts.ts
|
|
31990
|
-
var
|
|
31679
|
+
var runtimeFeedbackArtifacts_exports = {};
|
|
31991
31680
|
var init_runtimeFeedbackArtifacts = __esm({
|
|
31992
31681
|
"src/lib/runtimeFeedbackArtifacts.ts"() {
|
|
31993
31682
|
"use strict";
|
|
31994
|
-
|
|
31995
|
-
import_promises29 = __toESM(require("fs/promises"));
|
|
31996
|
-
import_node_path24 = __toESM(require("path"));
|
|
31997
|
-
init_runtimeEvidenceDeployment();
|
|
31998
|
-
init_runtimeEvidenceArtifacts();
|
|
31999
|
-
init_runtimeEvidenceProducer();
|
|
32000
|
-
RUNTIME_FEEDBACK_MANIFEST_FILE = "manifest.json";
|
|
32001
|
-
RUNTIME_FEEDBACK_REPLAY_FILE = "replay-runtime-evidence.json";
|
|
32002
|
-
RUNTIME_FEEDBACK_LOG_FILE = "replay.log";
|
|
32003
|
-
RUNTIME_FEEDBACK_COMPLETE_FILE = ".complete";
|
|
32004
|
-
isRecord3 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
32005
|
-
sha2563 = (value) => (0, import_node_crypto15.createHash)("sha256").update(value).digest("hex");
|
|
32006
|
-
safeSegment2 = (value, fallback) => {
|
|
32007
|
-
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
32008
|
-
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
32009
|
-
};
|
|
32010
|
-
parsePayload = (value, expectedFile) => {
|
|
32011
|
-
const payload = isRecord3(value) ? value : null;
|
|
32012
|
-
if (payload?.file !== expectedFile || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number" || !Number.isFinite(payload.bytes) || payload.bytes < 0) {
|
|
32013
|
-
throw new Error(`Invalid runtime feedback payload: ${expectedFile}`);
|
|
32014
|
-
}
|
|
32015
|
-
return payload;
|
|
32016
|
-
};
|
|
32017
|
-
parseManifest2 = (value) => {
|
|
32018
|
-
const manifest = isRecord3(value) ? value : null;
|
|
32019
|
-
const window = isRecord3(manifest?.window) ? manifest.window : null;
|
|
32020
|
-
const runtimeEvidence2 = isRecord3(manifest?.runtimeEvidence) ? manifest.runtimeEvidence : null;
|
|
32021
|
-
const safety = isRecord3(manifest?.safety) ? manifest.safety : null;
|
|
32022
|
-
const payloads = isRecord3(manifest?.payloads) ? manifest.payloads : null;
|
|
32023
|
-
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-feedback-replay" || typeof manifest.artifactId !== "string" || !manifest.artifactId.trim() || typeof manifest.runId !== "string" || !manifest.runId.trim() || typeof manifest.deploymentId !== "string" || !manifest.deploymentId.trim() || typeof manifest.deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(manifest.deploymentCompositionId) || typeof manifest.userName !== "string" || !manifest.userName.trim() || typeof manifest.createdAt !== "number" || typeof window?.startTime !== "number" || typeof window.endTime !== "number" || typeof runtimeEvidence2?.artifactId !== "string" || typeof runtimeEvidence2.payloadSha256 !== "string" || !/^[a-f0-9]{64}$/.test(runtimeEvidence2.payloadSha256) || !Array.isArray(manifest.activeStrategies) || manifest.activeStrategies.length === 0 || !manifest.activeStrategies.every(
|
|
32024
|
-
(strategy) => typeof strategy === "string" && strategy.trim()
|
|
32025
|
-
) || typeof manifest.cycleCount !== "number" || !Number.isFinite(manifest.cycleCount) || manifest.cycleCount <= 0 || safety?.cacheOnly !== true || safety.externalOrderPlacement !== false || safety.redis !== "isolated" || safety.timescale !== "read_only") {
|
|
32026
|
-
throw new Error("Invalid runtime feedback replay manifest");
|
|
32027
|
-
}
|
|
32028
|
-
const replayEvidence = parsePayload(
|
|
32029
|
-
payloads?.replayEvidence,
|
|
32030
|
-
RUNTIME_FEEDBACK_REPLAY_FILE
|
|
32031
|
-
);
|
|
32032
|
-
const log = parsePayload(payloads?.log, RUNTIME_FEEDBACK_LOG_FILE);
|
|
32033
|
-
return {
|
|
32034
|
-
...manifest,
|
|
32035
|
-
producer: parseRuntimeEvidenceProducer(manifest.producer),
|
|
32036
|
-
payloads: {
|
|
32037
|
-
replayEvidence: {
|
|
32038
|
-
...replayEvidence,
|
|
32039
|
-
file: RUNTIME_FEEDBACK_REPLAY_FILE
|
|
32040
|
-
},
|
|
32041
|
-
log: { ...log, file: RUNTIME_FEEDBACK_LOG_FILE }
|
|
32042
|
-
}
|
|
32043
|
-
};
|
|
32044
|
-
};
|
|
32045
|
-
assertReplayMatchesRuntimeEvidence = ({
|
|
32046
|
-
replayEvidence,
|
|
32047
|
-
runtimeEvidence: runtimeEvidence2
|
|
32048
|
-
}) => {
|
|
32049
|
-
if (replayEvidence.reportType !== "replay-runtime-evidence") {
|
|
32050
|
-
throw new Error("Runtime feedback replay payload has the wrong reportType");
|
|
32051
|
-
}
|
|
32052
|
-
const replayWindow = isRecord3(replayEvidence.window) ? replayEvidence.window : null;
|
|
32053
|
-
if (replayWindow?.startTime !== runtimeEvidence2.manifest.window.startTime || replayWindow.endTime !== runtimeEvidence2.manifest.window.endTime) {
|
|
32054
|
-
throw new Error("Runtime feedback replay window does not match evidence");
|
|
32055
|
-
}
|
|
32056
|
-
const runtimeDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
32057
|
-
runtimeEvidence2.artifact.deployment
|
|
32058
|
-
);
|
|
32059
|
-
const replayDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
32060
|
-
replayEvidence.deployment
|
|
32061
|
-
);
|
|
32062
|
-
if (replayDeployment.id !== runtimeDeployment.id || replayDeployment.deploymentCompositionId !== runtimeDeployment.deploymentCompositionId) {
|
|
32063
|
-
throw new Error(
|
|
32064
|
-
"Runtime feedback replay deployment does not match evidence"
|
|
32065
|
-
);
|
|
32066
|
-
}
|
|
32067
|
-
};
|
|
32068
|
-
sealRuntimeFeedbackReplayBundle = async ({
|
|
32069
|
-
bundleDir,
|
|
32070
|
-
runId,
|
|
32071
|
-
runtimeEvidenceBundle
|
|
32072
|
-
}) => {
|
|
32073
|
-
const replayEvidencePath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_REPLAY_FILE);
|
|
32074
|
-
const logPath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_LOG_FILE);
|
|
32075
|
-
const [replayPayload, logPayload] = await Promise.all([
|
|
32076
|
-
import_promises29.default.readFile(replayEvidencePath),
|
|
32077
|
-
import_promises29.default.readFile(logPath)
|
|
32078
|
-
]);
|
|
32079
|
-
const replayEvidence = JSON.parse(replayPayload.toString("utf8"));
|
|
32080
|
-
assertReplayMatchesRuntimeEvidence({
|
|
32081
|
-
replayEvidence,
|
|
32082
|
-
runtimeEvidence: runtimeEvidenceBundle
|
|
32083
|
-
});
|
|
32084
|
-
const replay = isRecord3(replayEvidence.replay) ? replayEvidence.replay : null;
|
|
32085
|
-
const cycleCount = Number(replay?.cycleCount);
|
|
32086
|
-
if (!Number.isFinite(cycleCount) || cycleCount <= 0) {
|
|
32087
|
-
throw new Error(
|
|
32088
|
-
`Runtime feedback replay produced no comparable cycles: ${String(replay?.cycleCount ?? "missing")}`
|
|
32089
|
-
);
|
|
32090
|
-
}
|
|
32091
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
32092
|
-
runtimeEvidenceBundle.artifact.deployment
|
|
32093
|
-
);
|
|
32094
|
-
const producer = parseRuntimeEvidenceProducer(
|
|
32095
|
-
runtimeEvidenceBundle.artifact.producer
|
|
32096
|
-
);
|
|
32097
|
-
const safeRunId = safeSegment2(runId, "run");
|
|
32098
|
-
const artifactId = `${runtimeEvidenceBundle.manifest.artifactId}_${safeRunId}`;
|
|
32099
|
-
const manifest = {
|
|
32100
|
-
schemaVersion: 1,
|
|
32101
|
-
reportType: "runtime-feedback-replay",
|
|
32102
|
-
artifactId,
|
|
32103
|
-
runId: safeRunId,
|
|
32104
|
-
deploymentId: deployment.id,
|
|
32105
|
-
deploymentCompositionId: deployment.deploymentCompositionId,
|
|
32106
|
-
userName: runtimeEvidenceBundle.manifest.userName,
|
|
32107
|
-
createdAt: Date.now(),
|
|
32108
|
-
window: { ...runtimeEvidenceBundle.manifest.window },
|
|
32109
|
-
runtimeEvidence: {
|
|
32110
|
-
artifactId: runtimeEvidenceBundle.manifest.artifactId,
|
|
32111
|
-
payloadSha256: runtimeEvidenceBundle.manifest.payload.sha256
|
|
32112
|
-
},
|
|
32113
|
-
producer,
|
|
32114
|
-
activeStrategies: activeRuntimeEvidenceStrategies(deployment).map(
|
|
32115
|
-
({ strategyName }) => strategyName
|
|
32116
|
-
),
|
|
32117
|
-
cycleCount,
|
|
32118
|
-
safety: {
|
|
32119
|
-
cacheOnly: true,
|
|
32120
|
-
externalOrderPlacement: false,
|
|
32121
|
-
redis: "isolated",
|
|
32122
|
-
timescale: "read_only"
|
|
32123
|
-
},
|
|
32124
|
-
payloads: {
|
|
32125
|
-
replayEvidence: {
|
|
32126
|
-
file: RUNTIME_FEEDBACK_REPLAY_FILE,
|
|
32127
|
-
sha256: sha2563(replayPayload),
|
|
32128
|
-
bytes: replayPayload.byteLength
|
|
32129
|
-
},
|
|
32130
|
-
log: {
|
|
32131
|
-
file: RUNTIME_FEEDBACK_LOG_FILE,
|
|
32132
|
-
sha256: sha2563(logPayload),
|
|
32133
|
-
bytes: logPayload.byteLength
|
|
32134
|
-
}
|
|
32135
|
-
}
|
|
32136
|
-
};
|
|
32137
|
-
await import_promises29.default.writeFile(
|
|
32138
|
-
import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_MANIFEST_FILE),
|
|
32139
|
-
`${JSON.stringify(manifest, null, 2)}
|
|
32140
|
-
`,
|
|
32141
|
-
"utf8"
|
|
32142
|
-
);
|
|
32143
|
-
await import_promises29.default.writeFile(
|
|
32144
|
-
import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_COMPLETE_FILE),
|
|
32145
|
-
`${artifactId}
|
|
32146
|
-
`,
|
|
32147
|
-
"utf8"
|
|
32148
|
-
);
|
|
32149
|
-
return verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
32150
|
-
};
|
|
32151
|
-
verifyRuntimeFeedbackReplayBundle = async (bundleDir) => {
|
|
32152
|
-
const manifestPath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_MANIFEST_FILE);
|
|
32153
|
-
const replayEvidencePath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_REPLAY_FILE);
|
|
32154
|
-
const logPath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_LOG_FILE);
|
|
32155
|
-
const completePath = import_node_path24.default.join(bundleDir, RUNTIME_FEEDBACK_COMPLETE_FILE);
|
|
32156
|
-
const [manifestText, replayPayload, logPayload, completeText] = await Promise.all([
|
|
32157
|
-
import_promises29.default.readFile(manifestPath, "utf8"),
|
|
32158
|
-
import_promises29.default.readFile(replayEvidencePath),
|
|
32159
|
-
import_promises29.default.readFile(logPath),
|
|
32160
|
-
import_promises29.default.readFile(completePath, "utf8")
|
|
32161
|
-
]);
|
|
32162
|
-
const manifest = parseManifest2(JSON.parse(manifestText));
|
|
32163
|
-
if (completeText.trim() !== manifest.artifactId) {
|
|
32164
|
-
throw new Error(`Invalid runtime feedback completion marker: ${bundleDir}`);
|
|
32165
|
-
}
|
|
32166
|
-
for (const [payload, descriptor] of [
|
|
32167
|
-
[replayPayload, manifest.payloads.replayEvidence],
|
|
32168
|
-
[logPayload, manifest.payloads.log]
|
|
32169
|
-
]) {
|
|
32170
|
-
if (payload.byteLength !== descriptor.bytes) {
|
|
32171
|
-
throw new Error(
|
|
32172
|
-
`Runtime feedback payload size mismatch: ${descriptor.file}`
|
|
32173
|
-
);
|
|
32174
|
-
}
|
|
32175
|
-
if (sha2563(payload) !== descriptor.sha256) {
|
|
32176
|
-
throw new Error(
|
|
32177
|
-
`Runtime feedback payload checksum mismatch: ${descriptor.file}`
|
|
32178
|
-
);
|
|
32179
|
-
}
|
|
32180
|
-
}
|
|
32181
|
-
const replayEvidence = JSON.parse(replayPayload.toString("utf8"));
|
|
32182
|
-
if (replayEvidence.reportType !== "replay-runtime-evidence") {
|
|
32183
|
-
throw new Error("Invalid runtime feedback replay evidence payload");
|
|
32184
|
-
}
|
|
32185
|
-
const replayWindow = isRecord3(replayEvidence.window) ? replayEvidence.window : null;
|
|
32186
|
-
const replay = isRecord3(replayEvidence.replay) ? replayEvidence.replay : null;
|
|
32187
|
-
const replayDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
32188
|
-
replayEvidence.deployment
|
|
32189
|
-
);
|
|
32190
|
-
const replayStrategies = activeRuntimeEvidenceStrategies(replayDeployment).map(({ strategyName }) => strategyName).sort();
|
|
32191
|
-
if (replayEvidence.userName !== manifest.userName || replayWindow?.startTime !== manifest.window.startTime || replayWindow.endTime !== manifest.window.endTime || replayDeployment.id !== manifest.deploymentId || replayDeployment.deploymentCompositionId !== manifest.deploymentCompositionId || Number(replay?.cycleCount) !== manifest.cycleCount || JSON.stringify(replayStrategies) !== JSON.stringify([...manifest.activeStrategies].sort())) {
|
|
32192
|
-
throw new Error("Runtime feedback replay payload does not match manifest");
|
|
32193
|
-
}
|
|
32194
|
-
return {
|
|
32195
|
-
bundleDir,
|
|
32196
|
-
manifestPath,
|
|
32197
|
-
replayEvidencePath,
|
|
32198
|
-
logPath,
|
|
32199
|
-
manifest,
|
|
32200
|
-
replayEvidence
|
|
32201
|
-
};
|
|
32202
|
-
};
|
|
32203
|
-
discoverRuntimeFeedbackReplayBundles = async (rootDir) => {
|
|
32204
|
-
const bundles = [];
|
|
32205
|
-
const visit = async (directory, depth) => {
|
|
32206
|
-
if (depth > 10) return;
|
|
32207
|
-
let entries;
|
|
32208
|
-
try {
|
|
32209
|
-
entries = await import_promises29.default.readdir(directory, { withFileTypes: true });
|
|
32210
|
-
} catch (error) {
|
|
32211
|
-
if (error.code === "ENOENT") return;
|
|
32212
|
-
throw error;
|
|
32213
|
-
}
|
|
32214
|
-
const names = new Set(entries.map((entry) => entry.name));
|
|
32215
|
-
if (names.has(RUNTIME_FEEDBACK_MANIFEST_FILE) && names.has(RUNTIME_FEEDBACK_REPLAY_FILE) && names.has(RUNTIME_FEEDBACK_LOG_FILE) && names.has(RUNTIME_FEEDBACK_COMPLETE_FILE)) {
|
|
32216
|
-
bundles.push(directory);
|
|
32217
|
-
return;
|
|
32218
|
-
}
|
|
32219
|
-
await Promise.all(
|
|
32220
|
-
entries.filter(
|
|
32221
|
-
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
32222
|
-
).map((entry) => visit(import_node_path24.default.join(directory, entry.name), depth + 1))
|
|
32223
|
-
);
|
|
32224
|
-
};
|
|
32225
|
-
await visit(rootDir, 0);
|
|
32226
|
-
return bundles.sort();
|
|
32227
|
-
};
|
|
32228
|
-
verifyRuntimeFeedbackReplaySource = async ({
|
|
32229
|
-
bundleDir,
|
|
32230
|
-
runtimeEvidenceBundleDir
|
|
32231
|
-
}) => {
|
|
32232
|
-
const [feedback, runtimeEvidence2] = await Promise.all([
|
|
32233
|
-
verifyRuntimeFeedbackReplayBundle(bundleDir),
|
|
32234
|
-
verifyRuntimeEvidenceBundle(runtimeEvidenceBundleDir)
|
|
32235
|
-
]);
|
|
32236
|
-
if (feedback.manifest.runtimeEvidence.artifactId !== runtimeEvidence2.manifest.artifactId || feedback.manifest.runtimeEvidence.payloadSha256 !== runtimeEvidence2.manifest.payload.sha256) {
|
|
32237
|
-
throw new Error("Runtime feedback bundle references different evidence");
|
|
32238
|
-
}
|
|
32239
|
-
assertReplayMatchesRuntimeEvidence({
|
|
32240
|
-
replayEvidence: feedback.replayEvidence,
|
|
32241
|
-
runtimeEvidence: runtimeEvidence2
|
|
32242
|
-
});
|
|
32243
|
-
return { feedback, runtimeEvidence: runtimeEvidence2 };
|
|
32244
|
-
};
|
|
31683
|
+
__reExport(runtimeFeedbackArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
32245
31684
|
}
|
|
32246
31685
|
});
|
|
32247
31686
|
|
|
32248
31687
|
// src/lib/runtimeFeedbackReplay.ts
|
|
32249
|
-
var
|
|
31688
|
+
var import_node_child_process7, import_promises28, import_node_path22, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
|
|
32250
31689
|
var init_runtimeFeedbackReplay = __esm({
|
|
32251
31690
|
"src/lib/runtimeFeedbackReplay.ts"() {
|
|
32252
31691
|
"use strict";
|
|
32253
|
-
|
|
32254
|
-
|
|
32255
|
-
|
|
31692
|
+
import_node_child_process7 = require("child_process");
|
|
31693
|
+
import_promises28 = __toESM(require("fs/promises"));
|
|
31694
|
+
import_node_path22 = __toESM(require("path"));
|
|
32256
31695
|
init_runtimeEvidenceDeployment();
|
|
32257
31696
|
init_runtimeEvidenceArtifacts();
|
|
32258
31697
|
init_runtimeEvidenceProducer();
|
|
@@ -32287,7 +31726,7 @@ var init_runtimeFeedbackReplay = __esm({
|
|
|
32287
31726
|
"localhost",
|
|
32288
31727
|
"redis"
|
|
32289
31728
|
]);
|
|
32290
|
-
|
|
31729
|
+
safeSegment = (value, fallback) => {
|
|
32291
31730
|
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
32292
31731
|
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
32293
31732
|
};
|
|
@@ -32385,7 +31824,7 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32385
31824
|
await logHandle.write(chunk);
|
|
32386
31825
|
});
|
|
32387
31826
|
};
|
|
32388
|
-
const child = (0,
|
|
31827
|
+
const child = (0, import_node_child_process7.spawn)(executable, command, {
|
|
32389
31828
|
cwd,
|
|
32390
31829
|
env,
|
|
32391
31830
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -32427,18 +31866,18 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32427
31866
|
if (!cliPath) {
|
|
32428
31867
|
throw new Error("Cannot resolve the TradeJS CLI executable path");
|
|
32429
31868
|
}
|
|
32430
|
-
const runtimeEvidenceBundle = await verifyRuntimeEvidenceBundle(
|
|
32431
|
-
|
|
31869
|
+
const runtimeEvidenceBundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(
|
|
31870
|
+
import_node_path22.default.dirname(runtimeEvidencePath)
|
|
32432
31871
|
);
|
|
32433
|
-
if (
|
|
31872
|
+
if (import_node_path22.default.resolve(runtimeEvidenceBundle.payloadPath) !== runtimeEvidencePath) {
|
|
32434
31873
|
throw new Error(
|
|
32435
31874
|
`Runtime evidence must be the verified bundle payload: ${runtimeEvidenceBundle.payloadPath}`
|
|
32436
31875
|
);
|
|
32437
31876
|
}
|
|
32438
|
-
const deployedProducer = parseRuntimeEvidenceProducer(
|
|
31877
|
+
const deployedProducer = (0, runtimeEvidenceProducer_exports.parseRuntimeEvidenceProducer)(
|
|
32439
31878
|
runtimeEvidenceBundle.artifact.producer
|
|
32440
31879
|
);
|
|
32441
|
-
const currentProducer = await resolveRuntimeEvidenceProducer({
|
|
31880
|
+
const currentProducer = await (0, runtimeEvidenceProducer_exports.resolveRuntimeEvidenceProducer)({
|
|
32442
31881
|
projectRoot: projectRoot18,
|
|
32443
31882
|
required: true
|
|
32444
31883
|
});
|
|
@@ -32447,10 +31886,10 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32447
31886
|
"Runtime feedback replay image identity does not match runtime evidence"
|
|
32448
31887
|
);
|
|
32449
31888
|
}
|
|
32450
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
31889
|
+
const deployment = (0, runtimeEvidenceDeployment_exports.parseRuntimeEvidenceDeploymentSnapshot)(
|
|
32451
31890
|
runtimeEvidenceBundle.artifact.deployment
|
|
32452
31891
|
);
|
|
32453
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
31892
|
+
const activeStrategies = (0, runtimeEvidenceDeployment_exports.activeRuntimeEvidenceStrategies)(deployment);
|
|
32454
31893
|
const intervals = new Set(
|
|
32455
31894
|
activeStrategies.map(({ interval: interval4 }) => String(interval4))
|
|
32456
31895
|
);
|
|
@@ -32459,16 +31898,16 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32459
31898
|
`Runtime feedback replay requires one interval, received ${[...intervals].join(",")}`
|
|
32460
31899
|
);
|
|
32461
31900
|
}
|
|
32462
|
-
await
|
|
32463
|
-
const existing = await
|
|
31901
|
+
await import_promises28.default.mkdir(outDir, { recursive: true });
|
|
31902
|
+
const existing = await import_promises28.default.readdir(outDir);
|
|
32464
31903
|
if (existing.length) {
|
|
32465
31904
|
throw new Error(
|
|
32466
31905
|
`Runtime feedback output directory must be empty: ${outDir}`
|
|
32467
31906
|
);
|
|
32468
31907
|
}
|
|
32469
|
-
const replayEvidencePath =
|
|
32470
|
-
const logHandle = await
|
|
32471
|
-
|
|
31908
|
+
const replayEvidencePath = import_node_path22.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_REPLAY_FILE);
|
|
31909
|
+
const logHandle = await import_promises28.default.open(
|
|
31910
|
+
import_node_path22.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_LOG_FILE),
|
|
32472
31911
|
"wx"
|
|
32473
31912
|
);
|
|
32474
31913
|
const commands = buildRuntimeFeedbackReplayCommands({
|
|
@@ -32495,9 +31934,9 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32495
31934
|
} finally {
|
|
32496
31935
|
await logHandle.close();
|
|
32497
31936
|
}
|
|
32498
|
-
return sealRuntimeFeedbackReplayBundle({
|
|
31937
|
+
return (0, runtimeFeedbackArtifacts_exports.sealRuntimeFeedbackReplayBundle)({
|
|
32499
31938
|
bundleDir: outDir,
|
|
32500
|
-
runId:
|
|
31939
|
+
runId: safeSegment(runId, "run"),
|
|
32501
31940
|
runtimeEvidenceBundle
|
|
32502
31941
|
});
|
|
32503
31942
|
};
|
|
@@ -32507,14 +31946,14 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32507
31946
|
// src/scripts/runtimeFeedbackReplay.ts
|
|
32508
31947
|
var runtimeFeedbackReplay_exports = {};
|
|
32509
31948
|
__export(runtimeFeedbackReplay_exports, {
|
|
32510
|
-
main: () =>
|
|
31949
|
+
main: () => main37,
|
|
32511
31950
|
runtimeFeedbackReplay: () => runtimeFeedbackReplay
|
|
32512
31951
|
});
|
|
32513
|
-
var
|
|
31952
|
+
var import_node_path23, import_args28, import_chalk44, flags25, projectRoot9, runtimeFeedbackReplay, main37;
|
|
32514
31953
|
var init_runtimeFeedbackReplay2 = __esm({
|
|
32515
31954
|
"src/scripts/runtimeFeedbackReplay.ts"() {
|
|
32516
31955
|
"use strict";
|
|
32517
|
-
|
|
31956
|
+
import_node_path23 = __toESM(require("path"));
|
|
32518
31957
|
import_args28 = __toESM(require("args"));
|
|
32519
31958
|
import_chalk44 = __toESM(require("chalk"));
|
|
32520
31959
|
init_runtimeFeedbackReplay();
|
|
@@ -32532,8 +31971,8 @@ var init_runtimeFeedbackReplay2 = __esm({
|
|
|
32532
31971
|
);
|
|
32533
31972
|
}
|
|
32534
31973
|
const verified = await runRuntimeFeedbackReplay({
|
|
32535
|
-
runtimeEvidencePath:
|
|
32536
|
-
outDir:
|
|
31974
|
+
runtimeEvidencePath: import_node_path23.default.resolve(projectRoot9, runtimeEvidence2),
|
|
31975
|
+
outDir: import_node_path23.default.resolve(projectRoot9, outDir),
|
|
32537
31976
|
runId: String(flags25.runId ?? "").trim() || void 0,
|
|
32538
31977
|
projectRoot: projectRoot9
|
|
32539
31978
|
});
|
|
@@ -32554,20 +31993,20 @@ var init_runtimeFeedbackReplay2 = __esm({
|
|
|
32554
31993
|
)
|
|
32555
31994
|
);
|
|
32556
31995
|
};
|
|
32557
|
-
|
|
31996
|
+
main37 = runtimeFeedbackReplay;
|
|
32558
31997
|
}
|
|
32559
31998
|
});
|
|
32560
31999
|
|
|
32561
32000
|
// src/lib/runtimeFeedbackNotification.ts
|
|
32562
|
-
var
|
|
32001
|
+
var isRecord, asRecord6, asArray3, finiteNumber5, requiredTimestamp, escapeHtml5, formatMskDateTime2, formatConnectorName, sumRows, buildRuntimeFeedbackTelegramMessage, notifyRuntimeFeedbackBundle;
|
|
32563
32002
|
var init_runtimeFeedbackNotification = __esm({
|
|
32564
32003
|
"src/lib/runtimeFeedbackNotification.ts"() {
|
|
32565
32004
|
"use strict";
|
|
32566
32005
|
init_runtimeFeedbackArtifacts();
|
|
32567
32006
|
init_telegramReports();
|
|
32568
|
-
|
|
32569
|
-
|
|
32570
|
-
asArray3 = (value) => Array.isArray(value) ? value.map(
|
|
32007
|
+
isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
32008
|
+
asRecord6 = (value) => isRecord(value) ? value : {};
|
|
32009
|
+
asArray3 = (value) => Array.isArray(value) ? value.map(asRecord6) : [];
|
|
32571
32010
|
finiteNumber5 = (value, fallback = 0) => {
|
|
32572
32011
|
const number = Number(value);
|
|
32573
32012
|
return Number.isFinite(number) ? number : fallback;
|
|
@@ -32598,18 +32037,18 @@ var init_runtimeFeedbackNotification = __esm({
|
|
|
32598
32037
|
if (replayEvidence.reportType !== "replay-runtime-evidence") {
|
|
32599
32038
|
throw new Error("Invalid runtime feedback replay evidence payload");
|
|
32600
32039
|
}
|
|
32601
|
-
const window =
|
|
32040
|
+
const window = asRecord6(replayEvidence.window);
|
|
32602
32041
|
const startTime = requiredTimestamp(window.startTime, "window.startTime");
|
|
32603
32042
|
const endTime = requiredTimestamp(window.endTime, "window.endTime");
|
|
32604
|
-
const deployment =
|
|
32605
|
-
const replay =
|
|
32606
|
-
if (!
|
|
32043
|
+
const deployment = asRecord6(replayEvidence.deployment);
|
|
32044
|
+
const replay = asRecord6(replayEvidence.replay);
|
|
32045
|
+
if (!isRecord(replay.runtimeComparison) || !isRecord(replay.runtimeComparison.counts) || !Array.isArray(replay.runtimeComparison.rows) || !isRecord(replay.runtimeComparison.lineage)) {
|
|
32607
32046
|
throw new Error("Runtime feedback replay comparison is missing");
|
|
32608
32047
|
}
|
|
32609
|
-
const comparison =
|
|
32610
|
-
const comparisonCounts =
|
|
32611
|
-
const runtimeCounts =
|
|
32612
|
-
const lineage =
|
|
32048
|
+
const comparison = asRecord6(replay.runtimeComparison);
|
|
32049
|
+
const comparisonCounts = asRecord6(comparison.counts);
|
|
32050
|
+
const runtimeCounts = asRecord6(asRecord6(replayEvidence.runtime).counts);
|
|
32051
|
+
const lineage = asRecord6(comparison.lineage);
|
|
32613
32052
|
const rows = asArray3(comparison.rows);
|
|
32614
32053
|
const matched = finiteNumber5(comparisonCounts.matched);
|
|
32615
32054
|
const runtimeOnly = finiteNumber5(comparisonCounts.runtimeOnly);
|
|
@@ -32673,7 +32112,7 @@ var init_runtimeFeedbackNotification = __esm({
|
|
|
32673
32112
|
bundleDir,
|
|
32674
32113
|
send = sendTelegramReport
|
|
32675
32114
|
}) => {
|
|
32676
|
-
const verified = await verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
32115
|
+
const verified = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(bundleDir);
|
|
32677
32116
|
const message = buildRuntimeFeedbackTelegramMessage(verified.replayEvidence);
|
|
32678
32117
|
await send(message, { userName: verified.manifest.userName });
|
|
32679
32118
|
return {
|
|
@@ -32688,14 +32127,14 @@ var init_runtimeFeedbackNotification = __esm({
|
|
|
32688
32127
|
// src/scripts/runtimeFeedbackNotify.ts
|
|
32689
32128
|
var runtimeFeedbackNotify_exports = {};
|
|
32690
32129
|
__export(runtimeFeedbackNotify_exports, {
|
|
32691
|
-
main: () =>
|
|
32130
|
+
main: () => main38,
|
|
32692
32131
|
runtimeFeedbackNotify: () => runtimeFeedbackNotify
|
|
32693
32132
|
});
|
|
32694
|
-
var
|
|
32133
|
+
var import_node_path24, import_args29, import_chalk45, flags26, projectRoot10, runtimeFeedbackNotify, main38;
|
|
32695
32134
|
var init_runtimeFeedbackNotify = __esm({
|
|
32696
32135
|
"src/scripts/runtimeFeedbackNotify.ts"() {
|
|
32697
32136
|
"use strict";
|
|
32698
|
-
|
|
32137
|
+
import_node_path24 = __toESM(require("path"));
|
|
32699
32138
|
import_args29 = __toESM(require("args"));
|
|
32700
32139
|
import_chalk45 = __toESM(require("chalk"));
|
|
32701
32140
|
init_runtimeFeedbackNotification();
|
|
@@ -32709,9 +32148,9 @@ var init_runtimeFeedbackNotify = __esm({
|
|
|
32709
32148
|
if (!bundle) {
|
|
32710
32149
|
throw new Error("Provide --bundle for runtime feedback notification.");
|
|
32711
32150
|
}
|
|
32712
|
-
const bundleDir =
|
|
32151
|
+
const bundleDir = import_node_path24.default.resolve(projectRoot10, bundle);
|
|
32713
32152
|
if (flags26.dryRun) {
|
|
32714
|
-
const verified = await verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
32153
|
+
const verified = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(bundleDir);
|
|
32715
32154
|
console.log(buildRuntimeFeedbackTelegramMessage(verified.replayEvidence));
|
|
32716
32155
|
return;
|
|
32717
32156
|
}
|
|
@@ -32720,32 +32159,32 @@ var init_runtimeFeedbackNotify = __esm({
|
|
|
32720
32159
|
import_chalk45.default.green(`Runtime feedback notification sent: ${result.artifactId}`)
|
|
32721
32160
|
);
|
|
32722
32161
|
};
|
|
32723
|
-
|
|
32162
|
+
main38 = runtimeFeedbackNotify;
|
|
32724
32163
|
}
|
|
32725
32164
|
});
|
|
32726
32165
|
|
|
32727
32166
|
// src/lib/runtimeEvidenceSync.ts
|
|
32728
|
-
var
|
|
32167
|
+
var import_node_child_process8, import_promises29, import_node_path25, import_node_util, execFileAsync, isExistingDestinationError, safeSegment2, withTrailingSlash, dateParts, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
|
|
32729
32168
|
var init_runtimeEvidenceSync = __esm({
|
|
32730
32169
|
"src/lib/runtimeEvidenceSync.ts"() {
|
|
32731
32170
|
"use strict";
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32171
|
+
import_node_child_process8 = require("child_process");
|
|
32172
|
+
import_promises29 = __toESM(require("fs/promises"));
|
|
32173
|
+
import_node_path25 = __toESM(require("path"));
|
|
32735
32174
|
import_node_util = require("util");
|
|
32736
32175
|
init_runtimeEvidenceArtifacts();
|
|
32737
32176
|
init_runtimeEvidenceDeployment();
|
|
32738
|
-
execFileAsync = (0, import_node_util.promisify)(
|
|
32739
|
-
|
|
32177
|
+
execFileAsync = (0, import_node_util.promisify)(import_node_child_process8.execFile);
|
|
32178
|
+
isExistingDestinationError = (error) => {
|
|
32740
32179
|
const code = error.code;
|
|
32741
32180
|
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
32742
32181
|
};
|
|
32743
|
-
|
|
32182
|
+
safeSegment2 = (value, fallback) => {
|
|
32744
32183
|
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
32745
32184
|
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
32746
32185
|
};
|
|
32747
32186
|
withTrailingSlash = (value) => value.endsWith("/") ? value : `${value}/`;
|
|
32748
|
-
|
|
32187
|
+
dateParts = (timestamp) => {
|
|
32749
32188
|
const date = new Date(timestamp);
|
|
32750
32189
|
return [
|
|
32751
32190
|
String(date.getUTCFullYear()),
|
|
@@ -32765,23 +32204,23 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32765
32204
|
withTrailingSlash(source),
|
|
32766
32205
|
withTrailingSlash(destination)
|
|
32767
32206
|
];
|
|
32768
|
-
receiptPath = (receiptsRoot, artifactId) =>
|
|
32207
|
+
receiptPath = (receiptsRoot, artifactId) => import_node_path25.default.join(receiptsRoot, `${safeSegment2(artifactId, "artifact")}.json`);
|
|
32769
32208
|
compareBundles = (left, right) => left.manifest.window.endTime - right.manifest.window.endTime || left.manifest.createdAt - right.manifest.createdAt;
|
|
32770
32209
|
listPendingRuntimeEvidenceBundles = async ({
|
|
32771
32210
|
evidenceRoot,
|
|
32772
32211
|
deploymentId
|
|
32773
32212
|
}) => {
|
|
32774
|
-
const safeDeploymentId =
|
|
32775
|
-
const artifactsRoot =
|
|
32776
|
-
const receiptsRoot =
|
|
32777
|
-
const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
|
|
32213
|
+
const safeDeploymentId = safeSegment2(deploymentId, "production");
|
|
32214
|
+
const artifactsRoot = import_node_path25.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
32215
|
+
const receiptsRoot = import_node_path25.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
32216
|
+
const bundles = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(artifactsRoot);
|
|
32778
32217
|
const pending = [];
|
|
32779
32218
|
for (const bundleDir of bundles) {
|
|
32780
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
32219
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
32781
32220
|
if (verified.manifest.deploymentId !== safeDeploymentId) continue;
|
|
32782
|
-
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
32221
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
|
|
32783
32222
|
try {
|
|
32784
|
-
await
|
|
32223
|
+
await import_promises29.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
|
|
32785
32224
|
continue;
|
|
32786
32225
|
} catch (error) {
|
|
32787
32226
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -32797,14 +32236,14 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32797
32236
|
scorecardPath,
|
|
32798
32237
|
runtimeFeedback
|
|
32799
32238
|
}) => {
|
|
32800
|
-
const safeDeploymentId =
|
|
32801
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
32239
|
+
const safeDeploymentId = safeSegment2(deploymentId, "production");
|
|
32240
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
32802
32241
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
32803
32242
|
throw new Error(
|
|
32804
32243
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
32805
32244
|
);
|
|
32806
32245
|
}
|
|
32807
|
-
const receiptsRoot =
|
|
32246
|
+
const receiptsRoot = import_node_path25.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
32808
32247
|
const finalPath = receiptPath(receiptsRoot, verified.manifest.artifactId);
|
|
32809
32248
|
const temporaryPath = `${finalPath}.tmp-${process.pid}`;
|
|
32810
32249
|
const receipt = {
|
|
@@ -32818,14 +32257,14 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32818
32257
|
replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
|
|
32819
32258
|
} : {}
|
|
32820
32259
|
};
|
|
32821
|
-
await
|
|
32822
|
-
await
|
|
32260
|
+
await import_promises29.default.mkdir(receiptsRoot, { recursive: true });
|
|
32261
|
+
await import_promises29.default.writeFile(
|
|
32823
32262
|
temporaryPath,
|
|
32824
32263
|
`${JSON.stringify(receipt, null, 2)}
|
|
32825
32264
|
`,
|
|
32826
32265
|
"utf8"
|
|
32827
32266
|
);
|
|
32828
|
-
await
|
|
32267
|
+
await import_promises29.default.rename(temporaryPath, finalPath);
|
|
32829
32268
|
return finalPath;
|
|
32830
32269
|
};
|
|
32831
32270
|
syncRuntimeEvidenceBundles = async ({
|
|
@@ -32839,47 +32278,47 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32839
32278
|
return { stdout: result.stdout, stderr: result.stderr };
|
|
32840
32279
|
}
|
|
32841
32280
|
}) => {
|
|
32842
|
-
const safeDeploymentId =
|
|
32843
|
-
const inboxRoot =
|
|
32844
|
-
const artifactsRoot =
|
|
32281
|
+
const safeDeploymentId = safeSegment2(deploymentId, "production");
|
|
32282
|
+
const inboxRoot = import_node_path25.default.join(evidenceRoot, "inbox", safeDeploymentId);
|
|
32283
|
+
const artifactsRoot = import_node_path25.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
32845
32284
|
await Promise.all([
|
|
32846
|
-
|
|
32847
|
-
|
|
32285
|
+
import_promises29.default.mkdir(inboxRoot, { recursive: true }),
|
|
32286
|
+
import_promises29.default.mkdir(artifactsRoot, { recursive: true })
|
|
32848
32287
|
]);
|
|
32849
32288
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
32850
32289
|
source,
|
|
32851
32290
|
destination: inboxRoot
|
|
32852
32291
|
});
|
|
32853
32292
|
const transfer = await runRsync(rsyncArgs);
|
|
32854
|
-
const discovered = await discoverRuntimeEvidenceBundles(inboxRoot);
|
|
32293
|
+
const discovered = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(inboxRoot);
|
|
32855
32294
|
const received = [];
|
|
32856
32295
|
for (const bundleDir of discovered) {
|
|
32857
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
32296
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
32858
32297
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
32859
32298
|
throw new Error(
|
|
32860
32299
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
32861
32300
|
);
|
|
32862
32301
|
}
|
|
32863
|
-
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
32864
|
-
const destinationDir =
|
|
32302
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
|
|
32303
|
+
const destinationDir = import_node_path25.default.join(
|
|
32865
32304
|
artifactsRoot,
|
|
32866
|
-
...
|
|
32867
|
-
|
|
32305
|
+
...dateParts(verified.manifest.window.endTime),
|
|
32306
|
+
safeSegment2(verified.manifest.artifactId, "artifact")
|
|
32868
32307
|
);
|
|
32869
|
-
await
|
|
32308
|
+
await import_promises29.default.mkdir(import_node_path25.default.dirname(destinationDir), { recursive: true });
|
|
32870
32309
|
try {
|
|
32871
|
-
await
|
|
32310
|
+
await import_promises29.default.rename(bundleDir, destinationDir);
|
|
32872
32311
|
} catch (error) {
|
|
32873
|
-
if (!
|
|
32874
|
-
const existing = await verifyRuntimeEvidenceBundle(destinationDir);
|
|
32312
|
+
if (!isExistingDestinationError(error)) throw error;
|
|
32313
|
+
const existing = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir);
|
|
32875
32314
|
if (existing.manifest.payload.sha256 !== verified.manifest.payload.sha256) {
|
|
32876
32315
|
throw new Error(
|
|
32877
32316
|
`Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
|
|
32878
32317
|
);
|
|
32879
32318
|
}
|
|
32880
|
-
await
|
|
32319
|
+
await import_promises29.default.rm(bundleDir, { recursive: true, force: true });
|
|
32881
32320
|
}
|
|
32882
|
-
received.push(await verifyRuntimeEvidenceBundle(destinationDir));
|
|
32321
|
+
received.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir));
|
|
32883
32322
|
}
|
|
32884
32323
|
const pending = await listPendingRuntimeEvidenceBundles({
|
|
32885
32324
|
evidenceRoot,
|
|
@@ -32897,26 +32336,26 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32897
32336
|
});
|
|
32898
32337
|
|
|
32899
32338
|
// src/lib/runtimeFeedbackSync.ts
|
|
32900
|
-
var
|
|
32339
|
+
var import_node_child_process9, import_promises30, import_node_path26, import_node_util2, execFileAsync2, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
|
|
32901
32340
|
var init_runtimeFeedbackSync = __esm({
|
|
32902
32341
|
"src/lib/runtimeFeedbackSync.ts"() {
|
|
32903
32342
|
"use strict";
|
|
32904
|
-
|
|
32905
|
-
|
|
32906
|
-
|
|
32343
|
+
import_node_child_process9 = require("child_process");
|
|
32344
|
+
import_promises30 = __toESM(require("fs/promises"));
|
|
32345
|
+
import_node_path26 = __toESM(require("path"));
|
|
32907
32346
|
import_node_util2 = require("util");
|
|
32908
32347
|
init_runtimeFeedbackArtifacts();
|
|
32909
32348
|
init_runtimeEvidenceSync();
|
|
32910
|
-
execFileAsync2 = (0, import_node_util2.promisify)(
|
|
32911
|
-
|
|
32349
|
+
execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process9.execFile);
|
|
32350
|
+
isExistingDestinationError2 = (error) => {
|
|
32912
32351
|
const code = error.code;
|
|
32913
32352
|
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
32914
32353
|
};
|
|
32915
|
-
|
|
32354
|
+
safeSegment3 = (value, fallback) => {
|
|
32916
32355
|
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
32917
32356
|
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
32918
32357
|
};
|
|
32919
|
-
|
|
32358
|
+
dateParts2 = (timestamp) => {
|
|
32920
32359
|
const date = new Date(timestamp);
|
|
32921
32360
|
return [
|
|
32922
32361
|
String(date.getUTCFullYear()),
|
|
@@ -32935,47 +32374,47 @@ var init_runtimeFeedbackSync = __esm({
|
|
|
32935
32374
|
return { stdout: result.stdout, stderr: result.stderr };
|
|
32936
32375
|
}
|
|
32937
32376
|
}) => {
|
|
32938
|
-
const safeDeploymentId =
|
|
32939
|
-
const inboxRoot =
|
|
32940
|
-
const artifactsRoot =
|
|
32377
|
+
const safeDeploymentId = safeSegment3(deploymentId, "production");
|
|
32378
|
+
const inboxRoot = import_node_path26.default.join(feedbackRoot, "inbox", safeDeploymentId);
|
|
32379
|
+
const artifactsRoot = import_node_path26.default.join(feedbackRoot, "artifacts", safeDeploymentId);
|
|
32941
32380
|
await Promise.all([
|
|
32942
|
-
|
|
32943
|
-
|
|
32381
|
+
import_promises30.default.mkdir(inboxRoot, { recursive: true }),
|
|
32382
|
+
import_promises30.default.mkdir(artifactsRoot, { recursive: true })
|
|
32944
32383
|
]);
|
|
32945
32384
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
32946
32385
|
source,
|
|
32947
32386
|
destination: inboxRoot
|
|
32948
32387
|
});
|
|
32949
32388
|
const transfer = await runRsync(rsyncArgs);
|
|
32950
|
-
const discovered = await discoverRuntimeFeedbackReplayBundles(inboxRoot);
|
|
32389
|
+
const discovered = await (0, runtimeFeedbackArtifacts_exports.discoverRuntimeFeedbackReplayBundles)(inboxRoot);
|
|
32951
32390
|
const received = [];
|
|
32952
32391
|
for (const bundleDir of discovered) {
|
|
32953
|
-
const verified = await verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
32392
|
+
const verified = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(bundleDir);
|
|
32954
32393
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
32955
32394
|
throw new Error(
|
|
32956
32395
|
`Runtime feedback deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
32957
32396
|
);
|
|
32958
32397
|
}
|
|
32959
|
-
const destinationDir =
|
|
32398
|
+
const destinationDir = import_node_path26.default.join(
|
|
32960
32399
|
artifactsRoot,
|
|
32961
|
-
...
|
|
32962
|
-
|
|
32963
|
-
|
|
32400
|
+
...dateParts2(verified.manifest.window.endTime),
|
|
32401
|
+
safeSegment3(verified.manifest.runtimeEvidence.artifactId, "artifact"),
|
|
32402
|
+
safeSegment3(verified.manifest.runId, "run")
|
|
32964
32403
|
);
|
|
32965
|
-
await
|
|
32404
|
+
await import_promises30.default.mkdir(import_node_path26.default.dirname(destinationDir), { recursive: true });
|
|
32966
32405
|
try {
|
|
32967
|
-
await
|
|
32406
|
+
await import_promises30.default.rename(bundleDir, destinationDir);
|
|
32968
32407
|
} catch (error) {
|
|
32969
|
-
if (!
|
|
32970
|
-
const existing = await verifyRuntimeFeedbackReplayBundle(destinationDir);
|
|
32408
|
+
if (!isExistingDestinationError2(error)) throw error;
|
|
32409
|
+
const existing = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir);
|
|
32971
32410
|
if (existing.manifest.payloads.replayEvidence.sha256 !== verified.manifest.payloads.replayEvidence.sha256) {
|
|
32972
32411
|
throw new Error(
|
|
32973
32412
|
`Conflicting runtime feedback replay ${verified.manifest.artifactId}`
|
|
32974
32413
|
);
|
|
32975
32414
|
}
|
|
32976
|
-
await
|
|
32415
|
+
await import_promises30.default.rm(bundleDir, { recursive: true, force: true });
|
|
32977
32416
|
}
|
|
32978
|
-
received.push(await verifyRuntimeFeedbackReplayBundle(destinationDir));
|
|
32417
|
+
received.push(await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir));
|
|
32979
32418
|
}
|
|
32980
32419
|
return {
|
|
32981
32420
|
rsyncArgs,
|
|
@@ -32990,14 +32429,14 @@ var init_runtimeFeedbackSync = __esm({
|
|
|
32990
32429
|
// src/scripts/runtimeFeedbackSync.ts
|
|
32991
32430
|
var runtimeFeedbackSync_exports = {};
|
|
32992
32431
|
__export(runtimeFeedbackSync_exports, {
|
|
32993
|
-
main: () =>
|
|
32432
|
+
main: () => main39,
|
|
32994
32433
|
runtimeFeedbackSync: () => runtimeFeedbackSync
|
|
32995
32434
|
});
|
|
32996
|
-
var
|
|
32435
|
+
var import_node_path27, import_args30, import_chalk46, flags27, projectRoot11, runtimeFeedbackSync, main39;
|
|
32997
32436
|
var init_runtimeFeedbackSync2 = __esm({
|
|
32998
32437
|
"src/scripts/runtimeFeedbackSync.ts"() {
|
|
32999
32438
|
"use strict";
|
|
33000
|
-
|
|
32439
|
+
import_node_path27 = __toESM(require("path"));
|
|
33001
32440
|
import_args30 = __toESM(require("args"));
|
|
33002
32441
|
import_chalk46 = __toESM(require("chalk"));
|
|
33003
32442
|
init_runtimeFeedbackSync();
|
|
@@ -33025,7 +32464,7 @@ var init_runtimeFeedbackSync2 = __esm({
|
|
|
33025
32464
|
"Provide --source or RUNTIME_FEEDBACK_RSYNC_SOURCE for runtime feedback sync."
|
|
33026
32465
|
);
|
|
33027
32466
|
}
|
|
33028
|
-
const feedbackRoot =
|
|
32467
|
+
const feedbackRoot = import_node_path27.default.resolve(projectRoot11, String(flags27.dir));
|
|
33029
32468
|
const result = await syncRuntimeFeedbackReplayBundles({
|
|
33030
32469
|
source,
|
|
33031
32470
|
feedbackRoot,
|
|
@@ -33052,18 +32491,18 @@ var init_runtimeFeedbackSync2 = __esm({
|
|
|
33052
32491
|
)
|
|
33053
32492
|
);
|
|
33054
32493
|
};
|
|
33055
|
-
|
|
32494
|
+
main39 = runtimeFeedbackSync;
|
|
33056
32495
|
}
|
|
33057
32496
|
});
|
|
33058
32497
|
|
|
33059
32498
|
// src/lib/runtimeEvidenceCompositionSnapshots.ts
|
|
33060
|
-
var
|
|
32499
|
+
var import_node_crypto14, import_promises31, import_node_path28, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord2, sha256, safeSegment4, isExistingDestinationError3, parseManifest, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
|
|
33061
32500
|
var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
33062
32501
|
"src/lib/runtimeEvidenceCompositionSnapshots.ts"() {
|
|
33063
32502
|
"use strict";
|
|
33064
|
-
|
|
33065
|
-
|
|
33066
|
-
|
|
32503
|
+
import_node_crypto14 = require("crypto");
|
|
32504
|
+
import_promises31 = __toESM(require("fs/promises"));
|
|
32505
|
+
import_node_path28 = __toESM(require("path"));
|
|
33067
32506
|
init_runtimeEvidenceDeployment();
|
|
33068
32507
|
init_runtimeEvidenceProducer();
|
|
33069
32508
|
SNAPSHOT_FILE = "snapshot.json";
|
|
@@ -33083,22 +32522,22 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33083
32522
|
}
|
|
33084
32523
|
};
|
|
33085
32524
|
};
|
|
33086
|
-
|
|
33087
|
-
|
|
33088
|
-
|
|
32525
|
+
isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
32526
|
+
sha256 = (value) => (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex");
|
|
32527
|
+
safeSegment4 = (value, label) => {
|
|
33089
32528
|
const normalized = value.trim();
|
|
33090
32529
|
if (!normalized || !/^[a-zA-Z0-9._:-]+$/.test(normalized)) {
|
|
33091
32530
|
throw new Error(`Invalid runtime evidence snapshot ${label}`);
|
|
33092
32531
|
}
|
|
33093
32532
|
return normalized;
|
|
33094
32533
|
};
|
|
33095
|
-
|
|
32534
|
+
isExistingDestinationError3 = (error) => {
|
|
33096
32535
|
const code = error.code;
|
|
33097
32536
|
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
33098
32537
|
};
|
|
33099
|
-
|
|
33100
|
-
const manifest =
|
|
33101
|
-
const payload =
|
|
32538
|
+
parseManifest = (value) => {
|
|
32539
|
+
const manifest = isRecord2(value) ? value : null;
|
|
32540
|
+
const payload = isRecord2(manifest?.payload) ? manifest.payload : null;
|
|
33102
32541
|
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence-composition-snapshot" || typeof manifest.createdAt !== "number" || typeof manifest.userName !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.deploymentCompositionId !== "string" || payload?.file !== SNAPSHOT_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number") {
|
|
33103
32542
|
throw new Error("Invalid runtime evidence composition snapshot manifest");
|
|
33104
32543
|
}
|
|
@@ -33106,28 +32545,28 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33106
32545
|
};
|
|
33107
32546
|
verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
|
|
33108
32547
|
const [manifestText, payload, completeText] = await Promise.all([
|
|
33109
|
-
|
|
33110
|
-
|
|
33111
|
-
|
|
32548
|
+
import_promises31.default.readFile(import_node_path28.default.join(bundleDir, MANIFEST_FILE), "utf8"),
|
|
32549
|
+
import_promises31.default.readFile(import_node_path28.default.join(bundleDir, SNAPSHOT_FILE)),
|
|
32550
|
+
import_promises31.default.readFile(import_node_path28.default.join(bundleDir, COMPLETE_FILE), "utf8")
|
|
33112
32551
|
]);
|
|
33113
|
-
const manifest =
|
|
32552
|
+
const manifest = parseManifest(JSON.parse(manifestText));
|
|
33114
32553
|
if (completeText.trim() !== manifest.deploymentCompositionId) {
|
|
33115
32554
|
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
33116
32555
|
}
|
|
33117
|
-
if (payload.byteLength !== manifest.payload.bytes ||
|
|
32556
|
+
if (payload.byteLength !== manifest.payload.bytes || sha256(payload) !== manifest.payload.sha256) {
|
|
33118
32557
|
throw new Error(
|
|
33119
32558
|
`Runtime evidence snapshot checksum mismatch in ${bundleDir}`
|
|
33120
32559
|
);
|
|
33121
32560
|
}
|
|
33122
32561
|
const value = JSON.parse(payload.toString("utf8"));
|
|
33123
|
-
const record =
|
|
32562
|
+
const record = isRecord2(value) ? value : null;
|
|
33124
32563
|
if (record?.schemaVersion !== 1 || record.reportType !== "runtime-evidence-composition-snapshot" || record.userName !== manifest.userName) {
|
|
33125
32564
|
throw new Error(
|
|
33126
32565
|
`Invalid runtime evidence snapshot payload in ${bundleDir}`
|
|
33127
32566
|
);
|
|
33128
32567
|
}
|
|
33129
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(record.deployment);
|
|
33130
|
-
const producer = parseRuntimeEvidenceProducer(record.producer);
|
|
32568
|
+
const deployment = (0, runtimeEvidenceDeployment_exports.parseRuntimeEvidenceDeploymentSnapshot)(record.deployment);
|
|
32569
|
+
const producer = (0, runtimeEvidenceProducer_exports.parseRuntimeEvidenceProducer)(record.producer);
|
|
33131
32570
|
if (deployment.id !== manifest.deploymentId || deployment.deploymentCompositionId !== manifest.deploymentCompositionId) {
|
|
33132
32571
|
throw new Error(
|
|
33133
32572
|
`Runtime evidence snapshot identity mismatch in ${bundleDir}`
|
|
@@ -33142,8 +32581,8 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33142
32581
|
deployment,
|
|
33143
32582
|
producer
|
|
33144
32583
|
}) => {
|
|
33145
|
-
const deploymentId =
|
|
33146
|
-
const compositionId =
|
|
32584
|
+
const deploymentId = safeSegment4(deployment.id, "deployment id");
|
|
32585
|
+
const compositionId = safeSegment4(
|
|
33147
32586
|
deployment.deploymentCompositionId,
|
|
33148
32587
|
"composition id"
|
|
33149
32588
|
);
|
|
@@ -33167,43 +32606,43 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33167
32606
|
deploymentCompositionId: compositionId,
|
|
33168
32607
|
payload: {
|
|
33169
32608
|
file: SNAPSHOT_FILE,
|
|
33170
|
-
sha256:
|
|
32609
|
+
sha256: sha256(payload),
|
|
33171
32610
|
bytes: Buffer.byteLength(payload)
|
|
33172
32611
|
}
|
|
33173
32612
|
};
|
|
33174
|
-
const snapshotsRoot =
|
|
33175
|
-
const bundleDir =
|
|
33176
|
-
const temporaryDir =
|
|
32613
|
+
const snapshotsRoot = import_node_path28.default.join(evidenceRoot, "snapshots", deploymentId);
|
|
32614
|
+
const bundleDir = import_node_path28.default.join(snapshotsRoot, compositionId);
|
|
32615
|
+
const temporaryDir = import_node_path28.default.join(
|
|
33177
32616
|
evidenceRoot,
|
|
33178
32617
|
"incoming",
|
|
33179
|
-
`snapshot-${compositionId}.tmp-${(0,
|
|
32618
|
+
`snapshot-${compositionId}.tmp-${(0, import_node_crypto14.randomUUID)()}`
|
|
33180
32619
|
);
|
|
33181
|
-
await
|
|
32620
|
+
await import_promises31.default.mkdir(temporaryDir, { recursive: true });
|
|
33182
32621
|
try {
|
|
33183
32622
|
await Promise.all([
|
|
33184
|
-
|
|
33185
|
-
|
|
33186
|
-
|
|
32623
|
+
import_promises31.default.writeFile(import_node_path28.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
|
|
32624
|
+
import_promises31.default.writeFile(
|
|
32625
|
+
import_node_path28.default.join(temporaryDir, MANIFEST_FILE),
|
|
33187
32626
|
`${JSON.stringify(manifest, null, 2)}
|
|
33188
32627
|
`,
|
|
33189
32628
|
"utf8"
|
|
33190
32629
|
)
|
|
33191
32630
|
]);
|
|
33192
|
-
await
|
|
33193
|
-
|
|
32631
|
+
await import_promises31.default.writeFile(
|
|
32632
|
+
import_node_path28.default.join(temporaryDir, COMPLETE_FILE),
|
|
33194
32633
|
`${compositionId}
|
|
33195
32634
|
`,
|
|
33196
32635
|
"utf8"
|
|
33197
32636
|
);
|
|
33198
|
-
await
|
|
32637
|
+
await import_promises31.default.mkdir(snapshotsRoot, { recursive: true });
|
|
33199
32638
|
try {
|
|
33200
|
-
await
|
|
32639
|
+
await import_promises31.default.rename(temporaryDir, bundleDir);
|
|
33201
32640
|
} catch (error) {
|
|
33202
|
-
if (!
|
|
33203
|
-
await
|
|
32641
|
+
if (!isExistingDestinationError3(error)) throw error;
|
|
32642
|
+
await import_promises31.default.rm(temporaryDir, { recursive: true, force: true });
|
|
33204
32643
|
}
|
|
33205
32644
|
} catch (error) {
|
|
33206
|
-
await
|
|
32645
|
+
await import_promises31.default.rm(temporaryDir, { recursive: true, force: true });
|
|
33207
32646
|
throw error;
|
|
33208
32647
|
}
|
|
33209
32648
|
const verified = await verifyRuntimeEvidenceCompositionSnapshot(bundleDir);
|
|
@@ -33221,12 +32660,12 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33221
32660
|
expectedCompositionId
|
|
33222
32661
|
}) => {
|
|
33223
32662
|
const [deployment, producer] = await Promise.all([
|
|
33224
|
-
resolveRuntimeEvidenceDeploymentSnapshot({
|
|
32663
|
+
(0, runtimeEvidenceDeployment_exports.resolveRuntimeEvidenceDeploymentSnapshot)({
|
|
33225
32664
|
userName: userName3,
|
|
33226
32665
|
projectRoot: projectRoot18,
|
|
33227
32666
|
deploymentId
|
|
33228
32667
|
}),
|
|
33229
|
-
resolveRuntimeEvidenceProducer({ projectRoot: projectRoot18, required: true })
|
|
32668
|
+
(0, runtimeEvidenceProducer_exports.resolveRuntimeEvidenceProducer)({ projectRoot: projectRoot18, required: true })
|
|
33230
32669
|
]);
|
|
33231
32670
|
if (!producer) {
|
|
33232
32671
|
throw new Error("Runtime evidence producer identity is required");
|
|
@@ -33237,31 +32676,31 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33237
32676
|
);
|
|
33238
32677
|
}
|
|
33239
32678
|
await publishRuntimeEvidenceCompositionSnapshot({
|
|
33240
|
-
evidenceRoot:
|
|
32679
|
+
evidenceRoot: import_node_path28.default.join(projectRoot18, "data", "runtime-evidence"),
|
|
33241
32680
|
userName: userName3,
|
|
33242
32681
|
deployment,
|
|
33243
32682
|
producer
|
|
33244
32683
|
});
|
|
33245
32684
|
};
|
|
33246
32685
|
discoverRuntimeEvidenceCompositionSnapshots = async (evidenceRoot) => {
|
|
33247
|
-
const rootDir =
|
|
32686
|
+
const rootDir = import_node_path28.default.join(evidenceRoot, "snapshots");
|
|
33248
32687
|
const bundleDirs = [];
|
|
33249
32688
|
let deployments;
|
|
33250
32689
|
try {
|
|
33251
|
-
deployments = await
|
|
32690
|
+
deployments = await import_promises31.default.readdir(rootDir, { withFileTypes: true });
|
|
33252
32691
|
} catch (error) {
|
|
33253
32692
|
if (error.code === "ENOENT") return [];
|
|
33254
32693
|
throw error;
|
|
33255
32694
|
}
|
|
33256
32695
|
for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
|
|
33257
|
-
const deploymentDir =
|
|
33258
|
-
const compositions = await
|
|
32696
|
+
const deploymentDir = import_node_path28.default.join(rootDir, deployment.name);
|
|
32697
|
+
const compositions = await import_promises31.default.readdir(deploymentDir, {
|
|
33259
32698
|
withFileTypes: true
|
|
33260
32699
|
});
|
|
33261
32700
|
bundleDirs.push(
|
|
33262
32701
|
...compositions.filter(
|
|
33263
32702
|
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
33264
|
-
).map((entry) =>
|
|
32703
|
+
).map((entry) => import_node_path28.default.join(deploymentDir, entry.name))
|
|
33265
32704
|
);
|
|
33266
32705
|
}
|
|
33267
32706
|
return Promise.all(
|
|
@@ -33313,17 +32752,17 @@ var init_runtimeEvidenceCompositions = __esm({
|
|
|
33313
32752
|
producer: snapshot.producer
|
|
33314
32753
|
});
|
|
33315
32754
|
}
|
|
33316
|
-
const bundleDirs = await discoverRuntimeEvidenceBundles(publishRoot);
|
|
32755
|
+
const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(publishRoot);
|
|
33317
32756
|
for (const bundleDir of bundleDirs) {
|
|
33318
|
-
const bundle = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
33319
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
32757
|
+
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
32758
|
+
const deployment = (0, runtimeEvidenceDeployment_exports.parseRuntimeEvidenceDeploymentSnapshot)(
|
|
33320
32759
|
bundle.artifact.deployment
|
|
33321
32760
|
);
|
|
33322
32761
|
if (deployment.id !== currentDeployment.id) continue;
|
|
33323
32762
|
if (bundle.artifact.producer == null) continue;
|
|
33324
32763
|
register({
|
|
33325
32764
|
deployment: { ...deployment, tickers: void 0 },
|
|
33326
|
-
producer: parseRuntimeEvidenceProducer(bundle.artifact.producer),
|
|
32765
|
+
producer: (0, runtimeEvidenceProducer_exports.parseRuntimeEvidenceProducer)(bundle.artifact.producer),
|
|
33327
32766
|
// A historical composition may reappear through a position that closes
|
|
33328
32767
|
// in this window even without current-window lineage scopes. Its latest
|
|
33329
32768
|
// checksum-verified universe is only a fallback; fresh scopes win.
|
|
@@ -33358,11 +32797,11 @@ var init_runtimeEvidenceCompositions = __esm({
|
|
|
33358
32797
|
return Number.POSITIVE_INFINITY;
|
|
33359
32798
|
};
|
|
33360
32799
|
belongsToSnapshot = (row, deployment) => {
|
|
33361
|
-
const strategy = activeRuntimeEvidenceStrategies(deployment).find(
|
|
32800
|
+
const strategy = (0, runtimeEvidenceDeployment_exports.activeRuntimeEvidenceStrategies)(deployment).find(
|
|
33362
32801
|
(candidate) => candidate.strategyName === row.strategy
|
|
33363
32802
|
);
|
|
33364
32803
|
return Boolean(
|
|
33365
|
-
strategy && row.deploymentId === deployment.id && row.accountId === deployment.accountId && runtimeLineageMatchesStrategySnapshot({
|
|
32804
|
+
strategy && row.deploymentId === deployment.id && row.accountId === deployment.accountId && (0, runtimeEvidenceDeployment_exports.runtimeLineageMatchesStrategySnapshot)({
|
|
33366
32805
|
lineage: row.runtimeLineage ?? row.lineage,
|
|
33367
32806
|
deployment,
|
|
33368
32807
|
strategy
|
|
@@ -33437,15 +32876,15 @@ var init_runtimeEvidenceCompositions = __esm({
|
|
|
33437
32876
|
// src/scripts/runtimeEvidence.ts
|
|
33438
32877
|
var runtimeEvidence_exports = {};
|
|
33439
32878
|
__export(runtimeEvidence_exports, {
|
|
33440
|
-
main: () =>
|
|
32879
|
+
main: () => main40,
|
|
33441
32880
|
runtimeEvidence: () => runtimeEvidence
|
|
33442
32881
|
});
|
|
33443
|
-
var
|
|
32882
|
+
var import_promises32, import_node_path29, import_args31, import_chalk47, flags28, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main40;
|
|
33444
32883
|
var init_runtimeEvidence = __esm({
|
|
33445
32884
|
"src/scripts/runtimeEvidence.ts"() {
|
|
33446
32885
|
"use strict";
|
|
33447
|
-
|
|
33448
|
-
|
|
32886
|
+
import_promises32 = __toESM(require("fs/promises"));
|
|
32887
|
+
import_node_path29 = __toESM(require("path"));
|
|
33449
32888
|
import_args31 = __toESM(require("args"));
|
|
33450
32889
|
import_chalk47 = __toESM(require("chalk"));
|
|
33451
32890
|
init_runtimeDebugEvidence();
|
|
@@ -33534,11 +32973,11 @@ var init_runtimeEvidence = __esm({
|
|
|
33534
32973
|
const { startTime, endTime, source } = resolveWindow2();
|
|
33535
32974
|
const deploymentId = String(flags28.deployment);
|
|
33536
32975
|
const publishDir = String(flags28.publishDir ?? "").trim();
|
|
33537
|
-
const producer = await resolveRuntimeEvidenceProducer({
|
|
32976
|
+
const producer = await (0, runtimeEvidenceProducer_exports.resolveRuntimeEvidenceProducer)({
|
|
33538
32977
|
projectRoot: projectRoot12,
|
|
33539
32978
|
required: Boolean(publishDir)
|
|
33540
32979
|
});
|
|
33541
|
-
const deploymentSnapshot = await resolveRuntimeEvidenceDeploymentSnapshot({
|
|
32980
|
+
const deploymentSnapshot = await (0, runtimeEvidenceDeployment_exports.resolveRuntimeEvidenceDeploymentSnapshot)({
|
|
33542
32981
|
userName: String(flags28.user),
|
|
33543
32982
|
projectRoot: projectRoot12,
|
|
33544
32983
|
deploymentId
|
|
@@ -33552,7 +32991,7 @@ var init_runtimeEvidence = __esm({
|
|
|
33552
32991
|
deploymentId
|
|
33553
32992
|
});
|
|
33554
32993
|
const snapshots = publishDir && producer ? await loadRuntimeEvidenceCompositionSnapshots({
|
|
33555
|
-
publishRoot:
|
|
32994
|
+
publishRoot: import_node_path29.default.resolve(projectRoot12, publishDir),
|
|
33556
32995
|
currentDeployment: deploymentSnapshot,
|
|
33557
32996
|
currentProducer: producer
|
|
33558
32997
|
}) : /* @__PURE__ */ new Map([
|
|
@@ -33581,7 +33020,7 @@ var init_runtimeEvidence = __esm({
|
|
|
33581
33020
|
ignoreUnknownCompositions: !publishDir
|
|
33582
33021
|
});
|
|
33583
33022
|
const artifacts = compositionRows.map((composition) => {
|
|
33584
|
-
const strategies = activeRuntimeEvidenceStrategies(composition.deployment).map(({ strategyName }) => strategyName).filter(
|
|
33023
|
+
const strategies = (0, runtimeEvidenceDeployment_exports.activeRuntimeEvidenceStrategies)(composition.deployment).map(({ strategyName }) => strategyName).filter(
|
|
33585
33024
|
(strategyName) => !requestedStrategies.length || requestedStrategies.includes(strategyName)
|
|
33586
33025
|
);
|
|
33587
33026
|
const runtime = buildRuntimeEvidenceReportPayload({
|
|
@@ -33593,7 +33032,7 @@ var init_runtimeEvidence = __esm({
|
|
|
33593
33032
|
trades: composition.trades,
|
|
33594
33033
|
lineageScopes: composition.lineageScopes
|
|
33595
33034
|
});
|
|
33596
|
-
const deployment = resolveRuntimeEvidenceTickerUniverse({
|
|
33035
|
+
const deployment = (0, runtimeEvidenceDeployment_exports.resolveRuntimeEvidenceTickerUniverse)({
|
|
33597
33036
|
deployment: composition.deployment,
|
|
33598
33037
|
lineageScopes: composition.lineageScopes,
|
|
33599
33038
|
fallbackTickers: composition.fallbackTickers
|
|
@@ -33626,14 +33065,14 @@ var init_runtimeEvidence = __esm({
|
|
|
33626
33065
|
throw new Error("Runtime evidence window has no versioned runtime rows");
|
|
33627
33066
|
}
|
|
33628
33067
|
const artifact = current.artifact;
|
|
33629
|
-
const outPath =
|
|
33630
|
-
await
|
|
33631
|
-
await
|
|
33068
|
+
const outPath = import_node_path29.default.resolve(projectRoot12, String(flags28.out));
|
|
33069
|
+
await import_promises32.default.mkdir(import_node_path29.default.dirname(outPath), { recursive: true });
|
|
33070
|
+
await import_promises32.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
33632
33071
|
`, "utf8");
|
|
33633
33072
|
const published = publishDir ? await Promise.all(
|
|
33634
33073
|
artifacts.map(
|
|
33635
|
-
({ artifact: artifact2, composition }) => publishRuntimeEvidenceBundle({
|
|
33636
|
-
publishRoot:
|
|
33074
|
+
({ artifact: artifact2, composition }) => (0, runtimeEvidenceArtifacts_exports.publishRuntimeEvidenceBundle)({
|
|
33075
|
+
publishRoot: import_node_path29.default.resolve(projectRoot12, publishDir),
|
|
33637
33076
|
deploymentId,
|
|
33638
33077
|
userName: String(flags28.user),
|
|
33639
33078
|
startTime,
|
|
@@ -33669,21 +33108,21 @@ var init_runtimeEvidence = __esm({
|
|
|
33669
33108
|
)
|
|
33670
33109
|
);
|
|
33671
33110
|
};
|
|
33672
|
-
|
|
33111
|
+
main40 = runtimeEvidence;
|
|
33673
33112
|
}
|
|
33674
33113
|
});
|
|
33675
33114
|
|
|
33676
33115
|
// src/scripts/runtimeEvidenceSync.ts
|
|
33677
33116
|
var runtimeEvidenceSync_exports = {};
|
|
33678
33117
|
__export(runtimeEvidenceSync_exports, {
|
|
33679
|
-
main: () =>
|
|
33118
|
+
main: () => main41,
|
|
33680
33119
|
runtimeEvidenceSync: () => runtimeEvidenceSync
|
|
33681
33120
|
});
|
|
33682
|
-
var
|
|
33121
|
+
var import_node_path30, import_args32, import_chalk48, flags29, projectRoot13, runtimeEvidenceSync, main41;
|
|
33683
33122
|
var init_runtimeEvidenceSync2 = __esm({
|
|
33684
33123
|
"src/scripts/runtimeEvidenceSync.ts"() {
|
|
33685
33124
|
"use strict";
|
|
33686
|
-
|
|
33125
|
+
import_node_path30 = __toESM(require("path"));
|
|
33687
33126
|
import_args32 = __toESM(require("args"));
|
|
33688
33127
|
import_chalk48 = __toESM(require("chalk"));
|
|
33689
33128
|
init_runtimeEvidenceSync();
|
|
@@ -33711,7 +33150,7 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
33711
33150
|
"Provide --source or RUNTIME_EVIDENCE_RSYNC_SOURCE for runtime evidence sync."
|
|
33712
33151
|
);
|
|
33713
33152
|
}
|
|
33714
|
-
const evidenceRoot =
|
|
33153
|
+
const evidenceRoot = import_node_path30.default.resolve(projectRoot13, String(flags29.dir));
|
|
33715
33154
|
const result = await syncRuntimeEvidenceBundles({
|
|
33716
33155
|
source,
|
|
33717
33156
|
evidenceRoot,
|
|
@@ -33743,23 +33182,23 @@ var init_runtimeEvidenceSync2 = __esm({
|
|
|
33743
33182
|
)
|
|
33744
33183
|
);
|
|
33745
33184
|
};
|
|
33746
|
-
|
|
33185
|
+
main41 = runtimeEvidenceSync;
|
|
33747
33186
|
}
|
|
33748
33187
|
});
|
|
33749
33188
|
|
|
33750
33189
|
// src/lib/runtimeScorecard.ts
|
|
33751
|
-
var
|
|
33190
|
+
var asRecord7, asArray4, finiteNumber6, finiteString2, packageVersionMap, round3, unwrapRows2, runtimePayload, runtimeWindow, extractRuntimeRows, buildEmbeddedLineageScope, runtimeDeploymentBinding, belongsToRuntimeDeployment, belongsToStrategy, filterArtifactByStrategy, countBy2, resolveGateDecision, buildDistributions, buildDistributionDelta, sum2, tradeTimestamp, dedupeTrades, maxDrawdown2, buildRollingPerformance, getReplayComparison, replayCountsForStrategy, getProspectiveSummary, buildRuntimeScorecard, formatRuntimeScorecardMarkdown;
|
|
33752
33191
|
var init_runtimeScorecard = __esm({
|
|
33753
33192
|
"src/lib/runtimeScorecard.ts"() {
|
|
33754
33193
|
"use strict";
|
|
33755
33194
|
init_runtimeLineage();
|
|
33756
33195
|
init_runtimeEvidenceDeployment();
|
|
33757
|
-
|
|
33196
|
+
asRecord7 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
33758
33197
|
asArray4 = (value) => Array.isArray(value) ? value : [];
|
|
33759
33198
|
finiteNumber6 = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
33760
33199
|
finiteString2 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
33761
33200
|
packageVersionMap = (value) => {
|
|
33762
|
-
const record =
|
|
33201
|
+
const record = asRecord7(value);
|
|
33763
33202
|
if (!record || Object.keys(record).length === 0) return null;
|
|
33764
33203
|
const entries = Object.entries(record);
|
|
33765
33204
|
if (entries.some(
|
|
@@ -33772,14 +33211,14 @@ var init_runtimeScorecard = __esm({
|
|
|
33772
33211
|
);
|
|
33773
33212
|
};
|
|
33774
33213
|
round3 = (value, decimals = 6) => Number(value.toFixed(decimals));
|
|
33775
|
-
unwrapRows2 = (value, key) => asArray4(value).map((item) =>
|
|
33214
|
+
unwrapRows2 = (value, key) => asArray4(value).map((item) => asRecord7(asRecord7(item)?.[key]) ?? asRecord7(item)).filter((item) => item != null);
|
|
33776
33215
|
runtimePayload = (artifact) => {
|
|
33777
|
-
const root =
|
|
33778
|
-
return
|
|
33216
|
+
const root = asRecord7(artifact) ?? {};
|
|
33217
|
+
return asRecord7(root.runtime) ?? root;
|
|
33779
33218
|
};
|
|
33780
33219
|
runtimeWindow = (artifact) => {
|
|
33781
|
-
const root =
|
|
33782
|
-
return
|
|
33220
|
+
const root = asRecord7(artifact) ?? {};
|
|
33221
|
+
return asRecord7(root.window) ?? asRecord7(runtimePayload(artifact).window) ?? {};
|
|
33783
33222
|
};
|
|
33784
33223
|
extractRuntimeRows = (artifact) => {
|
|
33785
33224
|
const runtime = runtimePayload(artifact);
|
|
@@ -33795,7 +33234,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33795
33234
|
rows,
|
|
33796
33235
|
strategy
|
|
33797
33236
|
}) => {
|
|
33798
|
-
const deployment =
|
|
33237
|
+
const deployment = asRecord7(asRecord7(artifact)?.deployment);
|
|
33799
33238
|
if (finiteNumber6(deployment?.schemaVersion) !== 2) return null;
|
|
33800
33239
|
const deploymentId = finiteString2(deployment?.id);
|
|
33801
33240
|
const accountId = finiteString2(deployment?.accountId);
|
|
@@ -33803,7 +33242,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33803
33242
|
deployment?.deploymentCompositionId
|
|
33804
33243
|
);
|
|
33805
33244
|
if (!deploymentId || !accountId || !deploymentCompositionId) return null;
|
|
33806
|
-
const snapshots = asArray4(deployment?.strategies).map(
|
|
33245
|
+
const snapshots = asArray4(deployment?.strategies).map(asRecord7).filter((item) => item != null).filter((item) => item.enabled === true).filter(
|
|
33807
33246
|
(item) => !strategy || finiteString2(item.strategyName) === strategy
|
|
33808
33247
|
);
|
|
33809
33248
|
const targetSeeds = snapshots.map((snapshot) => {
|
|
@@ -33845,10 +33284,10 @@ var init_runtimeScorecard = __esm({
|
|
|
33845
33284
|
const targets = /* @__PURE__ */ new Map();
|
|
33846
33285
|
for (const seed of targetSeeds) {
|
|
33847
33286
|
const matchingRows = lineageRows.filter(
|
|
33848
|
-
(row) => finiteString2(row.strategy) === seed.strategyName && finiteString2(row.deploymentId) === deploymentId && finiteString2(row.accountId) === accountId && identityMatches(
|
|
33287
|
+
(row) => finiteString2(row.strategy) === seed.strategyName && finiteString2(row.deploymentId) === deploymentId && finiteString2(row.accountId) === accountId && identityMatches(asRecord7(row.runtimeLineage), seed)
|
|
33849
33288
|
);
|
|
33850
33289
|
const riskValues = new Set(
|
|
33851
|
-
matchingRows.map((row) => finiteNumber6(
|
|
33290
|
+
matchingRows.map((row) => finiteNumber6(asRecord7(row.runtimeLineage)?.maxLossValue)).filter((value) => value != null)
|
|
33852
33291
|
);
|
|
33853
33292
|
targets.set(seed.strategyName, {
|
|
33854
33293
|
...seed,
|
|
@@ -33860,7 +33299,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33860
33299
|
const belongs = (row) => {
|
|
33861
33300
|
const strategyName = finiteString2(row.strategy);
|
|
33862
33301
|
const target = strategyName ? targets.get(strategyName) : null;
|
|
33863
|
-
const lineage =
|
|
33302
|
+
const lineage = asRecord7(row.runtimeLineage);
|
|
33864
33303
|
return Boolean(
|
|
33865
33304
|
target && target.maxLossValue != null && identityMatches(lineage, target) && finiteNumber6(lineage?.maxLossValue) === target.maxLossValue
|
|
33866
33305
|
);
|
|
@@ -33917,7 +33356,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33917
33356
|
};
|
|
33918
33357
|
};
|
|
33919
33358
|
runtimeDeploymentBinding = (artifact) => {
|
|
33920
|
-
const deployment =
|
|
33359
|
+
const deployment = asRecord7(asRecord7(artifact)?.deployment);
|
|
33921
33360
|
return {
|
|
33922
33361
|
deploymentId: finiteString2(deployment?.id),
|
|
33923
33362
|
accountId: finiteString2(deployment?.accountId)
|
|
@@ -33927,7 +33366,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33927
33366
|
belongsToStrategy = (row, strategy) => strategy == null || finiteString2(row.strategy) === strategy;
|
|
33928
33367
|
filterArtifactByStrategy = (artifact, strategy) => {
|
|
33929
33368
|
if (!strategy) return artifact;
|
|
33930
|
-
const root =
|
|
33369
|
+
const root = asRecord7(artifact) ?? {};
|
|
33931
33370
|
const runtime = runtimePayload(artifact);
|
|
33932
33371
|
return {
|
|
33933
33372
|
...root,
|
|
@@ -33935,24 +33374,24 @@ var init_runtimeScorecard = __esm({
|
|
|
33935
33374
|
...runtime,
|
|
33936
33375
|
evaluations: asArray4(runtime.evaluations).filter(
|
|
33937
33376
|
(item) => belongsToStrategy(
|
|
33938
|
-
|
|
33377
|
+
asRecord7(asRecord7(item)?.evaluation) ?? asRecord7(item) ?? {},
|
|
33939
33378
|
strategy
|
|
33940
33379
|
)
|
|
33941
33380
|
),
|
|
33942
33381
|
signals: asArray4(runtime.signals).filter(
|
|
33943
33382
|
(item) => belongsToStrategy(
|
|
33944
|
-
|
|
33383
|
+
asRecord7(asRecord7(item)?.signal) ?? asRecord7(item) ?? {},
|
|
33945
33384
|
strategy
|
|
33946
33385
|
)
|
|
33947
33386
|
),
|
|
33948
33387
|
trades: asArray4(runtime.trades).filter(
|
|
33949
33388
|
(item) => belongsToStrategy(
|
|
33950
|
-
|
|
33389
|
+
asRecord7(asRecord7(item)?.trade) ?? asRecord7(item) ?? {},
|
|
33951
33390
|
strategy
|
|
33952
33391
|
)
|
|
33953
33392
|
),
|
|
33954
33393
|
lineageScopes: asArray4(runtime.lineageScopes).filter(
|
|
33955
|
-
(item) => belongsToStrategy(
|
|
33394
|
+
(item) => belongsToStrategy(asRecord7(item) ?? {}, strategy)
|
|
33956
33395
|
)
|
|
33957
33396
|
}
|
|
33958
33397
|
};
|
|
@@ -33969,7 +33408,7 @@ var init_runtimeScorecard = __esm({
|
|
|
33969
33408
|
);
|
|
33970
33409
|
};
|
|
33971
33410
|
resolveGateDecision = (evaluation) => {
|
|
33972
|
-
const analysis =
|
|
33411
|
+
const analysis = asRecord7(evaluation.aiAnalysis);
|
|
33973
33412
|
const explicit = finiteString2(analysis?.gateDecision);
|
|
33974
33413
|
if (explicit === "approved" || explicit === "rejected") {
|
|
33975
33414
|
return { decision: explicit, source: "gate_decision" };
|
|
@@ -34000,7 +33439,7 @@ var init_runtimeScorecard = __esm({
|
|
|
34000
33439
|
(signal) => finiteString2(signal.orderSkipReason)
|
|
34001
33440
|
),
|
|
34002
33441
|
aiQuality: countBy2(candidates, (evaluation) => {
|
|
34003
|
-
const quality = finiteNumber6(
|
|
33442
|
+
const quality = finiteNumber6(asRecord7(evaluation.aiAnalysis)?.quality);
|
|
34004
33443
|
return quality == null ? null : String(quality);
|
|
34005
33444
|
})
|
|
34006
33445
|
};
|
|
@@ -34085,13 +33524,13 @@ var init_runtimeScorecard = __esm({
|
|
|
34085
33524
|
};
|
|
34086
33525
|
};
|
|
34087
33526
|
getReplayComparison = (artifact) => {
|
|
34088
|
-
const root =
|
|
34089
|
-
return
|
|
33527
|
+
const root = asRecord7(artifact) ?? {};
|
|
33528
|
+
return asRecord7(asRecord7(root.replay)?.runtimeComparison) ?? null;
|
|
34090
33529
|
};
|
|
34091
33530
|
replayCountsForStrategy = (replayComparison, strategy) => {
|
|
34092
33531
|
if (strategy) {
|
|
34093
|
-
const byStrategy =
|
|
34094
|
-
const strategyCounts =
|
|
33532
|
+
const byStrategy = asRecord7(replayComparison?.byStrategy);
|
|
33533
|
+
const strategyCounts = asRecord7(byStrategy?.[strategy]);
|
|
34095
33534
|
if (strategyCounts) {
|
|
34096
33535
|
return {
|
|
34097
33536
|
matched: finiteNumber6(strategyCounts.matched) ?? 0,
|
|
@@ -34100,7 +33539,7 @@ var init_runtimeScorecard = __esm({
|
|
|
34100
33539
|
};
|
|
34101
33540
|
}
|
|
34102
33541
|
}
|
|
34103
|
-
const counts =
|
|
33542
|
+
const counts = asRecord7(replayComparison?.counts);
|
|
34104
33543
|
return {
|
|
34105
33544
|
matched: finiteNumber6(counts?.matched) ?? 0,
|
|
34106
33545
|
backtestOnly: finiteNumber6(counts?.backtestOnly) ?? 0,
|
|
@@ -34108,7 +33547,7 @@ var init_runtimeScorecard = __esm({
|
|
|
34108
33547
|
};
|
|
34109
33548
|
};
|
|
34110
33549
|
getProspectiveSummary = (artifact) => {
|
|
34111
|
-
const root =
|
|
33550
|
+
const root = asRecord7(artifact);
|
|
34112
33551
|
if (!root || root.reportType !== "strategy-prospective-evidence") return null;
|
|
34113
33552
|
return {
|
|
34114
33553
|
rawCoreExpectancy: finiteNumber6(root.rawCoreExpectancy),
|
|
@@ -34132,9 +33571,9 @@ var init_runtimeScorecard = __esm({
|
|
|
34132
33571
|
strategy = null,
|
|
34133
33572
|
llmComparatorPolicy = "ai_approved_only"
|
|
34134
33573
|
}) => {
|
|
34135
|
-
assertCurrentRuntimeEvidenceArtifact(runtimeArtifact);
|
|
33574
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(runtimeArtifact);
|
|
34136
33575
|
for (const artifact of historyRuntimeArtifacts) {
|
|
34137
|
-
assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
33576
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(artifact);
|
|
34138
33577
|
}
|
|
34139
33578
|
const scopedRuntimeArtifact = filterArtifactByStrategy(
|
|
34140
33579
|
runtimeArtifact,
|
|
@@ -34169,7 +33608,7 @@ var init_runtimeScorecard = __esm({
|
|
|
34169
33608
|
(evaluation) => resolveGateDecision(evaluation)?.decision === "approved"
|
|
34170
33609
|
) : signalEvaluations;
|
|
34171
33610
|
const gateComparisons = llmEligibleEvaluations.map((evaluation) => {
|
|
34172
|
-
const analysis =
|
|
33611
|
+
const analysis = asRecord7(evaluation.aiAnalysis);
|
|
34173
33612
|
const gateDecision = resolveGateDecision(evaluation)?.decision ?? null;
|
|
34174
33613
|
const llmDecision = finiteString2(analysis?.llmDecision);
|
|
34175
33614
|
if (gateDecision !== "approved" && gateDecision !== "rejected" || llmDecision !== "approved" && llmDecision !== "rejected") {
|
|
@@ -34179,8 +33618,8 @@ var init_runtimeScorecard = __esm({
|
|
|
34179
33618
|
}).filter(
|
|
34180
33619
|
(comparison) => Boolean(comparison)
|
|
34181
33620
|
);
|
|
34182
|
-
const allocatorDecisions = signalEvaluations.map((evaluation) =>
|
|
34183
|
-
const riskDecisions = signalEvaluations.map((evaluation) =>
|
|
33621
|
+
const allocatorDecisions = signalEvaluations.map((evaluation) => asRecord7(evaluation.allocatorDecision)).filter((item) => item != null);
|
|
33622
|
+
const riskDecisions = signalEvaluations.map((evaluation) => asRecord7(evaluation.riskDecision)).filter((item) => item != null);
|
|
34184
33623
|
const orderAttempts = rows.signals.filter(
|
|
34185
33624
|
(signal) => signal.orderStatus === "completed" || signal.orderStatus === "failed"
|
|
34186
33625
|
);
|
|
@@ -34195,10 +33634,10 @@ var init_runtimeScorecard = __esm({
|
|
|
34195
33634
|
const runtimeOnly = replayCounts.runtimeOnly;
|
|
34196
33635
|
const comparisonTotal = matched + backtestOnly + runtimeOnly;
|
|
34197
33636
|
const parityRatio = comparisonTotal > 0 ? matched / comparisonTotal : null;
|
|
34198
|
-
const lineage =
|
|
33637
|
+
const lineage = asRecord7(replayComparison?.lineage);
|
|
34199
33638
|
const lineageReason = finiteString2(lineage?.reason);
|
|
34200
|
-
const calibrationRoot =
|
|
34201
|
-
const calibrationSamples = asArray4(calibrationRoot.samples).map(
|
|
33639
|
+
const calibrationRoot = asRecord7(calibrationArtifact) ?? {};
|
|
33640
|
+
const calibrationSamples = asArray4(calibrationRoot.samples).map(asRecord7).filter((item) => item != null).filter((item) => !strategy || finiteString2(item.strategy) === strategy).filter((item) => embeddedLineageScope.belongs(item));
|
|
34202
33641
|
const averageSampleMetric = (field) => {
|
|
34203
33642
|
const values = calibrationSamples.map((sample) => finiteNumber6(sample[field])).filter((value) => value != null);
|
|
34204
33643
|
return values.length ? round3(sum2(values) / values.length) : null;
|
|
@@ -34798,7 +34237,7 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
34798
34237
|
let artifact;
|
|
34799
34238
|
try {
|
|
34800
34239
|
const parsed = JSON.parse(
|
|
34801
|
-
await
|
|
34240
|
+
await import_promises33.default.readFile(reference.path, "utf8")
|
|
34802
34241
|
);
|
|
34803
34242
|
assert3(
|
|
34804
34243
|
parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
|
|
@@ -34945,13 +34384,13 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
34945
34384
|
})
|
|
34946
34385
|
);
|
|
34947
34386
|
}
|
|
34948
|
-
var
|
|
34387
|
+
var import_node_crypto15, import_promises33, import_node_path31, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment5, compactTimestamp, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber7, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
|
|
34949
34388
|
var init_strategyRelease = __esm({
|
|
34950
34389
|
"src/lib/strategyRelease.ts"() {
|
|
34951
34390
|
"use strict";
|
|
34952
|
-
|
|
34953
|
-
|
|
34954
|
-
|
|
34391
|
+
import_node_crypto15 = require("crypto");
|
|
34392
|
+
import_promises33 = __toESM(require("fs/promises"));
|
|
34393
|
+
import_node_path31 = __toESM(require("path"));
|
|
34955
34394
|
import_types9 = require("@tradejs/types");
|
|
34956
34395
|
import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
34957
34396
|
init_liveDiagnosis();
|
|
@@ -34964,17 +34403,17 @@ var init_strategyRelease = __esm({
|
|
|
34964
34403
|
REQUIRED_LONG_WINDOWS = [1095, 1460, 1825];
|
|
34965
34404
|
REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS = [365, 180, 90];
|
|
34966
34405
|
MIN_RECENT_DIRECTION_REPAIR_EVENTS = 20;
|
|
34967
|
-
|
|
34968
|
-
|
|
34406
|
+
safeSegment5 = import_strategyReleaseEvidence2.safeStrategyEvidenceSegment;
|
|
34407
|
+
compactTimestamp = import_strategyReleaseEvidence2.compactStrategyEvidenceTimestamp;
|
|
34969
34408
|
verifyFullPeriodChartArtifact = async (input) => {
|
|
34970
34409
|
const artifact = input.chartArtifact;
|
|
34971
34410
|
if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return false;
|
|
34972
34411
|
try {
|
|
34973
|
-
const artifactPath =
|
|
34412
|
+
const artifactPath = import_node_path31.default.resolve(artifact.path);
|
|
34974
34413
|
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
34975
34414
|
return false;
|
|
34976
34415
|
}
|
|
34977
|
-
const report = JSON.parse(await
|
|
34416
|
+
const report = JSON.parse(await import_promises33.default.readFile(artifactPath, "utf8"));
|
|
34978
34417
|
return Boolean(
|
|
34979
34418
|
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
|
|
34980
34419
|
);
|
|
@@ -34985,11 +34424,11 @@ var init_strategyRelease = __esm({
|
|
|
34985
34424
|
readVerifiedJsonArtifact = async (artifact) => {
|
|
34986
34425
|
if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return null;
|
|
34987
34426
|
try {
|
|
34988
|
-
const artifactPath =
|
|
34427
|
+
const artifactPath = import_node_path31.default.resolve(artifact.path);
|
|
34989
34428
|
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
34990
34429
|
return null;
|
|
34991
34430
|
}
|
|
34992
|
-
return JSON.parse(await
|
|
34431
|
+
return JSON.parse(await import_promises33.default.readFile(artifactPath, "utf8"));
|
|
34993
34432
|
} catch {
|
|
34994
34433
|
return null;
|
|
34995
34434
|
}
|
|
@@ -35480,7 +34919,7 @@ var init_strategyRelease = __esm({
|
|
|
35480
34919
|
maxLossValue: input.composition.maxLossValue,
|
|
35481
34920
|
...input.composition.directionPolicy == null ? {} : { directionPolicy: input.composition.directionPolicy }
|
|
35482
34921
|
};
|
|
35483
|
-
const compositionId = `${
|
|
34922
|
+
const compositionId = `${safeSegment5(input.strategy, "strategy")}_${strategyReleaseSha256(compositionIdentity).slice(0, 16)}`;
|
|
35484
34923
|
const reasons = releaseReasons({ ...input, gates: evidenceGates });
|
|
35485
34924
|
const economicFailure = reasons.some(
|
|
35486
34925
|
(reason) => [
|
|
@@ -35502,16 +34941,16 @@ var init_strategyRelease = __esm({
|
|
|
35502
34941
|
strategy: input.strategy,
|
|
35503
34942
|
createdAt: input.createdAt,
|
|
35504
34943
|
compositionId,
|
|
35505
|
-
evidence: input.evidence.map(({ kind, artifactId, sha256:
|
|
34944
|
+
evidence: input.evidence.map(({ kind, artifactId, sha256: sha2562 }) => ({
|
|
35506
34945
|
kind,
|
|
35507
34946
|
artifactId,
|
|
35508
|
-
sha256:
|
|
34947
|
+
sha256: sha2562
|
|
35509
34948
|
})),
|
|
35510
34949
|
verdict
|
|
35511
34950
|
};
|
|
35512
34951
|
return {
|
|
35513
34952
|
schema: import_types9.STRATEGY_RELEASE_SCHEMA,
|
|
35514
|
-
releaseId: `${
|
|
34953
|
+
releaseId: `${safeSegment5(input.strategy, "strategy")}_${compactTimestamp(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
|
|
35515
34954
|
strategy: input.strategy,
|
|
35516
34955
|
createdAt: input.createdAt,
|
|
35517
34956
|
composition: { ...input.composition, compositionId },
|
|
@@ -35535,7 +34974,7 @@ var init_strategyRelease = __esm({
|
|
|
35535
34974
|
manifest
|
|
35536
34975
|
});
|
|
35537
34976
|
verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
35538
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
34977
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises33.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
35539
34978
|
const envelope = value;
|
|
35540
34979
|
assert3(
|
|
35541
34980
|
envelope?.schema === "tradejs-strategy-release-envelope/v1",
|
|
@@ -35586,7 +35025,7 @@ var init_strategyRelease = __esm({
|
|
|
35586
35025
|
return envelope;
|
|
35587
35026
|
};
|
|
35588
35027
|
verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
|
|
35589
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
35028
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises33.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
35590
35029
|
return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
|
|
35591
35030
|
};
|
|
35592
35031
|
releaseMarkers = (manifest) => {
|
|
@@ -35648,14 +35087,14 @@ var init_strategyRelease = __esm({
|
|
|
35648
35087
|
};
|
|
35649
35088
|
writeJsonAtomic2 = async (filePath, value) => {
|
|
35650
35089
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
35651
|
-
await
|
|
35652
|
-
await
|
|
35090
|
+
await import_promises33.default.mkdir(import_node_path31.default.dirname(filePath), { recursive: true });
|
|
35091
|
+
await import_promises33.default.writeFile(
|
|
35653
35092
|
temporaryPath,
|
|
35654
35093
|
`${canonicalStrategyReleaseJson(value)}
|
|
35655
35094
|
`,
|
|
35656
35095
|
"utf8"
|
|
35657
35096
|
);
|
|
35658
|
-
await
|
|
35097
|
+
await import_promises33.default.rename(temporaryPath, filePath);
|
|
35659
35098
|
};
|
|
35660
35099
|
publishStrategyRelease = async ({
|
|
35661
35100
|
rootDir,
|
|
@@ -35672,16 +35111,16 @@ var init_strategyRelease = __esm({
|
|
|
35672
35111
|
path: entry.path
|
|
35673
35112
|
}))
|
|
35674
35113
|
});
|
|
35675
|
-
const releasePath =
|
|
35114
|
+
const releasePath = import_node_path31.default.join(
|
|
35676
35115
|
rootDir,
|
|
35677
35116
|
"releases",
|
|
35678
|
-
|
|
35117
|
+
safeSegment5(manifest.strategy, "strategy"),
|
|
35679
35118
|
`${manifest.releaseId}.json`
|
|
35680
35119
|
);
|
|
35681
|
-
const markerPath =
|
|
35120
|
+
const markerPath = import_node_path31.default.join(
|
|
35682
35121
|
rootDir,
|
|
35683
35122
|
"markers",
|
|
35684
|
-
|
|
35123
|
+
safeSegment5(manifest.strategy, "strategy"),
|
|
35685
35124
|
`${markerEnvelope.artifactId}.json`
|
|
35686
35125
|
);
|
|
35687
35126
|
await Promise.all([
|
|
@@ -35701,7 +35140,7 @@ var init_strategyRelease = __esm({
|
|
|
35701
35140
|
composition
|
|
35702
35141
|
}) => {
|
|
35703
35142
|
const diagnosisSha256 = strategyReleaseSha256(diagnosis);
|
|
35704
|
-
const diagnosisId = `${
|
|
35143
|
+
const diagnosisId = `${safeSegment5(diagnosis.strategy, "strategy")}_${compactTimestamp(diagnosis.createdAt)}_${diagnosisSha256.slice(0, 16)}`;
|
|
35705
35144
|
const envelope = {
|
|
35706
35145
|
schema: "tradejs-strategy-live-diagnosis-envelope/v1",
|
|
35707
35146
|
diagnosisId,
|
|
@@ -35758,16 +35197,16 @@ var init_strategyRelease = __esm({
|
|
|
35758
35197
|
markers,
|
|
35759
35198
|
sourceArtifacts
|
|
35760
35199
|
});
|
|
35761
|
-
const diagnosisPath =
|
|
35200
|
+
const diagnosisPath = import_node_path31.default.join(
|
|
35762
35201
|
rootDir,
|
|
35763
35202
|
"diagnoses",
|
|
35764
|
-
|
|
35203
|
+
safeSegment5(diagnosis.strategy, "strategy"),
|
|
35765
35204
|
`${diagnosisId}.json`
|
|
35766
35205
|
);
|
|
35767
|
-
const markerPath =
|
|
35206
|
+
const markerPath = import_node_path31.default.join(
|
|
35768
35207
|
rootDir,
|
|
35769
35208
|
"markers",
|
|
35770
|
-
|
|
35209
|
+
safeSegment5(diagnosis.strategy, "strategy"),
|
|
35771
35210
|
`${markerEnvelope.artifactId}.json`
|
|
35772
35211
|
);
|
|
35773
35212
|
await Promise.all([
|
|
@@ -35954,11 +35393,11 @@ var init_strategyRelease = __esm({
|
|
|
35954
35393
|
const specSha256 = finiteString3(artifact.specSha256);
|
|
35955
35394
|
assert3(researchId != null, "core result researchId is required");
|
|
35956
35395
|
assert3(specSha256 != null, "core result specSha256 is required");
|
|
35957
|
-
const researchDir =
|
|
35958
|
-
const manifestPath =
|
|
35959
|
-
const specPath =
|
|
35960
|
-
const manifestBytes = await
|
|
35961
|
-
const specBytes = await
|
|
35396
|
+
const researchDir = import_node_path31.default.dirname(resultPath);
|
|
35397
|
+
const manifestPath = import_node_path31.default.join(researchDir, "manifest.json");
|
|
35398
|
+
const specPath = import_node_path31.default.join(researchDir, "spec.json");
|
|
35399
|
+
const manifestBytes = await import_promises33.default.readFile(manifestPath).catch(() => null);
|
|
35400
|
+
const specBytes = await import_promises33.default.readFile(specPath).catch(() => null);
|
|
35962
35401
|
assert3(
|
|
35963
35402
|
manifestBytes != null && specBytes != null,
|
|
35964
35403
|
"core result must belong to a completed core research bundle"
|
|
@@ -35967,14 +35406,14 @@ var init_strategyRelease = __esm({
|
|
|
35967
35406
|
const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
|
|
35968
35407
|
const parsedSpec = JSON.parse(specBytes.toString("utf8"));
|
|
35969
35408
|
assert3(
|
|
35970
|
-
manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0,
|
|
35409
|
+
manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto15.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
|
|
35971
35410
|
"core result is not bound by its completed core research manifest"
|
|
35972
35411
|
);
|
|
35973
35412
|
for (const [relativePath, expectedSha256] of Object.entries(
|
|
35974
35413
|
artifactHashes ?? {}
|
|
35975
35414
|
)) {
|
|
35976
35415
|
assert3(
|
|
35977
|
-
!
|
|
35416
|
+
!import_node_path31.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
|
|
35978
35417
|
`core bundle artifact ${relativePath} escapes its research directory`
|
|
35979
35418
|
);
|
|
35980
35419
|
assert3(
|
|
@@ -35982,7 +35421,7 @@ var init_strategyRelease = __esm({
|
|
|
35982
35421
|
`core bundle artifact ${relativePath} has an invalid checksum`
|
|
35983
35422
|
);
|
|
35984
35423
|
const actualSha256 = await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(
|
|
35985
|
-
|
|
35424
|
+
import_node_path31.default.join(researchDir, relativePath)
|
|
35986
35425
|
);
|
|
35987
35426
|
assert3(
|
|
35988
35427
|
actualSha256 === expectedSha256,
|
|
@@ -35996,16 +35435,16 @@ var init_strategyRelease = __esm({
|
|
|
35996
35435
|
// src/scripts/runtimeScorecard.ts
|
|
35997
35436
|
var runtimeScorecard_exports = {};
|
|
35998
35437
|
__export(runtimeScorecard_exports, {
|
|
35999
|
-
main: () =>
|
|
35438
|
+
main: () => main42,
|
|
36000
35439
|
runtimeScorecard: () => runtimeScorecard
|
|
36001
35440
|
});
|
|
36002
|
-
var
|
|
35441
|
+
var import_promises34, import_node_crypto16, import_node_path32, import_args33, import_chalk49, flags30, projectRoot14, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main42;
|
|
36003
35442
|
var init_runtimeScorecard2 = __esm({
|
|
36004
35443
|
"src/scripts/runtimeScorecard.ts"() {
|
|
36005
35444
|
"use strict";
|
|
36006
|
-
|
|
36007
|
-
|
|
36008
|
-
|
|
35445
|
+
import_promises34 = __toESM(require("fs/promises"));
|
|
35446
|
+
import_node_crypto16 = require("crypto");
|
|
35447
|
+
import_node_path32 = __toESM(require("path"));
|
|
36009
35448
|
import_args33 = __toESM(require("args"));
|
|
36010
35449
|
import_chalk49 = __toESM(require("chalk"));
|
|
36011
35450
|
init_runtimeEvidenceArtifacts();
|
|
@@ -36075,21 +35514,21 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36075
35514
|
projectRoot14 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
36076
35515
|
resolveOptionalPath = (value) => {
|
|
36077
35516
|
const raw = String(value ?? "").trim();
|
|
36078
|
-
return raw ?
|
|
35517
|
+
return raw ? import_node_path32.default.resolve(projectRoot14, raw) : null;
|
|
36079
35518
|
};
|
|
36080
|
-
readJson = async (filePath) => filePath ? JSON.parse(await
|
|
35519
|
+
readJson = async (filePath) => filePath ? JSON.parse(await import_promises34.default.readFile(filePath, "utf8")) : void 0;
|
|
36081
35520
|
assertReportType = (artifact, expected, label) => {
|
|
36082
35521
|
if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
|
|
36083
35522
|
throw new Error(`${label} must be a ${expected} artifact`);
|
|
36084
35523
|
}
|
|
36085
35524
|
};
|
|
36086
|
-
sha256File2 = async (filePath) => (0,
|
|
35525
|
+
sha256File2 = async (filePath) => (0, import_node_crypto16.createHash)("sha256").update(await import_promises34.default.readFile(filePath)).digest("hex");
|
|
36087
35526
|
loadHistoryArtifacts = async (historyDir) => {
|
|
36088
35527
|
if (!historyDir) return [];
|
|
36089
|
-
const bundleDirs = await discoverRuntimeEvidenceBundles(historyDir);
|
|
35528
|
+
const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(historyDir);
|
|
36090
35529
|
const bundles = [];
|
|
36091
35530
|
for (const bundleDir of bundleDirs) {
|
|
36092
|
-
bundles.push(await verifyRuntimeEvidenceBundle(bundleDir));
|
|
35531
|
+
bundles.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir));
|
|
36093
35532
|
}
|
|
36094
35533
|
return bundles.map((bundle) => bundle.artifact);
|
|
36095
35534
|
};
|
|
@@ -36154,13 +35593,13 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36154
35593
|
strategy: scorecardStrategy,
|
|
36155
35594
|
llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
|
|
36156
35595
|
});
|
|
36157
|
-
const outPath =
|
|
35596
|
+
const outPath = import_node_path32.default.resolve(projectRoot14, String(flags30.out));
|
|
36158
35597
|
const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
|
|
36159
|
-
await
|
|
35598
|
+
await import_promises34.default.mkdir(import_node_path32.default.dirname(outPath), { recursive: true });
|
|
36160
35599
|
await Promise.all([
|
|
36161
|
-
|
|
35600
|
+
import_promises34.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
|
|
36162
35601
|
`, "utf8"),
|
|
36163
|
-
|
|
35602
|
+
import_promises34.default.writeFile(
|
|
36164
35603
|
markdownPath,
|
|
36165
35604
|
formatRuntimeScorecardMarkdown(scorecard),
|
|
36166
35605
|
"utf8"
|
|
@@ -36174,7 +35613,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36174
35613
|
const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
|
|
36175
35614
|
const strategyReleaseRoot = resolveOptionalPath(flags30.strategyReleaseRoot);
|
|
36176
35615
|
if (diagnosis && diagnosisPath) {
|
|
36177
|
-
await
|
|
35616
|
+
await import_promises34.default.writeFile(
|
|
36178
35617
|
diagnosisPath,
|
|
36179
35618
|
`${JSON.stringify(diagnosis, null, 2)}
|
|
36180
35619
|
`,
|
|
@@ -36195,7 +35634,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36195
35634
|
composition: verifiedRelease?.manifest.composition,
|
|
36196
35635
|
sourceArtifacts: await Promise.all(
|
|
36197
35636
|
sourcePaths.map(async (sourcePath) => ({
|
|
36198
|
-
artifactId:
|
|
35637
|
+
artifactId: import_node_path32.default.basename(sourcePath),
|
|
36199
35638
|
path: sourcePath,
|
|
36200
35639
|
sha256: await sha256File2(sourcePath)
|
|
36201
35640
|
}))
|
|
@@ -36205,12 +35644,12 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36205
35644
|
}
|
|
36206
35645
|
let receiptPath2 = null;
|
|
36207
35646
|
if (flags30.markProcessed) {
|
|
36208
|
-
const runtimeEvidenceBundle = await verifyRuntimeEvidenceBundle(
|
|
36209
|
-
|
|
35647
|
+
const runtimeEvidenceBundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(
|
|
35648
|
+
import_node_path32.default.dirname(runtimeEvidencePath)
|
|
36210
35649
|
);
|
|
36211
|
-
const feedbackSource = replayEvidencePath ? await verifyRuntimeFeedbackReplaySource({
|
|
36212
|
-
bundleDir:
|
|
36213
|
-
runtimeEvidenceBundleDir:
|
|
35650
|
+
const feedbackSource = replayEvidencePath ? await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplaySource)({
|
|
35651
|
+
bundleDir: import_node_path32.default.dirname(replayEvidencePath),
|
|
35652
|
+
runtimeEvidenceBundleDir: import_node_path32.default.dirname(runtimeEvidencePath)
|
|
36214
35653
|
}).catch((error) => {
|
|
36215
35654
|
if (runtimeEvidenceBundle.artifact.producer) throw error;
|
|
36216
35655
|
return null;
|
|
@@ -36221,9 +35660,9 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36221
35660
|
);
|
|
36222
35661
|
}
|
|
36223
35662
|
receiptPath2 = await markRuntimeEvidenceBundleProcessed({
|
|
36224
|
-
evidenceRoot:
|
|
35663
|
+
evidenceRoot: import_node_path32.default.resolve(projectRoot14, String(flags30.evidenceDir)),
|
|
36225
35664
|
deploymentId: String(flags30.deployment),
|
|
36226
|
-
bundleDir:
|
|
35665
|
+
bundleDir: import_node_path32.default.dirname(runtimeEvidencePath),
|
|
36227
35666
|
scorecardPath: outPath,
|
|
36228
35667
|
runtimeFeedback: feedbackSource ? {
|
|
36229
35668
|
artifactId: feedbackSource.feedback.manifest.artifactId,
|
|
@@ -36251,7 +35690,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36251
35690
|
)
|
|
36252
35691
|
);
|
|
36253
35692
|
};
|
|
36254
|
-
|
|
35693
|
+
main42 = runtimeScorecard;
|
|
36255
35694
|
}
|
|
36256
35695
|
});
|
|
36257
35696
|
|
|
@@ -36259,16 +35698,16 @@ var init_runtimeScorecard2 = __esm({
|
|
|
36259
35698
|
var runtimeControl_exports = {};
|
|
36260
35699
|
__export(runtimeControl_exports, {
|
|
36261
35700
|
RUNTIME_CONTROL_ACTIONS: () => RUNTIME_CONTROL_ACTIONS,
|
|
36262
|
-
main: () =>
|
|
35701
|
+
main: () => main43,
|
|
36263
35702
|
runtimeControl: () => runtimeControl
|
|
36264
35703
|
});
|
|
36265
|
-
var import_config9, import_runtimeControls,
|
|
35704
|
+
var import_config9, import_runtimeControls, import_runtimeStrategies5, argv, RUNTIME_CONTROL_ACTIONS, action, option, required2, projectRoot15, userName2, verify, inspect, updateControlState, runtimeControl, main43;
|
|
36266
35705
|
var init_runtimeControl = __esm({
|
|
36267
35706
|
"src/scripts/runtimeControl.ts"() {
|
|
36268
35707
|
"use strict";
|
|
36269
35708
|
import_config9 = require("dotenv/config");
|
|
36270
35709
|
import_runtimeControls = require("@tradejs/infra/runtimeControls");
|
|
36271
|
-
|
|
35710
|
+
import_runtimeStrategies5 = require("@tradejs/node/runtimeStrategies");
|
|
36272
35711
|
argv = process.argv.slice(2);
|
|
36273
35712
|
RUNTIME_CONTROL_ACTIONS = [
|
|
36274
35713
|
"inspect",
|
|
@@ -36289,7 +35728,7 @@ var init_runtimeControl = __esm({
|
|
|
36289
35728
|
projectRoot15 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
36290
35729
|
userName2 = String(option("user") ?? process.env.USER_NAME ?? "root");
|
|
36291
35730
|
verify = async () => {
|
|
36292
|
-
const deployments = await (0,
|
|
35731
|
+
const deployments = await (0, import_runtimeStrategies5.listRuntimeDeployments)({ userName: userName2, projectRoot: projectRoot15 });
|
|
36293
35732
|
const requestedDeployment = option("deployment");
|
|
36294
35733
|
const selected = requestedDeployment ? deployments.filter((deployment) => deployment.id === requestedDeployment) : deployments;
|
|
36295
35734
|
if (requestedDeployment && !selected.length) {
|
|
@@ -36298,7 +35737,7 @@ var init_runtimeControl = __esm({
|
|
|
36298
35737
|
const results2 = [];
|
|
36299
35738
|
for (const deployment of selected) {
|
|
36300
35739
|
try {
|
|
36301
|
-
const strategies = await (0,
|
|
35740
|
+
const strategies = await (0, import_runtimeStrategies5.loadResolvedRuntimeStrategies)({
|
|
36302
35741
|
userName: userName2,
|
|
36303
35742
|
projectRoot: projectRoot15,
|
|
36304
35743
|
deploymentId: deployment.id
|
|
@@ -36333,7 +35772,7 @@ var init_runtimeControl = __esm({
|
|
|
36333
35772
|
inspect = async () => {
|
|
36334
35773
|
const requestedDeployment = option("deployment");
|
|
36335
35774
|
const requestedStrategy = option("strategy");
|
|
36336
|
-
const deployments = (await (0,
|
|
35775
|
+
const deployments = (await (0, import_runtimeStrategies5.listRuntimeDeployments)({ userName: userName2, projectRoot: projectRoot15 })).filter(
|
|
36337
35776
|
(deployment) => !requestedDeployment || deployment.id === requestedDeployment
|
|
36338
35777
|
).map((deployment) => ({
|
|
36339
35778
|
...deployment,
|
|
@@ -36346,7 +35785,7 @@ var init_runtimeControl = __esm({
|
|
|
36346
35785
|
updateControlState = async (nextState) => {
|
|
36347
35786
|
const deploymentId = required2("deployment");
|
|
36348
35787
|
const strategyName = required2("strategy");
|
|
36349
|
-
const deployment = await (0,
|
|
35788
|
+
const deployment = await (0, import_runtimeStrategies5.getRuntimeDeployment)({
|
|
36350
35789
|
userName: userName2,
|
|
36351
35790
|
projectRoot: projectRoot15,
|
|
36352
35791
|
deploymentId
|
|
@@ -36376,7 +35815,7 @@ var init_runtimeControl = __esm({
|
|
|
36376
35815
|
} else {
|
|
36377
35816
|
await (0, import_runtimeControls.resumeRuntimeStrategy)({ userName: userName2, deploymentId, strategyName });
|
|
36378
35817
|
}
|
|
36379
|
-
const updated = await (0,
|
|
35818
|
+
const updated = await (0, import_runtimeStrategies5.getRuntimeDeployment)({
|
|
36380
35819
|
userName: userName2,
|
|
36381
35820
|
projectRoot: projectRoot15,
|
|
36382
35821
|
deploymentId
|
|
@@ -36410,24 +35849,24 @@ var init_runtimeControl = __esm({
|
|
|
36410
35849
|
`Usage: tradejs runtime-control ${RUNTIME_CONTROL_ACTIONS.join("|")}`
|
|
36411
35850
|
);
|
|
36412
35851
|
};
|
|
36413
|
-
|
|
35852
|
+
main43 = runtimeControl;
|
|
36414
35853
|
}
|
|
36415
35854
|
});
|
|
36416
35855
|
|
|
36417
35856
|
// src/scripts/strategyRelease.ts
|
|
36418
35857
|
var strategyRelease_exports = {};
|
|
36419
35858
|
__export(strategyRelease_exports, {
|
|
36420
|
-
main: () =>
|
|
35859
|
+
main: () => main44,
|
|
36421
35860
|
runStrategyReleaseCommand: () => runStrategyReleaseCommand
|
|
36422
35861
|
});
|
|
36423
|
-
var
|
|
35862
|
+
var import_promises35, import_node_fs6, import_node_readline3, import_node_path33, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main44;
|
|
36424
35863
|
var init_strategyRelease2 = __esm({
|
|
36425
35864
|
"src/scripts/strategyRelease.ts"() {
|
|
36426
35865
|
"use strict";
|
|
36427
|
-
|
|
35866
|
+
import_promises35 = __toESM(require("fs/promises"));
|
|
36428
35867
|
import_node_fs6 = require("fs");
|
|
36429
35868
|
import_node_readline3 = require("readline");
|
|
36430
|
-
|
|
35869
|
+
import_node_path33 = __toESM(require("path"));
|
|
36431
35870
|
import_chalk50 = __toESM(require("chalk"));
|
|
36432
35871
|
init_strategyRelease();
|
|
36433
35872
|
valueAfter2 = (argv2, name) => {
|
|
@@ -36440,17 +35879,17 @@ var init_strategyRelease2 = __esm({
|
|
|
36440
35879
|
};
|
|
36441
35880
|
writeJsonAtomic3 = async (filePath, value) => {
|
|
36442
35881
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
36443
|
-
await
|
|
36444
|
-
await
|
|
35882
|
+
await import_promises35.default.mkdir(import_node_path33.default.dirname(filePath), { recursive: true });
|
|
35883
|
+
await import_promises35.default.writeFile(
|
|
36445
35884
|
temporaryPath,
|
|
36446
35885
|
`${JSON.stringify(value, null, 2)}
|
|
36447
35886
|
`,
|
|
36448
35887
|
"utf8"
|
|
36449
35888
|
);
|
|
36450
|
-
await
|
|
35889
|
+
await import_promises35.default.rename(temporaryPath, filePath);
|
|
36451
35890
|
};
|
|
36452
35891
|
runStrategyReleaseCommand = async (options) => {
|
|
36453
|
-
const inputPath =
|
|
35892
|
+
const inputPath = import_node_path33.default.resolve(options.inputPath);
|
|
36454
35893
|
if (options.command === "verify") {
|
|
36455
35894
|
const envelope = await verifyStrategyReleaseEnvelope(inputPath);
|
|
36456
35895
|
return {
|
|
@@ -36488,7 +35927,7 @@ var init_strategyRelease2 = __esm({
|
|
|
36488
35927
|
endTime,
|
|
36489
35928
|
days: options.days?.length ? options.days : [7, 30, 90]
|
|
36490
35929
|
});
|
|
36491
|
-
const outputPath =
|
|
35930
|
+
const outputPath = import_node_path33.default.resolve(
|
|
36492
35931
|
options.outputPath ?? "output/strategy-monitoring-profile.json"
|
|
36493
35932
|
);
|
|
36494
35933
|
await writeJsonAtomic3(outputPath, profile);
|
|
@@ -36499,22 +35938,22 @@ var init_strategyRelease2 = __esm({
|
|
|
36499
35938
|
profile
|
|
36500
35939
|
};
|
|
36501
35940
|
}
|
|
36502
|
-
const input = JSON.parse(await
|
|
35941
|
+
const input = JSON.parse(await import_promises35.default.readFile(inputPath, "utf8"));
|
|
36503
35942
|
if (options.command === "decide") {
|
|
36504
35943
|
const decision = await deriveStrategyReleaseResearchDecision(input);
|
|
36505
35944
|
if (options.outputPath) {
|
|
36506
|
-
await writeJsonAtomic3(
|
|
35945
|
+
await writeJsonAtomic3(import_node_path33.default.resolve(options.outputPath), decision);
|
|
36507
35946
|
}
|
|
36508
35947
|
return {
|
|
36509
35948
|
kind: "decided",
|
|
36510
35949
|
...decision,
|
|
36511
|
-
outputPath: options.outputPath ?
|
|
35950
|
+
outputPath: options.outputPath ? import_node_path33.default.resolve(options.outputPath) : null
|
|
36512
35951
|
};
|
|
36513
35952
|
}
|
|
36514
35953
|
if (options.command === "retention") {
|
|
36515
35954
|
const plan = planStrategyEvidenceRetention(input);
|
|
36516
35955
|
if (options.apply) {
|
|
36517
|
-
await Promise.all(plan.delete.map((entry) =>
|
|
35956
|
+
await Promise.all(plan.delete.map((entry) => import_promises35.default.rm(entry.path)));
|
|
36518
35957
|
}
|
|
36519
35958
|
return {
|
|
36520
35959
|
kind: "retention",
|
|
@@ -36527,12 +35966,12 @@ var init_strategyRelease2 = __esm({
|
|
|
36527
35966
|
}
|
|
36528
35967
|
if (options.command === "diagnose") {
|
|
36529
35968
|
const diagnosis = buildStrategyLiveDiagnosis(input);
|
|
36530
|
-
const outputPath =
|
|
35969
|
+
const outputPath = import_node_path33.default.resolve(
|
|
36531
35970
|
options.outputPath ?? "output/strategy-live-diagnosis.json"
|
|
36532
35971
|
);
|
|
36533
35972
|
await writeJsonAtomic3(outputPath, diagnosis);
|
|
36534
35973
|
const published2 = options.rootDir ? await publishStrategyLiveDiagnosis({
|
|
36535
|
-
rootDir:
|
|
35974
|
+
rootDir: import_node_path33.default.resolve(options.rootDir),
|
|
36536
35975
|
diagnosis,
|
|
36537
35976
|
sourceArtifacts: input.sourceArtifacts ?? []
|
|
36538
35977
|
}) : null;
|
|
@@ -36549,7 +35988,7 @@ var init_strategyRelease2 = __esm({
|
|
|
36549
35988
|
evidence: await collectReleaseEvidenceReferences(input.evidence ?? [])
|
|
36550
35989
|
});
|
|
36551
35990
|
const published = await publishStrategyRelease({
|
|
36552
|
-
rootDir:
|
|
35991
|
+
rootDir: import_node_path33.default.resolve(options.rootDir ?? "data/strategy-release"),
|
|
36553
35992
|
manifest
|
|
36554
35993
|
});
|
|
36555
35994
|
return {
|
|
@@ -36567,7 +36006,7 @@ var init_strategyRelease2 = __esm({
|
|
|
36567
36006
|
yarn strategy:release profile --input <trades.jsonl> --variant <id> --startTime <ms> --endTime <ms> [--days 7,30,90] [--out <profile.json>]
|
|
36568
36007
|
yarn strategy:release diagnose --input <diagnosis-input.json> [--out output/diagnosis.json]
|
|
36569
36008
|
yarn strategy:release retention --input <inventory.json> [--apply]`);
|
|
36570
|
-
|
|
36009
|
+
main44 = async () => {
|
|
36571
36010
|
const argv2 = process.argv.slice(2);
|
|
36572
36011
|
const command = argv2[0];
|
|
36573
36012
|
if (!command || ![
|
|
@@ -36606,19 +36045,19 @@ __export(serverHealth_exports, {
|
|
|
36606
36045
|
buildServerHealthDiagnostics: () => buildServerHealthDiagnostics,
|
|
36607
36046
|
collectServerHealthSnapshot: () => collectServerHealthSnapshot,
|
|
36608
36047
|
evaluateServerHealth: () => evaluateServerHealth,
|
|
36609
|
-
main: () =>
|
|
36048
|
+
main: () => main45,
|
|
36610
36049
|
resolveServerHealthThresholds: () => resolveServerHealthThresholds
|
|
36611
36050
|
});
|
|
36612
|
-
var import_config10,
|
|
36051
|
+
var import_config10, import_node_child_process10, import_node_os3, import_node_fs7, import_args34, import_redis20, DEFAULT_STATE, DEFAULT_THRESHOLDS, escapeHtml6, formatPctValue, formatLoadPerCore, formatGiB, formatDuration2, readDiskUsage, parseMeminfoBytes, readMemorySnapshot, runDiagnosticCommand, runDiagnosticCommands, collectServerHealthSnapshot, buildHumanSummaryLines, evaluateServerHealth, shouldRecover, buildAlertMessage, buildRecoveryMessage, buildServerHealthDiagnostics, getStateKey, toFiniteNumber3, resolveServerHealthThresholds, main45;
|
|
36613
36052
|
var init_serverHealth = __esm({
|
|
36614
36053
|
"src/scripts/serverHealth.ts"() {
|
|
36615
36054
|
"use strict";
|
|
36616
36055
|
import_config10 = require("dotenv/config");
|
|
36617
|
-
|
|
36056
|
+
import_node_child_process10 = require("child_process");
|
|
36618
36057
|
import_node_os3 = __toESM(require("os"));
|
|
36619
36058
|
import_node_fs7 = require("fs");
|
|
36620
36059
|
import_args34 = __toESM(require("args"));
|
|
36621
|
-
|
|
36060
|
+
import_redis20 = require("@tradejs/infra/redis");
|
|
36622
36061
|
init_telegramReports();
|
|
36623
36062
|
DEFAULT_STATE = {
|
|
36624
36063
|
status: "healthy",
|
|
@@ -36651,21 +36090,21 @@ var init_serverHealth = __esm({
|
|
|
36651
36090
|
}
|
|
36652
36091
|
return `${minutes}m`;
|
|
36653
36092
|
};
|
|
36654
|
-
readDiskUsage = (
|
|
36093
|
+
readDiskUsage = (path44) => {
|
|
36655
36094
|
try {
|
|
36656
|
-
const stats = (0, import_node_fs7.statfsSync)(
|
|
36095
|
+
const stats = (0, import_node_fs7.statfsSync)(path44);
|
|
36657
36096
|
const totalBlocks = Number(stats.blocks ?? 0);
|
|
36658
36097
|
const availableBlocks = Number(stats.bavail ?? 0);
|
|
36659
36098
|
if (totalBlocks <= 0) {
|
|
36660
|
-
return { path:
|
|
36099
|
+
return { path: path44, usedPct: null };
|
|
36661
36100
|
}
|
|
36662
36101
|
const usedPct = (totalBlocks - Math.max(0, availableBlocks)) / totalBlocks * 100;
|
|
36663
36102
|
return {
|
|
36664
|
-
path:
|
|
36103
|
+
path: path44,
|
|
36665
36104
|
usedPct: Number.isFinite(usedPct) ? usedPct : null
|
|
36666
36105
|
};
|
|
36667
36106
|
} catch {
|
|
36668
|
-
return { path:
|
|
36107
|
+
return { path: path44, usedPct: null };
|
|
36669
36108
|
}
|
|
36670
36109
|
};
|
|
36671
36110
|
parseMeminfoBytes = (value) => {
|
|
@@ -36730,7 +36169,7 @@ var init_serverHealth = __esm({
|
|
|
36730
36169
|
}
|
|
36731
36170
|
};
|
|
36732
36171
|
runDiagnosticCommand = (command, args39) => {
|
|
36733
|
-
const output = (0,
|
|
36172
|
+
const output = (0, import_node_child_process10.execFileSync)(command, args39, {
|
|
36734
36173
|
encoding: "utf8",
|
|
36735
36174
|
timeout: 5e3,
|
|
36736
36175
|
maxBuffer: 1024 * 1024,
|
|
@@ -37022,13 +36461,13 @@ var init_serverHealth = __esm({
|
|
|
37022
36461
|
"Recovery threshold for disk used percent",
|
|
37023
36462
|
String(DEFAULT_THRESHOLDS.diskRecoverPct)
|
|
37024
36463
|
);
|
|
37025
|
-
|
|
36464
|
+
main45 = async () => {
|
|
37026
36465
|
const flags35 = import_args34.default.parse(process.argv);
|
|
37027
36466
|
const thresholds = resolveServerHealthThresholds(flags35);
|
|
37028
36467
|
const diskPath = String(flags35.diskPath || "/");
|
|
37029
36468
|
const snapshot = collectServerHealthSnapshot(diskPath);
|
|
37030
36469
|
const stateKey = getStateKey(String(flags35.user), snapshot.hostname);
|
|
37031
|
-
const prevState = await (0,
|
|
36470
|
+
const prevState = await (0, import_redis20.getData)(stateKey, DEFAULT_STATE) ?? DEFAULT_STATE;
|
|
37032
36471
|
const evaluation = evaluateServerHealth(snapshot, thresholds);
|
|
37033
36472
|
const cooldownMs = Math.max(60, Number(flags35.cooldownSec)) * 1e3;
|
|
37034
36473
|
const now2 = snapshot.timestamp;
|
|
@@ -37041,7 +36480,7 @@ var init_serverHealth = __esm({
|
|
|
37041
36480
|
lastOkAt: prevState.lastOkAt,
|
|
37042
36481
|
activeIssueCodes: evaluation.issues.map((issue) => issue.code)
|
|
37043
36482
|
};
|
|
37044
|
-
await (0,
|
|
36483
|
+
await (0, import_redis20.setData)(stateKey, nextState2, { expire: 0 });
|
|
37045
36484
|
if (shouldSend) {
|
|
37046
36485
|
const message = buildAlertMessage({
|
|
37047
36486
|
evaluation,
|
|
@@ -37070,7 +36509,7 @@ var init_serverHealth = __esm({
|
|
|
37070
36509
|
lastOkAt: now2,
|
|
37071
36510
|
activeIssueCodes: []
|
|
37072
36511
|
};
|
|
37073
|
-
await (0,
|
|
36512
|
+
await (0, import_redis20.setData)(stateKey, nextState, { expire: 0 });
|
|
37074
36513
|
if (recovered) {
|
|
37075
36514
|
const message = buildRecoveryMessage({ snapshot, prevState });
|
|
37076
36515
|
if (flags35.printOnly) {
|
|
@@ -38414,21 +37853,21 @@ var init_reporting = __esm({
|
|
|
38414
37853
|
var runtimeParity_exports = {};
|
|
38415
37854
|
__export(runtimeParity_exports, {
|
|
38416
37855
|
buildRuntimeParityMessage: () => buildRuntimeParityMessage,
|
|
38417
|
-
main: () =>
|
|
37856
|
+
main: () => main46,
|
|
38418
37857
|
runtimeParity: () => runtimeParity
|
|
38419
37858
|
});
|
|
38420
|
-
var import_config11,
|
|
37859
|
+
var import_config11, import_node_crypto17, import_args35, import_chalk52, import_constants19, import_time13, import_logger7, import_redis21, import_cli12, import_backtest7, import_connectors15, flags31, interval3, projectRoot16, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main46;
|
|
38421
37860
|
var init_runtimeParity2 = __esm({
|
|
38422
37861
|
"src/scripts/runtimeParity.ts"() {
|
|
38423
37862
|
"use strict";
|
|
38424
37863
|
import_config11 = require("dotenv/config");
|
|
38425
|
-
|
|
37864
|
+
import_node_crypto17 = require("crypto");
|
|
38426
37865
|
import_args35 = __toESM(require("args"));
|
|
38427
37866
|
import_chalk52 = __toESM(require("chalk"));
|
|
38428
37867
|
import_constants19 = require("@tradejs/core/constants");
|
|
38429
37868
|
import_time13 = require("@tradejs/core/time");
|
|
38430
37869
|
import_logger7 = require("@tradejs/infra/logger");
|
|
38431
|
-
|
|
37870
|
+
import_redis21 = require("@tradejs/infra/redis");
|
|
38432
37871
|
import_cli12 = require("@tradejs/node/cli");
|
|
38433
37872
|
import_backtest7 = require("@tradejs/node/backtest");
|
|
38434
37873
|
import_connectors15 = require("@tradejs/node/connectors");
|
|
@@ -38588,8 +38027,8 @@ var init_runtimeParity2 = __esm({
|
|
|
38588
38027
|
toleranceMs
|
|
38589
38028
|
}) => {
|
|
38590
38029
|
const [userConfig, strategyResults] = await Promise.all([
|
|
38591
|
-
(0,
|
|
38592
|
-
(0,
|
|
38030
|
+
(0, import_redis21.getData)(import_redis21.redisKeys.strategyConfig(userName3, strategy), {}),
|
|
38031
|
+
(0, import_redis21.getData)(import_redis21.redisKeys.strategyResults(userName3, strategy), {})
|
|
38593
38032
|
]);
|
|
38594
38033
|
const typedResults = strategyResults ?? {};
|
|
38595
38034
|
const symbolResult = typedResults?.[symbol];
|
|
@@ -38805,9 +38244,9 @@ var init_runtimeParity2 = __esm({
|
|
|
38805
38244
|
start: window.start,
|
|
38806
38245
|
end: window.end
|
|
38807
38246
|
},
|
|
38808
|
-
name: `${target.symbol}_${target.strategy}_${(0,
|
|
38809
|
-
testId: (0,
|
|
38810
|
-
testSuiteId: (0,
|
|
38247
|
+
name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto17.randomUUID)().slice(0, 8)}`,
|
|
38248
|
+
testId: (0, import_node_crypto17.randomUUID)().slice(0, 8),
|
|
38249
|
+
testSuiteId: (0, import_node_crypto17.randomUUID)().slice(0, 8),
|
|
38811
38250
|
strategyName: target.strategy,
|
|
38812
38251
|
strategyConfig: replayConfig,
|
|
38813
38252
|
connectorName,
|
|
@@ -38956,16 +38395,16 @@ var init_runtimeParity2 = __esm({
|
|
|
38956
38395
|
(0, import_backtest7.resetTestingKlineCache)(projectRoot16);
|
|
38957
38396
|
}
|
|
38958
38397
|
};
|
|
38959
|
-
|
|
38398
|
+
main46 = runtimeParity;
|
|
38960
38399
|
}
|
|
38961
38400
|
});
|
|
38962
38401
|
|
|
38963
38402
|
// src/lib/signals/runtimeStrategies.ts
|
|
38964
|
-
var
|
|
38403
|
+
var import_runtimeStrategies6;
|
|
38965
38404
|
var init_runtimeStrategies = __esm({
|
|
38966
38405
|
"src/lib/signals/runtimeStrategies.ts"() {
|
|
38967
38406
|
"use strict";
|
|
38968
|
-
|
|
38407
|
+
import_runtimeStrategies6 = require("@tradejs/node/runtimeStrategies");
|
|
38969
38408
|
}
|
|
38970
38409
|
});
|
|
38971
38410
|
|
|
@@ -39025,11 +38464,11 @@ var init_skipStats = __esm({
|
|
|
39025
38464
|
});
|
|
39026
38465
|
|
|
39027
38466
|
// src/lib/signals/evaluations.ts
|
|
39028
|
-
var
|
|
38467
|
+
var import_redis22, runtimeLineageScopeCache, runtimeLineageScopeCacheDayKey, runtimeLineageScopeCacheLoaded, buildRuntimeSignalEvaluationId, buildLineageField, flushRuntimeSignalEvaluations, createRuntimeSignalEvaluationBuffer;
|
|
39029
38468
|
var init_evaluations = __esm({
|
|
39030
38469
|
"src/lib/signals/evaluations.ts"() {
|
|
39031
38470
|
"use strict";
|
|
39032
|
-
|
|
38471
|
+
import_redis22 = require("@tradejs/infra/redis");
|
|
39033
38472
|
init_runtimeSignalsStorage();
|
|
39034
38473
|
init_runtimeLineage();
|
|
39035
38474
|
runtimeLineageScopeCache = /* @__PURE__ */ new Map();
|
|
@@ -39080,7 +38519,7 @@ var init_evaluations = __esm({
|
|
|
39080
38519
|
runtimeLineageScopeCacheDayKey = dayKey;
|
|
39081
38520
|
runtimeLineageScopeCacheLoaded = false;
|
|
39082
38521
|
}
|
|
39083
|
-
const lineageBucket =
|
|
38522
|
+
const lineageBucket = import_redis22.redisKeys.runtimeLineageScopeBucket(
|
|
39084
38523
|
dayEvaluations[0].userName,
|
|
39085
38524
|
dayKey
|
|
39086
38525
|
);
|
|
@@ -39088,7 +38527,7 @@ var init_evaluations = __esm({
|
|
|
39088
38527
|
(evaluation) => evaluation.runtimeLineage != null
|
|
39089
38528
|
);
|
|
39090
38529
|
if (lineageEvaluations.length > 0 && !runtimeLineageScopeCacheLoaded) {
|
|
39091
|
-
const storedScopes = await (0,
|
|
38530
|
+
const storedScopes = await (0, import_redis22.getHashJsonValues)(lineageBucket);
|
|
39092
38531
|
for (const scope of storedScopes) {
|
|
39093
38532
|
const lineageField = buildLineageField(scope);
|
|
39094
38533
|
runtimeLineageScopeCache.set(`${lineageBucket}:${lineageField}`, scope);
|
|
@@ -39133,7 +38572,7 @@ var init_evaluations = __esm({
|
|
|
39133
38572
|
lineageWrites.set(lineageField, scope);
|
|
39134
38573
|
}
|
|
39135
38574
|
if (lineageWrites.size > 0) {
|
|
39136
|
-
await (0,
|
|
38575
|
+
await (0, import_redis22.setHashJsonFields)(
|
|
39137
38576
|
lineageBucket,
|
|
39138
38577
|
[...lineageWrites].map(([field, data]) => ({ field, data })),
|
|
39139
38578
|
{
|
|
@@ -39145,7 +38584,7 @@ var init_evaluations = __esm({
|
|
|
39145
38584
|
const statsIncrements = /* @__PURE__ */ new Map();
|
|
39146
38585
|
for (const evaluation of dayEvaluations) {
|
|
39147
38586
|
if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
|
|
39148
|
-
const bucket =
|
|
38587
|
+
const bucket = import_redis22.redisKeys.runtimeSignalEvaluationBucket(
|
|
39149
38588
|
evaluation.userName,
|
|
39150
38589
|
dayKey,
|
|
39151
38590
|
evaluation.strategy
|
|
@@ -39157,7 +38596,7 @@ var init_evaluations = __esm({
|
|
|
39157
38596
|
});
|
|
39158
38597
|
detailedWrites.set(bucket, entries);
|
|
39159
38598
|
}
|
|
39160
|
-
const statsBucket =
|
|
38599
|
+
const statsBucket = import_redis22.redisKeys.runtimeSignalEvaluationStatsBucket(
|
|
39161
38600
|
evaluation.userName,
|
|
39162
38601
|
dayKey,
|
|
39163
38602
|
evaluation.strategy,
|
|
@@ -39173,12 +38612,12 @@ var init_evaluations = __esm({
|
|
|
39173
38612
|
}
|
|
39174
38613
|
await Promise.all([
|
|
39175
38614
|
...[...detailedWrites].map(
|
|
39176
|
-
([bucket, entries]) => (0,
|
|
38615
|
+
([bucket, entries]) => (0, import_redis22.setHashJsonFields)(bucket, entries, {
|
|
39177
38616
|
expire: runtimeSignalRetentionTtl
|
|
39178
38617
|
})
|
|
39179
38618
|
),
|
|
39180
38619
|
...[...statsIncrements].map(
|
|
39181
|
-
([bucket, increments]) => (0,
|
|
38620
|
+
([bucket, increments]) => (0, import_redis22.incrHashFields)(bucket, increments, {
|
|
39182
38621
|
expire: runtimeSignalRetentionTtl
|
|
39183
38622
|
})
|
|
39184
38623
|
)
|
|
@@ -39194,7 +38633,7 @@ var init_evaluations = __esm({
|
|
|
39194
38633
|
const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
|
|
39195
38634
|
const signalRefsByBucket = /* @__PURE__ */ new Map();
|
|
39196
38635
|
for (const { userName: userName3, signal } of pendingSignals) {
|
|
39197
|
-
const bucket =
|
|
38636
|
+
const bucket = import_redis22.redisKeys.runtimeSignalBucket(
|
|
39198
38637
|
userName3,
|
|
39199
38638
|
(0, import_time5.getRuntimeStorageDayKey)(signal.timestamp),
|
|
39200
38639
|
signal.strategy
|
|
@@ -39208,14 +38647,14 @@ var init_evaluations = __esm({
|
|
|
39208
38647
|
}
|
|
39209
38648
|
await Promise.all([
|
|
39210
38649
|
...pendingSignals.map(
|
|
39211
|
-
({ signal }) => (0,
|
|
39212
|
-
|
|
38650
|
+
({ signal }) => (0, import_redis22.setData)(
|
|
38651
|
+
import_redis22.redisKeys.storeSignal(signal.symbol, signal.signalId),
|
|
39213
38652
|
toStoredRuntimeSignal(signal),
|
|
39214
38653
|
{ expire: runtimeSignalRetentionTtl }
|
|
39215
38654
|
)
|
|
39216
38655
|
),
|
|
39217
38656
|
...[...signalRefsByBucket].map(
|
|
39218
|
-
([bucket, entries]) => (0,
|
|
38657
|
+
([bucket, entries]) => (0, import_redis22.setHashJsonFields)(bucket, entries, {
|
|
39219
38658
|
expire: runtimeSignalRetentionTtl
|
|
39220
38659
|
})
|
|
39221
38660
|
)
|
|
@@ -40016,7 +39455,7 @@ var init_configuredScopes = __esm({
|
|
|
40016
39455
|
});
|
|
40017
39456
|
|
|
40018
39457
|
// src/lib/signals/runner.ts
|
|
40019
|
-
var import_progress12, import_chalk54, import_connectors17, import_cli13, import_async5, import_strategies14, import_constants20, import_time14, import_logger11, import_runtimeDeploymentEvents, import_runtimeHeartbeats,
|
|
39458
|
+
var import_progress12, import_chalk54, import_connectors17, import_cli13, import_async5, import_strategies14, import_constants20, import_time14, import_logger11, import_runtimeDeploymentEvents, import_runtimeHeartbeats, import_runtimeStrategies7, SLOW_SIGNALS_WARNING_MS, formatDuration3, resolvePositiveInteger2, resolveNonNegativeInteger, createSignalsRunner;
|
|
40020
39459
|
var init_runner = __esm({
|
|
40021
39460
|
"src/lib/signals/runner.ts"() {
|
|
40022
39461
|
"use strict";
|
|
@@ -40031,7 +39470,7 @@ var init_runner = __esm({
|
|
|
40031
39470
|
import_logger11 = require("@tradejs/infra/logger");
|
|
40032
39471
|
import_runtimeDeploymentEvents = require("@tradejs/infra/runtimeDeploymentEvents");
|
|
40033
39472
|
import_runtimeHeartbeats = require("@tradejs/infra/runtimeHeartbeats");
|
|
40034
|
-
|
|
39473
|
+
import_runtimeStrategies7 = require("@tradejs/node/runtimeStrategies");
|
|
40035
39474
|
init_windows();
|
|
40036
39475
|
init_runtimeRedis();
|
|
40037
39476
|
init_runFormatting();
|
|
@@ -40122,7 +39561,7 @@ var init_runner = __esm({
|
|
|
40122
39561
|
return connectorName;
|
|
40123
39562
|
};
|
|
40124
39563
|
const createSignalsSession2 = async (lifecycle, scope = {}) => {
|
|
40125
|
-
const deployment = config2.deploymentId ? await (0,
|
|
39564
|
+
const deployment = config2.deploymentId ? await (0, import_runtimeStrategies7.getRuntimeDeployment)({
|
|
40126
39565
|
userName: config2.userName,
|
|
40127
39566
|
projectRoot: projectRoot18,
|
|
40128
39567
|
deploymentId: config2.deploymentId
|
|
@@ -40372,7 +39811,7 @@ var init_runner = __esm({
|
|
|
40372
39811
|
const primaryEthByTimestamp = new Map(
|
|
40373
39812
|
primaryEthClosedData.map((candle) => [candle.timestamp, candle])
|
|
40374
39813
|
);
|
|
40375
|
-
const configuredRuntimeStrategies = await (0,
|
|
39814
|
+
const configuredRuntimeStrategies = await (0, import_runtimeStrategies6.loadResolvedRuntimeStrategies)({
|
|
40376
39815
|
userName: config2.userName,
|
|
40377
39816
|
projectRoot: projectRoot18,
|
|
40378
39817
|
deploymentId: deployment?.id ?? "",
|
|
@@ -40613,7 +40052,7 @@ var init_runner = __esm({
|
|
|
40613
40052
|
}
|
|
40614
40053
|
};
|
|
40615
40054
|
const loadConfiguredSignalsScopes = async (deployment) => {
|
|
40616
|
-
const configuredStrategies = await (0,
|
|
40055
|
+
const configuredStrategies = await (0, import_runtimeStrategies6.loadResolvedRuntimeStrategies)({
|
|
40617
40056
|
userName: config2.userName,
|
|
40618
40057
|
projectRoot: projectRoot18,
|
|
40619
40058
|
deploymentId: deployment.id
|
|
@@ -40639,7 +40078,7 @@ var init_runner = __esm({
|
|
|
40639
40078
|
if (!config2.deploymentId) {
|
|
40640
40079
|
throw new Error("Runtime deployment id is required");
|
|
40641
40080
|
}
|
|
40642
|
-
const configuredDeployment = await (0,
|
|
40081
|
+
const configuredDeployment = await (0, import_runtimeStrategies7.getRuntimeDeployment)({
|
|
40643
40082
|
userName: config2.userName,
|
|
40644
40083
|
projectRoot: projectRoot18,
|
|
40645
40084
|
deploymentId: config2.deploymentId
|
|
@@ -40673,7 +40112,7 @@ var init_runner = __esm({
|
|
|
40673
40112
|
throw new Error("Runtime deployment id is required");
|
|
40674
40113
|
}
|
|
40675
40114
|
const deploymentId = config2.deploymentId;
|
|
40676
|
-
const initialDeployment = await (0,
|
|
40115
|
+
const initialDeployment = await (0, import_runtimeStrategies7.getRuntimeDeployment)({
|
|
40677
40116
|
userName: config2.userName,
|
|
40678
40117
|
projectRoot: projectRoot18,
|
|
40679
40118
|
deploymentId
|
|
@@ -40698,7 +40137,7 @@ var init_runner = __esm({
|
|
|
40698
40137
|
settleDelayMs: resolveNonNegativeInteger(config2.settleDelayMs, 5e3),
|
|
40699
40138
|
signal: abortController.signal,
|
|
40700
40139
|
runCycle: async () => {
|
|
40701
|
-
const currentDeployment = await (0,
|
|
40140
|
+
const currentDeployment = await (0, import_runtimeStrategies7.getRuntimeDeployment)({
|
|
40702
40141
|
userName: config2.userName,
|
|
40703
40142
|
projectRoot: projectRoot18,
|
|
40704
40143
|
deploymentId
|
|
@@ -40823,12 +40262,12 @@ var init_runner = __esm({
|
|
|
40823
40262
|
var signals_exports = {};
|
|
40824
40263
|
__export(signals_exports, {
|
|
40825
40264
|
createSignalsSession: () => createSignalsSession,
|
|
40826
|
-
main: () =>
|
|
40265
|
+
main: () => main47,
|
|
40827
40266
|
signals: () => signals,
|
|
40828
40267
|
signalsConfiguredScopesOnce: () => signalsConfiguredScopesOnce,
|
|
40829
40268
|
signalsDaemon: () => signalsDaemon
|
|
40830
40269
|
});
|
|
40831
|
-
var import_config12, import_args36, flags32, config, runner, createSignalsSession, signals, signalsConfiguredScopesOnce, signalsDaemon,
|
|
40270
|
+
var import_config12, import_args36, flags32, config, runner, createSignalsSession, signals, signalsConfiguredScopesOnce, signalsDaemon, main47;
|
|
40832
40271
|
var init_signals = __esm({
|
|
40833
40272
|
"src/scripts/signals.ts"() {
|
|
40834
40273
|
"use strict";
|
|
@@ -40900,31 +40339,31 @@ var init_signals = __esm({
|
|
|
40900
40339
|
signals = runner.runCycle;
|
|
40901
40340
|
signalsConfiguredScopesOnce = runner.runConfiguredScopesOnce;
|
|
40902
40341
|
signalsDaemon = runner.runDaemon;
|
|
40903
|
-
|
|
40342
|
+
main47 = () => config.watch ? signalsDaemon() : signalsConfiguredScopesOnce();
|
|
40904
40343
|
}
|
|
40905
40344
|
});
|
|
40906
40345
|
|
|
40907
40346
|
// src/scripts/signalsDaemon.ts
|
|
40908
40347
|
var signalsDaemon_exports = {};
|
|
40909
40348
|
__export(signalsDaemon_exports, {
|
|
40910
|
-
main: () =>
|
|
40349
|
+
main: () => main48
|
|
40911
40350
|
});
|
|
40912
|
-
var
|
|
40351
|
+
var main48;
|
|
40913
40352
|
var init_signalsDaemon = __esm({
|
|
40914
40353
|
"src/scripts/signalsDaemon.ts"() {
|
|
40915
40354
|
"use strict";
|
|
40916
40355
|
init_signals();
|
|
40917
|
-
|
|
40356
|
+
main48 = signalsDaemon;
|
|
40918
40357
|
}
|
|
40919
40358
|
});
|
|
40920
40359
|
|
|
40921
40360
|
// src/scripts/signalsSummary.ts
|
|
40922
40361
|
var signalsSummary_exports = {};
|
|
40923
40362
|
__export(signalsSummary_exports, {
|
|
40924
|
-
main: () =>
|
|
40363
|
+
main: () => main49,
|
|
40925
40364
|
signalsSummary: () => signalsSummary
|
|
40926
40365
|
});
|
|
40927
|
-
var import_config13, import_args37, import_logger12, import_connectors18,
|
|
40366
|
+
var import_config13, import_args37, import_logger12, import_connectors18, import_runtimeStrategies9, flags33, projectRoot17, SUMMARY_TIMEZONE2, SUMMARY_TIMEZONE_LABEL2, escapeHtml8, formatMskDateTime4, formatSigned3, formatPnlMoneyText, formatWinRateText, resolveSummaryTitle, normalizeStatus, shouldAttachDebugReport, getSummaryDateParts, formatSummaryIsoDayKey, unescapeHtml, stripTelegramHtml, buildSignalsSummaryAttachment, appendReportAttachmentSummary, resolveSummaryConnectorName, groupRuntimeTradesByConnectorScope, syncRuntimeTradeScopes, createRuntimeSignalStats, mergeRuntimeSignalStats, buildSummaryPrelude, resolveTradeStatusEmoji, isTimestampInWindow, isRuntimeTradeClosedInWindow, buildSummaryMessages, signalsSummary, main49;
|
|
40928
40367
|
var init_signalsSummary = __esm({
|
|
40929
40368
|
"src/scripts/signalsSummary.ts"() {
|
|
40930
40369
|
"use strict";
|
|
@@ -40938,7 +40377,7 @@ var init_signalsSummary = __esm({
|
|
|
40938
40377
|
init_runtimeSignalsLoader();
|
|
40939
40378
|
init_runtimeSignalsStorage();
|
|
40940
40379
|
init_runtimeDebugEvidence();
|
|
40941
|
-
|
|
40380
|
+
import_runtimeStrategies9 = require("@tradejs/node/runtimeStrategies");
|
|
40942
40381
|
import_args37.default.option(["u", "user"], "Use user config", "root");
|
|
40943
40382
|
import_args37.default.option(
|
|
40944
40383
|
"connector",
|
|
@@ -41482,7 +40921,7 @@ none`
|
|
|
41482
40921
|
loadRuntimeSignals(flags33.user, { startTime, endTime }),
|
|
41483
40922
|
loadRuntimeSignalEvaluationStatsBuckets(flags33.user),
|
|
41484
40923
|
loadRuntimeTrades(flags33.user),
|
|
41485
|
-
(0,
|
|
40924
|
+
(0, import_runtimeStrategies9.listRuntimeDeployments)({ userName: flags33.user, projectRoot: projectRoot17 })
|
|
41486
40925
|
]);
|
|
41487
40926
|
const {
|
|
41488
40927
|
trades: syncedTrades,
|
|
@@ -41612,16 +41051,16 @@ none`
|
|
|
41612
41051
|
});
|
|
41613
41052
|
}
|
|
41614
41053
|
};
|
|
41615
|
-
|
|
41054
|
+
main49 = signalsSummary;
|
|
41616
41055
|
}
|
|
41617
41056
|
});
|
|
41618
41057
|
|
|
41619
41058
|
// src/scripts/test-ml.ts
|
|
41620
41059
|
var test_ml_exports = {};
|
|
41621
41060
|
__export(test_ml_exports, {
|
|
41622
|
-
main: () =>
|
|
41061
|
+
main: () => main50
|
|
41623
41062
|
});
|
|
41624
|
-
var import_config14, import_constants21, import_ml3, import_registry5, now, INTERVAL_MIN, CANDLES, makeSeries, makeCandles, buildTrendline,
|
|
41063
|
+
var import_config14, import_constants21, import_ml3, import_registry5, now, INTERVAL_MIN, CANDLES, makeSeries, makeCandles, buildTrendline, main50;
|
|
41625
41064
|
var init_test_ml = __esm({
|
|
41626
41065
|
"src/scripts/test-ml.ts"() {
|
|
41627
41066
|
"use strict";
|
|
@@ -41671,7 +41110,7 @@ var init_test_ml = __esm({
|
|
|
41671
41110
|
{ timestamp: entryTs - 2 * INTERVAL_MIN * 6e4, value: price * 0.995 }
|
|
41672
41111
|
]
|
|
41673
41112
|
});
|
|
41674
|
-
|
|
41113
|
+
main50 = async () => {
|
|
41675
41114
|
const defaultConfig = await (0, import_registry5.getStrategyDefaults)("TrendLine", process.cwd());
|
|
41676
41115
|
if (!defaultConfig) {
|
|
41677
41116
|
throw new Error(
|
|
@@ -41764,9 +41203,9 @@ var init_test_ml = __esm({
|
|
|
41764
41203
|
// src/scripts/test.ts
|
|
41765
41204
|
var test_exports = {};
|
|
41766
41205
|
__export(test_exports, {
|
|
41767
|
-
main: () =>
|
|
41206
|
+
main: () => main51
|
|
41768
41207
|
});
|
|
41769
|
-
var import_config15, import_connectors19, getPositions,
|
|
41208
|
+
var import_config15, import_connectors19, getPositions, main51;
|
|
41770
41209
|
var init_test = __esm({
|
|
41771
41210
|
"src/scripts/test.ts"() {
|
|
41772
41211
|
"use strict";
|
|
@@ -41776,7 +41215,7 @@ var init_test = __esm({
|
|
|
41776
41215
|
const res = await connector.getPositions();
|
|
41777
41216
|
console.log("res", res);
|
|
41778
41217
|
};
|
|
41779
|
-
|
|
41218
|
+
main51 = async () => {
|
|
41780
41219
|
const byBitConnector = await import_connectors19.connectors.ByBit({
|
|
41781
41220
|
userName: "root"
|
|
41782
41221
|
});
|
|
@@ -41788,21 +41227,21 @@ var init_test = __esm({
|
|
|
41788
41227
|
// src/scripts/user-add.ts
|
|
41789
41228
|
var user_add_exports = {};
|
|
41790
41229
|
__export(user_add_exports, {
|
|
41791
|
-
main: () =>
|
|
41230
|
+
main: () => main52
|
|
41792
41231
|
});
|
|
41793
|
-
var import_args38, import_chalk55, import_bcryptjs,
|
|
41232
|
+
var import_args38, import_chalk55, import_bcryptjs, import_redis23, flags34, main52;
|
|
41794
41233
|
var init_user_add = __esm({
|
|
41795
41234
|
"src/scripts/user-add.ts"() {
|
|
41796
41235
|
"use strict";
|
|
41797
41236
|
import_args38 = __toESM(require("args"));
|
|
41798
41237
|
import_chalk55 = __toESM(require("chalk"));
|
|
41799
41238
|
import_bcryptjs = __toESM(require("bcryptjs"));
|
|
41800
|
-
|
|
41239
|
+
import_redis23 = require("@tradejs/infra/redis");
|
|
41801
41240
|
import_args38.default.example("yarn user-add -u myname -p 123456", "Create or update user");
|
|
41802
41241
|
import_args38.default.option(["u", "user"], "Username", "");
|
|
41803
41242
|
import_args38.default.option(["p", "password"], "Password (plain text)", "");
|
|
41804
41243
|
flags34 = import_args38.default.parse(process.argv);
|
|
41805
|
-
|
|
41244
|
+
main52 = async () => {
|
|
41806
41245
|
const userName3 = String(flags34.user || "").trim();
|
|
41807
41246
|
const password = String(flags34.password || "");
|
|
41808
41247
|
if (!userName3 || !password) {
|
|
@@ -41810,14 +41249,14 @@ var init_user_add = __esm({
|
|
|
41810
41249
|
process.exit(1);
|
|
41811
41250
|
}
|
|
41812
41251
|
const passwordHash = await import_bcryptjs.default.hash(password, 10);
|
|
41813
|
-
const existing = await (0,
|
|
41252
|
+
const existing = await (0, import_redis23.getData)(import_redis23.redisKeys.user(userName3), null);
|
|
41814
41253
|
const next = {
|
|
41815
41254
|
...existing ?? {},
|
|
41816
41255
|
passwordHash,
|
|
41817
41256
|
userName: userName3,
|
|
41818
41257
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
41819
41258
|
};
|
|
41820
|
-
await (0,
|
|
41259
|
+
await (0, import_redis23.setData)(import_redis23.redisKeys.user(userName3), next, {
|
|
41821
41260
|
expire: 0
|
|
41822
41261
|
});
|
|
41823
41262
|
console.log(import_chalk55.default.green(`User ${userName3} updated`));
|
|
@@ -41830,13 +41269,13 @@ var init_user_add = __esm({
|
|
|
41830
41269
|
var cli_exports = {};
|
|
41831
41270
|
__export(cli_exports, {
|
|
41832
41271
|
cleanupCliResources: () => cleanupCliResources,
|
|
41833
|
-
main: () =>
|
|
41272
|
+
main: () => main53,
|
|
41834
41273
|
printUsage: () => printUsage3,
|
|
41835
41274
|
runLoadedModule: () => runLoadedModule
|
|
41836
41275
|
});
|
|
41837
41276
|
module.exports = __toCommonJS(cli_exports);
|
|
41838
41277
|
var import_config16 = require("dotenv/config");
|
|
41839
|
-
var
|
|
41278
|
+
var import_redis24 = require("@tradejs/infra/redis");
|
|
41840
41279
|
var import_client9 = require("@tradejs/infra/timescale/client");
|
|
41841
41280
|
var scriptLoaders = {
|
|
41842
41281
|
"agent-run": () => Promise.resolve().then(() => (init_agentRun(), agentRun_exports)),
|
|
@@ -41864,6 +41303,7 @@ var scriptLoaders = {
|
|
|
41864
41303
|
"maintenance:cleanup-market-context": () => Promise.resolve().then(() => (init_cleanupMarketContext(), cleanupMarketContext_exports)),
|
|
41865
41304
|
migration: () => Promise.resolve().then(() => (init_migration(), migration_exports)),
|
|
41866
41305
|
"market-ws": () => Promise.resolve().then(() => (init_marketWs(), marketWs_exports)),
|
|
41306
|
+
"mcp-worker": () => Promise.resolve().then(() => (init_mcpWorker(), mcpWorker_exports)),
|
|
41867
41307
|
"hyperliquid:whale-backfill": () => Promise.resolve().then(() => (init_hyperliquidWhaleBackfill2(), hyperliquidWhaleBackfill_exports)),
|
|
41868
41308
|
"hyperliquid:whale-ingest": () => Promise.resolve().then(() => (init_hyperliquidWhaleIngest(), hyperliquidWhaleIngest_exports)),
|
|
41869
41309
|
"hyperliquid:whales:update": () => Promise.resolve().then(() => (init_hyperliquidWhalesUpdate(), hyperliquidWhalesUpdate_exports)),
|
|
@@ -41906,9 +41346,9 @@ var runLoadedModule = async (loaded) => {
|
|
|
41906
41346
|
}
|
|
41907
41347
|
};
|
|
41908
41348
|
var cleanupCliResources = async () => {
|
|
41909
|
-
await Promise.allSettled([(0,
|
|
41349
|
+
await Promise.allSettled([(0, import_redis24.closeRedisConnection)(), (0, import_client9.closeTimescalePool)()]);
|
|
41910
41350
|
};
|
|
41911
|
-
var
|
|
41351
|
+
var main53 = async () => {
|
|
41912
41352
|
const [, scriptPath, command = "", ...args39] = process.argv;
|
|
41913
41353
|
const loader = scriptLoaders[command];
|
|
41914
41354
|
if (!loader) {
|
|
@@ -41939,7 +41379,7 @@ var main52 = async () => {
|
|
|
41939
41379
|
}
|
|
41940
41380
|
};
|
|
41941
41381
|
if (require.main === module) {
|
|
41942
|
-
|
|
41382
|
+
main53().catch((error) => {
|
|
41943
41383
|
console.error(error);
|
|
41944
41384
|
process.exit(1);
|
|
41945
41385
|
});
|