@tradejs/cli 3.1.15-beta.228 → 3.1.15

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
@@ -25611,7 +25611,7 @@ var init_runtimeLineage = __esm({
25611
25611
  });
25612
25612
 
25613
25613
  // src/lib/runtimeEvidenceDeployment.ts
25614
- var import_runtimeStrategies3, isRecord, isNonEmptyString, isPackageVersionMap, INTERVALS, UNIVERSES, isRuntimeStrategySelection, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
25614
+ var import_runtimeStrategies3, isRecord, isNonEmptyString, isPackageVersionMap, INTERVALS, UNIVERSES, isRuntimeStrategySelection, samePackageVersions, lineageMatchesStrategySnapshot, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, resolveRuntimeEvidenceTickerUniverse, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
25615
25615
  var init_runtimeEvidenceDeployment = __esm({
25616
25616
  "src/lib/runtimeEvidenceDeployment.ts"() {
25617
25617
  "use strict";
@@ -25638,6 +25638,24 @@ var init_runtimeEvidenceDeployment = __esm({
25638
25638
  ]);
25639
25639
  UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
25640
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
+ );
25641
25659
  parseRuntimeEvidenceDeploymentSnapshot = (value) => {
25642
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)) {
25643
25661
  throw new Error(
@@ -25677,6 +25695,54 @@ var init_runtimeEvidenceDeployment = __esm({
25677
25695
  };
25678
25696
  };
25679
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
+ };
25680
25746
  runtimeDeploymentFromEvidence = (deployment) => ({
25681
25747
  id: deployment.id,
25682
25748
  deploymentCompositionId: deployment.deploymentCompositionId,
@@ -25853,18 +25919,18 @@ var init_runtimeEvidence = __esm({
25853
25919
  runtimeEvidence = async () => {
25854
25920
  const { startTime, endTime, source } = resolveWindow2();
25855
25921
  const deploymentId = String(flags25.deployment);
25856
- const deployment = await resolveRuntimeEvidenceDeploymentSnapshot({
25922
+ const deploymentSnapshot = await resolveRuntimeEvidenceDeploymentSnapshot({
25857
25923
  userName: String(flags25.user),
25858
25924
  projectRoot: projectRoot9,
25859
25925
  deploymentId
25860
25926
  });
25861
- const activeStrategies = activeRuntimeEvidenceStrategies(deployment).map(
25862
- ({ strategyName }) => strategyName
25863
- );
25927
+ const activeStrategies = activeRuntimeEvidenceStrategies(
25928
+ deploymentSnapshot
25929
+ ).map(({ strategyName }) => strategyName);
25864
25930
  const requestedStrategies = parseStrategyFilter2(flags25.strategy);
25865
25931
  const strategies = requestedStrategies.length ? requestedStrategies : activeStrategies;
25866
25932
  const declaredStrategies = new Set(
25867
- deployment.strategies.map(({ strategyName }) => strategyName)
25933
+ deploymentSnapshot.strategies.map(({ strategyName }) => strategyName)
25868
25934
  );
25869
25935
  const unknownStrategies = strategies.filter(
25870
25936
  (strategyName) => !declaredStrategies.has(strategyName)
@@ -25892,6 +25958,10 @@ var init_runtimeEvidence = __esm({
25892
25958
  evaluationStatsBuckets: evidence.evaluationStatsBuckets,
25893
25959
  lineageScopes: evidence.lineageScopes
25894
25960
  });
25961
+ const deployment = resolveRuntimeEvidenceTickerUniverse({
25962
+ deployment: deploymentSnapshot,
25963
+ lineageScopes: evidence.lineageScopes
25964
+ });
25895
25965
  const artifact = {
25896
25966
  reportType: "runtime-evidence",
25897
25967
  generatedAt: Date.now(),
@@ -25949,7 +26019,7 @@ var init_runtimeEvidence = __esm({
25949
26019
  });
25950
26020
 
25951
26021
  // src/lib/runtimeEvidenceSync.ts
25952
- var import_node_child_process7, import_promises25, import_node_path19, import_node_util, execFileAsync, isExistingDestinationError2, safeSegment2, withTrailingSlash, dateParts2, buildRuntimeEvidenceRsyncArgs, receiptPath, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
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;
25953
26023
  var init_runtimeEvidenceSync = __esm({
25954
26024
  "src/lib/runtimeEvidenceSync.ts"() {
25955
26025
  "use strict";
@@ -25958,6 +26028,7 @@ var init_runtimeEvidenceSync = __esm({
25958
26028
  import_node_path19 = __toESM(require("path"));
25959
26029
  import_node_util = require("util");
25960
26030
  init_runtimeEvidenceArtifacts();
26031
+ init_runtimeEvidenceDeployment();
25961
26032
  execFileAsync = (0, import_node_util.promisify)(import_node_child_process7.execFile);
25962
26033
  isExistingDestinationError2 = (error) => {
25963
26034
  const code = error.code;
@@ -25989,7 +26060,26 @@ var init_runtimeEvidenceSync = __esm({
25989
26060
  withTrailingSlash(destination)
25990
26061
  ];
25991
26062
  receiptPath = (receiptsRoot, artifactId) => import_node_path19.default.join(receiptsRoot, `${safeSegment2(artifactId, "artifact")}.json`);
25992
- listPendingRuntimeEvidenceBundles = async ({
26063
+ 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 ({
25993
26083
  evidenceRoot,
25994
26084
  deploymentId
25995
26085
  }) => {
@@ -25998,19 +26088,29 @@ var init_runtimeEvidenceSync = __esm({
25998
26088
  const receiptsRoot = import_node_path19.default.join(evidenceRoot, "receipts", safeDeploymentId);
25999
26089
  const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
26000
26090
  const pending = [];
26091
+ const unsupported = [];
26001
26092
  for (const bundleDir of bundles) {
26002
26093
  const verified = await verifyRuntimeEvidenceBundle(bundleDir);
26003
26094
  if (verified.manifest.deploymentId !== safeDeploymentId) continue;
26004
26095
  try {
26005
26096
  await import_promises25.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
26097
+ continue;
26006
26098
  } catch (error) {
26007
26099
  if (error.code !== "ENOENT") throw error;
26100
+ }
26101
+ const support = inspectRuntimeEvidenceBundleSupport(verified);
26102
+ if (support.supported) {
26008
26103
  pending.push(verified);
26104
+ } else {
26105
+ unsupported.push({ bundle: verified, reason: support.reason });
26009
26106
  }
26010
26107
  }
26011
- return pending.sort(
26012
- (left, right) => left.manifest.window.startTime - right.manifest.window.startTime || left.manifest.createdAt - right.manifest.createdAt
26013
- );
26108
+ return {
26109
+ pending: pending.sort(compareBundles),
26110
+ unsupported: unsupported.sort(
26111
+ (left, right) => compareBundles(left.bundle, right.bundle)
26112
+ )
26113
+ };
26014
26114
  };
26015
26115
  markRuntimeEvidenceBundleProcessed = async ({
26016
26116
  evidenceRoot,
@@ -26097,15 +26197,16 @@ var init_runtimeEvidenceSync = __esm({
26097
26197
  }
26098
26198
  received.push(await verifyRuntimeEvidenceBundle(destinationDir));
26099
26199
  }
26200
+ const statuses = await listRuntimeEvidenceBundleStatuses({
26201
+ evidenceRoot,
26202
+ deploymentId: safeDeploymentId
26203
+ });
26100
26204
  return {
26101
26205
  rsyncArgs,
26102
26206
  stdout: String(transfer.stdout ?? ""),
26103
26207
  stderr: String(transfer.stderr ?? ""),
26104
26208
  received,
26105
- pending: await listPendingRuntimeEvidenceBundles({
26106
- evidenceRoot,
26107
- deploymentId: safeDeploymentId
26108
- })
26209
+ ...statuses
26109
26210
  };
26110
26211
  };
26111
26212
  }
@@ -26157,7 +26258,7 @@ var init_runtimeEvidenceSync2 = __esm({
26157
26258
  });
26158
26259
  console.log(
26159
26260
  import_chalk40.default.green(
26160
- `Runtime evidence sync completed: received=${result.received.length} pending=${result.pending.length}`
26261
+ `Runtime evidence sync completed: received=${result.received.length} pending=${result.pending.length} unsupported=${result.unsupported.length}`
26161
26262
  )
26162
26263
  );
26163
26264
  console.log(
@@ -26174,6 +26275,13 @@ var init_runtimeEvidenceSync2 = __esm({
26174
26275
  bundleDir: bundle.bundleDir,
26175
26276
  payloadPath: bundle.payloadPath,
26176
26277
  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
26177
26285
  }))
26178
26286
  },
26179
26287
  null,
@@ -26186,7 +26294,7 @@ var init_runtimeEvidenceSync2 = __esm({
26186
26294
  });
26187
26295
 
26188
26296
  // src/lib/runtimeScorecard.ts
26189
- var asRecord6, asArray3, finiteNumber5, finiteString2, packageVersionMap, round, unwrapRows, runtimePayload, runtimeWindow, extractRuntimeRows, buildRuntimeLineageSummary, belongsToRuntimeLineage, runtimeDeploymentBinding, belongsToRuntimeDeployment, belongsToStrategy, filterArtifactByStrategy, countBy2, buildDistributions, buildDistributionDelta, sum2, statsCount, tradeTimestamp, dedupeTrades, maxDrawdown, buildRollingPerformance, getReplayComparison, replayCountsForStrategy, getCalibrationSummary, getProspectiveSummary, buildRuntimeScorecard, formatRuntimeScorecardMarkdown;
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;
26190
26298
  var init_runtimeScorecard = __esm({
26191
26299
  "src/lib/runtimeScorecard.ts"() {
26192
26300
  "use strict";
@@ -26297,6 +26405,138 @@ var init_runtimeScorecard = __esm({
26297
26405
  maxLossValue: finiteNumber5(identity?.maxLossValue)
26298
26406
  };
26299
26407
  };
26408
+ buildEmbeddedLineageScope = ({
26409
+ artifact,
26410
+ rows,
26411
+ strategy
26412
+ }) => {
26413
+ const deployment = asRecord6(asRecord6(artifact)?.deployment);
26414
+ if (finiteNumber5(deployment?.schemaVersion) !== 2) return null;
26415
+ const deploymentId = finiteString2(deployment?.id);
26416
+ const accountId = finiteString2(deployment?.accountId);
26417
+ const deploymentCompositionId = finiteString2(
26418
+ deployment?.deploymentCompositionId
26419
+ );
26420
+ if (!deploymentId || !accountId || !deploymentCompositionId) return null;
26421
+ const snapshots = asArray3(deployment?.strategies).map(asRecord6).filter((item) => item != null).filter((item) => item.enabled === true).filter(
26422
+ (item) => !strategy || finiteString2(item.strategyName) === strategy
26423
+ );
26424
+ const targetSeeds = snapshots.map((snapshot) => {
26425
+ const strategyName = finiteString2(snapshot.strategyName);
26426
+ const strategyRevision = finiteString2(snapshot.strategyRevision);
26427
+ const strategyPackageVersion = finiteString2(
26428
+ snapshot.strategyPackageVersion
26429
+ );
26430
+ const strategyDependencyVersions = packageVersionMap(
26431
+ snapshot.strategyDependencyVersions
26432
+ );
26433
+ const runtimePackageVersion = finiteString2(
26434
+ snapshot.runtimePackageVersion
26435
+ );
26436
+ return strategyName && strategyRevision && strategyPackageVersion && strategyDependencyVersions && runtimePackageVersion ? {
26437
+ strategyName,
26438
+ strategyRevision,
26439
+ deploymentCompositionId,
26440
+ strategyPackageVersion,
26441
+ strategyDependencyVersions,
26442
+ runtimePackageVersion
26443
+ } : null;
26444
+ }).filter((item) => item != null);
26445
+ if (targetSeeds.length !== snapshots.length || targetSeeds.length === 0) {
26446
+ return null;
26447
+ }
26448
+ const lineageRows = [
26449
+ ...rows.evaluations,
26450
+ ...rows.signals,
26451
+ ...rows.trades,
26452
+ ...rows.lineageScopes.map((scope) => ({
26453
+ strategy: scope.strategy,
26454
+ deploymentId: scope.deploymentId,
26455
+ accountId: scope.accountId,
26456
+ runtimeLineage: scope.lineage
26457
+ }))
26458
+ ];
26459
+ const identityMatches = (lineage, target) => finiteNumber5(lineage?.schemaVersion) === 3 && finiteString2(lineage?.strategyRevision) === target.strategyRevision && finiteString2(lineage?.deploymentCompositionId) === target.deploymentCompositionId && finiteString2(lineage?.strategyPackageVersion) === target.strategyPackageVersion && JSON.stringify(packageVersionMap(lineage?.strategyDependencyVersions)) === JSON.stringify(target.strategyDependencyVersions) && finiteString2(lineage?.runtimePackageVersion) === target.runtimePackageVersion;
26460
+ const targets = /* @__PURE__ */ new Map();
26461
+ for (const seed of targetSeeds) {
26462
+ const matchingRows = lineageRows.filter(
26463
+ (row) => finiteString2(row.strategy) === seed.strategyName && finiteString2(row.deploymentId) === deploymentId && finiteString2(row.accountId) === accountId && identityMatches(asRecord6(row.runtimeLineage), seed)
26464
+ );
26465
+ const riskValues = new Set(
26466
+ matchingRows.map((row) => finiteNumber5(asRecord6(row.runtimeLineage)?.maxLossValue)).filter((value) => value != null)
26467
+ );
26468
+ targets.set(seed.strategyName, {
26469
+ ...seed,
26470
+ maxLossValue: riskValues.size === 1 ? [...riskValues][0] : null,
26471
+ rowsWithLineage: matchingRows.length,
26472
+ riskConflict: riskValues.size > 1
26473
+ });
26474
+ }
26475
+ const belongs = (row) => {
26476
+ const strategyName = finiteString2(row.strategy);
26477
+ const target = strategyName ? targets.get(strategyName) : null;
26478
+ const lineage = asRecord6(row.runtimeLineage);
26479
+ return Boolean(
26480
+ target && target.maxLossValue != null && identityMatches(lineage, target) && finiteNumber5(lineage?.maxLossValue) === target.maxLossValue
26481
+ );
26482
+ };
26483
+ const targetValues = [...targets.values()];
26484
+ const coverageComplete = targetValues.every(
26485
+ (target) => target.rowsWithLineage > 0 && target.maxLossValue != null
26486
+ );
26487
+ const commonRiskValues = new Set(
26488
+ targetValues.map((target) => target.maxLossValue).filter((value) => value != null)
26489
+ );
26490
+ const singleTarget = targetValues.length === 1 ? targetValues[0] : null;
26491
+ const singleLineage = singleTarget?.maxLossValue != null ? {
26492
+ schemaVersion: 3,
26493
+ strategyRevision: singleTarget.strategyRevision,
26494
+ deploymentCompositionId: singleTarget.deploymentCompositionId,
26495
+ strategyPackageVersion: singleTarget.strategyPackageVersion,
26496
+ strategyDependencyVersions: singleTarget.strategyDependencyVersions,
26497
+ runtimePackageVersion: singleTarget.runtimePackageVersion,
26498
+ maxLossValue: singleTarget.maxLossValue
26499
+ } : null;
26500
+ return {
26501
+ belongs,
26502
+ summary: {
26503
+ complete: coverageComplete,
26504
+ identityComplete: true,
26505
+ coverageComplete,
26506
+ conflicts: targetValues.some((target) => target.riskConflict),
26507
+ rows: lineageRows.length,
26508
+ rowsWithLineage: targetValues.reduce(
26509
+ (total, target) => total + target.rowsWithLineage,
26510
+ 0
26511
+ ),
26512
+ schemaVersion: 3,
26513
+ lineageKey: singleLineage ? runtimeLineageKey(singleLineage) : null,
26514
+ strategyRevision: singleTarget?.strategyRevision ?? null,
26515
+ deploymentCompositionId,
26516
+ strategyPackageVersion: singleTarget?.strategyPackageVersion ?? null,
26517
+ strategyDependencyVersions: singleTarget?.strategyDependencyVersions ?? null,
26518
+ runtimePackageVersion: singleTarget?.runtimePackageVersion ?? null,
26519
+ compositionId: null,
26520
+ gitSha: null,
26521
+ gitDirty: null,
26522
+ gateFingerprint: null,
26523
+ configFingerprint: null,
26524
+ contextFingerprint: null,
26525
+ maxLossValue: commonRiskValues.size === 1 ? [...commonRiskValues][0] : null,
26526
+ strategyScopes: Object.fromEntries(
26527
+ targetValues.map((target) => [
26528
+ target.strategyName,
26529
+ {
26530
+ strategyRevision: target.strategyRevision,
26531
+ rowsWithLineage: target.rowsWithLineage,
26532
+ maxLossValue: target.maxLossValue,
26533
+ complete: target.rowsWithLineage > 0 && target.maxLossValue != null
26534
+ }
26535
+ ])
26536
+ )
26537
+ }
26538
+ };
26539
+ };
26300
26540
  belongsToRuntimeLineage = (row, summary) => {
26301
26541
  if (!summary.identityComplete || !summary.lineageKey) return false;
26302
26542
  const lineage = asRecord6(row.runtimeLineage);
@@ -26522,7 +26762,12 @@ var init_runtimeScorecard = __esm({
26522
26762
  );
26523
26763
  const deploymentBinding = runtimeDeploymentBinding(runtimeArtifact);
26524
26764
  const rows = extractRuntimeRows(scopedRuntimeArtifact);
26525
- const runtimeLineage = buildRuntimeLineageSummary(rows);
26765
+ const embeddedLineageScope = buildEmbeddedLineageScope({
26766
+ artifact: runtimeArtifact,
26767
+ rows,
26768
+ strategy
26769
+ });
26770
+ const runtimeLineage = embeddedLineageScope?.summary ?? buildRuntimeLineageSummary(rows);
26526
26771
  const window = runtimeWindow(runtimeArtifact);
26527
26772
  const startTime = finiteNumber5(window.startTime) ?? generatedAt - 864e5;
26528
26773
  const endTime = finiteNumber5(window.endTime) ?? generatedAt;
@@ -26571,12 +26816,17 @@ var init_runtimeScorecard = __esm({
26571
26816
  const lineageReason = finiteString2(lineage?.reason);
26572
26817
  const calibrationRoot = asRecord6(calibrationArtifact) ?? {};
26573
26818
  const calibrationSummary = asRecord6(calibrationRoot.summary);
26574
- const calibration = strategy ? asRecord6(asRecord6(calibrationSummary?.byStrategy)?.[strategy]) : getCalibrationSummary(calibrationArtifact);
26575
- const actualSlippageBps = finiteNumber5(
26576
- asRecord6(calibration?.signalToFillAdverseBps)?.avg
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)
26577
26821
  );
26578
- const residualVsModelBps = finiteNumber5(
26579
- asRecord6(calibration?.residualVsCurrentModelBps)?.avg
26822
+ const averageSampleMetric = (field) => {
26823
+ const values = calibrationSamples.map((sample) => finiteNumber5(sample[field])).filter((value) => value != null);
26824
+ return values.length ? round(sum2(values) / values.length) : null;
26825
+ };
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
26580
26830
  );
26581
26831
  const prospective = getProspectiveSummary(prospectiveEvidenceArtifact);
26582
26832
  const historyTrades = dedupeTrades([
@@ -26584,10 +26834,13 @@ var init_runtimeScorecard = __esm({
26584
26834
  scopedRuntimeArtifact
26585
26835
  ]);
26586
26836
  const comparableHistoryTrades = historyTrades.filter(
26587
- (trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && belongsToRuntimeLineage(trade, runtimeLineage)
26837
+ (trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && (embeddedLineageScope ? embeddedLineageScope.belongs(trade) : belongsToRuntimeLineage(trade, runtimeLineage))
26588
26838
  );
26589
26839
  const comparableCurrentClosedTrades = currentClosedTrades.filter(
26590
- (trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && belongsToRuntimeLineage(trade, runtimeLineage)
26840
+ (trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && (embeddedLineageScope ? embeddedLineageScope.belongs(trade) : belongsToRuntimeLineage(trade, runtimeLineage))
26841
+ );
26842
+ const comparableFills = rows.trades.filter(
26843
+ (trade) => belongsToRuntimeDeployment(trade, deploymentBinding) && (embeddedLineageScope ? embeddedLineageScope.belongs(trade) : belongsToRuntimeLineage(trade, runtimeLineage))
26591
26844
  );
26592
26845
  const currentDistributions = buildDistributions(rows);
26593
26846
  const previousArtifact = scopedHistoryArtifacts.map((artifact) => ({ artifact, window: runtimeWindow(artifact) })).filter(({ window: candidateWindow }) => {
@@ -26701,7 +26954,8 @@ var init_runtimeScorecard = __esm({
26701
26954
  `${finiteString2(signal.orderSkipReason) ?? ""} ${finiteString2(signal.orderFailureReason) ?? ""}`
26702
26955
  )
26703
26956
  ).length,
26704
- fills: rows.trades.length,
26957
+ fills: comparableFills.length,
26958
+ nonComparableFills: rows.trades.length - comparableFills.length,
26705
26959
  closedTrades: currentClosedTrades.length,
26706
26960
  comparableClosedTrades: comparableCurrentClosedTrades.length,
26707
26961
  nonComparableClosedTrades: currentClosedTrades.length - comparableCurrentClosedTrades.length
@@ -26750,7 +27004,7 @@ var init_runtimeScorecard = __esm({
26750
27004
  lineageReason
26751
27005
  },
26752
27006
  execution: {
26753
- available: calibration != null,
27007
+ available: actualSlippageBps != null || residualVsModelBps != null,
26754
27008
  actualSignalToFillSlippageBps: actualSlippageBps,
26755
27009
  residualVsCurrentModelBps: residualVsModelBps
26756
27010
  },
@@ -33573,7 +33827,13 @@ var init_runtimeEvidenceSource = __esm({
33573
33827
  userName: String(root.userName ?? runtime.userName ?? "").trim(),
33574
33828
  startTime: asFiniteNumber(rootWindow?.startTime) ?? asFiniteNumber(runtimeWindow2?.startTime),
33575
33829
  endTime: asFiniteNumber(rootWindow?.endTime) ?? asFiniteNumber(runtimeWindow2?.endTime),
33576
- deployment: parseRuntimeEvidenceDeploymentSnapshot(root.deployment)
33830
+ deployment: resolveRuntimeEvidenceTickerUniverse({
33831
+ deployment: parseRuntimeEvidenceDeploymentSnapshot(root.deployment),
33832
+ lineageScopes: unwrapRows2(
33833
+ runtime.lineageScopes,
33834
+ "lineageScope"
33835
+ )
33836
+ })
33577
33837
  };
33578
33838
  };
33579
33839
  loadReplayRuntimeEvidenceMetadata = async (params) => {
@@ -35969,7 +36229,7 @@ var init_runtimeComparison = __esm({
35969
36229
  excludedRuntimeLineageScopes: runtimeLineageScopes.length - comparableRuntimeLineageScopes.length,
35970
36230
  excludedExchangeEntries: 0,
35971
36231
  excludedBacktestEntries: backtestEntries.length - comparableBacktestEntries.length,
35972
- reason: comparableScopeKeys.size > 0 ? null : "no_runtime_artifacts_with_matching_lineage",
36232
+ reason: comparableScopeKeys.size > 0 ? null : expectedByScope.size === 0 ? "replay_produced_no_lineage_scopes" : "no_runtime_artifacts_with_matching_lineage",
35973
36233
  replay: [...expectedByScope.entries()].map(([scope, lineage]) => {
35974
36234
  const [deploymentId, accountId, strategy, symbol] = scope.split("::");
35975
36235
  return {
@@ -23,6 +23,7 @@ __export(runtimeEvidenceDeployment_exports, {
23
23
  activeRuntimeEvidenceStrategies: () => activeRuntimeEvidenceStrategies,
24
24
  parseRuntimeEvidenceDeploymentSnapshot: () => parseRuntimeEvidenceDeploymentSnapshot,
25
25
  resolveRuntimeEvidenceDeploymentSnapshot: () => resolveRuntimeEvidenceDeploymentSnapshot,
26
+ resolveRuntimeEvidenceTickerUniverse: () => resolveRuntimeEvidenceTickerUniverse,
26
27
  runtimeDeploymentFromEvidence: () => runtimeDeploymentFromEvidence
27
28
  });
28
29
  module.exports = __toCommonJS(runtimeEvidenceDeployment_exports);
@@ -49,6 +50,24 @@ var INTERVALS = /* @__PURE__ */ new Set([
49
50
  ]);
50
51
  var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
51
52
  var isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
53
+ var samePackageVersions = (left, right) => {
54
+ if (!left || !right) return false;
55
+ const leftEntries = Object.entries(left).sort(
56
+ ([a], [b]) => a.localeCompare(b)
57
+ );
58
+ const rightEntries = Object.entries(right).sort(
59
+ ([a], [b]) => a.localeCompare(b)
60
+ );
61
+ return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
62
+ };
63
+ var lineageMatchesStrategySnapshot = ({
64
+ lineage,
65
+ deployment,
66
+ strategy
67
+ }) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
68
+ lineage.strategyDependencyVersions,
69
+ strategy.strategyDependencyVersions
70
+ );
52
71
  var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
53
72
  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)) {
54
73
  throw new Error(
@@ -88,6 +107,54 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
88
107
  };
89
108
  };
90
109
  var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
110
+ var resolveRuntimeEvidenceTickerUniverse = ({
111
+ deployment,
112
+ lineageScopes
113
+ }) => {
114
+ const declaredTickers = deployment.tickers?.filter(isNonEmptyString) ?? [];
115
+ if (declaredTickers.length > 0) {
116
+ return {
117
+ ...deployment,
118
+ tickers: [
119
+ ...new Set(declaredTickers.map((ticker) => ticker.trim()))
120
+ ].sort()
121
+ };
122
+ }
123
+ const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
124
+ if (activeStrategies.length > 0 && activeStrategies.every((strategy) => strategy.selection?.tickers?.length)) {
125
+ return {
126
+ ...deployment,
127
+ tickers: [
128
+ ...new Set(
129
+ activeStrategies.flatMap(
130
+ (strategy) => strategy.selection?.tickers ?? []
131
+ )
132
+ )
133
+ ].sort()
134
+ };
135
+ }
136
+ const strategiesByName = new Map(
137
+ activeStrategies.map((strategy) => [strategy.strategyName, strategy])
138
+ );
139
+ const tickers = /* @__PURE__ */ new Set();
140
+ for (const scope of lineageScopes) {
141
+ const strategy = strategiesByName.get(scope.strategy);
142
+ if (!strategy || scope.deploymentId !== deployment.id || scope.accountId !== deployment.accountId || !isNonEmptyString(scope.symbol) || !lineageMatchesStrategySnapshot({
143
+ lineage: scope.lineage,
144
+ deployment,
145
+ strategy
146
+ })) {
147
+ continue;
148
+ }
149
+ tickers.add(scope.symbol.trim());
150
+ }
151
+ if (tickers.size === 0) {
152
+ throw new Error(
153
+ "Runtime evidence has no immutable ticker universe for the embedded deployment composition"
154
+ );
155
+ }
156
+ return { ...deployment, tickers: [...tickers].sort() };
157
+ };
91
158
  var runtimeDeploymentFromEvidence = (deployment) => ({
92
159
  id: deployment.id,
93
160
  deploymentCompositionId: deployment.deploymentCompositionId,
@@ -169,5 +236,6 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
169
236
  activeRuntimeEvidenceStrategies,
170
237
  parseRuntimeEvidenceDeploymentSnapshot,
171
238
  resolveRuntimeEvidenceDeploymentSnapshot,
239
+ resolveRuntimeEvidenceTickerUniverse,
172
240
  runtimeDeploymentFromEvidence
173
241
  });