@tradejs/cli 3.1.16-beta.230 → 3.1.17-beta.231

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