@tradejs/cli 3.1.27-beta.248 → 3.1.27-beta.250

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 = (path41) => (Array.isArray(path41) ? path41 : path41.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
2189
- classifyAiPocketCoverageFeaturePath = (path41) => {
2190
- const segments = normalizeFeaturePath(path41);
2188
+ normalizeFeaturePath = (path42) => (Array.isArray(path42) ? path42 : path42.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
2189
+ classifyAiPocketCoverageFeaturePath = (path42) => {
2190
+ const segments = normalizeFeaturePath(path42);
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 = (path41) => {
2365
- const segments = (Array.isArray(path41) ? path41 : path41.split(".")).filter(
2364
+ classifyAiPocketFeaturePath = (path42) => {
2365
+ const segments = (Array.isArray(path42) ? path42 : path42.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 = (path41) => {
10697
- if (path41.includes("global-metrics")) return "global";
10698
- if (path41.includes("cryptocurrency/quotes")) return "reference";
10699
- if (path41.includes("exchange/quotes")) return "exchangeLiquidity";
10700
- if (path41.includes("fear-and-greed")) return "fearGreed";
10701
- if (path41.includes("cmc100")) return "cmc100";
10702
- if (path41.includes("cmc20")) return "cmc20";
10703
- return path41;
10704
- };
10705
- recordCoinMarketCapFetchStats = (stats, path41, creditCount) => {
10696
+ getCoinMarketCapPathLabel = (path42) => {
10697
+ if (path42.includes("global-metrics")) return "global";
10698
+ if (path42.includes("cryptocurrency/quotes")) return "reference";
10699
+ if (path42.includes("exchange/quotes")) return "exchangeLiquidity";
10700
+ if (path42.includes("fear-and-greed")) return "fearGreed";
10701
+ if (path42.includes("cmc100")) return "cmc100";
10702
+ if (path42.includes("cmc20")) return "cmc20";
10703
+ return path42;
10704
+ };
10705
+ recordCoinMarketCapFetchStats = (stats, path42, creditCount) => {
10706
10706
  if (!stats) return;
10707
- const existing = stats.byPath.get(path41) ?? { requests: 0, credits: 0 };
10707
+ const existing = stats.byPath.get(path42) ?? { 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(path41, existing);
10712
+ stats.byPath.set(path42, existing);
10713
10713
  };
10714
10714
  formatCoinMarketCapFetchStats = (stats) => {
10715
10715
  const byPath = [...stats.byPath.entries()].map(
10716
- ([path41, item]) => `${getCoinMarketCapPathLabel(path41)}=${item.requests}req/${item.credits}cr`
10716
+ ([path42, item]) => `${getCoinMarketCapPathLabel(path42)}=${item.requests}req/${item.credits}cr`
10717
10717
  ).join(" ");
10718
10718
  return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
10719
10719
  };
@@ -26625,12 +26625,378 @@ var init_runtimeFeedbackSync2 = __esm({
26625
26625
  }
26626
26626
  });
26627
26627
 
26628
+ // src/lib/runtimeEvidenceCompositionSnapshots.ts
26629
+ var import_node_crypto13, import_promises28, import_node_path24, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord4, sha2564, safeSegment6, isExistingDestinationError4, parseManifest3, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
26630
+ var init_runtimeEvidenceCompositionSnapshots = __esm({
26631
+ "src/lib/runtimeEvidenceCompositionSnapshots.ts"() {
26632
+ "use strict";
26633
+ import_node_crypto13 = require("crypto");
26634
+ import_promises28 = __toESM(require("fs/promises"));
26635
+ import_node_path24 = __toESM(require("path"));
26636
+ init_runtimeEvidenceDeployment();
26637
+ init_runtimeEvidenceProducer();
26638
+ SNAPSHOT_FILE = "snapshot.json";
26639
+ MANIFEST_FILE = "manifest.json";
26640
+ COMPLETE_FILE = ".complete";
26641
+ createRuntimeEvidenceCompositionSnapshotRecorder = ({
26642
+ persist,
26643
+ onError
26644
+ }) => {
26645
+ const completed = /* @__PURE__ */ new Set();
26646
+ const inFlight = /* @__PURE__ */ new Set();
26647
+ return {
26648
+ observe(compositionId) {
26649
+ if (completed.has(compositionId) || inFlight.has(compositionId)) return;
26650
+ inFlight.add(compositionId);
26651
+ void Promise.resolve().then(() => persist(compositionId)).then(() => completed.add(compositionId)).catch((error) => onError(compositionId, error)).finally(() => inFlight.delete(compositionId));
26652
+ }
26653
+ };
26654
+ };
26655
+ isRecord4 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
26656
+ sha2564 = (value) => (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex");
26657
+ safeSegment6 = (value, label) => {
26658
+ const normalized = value.trim();
26659
+ if (!normalized || !/^[a-zA-Z0-9._:-]+$/.test(normalized)) {
26660
+ throw new Error(`Invalid runtime evidence snapshot ${label}`);
26661
+ }
26662
+ return normalized;
26663
+ };
26664
+ isExistingDestinationError4 = (error) => {
26665
+ const code = error.code;
26666
+ return code === "EEXIST" || code === "ENOTEMPTY";
26667
+ };
26668
+ parseManifest3 = (value) => {
26669
+ const manifest = isRecord4(value) ? value : null;
26670
+ const payload = isRecord4(manifest?.payload) ? manifest.payload : null;
26671
+ if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence-composition-snapshot" || typeof manifest.createdAt !== "number" || typeof manifest.userName !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.deploymentCompositionId !== "string" || payload?.file !== SNAPSHOT_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number") {
26672
+ throw new Error("Invalid runtime evidence composition snapshot manifest");
26673
+ }
26674
+ return manifest;
26675
+ };
26676
+ verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
26677
+ const [manifestText, payload, completeText] = await Promise.all([
26678
+ import_promises28.default.readFile(import_node_path24.default.join(bundleDir, MANIFEST_FILE), "utf8"),
26679
+ import_promises28.default.readFile(import_node_path24.default.join(bundleDir, SNAPSHOT_FILE)),
26680
+ import_promises28.default.readFile(import_node_path24.default.join(bundleDir, COMPLETE_FILE), "utf8")
26681
+ ]);
26682
+ const manifest = parseManifest3(JSON.parse(manifestText));
26683
+ if (completeText.trim() !== manifest.deploymentCompositionId) {
26684
+ throw new Error(`Invalid completion marker in ${bundleDir}`);
26685
+ }
26686
+ if (payload.byteLength !== manifest.payload.bytes || sha2564(payload) !== manifest.payload.sha256) {
26687
+ throw new Error(
26688
+ `Runtime evidence snapshot checksum mismatch in ${bundleDir}`
26689
+ );
26690
+ }
26691
+ const value = JSON.parse(payload.toString("utf8"));
26692
+ const record = isRecord4(value) ? value : null;
26693
+ if (record?.schemaVersion !== 1 || record.reportType !== "runtime-evidence-composition-snapshot" || record.userName !== manifest.userName) {
26694
+ throw new Error(
26695
+ `Invalid runtime evidence snapshot payload in ${bundleDir}`
26696
+ );
26697
+ }
26698
+ const deployment = parseRuntimeEvidenceDeploymentSnapshot(record.deployment);
26699
+ const producer = parseRuntimeEvidenceProducer(record.producer);
26700
+ if (deployment.id !== manifest.deploymentId || deployment.deploymentCompositionId !== manifest.deploymentCompositionId) {
26701
+ throw new Error(
26702
+ `Runtime evidence snapshot identity mismatch in ${bundleDir}`
26703
+ );
26704
+ }
26705
+ return { bundleDir, deployment, producer };
26706
+ };
26707
+ sameSnapshot = (snapshot, deployment, producer) => JSON.stringify(snapshot.deployment) === JSON.stringify(deployment) && JSON.stringify(snapshot.producer) === JSON.stringify(producer);
26708
+ publishRuntimeEvidenceCompositionSnapshot = async ({
26709
+ evidenceRoot,
26710
+ userName: userName3,
26711
+ deployment,
26712
+ producer
26713
+ }) => {
26714
+ const deploymentId = safeSegment6(deployment.id, "deployment id");
26715
+ const compositionId = safeSegment6(
26716
+ deployment.deploymentCompositionId,
26717
+ "composition id"
26718
+ );
26719
+ const createdAt = Date.now();
26720
+ const snapshot = {
26721
+ schemaVersion: 1,
26722
+ reportType: "runtime-evidence-composition-snapshot",
26723
+ createdAt,
26724
+ userName: userName3,
26725
+ deployment,
26726
+ producer
26727
+ };
26728
+ const payload = `${JSON.stringify(snapshot, null, 2)}
26729
+ `;
26730
+ const manifest = {
26731
+ schemaVersion: 1,
26732
+ reportType: "runtime-evidence-composition-snapshot",
26733
+ createdAt,
26734
+ userName: userName3,
26735
+ deploymentId,
26736
+ deploymentCompositionId: compositionId,
26737
+ payload: {
26738
+ file: SNAPSHOT_FILE,
26739
+ sha256: sha2564(payload),
26740
+ bytes: Buffer.byteLength(payload)
26741
+ }
26742
+ };
26743
+ const snapshotsRoot = import_node_path24.default.join(evidenceRoot, "snapshots", deploymentId);
26744
+ const bundleDir = import_node_path24.default.join(snapshotsRoot, compositionId);
26745
+ const temporaryDir = import_node_path24.default.join(
26746
+ evidenceRoot,
26747
+ "incoming",
26748
+ `snapshot-${compositionId}.tmp-${(0, import_node_crypto13.randomUUID)()}`
26749
+ );
26750
+ await import_promises28.default.mkdir(temporaryDir, { recursive: true });
26751
+ try {
26752
+ await Promise.all([
26753
+ import_promises28.default.writeFile(import_node_path24.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
26754
+ import_promises28.default.writeFile(
26755
+ import_node_path24.default.join(temporaryDir, MANIFEST_FILE),
26756
+ `${JSON.stringify(manifest, null, 2)}
26757
+ `,
26758
+ "utf8"
26759
+ )
26760
+ ]);
26761
+ await import_promises28.default.writeFile(
26762
+ import_node_path24.default.join(temporaryDir, COMPLETE_FILE),
26763
+ `${compositionId}
26764
+ `,
26765
+ "utf8"
26766
+ );
26767
+ await import_promises28.default.mkdir(snapshotsRoot, { recursive: true });
26768
+ try {
26769
+ await import_promises28.default.rename(temporaryDir, bundleDir);
26770
+ } catch (error) {
26771
+ if (!isExistingDestinationError4(error)) throw error;
26772
+ await import_promises28.default.rm(temporaryDir, { recursive: true, force: true });
26773
+ }
26774
+ } catch (error) {
26775
+ await import_promises28.default.rm(temporaryDir, { recursive: true, force: true });
26776
+ throw error;
26777
+ }
26778
+ const verified = await verifyRuntimeEvidenceCompositionSnapshot(bundleDir);
26779
+ if (!sameSnapshot(verified, deployment, producer)) {
26780
+ throw new Error(
26781
+ `Conflicting runtime evidence snapshot for composition ${compositionId}`
26782
+ );
26783
+ }
26784
+ return verified;
26785
+ };
26786
+ captureRuntimeEvidenceCompositionSnapshot = async ({
26787
+ projectRoot: projectRoot17,
26788
+ userName: userName3,
26789
+ deploymentId,
26790
+ expectedCompositionId
26791
+ }) => {
26792
+ const [deployment, producer] = await Promise.all([
26793
+ resolveRuntimeEvidenceDeploymentSnapshot({
26794
+ userName: userName3,
26795
+ projectRoot: projectRoot17,
26796
+ deploymentId
26797
+ }),
26798
+ resolveRuntimeEvidenceProducer({ projectRoot: projectRoot17, required: true })
26799
+ ]);
26800
+ if (!producer) {
26801
+ throw new Error("Runtime evidence producer identity is required");
26802
+ }
26803
+ if (deployment.deploymentCompositionId !== expectedCompositionId) {
26804
+ throw new Error(
26805
+ `Runtime deployment composition changed while capturing snapshot: expected ${expectedCompositionId}, received ${deployment.deploymentCompositionId}`
26806
+ );
26807
+ }
26808
+ await publishRuntimeEvidenceCompositionSnapshot({
26809
+ evidenceRoot: import_node_path24.default.join(projectRoot17, "data", "runtime-evidence"),
26810
+ userName: userName3,
26811
+ deployment,
26812
+ producer
26813
+ });
26814
+ };
26815
+ discoverRuntimeEvidenceCompositionSnapshots = async (evidenceRoot) => {
26816
+ const rootDir = import_node_path24.default.join(evidenceRoot, "snapshots");
26817
+ const bundleDirs = [];
26818
+ let deployments;
26819
+ try {
26820
+ deployments = await import_promises28.default.readdir(rootDir, { withFileTypes: true });
26821
+ } catch (error) {
26822
+ if (error.code === "ENOENT") return [];
26823
+ throw error;
26824
+ }
26825
+ for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
26826
+ const deploymentDir = import_node_path24.default.join(rootDir, deployment.name);
26827
+ const compositions = await import_promises28.default.readdir(deploymentDir, {
26828
+ withFileTypes: true
26829
+ });
26830
+ bundleDirs.push(
26831
+ ...compositions.filter(
26832
+ (entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
26833
+ ).map((entry) => import_node_path24.default.join(deploymentDir, entry.name))
26834
+ );
26835
+ }
26836
+ return Promise.all(
26837
+ bundleDirs.sort().map(verifyRuntimeEvidenceCompositionSnapshot)
26838
+ );
26839
+ };
26840
+ }
26841
+ });
26842
+
26843
+ // src/lib/runtimeEvidenceCompositions.ts
26844
+ var stableSnapshotIdentity, producerIdentity, loadRuntimeEvidenceCompositionSnapshots, rowCompositionId, rowTimestamp, belongsToSnapshot, splitRuntimeEvidenceByComposition;
26845
+ var init_runtimeEvidenceCompositions = __esm({
26846
+ "src/lib/runtimeEvidenceCompositions.ts"() {
26847
+ "use strict";
26848
+ init_runtimeEvidenceArtifacts();
26849
+ init_runtimeEvidenceCompositionSnapshots();
26850
+ init_runtimeEvidenceDeployment();
26851
+ init_runtimeEvidenceProducer();
26852
+ stableSnapshotIdentity = (deployment) => JSON.stringify({ ...deployment, tickers: void 0 });
26853
+ producerIdentity = (producer) => JSON.stringify(producer);
26854
+ loadRuntimeEvidenceCompositionSnapshots = async ({
26855
+ publishRoot,
26856
+ currentDeployment,
26857
+ currentProducer
26858
+ }) => {
26859
+ const snapshots = /* @__PURE__ */ new Map();
26860
+ const register = (snapshot) => {
26861
+ const compositionId = snapshot.deployment.deploymentCompositionId;
26862
+ const known = snapshots.get(compositionId);
26863
+ if (known && (stableSnapshotIdentity(known.deployment) !== stableSnapshotIdentity(snapshot.deployment) || producerIdentity(known.producer) !== producerIdentity(snapshot.producer))) {
26864
+ throw new Error(
26865
+ `Conflicting runtime evidence snapshot for composition ${compositionId}`
26866
+ );
26867
+ }
26868
+ snapshots.set(compositionId, snapshot);
26869
+ };
26870
+ const compositionSnapshots = await discoverRuntimeEvidenceCompositionSnapshots(publishRoot);
26871
+ for (const snapshot of compositionSnapshots) {
26872
+ if (snapshot.deployment.id !== currentDeployment.id) continue;
26873
+ register({
26874
+ deployment: { ...snapshot.deployment, tickers: void 0 },
26875
+ producer: snapshot.producer
26876
+ });
26877
+ }
26878
+ const bundleDirs = await discoverRuntimeEvidenceBundles(publishRoot);
26879
+ for (const bundleDir of bundleDirs) {
26880
+ const bundle = await verifyRuntimeEvidenceBundle(bundleDir);
26881
+ const deployment = parseRuntimeEvidenceDeploymentSnapshot(
26882
+ bundle.artifact.deployment
26883
+ );
26884
+ if (deployment.id !== currentDeployment.id) continue;
26885
+ if (bundle.artifact.producer == null) continue;
26886
+ register({
26887
+ deployment: { ...deployment, tickers: void 0 },
26888
+ producer: parseRuntimeEvidenceProducer(bundle.artifact.producer)
26889
+ });
26890
+ }
26891
+ const historicalCurrent = snapshots.get(
26892
+ currentDeployment.deploymentCompositionId
26893
+ );
26894
+ if (historicalCurrent && stableSnapshotIdentity(historicalCurrent.deployment) !== stableSnapshotIdentity(currentDeployment)) {
26895
+ throw new Error(
26896
+ `Current runtime deployment conflicts with stored composition ${currentDeployment.deploymentCompositionId}`
26897
+ );
26898
+ }
26899
+ snapshots.set(currentDeployment.deploymentCompositionId, {
26900
+ deployment: { ...currentDeployment, tickers: void 0 },
26901
+ producer: currentProducer
26902
+ });
26903
+ return snapshots;
26904
+ };
26905
+ rowCompositionId = (row) => row.runtimeLineage?.deploymentCompositionId ?? row.lineage?.deploymentCompositionId ?? null;
26906
+ rowTimestamp = (row) => {
26907
+ for (const field of [
26908
+ "firstTimestamp",
26909
+ "entryTimestamp",
26910
+ "timestamp",
26911
+ "lastTimestamp"
26912
+ ]) {
26913
+ const value = row[field];
26914
+ if (typeof value === "number" && Number.isFinite(value)) return value;
26915
+ }
26916
+ return Number.POSITIVE_INFINITY;
26917
+ };
26918
+ belongsToSnapshot = (row, deployment) => {
26919
+ const strategy = activeRuntimeEvidenceStrategies(deployment).find(
26920
+ (candidate) => candidate.strategyName === row.strategy
26921
+ );
26922
+ return Boolean(
26923
+ strategy && row.deploymentId === deployment.id && row.accountId === deployment.accountId && runtimeLineageMatchesStrategySnapshot({
26924
+ lineage: row.runtimeLineage ?? row.lineage,
26925
+ deployment,
26926
+ strategy
26927
+ })
26928
+ );
26929
+ };
26930
+ splitRuntimeEvidenceByComposition = ({
26931
+ evidence,
26932
+ snapshots,
26933
+ includeEmptyCompositionIds = [],
26934
+ ignoreUnknownCompositions = false
26935
+ }) => {
26936
+ const observed = /* @__PURE__ */ new Set();
26937
+ for (const row of [
26938
+ ...evidence.trades,
26939
+ ...evidence.signals,
26940
+ ...evidence.evaluations,
26941
+ ...evidence.lineageScopes
26942
+ ]) {
26943
+ const compositionId = rowCompositionId(row);
26944
+ if (compositionId) observed.add(compositionId);
26945
+ }
26946
+ for (const compositionId of includeEmptyCompositionIds) {
26947
+ observed.add(compositionId);
26948
+ }
26949
+ const missing = [...observed].filter(
26950
+ (compositionId) => !snapshots.has(compositionId)
26951
+ );
26952
+ if (missing.length && !ignoreUnknownCompositions) {
26953
+ throw new Error(
26954
+ `Runtime evidence has no verified deployment snapshot for composition(s): ${missing.sort().join(", ")}`
26955
+ );
26956
+ }
26957
+ return [...observed].filter((compositionId) => snapshots.has(compositionId)).map((compositionId) => snapshots.get(compositionId)).map(({ deployment, producer }) => {
26958
+ const trades = evidence.trades.filter(
26959
+ (row) => belongsToSnapshot(row, deployment)
26960
+ );
26961
+ const signals2 = evidence.signals.filter(
26962
+ (row) => belongsToSnapshot(row, deployment)
26963
+ );
26964
+ const evaluations = evidence.evaluations.filter(
26965
+ (row) => belongsToSnapshot(row, deployment)
26966
+ );
26967
+ const lineageScopes = evidence.lineageScopes.filter(
26968
+ (row) => belongsToSnapshot(row, deployment)
26969
+ );
26970
+ const timestamps = [
26971
+ ...trades,
26972
+ ...signals2,
26973
+ ...evaluations,
26974
+ ...lineageScopes
26975
+ ].map((row) => rowTimestamp(row));
26976
+ return {
26977
+ deployment,
26978
+ producer,
26979
+ trades,
26980
+ signals: signals2,
26981
+ evaluations,
26982
+ lineageScopes,
26983
+ firstTimestamp: Math.min(...timestamps)
26984
+ };
26985
+ }).sort(
26986
+ (left, right) => left.firstTimestamp - right.firstTimestamp || left.deployment.deploymentCompositionId.localeCompare(
26987
+ right.deployment.deploymentCompositionId
26988
+ )
26989
+ );
26990
+ };
26991
+ }
26992
+ });
26993
+
26628
26994
  // src/lib/runtimeLineage.ts
26629
- var import_node_crypto13, normalizeForStableJson2, resolveRuntimeMaxLossValue, fingerprintRuntimeValue, buildRuntimeLineage, runtimeLineageKey, runtimeLineagesMatch, runtimeLineagesComparable;
26995
+ var import_node_crypto14, normalizeForStableJson2, resolveRuntimeMaxLossValue, fingerprintRuntimeValue, buildRuntimeLineage, runtimeLineageKey, runtimeLineagesMatch, runtimeLineagesComparable;
26630
26996
  var init_runtimeLineage = __esm({
26631
26997
  "src/lib/runtimeLineage.ts"() {
26632
26998
  "use strict";
26633
- import_node_crypto13 = require("crypto");
26999
+ import_node_crypto14 = require("crypto");
26634
27000
  normalizeForStableJson2 = (value) => {
26635
27001
  if (Array.isArray(value)) {
26636
27002
  return value.map(normalizeForStableJson2);
@@ -26655,7 +27021,7 @@ var init_runtimeLineage = __esm({
26655
27021
  );
26656
27022
  return Number.isFinite(maxLossValue) ? maxLossValue : null;
26657
27023
  };
26658
- fingerprintRuntimeValue = (value) => (0, import_node_crypto13.createHash)("sha256").update(JSON.stringify(normalizeForStableJson2(value))).digest("hex").slice(0, 16);
27024
+ fingerprintRuntimeValue = (value) => (0, import_node_crypto14.createHash)("sha256").update(JSON.stringify(normalizeForStableJson2(value))).digest("hex").slice(0, 16);
26659
27025
  buildRuntimeLineage = async ({
26660
27026
  strategyRevision,
26661
27027
  deploymentCompositionId,
@@ -26709,16 +27075,17 @@ __export(runtimeEvidence_exports, {
26709
27075
  main: () => main36,
26710
27076
  runtimeEvidence: () => runtimeEvidence
26711
27077
  });
26712
- var import_promises28, import_node_path24, import_args28, import_chalk41, flags27, projectRoot11, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main36;
27078
+ var import_promises29, import_node_path25, import_args28, import_chalk41, flags27, projectRoot11, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main36;
26713
27079
  var init_runtimeEvidence = __esm({
26714
27080
  "src/scripts/runtimeEvidence.ts"() {
26715
27081
  "use strict";
26716
- import_promises28 = __toESM(require("fs/promises"));
26717
- import_node_path24 = __toESM(require("path"));
27082
+ import_promises29 = __toESM(require("fs/promises"));
27083
+ import_node_path25 = __toESM(require("path"));
26718
27084
  import_args28 = __toESM(require("args"));
26719
27085
  import_chalk41 = __toESM(require("chalk"));
26720
27086
  init_runtimeDebugEvidence();
26721
27087
  init_runtimeEvidenceArtifacts();
27088
+ init_runtimeEvidenceCompositions();
26722
27089
  init_runtimeLineage();
26723
27090
  init_runtimeEvidenceProducer();
26724
27091
  init_runtimeEvidenceDeployment();
@@ -26811,15 +27178,30 @@ var init_runtimeEvidence = __esm({
26811
27178
  projectRoot: projectRoot11,
26812
27179
  deploymentId
26813
27180
  });
26814
- const activeStrategies = activeRuntimeEvidenceStrategies(
26815
- deploymentSnapshot
26816
- ).map(({ strategyName }) => strategyName);
26817
27181
  const requestedStrategies = parseStrategyFilter2(flags27.strategy);
26818
- const strategies = requestedStrategies.length ? requestedStrategies : activeStrategies;
27182
+ const evidence = await collectRuntimeDebugEvidence({
27183
+ userName: flags27.user,
27184
+ startTime,
27185
+ endTime,
27186
+ strategies: requestedStrategies.length ? requestedStrategies : void 0,
27187
+ deploymentId
27188
+ });
27189
+ const snapshots = publishDir && producer ? await loadRuntimeEvidenceCompositionSnapshots({
27190
+ publishRoot: import_node_path25.default.resolve(projectRoot11, publishDir),
27191
+ currentDeployment: deploymentSnapshot,
27192
+ currentProducer: producer
27193
+ }) : /* @__PURE__ */ new Map([
27194
+ [
27195
+ deploymentSnapshot.deploymentCompositionId,
27196
+ { deployment: deploymentSnapshot, producer }
27197
+ ]
27198
+ ]);
26819
27199
  const declaredStrategies = new Set(
26820
- deploymentSnapshot.strategies.map(({ strategyName }) => strategyName)
27200
+ [...snapshots.values()].flatMap(
27201
+ ({ deployment }) => deployment.strategies.map(({ strategyName }) => strategyName)
27202
+ )
26821
27203
  );
26822
- const unknownStrategies = strategies.filter(
27204
+ const unknownStrategies = requestedStrategies.filter(
26823
27205
  (strategyName) => !declaredStrategies.has(strategyName)
26824
27206
  );
26825
27207
  if (unknownStrategies.length) {
@@ -26827,97 +27209,94 @@ var init_runtimeEvidence = __esm({
26827
27209
  `Strategies are not declared in ${deploymentId}: ${unknownStrategies.join(", ")}`
26828
27210
  );
26829
27211
  }
26830
- const evidence = await collectRuntimeDebugEvidence({
26831
- userName: flags27.user,
26832
- startTime,
26833
- endTime,
26834
- strategies,
26835
- deploymentId
27212
+ const compositionRows = splitRuntimeEvidenceByComposition({
27213
+ evidence,
27214
+ snapshots,
27215
+ includeEmptyCompositionIds: publishDir ? [] : [deploymentSnapshot.deploymentCompositionId],
27216
+ ignoreUnknownCompositions: !publishDir
26836
27217
  });
26837
- const activeSnapshots = new Map(
26838
- activeRuntimeEvidenceStrategies(deploymentSnapshot).map((strategy) => [
26839
- strategy.strategyName,
26840
- strategy
26841
- ])
26842
- );
26843
- const belongsToCurrentDeployment = (row) => {
26844
- const snapshot = activeSnapshots.get(row.strategy);
26845
- return Boolean(
26846
- snapshot && row.deploymentId === deploymentSnapshot.id && row.accountId === deploymentSnapshot.accountId && runtimeLineageMatchesStrategySnapshot({
26847
- lineage: row.runtimeLineage,
26848
- deployment: deploymentSnapshot,
26849
- strategy: snapshot
26850
- })
27218
+ const artifacts = compositionRows.map((composition) => {
27219
+ const strategies = activeRuntimeEvidenceStrategies(composition.deployment).map(({ strategyName }) => strategyName).filter(
27220
+ (strategyName) => !requestedStrategies.length || requestedStrategies.includes(strategyName)
26851
27221
  );
26852
- };
26853
- const currentSignals = evidence.signals.filter(belongsToCurrentDeployment);
26854
- const currentEvaluations = evidence.evaluations.filter(
26855
- belongsToCurrentDeployment
26856
- );
26857
- const currentTrades = evidence.trades.filter(belongsToCurrentDeployment);
26858
- const currentLineageScopes = evidence.lineageScopes.filter(
26859
- (scope) => belongsToCurrentDeployment({
26860
- ...scope,
26861
- runtimeLineage: scope.lineage
26862
- })
26863
- );
26864
- const runtime = buildRuntimeEvidenceReportPayload({
26865
- userName: flags27.user,
26866
- startTime,
26867
- endTime,
26868
- signals: currentSignals,
26869
- evaluations: currentEvaluations,
26870
- trades: currentTrades,
26871
- lineageScopes: currentLineageScopes
26872
- });
26873
- const deployment = resolveRuntimeEvidenceTickerUniverse({
26874
- deployment: deploymentSnapshot,
26875
- lineageScopes: currentLineageScopes
26876
- });
26877
- const artifact = {
26878
- reportType: "runtime-evidence",
26879
- generatedAt: Date.now(),
26880
- ...producer ? { producer } : {},
26881
- userName: flags27.user,
26882
- window: {
27222
+ const runtime = buildRuntimeEvidenceReportPayload({
27223
+ userName: flags27.user,
26883
27224
  startTime,
26884
27225
  endTime,
26885
- startIso: new Date(startTime).toISOString(),
26886
- endIso: new Date(endTime).toISOString(),
26887
- source
26888
- },
26889
- strategies,
26890
- deployment,
26891
- runtime
26892
- };
26893
- const outPath = import_node_path24.default.resolve(projectRoot11, String(flags27.out));
26894
- await import_promises28.default.mkdir(import_node_path24.default.dirname(outPath), { recursive: true });
26895
- await import_promises28.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
27226
+ signals: composition.signals,
27227
+ evaluations: composition.evaluations,
27228
+ trades: composition.trades,
27229
+ lineageScopes: composition.lineageScopes
27230
+ });
27231
+ const deployment = resolveRuntimeEvidenceTickerUniverse({
27232
+ deployment: composition.deployment,
27233
+ lineageScopes: composition.lineageScopes
27234
+ });
27235
+ return {
27236
+ artifact: {
27237
+ reportType: "runtime-evidence",
27238
+ generatedAt: Date.now(),
27239
+ ...composition.producer ? { producer: composition.producer } : {},
27240
+ ...producer && composition.producer && composition.producer !== producer ? { collector: producer } : {},
27241
+ userName: flags27.user,
27242
+ window: {
27243
+ startTime,
27244
+ endTime,
27245
+ startIso: new Date(startTime).toISOString(),
27246
+ endIso: new Date(endTime).toISOString(),
27247
+ source
27248
+ },
27249
+ strategies,
27250
+ deployment,
27251
+ runtime
27252
+ },
27253
+ composition
27254
+ };
27255
+ });
27256
+ const current = artifacts.find(
27257
+ ({ artifact: artifact2 }) => artifact2.deployment.deploymentCompositionId === deploymentSnapshot.deploymentCompositionId
27258
+ ) ?? artifacts.at(-1);
27259
+ if (!current) {
27260
+ throw new Error("Runtime evidence window has no versioned runtime rows");
27261
+ }
27262
+ const artifact = current.artifact;
27263
+ const outPath = import_node_path25.default.resolve(projectRoot11, String(flags27.out));
27264
+ await import_promises29.default.mkdir(import_node_path25.default.dirname(outPath), { recursive: true });
27265
+ await import_promises29.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
26896
27266
  `, "utf8");
26897
- const published = publishDir ? await publishRuntimeEvidenceBundle({
26898
- publishRoot: import_node_path24.default.resolve(projectRoot11, publishDir),
26899
- deploymentId,
26900
- userName: String(flags27.user),
26901
- startTime,
26902
- endTime,
26903
- artifact,
26904
- counts: artifact.runtime.counts,
26905
- lineageKeys: [
26906
- ...currentSignals.map((signal) => signal.runtimeLineage),
26907
- ...currentEvaluations.map((evaluation) => evaluation.runtimeLineage),
26908
- ...currentTrades.map((trade) => trade.runtimeLineage),
26909
- ...currentLineageScopes.map((scope) => scope.lineage)
26910
- ].filter((lineage) => lineage != null).map(runtimeLineageKey).filter((key, index, values) => values.indexOf(key) === index)
26911
- }) : null;
27267
+ const published = publishDir ? await Promise.all(
27268
+ artifacts.map(
27269
+ ({ artifact: artifact2, composition }) => publishRuntimeEvidenceBundle({
27270
+ publishRoot: import_node_path25.default.resolve(projectRoot11, publishDir),
27271
+ deploymentId,
27272
+ userName: String(flags27.user),
27273
+ startTime,
27274
+ endTime,
27275
+ artifact: artifact2,
27276
+ counts: artifact2.runtime.counts,
27277
+ lineageKeys: [
27278
+ ...composition.signals.map((signal) => signal.runtimeLineage),
27279
+ ...composition.evaluations.map(
27280
+ (evaluation) => evaluation.runtimeLineage
27281
+ ),
27282
+ ...composition.trades.map((trade) => trade.runtimeLineage),
27283
+ ...composition.lineageScopes.map((scope) => scope.lineage)
27284
+ ].filter((lineage) => lineage != null).map(runtimeLineageKey).filter((key, index, values) => values.indexOf(key) === index)
27285
+ })
27286
+ )
27287
+ ) : [];
26912
27288
  console.log(import_chalk41.default.green(`Wrote ${outPath}`));
26913
- if (published) {
26914
- console.log(import_chalk41.default.green(`Published ${published.bundleDir}`));
27289
+ for (const bundle of published) {
27290
+ console.log(import_chalk41.default.green(`Published ${bundle.bundleDir}`));
26915
27291
  }
26916
27292
  console.log(
26917
27293
  JSON.stringify(
26918
27294
  {
26919
- strategies: artifact.strategies,
26920
- runtimeCounts: artifact.runtime.counts
27295
+ compositions: artifacts.map(({ artifact: artifact2 }) => ({
27296
+ deploymentCompositionId: artifact2.deployment.deploymentCompositionId,
27297
+ strategies: artifact2.strategies,
27298
+ runtimeCounts: artifact2.runtime.counts
27299
+ }))
26921
27300
  },
26922
27301
  null,
26923
27302
  2
@@ -26934,11 +27313,11 @@ __export(runtimeEvidenceSync_exports, {
26934
27313
  main: () => main37,
26935
27314
  runtimeEvidenceSync: () => runtimeEvidenceSync
26936
27315
  });
26937
- var import_node_path25, import_args29, import_chalk42, flags28, projectRoot12, runtimeEvidenceSync, main37;
27316
+ var import_node_path26, import_args29, import_chalk42, flags28, projectRoot12, runtimeEvidenceSync, main37;
26938
27317
  var init_runtimeEvidenceSync2 = __esm({
26939
27318
  "src/scripts/runtimeEvidenceSync.ts"() {
26940
27319
  "use strict";
26941
- import_node_path25 = __toESM(require("path"));
27320
+ import_node_path26 = __toESM(require("path"));
26942
27321
  import_args29 = __toESM(require("args"));
26943
27322
  import_chalk42 = __toESM(require("chalk"));
26944
27323
  init_runtimeEvidenceSync();
@@ -26966,7 +27345,7 @@ var init_runtimeEvidenceSync2 = __esm({
26966
27345
  "Provide --source or RUNTIME_EVIDENCE_RSYNC_SOURCE for runtime evidence sync."
26967
27346
  );
26968
27347
  }
26969
- const evidenceRoot = import_node_path25.default.resolve(projectRoot12, String(flags28.dir));
27348
+ const evidenceRoot = import_node_path26.default.resolve(projectRoot12, String(flags28.dir));
26970
27349
  const result = await syncRuntimeEvidenceBundles({
26971
27350
  source,
26972
27351
  evidenceRoot,
@@ -28053,7 +28432,7 @@ async function collectReleaseEvidenceReferences(references) {
28053
28432
  let artifact;
28054
28433
  try {
28055
28434
  const parsed = JSON.parse(
28056
- await import_promises29.default.readFile(reference.path, "utf8")
28435
+ await import_promises30.default.readFile(reference.path, "utf8")
28057
28436
  );
28058
28437
  assert3(
28059
28438
  parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
@@ -28200,13 +28579,13 @@ async function collectReleaseEvidenceReferences(references) {
28200
28579
  })
28201
28580
  );
28202
28581
  }
28203
- var import_node_crypto14, import_promises29, import_node_path26, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment6, 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;
28582
+ var import_node_crypto15, import_promises30, import_node_path27, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment7, 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;
28204
28583
  var init_strategyRelease = __esm({
28205
28584
  "src/lib/strategyRelease.ts"() {
28206
28585
  "use strict";
28207
- import_node_crypto14 = require("crypto");
28208
- import_promises29 = __toESM(require("fs/promises"));
28209
- import_node_path26 = __toESM(require("path"));
28586
+ import_node_crypto15 = require("crypto");
28587
+ import_promises30 = __toESM(require("fs/promises"));
28588
+ import_node_path27 = __toESM(require("path"));
28210
28589
  import_types9 = require("@tradejs/types");
28211
28590
  import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
28212
28591
  init_liveDiagnosis();
@@ -28219,17 +28598,17 @@ var init_strategyRelease = __esm({
28219
28598
  REQUIRED_LONG_WINDOWS = [1095, 1460, 1825];
28220
28599
  REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS = [365, 180, 90];
28221
28600
  MIN_RECENT_DIRECTION_REPAIR_EVENTS = 20;
28222
- safeSegment6 = import_strategyReleaseEvidence2.safeStrategyEvidenceSegment;
28601
+ safeSegment7 = import_strategyReleaseEvidence2.safeStrategyEvidenceSegment;
28223
28602
  compactTimestamp2 = import_strategyReleaseEvidence2.compactStrategyEvidenceTimestamp;
28224
28603
  verifyFullPeriodChartArtifact = async (input) => {
28225
28604
  const artifact = input.chartArtifact;
28226
28605
  if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return false;
28227
28606
  try {
28228
- const artifactPath = import_node_path26.default.resolve(artifact.path);
28607
+ const artifactPath = import_node_path27.default.resolve(artifact.path);
28229
28608
  if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
28230
28609
  return false;
28231
28610
  }
28232
- const report = JSON.parse(await import_promises29.default.readFile(artifactPath, "utf8"));
28611
+ const report = JSON.parse(await import_promises30.default.readFile(artifactPath, "utf8"));
28233
28612
  return Boolean(
28234
28613
  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
28235
28614
  );
@@ -28240,11 +28619,11 @@ var init_strategyRelease = __esm({
28240
28619
  readVerifiedJsonArtifact = async (artifact) => {
28241
28620
  if (!artifact?.path || !SHA256_RE2.test(artifact.sha256)) return null;
28242
28621
  try {
28243
- const artifactPath = import_node_path26.default.resolve(artifact.path);
28622
+ const artifactPath = import_node_path27.default.resolve(artifact.path);
28244
28623
  if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
28245
28624
  return null;
28246
28625
  }
28247
- return JSON.parse(await import_promises29.default.readFile(artifactPath, "utf8"));
28626
+ return JSON.parse(await import_promises30.default.readFile(artifactPath, "utf8"));
28248
28627
  } catch {
28249
28628
  return null;
28250
28629
  }
@@ -28735,7 +29114,7 @@ var init_strategyRelease = __esm({
28735
29114
  maxLossValue: input.composition.maxLossValue,
28736
29115
  ...input.composition.directionPolicy == null ? {} : { directionPolicy: input.composition.directionPolicy }
28737
29116
  };
28738
- const compositionId = `${safeSegment6(input.strategy, "strategy")}_${strategyReleaseSha256(compositionIdentity).slice(0, 16)}`;
29117
+ const compositionId = `${safeSegment7(input.strategy, "strategy")}_${strategyReleaseSha256(compositionIdentity).slice(0, 16)}`;
28739
29118
  const reasons = releaseReasons({ ...input, gates: evidenceGates });
28740
29119
  const economicFailure = reasons.some(
28741
29120
  (reason) => [
@@ -28757,16 +29136,16 @@ var init_strategyRelease = __esm({
28757
29136
  strategy: input.strategy,
28758
29137
  createdAt: input.createdAt,
28759
29138
  compositionId,
28760
- evidence: input.evidence.map(({ kind, artifactId, sha256: sha2564 }) => ({
29139
+ evidence: input.evidence.map(({ kind, artifactId, sha256: sha2565 }) => ({
28761
29140
  kind,
28762
29141
  artifactId,
28763
- sha256: sha2564
29142
+ sha256: sha2565
28764
29143
  })),
28765
29144
  verdict
28766
29145
  };
28767
29146
  return {
28768
29147
  schema: import_types9.STRATEGY_RELEASE_SCHEMA,
28769
- releaseId: `${safeSegment6(input.strategy, "strategy")}_${compactTimestamp2(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
29148
+ releaseId: `${safeSegment7(input.strategy, "strategy")}_${compactTimestamp2(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
28770
29149
  strategy: input.strategy,
28771
29150
  createdAt: input.createdAt,
28772
29151
  composition: { ...input.composition, compositionId },
@@ -28790,7 +29169,7 @@ var init_strategyRelease = __esm({
28790
29169
  manifest
28791
29170
  });
28792
29171
  verifyStrategyReleaseEnvelope = async (valueOrPath) => {
28793
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises29.default.readFile(valueOrPath, "utf8")) : valueOrPath;
29172
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises30.default.readFile(valueOrPath, "utf8")) : valueOrPath;
28794
29173
  const envelope = value;
28795
29174
  assert3(
28796
29175
  envelope?.schema === "tradejs-strategy-release-envelope/v1",
@@ -28841,7 +29220,7 @@ var init_strategyRelease = __esm({
28841
29220
  return envelope;
28842
29221
  };
28843
29222
  verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
28844
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises29.default.readFile(valueOrPath, "utf8")) : valueOrPath;
29223
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises30.default.readFile(valueOrPath, "utf8")) : valueOrPath;
28845
29224
  return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
28846
29225
  };
28847
29226
  releaseMarkers = (manifest) => {
@@ -28903,14 +29282,14 @@ var init_strategyRelease = __esm({
28903
29282
  };
28904
29283
  writeJsonAtomic2 = async (filePath, value) => {
28905
29284
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
28906
- await import_promises29.default.mkdir(import_node_path26.default.dirname(filePath), { recursive: true });
28907
- await import_promises29.default.writeFile(
29285
+ await import_promises30.default.mkdir(import_node_path27.default.dirname(filePath), { recursive: true });
29286
+ await import_promises30.default.writeFile(
28908
29287
  temporaryPath,
28909
29288
  `${canonicalStrategyReleaseJson(value)}
28910
29289
  `,
28911
29290
  "utf8"
28912
29291
  );
28913
- await import_promises29.default.rename(temporaryPath, filePath);
29292
+ await import_promises30.default.rename(temporaryPath, filePath);
28914
29293
  };
28915
29294
  publishStrategyRelease = async ({
28916
29295
  rootDir,
@@ -28927,16 +29306,16 @@ var init_strategyRelease = __esm({
28927
29306
  path: entry.path
28928
29307
  }))
28929
29308
  });
28930
- const releasePath = import_node_path26.default.join(
29309
+ const releasePath = import_node_path27.default.join(
28931
29310
  rootDir,
28932
29311
  "releases",
28933
- safeSegment6(manifest.strategy, "strategy"),
29312
+ safeSegment7(manifest.strategy, "strategy"),
28934
29313
  `${manifest.releaseId}.json`
28935
29314
  );
28936
- const markerPath = import_node_path26.default.join(
29315
+ const markerPath = import_node_path27.default.join(
28937
29316
  rootDir,
28938
29317
  "markers",
28939
- safeSegment6(manifest.strategy, "strategy"),
29318
+ safeSegment7(manifest.strategy, "strategy"),
28940
29319
  `${markerEnvelope.artifactId}.json`
28941
29320
  );
28942
29321
  await Promise.all([
@@ -28956,7 +29335,7 @@ var init_strategyRelease = __esm({
28956
29335
  composition
28957
29336
  }) => {
28958
29337
  const diagnosisSha256 = strategyReleaseSha256(diagnosis);
28959
- const diagnosisId = `${safeSegment6(diagnosis.strategy, "strategy")}_${compactTimestamp2(diagnosis.createdAt)}_${diagnosisSha256.slice(0, 16)}`;
29338
+ const diagnosisId = `${safeSegment7(diagnosis.strategy, "strategy")}_${compactTimestamp2(diagnosis.createdAt)}_${diagnosisSha256.slice(0, 16)}`;
28960
29339
  const envelope = {
28961
29340
  schema: "tradejs-strategy-live-diagnosis-envelope/v1",
28962
29341
  diagnosisId,
@@ -29013,16 +29392,16 @@ var init_strategyRelease = __esm({
29013
29392
  markers,
29014
29393
  sourceArtifacts
29015
29394
  });
29016
- const diagnosisPath = import_node_path26.default.join(
29395
+ const diagnosisPath = import_node_path27.default.join(
29017
29396
  rootDir,
29018
29397
  "diagnoses",
29019
- safeSegment6(diagnosis.strategy, "strategy"),
29398
+ safeSegment7(diagnosis.strategy, "strategy"),
29020
29399
  `${diagnosisId}.json`
29021
29400
  );
29022
- const markerPath = import_node_path26.default.join(
29401
+ const markerPath = import_node_path27.default.join(
29023
29402
  rootDir,
29024
29403
  "markers",
29025
- safeSegment6(diagnosis.strategy, "strategy"),
29404
+ safeSegment7(diagnosis.strategy, "strategy"),
29026
29405
  `${markerEnvelope.artifactId}.json`
29027
29406
  );
29028
29407
  await Promise.all([
@@ -29209,11 +29588,11 @@ var init_strategyRelease = __esm({
29209
29588
  const specSha256 = finiteString3(artifact.specSha256);
29210
29589
  assert3(researchId != null, "core result researchId is required");
29211
29590
  assert3(specSha256 != null, "core result specSha256 is required");
29212
- const researchDir = import_node_path26.default.dirname(resultPath);
29213
- const manifestPath = import_node_path26.default.join(researchDir, "manifest.json");
29214
- const specPath = import_node_path26.default.join(researchDir, "spec.json");
29215
- const manifestBytes = await import_promises29.default.readFile(manifestPath).catch(() => null);
29216
- const specBytes = await import_promises29.default.readFile(specPath).catch(() => null);
29591
+ const researchDir = import_node_path27.default.dirname(resultPath);
29592
+ const manifestPath = import_node_path27.default.join(researchDir, "manifest.json");
29593
+ const specPath = import_node_path27.default.join(researchDir, "spec.json");
29594
+ const manifestBytes = await import_promises30.default.readFile(manifestPath).catch(() => null);
29595
+ const specBytes = await import_promises30.default.readFile(specPath).catch(() => null);
29217
29596
  assert3(
29218
29597
  manifestBytes != null && specBytes != null,
29219
29598
  "core result must belong to a completed core research bundle"
@@ -29222,14 +29601,14 @@ var init_strategyRelease = __esm({
29222
29601
  const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
29223
29602
  const parsedSpec = JSON.parse(specBytes.toString("utf8"));
29224
29603
  assert3(
29225
- manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto14.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
29604
+ manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto15.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
29226
29605
  "core result is not bound by its completed core research manifest"
29227
29606
  );
29228
29607
  for (const [relativePath, expectedSha256] of Object.entries(
29229
29608
  artifactHashes ?? {}
29230
29609
  )) {
29231
29610
  assert3(
29232
- !import_node_path26.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
29611
+ !import_node_path27.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
29233
29612
  `core bundle artifact ${relativePath} escapes its research directory`
29234
29613
  );
29235
29614
  assert3(
@@ -29237,7 +29616,7 @@ var init_strategyRelease = __esm({
29237
29616
  `core bundle artifact ${relativePath} has an invalid checksum`
29238
29617
  );
29239
29618
  const actualSha256 = await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(
29240
- import_node_path26.default.join(researchDir, relativePath)
29619
+ import_node_path27.default.join(researchDir, relativePath)
29241
29620
  );
29242
29621
  assert3(
29243
29622
  actualSha256 === expectedSha256,
@@ -29254,13 +29633,13 @@ __export(runtimeScorecard_exports, {
29254
29633
  main: () => main38,
29255
29634
  runtimeScorecard: () => runtimeScorecard
29256
29635
  });
29257
- var import_promises30, import_node_crypto15, import_node_path27, import_args30, import_chalk43, flags29, projectRoot13, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main38;
29636
+ var import_promises31, import_node_crypto16, import_node_path28, import_args30, import_chalk43, flags29, projectRoot13, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main38;
29258
29637
  var init_runtimeScorecard2 = __esm({
29259
29638
  "src/scripts/runtimeScorecard.ts"() {
29260
29639
  "use strict";
29261
- import_promises30 = __toESM(require("fs/promises"));
29262
- import_node_crypto15 = require("crypto");
29263
- import_node_path27 = __toESM(require("path"));
29640
+ import_promises31 = __toESM(require("fs/promises"));
29641
+ import_node_crypto16 = require("crypto");
29642
+ import_node_path28 = __toESM(require("path"));
29264
29643
  import_args30 = __toESM(require("args"));
29265
29644
  import_chalk43 = __toESM(require("chalk"));
29266
29645
  init_runtimeEvidenceArtifacts();
@@ -29330,15 +29709,15 @@ var init_runtimeScorecard2 = __esm({
29330
29709
  projectRoot13 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
29331
29710
  resolveOptionalPath = (value) => {
29332
29711
  const raw = String(value ?? "").trim();
29333
- return raw ? import_node_path27.default.resolve(projectRoot13, raw) : null;
29712
+ return raw ? import_node_path28.default.resolve(projectRoot13, raw) : null;
29334
29713
  };
29335
- readJson = async (filePath) => filePath ? JSON.parse(await import_promises30.default.readFile(filePath, "utf8")) : void 0;
29714
+ readJson = async (filePath) => filePath ? JSON.parse(await import_promises31.default.readFile(filePath, "utf8")) : void 0;
29336
29715
  assertReportType = (artifact, expected, label) => {
29337
29716
  if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
29338
29717
  throw new Error(`${label} must be a ${expected} artifact`);
29339
29718
  }
29340
29719
  };
29341
- sha256File2 = async (filePath) => (0, import_node_crypto15.createHash)("sha256").update(await import_promises30.default.readFile(filePath)).digest("hex");
29720
+ sha256File2 = async (filePath) => (0, import_node_crypto16.createHash)("sha256").update(await import_promises31.default.readFile(filePath)).digest("hex");
29342
29721
  loadHistoryArtifacts = async (historyDir) => {
29343
29722
  if (!historyDir) return [];
29344
29723
  const bundleDirs = await discoverRuntimeEvidenceBundles(historyDir);
@@ -29409,13 +29788,13 @@ var init_runtimeScorecard2 = __esm({
29409
29788
  strategy: scorecardStrategy,
29410
29789
  llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
29411
29790
  });
29412
- const outPath = import_node_path27.default.resolve(projectRoot13, String(flags29.out));
29791
+ const outPath = import_node_path28.default.resolve(projectRoot13, String(flags29.out));
29413
29792
  const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
29414
- await import_promises30.default.mkdir(import_node_path27.default.dirname(outPath), { recursive: true });
29793
+ await import_promises31.default.mkdir(import_node_path28.default.dirname(outPath), { recursive: true });
29415
29794
  await Promise.all([
29416
- import_promises30.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
29795
+ import_promises31.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
29417
29796
  `, "utf8"),
29418
- import_promises30.default.writeFile(
29797
+ import_promises31.default.writeFile(
29419
29798
  markdownPath,
29420
29799
  formatRuntimeScorecardMarkdown(scorecard),
29421
29800
  "utf8"
@@ -29429,7 +29808,7 @@ var init_runtimeScorecard2 = __esm({
29429
29808
  const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
29430
29809
  const strategyReleaseRoot = resolveOptionalPath(flags29.strategyReleaseRoot);
29431
29810
  if (diagnosis && diagnosisPath) {
29432
- await import_promises30.default.writeFile(
29811
+ await import_promises31.default.writeFile(
29433
29812
  diagnosisPath,
29434
29813
  `${JSON.stringify(diagnosis, null, 2)}
29435
29814
  `,
@@ -29450,7 +29829,7 @@ var init_runtimeScorecard2 = __esm({
29450
29829
  composition: verifiedRelease?.manifest.composition,
29451
29830
  sourceArtifacts: await Promise.all(
29452
29831
  sourcePaths.map(async (sourcePath) => ({
29453
- artifactId: import_node_path27.default.basename(sourcePath),
29832
+ artifactId: import_node_path28.default.basename(sourcePath),
29454
29833
  path: sourcePath,
29455
29834
  sha256: await sha256File2(sourcePath)
29456
29835
  }))
@@ -29461,11 +29840,11 @@ var init_runtimeScorecard2 = __esm({
29461
29840
  let receiptPath2 = null;
29462
29841
  if (flags29.markProcessed) {
29463
29842
  const runtimeEvidenceBundle = await verifyRuntimeEvidenceBundle(
29464
- import_node_path27.default.dirname(runtimeEvidencePath)
29843
+ import_node_path28.default.dirname(runtimeEvidencePath)
29465
29844
  );
29466
29845
  const feedbackSource = replayEvidencePath ? await verifyRuntimeFeedbackReplaySource({
29467
- bundleDir: import_node_path27.default.dirname(replayEvidencePath),
29468
- runtimeEvidenceBundleDir: import_node_path27.default.dirname(runtimeEvidencePath)
29846
+ bundleDir: import_node_path28.default.dirname(replayEvidencePath),
29847
+ runtimeEvidenceBundleDir: import_node_path28.default.dirname(runtimeEvidencePath)
29469
29848
  }).catch((error) => {
29470
29849
  if (runtimeEvidenceBundle.artifact.producer) throw error;
29471
29850
  return null;
@@ -29476,9 +29855,9 @@ var init_runtimeScorecard2 = __esm({
29476
29855
  );
29477
29856
  }
29478
29857
  receiptPath2 = await markRuntimeEvidenceBundleProcessed({
29479
- evidenceRoot: import_node_path27.default.resolve(projectRoot13, String(flags29.evidenceDir)),
29858
+ evidenceRoot: import_node_path28.default.resolve(projectRoot13, String(flags29.evidenceDir)),
29480
29859
  deploymentId: String(flags29.deployment),
29481
- bundleDir: import_node_path27.default.dirname(runtimeEvidencePath),
29860
+ bundleDir: import_node_path28.default.dirname(runtimeEvidencePath),
29482
29861
  scorecardPath: outPath,
29483
29862
  runtimeFeedback: feedbackSource ? {
29484
29863
  artifactId: feedbackSource.feedback.manifest.artifactId,
@@ -29675,14 +30054,14 @@ __export(strategyRelease_exports, {
29675
30054
  main: () => main40,
29676
30055
  runStrategyReleaseCommand: () => runStrategyReleaseCommand
29677
30056
  });
29678
- var import_promises31, import_node_fs5, import_node_readline2, import_node_path28, import_chalk44, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main40;
30057
+ var import_promises32, import_node_fs5, import_node_readline2, import_node_path29, import_chalk44, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main40;
29679
30058
  var init_strategyRelease2 = __esm({
29680
30059
  "src/scripts/strategyRelease.ts"() {
29681
30060
  "use strict";
29682
- import_promises31 = __toESM(require("fs/promises"));
30061
+ import_promises32 = __toESM(require("fs/promises"));
29683
30062
  import_node_fs5 = require("fs");
29684
30063
  import_node_readline2 = require("readline");
29685
- import_node_path28 = __toESM(require("path"));
30064
+ import_node_path29 = __toESM(require("path"));
29686
30065
  import_chalk44 = __toESM(require("chalk"));
29687
30066
  init_strategyRelease();
29688
30067
  valueAfter2 = (argv2, name) => {
@@ -29695,17 +30074,17 @@ var init_strategyRelease2 = __esm({
29695
30074
  };
29696
30075
  writeJsonAtomic3 = async (filePath, value) => {
29697
30076
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
29698
- await import_promises31.default.mkdir(import_node_path28.default.dirname(filePath), { recursive: true });
29699
- await import_promises31.default.writeFile(
30077
+ await import_promises32.default.mkdir(import_node_path29.default.dirname(filePath), { recursive: true });
30078
+ await import_promises32.default.writeFile(
29700
30079
  temporaryPath,
29701
30080
  `${JSON.stringify(value, null, 2)}
29702
30081
  `,
29703
30082
  "utf8"
29704
30083
  );
29705
- await import_promises31.default.rename(temporaryPath, filePath);
30084
+ await import_promises32.default.rename(temporaryPath, filePath);
29706
30085
  };
29707
30086
  runStrategyReleaseCommand = async (options) => {
29708
- const inputPath = import_node_path28.default.resolve(options.inputPath);
30087
+ const inputPath = import_node_path29.default.resolve(options.inputPath);
29709
30088
  if (options.command === "verify") {
29710
30089
  const envelope = await verifyStrategyReleaseEnvelope(inputPath);
29711
30090
  return {
@@ -29743,7 +30122,7 @@ var init_strategyRelease2 = __esm({
29743
30122
  endTime,
29744
30123
  days: options.days?.length ? options.days : [7, 30, 90]
29745
30124
  });
29746
- const outputPath = import_node_path28.default.resolve(
30125
+ const outputPath = import_node_path29.default.resolve(
29747
30126
  options.outputPath ?? "output/strategy-monitoring-profile.json"
29748
30127
  );
29749
30128
  await writeJsonAtomic3(outputPath, profile);
@@ -29754,22 +30133,22 @@ var init_strategyRelease2 = __esm({
29754
30133
  profile
29755
30134
  };
29756
30135
  }
29757
- const input = JSON.parse(await import_promises31.default.readFile(inputPath, "utf8"));
30136
+ const input = JSON.parse(await import_promises32.default.readFile(inputPath, "utf8"));
29758
30137
  if (options.command === "decide") {
29759
30138
  const decision = await deriveStrategyReleaseResearchDecision(input);
29760
30139
  if (options.outputPath) {
29761
- await writeJsonAtomic3(import_node_path28.default.resolve(options.outputPath), decision);
30140
+ await writeJsonAtomic3(import_node_path29.default.resolve(options.outputPath), decision);
29762
30141
  }
29763
30142
  return {
29764
30143
  kind: "decided",
29765
30144
  ...decision,
29766
- outputPath: options.outputPath ? import_node_path28.default.resolve(options.outputPath) : null
30145
+ outputPath: options.outputPath ? import_node_path29.default.resolve(options.outputPath) : null
29767
30146
  };
29768
30147
  }
29769
30148
  if (options.command === "retention") {
29770
30149
  const plan = planStrategyEvidenceRetention(input);
29771
30150
  if (options.apply) {
29772
- await Promise.all(plan.delete.map((entry) => import_promises31.default.rm(entry.path)));
30151
+ await Promise.all(plan.delete.map((entry) => import_promises32.default.rm(entry.path)));
29773
30152
  }
29774
30153
  return {
29775
30154
  kind: "retention",
@@ -29782,12 +30161,12 @@ var init_strategyRelease2 = __esm({
29782
30161
  }
29783
30162
  if (options.command === "diagnose") {
29784
30163
  const diagnosis = buildStrategyLiveDiagnosis(input);
29785
- const outputPath = import_node_path28.default.resolve(
30164
+ const outputPath = import_node_path29.default.resolve(
29786
30165
  options.outputPath ?? "output/strategy-live-diagnosis.json"
29787
30166
  );
29788
30167
  await writeJsonAtomic3(outputPath, diagnosis);
29789
30168
  const published2 = options.rootDir ? await publishStrategyLiveDiagnosis({
29790
- rootDir: import_node_path28.default.resolve(options.rootDir),
30169
+ rootDir: import_node_path29.default.resolve(options.rootDir),
29791
30170
  diagnosis,
29792
30171
  sourceArtifacts: input.sourceArtifacts ?? []
29793
30172
  }) : null;
@@ -29804,7 +30183,7 @@ var init_strategyRelease2 = __esm({
29804
30183
  evidence: await collectReleaseEvidenceReferences(input.evidence ?? [])
29805
30184
  });
29806
30185
  const published = await publishStrategyRelease({
29807
- rootDir: import_node_path28.default.resolve(options.rootDir ?? "data/strategy-release"),
30186
+ rootDir: import_node_path29.default.resolve(options.rootDir ?? "data/strategy-release"),
29808
30187
  manifest
29809
30188
  });
29810
30189
  return {
@@ -29906,21 +30285,21 @@ var init_serverHealth = __esm({
29906
30285
  }
29907
30286
  return `${minutes}m`;
29908
30287
  };
29909
- readDiskUsage = (path41) => {
30288
+ readDiskUsage = (path42) => {
29910
30289
  try {
29911
- const stats = (0, import_node_fs6.statfsSync)(path41);
30290
+ const stats = (0, import_node_fs6.statfsSync)(path42);
29912
30291
  const totalBlocks = Number(stats.blocks ?? 0);
29913
30292
  const availableBlocks = Number(stats.bavail ?? 0);
29914
30293
  if (totalBlocks <= 0) {
29915
- return { path: path41, usedPct: null };
30294
+ return { path: path42, usedPct: null };
29916
30295
  }
29917
30296
  const usedPct = (totalBlocks - Math.max(0, availableBlocks)) / totalBlocks * 100;
29918
30297
  return {
29919
- path: path41,
30298
+ path: path42,
29920
30299
  usedPct: Number.isFinite(usedPct) ? usedPct : null
29921
30300
  };
29922
30301
  } catch {
29923
- return { path: path41, usedPct: null };
30302
+ return { path: path42, usedPct: null };
29924
30303
  }
29925
30304
  };
29926
30305
  parseMeminfoBytes = (value) => {
@@ -32028,12 +32407,12 @@ __export(runtimeParity_exports, {
32028
32407
  main: () => main42,
32029
32408
  runtimeParity: () => runtimeParity
32030
32409
  });
32031
- var import_config11, import_node_crypto16, import_args32, import_chalk46, import_constants15, import_time9, import_logger6, import_redis17, import_cli11, import_backtest3, import_connectors14, flags30, interval3, projectRoot15, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main42;
32410
+ var import_config11, import_node_crypto17, import_args32, import_chalk46, import_constants15, import_time9, import_logger6, import_redis17, import_cli11, import_backtest3, import_connectors14, flags30, interval3, projectRoot15, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main42;
32032
32411
  var init_runtimeParity2 = __esm({
32033
32412
  "src/scripts/runtimeParity.ts"() {
32034
32413
  "use strict";
32035
32414
  import_config11 = require("dotenv/config");
32036
- import_node_crypto16 = require("crypto");
32415
+ import_node_crypto17 = require("crypto");
32037
32416
  import_args32 = __toESM(require("args"));
32038
32417
  import_chalk46 = __toESM(require("chalk"));
32039
32418
  import_constants15 = require("@tradejs/core/constants");
@@ -32416,9 +32795,9 @@ var init_runtimeParity2 = __esm({
32416
32795
  start: window.start,
32417
32796
  end: window.end
32418
32797
  },
32419
- name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto16.randomUUID)().slice(0, 8)}`,
32420
- testId: (0, import_node_crypto16.randomUUID)().slice(0, 8),
32421
- testSuiteId: (0, import_node_crypto16.randomUUID)().slice(0, 8),
32798
+ name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto17.randomUUID)().slice(0, 8)}`,
32799
+ testId: (0, import_node_crypto17.randomUUID)().slice(0, 8),
32800
+ testSuiteId: (0, import_node_crypto17.randomUUID)().slice(0, 8),
32422
32801
  strategyName: target.strategy,
32423
32802
  strategyConfig: replayConfig,
32424
32803
  connectorName,
@@ -33657,6 +34036,7 @@ var init_runner = __esm({
33657
34036
  init_klineFeed();
33658
34037
  init_tickerEvaluator();
33659
34038
  init_configuredScopes();
34039
+ init_runtimeEvidenceCompositionSnapshots();
33660
34040
  SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
33661
34041
  formatDuration3 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
33662
34042
  resolvePositiveInteger2 = (value, fallback) => {
@@ -33677,6 +34057,19 @@ var init_runner = __esm({
33677
34057
  createSignalsRunner = (config2) => {
33678
34058
  const interval4 = config2.interval;
33679
34059
  const projectRoot17 = config2.projectRoot?.trim() || String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
34060
+ const compositionSnapshotRecorder = process.env.TRADEJS_PROJECT_SHA && process.env.TRADEJS_PROJECT_IMAGE_DIGEST && config2.deploymentId ? createRuntimeEvidenceCompositionSnapshotRecorder({
34061
+ persist: (compositionId) => captureRuntimeEvidenceCompositionSnapshot({
34062
+ projectRoot: projectRoot17,
34063
+ userName: config2.userName,
34064
+ deploymentId: config2.deploymentId,
34065
+ expectedCompositionId: compositionId
34066
+ }),
34067
+ onError: (compositionId, error) => import_logger10.logger.warn(
34068
+ "runtime evidence snapshot unavailable; trading continues and the next cycle will retry (composition=%s): %s",
34069
+ compositionId,
34070
+ error instanceof Error ? error.message : String(error)
34071
+ )
34072
+ }) : null;
33680
34073
  const resolveSignalsDaemonMaxLiveBars = (runtimeInterval = interval4) => {
33681
34074
  const intervalMinutes = Number(runtimeInterval);
33682
34075
  const preloadBars = Math.ceil(
@@ -34286,6 +34679,9 @@ var init_runner = __esm({
34286
34679
  if (!currentDeployment) {
34287
34680
  throw new Error(`Runtime deployment not found: ${deploymentId}`);
34288
34681
  }
34682
+ compositionSnapshotRecorder?.observe(
34683
+ currentDeployment.deploymentCompositionId
34684
+ );
34289
34685
  const scopes = await loadConfiguredSignalsScopes(currentDeployment);
34290
34686
  for (const [key, staleSession] of sessions) {
34291
34687
  if (scopes.has(key)) continue;
@@ -34575,12 +34971,12 @@ var init_cliConfig2 = __esm({
34575
34971
  });
34576
34972
 
34577
34973
  // src/lib/replay/runtimeEvidenceSource.ts
34578
- var import_promises32, import_node_path29, asRecord7, asFiniteNumber, unwrapRows2, assertRuntimeRowsMatchDeployment, readRuntimeEvidenceArtifact, loadReplayRuntimeEvidenceMetadata, buildRuntimeEvidenceLineageScopes, loadReplayRuntimeEvidenceSource;
34974
+ var import_promises33, import_node_path30, asRecord7, asFiniteNumber, unwrapRows2, assertRuntimeRowsMatchDeployment, readRuntimeEvidenceArtifact, loadReplayRuntimeEvidenceMetadata, buildRuntimeEvidenceLineageScopes, loadReplayRuntimeEvidenceSource;
34579
34975
  var init_runtimeEvidenceSource = __esm({
34580
34976
  "src/lib/replay/runtimeEvidenceSource.ts"() {
34581
34977
  "use strict";
34582
- import_promises32 = __toESM(require("fs/promises"));
34583
- import_node_path29 = __toESM(require("path"));
34978
+ import_promises33 = __toESM(require("fs/promises"));
34979
+ import_node_path30 = __toESM(require("path"));
34584
34980
  init_runtimeLineage();
34585
34981
  init_runtimeEvidenceDeployment();
34586
34982
  asRecord7 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -34611,9 +35007,9 @@ var init_runtimeEvidenceSource = __esm({
34611
35007
  filePath,
34612
35008
  projectRoot: projectRoot17
34613
35009
  }) => {
34614
- const resolvedPath = import_node_path29.default.resolve(projectRoot17, filePath);
35010
+ const resolvedPath = import_node_path30.default.resolve(projectRoot17, filePath);
34615
35011
  const root = asRecord7(
34616
- JSON.parse(await import_promises32.default.readFile(resolvedPath, "utf8"))
35012
+ JSON.parse(await import_promises33.default.readFile(resolvedPath, "utf8"))
34617
35013
  );
34618
35014
  const runtime = asRecord7(root?.runtime) ?? root;
34619
35015
  if (!root || !runtime) {
@@ -38285,12 +38681,12 @@ var init_runtimeComparison = __esm({
38285
38681
  });
38286
38682
 
38287
38683
  // src/lib/replay/outputReport.ts
38288
- var import_promises33, import_node_path30, import_data6, formatMsk, formatNumber5, formatMoney2, formatPct, tableCell, createMarkdownTable2, entryStrategy, entryKey, buildDrilldownMap, buildPerTradeAnalysis, renderMatchedRows, renderRuntimeOnlyRows, renderOrderFailedRows, renderBacktestOnlyRows, renderStrategyRows, renderLineageRows, writeReplayOutputReport;
38684
+ var import_promises34, import_node_path31, import_data6, formatMsk, formatNumber5, formatMoney2, formatPct, tableCell, createMarkdownTable2, entryStrategy, entryKey, buildDrilldownMap, buildPerTradeAnalysis, renderMatchedRows, renderRuntimeOnlyRows, renderOrderFailedRows, renderBacktestOnlyRows, renderStrategyRows, renderLineageRows, writeReplayOutputReport;
38289
38685
  var init_outputReport = __esm({
38290
38686
  "src/lib/replay/outputReport.ts"() {
38291
38687
  "use strict";
38292
- import_promises33 = __toESM(require("fs/promises"));
38293
- import_node_path30 = __toESM(require("path"));
38688
+ import_promises34 = __toESM(require("fs/promises"));
38689
+ import_node_path31 = __toESM(require("path"));
38294
38690
  import_data6 = require("@tradejs/core/data");
38295
38691
  init_support();
38296
38692
  formatMsk = (timestamp) => typeof timestamp === "number" && Number.isFinite(timestamp) ? new Intl.DateTimeFormat("ru-RU", {
@@ -38595,8 +38991,8 @@ var init_outputReport = __esm({
38595
38991
  strategySnapshot,
38596
38992
  runtimeComparison
38597
38993
  }) => {
38598
- const outputDir = import_node_path30.default.resolve(projectRoot17, "data/replay/output");
38599
- await import_promises33.default.mkdir(outputDir, { recursive: true });
38994
+ const outputDir = import_node_path31.default.resolve(projectRoot17, "data/replay/output");
38995
+ await import_promises34.default.mkdir(outputDir, { recursive: true });
38600
38996
  const perTradeAnalysis = buildPerTradeAnalysis(runtimeComparison);
38601
38997
  const report = {
38602
38998
  reportType: "replay-output",
@@ -38631,8 +39027,8 @@ var init_outputReport = __esm({
38631
39027
  runtimeComparison,
38632
39028
  perTradeAnalysis
38633
39029
  };
38634
- const markdownPath = import_node_path30.default.join(outputDir, `${timestamp}-replay-report.md`);
38635
- const jsonPath = import_node_path30.default.join(outputDir, `${timestamp}-replay-report.json`);
39030
+ const markdownPath = import_node_path31.default.join(outputDir, `${timestamp}-replay-report.md`);
39031
+ const jsonPath = import_node_path31.default.join(outputDir, `${timestamp}-replay-report.json`);
38636
39032
  const lines = [
38637
39033
  "# Replay Report",
38638
39034
  "",
@@ -38698,8 +39094,8 @@ var init_outputReport = __esm({
38698
39094
  ""
38699
39095
  ];
38700
39096
  await Promise.all([
38701
- import_promises33.default.writeFile(markdownPath, lines.join("\n"), "utf8"),
38702
- import_promises33.default.writeFile(jsonPath, `${(0, import_data6.toJson)(report, true)}
39097
+ import_promises34.default.writeFile(markdownPath, lines.join("\n"), "utf8"),
39098
+ import_promises34.default.writeFile(jsonPath, `${(0, import_data6.toJson)(report, true)}
38703
39099
  `, "utf8")
38704
39100
  ]);
38705
39101
  return {