@tradejs/cli 3.1.29-beta.297 → 3.1.29-beta.299

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
@@ -454,10 +454,10 @@ var init_charts = __esm({
454
454
  const span = Math.max(1e-9, maxY - minY), x = (time2) => 72 + 852 * (time2 - minX) / Math.max(1, maxX - minX), y = (value) => 238 - 196 * (value - minY) / span;
455
455
  const paths = populated.map((item) => {
456
456
  const points = sampleResearchCurve(item.points);
457
- const path57 = points.map(
457
+ const path58 = points.map(
458
458
  ([time2, value], index) => `${index ? "H" : "M"}${x(time2).toFixed(2)}${index ? "V" : ","}${y(value).toFixed(2)}`
459
459
  ).join(" ");
460
- return `<path d="${path57}" fill="none" stroke="${escapeResearchHtml(item.color)}" stroke-width="2.5" stroke-linejoin="round"/>`;
460
+ return `<path d="${path58}" fill="none" stroke="${escapeResearchHtml(item.color)}" stroke-width="2.5" stroke-linejoin="round"/>`;
461
461
  }).join("");
462
462
  return `<figure class="chart"><figcaption>${escapeResearchHtml(title)}</figcaption><svg viewBox="0 0 960 285" role="img" aria-label="${escapeResearchHtml(title)}"><title>${escapeResearchHtml(title)}</title>${[
463
463
  4
@@ -526,7 +526,7 @@ function pricePanel(t, c, step, x, y, w, h) {
526
526
  ["bbLower", "#8898ab"]
527
527
  ]) {
528
528
  let previous = null;
529
- const path57 = c.map((b) => {
529
+ const path58 = c.map((b) => {
530
530
  const v = b[key2];
531
531
  if (v == null) {
532
532
  previous = null;
@@ -536,7 +536,7 @@ function pricePanel(t, c, step, x, y, w, h) {
536
536
  previous = b.timestamp;
537
537
  return `${command}${X(b.timestamp)},${Y(v)}`;
538
538
  }).join(" ");
539
- s += `<path d="${path57}" fill="none" stroke="${color}" stroke-width="1.4"/>`;
539
+ s += `<path d="${path58}" fill="none" stroke="${color}" stroke-width="1.4"/>`;
540
540
  }
541
541
  for (const line of t.figures.lines)
542
542
  s += `<polyline points="${line.points.map((p) => `${X(p.timestamp)},${Y(p.value)}`).join(" ")}" fill="none" stroke="#0284c7" stroke-width="2"/>`;
@@ -3822,9 +3822,9 @@ var init_features = __esm({
3822
3822
  "targetsymbol",
3823
3823
  "universe"
3824
3824
  ]);
3825
- normalizeFeaturePath = (path57) => (Array.isArray(path57) ? path57 : path57.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
3826
- classifyAiPocketCoverageFeaturePath = (path57) => {
3827
- const segments = normalizeFeaturePath(path57);
3825
+ normalizeFeaturePath = (path58) => (Array.isArray(path58) ? path58 : path58.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
3826
+ classifyAiPocketCoverageFeaturePath = (path58) => {
3827
+ const segments = normalizeFeaturePath(path58);
3828
3828
  const normalizedPath = segments.join(".");
3829
3829
  if (segments.some(
3830
3830
  (segment) => segment.includes("cmc") || segment.includes("coinmarketcap")
@@ -3998,8 +3998,8 @@ var init_features = __esm({
3998
3998
  "volumeusd",
3999
3999
  "vwap"
4000
4000
  ]);
4001
- classifyAiPocketFeaturePath = (path57) => {
4002
- const segments = (Array.isArray(path57) ? path57 : path57.split(".")).filter(
4001
+ classifyAiPocketFeaturePath = (path58) => {
4002
+ const segments = (Array.isArray(path58) ? path58 : path58.split(".")).filter(
4003
4003
  Boolean
4004
4004
  );
4005
4005
  const normalized = segments.map((segment) => segment.toLowerCase());
@@ -4329,11 +4329,11 @@ var init_features = __esm({
4329
4329
  excludeFeaturePattern.source,
4330
4330
  excludeFeaturePattern.flags.replace(/[gy]/g, "")
4331
4331
  ) : void 0;
4332
- const isOperatorExcluded = (path57) => {
4333
- if (!exclusion?.test(path57)) {
4332
+ const isOperatorExcluded = (path58) => {
4333
+ if (!exclusion?.test(path58)) {
4334
4334
  return false;
4335
4335
  }
4336
- onFeatureExcluded?.({ path: path57, classification: "operator-excluded" });
4336
+ onFeatureExcluded?.({ path: path58, classification: "operator-excluded" });
4337
4337
  return true;
4338
4338
  };
4339
4339
  const signal = payload.signal ?? {};
@@ -4416,15 +4416,15 @@ var init_features = __esm({
4416
4416
  if (registered) {
4417
4417
  (0, import_aiFeatures.validateAiFeatureSnapshot)(registered);
4418
4418
  for (const definition of registered.definitions) {
4419
- const path57 = `registered.${definition.id}`;
4420
- if (isOperatorExcluded(path57)) continue;
4419
+ const path58 = `registered.${definition.id}`;
4420
+ if (isOperatorExcluded(path58)) continue;
4421
4421
  const value = registered.values[definition.id];
4422
4422
  const classification = definition.role === "outcome" || definition.role === "policy" ? "derived-policy" : definition.role !== "input" ? definition.role : featurePolicy === "causal-stationary" && !definition.stationary ? "raw-nonstationary" : value === null || value === "unknown" ? "data-quality" : "eligible";
4423
4423
  if (classification !== "eligible") {
4424
- onFeatureExcluded?.({ path: path57, classification });
4424
+ onFeatureExcluded?.({ path: path58, classification });
4425
4425
  continue;
4426
4426
  }
4427
- features[path57] = value;
4427
+ features[path58] = value;
4428
4428
  }
4429
4429
  }
4430
4430
  return { features, featureCoverage };
@@ -8543,7 +8543,7 @@ var init_command = __esm({
8543
8543
  options.testSince
8544
8544
  );
8545
8545
  const sources = await Promise.all(
8546
- filePaths.map(async (path57) => ({ path: path57, sha256: await sha256File(path57) }))
8546
+ filePaths.map(async (path58) => ({ path: path58, sha256: await sha256File(path58) }))
8547
8547
  );
8548
8548
  const dataset = await evaluateAiPocketSearchDataset({
8549
8549
  prepared: preparedDataset,
@@ -13595,27 +13595,27 @@ var init_coinMarketCapContextBackfill = __esm({
13595
13595
  totalCredits: 0,
13596
13596
  byPath: /* @__PURE__ */ new Map()
13597
13597
  });
13598
- getCoinMarketCapPathLabel = (path57) => {
13599
- if (path57.includes("global-metrics")) return "global";
13600
- if (path57.includes("cryptocurrency/quotes")) return "reference";
13601
- if (path57.includes("exchange/quotes")) return "exchangeLiquidity";
13602
- if (path57.includes("fear-and-greed")) return "fearGreed";
13603
- if (path57.includes("cmc100")) return "cmc100";
13604
- if (path57.includes("cmc20")) return "cmc20";
13605
- return path57;
13606
- };
13607
- recordCoinMarketCapFetchStats = (stats, path57, creditCount) => {
13598
+ getCoinMarketCapPathLabel = (path58) => {
13599
+ if (path58.includes("global-metrics")) return "global";
13600
+ if (path58.includes("cryptocurrency/quotes")) return "reference";
13601
+ if (path58.includes("exchange/quotes")) return "exchangeLiquidity";
13602
+ if (path58.includes("fear-and-greed")) return "fearGreed";
13603
+ if (path58.includes("cmc100")) return "cmc100";
13604
+ if (path58.includes("cmc20")) return "cmc20";
13605
+ return path58;
13606
+ };
13607
+ recordCoinMarketCapFetchStats = (stats, path58, creditCount) => {
13608
13608
  if (!stats) return;
13609
- const existing = stats.byPath.get(path57) ?? { requests: 0, credits: 0 };
13609
+ const existing = stats.byPath.get(path58) ?? { requests: 0, credits: 0 };
13610
13610
  existing.requests += 1;
13611
13611
  existing.credits += creditCount ?? 0;
13612
13612
  stats.requests += 1;
13613
13613
  stats.totalCredits += creditCount ?? 0;
13614
- stats.byPath.set(path57, existing);
13614
+ stats.byPath.set(path58, existing);
13615
13615
  };
13616
13616
  formatCoinMarketCapFetchStats = (stats) => {
13617
13617
  const byPath = [...stats.byPath.entries()].map(
13618
- ([path57, item]) => `${getCoinMarketCapPathLabel(path57)}=${item.requests}req/${item.credits}cr`
13618
+ ([path58, item]) => `${getCoinMarketCapPathLabel(path58)}=${item.requests}req/${item.credits}cr`
13619
13619
  ).join(" ");
13620
13620
  return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
13621
13621
  };
@@ -17435,8 +17435,14 @@ var init_backtest = __esm({
17435
17435
  console.log(import_chalk15.default.gray(`full report: ${markdownReportPath}`));
17436
17436
  console.log("");
17437
17437
  if (!isFastMode || flags5.persistResults) {
17438
- await (0, import_redis8.setData)(
17439
- import_redis8.redisKeys.backtestResults(userName, flags5.config, timestamp),
17438
+ const mcpTimestamp = process.env.MCP_WORKER === "true" ? process.env.MCP_BACKTEST_RESULT_TIMESTAMP : void 0;
17439
+ const saveResult = mcpTimestamp ? import_redis8.setDataStrict : import_redis8.setData;
17440
+ await saveResult(
17441
+ import_redis8.redisKeys.backtestResults(
17442
+ userName,
17443
+ flags5.config,
17444
+ mcpTimestamp ?? timestamp
17445
+ ),
17440
17446
  {
17441
17447
  config: flags5.config,
17442
17448
  mode: "config",
@@ -26064,13 +26070,16 @@ async function fetchTarget(userName3, request, target, loaded) {
26064
26070
  const interval4 = dataset.interval;
26065
26071
  const missing = (time2) => time2 >= day && time2 < end && !loaded.has(time2);
26066
26072
  if (dataset.provider === "CoinMarketCap") {
26067
- await backfillCoinMarketCapContext({
26073
+ const params = {
26068
26074
  userName: userName3,
26069
26075
  startMs: day,
26070
26076
  preloadStartMs: day,
26071
26077
  endMs: end,
26072
26078
  repairDataset: dataset.id
26073
- });
26079
+ };
26080
+ if (resolveCoinMarketCapBackfillWindow(params).fromMs > day)
26081
+ return "outside_configured_history";
26082
+ await backfillCoinMarketCapContext(params);
26074
26083
  return;
26075
26084
  }
26076
26085
  if (dataset.provider === "Coinalyze") {
@@ -26079,7 +26088,7 @@ async function fetchTarget(userName3, request, target, loaded) {
26079
26088
  userName3,
26080
26089
  series
26081
26090
  );
26082
- if (!marketSymbol) return;
26091
+ if (!marketSymbol) return "no_matching_market";
26083
26092
  const { derivativesRows = [] } = await import_connectors11.marketDataProviders.coinalyze.fetchWindow({
26084
26093
  symbol: series,
26085
26094
  marketSymbol,
@@ -26171,8 +26180,7 @@ async function fetchTarget(userName3, request, target, loaded) {
26171
26180
  const universe = (0, import_strategies11.getBinanceBreadthUniverses)().find(
26172
26181
  (item) => item.universe === series
26173
26182
  );
26174
- if (!universe)
26175
- throw new Error("The historical Binance basket is unavailable.");
26183
+ if (!universe) return "historical_basket_unavailable";
26176
26184
  const candlesBySymbol = {};
26177
26185
  const warmup = day - 2 * DAY_MS11;
26178
26186
  for (let offset = 0; offset < universe.symbols.length; offset += 4) {
@@ -26201,14 +26209,16 @@ async function main17() {
26201
26209
  );
26202
26210
  await (0, import_client5.waitForDbReady)();
26203
26211
  const before = await (0, import_dataCoverage.readDataBackfillSlots)(request, target.end);
26204
- if (before.loaded.size < before.expected)
26205
- await fetchTarget(userName3, request, target, before.loaded);
26212
+ const outcome = before.loaded.size < before.expected ? await fetchTarget(userName3, request, target, before.loaded) : void 0;
26206
26213
  const after = await (0, import_dataCoverage.readDataBackfillSlots)(request, target.end);
26207
26214
  const result = {
26208
26215
  loaded: after.loaded.size,
26209
26216
  added: Math.max(0, after.loaded.size - before.loaded.size),
26210
26217
  missing: Math.max(0, after.expected - after.loaded.size)
26211
26218
  };
26219
+ if (result.missing) {
26220
+ result.outcome = outcome ?? (result.added ? "some_missing_slots_filled" : "no_missing_slots_filled");
26221
+ }
26212
26222
  console.log(`TRADEJS_DATA_BACKFILL ${JSON.stringify(result)}`);
26213
26223
  }
26214
26224
  var import_connectors11, import_candles3, import_client5, import_dataCoverage, import_derivatives2, import_marketContext5, import_spread, import_strategies11, DAY_MS11;
@@ -28446,12 +28456,11 @@ var init_runtimeEvidenceArtifacts = __esm({
28446
28456
  });
28447
28457
 
28448
28458
  // src/lib/mcpReplayProcess.ts
28449
- var import_node_path19, import_node_crypto14, import_promises22, client, buildMcpReplayProcess;
28459
+ var import_node_path19, import_promises22, client, buildMcpReplayProcess;
28450
28460
  var init_mcpReplayProcess = __esm({
28451
28461
  "src/lib/mcpReplayProcess.ts"() {
28452
28462
  "use strict";
28453
28463
  import_node_path19 = __toESM(require("path"));
28454
- import_node_crypto14 = require("crypto");
28455
28464
  import_promises22 = __toESM(require("fs/promises"));
28456
28465
  init_runtimeEvidenceArtifacts();
28457
28466
  client = `
@@ -28492,6 +28501,7 @@ const timer = setInterval(() => {
28492
28501
  `;
28493
28502
  buildMcpReplayProcess = async ({
28494
28503
  evidencePath,
28504
+ expectedEvidenceSha256,
28495
28505
  outDir,
28496
28506
  runId,
28497
28507
  projectRoot: projectRoot18,
@@ -28502,6 +28512,9 @@ const timer = setInterval(() => {
28502
28512
  const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path19.default.dirname(evidencePath));
28503
28513
  if (import_node_path19.default.resolve(evidencePath) !== import_node_path19.default.resolve(bundle.payloadPath))
28504
28514
  throw new Error("Replay requires the verified bundle payload");
28515
+ const payloadSha256 = bundle.manifest.payload.sha256;
28516
+ if (expectedEvidenceSha256 && expectedEvidenceSha256 !== payloadSha256)
28517
+ throw new Error("Runtime evidence changed since job submission");
28505
28518
  const relative = import_node_path19.default.relative(import_node_path19.default.join(projectRoot18, "data"), evidencePath);
28506
28519
  if (relative.startsWith("..") || import_node_path19.default.isAbsolute(relative))
28507
28520
  throw new Error("Evidence must be inside Project data");
@@ -28511,14 +28524,13 @@ const timer = setInterval(() => {
28511
28524
  );
28512
28525
  if (heartbeat.protocolVersion !== 2 || !Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
28513
28526
  throw new Error("Host replay runner heartbeat is stale");
28514
- const bytes = await import_promises22.default.readFile(evidencePath);
28515
28527
  const request = JSON.stringify({
28516
28528
  schemaVersion: 1,
28517
28529
  id: runId,
28518
28530
  evidence: relative,
28519
28531
  artifactId: bundle.manifest.artifactId,
28520
28532
  deploymentId: bundle.manifest.deploymentId,
28521
- payloadSha256: (0, import_node_crypto14.createHash)("sha256").update(bytes).digest("hex")
28533
+ payloadSha256
28522
28534
  });
28523
28535
  void outDir;
28524
28536
  return {
@@ -28529,28 +28541,123 @@ const timer = setInterval(() => {
28529
28541
  }
28530
28542
  });
28531
28543
 
28544
+ // src/lib/mcpJobOutputs.ts
28545
+ var import_promises23, import_node_path20, import_redis16, import_diagnostics, import_mcp, mcpBacktestResultTimestamp, collectEvidence, collectReplay, collectMcpJobOutputs;
28546
+ var init_mcpJobOutputs = __esm({
28547
+ "src/lib/mcpJobOutputs.ts"() {
28548
+ "use strict";
28549
+ import_promises23 = require("fs/promises");
28550
+ import_node_path20 = __toESM(require("path"));
28551
+ import_redis16 = require("@tradejs/infra/redis");
28552
+ import_diagnostics = require("@tradejs/node/diagnostics");
28553
+ import_mcp = require("@tradejs/node/mcp");
28554
+ init_runFormatting();
28555
+ mcpBacktestResultTimestamp = (job) => createTimestamp(new Date(job.createdAt));
28556
+ collectEvidence = async (job) => Promise.all(
28557
+ (await (0, import_diagnostics.discoverRuntimeEvidenceBundles)((0, import_mcp.mcpJobDirectory)(job))).map(
28558
+ async (bundleDir) => {
28559
+ const { manifest } = await (0, import_diagnostics.verifyRuntimeEvidenceBundle)(bundleDir);
28560
+ if (manifest.userName !== job.userName || manifest.deploymentId !== job.request.deploymentId || manifest.window.startTime !== job.request.startTime || manifest.window.endTime !== job.request.endTime)
28561
+ throw new Error("Runtime evidence does not match the job");
28562
+ return {
28563
+ bundleDir,
28564
+ id: (0, import_mcp.mcpId)(`${manifest.artifactId}:${manifest.payload.sha256}`)
28565
+ };
28566
+ }
28567
+ )
28568
+ );
28569
+ collectReplay = async (job) => {
28570
+ const sourceDir = import_node_path20.default.dirname(String(job.request.verifiedEvidencePath));
28571
+ const source = await (0, import_diagnostics.verifyRuntimeEvidenceBundle)(sourceDir);
28572
+ const { artifactId, deploymentId, userName: userName3, window } = source.manifest;
28573
+ if (userName3 !== job.userName || deploymentId !== job.request.deploymentId || job.request.verifiedEvidenceSha256 !== void 0 && job.request.verifiedEvidenceSha256 !== source.manifest.payload.sha256 || !/^[A-Za-z0-9._-]+$/.test(artifactId) || !/^[A-Za-z0-9._-]+$/.test(deploymentId) || [".", ".."].includes(artifactId) || [".", ".."].includes(deploymentId))
28574
+ throw new Error("Runtime evidence does not match the replay job");
28575
+ const root = import_node_path20.default.join((0, import_mcp.mcpProjectRoot)(), "data/runtime-feedback");
28576
+ const receipt = JSON.parse(
28577
+ await (0, import_promises23.readFile)(
28578
+ import_node_path20.default.join(root, "completed", deploymentId, `${artifactId}.json`),
28579
+ "utf8"
28580
+ )
28581
+ );
28582
+ if (!(0, import_mcp.isMcpRecord)(receipt) || receipt.schemaVersion !== 1 || receipt.runtimeEvidenceArtifactId !== artifactId || typeof receipt.runtimeFeedbackBundle !== "string")
28583
+ throw new Error("Invalid replay completion receipt");
28584
+ const runId = import_node_path20.default.basename(receipt.runtimeFeedbackBundle);
28585
+ if (!/^[A-Za-z0-9_-]+$/.test(runId))
28586
+ throw new Error("Invalid replay bundle name");
28587
+ const day = new Date(window.endTime).toISOString().slice(0, 10).split("-");
28588
+ const bundleDir = import_node_path20.default.join(
28589
+ root,
28590
+ "ready",
28591
+ deploymentId,
28592
+ ...day,
28593
+ artifactId,
28594
+ runId
28595
+ );
28596
+ const { feedback } = await (0, import_diagnostics.verifyRuntimeFeedbackReplaySource)({
28597
+ bundleDir,
28598
+ runtimeEvidenceBundleDir: sourceDir
28599
+ });
28600
+ const { manifest } = feedback;
28601
+ return [
28602
+ {
28603
+ bundleDir,
28604
+ id: (0, import_mcp.mcpId)(
28605
+ `${manifest.artifactId}:${manifest.payloads.replayEvidence.sha256}`
28606
+ )
28607
+ }
28608
+ ];
28609
+ };
28610
+ collectMcpJobOutputs = async (job) => {
28611
+ if (job.kind === "backtest") {
28612
+ const config2 = job.request.frozenConfigId;
28613
+ if (typeof config2 !== "string")
28614
+ throw new Error("Invalid frozen backtest config");
28615
+ const timestamp = mcpBacktestResultTimestamp(job);
28616
+ if (!await (0, import_redis16.getDataStrict)(
28617
+ import_redis16.redisKeys.backtestResults(job.userName, config2, timestamp)
28618
+ ))
28619
+ throw new Error("Backtest result was not saved");
28620
+ return { resultId: `${config2}:${timestamp}` };
28621
+ }
28622
+ const bundles = job.kind === "runtime-evidence" ? await collectEvidence(job) : await collectReplay(job);
28623
+ if (!bundles.length)
28624
+ throw new Error("No verified diagnostic report was saved");
28625
+ for (const { id, bundleDir } of bundles) {
28626
+ if (!await import_redis16.mcpStorage.put(
28627
+ (0, import_mcp.mcpArtifactLocationId)(job.userName, id),
28628
+ bundleDir,
28629
+ import_mcp.MCP_JOB_TTL
28630
+ ))
28631
+ throw new Error("Diagnostic report location could not be saved");
28632
+ }
28633
+ return { artifactIds: bundles.map(({ id }) => id) };
28634
+ };
28635
+ }
28636
+ });
28637
+
28532
28638
  // src/scripts/mcpWorker.ts
28533
28639
  var mcpWorker_exports = {};
28534
28640
  __export(mcpWorker_exports, {
28535
28641
  main: () => main29
28536
28642
  });
28537
- var import_node_child_process4, import_node_crypto15, import_promises23, import_redis16, import_mcp, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main29;
28643
+ var import_node_child_process4, import_node_crypto14, import_promises24, import_redis17, import_mcp2, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main29;
28538
28644
  var init_mcpWorker = __esm({
28539
28645
  "src/scripts/mcpWorker.ts"() {
28540
28646
  "use strict";
28541
28647
  import_node_child_process4 = require("child_process");
28542
- import_node_crypto15 = require("crypto");
28543
- import_promises23 = require("fs/promises");
28544
- import_redis16 = require("@tradejs/infra/redis");
28545
- import_mcp = require("@tradejs/node/mcp");
28648
+ import_node_crypto14 = require("crypto");
28649
+ import_promises24 = require("fs/promises");
28650
+ import_redis17 = require("@tradejs/infra/redis");
28651
+ import_mcp2 = require("@tradejs/node/mcp");
28546
28652
  init_mcpReplayProcess();
28653
+ init_mcpJobOutputs();
28547
28654
  pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28548
28655
  leaseKey = "worker:lease";
28549
28656
  LEASE_SECONDS = 15;
28550
28657
  JOB_TIMEOUT_MS = 60 * 60 * 1e3;
28551
28658
  main29 = async (options = {}) => {
28552
- const owner = (0, import_node_crypto15.randomUUID)();
28553
- if (!await import_redis16.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
28659
+ const owner = (0, import_node_crypto14.randomUUID)();
28660
+ if (!await import_redis17.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
28554
28661
  throw new Error("Another MCP worker owns this storage");
28555
28662
  let stopping = false;
28556
28663
  let child;
@@ -28565,7 +28672,7 @@ var init_mcpWorker = __esm({
28565
28672
  try {
28566
28673
  const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
28567
28674
  const heartbeat2 = JSON.parse(
28568
- await (0, import_promises23.readFile)(`${root}/heartbeat.json`, "utf8")
28675
+ await (0, import_promises24.readFile)(`${root}/heartbeat.json`, "utf8")
28569
28676
  );
28570
28677
  replayReady = heartbeat2.protocolVersion === 2 && Number.isFinite(heartbeat2.observedAt) && Date.now() - heartbeat2.observedAt >= 0 && Date.now() - heartbeat2.observedAt < 12e4;
28571
28678
  replayReadiness = replayReady && (heartbeat2.readiness === "ready" || heartbeat2.readiness === "waiting_resources") ? heartbeat2.readiness : "unknown";
@@ -28614,10 +28721,10 @@ var init_mcpWorker = __esm({
28614
28721
  if (renewing || leaseLost) return;
28615
28722
  renewing = true;
28616
28723
  try {
28617
- if (!await import_redis16.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
28724
+ if (!await import_redis17.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
28618
28725
  throw new Error("Worker lease lost");
28619
28726
  await updateReplayReady();
28620
- await import_redis16.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
28727
+ await import_redis17.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
28621
28728
  } catch {
28622
28729
  leaseLost = true;
28623
28730
  stop();
@@ -28626,17 +28733,17 @@ var init_mcpWorker = __esm({
28626
28733
  }
28627
28734
  }, 2e3);
28628
28735
  try {
28629
- manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
28736
+ manifestHash = await (0, import_mcp2.mcpPackageManifestHash)();
28630
28737
  await updateReplayReady();
28631
- await import_redis16.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
28738
+ await import_redis17.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
28632
28739
  let cursor = "0";
28633
28740
  do {
28634
- const page = await import_redis16.mcpStorage.scan("jobs:", cursor);
28741
+ const page = await import_redis17.mcpStorage.scan("jobs:", cursor);
28635
28742
  cursor = page.cursor;
28636
28743
  for (const key2 of page.ids) {
28637
- const job = await import_redis16.mcpStorage.get(key2);
28744
+ const job = await import_redis17.mcpStorage.get(key2);
28638
28745
  if (job?.status === "running")
28639
- await import_redis16.mcpStorage.compare(
28746
+ await import_redis17.mcpStorage.compare(
28640
28747
  key2,
28641
28748
  job,
28642
28749
  {
@@ -28646,7 +28753,7 @@ var init_mcpWorker = __esm({
28646
28753
  finishedAt: Date.now(),
28647
28754
  updatedAt: Date.now()
28648
28755
  },
28649
- import_mcp.MCP_JOB_TTL
28756
+ import_mcp2.MCP_JOB_TTL
28650
28757
  );
28651
28758
  }
28652
28759
  } while (cursor !== "0" && !stopping);
@@ -28657,10 +28764,10 @@ var init_mcpWorker = __esm({
28657
28764
  let queued;
28658
28765
  cursor = "0";
28659
28766
  do {
28660
- const page = await import_redis16.mcpStorage.scan("jobs:", cursor);
28767
+ const page = await import_redis17.mcpStorage.scan("jobs:", cursor);
28661
28768
  cursor = page.cursor;
28662
28769
  for (const key2 of page.ids) {
28663
- const job = await import_redis16.mcpStorage.get(key2);
28770
+ const job = await import_redis17.mcpStorage.get(key2);
28664
28771
  if (job && ["queued", "waiting_resources", "waiting_executor"].includes(
28665
28772
  job.status
28666
28773
  ) && (!queued || job.createdAt < queued.createdAt))
@@ -28671,17 +28778,17 @@ var init_mcpWorker = __esm({
28671
28778
  await pause(1e3);
28672
28779
  continue;
28673
28780
  }
28674
- const jobKey = (0, import_mcp.mcpJobStorageId)(queued.userName, queued.id);
28781
+ const jobKey = (0, import_mcp2.mcpJobStorageId)(queued.userName, queued.id);
28675
28782
  const started = {
28676
28783
  ...queued,
28677
28784
  status: queued.kind === "runtime-feedback-replay" ? "waiting_executor" : "running",
28678
28785
  ...queued.kind === "runtime-feedback-replay" ? {} : { startedAt: Date.now() },
28679
28786
  updatedAt: Date.now()
28680
28787
  };
28681
- if (!await import_redis16.mcpStorage.compare(jobKey, queued, started, import_mcp.MCP_JOB_TTL))
28788
+ if (!await import_redis17.mcpStorage.compare(jobKey, queued, started, import_mcp2.MCP_JOB_TTL))
28682
28789
  continue;
28683
28790
  if (started.kind !== "runtime-feedback-replay" && started.packageManifestSha256 !== manifestHash) {
28684
- await import_redis16.mcpStorage.compare(
28791
+ await import_redis17.mcpStorage.compare(
28685
28792
  jobKey,
28686
28793
  started,
28687
28794
  {
@@ -28690,19 +28797,19 @@ var init_mcpWorker = __esm({
28690
28797
  error: "Package composition changed since submission",
28691
28798
  finishedAt: Date.now()
28692
28799
  },
28693
- import_mcp.MCP_JOB_TTL
28800
+ import_mcp2.MCP_JOB_TTL
28694
28801
  );
28695
28802
  continue;
28696
28803
  }
28697
- await (0, import_promises23.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
28804
+ await (0, import_promises24.mkdir)((0, import_mcp2.mcpJobDirectory)(started), { recursive: true });
28698
28805
  if (started.kind === "backtest")
28699
- await (0, import_redis16.setDataStrict)(
28700
- import_redis16.redisKeys.backtestConfig(
28806
+ await (0, import_redis17.setDataStrict)(
28807
+ import_redis17.redisKeys.backtestConfig(
28701
28808
  started.userName,
28702
28809
  String(started.request.frozenConfigId)
28703
28810
  ),
28704
28811
  started.request.resolvedConfig,
28705
- { expire: import_mcp.MCP_JOB_TTL }
28812
+ { expire: import_mcp2.MCP_JOB_TTL }
28706
28813
  );
28707
28814
  const jobEnv = {
28708
28815
  ...process.env,
@@ -28715,6 +28822,8 @@ var init_mcpWorker = __esm({
28715
28822
  MAKE_ORDERS: "false",
28716
28823
  TRADEJS_EXTERNAL_ORDER_PLACEMENT: "false"
28717
28824
  };
28825
+ if (started.kind === "backtest")
28826
+ jobEnv.MCP_BACKTEST_RESULT_TIMESTAMP = mcpBacktestResultTimestamp(started);
28718
28827
  if (started.kind === "runtime-feedback-replay") {
28719
28828
  for (const name of Object.keys(jobEnv)) {
28720
28829
  if (/secret|password|token|api.?key|private.?key|cookie|credential/i.test(
@@ -28740,13 +28849,14 @@ var init_mcpWorker = __esm({
28740
28849
  if (started.kind === "runtime-feedback-replay")
28741
28850
  command = await buildMcpReplayProcess({
28742
28851
  evidencePath: String(started.request.verifiedEvidencePath),
28743
- outDir: (0, import_mcp.mcpJobDirectory)(started),
28852
+ expectedEvidenceSha256: typeof started.request.verifiedEvidenceSha256 === "string" ? started.request.verifiedEvidenceSha256 : void 0,
28853
+ outDir: (0, import_mcp2.mcpJobDirectory)(started),
28744
28854
  runId: started.id,
28745
28855
  projectRoot: process.env.PROJECT_CWD || process.cwd(),
28746
28856
  env: process.env
28747
28857
  });
28748
28858
  } catch (error) {
28749
- await import_redis16.mcpStorage.compare(
28859
+ await import_redis17.mcpStorage.compare(
28750
28860
  jobKey,
28751
28861
  started,
28752
28862
  {
@@ -28754,9 +28864,9 @@ var init_mcpWorker = __esm({
28754
28864
  status: "failed",
28755
28865
  finishedAt: Date.now(),
28756
28866
  updatedAt: Date.now(),
28757
- error: error instanceof Error ? (0, import_mcp.redactMcpJobLog)(error.message) : "Replay preparation failed"
28867
+ error: error instanceof Error ? (0, import_mcp2.redactMcpJobLog)(error.message) : "Replay preparation failed"
28758
28868
  },
28759
- import_mcp.MCP_JOB_TTL
28869
+ import_mcp2.MCP_JOB_TTL
28760
28870
  );
28761
28871
  continue;
28762
28872
  }
@@ -28776,7 +28886,7 @@ var init_mcpWorker = __esm({
28776
28886
  const logs = [];
28777
28887
  const log = (chunk) => {
28778
28888
  const lines = chunk.toString().replace(/\u001b\[[0-9;]*m/g, "").split(/[\r\n]+/).filter(Boolean);
28779
- logs.push(...lines.map(import_mcp.redactMcpJobLog));
28889
+ logs.push(...lines.map(import_mcp2.redactMcpJobLog));
28780
28890
  if (logs.length > 150) logs.splice(0, logs.length - 150);
28781
28891
  };
28782
28892
  currentChild.stdout?.on("data", log);
@@ -28784,7 +28894,7 @@ var init_mcpWorker = __esm({
28784
28894
  let killAt;
28785
28895
  const monitor = setInterval(async () => {
28786
28896
  try {
28787
- const latest = await import_redis16.mcpStorage.get(jobKey);
28897
+ const latest = await import_redis17.mcpStorage.get(jobKey);
28788
28898
  if (!latest || latest.cancelRequested || stopping || timedOut) {
28789
28899
  killAt ??= Date.now();
28790
28900
  signalChild(Date.now() - killAt > 8e3 ? "SIGKILL" : "SIGTERM");
@@ -28794,7 +28904,7 @@ var init_mcpWorker = __esm({
28794
28904
  try {
28795
28905
  const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
28796
28906
  const state = JSON.parse(
28797
- await (0, import_promises23.readFile)(`${root}/${latest.id}.state`, "utf8")
28907
+ await (0, import_promises24.readFile)(`${root}/${latest.id}.state`, "utf8")
28798
28908
  );
28799
28909
  if (state && typeof state === "object" && "status" in state && (state.status === "waiting_resources" || state.status === "waiting_executor" || state.status === "running"))
28800
28910
  replayStatus = state.status;
@@ -28809,7 +28919,7 @@ var init_mcpWorker = __esm({
28809
28919
  }
28810
28920
  }
28811
28921
  if (latest && !leaseLost)
28812
- await import_redis16.mcpStorage.compare(
28922
+ await import_redis17.mcpStorage.compare(
28813
28923
  jobKey,
28814
28924
  latest,
28815
28925
  {
@@ -28821,7 +28931,7 @@ var init_mcpWorker = __esm({
28821
28931
  logs: [...logs],
28822
28932
  updatedAt: Date.now()
28823
28933
  },
28824
- import_mcp.MCP_JOB_TTL
28934
+ import_mcp2.MCP_JOB_TTL
28825
28935
  );
28826
28936
  } catch {
28827
28937
  leaseLost = true;
@@ -28838,25 +28948,34 @@ var init_mcpWorker = __esm({
28838
28948
  clearTimeout(timeout);
28839
28949
  clearInterval(monitor);
28840
28950
  child = void 0;
28951
+ let outputs = {};
28952
+ if (!leaseLost && outcome.code === 0 && !outcome.error && !timedOut && !stopping) {
28953
+ try {
28954
+ outputs = await collectMcpJobOutputs(started);
28955
+ } catch {
28956
+ outcome.error = "Job finished but its saved output could not be verified";
28957
+ }
28958
+ }
28841
28959
  if (!leaseLost) {
28842
28960
  for (let attempt = 0; attempt < 4; attempt++) {
28843
- const latest = await import_redis16.mcpStorage.get(jobKey);
28961
+ const latest = await import_redis17.mcpStorage.get(jobKey);
28844
28962
  if (!latest) break;
28845
28963
  const cancelled = latest.cancelRequested;
28846
28964
  const next = {
28847
28965
  ...latest,
28848
28966
  logs,
28849
- status: cancelled ? "cancelled" : outcome.code === 0 && !timedOut && !stopping ? "completed" : "failed",
28967
+ status: cancelled ? "cancelled" : outcome.code === 0 && !outcome.error && !timedOut && !stopping ? "completed" : "failed",
28968
+ ...cancelled || stopping ? {} : outputs,
28850
28969
  exitCode: outcome.code,
28851
28970
  updatedAt: Date.now(),
28852
28971
  finishedAt: Date.now(),
28853
- ...cancelled ? {} : timedOut ? { error: "Job exceeded one hour" } : stopping ? { error: "Worker stopped; this job was not replayed" } : outcome.code !== 0 ? {
28972
+ ...cancelled ? {} : timedOut ? { error: "Job exceeded one hour" } : stopping ? { error: "Worker stopped; this job was not replayed" } : outcome.code !== 0 || outcome.error ? {
28854
28973
  error: outcome.error || (started.kind === "runtime-feedback-replay" ? logs.find(
28855
28974
  (line) => line.startsWith("Host replay: ")
28856
28975
  ) || logs.at(-1) : void 0) || "Research process failed"
28857
28976
  } : {}
28858
28977
  };
28859
- if (await import_redis16.mcpStorage.compare(jobKey, latest, next, import_mcp.MCP_JOB_TTL))
28978
+ if (await import_redis17.mcpStorage.compare(jobKey, latest, next, import_mcp2.MCP_JOB_TTL))
28860
28979
  break;
28861
28980
  }
28862
28981
  }
@@ -28866,8 +28985,8 @@ var init_mcpWorker = __esm({
28866
28985
  options.signal?.removeEventListener("abort", stop);
28867
28986
  process.removeListener("SIGINT", stop);
28868
28987
  process.removeListener("SIGTERM", stop);
28869
- if (await import_redis16.mcpStorage.release(leaseKey, owner))
28870
- await import_redis16.mcpStorage.remove("worker:heartbeat");
28988
+ if (await import_redis17.mcpStorage.release(leaseKey, owner))
28989
+ await import_redis17.mcpStorage.remove("worker:heartbeat");
28871
28990
  }
28872
28991
  if (leaseLost)
28873
28992
  throw new Error("Worker lease lost; active computation was stopped");
@@ -29230,13 +29349,13 @@ var hyperliquidWhalesUpdate_exports = {};
29230
29349
  __export(hyperliquidWhalesUpdate_exports, {
29231
29350
  main: () => main32
29232
29351
  });
29233
- var import_config8, import_args21, import_node_crypto16, import_strategies13, LEADERBOARD_URL, DAY_MS12, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main32;
29352
+ var import_config8, import_args21, import_node_crypto15, import_strategies13, LEADERBOARD_URL, DAY_MS12, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main32;
29234
29353
  var init_hyperliquidWhalesUpdate = __esm({
29235
29354
  "src/scripts/hyperliquidWhalesUpdate.ts"() {
29236
29355
  "use strict";
29237
29356
  import_config8 = require("dotenv/config");
29238
29357
  import_args21 = __toESM(require("args"));
29239
- import_node_crypto16 = require("crypto");
29358
+ import_node_crypto15 = require("crypto");
29240
29359
  import_strategies13 = require("@tradejs/node/strategies");
29241
29360
  init_hyperliquidWhaleBackfill();
29242
29361
  init_hyperliquidRateLimiter();
@@ -29250,7 +29369,7 @@ var init_hyperliquidWhalesUpdate = __esm({
29250
29369
  );
29251
29370
  import_args21.default.option(["d", "days"], "Calibration window in days", 7);
29252
29371
  flags19 = import_args21.default.parse(process.argv);
29253
- fingerprint = (addresses) => (0, import_node_crypto16.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
29372
+ fingerprint = (addresses) => (0, import_node_crypto15.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
29254
29373
  runConcurrent2 = async (params) => {
29255
29374
  let nextIndex = 0;
29256
29375
  await Promise.all(
@@ -29359,13 +29478,13 @@ var mlExport_exports = {};
29359
29478
  __export(mlExport_exports, {
29360
29479
  main: () => main33
29361
29480
  });
29362
- var import_args22, import_chalk37, import_promises24, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main33;
29481
+ var import_args22, import_chalk37, import_promises25, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main33;
29363
29482
  var init_mlExport = __esm({
29364
29483
  "src/scripts/mlExport.ts"() {
29365
29484
  "use strict";
29366
29485
  import_args22 = __toESM(require("args"));
29367
29486
  import_chalk37 = __toESM(require("chalk"));
29368
- import_promises24 = __toESM(require("fs/promises"));
29487
+ import_promises25 = __toESM(require("fs/promises"));
29369
29488
  import_path8 = __toESM(require("path"));
29370
29489
  import_ml = require("@tradejs/infra/ml");
29371
29490
  init_checkpoint();
@@ -29416,7 +29535,7 @@ var init_mlExport = __esm({
29416
29535
  };
29417
29536
  main33 = async () => {
29418
29537
  const outDir = String(flags20.outDir || "data/ml/export");
29419
- await import_promises24.default.mkdir(outDir, { recursive: true });
29538
+ await import_promises25.default.mkdir(outDir, { recursive: true });
29420
29539
  const strategyName = await resolveExportStrategy({
29421
29540
  explicitStrategy: String(flags20.strategy || ""),
29422
29541
  outDir,
@@ -29461,7 +29580,7 @@ var init_mlExport = __esm({
29461
29580
  const shouldDeleteChunks = !Boolean(flags20.keepChunks);
29462
29581
  if (shouldDeleteChunks) {
29463
29582
  for (const filePath of chunkFiles) {
29464
- await import_promises24.default.rm(filePath, { force: true });
29583
+ await import_promises25.default.rm(filePath, { force: true });
29465
29584
  }
29466
29585
  }
29467
29586
  console.log(import_chalk37.default.green(`Merged dataset saved: ${mergedPath}`));
@@ -29482,13 +29601,13 @@ var mlInspect_exports = {};
29482
29601
  __export(mlInspect_exports, {
29483
29602
  main: () => main34
29484
29603
  });
29485
- var import_args23, import_chalk38, import_promises25, import_fs3, import_path9, import_readline2, import_child_process2, flags21, toMode, toInspectTool, selectInspectTool, asPositiveInt, readRowsHead, readRowsTail, readRowsSample, quantileSorted, mean2, std, findLatestDataset, buildNumericStats, formatNumber5, runQuickInspect, runYDataInspect, main34;
29604
+ var import_args23, import_chalk38, import_promises26, import_fs3, import_path9, import_readline2, import_child_process2, flags21, toMode, toInspectTool, selectInspectTool, asPositiveInt, readRowsHead, readRowsTail, readRowsSample, quantileSorted, mean2, std, findLatestDataset, buildNumericStats, formatNumber5, runQuickInspect, runYDataInspect, main34;
29486
29605
  var init_mlInspect = __esm({
29487
29606
  "src/scripts/mlInspect.ts"() {
29488
29607
  "use strict";
29489
29608
  import_args23 = __toESM(require("args"));
29490
29609
  import_chalk38 = __toESM(require("chalk"));
29491
- import_promises25 = __toESM(require("fs/promises"));
29610
+ import_promises26 = __toESM(require("fs/promises"));
29492
29611
  import_fs3 = require("fs");
29493
29612
  import_path9 = __toESM(require("path"));
29494
29613
  import_readline2 = __toESM(require("readline"));
@@ -29665,7 +29784,7 @@ var init_mlInspect = __esm({
29665
29784
  };
29666
29785
  findLatestDataset = async (params) => {
29667
29786
  const { dir, strategy } = params;
29668
- const entries = await import_promises25.default.readdir(dir, { withFileTypes: true });
29787
+ const entries = await import_promises26.default.readdir(dir, { withFileTypes: true });
29669
29788
  const strategyToken = strategy.trim().toLowerCase();
29670
29789
  const files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.endsWith(".jsonl")).filter(
29671
29790
  (name) => !name.includes(".train.") && !name.includes(".test.")
@@ -29677,7 +29796,7 @@ var init_mlInspect = __esm({
29677
29796
  }
29678
29797
  const withMtime = await Promise.all(
29679
29798
  files.map(async (name) => {
29680
- const stat = await import_promises25.default.stat(import_path9.default.join(dir, name));
29799
+ const stat = await import_promises26.default.stat(import_path9.default.join(dir, name));
29681
29800
  return { name, mtime: stat.mtimeMs };
29682
29801
  })
29683
29802
  );
@@ -29922,7 +30041,7 @@ var init_mlInspect = __esm({
29922
30041
  const relToData = import_path9.default.relative(dataRoot, absDatasetPath);
29923
30042
  const inputInContainer = `/app/data/${relToData}`;
29924
30043
  const reportDir = import_path9.default.dirname(absDatasetPath);
29925
- await import_promises25.default.mkdir(reportDir, { recursive: true });
30044
+ await import_promises26.default.mkdir(reportDir, { recursive: true });
29926
30045
  const reportPath = import_path9.default.join(
29927
30046
  reportDir,
29928
30047
  `${import_path9.default.basename(datasetPath, import_path9.default.extname(datasetPath))}.profile.html`
@@ -30018,12 +30137,12 @@ var mlTrainLatestSelect_exports = {};
30018
30137
  __export(mlTrainLatestSelect_exports, {
30019
30138
  main: () => main35
30020
30139
  });
30021
- var import_path10, import_promises26, import_fs4, import_crypto2, import_child_process3, import_events, import_readline3, import_args24, import_chalk39, import_ml2, toFileToken6, asBool, asInt7, asNonNegativeInt, formatBytes, getMlContainerMemUsage, MODEL_TYPES, STRATEGIES, flags22, parseStrategy, parseModelType, selectModelType, listDatasetFiles, concatFiles, pipeNormalized, DAY_MS13, SPLIT_PROGRESS_EVERY, parseTimestampMs, scanMaxLabeledTimestampMs, scanMaxTrainTimestampMs, hashFileNameSha1, prepareTrainWindowFiles, main35;
30140
+ var import_path10, import_promises27, import_fs4, import_crypto2, import_child_process3, import_events, import_readline3, import_args24, import_chalk39, import_ml2, toFileToken6, asBool, asInt7, asNonNegativeInt, formatBytes, getMlContainerMemUsage, MODEL_TYPES, STRATEGIES, flags22, parseStrategy, parseModelType, selectModelType, listDatasetFiles, concatFiles, pipeNormalized, DAY_MS13, SPLIT_PROGRESS_EVERY, parseTimestampMs, scanMaxLabeledTimestampMs, scanMaxTrainTimestampMs, hashFileNameSha1, prepareTrainWindowFiles, main35;
30022
30141
  var init_mlTrainLatestSelect = __esm({
30023
30142
  "src/scripts/mlTrainLatestSelect.ts"() {
30024
30143
  "use strict";
30025
30144
  import_path10 = __toESM(require("path"));
30026
- import_promises26 = __toESM(require("fs/promises"));
30145
+ import_promises27 = __toESM(require("fs/promises"));
30027
30146
  import_fs4 = require("fs");
30028
30147
  import_crypto2 = require("crypto");
30029
30148
  import_child_process3 = require("child_process");
@@ -30152,7 +30271,7 @@ var init_mlTrainLatestSelect = __esm({
30152
30271
  return defaultModel;
30153
30272
  };
30154
30273
  listDatasetFiles = async (dir, strategyName) => {
30155
- const entries = await import_promises26.default.readdir(dir, { withFileTypes: true });
30274
+ const entries = await import_promises27.default.readdir(dir, { withFileTypes: true });
30156
30275
  const prefix = `ml-dataset-${toFileToken6(strategyName)}-`;
30157
30276
  const legacyPrefix = "ml-dataset-";
30158
30277
  const fileNames = entries.filter((entry) => entry.isFile()).map((entry) => entry.name);
@@ -30163,7 +30282,7 @@ var init_mlTrainLatestSelect = __esm({
30163
30282
  ).filter((name) => !name.includes(".train.") && !name.includes(".test.")).filter((name) => !name.includes(".holdout-train.")).filter((name) => !name.includes(".holdout-test.")).filter((name) => !name.includes(".walk-forward.")).filter((name) => !name.includes(".prod."));
30164
30283
  const withMtime = await Promise.all(
30165
30284
  jsonlFiles.map(async (name) => {
30166
- const stat = await import_promises26.default.stat(import_path10.default.join(dir, name));
30285
+ const stat = await import_promises27.default.stat(import_path10.default.join(dir, name));
30167
30286
  return { name, mtime: stat.mtimeMs };
30168
30287
  })
30169
30288
  );
@@ -30339,13 +30458,13 @@ var init_mlTrainLatestSelect = __esm({
30339
30458
  const metaPath = import_path10.default.join(dir, `${parsed.name}.windows.${key2}.meta.json`);
30340
30459
  try {
30341
30460
  const [metaRaw] = await Promise.all([
30342
- import_promises26.default.readFile(metaPath, "utf8"),
30343
- import_promises26.default.access(holdoutTrainPath),
30344
- import_promises26.default.access(holdoutTestPath),
30345
- import_promises26.default.access(prodPath),
30461
+ import_promises27.default.readFile(metaPath, "utf8"),
30462
+ import_promises27.default.access(holdoutTrainPath),
30463
+ import_promises27.default.access(holdoutTestPath),
30464
+ import_promises27.default.access(prodPath),
30346
30465
  ...walkForwardFoldDefs.flatMap((entry) => [
30347
- import_promises26.default.access(entry.trainPath),
30348
- import_promises26.default.access(entry.testPath)
30466
+ import_promises27.default.access(entry.trainPath),
30467
+ import_promises27.default.access(entry.testPath)
30349
30468
  ])
30350
30469
  ]);
30351
30470
  const meta2 = JSON.parse(metaRaw);
@@ -30712,7 +30831,7 @@ var init_mlTrainLatestSelect = __esm({
30712
30831
  },
30713
30832
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
30714
30833
  };
30715
- await import_promises26.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
30834
+ await import_promises27.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
30716
30835
  `, "utf8");
30717
30836
  return {
30718
30837
  holdoutTrainPath,
@@ -30770,7 +30889,7 @@ var init_mlTrainLatestSelect = __esm({
30770
30889
  process.exit(1);
30771
30890
  }
30772
30891
  try {
30773
- const inputStat = await import_promises26.default.stat(inputPath);
30892
+ const inputStat = await import_promises27.default.stat(inputPath);
30774
30893
  const totalInputBytes = inputStat.size;
30775
30894
  const autoIncrementalThresholdGb = asInt7(
30776
30895
  process.env.ML_TRAIN_INCREMENTAL_THRESHOLD_GB,
@@ -30959,7 +31078,7 @@ var init_mlTrainLatestSelect = __esm({
30959
31078
  const modelDir = import_path10.default.join(modelDirRoot, "models");
30960
31079
  let savedModels = [];
30961
31080
  try {
30962
- const entries = await import_promises26.default.readdir(modelDir, { withFileTypes: true });
31081
+ const entries = await import_promises27.default.readdir(modelDir, { withFileTypes: true });
30963
31082
  savedModels = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter(
30964
31083
  (name) => name === `${selected}.joblib` || /^.+\.model\d+\.joblib$/.test(name)
30965
31084
  ).filter((name) => name.startsWith(`${selected}.`)).sort();
@@ -30981,7 +31100,7 @@ var init_mlTrainLatestSelect = __esm({
30981
31100
  process.exitCode = finalCode;
30982
31101
  } finally {
30983
31102
  for (const file of cleanupFiles) {
30984
- await import_promises26.default.rm(file, { force: true });
31103
+ await import_promises27.default.rm(file, { force: true });
30985
31104
  }
30986
31105
  }
30987
31106
  process.exit(process.exitCode ?? 1);
@@ -31013,20 +31132,20 @@ __export(researchAuto_exports, {
31013
31132
  toStrategyConfigGrid: () => toStrategyConfigGrid2,
31014
31133
  trimTextTail: () => trimTextTail2
31015
31134
  });
31016
- var import_args25, import_chalk40, import_node_child_process5, import_promises27, import_node_os2, import_node_path20, import_constants19, import_ai8, import_logger7, import_redis17, import_registry4, flags23, projectRoot8, dotenvPath, getResearchAutoLockPath, readResearchAutoLock, isProcessAlive, acquireResearchAutoLock, releaseResearchAutoLock, resolvePositiveInteger, resolveHeapMbFromEnv, buildNodeOptions, RESEARCH_AUTO_PARENT_HEAP_MB, RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB, RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB, RESEARCH_AUTO_AGENT_PARENT_HEAP_MB, trimTextTail2, escapeHtml3, createEmptySteps, saveRun, listMergedFiles3, getBacktestResultsPrefix, listRuntimeStrategyNames, toStrategyConfigGrid2, formatMskDateTime, buildTelegramReport, runCliCommand, resolveTarget, parseJsonOutput, logResearch, executeNonBlockingStep, main36;
31135
+ var import_args25, import_chalk40, import_node_child_process5, import_promises28, import_node_os2, import_node_path21, import_constants19, import_ai8, import_logger7, import_redis18, import_registry4, flags23, projectRoot8, dotenvPath, getResearchAutoLockPath, readResearchAutoLock, isProcessAlive, acquireResearchAutoLock, releaseResearchAutoLock, resolvePositiveInteger, resolveHeapMbFromEnv, buildNodeOptions, RESEARCH_AUTO_PARENT_HEAP_MB, RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB, RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB, RESEARCH_AUTO_AGENT_PARENT_HEAP_MB, trimTextTail2, escapeHtml3, createEmptySteps, saveRun, listMergedFiles3, getBacktestResultsPrefix, listRuntimeStrategyNames, toStrategyConfigGrid2, formatMskDateTime, buildTelegramReport, runCliCommand, resolveTarget, parseJsonOutput, logResearch, executeNonBlockingStep, main36;
31017
31136
  var init_researchAuto = __esm({
31018
31137
  "src/scripts/researchAuto.ts"() {
31019
31138
  "use strict";
31020
31139
  import_args25 = __toESM(require("args"));
31021
31140
  import_chalk40 = __toESM(require("chalk"));
31022
31141
  import_node_child_process5 = require("child_process");
31023
- import_promises27 = __toESM(require("fs/promises"));
31142
+ import_promises28 = __toESM(require("fs/promises"));
31024
31143
  import_node_os2 = __toESM(require("os"));
31025
- import_node_path20 = __toESM(require("path"));
31144
+ import_node_path21 = __toESM(require("path"));
31026
31145
  import_constants19 = require("@tradejs/core/constants");
31027
31146
  import_ai8 = require("@tradejs/infra/ai");
31028
31147
  import_logger7 = require("@tradejs/infra/logger");
31029
- import_redis17 = require("@tradejs/infra/redis");
31148
+ import_redis18 = require("@tradejs/infra/redis");
31030
31149
  import_registry4 = require("@tradejs/node/registry");
31031
31150
  init_runtimeRedis();
31032
31151
  init_runtimeStrategyBacktest();
@@ -31056,9 +31175,9 @@ var init_researchAuto = __esm({
31056
31175
  flags23 = import_args25.default.parse(process.argv);
31057
31176
  ({ projectRoot: projectRoot8 } = resolveResearchRoots());
31058
31177
  dotenvPath = String(
31059
- process.env.DOTENV_CONFIG_PATH || import_node_path20.default.join(projectRoot8, ".env")
31060
- ).trim() || import_node_path20.default.join(projectRoot8, ".env");
31061
- getResearchAutoLockPath = (userName3) => import_node_path20.default.join(
31178
+ process.env.DOTENV_CONFIG_PATH || import_node_path21.default.join(projectRoot8, ".env")
31179
+ ).trim() || import_node_path21.default.join(projectRoot8, ".env");
31180
+ getResearchAutoLockPath = (userName3) => import_node_path21.default.join(
31062
31181
  projectRoot8,
31063
31182
  "data",
31064
31183
  "cache",
@@ -31067,7 +31186,7 @@ var init_researchAuto = __esm({
31067
31186
  );
31068
31187
  readResearchAutoLock = async (lockPath) => {
31069
31188
  try {
31070
- const raw = await import_promises27.default.readFile(lockPath, "utf8");
31189
+ const raw = await import_promises28.default.readFile(lockPath, "utf8");
31071
31190
  return JSON.parse(raw);
31072
31191
  } catch {
31073
31192
  return null;
@@ -31102,9 +31221,9 @@ var init_researchAuto = __esm({
31102
31221
  startedAt,
31103
31222
  argv: [...process.argv]
31104
31223
  };
31105
- await import_promises27.default.mkdir(import_node_path20.default.dirname(lockPath), { recursive: true });
31224
+ await import_promises28.default.mkdir(import_node_path21.default.dirname(lockPath), { recursive: true });
31106
31225
  const writeLock = async () => {
31107
- await import_promises27.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
31226
+ await import_promises28.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
31108
31227
  flag: "wx"
31109
31228
  });
31110
31229
  };
@@ -31123,7 +31242,7 @@ var init_researchAuto = __esm({
31123
31242
  `research:auto is already running for user ${userName3} (runId=${existingLock.runId}, strategy=${existingLock.strategy}, pid=${existingLock.pid}, ppid=${existingLock.ppid}, startedAt=${existingLock.startedAt}, host=${existingLock.hostname})`
31124
31243
  );
31125
31244
  }
31126
- await import_promises27.default.unlink(lockPath).catch(() => void 0);
31245
+ await import_promises28.default.unlink(lockPath).catch(() => void 0);
31127
31246
  await writeLock();
31128
31247
  return lockPath;
31129
31248
  };
@@ -31135,7 +31254,7 @@ var init_researchAuto = __esm({
31135
31254
  if (existingLock && existingLock.pid !== process.pid) {
31136
31255
  return;
31137
31256
  }
31138
- await import_promises27.default.unlink(lockPath).catch(() => void 0);
31257
+ await import_promises28.default.unlink(lockPath).catch(() => void 0);
31139
31258
  };
31140
31259
  resolvePositiveInteger = (value, fallback) => {
31141
31260
  const parsed = Number.parseInt(String(value ?? ""), 10);
@@ -31228,18 +31347,18 @@ var init_researchAuto = __esm({
31228
31347
  }
31229
31348
  });
31230
31349
  saveRun = async (run) => {
31231
- await (0, import_redis17.setData)(import_redis17.redisKeys.researchRun(run.userName, run.runId), run, {
31350
+ await (0, import_redis18.setData)(import_redis18.redisKeys.researchRun(run.userName, run.runId), run, {
31232
31351
  expire: import_constants19.TTL_1M
31233
31352
  });
31234
- await (0, import_redis17.setData)(import_redis17.redisKeys.researchLatestRun(run.userName, run.strategy), run, {
31353
+ await (0, import_redis18.setData)(import_redis18.redisKeys.researchLatestRun(run.userName, run.strategy), run, {
31235
31354
  expire: import_constants19.TTL_1M
31236
31355
  });
31237
31356
  };
31238
31357
  listMergedFiles3 = async (outDir, strategyName) => {
31239
31358
  try {
31240
- const entries = await import_promises27.default.readdir(outDir);
31359
+ const entries = await import_promises28.default.readdir(outDir);
31241
31360
  const prefix = `ai-dataset-${(0, import_ai8.toFileToken)(strategyName)}-merged-`;
31242
- return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).sort().map((name) => import_node_path20.default.join(outDir, name));
31361
+ return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).sort().map((name) => import_node_path21.default.join(outDir, name));
31243
31362
  } catch {
31244
31363
  return [];
31245
31364
  }
@@ -31373,7 +31492,7 @@ var init_researchAuto = __esm({
31373
31492
  return new Promise((resolve, reject) => {
31374
31493
  const child = (0, import_node_child_process5.spawn)(
31375
31494
  process.execPath,
31376
- [import_node_path20.default.resolve(process.argv[1]), params.command, ...params.args],
31495
+ [import_node_path21.default.resolve(process.argv[1]), params.command, ...params.args],
31377
31496
  {
31378
31497
  cwd: projectRoot8,
31379
31498
  env,
@@ -31461,8 +31580,8 @@ var init_researchAuto = __esm({
31461
31580
  const candidates = [];
31462
31581
  for (const strategy of availableStrategies) {
31463
31582
  const config2 = `${strategy}:research`;
31464
- const latestRun = await (0, import_redis17.getData)(
31465
- import_redis17.redisKeys.researchLatestRun(userName3, strategy),
31583
+ const latestRun = await (0, import_redis18.getData)(
31584
+ import_redis18.redisKeys.researchLatestRun(userName3, strategy),
31466
31585
  null
31467
31586
  );
31468
31587
  const lastFinishedAt = latestRun?.finishedAt ? Date.parse(latestRun.finishedAt) : 0;
@@ -31556,8 +31675,8 @@ var init_researchAuto = __esm({
31556
31675
  const jsonOutput = Boolean(flags23.json);
31557
31676
  const skipAgent = Boolean(flags23.skipAgent);
31558
31677
  const outDirArg = String(flags23.outDir || "data/ai/export").trim() || "data/ai/export";
31559
- const outDir = import_node_path20.default.resolve(projectRoot8, outDirArg);
31560
- const cleanDirArg = import_node_path20.default.relative(import_node_path20.default.join(projectRoot8, "data"), outDir).replace(/\\/g, "/");
31678
+ const outDir = import_node_path21.default.resolve(projectRoot8, outDirArg);
31679
+ const cleanDirArg = import_node_path21.default.relative(import_node_path21.default.join(projectRoot8, "data"), outDir).replace(/\\/g, "/");
31561
31680
  const target = await resolveTarget();
31562
31681
  const runId = `${Date.now()}-${(0, import_ai8.toFileToken)(target.strategy)}`;
31563
31682
  const run = {
@@ -31641,13 +31760,13 @@ var init_researchAuto = __esm({
31641
31760
  startedAt
31642
31761
  };
31643
31762
  await saveRun(run);
31644
- const strategyConfigKey = import_redis17.redisKeys.strategyConfig(
31763
+ const strategyConfigKey = import_redis18.redisKeys.strategyConfig(
31645
31764
  userName3,
31646
31765
  target.strategy
31647
31766
  );
31648
- const backtestConfigKey = import_redis17.redisKeys.backtestConfig(userName3, target.config);
31767
+ const backtestConfigKey = import_redis18.redisKeys.backtestConfig(userName3, target.config);
31649
31768
  const defaults = await (0, import_registry4.getStrategyDefaults)(target.strategy, projectRoot8) || {};
31650
- const userStrategyConfig = await (0, import_redis17.getData)(
31769
+ const userStrategyConfig = await (0, import_redis18.getData)(
31651
31770
  strategyConfigKey,
31652
31771
  {}
31653
31772
  );
@@ -31661,7 +31780,7 @@ var init_researchAuto = __esm({
31661
31780
  );
31662
31781
  }
31663
31782
  const backtestConfig = toStrategyConfigGrid2(strategyConfig);
31664
- await (0, import_redis17.setData)(backtestConfigKey, backtestConfig, { expire: 0 });
31783
+ await (0, import_redis18.setData)(backtestConfigKey, backtestConfig, { expire: 0 });
31665
31784
  logResearch(
31666
31785
  `stored backtest config at ${backtestConfigKey} with ${Object.keys(strategyConfig).length} top-level fields`
31667
31786
  );
@@ -31701,7 +31820,7 @@ var init_researchAuto = __esm({
31701
31820
  `resource knobs: researchAutoHeapMb=${RESEARCH_AUTO_PARENT_HEAP_MB}, backtestParentHeapMb=${RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB}, aiTrainParentHeapMb=${RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB}, agentParentHeapMb=${RESEARCH_AUTO_AGENT_PARENT_HEAP_MB}, backtestWorkerHeapMb=${process.env.BACKTEST_WORKER_HEAP_MB || "auto"}, backtestMaxParallel=${process.env.BACKTEST_MAX_PARALLEL || "auto"}, klineConcurrency=${process.env.KLINE_CONCURRENCY_LIMIT || "default"}`
31702
31821
  );
31703
31822
  const backtestKeysBefore = new Set(
31704
- await (0, import_redis17.getKeys)(getBacktestResultsPrefix(userName3, target.config))
31823
+ await (0, import_redis18.getKeys)(getBacktestResultsPrefix(userName3, target.config))
31705
31824
  );
31706
31825
  const aiFilesBefore = new Set(
31707
31826
  await listMergedFiles3(outDir, target.strategy)
@@ -31763,14 +31882,14 @@ var init_researchAuto = __esm({
31763
31882
  captureMode: "full"
31764
31883
  }
31765
31884
  );
31766
- const backtestKeysAfter = await (0, import_redis17.getKeys)(
31885
+ const backtestKeysAfter = await (0, import_redis18.getKeys)(
31767
31886
  getBacktestResultsPrefix(userName3, target.config)
31768
31887
  );
31769
31888
  const newBacktestKeys = backtestKeysAfter.filter((key2) => !backtestKeysBefore.has(key2)).sort();
31770
31889
  const backtestResultKey = newBacktestKeys[newBacktestKeys.length - 1] || backtestKeysAfter.sort().at(-1);
31771
31890
  if (backtestResultKey) {
31772
31891
  logResearch(`detected backtest result key ${backtestResultKey}`);
31773
- const backtestResult = await (0, import_redis17.getData)(backtestResultKey, null);
31892
+ const backtestResult = await (0, import_redis18.getData)(backtestResultKey, null);
31774
31893
  run.artifacts.backtestResultKey = backtestResultKey;
31775
31894
  run.artifacts.backtestResult = backtestResult ? {
31776
31895
  finishedAt: backtestResult.finishedAt,
@@ -31891,14 +32010,14 @@ Telegram report failed: ${suffix}`;
31891
32010
  });
31892
32011
 
31893
32012
  // src/lib/coreResearch/artifacts.ts
31894
- var import_node_fs7, import_node_events2, import_promises28, import_node_path21, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades, summarizeCoreResearchComparison;
32013
+ var import_node_fs7, import_node_events2, import_promises29, import_node_path22, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades, summarizeCoreResearchComparison;
31895
32014
  var init_artifacts = __esm({
31896
32015
  "src/lib/coreResearch/artifacts.ts"() {
31897
32016
  "use strict";
31898
32017
  import_node_fs7 = require("fs");
31899
32018
  import_node_events2 = require("events");
31900
- import_promises28 = __toESM(require("fs/promises"));
31901
- import_node_path21 = __toESM(require("path"));
32019
+ import_promises29 = __toESM(require("fs/promises"));
32020
+ import_node_path22 = __toESM(require("path"));
31902
32021
  init_io();
31903
32022
  csv = (value) => {
31904
32023
  const text3 = String(value ?? "");
@@ -31912,7 +32031,7 @@ var init_artifacts = __esm({
31912
32031
  await (0, import_node_events2.once)(output, "close");
31913
32032
  };
31914
32033
  writeCoreResearchMatches = async (params) => {
31915
- await import_promises28.default.mkdir(import_node_path21.default.dirname(params.filePath), { recursive: true });
32034
+ await import_promises29.default.mkdir(import_node_path22.default.dirname(params.filePath), { recursive: true });
31916
32035
  const output = (0, import_node_fs7.createWriteStream)(params.filePath, { encoding: "utf8" });
31917
32036
  await writeLine(
31918
32037
  output,
@@ -31963,7 +32082,7 @@ var init_artifacts = __esm({
31963
32082
  await closeOutput(output);
31964
32083
  };
31965
32084
  writeCoreResearchTrades = async (params) => {
31966
- await import_promises28.default.mkdir(import_node_path21.default.dirname(params.filePath), { recursive: true });
32085
+ await import_promises29.default.mkdir(import_node_path22.default.dirname(params.filePath), { recursive: true });
31967
32086
  const output = (0, import_node_fs7.createWriteStream)(params.filePath, { encoding: "utf8" });
31968
32087
  for (const variant of params.variants) {
31969
32088
  for (const trade of variant.trades) {
@@ -32251,13 +32370,13 @@ var init_comparison = __esm({
32251
32370
  });
32252
32371
 
32253
32372
  // src/lib/coreResearch/dataset.ts
32254
- var import_node_crypto17, import_node_fs8, import_node_path22, import_node_readline3, asRecord4, finiteNumber4, normalizeDirection, findStrategySetupIdentity, classifyBreadth, classifyDerivatives, resolveCoreResearchRegime, normalizeCompletedTrade, completedTradeIdentity, positionCycleIdentity, sumBy, weightedPrice, aggregatePositionCycles, compareText, compareTrades, readCoreResearchVariant;
32373
+ var import_node_crypto16, import_node_fs8, import_node_path23, import_node_readline3, asRecord4, finiteNumber4, normalizeDirection, findStrategySetupIdentity, classifyBreadth, classifyDerivatives, resolveCoreResearchRegime, normalizeCompletedTrade, completedTradeIdentity, positionCycleIdentity, sumBy, weightedPrice, aggregatePositionCycles, compareText, compareTrades, readCoreResearchVariant;
32255
32374
  var init_dataset2 = __esm({
32256
32375
  "src/lib/coreResearch/dataset.ts"() {
32257
32376
  "use strict";
32258
- import_node_crypto17 = require("crypto");
32377
+ import_node_crypto16 = require("crypto");
32259
32378
  import_node_fs8 = require("fs");
32260
- import_node_path22 = __toESM(require("path"));
32379
+ import_node_path23 = __toESM(require("path"));
32261
32380
  import_node_readline3 = __toESM(require("readline"));
32262
32381
  asRecord4 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
32263
32382
  finiteNumber4 = (value, field) => {
@@ -32468,9 +32587,9 @@ var init_dataset2 = __esm({
32468
32587
  const seen = /* @__PURE__ */ new Map();
32469
32588
  let duplicateRowsDropped = 0;
32470
32589
  for (const inputPath of variant.files) {
32471
- const filePath = import_node_path22.default.resolve(inputPath);
32590
+ const filePath = import_node_path23.default.resolve(inputPath);
32472
32591
  const input = (0, import_node_fs8.createReadStream)(filePath);
32473
- const hash2 = (0, import_node_crypto17.createHash)("sha256");
32592
+ const hash2 = (0, import_node_crypto16.createHash)("sha256");
32474
32593
  input.on("data", (chunk) => hash2.update(chunk));
32475
32594
  const lines = import_node_readline3.default.createInterface({ input, crlfDelay: Infinity });
32476
32595
  const fileTrades = [];
@@ -32960,14 +33079,14 @@ var init_selection = __esm({
32960
33079
  });
32961
33080
 
32962
33081
  // src/lib/coreResearch/orchestrator.ts
32963
- var import_promises29, import_node_path23, import_node_child_process6, import_node_crypto18, import_coreResearch, summarizeSupplementalFiles, analyzeCoreResearchPrepared, analyzeCoreResearch, createCoreResearchSpecTemplate, runCommand2, commandValue, commandHas, validateCoreResearchRunCommand, runCoreResearch;
33082
+ var import_promises30, import_node_path24, import_node_child_process6, import_node_crypto17, import_coreResearch, summarizeSupplementalFiles, analyzeCoreResearchPrepared, analyzeCoreResearch, createCoreResearchSpecTemplate, runCommand2, commandValue, commandHas, validateCoreResearchRunCommand, runCoreResearch;
32964
33083
  var init_orchestrator = __esm({
32965
33084
  "src/lib/coreResearch/orchestrator.ts"() {
32966
33085
  "use strict";
32967
- import_promises29 = __toESM(require("fs/promises"));
32968
- import_node_path23 = __toESM(require("path"));
33086
+ import_promises30 = __toESM(require("fs/promises"));
33087
+ import_node_path24 = __toESM(require("path"));
32969
33088
  import_node_child_process6 = require("child_process");
32970
- import_node_crypto18 = require("crypto");
33089
+ import_node_crypto17 = require("crypto");
32971
33090
  import_coreResearch = require("@tradejs/infra/coreResearch");
32972
33091
  init_artifacts();
32973
33092
  init_io();
@@ -33173,7 +33292,7 @@ var init_orchestrator = __esm({
33173
33292
  const primarySourceHashes = Object.fromEntries(
33174
33293
  analyses.flatMap(
33175
33294
  (analysis) => analysis.files.map((file) => [
33176
- import_node_path23.default.relative(paths.researchDir, file.path),
33295
+ import_node_path24.default.relative(paths.researchDir, file.path),
33177
33296
  file.sha256
33178
33297
  ])
33179
33298
  )
@@ -33192,8 +33311,8 @@ var init_orchestrator = __esm({
33192
33311
  const supplementalSourceHashes = Object.fromEntries(
33193
33312
  await Promise.all(
33194
33313
  supplementalSourcePaths.map(async (filePath) => [
33195
- import_node_path23.default.relative(paths.researchDir, import_node_path23.default.resolve(filePath)),
33196
- await sha256File(import_node_path23.default.resolve(filePath))
33314
+ import_node_path24.default.relative(paths.researchDir, import_node_path24.default.resolve(filePath)),
33315
+ await sha256File(import_node_path24.default.resolve(filePath))
33197
33316
  ])
33198
33317
  )
33199
33318
  );
@@ -33264,7 +33383,7 @@ var init_orchestrator = __esm({
33264
33383
  const tradesByVariant = new Map(
33265
33384
  windowed.map((entry) => [entry.variant.id, entry.trades])
33266
33385
  );
33267
- await import_promises29.default.writeFile(
33386
+ await import_promises30.default.writeFile(
33268
33387
  paths.reportPath,
33269
33388
  buildCoreResearchHtml({ spec, result, tradesByVariant }),
33270
33389
  "utf8"
@@ -33278,17 +33397,17 @@ var init_orchestrator = __esm({
33278
33397
  "trades.jsonl": await sha256File(paths.tradesPath),
33279
33398
  "report.html": await sha256File(paths.reportPath)
33280
33399
  };
33281
- const resolvedRunsPath = import_node_path23.default.join(paths.researchDir, "resolved-runs.json");
33400
+ const resolvedRunsPath = import_node_path24.default.join(paths.researchDir, "resolved-runs.json");
33282
33401
  try {
33283
33402
  artifactHashes["resolved-runs.json"] = await sha256File(resolvedRunsPath);
33284
33403
  } catch (error) {
33285
33404
  if (error.code !== "ENOENT") throw error;
33286
33405
  }
33287
33406
  try {
33288
- for (const name of await import_promises29.default.readdir(paths.runLogDir)) {
33407
+ for (const name of await import_promises30.default.readdir(paths.runLogDir)) {
33289
33408
  if (!name.endsWith(".log")) continue;
33290
33409
  artifactHashes[`runs/${name}`] = await sha256File(
33291
- import_node_path23.default.join(paths.runLogDir, name)
33410
+ import_node_path24.default.join(paths.runLogDir, name)
33292
33411
  );
33293
33412
  }
33294
33413
  } catch (error) {
@@ -33345,9 +33464,9 @@ var init_orchestrator = __esm({
33345
33464
  }
33346
33465
  };
33347
33466
  createCoreResearchSpecTemplate = (params) => {
33348
- const rootDir = import_node_path23.default.relative(
33349
- import_node_path23.default.resolve(params.projectRoot),
33350
- import_node_path23.default.join(import_node_path23.default.resolve(params.projectRoot), "data", "research", "core")
33467
+ const rootDir = import_node_path24.default.relative(
33468
+ import_node_path24.default.resolve(params.projectRoot),
33469
+ import_node_path24.default.join(import_node_path24.default.resolve(params.projectRoot), "data", "research", "core")
33351
33470
  ).replace(/\\/g, "/");
33352
33471
  const lineage = (() => {
33353
33472
  try {
@@ -33378,7 +33497,7 @@ var init_orchestrator = __esm({
33378
33497
  gitSha,
33379
33498
  ...sourceRepository ? { sourceRepository } : {},
33380
33499
  ...dirtyDiff ? {
33381
- dirtyDiffSha256: (0, import_node_crypto18.createHash)("sha256").update(dirtyDiff).digest("hex")
33500
+ dirtyDiffSha256: (0, import_node_crypto17.createHash)("sha256").update(dirtyDiff).digest("hex")
33382
33501
  } : {}
33383
33502
  };
33384
33503
  } catch {
@@ -33485,7 +33604,7 @@ var init_orchestrator = __esm({
33485
33604
  };
33486
33605
  runCommand2 = async (params) => {
33487
33606
  if (!params.command.length) throw new Error("Cannot run an empty command");
33488
- await import_promises29.default.mkdir(import_node_path23.default.dirname(params.logPath), { recursive: true });
33607
+ await import_promises30.default.mkdir(import_node_path24.default.dirname(params.logPath), { recursive: true });
33489
33608
  const chunks = [];
33490
33609
  const child = (0, import_node_child_process6.spawn)(params.command[0], params.command.slice(1), {
33491
33610
  cwd: params.cwd,
@@ -33505,7 +33624,7 @@ var init_orchestrator = __esm({
33505
33624
  child.once("close", (code) => resolve(code ?? 1));
33506
33625
  });
33507
33626
  const output = chunks.join("");
33508
- await import_promises29.default.writeFile(params.logPath, output, "utf8");
33627
+ await import_promises30.default.writeFile(params.logPath, output, "utf8");
33509
33628
  if (exitCode !== 0) {
33510
33629
  throw new Error(
33511
33630
  `Command failed with exit ${exitCode}: ${params.command.join(" ")}`
@@ -33559,7 +33678,7 @@ var init_orchestrator = __esm({
33559
33678
  };
33560
33679
  runCoreResearch = async (params) => {
33561
33680
  const { spec } = params;
33562
- const cwd = import_node_path23.default.resolve(params.cwd ?? process.cwd());
33681
+ const cwd = import_node_path24.default.resolve(params.cwd ?? process.cwd());
33563
33682
  const prepared = await prepareCoreResearch(spec);
33564
33683
  await verifyPreparedSupport(prepared);
33565
33684
  const resolvedVariants = [];
@@ -33578,7 +33697,7 @@ var init_orchestrator = __esm({
33578
33697
  artifactHashes: { variant: sha256Json(variant) }
33579
33698
  });
33580
33699
  let runId = "";
33581
- const backtestLogPath = import_node_path23.default.join(
33700
+ const backtestLogPath = import_node_path24.default.join(
33582
33701
  prepared.paths.runLogDir,
33583
33702
  `${variant.id}-backtest.log`
33584
33703
  );
@@ -33594,7 +33713,7 @@ var init_orchestrator = __esm({
33594
33713
  env: {
33595
33714
  PROJECT_CWD: cwd,
33596
33715
  ...params.sourceRepositoryRoot ? {
33597
- [SOURCE_REPOSITORY_ROOT_ENV]: import_node_path23.default.resolve(
33716
+ [SOURCE_REPOSITORY_ROOT_ENV]: import_node_path24.default.resolve(
33598
33717
  params.sourceRepositoryRoot
33599
33718
  )
33600
33719
  } : {}
@@ -33609,12 +33728,12 @@ var init_orchestrator = __esm({
33609
33728
  if (!runId) {
33610
33729
  throw new Error(`Backtest for ${variant.id} did not report a run id`);
33611
33730
  }
33612
- const exportLogPath = import_node_path23.default.join(
33731
+ const exportLogPath = import_node_path24.default.join(
33613
33732
  prepared.paths.runLogDir,
33614
33733
  `${variant.id}-export.log`
33615
33734
  );
33616
33735
  const exportParts = [];
33617
- const cliPath = import_node_path23.default.resolve(process.argv[1]);
33736
+ const cliPath = import_node_path24.default.resolve(process.argv[1]);
33618
33737
  await runCommand2({
33619
33738
  command: [
33620
33739
  process.execPath,
@@ -33634,14 +33753,14 @@ var init_orchestrator = __esm({
33634
33753
  env: {
33635
33754
  PROJECT_CWD: cwd,
33636
33755
  ...params.sourceRepositoryRoot ? {
33637
- [SOURCE_REPOSITORY_ROOT_ENV]: import_node_path23.default.resolve(
33756
+ [SOURCE_REPOSITORY_ROOT_ENV]: import_node_path24.default.resolve(
33638
33757
  params.sourceRepositoryRoot
33639
33758
  )
33640
33759
  } : {}
33641
33760
  },
33642
33761
  onLine: (line) => {
33643
33762
  const match = line.match(/^part\d+:\s+(.+)$/);
33644
- if (match) exportParts.push(import_node_path23.default.resolve(cwd, match[1].trim()));
33763
+ if (match) exportParts.push(import_node_path24.default.resolve(cwd, match[1].trim()));
33645
33764
  }
33646
33765
  });
33647
33766
  if (!exportParts.length) {
@@ -33652,7 +33771,7 @@ var init_orchestrator = __esm({
33652
33771
  const traceFiles = await (0, import_coreResearch.listCoreResearchTraceFiles)({
33653
33772
  strategyName: spec.strategy,
33654
33773
  runId,
33655
- outDir: import_node_path23.default.resolve(cwd, "data/research/core/trace")
33774
+ outDir: import_node_path24.default.resolve(cwd, "data/research/core/trace")
33656
33775
  });
33657
33776
  resolvedVariants.push({
33658
33777
  ...variant,
@@ -33672,7 +33791,7 @@ var init_orchestrator = __esm({
33672
33791
  ...Object.fromEntries(
33673
33792
  await Promise.all(
33674
33793
  exportParts.map(async (filePath) => [
33675
- import_node_path23.default.basename(filePath),
33794
+ import_node_path24.default.basename(filePath),
33676
33795
  await sha256File(filePath)
33677
33796
  ])
33678
33797
  )
@@ -33691,7 +33810,7 @@ var init_orchestrator = __esm({
33691
33810
  }
33692
33811
  }
33693
33812
  await writeJsonAtomic(
33694
- import_node_path23.default.join(prepared.paths.researchDir, "resolved-runs.json"),
33813
+ import_node_path24.default.join(prepared.paths.researchDir, "resolved-runs.json"),
33695
33814
  {
33696
33815
  schema: "tradejs-core-research-resolved-runs/v1",
33697
33816
  researchId: spec.researchId,
@@ -33711,12 +33830,12 @@ var coreResearch_exports = {};
33711
33830
  __export(coreResearch_exports, {
33712
33831
  main: () => main37
33713
33832
  });
33714
- var import_promises30, import_node_path24, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main37;
33833
+ var import_promises31, import_node_path25, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main37;
33715
33834
  var init_coreResearch = __esm({
33716
33835
  "src/scripts/coreResearch.ts"() {
33717
33836
  "use strict";
33718
- import_promises30 = __toESM(require("fs/promises"));
33719
- import_node_path24 = __toESM(require("path"));
33837
+ import_promises31 = __toESM(require("fs/promises"));
33838
+ import_node_path25 = __toESM(require("path"));
33720
33839
  import_chalk41 = __toESM(require("chalk"));
33721
33840
  init_io();
33722
33841
  init_orchestrator();
@@ -33740,7 +33859,7 @@ var init_coreResearch = __esm({
33740
33859
  const symbolsFile = valueAfter(argv2, "--symbolsFile");
33741
33860
  if (symbolsFile) {
33742
33861
  const parsed = JSON.parse(
33743
- await import_promises30.default.readFile(import_node_path24.default.resolve(projectRoot18, symbolsFile), "utf8")
33862
+ await import_promises31.default.readFile(import_node_path25.default.resolve(projectRoot18, symbolsFile), "utf8")
33744
33863
  );
33745
33864
  if (!Array.isArray(parsed) || parsed.some((symbol) => typeof symbol !== "string")) {
33746
33865
  throw new Error("--symbolsFile must contain a JSON string array");
@@ -33771,14 +33890,14 @@ The run command executes only variants with an explicit command[] in the preregi
33771
33890
  return;
33772
33891
  }
33773
33892
  if (command === "index") {
33774
- const rootDir = import_node_path24.default.resolve(
33893
+ const rootDir = import_node_path25.default.resolve(
33775
33894
  roots.projectRoot,
33776
33895
  required(valueAfter(argv2, "--root"), "--root")
33777
33896
  );
33778
33897
  const index = await writeCoreResearchStageIndex(rootDir);
33779
33898
  console.log(
33780
33899
  import_chalk41.default.green(
33781
- `Core research index: ${import_node_path24.default.join(rootDir, "index.json")} (${index.families.length} families)`
33900
+ `Core research index: ${import_node_path25.default.join(rootDir, "index.json")} (${index.families.length} families)`
33782
33901
  )
33783
33902
  );
33784
33903
  return;
@@ -33787,7 +33906,7 @@ The run command executes only variants with an explicit command[] in the preregi
33787
33906
  projectRoot: roots.projectRoot
33788
33907
  });
33789
33908
  if (command === "init") {
33790
- const outputPath = import_node_path24.default.resolve(
33909
+ const outputPath = import_node_path25.default.resolve(
33791
33910
  roots.projectRoot,
33792
33911
  required(valueAfter(argv2, "--out"), "--out")
33793
33912
  );
@@ -33811,7 +33930,7 @@ The run command executes only variants with an explicit command[] in the preregi
33811
33930
  );
33812
33931
  return;
33813
33932
  }
33814
- const specPath = import_node_path24.default.resolve(
33933
+ const specPath = import_node_path25.default.resolve(
33815
33934
  roots.projectRoot,
33816
33935
  required(valueAfter(argv2, "--spec"), "--spec")
33817
33936
  );
@@ -33961,7 +34080,7 @@ var init_specification = __esm({
33961
34080
  if (!spec.budget || !spec.selection || !spec.diagnostics)
33962
34081
  throw new Error("Missing research budgets or criteria");
33963
34082
  if (spec.featurePaths !== void 0 && (!Array.isArray(spec.featurePaths) || !spec.featurePaths.length || spec.featurePaths.length > 64 || new Set(spec.featurePaths).size !== spec.featurePaths.length || spec.featurePaths.some(
33964
- (path57) => typeof path57 !== "string" || !/^additionalIndicators\.[a-zA-Z0-9_.]+$/.test(path57) || classifyAiPocketFeaturePath(path57.split(".")) !== "eligible"
34083
+ (path58) => typeof path58 !== "string" || !/^additionalIndicators\.[a-zA-Z0-9_.]+$/.test(path58) || classifyAiPocketFeaturePath(path58.split(".")) !== "eligible"
33965
34084
  )))
33966
34085
  throw new Error("Feature paths must be unique causal market features");
33967
34086
  positive(spec.budget.maxVariants, "maxVariants", 12);
@@ -34044,10 +34163,10 @@ var init_specification = __esm({
34044
34163
  ))
34045
34164
  throw new Error("Invalid event horizons");
34046
34165
  if (!Array.isArray(spec.diagnostics.requiredPaths) || !spec.diagnostics.requiredPaths.length || spec.diagnostics.requiredPaths.some(
34047
- (path57) => !/^[a-zA-Z0-9_.]+$/.test(path57) || classifyAiPocketFeaturePath([
34166
+ (path58) => !/^[a-zA-Z0-9_.]+$/.test(path58) || classifyAiPocketFeaturePath([
34048
34167
  "additionalIndicators",
34049
34168
  "baseContext",
34050
- ...path57.split(".")
34169
+ ...path58.split(".")
34051
34170
  ]) !== "eligible"
34052
34171
  ))
34053
34172
  throw new Error("Required context paths must be causal market features");
@@ -34092,30 +34211,30 @@ __export(io_exports, {
34092
34211
  verifyResearchState: () => verifyResearchState,
34093
34212
  withResearchLock: () => withResearchLock
34094
34213
  });
34095
- var import_promises31, import_node_path25, import_node_os3, import_node_crypto19, researchDirectory, readJson, boundResearchPath, withResearchLock, verifyResearchState, verifyCompletedResearch, initializeResearchState, isRetainedDeletion;
34214
+ var import_promises32, import_node_path26, import_node_os3, import_node_crypto18, researchDirectory, readJson, boundResearchPath, withResearchLock, verifyResearchState, verifyCompletedResearch, initializeResearchState, isRetainedDeletion;
34096
34215
  var init_io2 = __esm({
34097
34216
  "src/lib/strategyResearch/io.ts"() {
34098
34217
  "use strict";
34099
- import_promises31 = __toESM(require("fs/promises"));
34100
- import_node_path25 = __toESM(require("path"));
34218
+ import_promises32 = __toESM(require("fs/promises"));
34219
+ import_node_path26 = __toESM(require("path"));
34101
34220
  import_node_os3 = __toESM(require("os"));
34102
- import_node_crypto19 = require("crypto");
34221
+ import_node_crypto18 = require("crypto");
34103
34222
  init_io();
34104
- researchDirectory = (projectRoot18, spec) => import_node_path25.default.join(projectRoot18, "data/research/strategy", spec.core.researchId);
34105
- readJson = async (file) => JSON.parse(await import_promises31.default.readFile(file, "utf8"));
34223
+ researchDirectory = (projectRoot18, spec) => import_node_path26.default.join(projectRoot18, "data/research/strategy", spec.core.researchId);
34224
+ readJson = async (file) => JSON.parse(await import_promises32.default.readFile(file, "utf8"));
34106
34225
  boundResearchPath = async (root, relative) => {
34107
- const target = import_node_path25.default.resolve(root, relative);
34108
- const realRoot = await import_promises31.default.realpath(root);
34226
+ const target = import_node_path26.default.resolve(root, relative);
34227
+ const realRoot = await import_promises32.default.realpath(root);
34109
34228
  let ancestor = target;
34110
34229
  while (true) {
34111
34230
  try {
34112
- const real = await import_promises31.default.realpath(ancestor);
34113
- if (real !== realRoot && !real.startsWith(`${realRoot}${import_node_path25.default.sep}`))
34231
+ const real = await import_promises32.default.realpath(ancestor);
34232
+ if (real !== realRoot && !real.startsWith(`${realRoot}${import_node_path26.default.sep}`))
34114
34233
  throw new Error(`Research path escapes Project: ${relative}`);
34115
34234
  break;
34116
34235
  } catch (error) {
34117
34236
  if (error.code !== "ENOENT") throw error;
34118
- const parent = import_node_path25.default.dirname(ancestor);
34237
+ const parent = import_node_path26.default.dirname(ancestor);
34119
34238
  if (parent === ancestor) throw error;
34120
34239
  ancestor = parent;
34121
34240
  }
@@ -34127,9 +34246,9 @@ var init_io2 = __esm({
34127
34246
  projectRoot18,
34128
34247
  "data/research/strategy/.lock"
34129
34248
  );
34130
- await import_promises31.default.mkdir(import_node_path25.default.dirname(file), { recursive: true });
34131
- const token = (0, import_node_crypto19.randomUUID)();
34132
- const acquire = () => import_promises31.default.writeFile(
34249
+ await import_promises32.default.mkdir(import_node_path26.default.dirname(file), { recursive: true });
34250
+ const token = (0, import_node_crypto18.randomUUID)();
34251
+ const acquire = () => import_promises32.default.writeFile(
34133
34252
  file,
34134
34253
  JSON.stringify({ pid: process.pid, host: import_node_os3.default.hostname(), token }),
34135
34254
  { flag: "wx", mode: 384 }
@@ -34150,18 +34269,18 @@ var init_io2 = __esm({
34150
34269
  if (probe.code === "ESRCH") alive = false;
34151
34270
  }
34152
34271
  if (alive) throw new Error(`Research is already running (pid=${lock.pid})`);
34153
- await import_promises31.default.unlink(file);
34272
+ await import_promises32.default.unlink(file);
34154
34273
  await acquire();
34155
34274
  }
34156
34275
  try {
34157
34276
  return await work();
34158
34277
  } finally {
34159
34278
  const owner = await readJson(file);
34160
- if (owner.token === token) await import_promises31.default.unlink(file);
34279
+ if (owner.token === token) await import_promises32.default.unlink(file);
34161
34280
  }
34162
34281
  };
34163
34282
  verifyResearchState = async (directory, state) => {
34164
- const frozenSpec = await readJson(import_node_path25.default.join(directory, "spec.json"));
34283
+ const frozenSpec = await readJson(import_node_path26.default.join(directory, "spec.json"));
34165
34284
  if (sha256Json(frozenSpec) !== state.specSha256)
34166
34285
  throw new Error("Frozen research spec changed");
34167
34286
  for (const [name, stage] of Object.entries(state.stages)) {
@@ -34180,14 +34299,14 @@ var init_io2 = __esm({
34180
34299
  };
34181
34300
  verifyCompletedResearch = async (directory, state) => {
34182
34301
  await verifyResearchState(directory, state);
34183
- const manifest = await readJson(import_node_path25.default.join(directory, "manifest.json"));
34302
+ const manifest = await readJson(import_node_path26.default.join(directory, "manifest.json"));
34184
34303
  if (manifest.specSha256 !== state.specSha256)
34185
34304
  throw new Error("Final manifest spec mismatch");
34186
34305
  for (const [relative, expected] of Object.entries(manifest.artifacts))
34187
34306
  if (await sha256File(await boundResearchPath(directory, relative)) !== expected)
34188
34307
  throw new Error(`Changed final research artifact: ${relative}`);
34189
- const inventory = await readJson(import_node_path25.default.join(directory, "retention.json"));
34190
- const projectRoot18 = import_node_path25.default.resolve(directory, "../../../..");
34308
+ const inventory = await readJson(import_node_path26.default.join(directory, "retention.json"));
34309
+ const projectRoot18 = import_node_path26.default.resolve(directory, "../../../..");
34191
34310
  for (const artifact of inventory.research.permanentArtifacts) {
34192
34311
  const file = await boundResearchPath(projectRoot18, artifact.path);
34193
34312
  if (await sha256File(file) !== artifact.sha256)
@@ -34195,8 +34314,8 @@ var init_io2 = __esm({
34195
34314
  }
34196
34315
  };
34197
34316
  initializeResearchState = async (directory, spec, lineage) => {
34198
- await import_promises31.default.mkdir(directory, { recursive: true });
34199
- const file = import_node_path25.default.join(directory, "state.json");
34317
+ await import_promises32.default.mkdir(directory, { recursive: true });
34318
+ const file = import_node_path26.default.join(directory, "state.json");
34200
34319
  let previous;
34201
34320
  try {
34202
34321
  previous = await readJson(file);
@@ -34220,18 +34339,18 @@ var init_io2 = __esm({
34220
34339
  status: "running",
34221
34340
  stages: {}
34222
34341
  };
34223
- await writeJsonAtomic(import_node_path25.default.join(directory, "spec.json"), spec);
34342
+ await writeJsonAtomic(import_node_path26.default.join(directory, "spec.json"), spec);
34224
34343
  await writeJsonAtomic(file, state);
34225
34344
  return state;
34226
34345
  };
34227
34346
  isRetainedDeletion = async (directory, file, hash2) => {
34228
34347
  try {
34229
- const inventory = await readJson(import_node_path25.default.join(directory, "retention.json"));
34348
+ const inventory = await readJson(import_node_path26.default.join(directory, "retention.json"));
34230
34349
  const index = inventory.entries.findIndex(
34231
34350
  (entry) => entry.path === file && entry.sha256 === hash2
34232
34351
  );
34233
34352
  if (index < 0) return false;
34234
- const receipt = await readJson(import_node_path25.default.join(directory, "retention", `${index}.json`));
34353
+ const receipt = await readJson(import_node_path26.default.join(directory, "retention", `${index}.json`));
34235
34354
  return ["applying", "completed"].includes(receipt.status) && receipt.files[0]?.path === file && receipt.files[0]?.sha256 === hash2;
34236
34355
  } catch (error) {
34237
34356
  if (error.code === "ENOENT") return false;
@@ -35271,11 +35390,11 @@ var init_report2 = __esm({
35271
35390
  });
35272
35391
 
35273
35392
  // src/lib/strategyRelease/researchFileConsumers.ts
35274
- var import_node_path26, import_node_child_process7, import_node_util, execFileAsync, runCommand3, GUEST_FILE_CHECK, assertNoResearchFileConsumers;
35393
+ var import_node_path27, import_node_child_process7, import_node_util, execFileAsync, runCommand3, GUEST_FILE_CHECK, assertNoResearchFileConsumers;
35275
35394
  var init_researchFileConsumers = __esm({
35276
35395
  "src/lib/strategyRelease/researchFileConsumers.ts"() {
35277
35396
  "use strict";
35278
- import_node_path26 = __toESM(require("path"));
35397
+ import_node_path27 = __toESM(require("path"));
35279
35398
  import_node_child_process7 = require("child_process");
35280
35399
  import_node_util = require("util");
35281
35400
  execFileAsync = (0, import_node_util.promisify)(import_node_child_process7.execFile);
@@ -35306,15 +35425,15 @@ print(json.dumps(sorted(opened)))
35306
35425
  `;
35307
35426
  assertNoResearchFileConsumers = async (files, run = runCommand3) => {
35308
35427
  const virtualPids = /* @__PURE__ */ new Set();
35309
- const wanted = new Set(files.map((file) => import_node_path26.default.resolve(file)));
35310
- let commonRoot = files.length ? import_node_path26.default.dirname(files[0]) : "";
35428
+ const wanted = new Set(files.map((file) => import_node_path27.default.resolve(file)));
35429
+ let commonRoot = files.length ? import_node_path27.default.dirname(files[0]) : "";
35311
35430
  while (commonRoot && files.some((file) => {
35312
- const relative = import_node_path26.default.relative(commonRoot, file);
35313
- return relative === ".." || relative.startsWith(`..${import_node_path26.default.sep}`) || import_node_path26.default.isAbsolute(relative);
35431
+ const relative = import_node_path27.default.relative(commonRoot, file);
35432
+ return relative === ".." || relative.startsWith(`..${import_node_path27.default.sep}`) || import_node_path27.default.isAbsolute(relative);
35314
35433
  }))
35315
- commonRoot = import_node_path26.default.dirname(commonRoot);
35434
+ commonRoot = import_node_path27.default.dirname(commonRoot);
35316
35435
  const selectors = [];
35317
- if (files.length > 1e3 && commonRoot !== import_node_path26.default.parse(commonRoot).root) {
35436
+ if (files.length > 1e3 && commonRoot !== import_node_path27.default.parse(commonRoot).root) {
35318
35437
  selectors.push(["+D", commonRoot]);
35319
35438
  } else {
35320
35439
  for (let offset = 0; offset < files.length; offset += 100)
@@ -35338,7 +35457,7 @@ print(json.dumps(sorted(opened)))
35338
35457
  if (line.startsWith("c"))
35339
35458
  virtual = line.startsWith("ccom.apple.Virtualization.");
35340
35459
  if (line.startsWith("n")) {
35341
- if (!wanted.has(import_node_path26.default.resolve(line.slice(1)))) continue;
35460
+ if (!wanted.has(import_node_path27.default.resolve(line.slice(1)))) continue;
35342
35461
  if (!virtual || !/^\d+$/.test(pid))
35343
35462
  throw new Error(
35344
35463
  `Research cleanup found open files: ${line.slice(1)}`
@@ -35372,9 +35491,9 @@ print(json.dumps(sorted(opened)))
35372
35491
  for (const mount of container.Mounts) {
35373
35492
  if (mount.Type !== "bind") continue;
35374
35493
  for (const file of files) {
35375
- const relative = import_node_path26.default.relative(mount.Source, file);
35376
- if (relative === "" || !relative.startsWith(`..${import_node_path26.default.sep}`) && relative !== ".." && !import_node_path26.default.isAbsolute(relative)) {
35377
- guestFiles.add(import_node_path26.default.posix.join(mount.Destination, relative));
35494
+ const relative = import_node_path27.default.relative(mount.Source, file);
35495
+ if (relative === "" || !relative.startsWith(`..${import_node_path27.default.sep}`) && relative !== ".." && !import_node_path27.default.isAbsolute(relative)) {
35496
+ guestFiles.add(import_node_path27.default.posix.join(mount.Destination, relative));
35378
35497
  covered.add(file);
35379
35498
  }
35380
35499
  }
@@ -35455,14 +35574,14 @@ var init_evidenceRetention = __esm({
35455
35574
  });
35456
35575
 
35457
35576
  // src/lib/strategyRelease/researchRetention.ts
35458
- var import_promises32, import_researchMetricSnapshot, import_node_path27, import_node_crypto20, import_strategyReleaseEvidence2, SHA256_RE2, mapFiles, fileSha256, inside, applyResearchRetention;
35577
+ var import_promises33, import_researchMetricSnapshot, import_node_path28, import_node_crypto19, import_strategyReleaseEvidence2, SHA256_RE2, mapFiles, fileSha256, inside, applyResearchRetention;
35459
35578
  var init_researchRetention = __esm({
35460
35579
  "src/lib/strategyRelease/researchRetention.ts"() {
35461
35580
  "use strict";
35462
- import_promises32 = __toESM(require("fs/promises"));
35581
+ import_promises33 = __toESM(require("fs/promises"));
35463
35582
  import_researchMetricSnapshot = require("@tradejs/infra/researchMetricSnapshot");
35464
- import_node_path27 = __toESM(require("path"));
35465
- import_node_crypto20 = require("crypto");
35583
+ import_node_path28 = __toESM(require("path"));
35584
+ import_node_crypto19 = require("crypto");
35466
35585
  import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
35467
35586
  init_researchFileConsumers();
35468
35587
  init_evidenceRetention();
@@ -35482,15 +35601,15 @@ var init_researchRetention = __esm({
35482
35601
  if (worker.status === "rejected") throw worker.reason;
35483
35602
  return results2;
35484
35603
  };
35485
- fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto20.createHash)("sha256").update(await import_promises32.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(file);
35604
+ fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto19.createHash)("sha256").update(await import_promises33.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(file);
35486
35605
  inside = (root, file) => {
35487
- const relative = import_node_path27.default.relative(root, file);
35488
- return relative !== "" && !relative.startsWith(`..${import_node_path27.default.sep}`) && relative !== ".." && !import_node_path27.default.isAbsolute(relative);
35606
+ const relative = import_node_path28.default.relative(root, file);
35607
+ return relative !== "" && !relative.startsWith(`..${import_node_path28.default.sep}`) && relative !== ".." && !import_node_path28.default.isAbsolute(relative);
35489
35608
  };
35490
35609
  applyResearchRetention = async (options) => {
35491
- const projectRoot18 = await import_promises32.default.realpath(options.projectRoot);
35492
- const dataRoot = import_node_path27.default.join(projectRoot18, "data");
35493
- const resolve = (file) => import_node_path27.default.resolve(projectRoot18, file);
35610
+ const projectRoot18 = await import_promises33.default.realpath(options.projectRoot);
35611
+ const dataRoot = import_node_path28.default.join(projectRoot18, "data");
35612
+ const resolve = (file) => import_node_path28.default.resolve(projectRoot18, file);
35494
35613
  const receiptPath2 = resolve(options.receiptPath);
35495
35614
  const journalPath = `${receiptPath2}.deleted.jsonl`;
35496
35615
  const permanent = new Set(
@@ -35515,13 +35634,13 @@ var init_researchRetention = __esm({
35515
35634
  }
35516
35635
  await mapFiles(options.research.permanentArtifacts, async (artifact) => {
35517
35636
  const file = resolve(artifact.path);
35518
- if (!inside(projectRoot18, await import_promises32.default.realpath(file)) || !SHA256_RE2.test(artifact.sha256) || await fileSha256(file, (await import_promises32.default.stat(file)).size) !== artifact.sha256) {
35637
+ if (!inside(projectRoot18, await import_promises33.default.realpath(file)) || !SHA256_RE2.test(artifact.sha256) || await fileSha256(file, (await import_promises33.default.stat(file)).size) !== artifact.sha256) {
35519
35638
  throw new Error(
35520
35639
  `Permanent research artifact checksum/path mismatch: ${file}`
35521
35640
  );
35522
35641
  }
35523
35642
  if (artifact.role === "note") {
35524
- const handle = await import_promises32.default.open(file, "r");
35643
+ const handle = await import_promises33.default.open(file, "r");
35525
35644
  try {
35526
35645
  const header = Buffer.alloc(4096);
35527
35646
  const { bytesRead } = await handle.read(header, 0, header.length, 0);
@@ -35534,9 +35653,9 @@ var init_researchRetention = __esm({
35534
35653
  );
35535
35654
  }
35536
35655
  if (!retired && /^schema:\s*tradejs-research\/v2\s*$/m.test(frontmatter[1])) {
35537
- if ((await import_promises32.default.stat(file)).size > 8 * 1024 * 1024)
35656
+ if ((await import_promises33.default.stat(file)).size > 8 * 1024 * 1024)
35538
35657
  throw new Error("Compact permanent note exceeds 8 MiB");
35539
- const content = await import_promises32.default.readFile(file, "utf8");
35658
+ const content = await import_promises33.default.readFile(file, "utf8");
35540
35659
  const section = content.split("## Metrics snapshot (machine-readable)")[1]?.split("## Reported metrics")[0] ?? "";
35541
35660
  const blocks = [
35542
35661
  ...section.matchAll(/```json\r?\n([\s\S]*?)\r?\n```/g)
@@ -35561,9 +35680,9 @@ var init_researchRetention = __esm({
35561
35680
  if (checkedPaths.has(file))
35562
35681
  throw new Error(`Duplicate cleanup path: ${file}`);
35563
35682
  checkedPaths.add(file);
35564
- if (await import_promises32.default.realpath(file) !== file)
35683
+ if (await import_promises33.default.realpath(file) !== file)
35565
35684
  throw new Error(`Research cleanup refuses symlinks: ${file}`);
35566
- const stat = await import_promises32.default.lstat(file);
35685
+ const stat = await import_promises33.default.lstat(file);
35567
35686
  if (!stat.isFile() || stat.size !== entry.bytes || await fileSha256(file, stat.size) !== entry.sha256) {
35568
35687
  throw new Error(
35569
35688
  `Disposable research file checksum/size mismatch: ${file}`
@@ -35589,29 +35708,29 @@ var init_researchRetention = __esm({
35589
35708
  }))
35590
35709
  };
35591
35710
  if (!options.apply) return receipt;
35592
- await import_promises32.default.mkdir(import_node_path27.default.dirname(receiptPath2), { recursive: true });
35593
- if (await import_promises32.default.realpath(import_node_path27.default.dirname(receiptPath2)) !== import_node_path27.default.dirname(receiptPath2)) {
35711
+ await import_promises33.default.mkdir(import_node_path28.default.dirname(receiptPath2), { recursive: true });
35712
+ if (await import_promises33.default.realpath(import_node_path28.default.dirname(receiptPath2)) !== import_node_path28.default.dirname(receiptPath2)) {
35594
35713
  throw new Error("Cleanup receipt refuses symlinked directories");
35595
35714
  }
35596
- const lock = await import_promises32.default.open(`${receiptPath2}.lock`, "wx");
35715
+ const lock = await import_promises33.default.open(`${receiptPath2}.lock`, "wx");
35597
35716
  let journal;
35598
35717
  const writeReceipt = async () => {
35599
35718
  const temp = `${receiptPath2}.${process.pid}.tmp`;
35600
- await import_promises32.default.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
35719
+ await import_promises33.default.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
35601
35720
  `, "utf8");
35602
- await import_promises32.default.rename(temp, receiptPath2);
35721
+ await import_promises33.default.rename(temp, receiptPath2);
35603
35722
  };
35604
35723
  try {
35605
- journal = await import_promises32.default.open(journalPath, "wx");
35724
+ journal = await import_promises33.default.open(journalPath, "wx");
35606
35725
  receipt.status = "applying";
35607
35726
  await writeReceipt();
35608
35727
  for (let index = 0; index < checked.length; index += 1) {
35609
35728
  const { file, entry, ino, mtimeMs } = checked[index];
35610
- const stat = await import_promises32.default.lstat(file);
35729
+ const stat = await import_promises33.default.lstat(file);
35611
35730
  if (!stat.isFile() || stat.ino !== ino || stat.mtimeMs !== mtimeMs || stat.size !== entry.bytes) {
35612
35731
  throw new Error(`Research file changed during cleanup: ${file}`);
35613
35732
  }
35614
- await import_promises32.default.unlink(file);
35733
+ await import_promises33.default.unlink(file);
35615
35734
  receipt.files[index].removed = true;
35616
35735
  await journal.write(`${JSON.stringify(receipt.files[index])}
35617
35736
  `);
@@ -35625,19 +35744,19 @@ var init_researchRetention = __esm({
35625
35744
  } finally {
35626
35745
  await journal?.close();
35627
35746
  await lock.close();
35628
- await import_promises32.default.unlink(`${receiptPath2}.lock`);
35747
+ await import_promises33.default.unlink(`${receiptPath2}.lock`);
35629
35748
  }
35630
35749
  };
35631
35750
  }
35632
35751
  });
35633
35752
 
35634
35753
  // src/lib/strategyResearch/retention.ts
35635
- var import_promises33, import_node_path28, createResearchRetentionInventory, applyRetentionInventory, finishResearchRetention;
35754
+ var import_promises34, import_node_path29, createResearchRetentionInventory, applyRetentionInventory, finishResearchRetention;
35636
35755
  var init_retention = __esm({
35637
35756
  "src/lib/strategyResearch/retention.ts"() {
35638
35757
  "use strict";
35639
- import_promises33 = __toESM(require("fs/promises"));
35640
- import_node_path28 = __toESM(require("path"));
35758
+ import_promises34 = __toESM(require("fs/promises"));
35759
+ import_node_path29 = __toESM(require("path"));
35641
35760
  init_researchRetention();
35642
35761
  init_io();
35643
35762
  init_io2();
@@ -35645,17 +35764,17 @@ var init_retention = __esm({
35645
35764
  const permanentArtifacts = [];
35646
35765
  for (const [role, file] of [
35647
35766
  ["note", notePath],
35648
- ["metrics", import_node_path28.default.join(directory, "result.json")],
35649
- ["candidates", import_node_path28.default.join(directory, "03-freeze-gates/result.json")],
35650
- ["candidates", import_node_path28.default.join(directory, "resolved-spec.json")],
35651
- ["ledger", import_node_path28.default.join(directory, "05-freeze-primary/result.json")],
35652
- ["chart", import_node_path28.default.join(directory, "report.html")],
35767
+ ["metrics", import_node_path29.default.join(directory, "result.json")],
35768
+ ["candidates", import_node_path29.default.join(directory, "03-freeze-gates/result.json")],
35769
+ ["candidates", import_node_path29.default.join(directory, "resolved-spec.json")],
35770
+ ["ledger", import_node_path29.default.join(directory, "05-freeze-primary/result.json")],
35771
+ ["chart", import_node_path29.default.join(directory, "report.html")],
35653
35772
  ...[
35654
35773
  "source.patch",
35655
35774
  "source-baseline.tar",
35656
35775
  "source-untracked.json",
35657
35776
  "source-jev-models.json"
35658
- ].map((file2) => ["source", import_node_path28.default.join(directory, file2)])
35777
+ ].map((file2) => ["source", import_node_path29.default.join(directory, file2)])
35659
35778
  ]) {
35660
35779
  try {
35661
35780
  permanentArtifacts.push({
@@ -35682,7 +35801,7 @@ var init_retention = __esm({
35682
35801
  (variant) => variant.files.includes(source)
35683
35802
  ))
35684
35803
  files.set(
35685
- await import_promises33.default.realpath(await boundResearchPath(projectRoot18, source)),
35804
+ await import_promises34.default.realpath(await boundResearchPath(projectRoot18, source)),
35686
35805
  sha2
35687
35806
  );
35688
35807
  }
@@ -35691,7 +35810,7 @@ var init_retention = __esm({
35691
35810
  }
35692
35811
  const entries = [];
35693
35812
  for (const [file, hash2] of files) {
35694
- const stat = await import_promises33.default.stat(file);
35813
+ const stat = await import_promises34.default.stat(file);
35695
35814
  entries.push({
35696
35815
  path: file,
35697
35816
  kind: "research_payload",
@@ -35715,13 +35834,13 @@ var init_retention = __esm({
35715
35834
  };
35716
35835
  applyRetentionInventory = async (projectRoot18, directory) => {
35717
35836
  const inventory = await readJson(
35718
- import_node_path28.default.join(directory, "retention.json")
35837
+ import_node_path29.default.join(directory, "retention.json")
35719
35838
  );
35720
- const receipts = import_node_path28.default.join(directory, "retention");
35721
- await import_promises33.default.mkdir(receipts, { recursive: true });
35839
+ const receipts = import_node_path29.default.join(directory, "retention");
35840
+ await import_promises34.default.mkdir(receipts, { recursive: true });
35722
35841
  for (let index = 0; index < inventory.entries.length; index++) {
35723
35842
  const entry = inventory.entries[index];
35724
- const receiptPath2 = import_node_path28.default.join(receipts, `${index}.json`);
35843
+ const receiptPath2 = import_node_path29.default.join(receipts, `${index}.json`);
35725
35844
  let receipt;
35726
35845
  try {
35727
35846
  receipt = await readJson(receiptPath2);
@@ -35736,7 +35855,7 @@ var init_retention = __esm({
35736
35855
  );
35737
35856
  if (receipt.status === "completed" && recorded.removed) continue;
35738
35857
  try {
35739
- await import_promises33.default.stat(entry.path);
35858
+ await import_promises34.default.stat(entry.path);
35740
35859
  } catch (error) {
35741
35860
  if (error.code !== "ENOENT") throw error;
35742
35861
  if (receipt.status !== "applying") throw error;
@@ -35757,13 +35876,13 @@ var init_retention = __esm({
35757
35876
  entries: [entry],
35758
35877
  receiptPath: receiptPath2,
35759
35878
  apply: true,
35760
- protectedPaths: [import_node_path28.default.join(directory, "retention.json")]
35879
+ protectedPaths: [import_node_path29.default.join(directory, "retention.json")]
35761
35880
  });
35762
35881
  }
35763
35882
  return { status: "completed", files: inventory.entries.length };
35764
35883
  };
35765
35884
  finishResearchRetention = async (projectRoot18, directory) => {
35766
- const statusPath = import_node_path28.default.join(directory, "retention-status.json");
35885
+ const statusPath = import_node_path29.default.join(directory, "retention-status.json");
35767
35886
  try {
35768
35887
  const result = await applyRetentionInventory(projectRoot18, directory);
35769
35888
  await writeJsonAtomic(statusPath, result);
@@ -35780,13 +35899,13 @@ var init_retention = __esm({
35780
35899
  });
35781
35900
 
35782
35901
  // src/lib/strategyResearch/orchestrator.ts
35783
- var import_promises34, import_researchMetricSnapshot2, import_node_path29, runStrategyResearch;
35902
+ var import_promises35, import_researchMetricSnapshot2, import_node_path30, runStrategyResearch;
35784
35903
  var init_orchestrator2 = __esm({
35785
35904
  "src/lib/strategyResearch/orchestrator.ts"() {
35786
35905
  "use strict";
35787
- import_promises34 = __toESM(require("fs/promises"));
35906
+ import_promises35 = __toESM(require("fs/promises"));
35788
35907
  import_researchMetricSnapshot2 = require("@tradejs/infra/researchMetricSnapshot");
35789
- import_node_path29 = __toESM(require("path"));
35908
+ import_node_path30 = __toESM(require("path"));
35790
35909
  init_metrics();
35791
35910
  init_io();
35792
35911
  init_specification();
@@ -35801,7 +35920,7 @@ var init_orchestrator2 = __esm({
35801
35920
  runStrategyResearch = async (parameters) => {
35802
35921
  let spec = validateStrategyResearchSpec(parameters.spec);
35803
35922
  const { backend } = parameters;
35804
- const projectRoot18 = await import_promises34.default.realpath(parameters.projectRoot);
35923
+ const projectRoot18 = await import_promises35.default.realpath(parameters.projectRoot);
35805
35924
  await boundResearchPath(
35806
35925
  projectRoot18,
35807
35926
  `data/research/strategy/${spec.core.researchId}`
@@ -35810,7 +35929,7 @@ var init_orchestrator2 = __esm({
35810
35929
  const directory = researchDirectory(projectRoot18, spec);
35811
35930
  const lineage = await backend.lineage();
35812
35931
  const state = await initializeResearchState(directory, spec, lineage);
35813
- const statePath = import_node_path29.default.join(directory, "state.json");
35932
+ const statePath = import_node_path30.default.join(directory, "state.json");
35814
35933
  const elapsedBefore = state.elapsedMs ?? 0;
35815
35934
  const activeStart = Date.now();
35816
35935
  const elapsed = () => elapsedBefore + Date.now() - activeStart;
@@ -35820,7 +35939,7 @@ var init_orchestrator2 = __esm({
35820
35939
  directory,
35821
35940
  state,
35822
35941
  conclusion: await readJson(
35823
- import_node_path29.default.join(directory, "result.json")
35942
+ import_node_path30.default.join(directory, "result.json")
35824
35943
  )
35825
35944
  };
35826
35945
  }
@@ -35829,14 +35948,14 @@ var init_orchestrator2 = __esm({
35829
35948
  state.elapsedMs = elapsed();
35830
35949
  return writeJsonAtomic(statePath, state);
35831
35950
  };
35832
- const event = async (stage2, status) => import_promises34.default.appendFile(
35833
- import_node_path29.default.join(directory, "events.jsonl"),
35951
+ const event = async (stage2, status) => import_promises35.default.appendFile(
35952
+ import_node_path30.default.join(directory, "events.jsonl"),
35834
35953
  `${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), stage: stage2, status, specSha256: state.specSha256 })}
35835
35954
  `
35836
35955
  );
35837
35956
  const stage = async (name, work) => {
35838
35957
  const stageDirectory = await boundResearchPath(directory, name);
35839
- const resultPath = import_node_path29.default.join(stageDirectory, "result.json");
35958
+ const resultPath = import_node_path30.default.join(stageDirectory, "result.json");
35840
35959
  if (state.stages[name]?.status === "completed")
35841
35960
  return readJson(resultPath);
35842
35961
  if (elapsed() > spec.budget.maxMinutes * 6e4)
@@ -35851,20 +35970,20 @@ var init_orchestrator2 = __esm({
35851
35970
  };
35852
35971
  state.status = "running";
35853
35972
  delete state.error;
35854
- await import_promises34.default.mkdir(stageDirectory, { recursive: true });
35973
+ await import_promises35.default.mkdir(stageDirectory, { recursive: true });
35855
35974
  await save();
35856
35975
  await event(name, "started");
35857
- await import_promises34.default.writeFile(
35858
- import_node_path29.default.join(directory, "report.html"),
35976
+ await import_promises35.default.writeFile(
35977
+ import_node_path30.default.join(directory, "report.html"),
35859
35978
  buildStrategyResearchReport({ spec, state, diagnostics })
35860
35979
  );
35861
35980
  try {
35862
35981
  const result = await work(stageDirectory);
35863
35982
  await writeJsonAtomic(resultPath, result);
35864
35983
  const artifacts = {};
35865
- for (const file of await import_promises34.default.readdir(stageDirectory)) {
35866
- const full = import_node_path29.default.join(stageDirectory, file);
35867
- if ((await import_promises34.default.stat(full)).isFile())
35984
+ for (const file of await import_promises35.default.readdir(stageDirectory)) {
35985
+ const full = import_node_path30.default.join(stageDirectory, file);
35986
+ if ((await import_promises35.default.stat(full)).isFile())
35868
35987
  artifacts[`${name}/${file}`] = await sha256File(full);
35869
35988
  }
35870
35989
  if (name === "01-preflight") {
@@ -35875,7 +35994,7 @@ var init_orchestrator2 = __esm({
35875
35994
  "source-jev-models.json"
35876
35995
  ]) {
35877
35996
  try {
35878
- artifacts[file] = await sha256File(import_node_path29.default.join(directory, file));
35997
+ artifacts[file] = await sha256File(import_node_path30.default.join(directory, file));
35879
35998
  } catch (error) {
35880
35999
  if (error.code !== "ENOENT")
35881
36000
  throw error;
@@ -35908,14 +36027,14 @@ var init_orchestrator2 = __esm({
35908
36027
  let previousRunId;
35909
36028
  try {
35910
36029
  previousRunId = (await readJson(
35911
- import_node_path29.default.join(folder, "native-run.json")
36030
+ import_node_path30.default.join(folder, "native-run.json")
35912
36031
  )).runId;
35913
36032
  } catch (error) {
35914
36033
  if (error.code !== "ENOENT") throw error;
35915
36034
  }
35916
36035
  if (!previousRunId) {
35917
36036
  try {
35918
- if ((await import_promises34.default.stat(import_node_path29.default.join(folder, "backtest.log"))).size)
36037
+ if ((await import_promises35.default.stat(import_node_path30.default.join(folder, "backtest.log"))).size)
35919
36038
  throw new Error(
35920
36039
  "Previous native attempt has no recorded run identity; inspect its log before another launch"
35921
36040
  );
@@ -35936,7 +36055,7 @@ var init_orchestrator2 = __esm({
35936
36055
  },
35937
36056
  variant,
35938
36057
  folder,
35939
- async (runId) => writeJsonAtomic(import_node_path29.default.join(folder, "native-run.json"), { runId }),
36058
+ async (runId) => writeJsonAtomic(import_node_path30.default.join(folder, "native-run.json"), { runId }),
35940
36059
  previousRunId,
35941
36060
  confirmation
35942
36061
  );
@@ -35951,15 +36070,15 @@ var init_orchestrator2 = __esm({
35951
36070
  try {
35952
36071
  const inventory = await stage("01-preflight", async () => {
35953
36072
  const prior = [];
35954
- const root = import_node_path29.default.dirname(directory);
35955
- for (const id of await import_promises34.default.readdir(root)) {
36073
+ const root = import_node_path30.default.dirname(directory);
36074
+ for (const id of await import_promises35.default.readdir(root)) {
35956
36075
  if (id === spec.core.researchId || id.startsWith(".")) continue;
35957
36076
  try {
35958
36077
  const previous = await readJson(
35959
- import_node_path29.default.join(root, id, "spec.json")
36078
+ import_node_path30.default.join(root, id, "spec.json")
35960
36079
  );
35961
36080
  const previousState = await readJson(
35962
- import_node_path29.default.join(root, id, "state.json")
36081
+ import_node_path30.default.join(root, id, "state.json")
35963
36082
  );
35964
36083
  const overlap = previous.core.strategy === spec.core.strategy && previous.core.window.start < spec.core.window.end && previous.core.window.end > (spec.testSince || spec.core.window.start);
35965
36084
  if (overlap && previousState.holdoutOpenedAt)
@@ -35985,7 +36104,7 @@ var init_orchestrator2 = __esm({
35985
36104
  let previous;
35986
36105
  try {
35987
36106
  previous = (await readJson(
35988
- import_node_path29.default.join(folder, "native-run.json")
36107
+ import_node_path30.default.join(folder, "native-run.json")
35989
36108
  )).runId;
35990
36109
  } catch (error) {
35991
36110
  if (error.code !== "ENOENT")
@@ -35995,7 +36114,7 @@ var init_orchestrator2 = __esm({
35995
36114
  spec,
35996
36115
  control,
35997
36116
  folder,
35998
- async (runId) => writeJsonAtomic(import_node_path29.default.join(folder, "native-run.json"), {
36117
+ async (runId) => writeJsonAtomic(import_node_path30.default.join(folder, "native-run.json"), {
35999
36118
  runId
36000
36119
  }),
36001
36120
  previous
@@ -36009,7 +36128,7 @@ var init_orchestrator2 = __esm({
36009
36128
  );
36010
36129
  spec = { ...spec, testSince: partition.testSince };
36011
36130
  }
36012
- await writeJsonAtomic(import_node_path29.default.join(directory, "resolved-spec.json"), spec);
36131
+ await writeJsonAtomic(import_node_path30.default.join(directory, "resolved-spec.json"), spec);
36013
36132
  let gates = [];
36014
36133
  let primaryId = null;
36015
36134
  let frozenSelection;
@@ -36065,10 +36184,10 @@ var init_orchestrator2 = __esm({
36065
36184
  core: { ...spec.core, researchId: spec.frozenFrom }
36066
36185
  });
36067
36186
  const parentState = await readJson(
36068
- import_node_path29.default.join(parentDirectory, "state.json")
36187
+ import_node_path30.default.join(parentDirectory, "state.json")
36069
36188
  );
36070
36189
  const parentSpec = await readJson(
36071
- import_node_path29.default.join(parentDirectory, "spec.json")
36190
+ import_node_path30.default.join(parentDirectory, "spec.json")
36072
36191
  );
36073
36192
  const { verifyCompletedResearch: verifyCompletedResearch2 } = await Promise.resolve().then(() => (init_io2(), io_exports));
36074
36193
  await verifyCompletedResearch2(parentDirectory, parentState);
@@ -36095,10 +36214,10 @@ var init_orchestrator2 = __esm({
36095
36214
  "Frozen revalidation requires complete, unchanged rules/runtime and a strictly new period"
36096
36215
  );
36097
36216
  gates = await readJson(
36098
- import_node_path29.default.join(parentDirectory, "03-freeze-gates/result.json")
36217
+ import_node_path30.default.join(parentDirectory, "03-freeze-gates/result.json")
36099
36218
  );
36100
36219
  frozenSelection = await readJson(
36101
- import_node_path29.default.join(parentDirectory, "05-freeze-primary/result.json")
36220
+ import_node_path30.default.join(parentDirectory, "05-freeze-primary/result.json")
36102
36221
  );
36103
36222
  if (frozenSelection.schema !== "tradejs-research-selection/v1" || !Array.isArray(frozenSelection.compositions))
36104
36223
  throw new Error(
@@ -36227,7 +36346,7 @@ var init_orchestrator2 = __esm({
36227
36346
  `06-raw-metrics-${variant.id}`,
36228
36347
  async (folder) => {
36229
36348
  const resolved = spec.frozenFrom ? (await run(spec, variant, `06-raw-revalidation-${variant.id}`)).variant : (await readJson(
36230
- import_node_path29.default.join(directory, `02-raw-${variant.id}`, "result.json")
36349
+ import_node_path30.default.join(directory, `02-raw-${variant.id}`, "result.json")
36231
36350
  )).variant;
36232
36351
  const dataset = await backend.loadDataset(
36233
36352
  spec,
@@ -36404,7 +36523,7 @@ var init_orchestrator2 = __esm({
36404
36523
  for (const name of Object.keys(state.stages)) {
36405
36524
  try {
36406
36525
  const result = await readJson(
36407
- import_node_path29.default.join(directory, name, "result.json")
36526
+ import_node_path30.default.join(directory, name, "result.json")
36408
36527
  );
36409
36528
  if (result?.variant)
36410
36529
  executions.push({ stage: name, ...result.variant });
@@ -36412,7 +36531,7 @@ var init_orchestrator2 = __esm({
36412
36531
  if (error.code !== "ENOENT") throw error;
36413
36532
  }
36414
36533
  }
36415
- await writeJsonAtomic(import_node_path29.default.join(directory, "result.json"), {
36534
+ await writeJsonAtomic(import_node_path30.default.join(directory, "result.json"), {
36416
36535
  ...conclusion,
36417
36536
  executions,
36418
36537
  rawCore: Object.entries(rawReports).map(([id, windows]) => ({
@@ -36425,8 +36544,8 @@ var init_orchestrator2 = __esm({
36425
36544
  state.status = "completed";
36426
36545
  delete state.error;
36427
36546
  await save();
36428
- await import_promises34.default.writeFile(
36429
- import_node_path29.default.join(directory, "report.html"),
36547
+ await import_promises35.default.writeFile(
36548
+ import_node_path30.default.join(directory, "report.html"),
36430
36549
  buildStrategyResearchReport({
36431
36550
  spec,
36432
36551
  state,
@@ -36439,7 +36558,7 @@ var init_orchestrator2 = __esm({
36439
36558
  projectRoot18,
36440
36559
  `notes/${spec.core.strategy}`
36441
36560
  );
36442
- await import_promises34.default.mkdir(noteDirectory, { recursive: true });
36561
+ await import_promises35.default.mkdir(noteDirectory, { recursive: true });
36443
36562
  const compact = {
36444
36563
  ...conclusion,
36445
36564
  gates,
@@ -36513,8 +36632,8 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36513
36632
  throw new Error(
36514
36633
  "Compact permanent note exceeds 8 MiB; archive source separately, never truncate metrics"
36515
36634
  );
36516
- await import_promises34.default.writeFile(
36517
- import_node_path29.default.join(
36635
+ await import_promises35.default.writeFile(
36636
+ import_node_path30.default.join(
36518
36637
  noteDirectory,
36519
36638
  `${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
36520
36639
  ),
@@ -36522,8 +36641,8 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36522
36641
  { flag: "wx" }
36523
36642
  ).catch(async (error) => {
36524
36643
  if (error.code !== "EEXIST") throw error;
36525
- const existing = await import_promises34.default.readFile(
36526
- import_node_path29.default.join(
36644
+ const existing = await import_promises35.default.readFile(
36645
+ import_node_path30.default.join(
36527
36646
  noteDirectory,
36528
36647
  `${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
36529
36648
  ),
@@ -36535,19 +36654,19 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36535
36654
  );
36536
36655
  });
36537
36656
  await writeJsonAtomic(
36538
- import_node_path29.default.join(directory, "retention.json"),
36657
+ import_node_path30.default.join(directory, "retention.json"),
36539
36658
  await createResearchRetentionInventory(
36540
36659
  projectRoot18,
36541
36660
  directory,
36542
36661
  spec,
36543
36662
  state,
36544
- import_node_path29.default.join(
36663
+ import_node_path30.default.join(
36545
36664
  noteDirectory,
36546
36665
  `${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
36547
36666
  )
36548
36667
  )
36549
36668
  );
36550
- await writeJsonAtomic(import_node_path29.default.join(directory, "manifest.json"), {
36669
+ await writeJsonAtomic(import_node_path30.default.join(directory, "manifest.json"), {
36551
36670
  schema: "tradejs-strategy-research-manifest/v1",
36552
36671
  specSha256: state.specSha256,
36553
36672
  artifacts: Object.fromEntries(
@@ -36561,7 +36680,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36561
36680
  "retention.json"
36562
36681
  ].map(async (file) => [
36563
36682
  file,
36564
- await sha256File(import_node_path29.default.join(directory, file))
36683
+ await sha256File(import_node_path30.default.join(directory, file))
36565
36684
  ])
36566
36685
  )
36567
36686
  )
@@ -36574,7 +36693,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36574
36693
  );
36575
36694
  }
36576
36695
  parameters.onProgress?.(
36577
- `\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${import_node_path29.default.join(directory, "report.html")}`
36696
+ `\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${import_node_path30.default.join(directory, "report.html")}`
36578
36697
  );
36579
36698
  return { directory, state, conclusion };
36580
36699
  } catch (error) {
@@ -36595,9 +36714,9 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36595
36714
  frozenGates: 0
36596
36715
  }
36597
36716
  };
36598
- await writeJsonAtomic(import_node_path29.default.join(directory, "result.json"), conclusion);
36599
- await import_promises34.default.writeFile(
36600
- import_node_path29.default.join(directory, "report.html"),
36717
+ await writeJsonAtomic(import_node_path30.default.join(directory, "result.json"), conclusion);
36718
+ await import_promises35.default.writeFile(
36719
+ import_node_path30.default.join(directory, "report.html"),
36601
36720
  buildStrategyResearchReport({ spec, state, conclusion, diagnostics })
36602
36721
  );
36603
36722
  throw error;
@@ -36608,18 +36727,18 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
36608
36727
  });
36609
36728
 
36610
36729
  // src/lib/strategyResearch/native.ts
36611
- var import_promises35, import_node_fs9, import_node_path30, import_node_os4, import_node_readline4, import_node_child_process8, import_node_module3, import_redis18, import_ai9, import_backtest7, import_registry5, import_connectors15, import_data9, import_coreResearch2, import_jev6, validateResearchJevTraining, nativeConfig, runResearchCommand, createNativeStrategyResearchBackend;
36730
+ var import_promises36, import_node_fs9, import_node_path31, import_node_os4, import_node_readline4, import_node_child_process8, import_node_module3, import_redis19, import_ai9, import_backtest7, import_registry5, import_connectors15, import_data9, import_coreResearch2, import_jev6, validateResearchJevTraining, nativeConfig, runResearchCommand, createNativeStrategyResearchBackend;
36612
36731
  var init_native = __esm({
36613
36732
  "src/lib/strategyResearch/native.ts"() {
36614
36733
  "use strict";
36615
- import_promises35 = __toESM(require("fs/promises"));
36734
+ import_promises36 = __toESM(require("fs/promises"));
36616
36735
  import_node_fs9 = require("fs");
36617
- import_node_path30 = __toESM(require("path"));
36736
+ import_node_path31 = __toESM(require("path"));
36618
36737
  import_node_os4 = __toESM(require("os"));
36619
36738
  import_node_readline4 = __toESM(require("readline"));
36620
36739
  import_node_child_process8 = require("child_process");
36621
36740
  import_node_module3 = require("module");
36622
- import_redis18 = require("@tradejs/infra/redis");
36741
+ import_redis19 = require("@tradejs/infra/redis");
36623
36742
  import_ai9 = require("@tradejs/node/ai");
36624
36743
  import_backtest7 = require("@tradejs/node/backtest");
36625
36744
  import_registry5 = require("@tradejs/node/registry");
@@ -36780,7 +36899,7 @@ var init_native = __esm({
36780
36899
  };
36781
36900
  createNativeStrategyResearchBackend = (parameters) => {
36782
36901
  const { projectRoot: projectRoot18, sourceRepositoryRoot } = parameters;
36783
- const cliPath = import_node_path30.default.resolve(parameters.cliPath ?? process.argv[1]);
36902
+ const cliPath = import_node_path31.default.resolve(parameters.cliPath ?? process.argv[1]);
36784
36903
  let connector;
36785
36904
  const getConnector = async (spec) => {
36786
36905
  if (connector) return connector;
@@ -36859,57 +36978,57 @@ var init_native = __esm({
36859
36978
  const untrackedHashes = await Promise.all(
36860
36979
  untracked.map(async (file) => [
36861
36980
  file,
36862
- await sha256File(import_node_path30.default.join(sourceRepositoryRoot, file))
36981
+ await sha256File(import_node_path31.default.join(sourceRepositoryRoot, file))
36863
36982
  ])
36864
36983
  );
36865
36984
  const requireFromRuntime = (0, import_node_module3.createRequire)(cliPath);
36866
36985
  const hashes = {};
36867
36986
  const hashRuntimeDirectory = async (directory, label, root = directory) => {
36868
- for (const entry of await import_promises35.default.readdir(directory, {
36987
+ for (const entry of await import_promises36.default.readdir(directory, {
36869
36988
  withFileTypes: true
36870
36989
  })) {
36871
- const file = import_node_path30.default.join(directory, entry.name);
36990
+ const file = import_node_path31.default.join(directory, entry.name);
36872
36991
  if (entry.isDirectory())
36873
36992
  await hashRuntimeDirectory(file, label, root);
36874
36993
  else if (/\.(?:m?js|cjs|json)$/.test(entry.name))
36875
- hashes[`${label}:${import_node_path30.default.relative(root, file)}`] = await sha256File(file);
36994
+ hashes[`${label}:${import_node_path31.default.relative(root, file)}`] = await sha256File(file);
36876
36995
  }
36877
36996
  };
36878
- await hashRuntimeDirectory(import_node_path30.default.dirname(cliPath), "cli-runtime");
36997
+ await hashRuntimeDirectory(import_node_path31.default.dirname(cliPath), "cli-runtime");
36879
36998
  for (const entry of [
36880
36999
  "@tradejs/node/backtest",
36881
37000
  "@tradejs/node/ai",
36882
37001
  "@tradejs/core/strategies"
36883
37002
  ]) {
36884
37003
  const resolved = requireFromRuntime.resolve(entry);
36885
- const directory = import_node_path30.default.dirname(resolved);
37004
+ const directory = import_node_path31.default.dirname(resolved);
36886
37005
  await hashRuntimeDirectory(directory, entry);
36887
37006
  }
36888
- const projectPackages = import_node_path30.default.join(projectRoot18, "node_modules/@tradejs");
36889
- for (const name of (await import_promises35.default.readdir(projectPackages)).sort()) {
36890
- const packageRoot = import_node_path30.default.join(projectPackages, name);
37007
+ const projectPackages = import_node_path31.default.join(projectRoot18, "node_modules/@tradejs");
37008
+ for (const name of (await import_promises36.default.readdir(projectPackages)).sort()) {
37009
+ const packageRoot = import_node_path31.default.join(projectPackages, name);
36891
37010
  const visit = async (directory) => {
36892
- for (const entry of await import_promises35.default.readdir(directory, {
37011
+ for (const entry of await import_promises36.default.readdir(directory, {
36893
37012
  withFileTypes: true
36894
37013
  })) {
36895
- const file = import_node_path30.default.join(directory, entry.name);
37014
+ const file = import_node_path31.default.join(directory, entry.name);
36896
37015
  if (entry.isDirectory()) await visit(file);
36897
37016
  else if (/\.(?:m?js|cjs|json)$/.test(entry.name))
36898
- hashes[`installed:${name}:${import_node_path30.default.relative(packageRoot, file)}`] = await sha256File(file);
37017
+ hashes[`installed:${name}:${import_node_path31.default.relative(packageRoot, file)}`] = await sha256File(file);
36899
37018
  }
36900
37019
  };
36901
37020
  try {
36902
- await visit(import_node_path30.default.join(packageRoot, "dist"));
37021
+ await visit(import_node_path31.default.join(packageRoot, "dist"));
36903
37022
  hashes[`installed:${name}:package.json`] = await sha256File(
36904
- import_node_path30.default.join(packageRoot, "package.json")
37023
+ import_node_path31.default.join(packageRoot, "package.json")
36905
37024
  );
36906
37025
  } catch (error) {
36907
37026
  if (error.code !== "ENOENT") throw error;
36908
37027
  }
36909
37028
  }
36910
37029
  return {
36911
- sourceRoot: await import_promises35.default.realpath(sourceRepositoryRoot),
36912
- projectRoot: await import_promises35.default.realpath(projectRoot18),
37030
+ sourceRoot: await import_promises36.default.realpath(sourceRepositoryRoot),
37031
+ projectRoot: await import_promises36.default.realpath(projectRoot18),
36913
37032
  sourceGitSha: git(["rev-parse", "HEAD"]).trim(),
36914
37033
  sourceDiffSha256: sha256Json(git(["diff", "--binary", "HEAD"])),
36915
37034
  sourceUntrackedSha256: sha256Json(untrackedHashes),
@@ -36934,8 +37053,8 @@ var init_native = __esm({
36934
37053
  projectRoot18,
36935
37054
  `data/research/strategy/${spec.core.researchId}`
36936
37055
  );
36937
- await import_promises35.default.writeFile(
36938
- import_node_path30.default.join(directory, "source.patch"),
37056
+ await import_promises36.default.writeFile(
37057
+ import_node_path31.default.join(directory, "source.patch"),
36939
37058
  (0, import_node_child_process8.execFileSync)("git", ["diff", "--binary", "HEAD"], {
36940
37059
  cwd: sourceRepositoryRoot,
36941
37060
  maxBuffer: 32 * 1024 * 1024
@@ -36948,7 +37067,7 @@ var init_native = __esm({
36948
37067
  "--format=tar",
36949
37068
  "HEAD",
36950
37069
  "--output",
36951
- import_node_path30.default.join(directory, "source-baseline.tar")
37070
+ import_node_path31.default.join(directory, "source-baseline.tar")
36952
37071
  ],
36953
37072
  { cwd: sourceRepositoryRoot }
36954
37073
  );
@@ -36969,7 +37088,7 @@ var init_native = __esm({
36969
37088
  "Untracked credentials cannot be archived as research source"
36970
37089
  );
36971
37090
  const file = await boundResearchPath(sourceRepositoryRoot, relative);
36972
- const content = await import_promises35.default.readFile(file);
37091
+ const content = await import_promises36.default.readFile(file);
36973
37092
  sourceBytes += content.length;
36974
37093
  if (sourceBytes > 32 * 1024 * 1024)
36975
37094
  throw new Error("Untracked source archive exceeds 32 MiB");
@@ -36980,7 +37099,7 @@ var init_native = __esm({
36980
37099
  });
36981
37100
  }
36982
37101
  await writeJsonAtomic(
36983
- import_node_path30.default.join(directory, "source-untracked.json"),
37102
+ import_node_path31.default.join(directory, "source-untracked.json"),
36984
37103
  sourceFiles
36985
37104
  );
36986
37105
  const models = /* @__PURE__ */ new Map();
@@ -36988,7 +37107,7 @@ var init_native = __esm({
36988
37107
  const jev = (0, import_jev6.parseJevConfig)(variant.resolvedConfig.JEV);
36989
37108
  if (jev?.source !== "local") continue;
36990
37109
  const file = await boundResearchPath(projectRoot18, jev.modelFile);
36991
- const bytes = await import_promises35.default.readFile(file);
37110
+ const bytes = await import_promises36.default.readFile(file);
36992
37111
  if (bytes.length > 32 * 1024 * 1024 || await sha256File(file) !== jev.modelSha256)
36993
37112
  throw new Error("Frozen local Jev model size/checksum mismatch");
36994
37113
  validateResearchJevTraining(
@@ -37002,7 +37121,7 @@ var init_native = __esm({
37002
37121
  });
37003
37122
  }
37004
37123
  if (models.size)
37005
- await writeJsonAtomic(import_node_path30.default.join(directory, "source-jev-models.json"), [
37124
+ await writeJsonAtomic(import_node_path31.default.join(directory, "source-jev-models.json"), [
37006
37125
  ...models.values()
37007
37126
  ]);
37008
37127
  const coverage = [];
@@ -37050,7 +37169,7 @@ var init_native = __esm({
37050
37169
  };
37051
37170
  }
37052
37171
  assertResources(spec);
37053
- await import_promises35.default.mkdir(directory, { recursive: true });
37172
+ await import_promises36.default.mkdir(directory, { recursive: true });
37054
37173
  const config2 = nativeConfig(spec, variant);
37055
37174
  const jev = (0, import_jev6.parseJevConfig)(config2.JEV);
37056
37175
  if (jev?.source === "provider")
@@ -37083,17 +37202,17 @@ var init_native = __esm({
37083
37202
  const grid = Object.fromEntries(
37084
37203
  Object.entries(config2).map(([key3, value]) => [key3, [value]])
37085
37204
  );
37086
- const key2 = import_redis18.redisKeys.backtestConfig("root", configName);
37087
- const existing = await (0, import_redis18.getData)(key2, null);
37205
+ const key2 = import_redis19.redisKeys.backtestConfig("root", configName);
37206
+ const existing = await (0, import_redis19.getData)(key2, null);
37088
37207
  if (existing != null && sha256Json(existing) !== sha256Json(grid))
37089
37208
  throw new Error(`Frozen research config changed: ${configName}`);
37090
- if (existing == null) await (0, import_redis18.setData)(key2, grid, { expire: 0 });
37209
+ if (existing == null) await (0, import_redis19.setData)(key2, grid, { expire: 0 });
37091
37210
  let runId = previousRunId ?? "";
37092
37211
  const common = {
37093
37212
  executable: process.execPath,
37094
37213
  cwd: projectRoot18,
37095
37214
  timeoutMs: spec.budget.maxMinutes * 6e4,
37096
- processReceipt: import_node_path30.default.join(directory, "native-process.json"),
37215
+ processReceipt: import_node_path31.default.join(directory, "native-process.json"),
37097
37216
  env: {
37098
37217
  PROJECT_CWD: projectRoot18,
37099
37218
  TRADEJS_SOURCE_REPOSITORY_ROOT: sourceRepositoryRoot,
@@ -37111,7 +37230,7 @@ var init_native = __esm({
37111
37230
  if (previousManifest?.status !== "completed")
37112
37231
  await runResearchCommand({
37113
37232
  ...common,
37114
- log: import_node_path30.default.join(directory, "backtest.log"),
37233
+ log: import_node_path31.default.join(directory, "backtest.log"),
37115
37234
  args: [
37116
37235
  cliPath,
37117
37236
  "backtest",
@@ -37168,13 +37287,13 @@ var init_native = __esm({
37168
37287
  userName: "root"
37169
37288
  });
37170
37289
  if (completed.length === manifest.testSuite.length && completed.every((entry) => Number(entry.result.stat.orders) === 0)) {
37171
- const empty = import_node_path30.default.join(directory, "verified-empty.jsonl");
37172
- await import_promises35.default.writeFile(empty, "");
37290
+ const empty = import_node_path31.default.join(directory, "verified-empty.jsonl");
37291
+ await import_promises36.default.writeFile(empty, "");
37173
37292
  files.push(empty);
37174
37293
  } else
37175
37294
  await runResearchCommand({
37176
37295
  ...common,
37177
- log: import_node_path30.default.join(directory, "export.log"),
37296
+ log: import_node_path31.default.join(directory, "export.log"),
37178
37297
  args: [
37179
37298
  cliPath,
37180
37299
  "ai-export",
@@ -37189,7 +37308,7 @@ var init_native = __esm({
37189
37308
  ],
37190
37309
  onLine: (line) => {
37191
37310
  const match = line.match(/^part\d+:\s+(.+)$/);
37192
- if (match) files.push(import_node_path30.default.resolve(projectRoot18, match[1].trim()));
37311
+ if (match) files.push(import_node_path31.default.resolve(projectRoot18, match[1].trim()));
37193
37312
  }
37194
37313
  });
37195
37314
  if (!files.length)
@@ -37205,7 +37324,7 @@ var init_native = __esm({
37205
37324
  configSha256: sha256Json(config2)
37206
37325
  };
37207
37326
  await writeJsonAtomic(
37208
- import_node_path30.default.join(directory, "sources.json"),
37327
+ import_node_path31.default.join(directory, "sources.json"),
37209
37328
  Object.fromEntries(
37210
37329
  await Promise.all(
37211
37330
  files.map(async (file) => [file, await sha256File(file)])
@@ -37250,7 +37369,7 @@ var init_native = __esm({
37250
37369
  )
37251
37370
  });
37252
37371
  await writeJsonAtomic(
37253
- import_node_path30.default.join(directory, "reconciliation.json"),
37372
+ import_node_path31.default.join(directory, "reconciliation.json"),
37254
37373
  reconciliation
37255
37374
  );
37256
37375
  if (reconciliation.status !== "match")
@@ -37469,12 +37588,12 @@ var init_native = __esm({
37469
37588
  const traceFiles = variant.runId ? await (0, import_coreResearch2.listCoreResearchTraceFiles)({
37470
37589
  strategyName: spec.core.strategy,
37471
37590
  runId: variant.runId,
37472
- outDir: import_node_path30.default.join(projectRoot18, "data/research/core/trace")
37591
+ outDir: import_node_path31.default.join(projectRoot18, "data/research/core/trace")
37473
37592
  }) : [];
37474
37593
  const funnel2 = traceFiles.length ? await summarizeCoreResearchTrace(traceFiles) : null;
37475
37594
  if (variant.configName === `${spec.core.strategy}:auto-${spec.core.researchId}-${variant.id}`)
37476
37595
  await writeJsonAtomic(
37477
- import_node_path30.default.join(directory, "payloads.json"),
37596
+ import_node_path31.default.join(directory, "payloads.json"),
37478
37597
  Object.fromEntries(
37479
37598
  await Promise.all(
37480
37599
  traceFiles.map(async (file) => [file, await sha256File(file)])
@@ -37521,17 +37640,17 @@ var strategyResearch_exports = {};
37521
37640
  __export(strategyResearch_exports, {
37522
37641
  main: () => main38
37523
37642
  });
37524
- var import_promises36, import_node_path31, import_redis19, usage, main38;
37643
+ var import_promises37, import_node_path32, import_redis20, usage, main38;
37525
37644
  var init_strategyResearch2 = __esm({
37526
37645
  "src/scripts/strategyResearch.ts"() {
37527
37646
  "use strict";
37528
- import_promises36 = __toESM(require("fs/promises"));
37529
- import_node_path31 = __toESM(require("path"));
37647
+ import_promises37 = __toESM(require("fs/promises"));
37648
+ import_node_path32 = __toESM(require("path"));
37530
37649
  init_strategyResearch();
37531
37650
  init_researchRoots();
37532
37651
  init_io();
37533
37652
  init_orchestrator();
37534
- import_redis19 = require("@tradejs/infra/redis");
37653
+ import_redis20 = require("@tradejs/infra/redis");
37535
37654
  init_io2();
37536
37655
  usage = `Usage:
37537
37656
  tradejs research:strategy init --coreSpec <core-spec.json> --out <workflow.json>
@@ -37584,7 +37703,7 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37584
37703
  const resolve = (key2) => boundResearchPath(projectRoot18, required4(key2));
37585
37704
  if (command === "init") {
37586
37705
  const output = await resolve("--out");
37587
- await import_promises36.default.mkdir(import_node_path31.default.dirname(output), { recursive: true });
37706
+ await import_promises37.default.mkdir(import_node_path32.default.dirname(output), { recursive: true });
37588
37707
  const timestamp = (key2) => {
37589
37708
  const text3 = required4(key2);
37590
37709
  const value = /^\d+$/.test(text3) ? Number(text3) : Date.parse(text3);
@@ -37619,8 +37738,8 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37619
37738
  throw new Error(
37620
37739
  "Every config must belong to the selected strategy"
37621
37740
  );
37622
- const grid = await (0, import_redis19.getData)(
37623
- import_redis19.redisKeys.backtestConfig("root", configName),
37741
+ const grid = await (0, import_redis20.getData)(
37742
+ import_redis20.redisKeys.backtestConfig("root", configName),
37624
37743
  null
37625
37744
  );
37626
37745
  if (!grid || typeof grid !== "object" || Array.isArray(grid) || !Object.keys(grid).length)
@@ -37661,7 +37780,7 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37661
37780
  const spec2 = validateStrategyResearchSpec(
37662
37781
  createStrategyResearchSpec(loaded.spec)
37663
37782
  );
37664
- await import_promises36.default.writeFile(output, `${JSON.stringify(spec2, null, 2)}
37783
+ await import_promises37.default.writeFile(output, `${JSON.stringify(spec2, null, 2)}
37665
37784
  `, {
37666
37785
  flag: "wx"
37667
37786
  });
@@ -37676,7 +37795,7 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37676
37795
  const directory = researchDirectory(projectRoot18, spec);
37677
37796
  if (command === "status") {
37678
37797
  const state = await readJson(
37679
- import_node_path31.default.join(directory, "state.json")
37798
+ import_node_path32.default.join(directory, "state.json")
37680
37799
  );
37681
37800
  console.log(
37682
37801
  JSON.stringify(
@@ -37684,9 +37803,9 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37684
37803
  status: state.status,
37685
37804
  stages: state.stages,
37686
37805
  error: state.error,
37687
- report: import_node_path31.default.join(directory, "report.html"),
37806
+ report: import_node_path32.default.join(directory, "report.html"),
37688
37807
  retention: await readJson(
37689
- import_node_path31.default.join(directory, "retention-status.json")
37808
+ import_node_path32.default.join(directory, "retention-status.json")
37690
37809
  ).catch((error) => {
37691
37810
  if (error.code === "ENOENT") return { status: "not-started" };
37692
37811
  throw error;
@@ -37700,7 +37819,7 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37700
37819
  }
37701
37820
  if (command === "verify" || command === "revalidate") {
37702
37821
  const state = await readJson(
37703
- import_node_path31.default.join(directory, "state.json")
37822
+ import_node_path32.default.join(directory, "state.json")
37704
37823
  );
37705
37824
  await verifyCompletedResearch(directory, state);
37706
37825
  if (command === "verify") {
@@ -37735,8 +37854,8 @@ Revalidate keeps the frozen rule and evaluates a new period without fitting.
37735
37854
  }
37736
37855
  });
37737
37856
  const output = await resolve("--out");
37738
- await import_promises36.default.mkdir(import_node_path31.default.dirname(output), { recursive: true });
37739
- await import_promises36.default.writeFile(output, `${JSON.stringify(next, null, 2)}
37857
+ await import_promises37.default.mkdir(import_node_path32.default.dirname(output), { recursive: true });
37858
+ await import_promises37.default.writeFile(output, `${JSON.stringify(next, null, 2)}
37740
37859
  `, {
37741
37860
  flag: "wx"
37742
37861
  });
@@ -37760,7 +37879,7 @@ __export(results_exports, {
37760
37879
  main: () => main39,
37761
37880
  results: () => results
37762
37881
  });
37763
- var import_args26, import_chalk42, import_connectors16, import_cli11, import_redis20, ListIt4, flags24, MIN_PROFIT, MIN_WIN_RATE, MIN_ORDERS_PER_MONTH, createListIt4, formatPercent4, getMonthlyReturn, toStrategyResultEntry, toStrategyResults, getTestConfigs, buildBestResults, getSavedProfitsBySymbol, getCoverageRow, results, main39;
37882
+ var import_args26, import_chalk42, import_connectors16, import_cli11, import_redis21, ListIt4, flags24, MIN_PROFIT, MIN_WIN_RATE, MIN_ORDERS_PER_MONTH, createListIt4, formatPercent4, getMonthlyReturn, toStrategyResultEntry, toStrategyResults, getTestConfigs, buildBestResults, getSavedProfitsBySymbol, getCoverageRow, results, main39;
37764
37883
  var init_results = __esm({
37765
37884
  "src/scripts/results.ts"() {
37766
37885
  "use strict";
@@ -37768,7 +37887,7 @@ var init_results = __esm({
37768
37887
  import_chalk42 = __toESM(require("chalk"));
37769
37888
  import_connectors16 = require("@tradejs/connectors");
37770
37889
  import_cli11 = require("@tradejs/node/cli");
37771
- import_redis20 = require("@tradejs/infra/redis");
37890
+ import_redis21 = require("@tradejs/infra/redis");
37772
37891
  ListIt4 = require("list-it");
37773
37892
  import_args26.default.example(
37774
37893
  "yarn results --strategy TrendLine --coverage",
@@ -37808,8 +37927,8 @@ var init_results = __esm({
37808
37927
  [...rows].map((row) => [row.symbol, toStrategyResultEntry(row)])
37809
37928
  );
37810
37929
  getTestConfigs = async (userName3) => {
37811
- const testSummariesKey = typeof import_redis20.redisKeys.testSummaries === "function" ? import_redis20.redisKeys.testSummaries(userName3) : null;
37812
- const indexedItems = testSummariesKey ? await (0, import_redis20.getData)(testSummariesKey, null) : null;
37930
+ const testSummariesKey = typeof import_redis21.redisKeys.testSummaries === "function" ? import_redis21.redisKeys.testSummaries(userName3) : null;
37931
+ const indexedItems = testSummariesKey ? await (0, import_redis21.getData)(testSummariesKey, null) : null;
37813
37932
  if (Array.isArray(indexedItems) && indexedItems.length) {
37814
37933
  return indexedItems.map((item) => {
37815
37934
  const testName = typeof item?.value === "string" ? item.value : null;
@@ -37820,8 +37939,8 @@ var init_results = __esm({
37820
37939
  return { strategyName, testName };
37821
37940
  }).filter(Boolean);
37822
37941
  }
37823
- const testsPrefix = import_redis20.redisKeys.tests(userName3);
37824
- const keys = await (0, import_redis20.getKeys)(testsPrefix);
37942
+ const testsPrefix = import_redis21.redisKeys.tests(userName3);
37943
+ const keys = await (0, import_redis21.getKeys)(testsPrefix);
37825
37944
  const configKeys = keys.filter((key2) => key2.endsWith(":config"));
37826
37945
  return configKeys.map((key2) => {
37827
37946
  const parts = key2.split(":");
@@ -37840,15 +37959,15 @@ var init_results = __esm({
37840
37959
  testName,
37841
37960
  strategyName: strategyFromIndex
37842
37961
  } of testConfigs) {
37843
- const config2 = await (0, import_redis20.getData)(
37844
- import_redis20.redisKeys.testConfig(userName3, strategyFromIndex, testName),
37962
+ const config2 = await (0, import_redis21.getData)(
37963
+ import_redis21.redisKeys.testConfig(userName3, strategyFromIndex, testName),
37845
37964
  null
37846
37965
  );
37847
37966
  if (!config2 || config2.strategyName !== strategyName) {
37848
37967
  continue;
37849
37968
  }
37850
- const stat = await (0, import_redis20.getData)(
37851
- import_redis20.redisKeys.testStat(userName3, strategyFromIndex, testName),
37969
+ const stat = await (0, import_redis21.getData)(
37970
+ import_redis21.redisKeys.testStat(userName3, strategyFromIndex, testName),
37852
37971
  null
37853
37972
  );
37854
37973
  if (!stat) {
@@ -37893,8 +38012,8 @@ var init_results = __esm({
37893
38012
  return savedProfitBySymbol;
37894
38013
  };
37895
38014
  getCoverageRow = async (strategyName, userName3, goodSymbols) => {
37896
- const currentResults = await (0, import_redis20.getData)(
37897
- import_redis20.redisKeys.strategyResults(userName3, strategyName),
38015
+ const currentResults = await (0, import_redis21.getData)(
38016
+ import_redis21.redisKeys.strategyResults(userName3, strategyName),
37898
38017
  {}
37899
38018
  );
37900
38019
  const existingSymbols = new Set(Object.keys(currentResults));
@@ -37928,8 +38047,8 @@ var init_results = __esm({
37928
38047
  const strategyName = flags24.strategy;
37929
38048
  const userName3 = flags24.user;
37930
38049
  if (flags24.clear) {
37931
- const cleared = await (0, import_redis20.delKey)(
37932
- import_redis20.redisKeys.strategyResults(userName3, strategyName)
38050
+ const cleared = await (0, import_redis21.delKey)(
38051
+ import_redis21.redisKeys.strategyResults(userName3, strategyName)
37933
38052
  );
37934
38053
  console.log(
37935
38054
  cleared ? import_chalk42.default.green(`Cleared results:${strategyName}`) : import_chalk42.default.yellow(`No results to clear for ${strategyName}`)
@@ -37977,8 +38096,8 @@ var init_results = __esm({
37977
38096
  console.log(import_chalk42.default.yellow("No good results to merge."));
37978
38097
  process.exit(0);
37979
38098
  }
37980
- const current = await (0, import_redis20.getData)(
37981
- import_redis20.redisKeys.strategyResults(userName3, strategyName),
38099
+ const current = await (0, import_redis21.getData)(
38100
+ import_redis21.redisKeys.strategyResults(userName3, strategyName),
37982
38101
  {}
37983
38102
  );
37984
38103
  const savedProfitBySymbol = await getSavedProfitsBySymbol(current);
@@ -38000,7 +38119,7 @@ var init_results = __esm({
38000
38119
  ...current,
38001
38120
  ...toStrategyResults(updates)
38002
38121
  };
38003
- await (0, import_redis20.setData)(import_redis20.redisKeys.strategyResults(userName3, strategyName), merged, {
38122
+ await (0, import_redis21.setData)(import_redis21.redisKeys.strategyResults(userName3, strategyName), merged, {
38004
38123
  expire: 0
38005
38124
  });
38006
38125
  if (flags24.verbose) {
@@ -38041,8 +38160,8 @@ var init_results = __esm({
38041
38160
  );
38042
38161
  process.exit(0);
38043
38162
  }
38044
- await (0, import_redis20.setData)(
38045
- import_redis20.redisKeys.strategyResults(userName3, strategyName),
38163
+ await (0, import_redis21.setData)(
38164
+ import_redis21.redisKeys.strategyResults(userName3, strategyName),
38046
38165
  resultsConfig,
38047
38166
  {
38048
38167
  expire: 0
@@ -38061,11 +38180,11 @@ var init_results = __esm({
38061
38180
  });
38062
38181
 
38063
38182
  // src/lib/runtimeDebugEvidence.ts
38064
- var import_redis21, RUNTIME_DEBUG_TIMEZONE, RUNTIME_DEBUG_TIMEZONE_LABEL, formatRuntimeDebugDateTime, getRuntimeDebugDateParts, formatRuntimeDebugIsoDayKey, buildRuntimeDebugEvaluationId, filterByStrategies, collectRuntimeDebugEvidence, buildRuntimeDebugReportPayload, buildRuntimeEvidenceReportPayload, buildRuntimeDebugReportAttachment;
38183
+ var import_redis22, RUNTIME_DEBUG_TIMEZONE, RUNTIME_DEBUG_TIMEZONE_LABEL, formatRuntimeDebugDateTime, getRuntimeDebugDateParts, formatRuntimeDebugIsoDayKey, buildRuntimeDebugEvaluationId, filterByStrategies, collectRuntimeDebugEvidence, buildRuntimeDebugReportPayload, buildRuntimeEvidenceReportPayload, buildRuntimeDebugReportAttachment;
38065
38184
  var init_runtimeDebugEvidence = __esm({
38066
38185
  "src/lib/runtimeDebugEvidence.ts"() {
38067
38186
  "use strict";
38068
- import_redis21 = require("@tradejs/infra/redis");
38187
+ import_redis22 = require("@tradejs/infra/redis");
38069
38188
  init_runtimeRedis();
38070
38189
  init_runtimeSignalsLoader();
38071
38190
  init_runtimeSignalsStorage();
@@ -38172,24 +38291,24 @@ var init_runtimeDebugEvidence = __esm({
38172
38291
  const tradeDayKey = (0, import_time5.getRuntimeStorageDayKey)(trade.entryTimestamp);
38173
38292
  const signalDayKey = signal != null ? (0, import_time5.getRuntimeStorageDayKey)(signal.timestamp) : tradeDayKey;
38174
38293
  const evaluationDayKey = knownEvaluation != null ? (0, import_time5.getRuntimeStorageDayKey)(knownEvaluation.timestamp) : signalDayKey;
38175
- const tradeKey = import_redis21.redisKeys.runtimeTrade(userName3, trade.orderId);
38176
- const tradeBucketKey = import_redis21.redisKeys.runtimeTradeBucket(
38294
+ const tradeKey = import_redis22.redisKeys.runtimeTrade(userName3, trade.orderId);
38295
+ const tradeBucketKey = import_redis22.redisKeys.runtimeTradeBucket(
38177
38296
  userName3,
38178
38297
  tradeDayKey
38179
38298
  );
38180
- const activeTradeKey = import_redis21.redisKeys.runtimeActiveTrade(
38299
+ const activeTradeKey = import_redis22.redisKeys.runtimeActiveTrade(
38181
38300
  userName3,
38182
38301
  trade.symbol,
38183
38302
  trade.deploymentId ?? trade.accountId
38184
38303
  );
38185
- const signalKey = trade.signalId != null ? import_redis21.redisKeys.storeSignal(trade.symbol, trade.signalId) : null;
38186
- const evaluationBucketKey = import_redis21.redisKeys.runtimeSignalEvaluationBucket(
38304
+ const signalKey = trade.signalId != null ? import_redis22.redisKeys.storeSignal(trade.symbol, trade.signalId) : null;
38305
+ const evaluationBucketKey = import_redis22.redisKeys.runtimeSignalEvaluationBucket(
38187
38306
  userName3,
38188
38307
  evaluationDayKey,
38189
38308
  knownEvaluation?.strategy ?? trade.strategy
38190
38309
  );
38191
38310
  const evaluationField = knownEvaluation?.evaluationId ?? evaluationId;
38192
- const evaluationKey = import_redis21.redisKeys.runtimeSignalEvaluation(
38311
+ const evaluationKey = import_redis22.redisKeys.runtimeSignalEvaluation(
38193
38312
  userName3,
38194
38313
  evaluationField
38195
38314
  );
@@ -38200,11 +38319,11 @@ var init_runtimeDebugEvidence = __esm({
38200
38319
  directEvaluationValue,
38201
38320
  bucketEvaluationValue
38202
38321
  ] = await Promise.all([
38203
- (0, import_redis21.getData)(tradeKey, null),
38204
- (0, import_redis21.getData)(activeTradeKey, null),
38205
- signalKey ? (0, import_redis21.getData)(signalKey, null) : Promise.resolve(null),
38206
- (0, import_redis21.getData)(evaluationKey, null),
38207
- knownEvaluation ? Promise.resolve(knownEvaluation) : (0, import_redis21.getHashJsonField)(
38322
+ (0, import_redis22.getData)(tradeKey, null),
38323
+ (0, import_redis22.getData)(activeTradeKey, null),
38324
+ signalKey ? (0, import_redis22.getData)(signalKey, null) : Promise.resolve(null),
38325
+ (0, import_redis22.getData)(evaluationKey, null),
38326
+ knownEvaluation ? Promise.resolve(knownEvaluation) : (0, import_redis22.getHashJsonField)(
38208
38327
  evaluationBucketKey,
38209
38328
  evaluationField,
38210
38329
  null
@@ -38261,12 +38380,12 @@ var init_runtimeDebugEvidence = __esm({
38261
38380
  dayKeys
38262
38381
  },
38263
38382
  redisPrefixes: {
38264
- runtimeTrades: import_redis21.redisKeys.runtimeTrades(userName3),
38265
- runtimeTradeBuckets: import_redis21.redisKeys.runtimeTradeBuckets(userName3),
38266
- runtimeActiveTrades: import_redis21.redisKeys.runtimeActiveTrades(userName3),
38267
- runtimeSignals: import_redis21.redisKeys.runtimeSignalBuckets(userName3),
38268
- runtimeSignalEvaluations: import_redis21.redisKeys.runtimeSignalEvaluationBuckets(userName3),
38269
- runtimeSignalEvaluationStats: import_redis21.redisKeys.runtimeSignalEvaluationStatsBuckets(userName3)
38383
+ runtimeTrades: import_redis22.redisKeys.runtimeTrades(userName3),
38384
+ runtimeTradeBuckets: import_redis22.redisKeys.runtimeTradeBuckets(userName3),
38385
+ runtimeActiveTrades: import_redis22.redisKeys.runtimeActiveTrades(userName3),
38386
+ runtimeSignals: import_redis22.redisKeys.runtimeSignalBuckets(userName3),
38387
+ runtimeSignalEvaluations: import_redis22.redisKeys.runtimeSignalEvaluationBuckets(userName3),
38388
+ runtimeSignalEvaluationStats: import_redis22.redisKeys.runtimeSignalEvaluationStatsBuckets(userName3)
38270
38389
  },
38271
38390
  counts: {
38272
38391
  trades: trades.length,
@@ -38277,18 +38396,18 @@ var init_runtimeDebugEvidence = __esm({
38277
38396
  },
38278
38397
  trades: debugTrades,
38279
38398
  signals: signals2.map((signal) => ({
38280
- redisKey: import_redis21.redisKeys.storeSignal(signal.symbol, signal.signalId),
38399
+ redisKey: import_redis22.redisKeys.storeSignal(signal.symbol, signal.signalId),
38281
38400
  signal
38282
38401
  })),
38283
38402
  evaluations: reportEvaluations.map((evaluation) => ({
38284
38403
  redisDebug: {
38285
- key: import_redis21.redisKeys.runtimeSignalEvaluationBucket(
38404
+ key: import_redis22.redisKeys.runtimeSignalEvaluationBucket(
38286
38405
  userName3,
38287
38406
  (0, import_time5.getRuntimeStorageDayKey)(evaluation.timestamp),
38288
38407
  evaluation.strategy
38289
38408
  ),
38290
38409
  field: evaluation.evaluationId,
38291
- directKey: import_redis21.redisKeys.runtimeSignalEvaluation(
38410
+ directKey: import_redis22.redisKeys.runtimeSignalEvaluation(
38292
38411
  userName3,
38293
38412
  evaluation.evaluationId
38294
38413
  )
@@ -38353,17 +38472,17 @@ __export(replayRuntimeEvidence_exports, {
38353
38472
  replayRuntimeEvidence: () => replayRuntimeEvidence,
38354
38473
  summarizeReplayComparison: () => summarizeReplayComparison
38355
38474
  });
38356
- var import_promises37, import_node_path32, import_args27, import_chalk43, import_redis22, toEpochMs2, resolveWindow, parseStrategyFilter, asRecord5, asArray2, sum, groupCount, compactMatched, resolveItemStrategy, summarizeReplayComparison, loadReplayResult, getReplayStrategies, loadRuntimePayload, replayRuntimeEvidence, main40;
38475
+ var import_promises38, import_node_path33, import_args27, import_chalk43, import_redis23, toEpochMs2, resolveWindow, parseStrategyFilter, asRecord5, asArray2, sum, groupCount, compactMatched, resolveItemStrategy, summarizeReplayComparison, loadReplayResult, getReplayStrategies, loadRuntimePayload, replayRuntimeEvidence, main40;
38357
38476
  var init_replayRuntimeEvidence = __esm({
38358
38477
  "src/scripts/replayRuntimeEvidence.ts"() {
38359
38478
  "use strict";
38360
38479
  init_jsonFile();
38361
38480
  init_memoryProfile();
38362
- import_promises37 = __toESM(require("fs/promises"));
38363
- import_node_path32 = __toESM(require("path"));
38481
+ import_promises38 = __toESM(require("fs/promises"));
38482
+ import_node_path33 = __toESM(require("path"));
38364
38483
  import_args27 = __toESM(require("args"));
38365
38484
  import_chalk43 = __toESM(require("chalk"));
38366
- import_redis22 = require("@tradejs/infra/redis");
38485
+ import_redis23 = require("@tradejs/infra/redis");
38367
38486
  init_runtimeDebugEvidence();
38368
38487
  init_support2();
38369
38488
  import_args27.default.option(["u", "user"], "Use user config", "root");
@@ -38586,18 +38705,18 @@ var init_replayRuntimeEvidence = __esm({
38586
38705
  return {
38587
38706
  key: replayKey,
38588
38707
  availableKeys: void 0,
38589
- value: await (0, import_redis22.getData)(replayKey, null)
38708
+ value: await (0, import_redis23.getData)(replayKey, null)
38590
38709
  };
38591
38710
  }
38592
- const prefix = import_redis22.redisKeys.backtestResults(userName3, REPLAY_RESULTS_CONFIG, "");
38593
- const keys = (await (0, import_redis22.getKeys)(prefix)).sort(
38711
+ const prefix = import_redis23.redisKeys.backtestResults(userName3, REPLAY_RESULTS_CONFIG, "");
38712
+ const keys = (await (0, import_redis23.getKeys)(prefix)).sort(
38594
38713
  (left, right) => left.localeCompare(right)
38595
38714
  );
38596
38715
  const key2 = keys[keys.length - 1] ?? null;
38597
38716
  return {
38598
38717
  key: key2,
38599
38718
  availableKeys: keys.slice(-10),
38600
- value: key2 ? await (0, import_redis22.getData)(key2, null) : null
38719
+ value: key2 ? await (0, import_redis23.getData)(key2, null) : null
38601
38720
  };
38602
38721
  };
38603
38722
  getReplayStrategies = (replayValue) => {
@@ -38622,10 +38741,10 @@ var init_replayRuntimeEvidence = __esm({
38622
38741
  runtimeEvidenceFile,
38623
38742
  projectRoot: projectRoot18
38624
38743
  }) => {
38625
- const runtimeEvidencePath = typeof runtimeEvidenceFile === "string" && runtimeEvidenceFile.trim() ? import_node_path32.default.resolve(projectRoot18, runtimeEvidenceFile.trim()) : null;
38744
+ const runtimeEvidencePath = typeof runtimeEvidenceFile === "string" && runtimeEvidenceFile.trim() ? import_node_path33.default.resolve(projectRoot18, runtimeEvidenceFile.trim()) : null;
38626
38745
  if (runtimeEvidencePath) {
38627
38746
  const artifact = JSON.parse(
38628
- await import_promises37.default.readFile(runtimeEvidencePath, "utf8")
38747
+ await import_promises38.default.readFile(runtimeEvidencePath, "utf8")
38629
38748
  );
38630
38749
  return {
38631
38750
  source: "file",
@@ -38711,8 +38830,8 @@ var init_replayRuntimeEvidence = __esm({
38711
38830
  },
38712
38831
  runtime: runtime.payload
38713
38832
  };
38714
- const outPath = import_node_path32.default.resolve(projectRoot18, String(flags36.out));
38715
- await import_promises37.default.mkdir(import_node_path32.default.dirname(outPath), { recursive: true });
38833
+ const outPath = import_node_path33.default.resolve(projectRoot18, String(flags36.out));
38834
+ await import_promises38.default.mkdir(import_node_path33.default.dirname(outPath), { recursive: true });
38716
38835
  const memory = createReplayMemoryProfile();
38717
38836
  memory?.("evidence:write:start");
38718
38837
  await writeReplayJsonFile(outPath, artifact);
@@ -38756,14 +38875,14 @@ var init_runtimeFeedbackArtifacts = __esm({
38756
38875
  });
38757
38876
 
38758
38877
  // src/lib/runtimeFeedbackReplay.ts
38759
- var import_node_child_process9, import_promises38, import_node_path33, import_mcp2, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
38878
+ var import_node_child_process9, import_promises39, import_node_path34, import_mcp3, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
38760
38879
  var init_runtimeFeedbackReplay = __esm({
38761
38880
  "src/lib/runtimeFeedbackReplay.ts"() {
38762
38881
  "use strict";
38763
38882
  import_node_child_process9 = require("child_process");
38764
- import_promises38 = __toESM(require("fs/promises"));
38765
- import_node_path33 = __toESM(require("path"));
38766
- import_mcp2 = require("@tradejs/node/mcp");
38883
+ import_promises39 = __toESM(require("fs/promises"));
38884
+ import_node_path34 = __toESM(require("path"));
38885
+ import_mcp3 = require("@tradejs/node/mcp");
38767
38886
  init_runtimeEvidenceDeployment();
38768
38887
  init_runtimeEvidenceArtifacts();
38769
38888
  init_runtimeEvidenceProducer();
@@ -38898,7 +39017,7 @@ var init_runtimeFeedbackReplay = __esm({
38898
39017
  logHandle
38899
39018
  }) => {
38900
39019
  await logHandle.writeFile(
38901
- "\n" + (0, import_mcp2.formatMcpArtifactLogLine)(`$ ${[executable, ...command].join(" ")}`)
39020
+ "\n" + (0, import_mcp3.formatMcpArtifactLogLine)(`$ ${[executable, ...command].join(" ")}`)
38902
39021
  );
38903
39022
  const child = (0, import_node_child_process9.spawn)(executable, command, {
38904
39023
  cwd,
@@ -38921,7 +39040,7 @@ var init_runtimeFeedbackReplay = __esm({
38921
39040
  let pendingLogWrite = Promise.resolve();
38922
39041
  const copyLog = async (input, output) => {
38923
39042
  const writeLine2 = async (line) => {
38924
- const formatted = (0, import_mcp2.formatMcpArtifactLogLine)(line);
39043
+ const formatted = (0, import_mcp3.formatMcpArtifactLogLine)(line);
38925
39044
  pendingLogWrite = pendingLogWrite.then(
38926
39045
  () => logHandle.writeFile(formatted)
38927
39046
  );
@@ -38964,9 +39083,9 @@ var init_runtimeFeedbackReplay = __esm({
38964
39083
  throw new Error("Cannot resolve the TradeJS CLI executable path");
38965
39084
  }
38966
39085
  const runtimeEvidenceBundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(
38967
- import_node_path33.default.dirname(runtimeEvidencePath)
39086
+ import_node_path34.default.dirname(runtimeEvidencePath)
38968
39087
  );
38969
- if (import_node_path33.default.resolve(runtimeEvidenceBundle.payloadPath) !== runtimeEvidencePath) {
39088
+ if (import_node_path34.default.resolve(runtimeEvidenceBundle.payloadPath) !== runtimeEvidencePath) {
38970
39089
  throw new Error(
38971
39090
  `Runtime evidence must be the verified bundle payload: ${runtimeEvidenceBundle.payloadPath}`
38972
39091
  );
@@ -38993,16 +39112,16 @@ var init_runtimeFeedbackReplay = __esm({
38993
39112
  if (!intervals.size) {
38994
39113
  throw new Error("Runtime feedback replay requires an active interval");
38995
39114
  }
38996
- await import_promises38.default.mkdir(outDir, { recursive: true });
38997
- const existing = await import_promises38.default.readdir(outDir);
39115
+ await import_promises39.default.mkdir(outDir, { recursive: true });
39116
+ const existing = await import_promises39.default.readdir(outDir);
38998
39117
  if (existing.length) {
38999
39118
  throw new Error(
39000
39119
  `Runtime feedback output directory must be empty: ${outDir}`
39001
39120
  );
39002
39121
  }
39003
- const replayEvidencePath = import_node_path33.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_REPLAY_FILE);
39004
- const logHandle = await import_promises38.default.open(
39005
- import_node_path33.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_LOG_FILE),
39122
+ const replayEvidencePath = import_node_path34.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_REPLAY_FILE);
39123
+ const logHandle = await import_promises39.default.open(
39124
+ import_node_path34.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_LOG_FILE),
39006
39125
  "wx"
39007
39126
  );
39008
39127
  const commands = buildRuntimeFeedbackReplayCommands({
@@ -39044,11 +39163,11 @@ __export(runtimeFeedbackReplay_exports, {
39044
39163
  main: () => main41,
39045
39164
  runtimeFeedbackReplay: () => runtimeFeedbackReplay
39046
39165
  });
39047
- var import_node_path34, import_args28, import_chalk44, flags25, projectRoot9, runtimeFeedbackReplay, main41;
39166
+ var import_node_path35, import_args28, import_chalk44, flags25, projectRoot9, runtimeFeedbackReplay, main41;
39048
39167
  var init_runtimeFeedbackReplay2 = __esm({
39049
39168
  "src/scripts/runtimeFeedbackReplay.ts"() {
39050
39169
  "use strict";
39051
- import_node_path34 = __toESM(require("path"));
39170
+ import_node_path35 = __toESM(require("path"));
39052
39171
  import_args28 = __toESM(require("args"));
39053
39172
  import_chalk44 = __toESM(require("chalk"));
39054
39173
  init_runtimeFeedbackReplay();
@@ -39066,8 +39185,8 @@ var init_runtimeFeedbackReplay2 = __esm({
39066
39185
  );
39067
39186
  }
39068
39187
  const verified = await runRuntimeFeedbackReplay({
39069
- runtimeEvidencePath: import_node_path34.default.resolve(projectRoot9, runtimeEvidence2),
39070
- outDir: import_node_path34.default.resolve(projectRoot9, outDir),
39188
+ runtimeEvidencePath: import_node_path35.default.resolve(projectRoot9, runtimeEvidence2),
39189
+ outDir: import_node_path35.default.resolve(projectRoot9, outDir),
39071
39190
  runId: String(flags25.runId ?? "").trim() || void 0,
39072
39191
  projectRoot: projectRoot9
39073
39192
  });
@@ -39229,11 +39348,11 @@ __export(runtimeFeedbackNotify_exports, {
39229
39348
  main: () => main42,
39230
39349
  runtimeFeedbackNotify: () => runtimeFeedbackNotify
39231
39350
  });
39232
- var import_node_path35, import_args29, import_chalk45, flags26, projectRoot10, runtimeFeedbackNotify, main42;
39351
+ var import_node_path36, import_args29, import_chalk45, flags26, projectRoot10, runtimeFeedbackNotify, main42;
39233
39352
  var init_runtimeFeedbackNotify = __esm({
39234
39353
  "src/scripts/runtimeFeedbackNotify.ts"() {
39235
39354
  "use strict";
39236
- import_node_path35 = __toESM(require("path"));
39355
+ import_node_path36 = __toESM(require("path"));
39237
39356
  import_args29 = __toESM(require("args"));
39238
39357
  import_chalk45 = __toESM(require("chalk"));
39239
39358
  init_runtimeFeedbackNotification();
@@ -39247,7 +39366,7 @@ var init_runtimeFeedbackNotify = __esm({
39247
39366
  if (!bundle) {
39248
39367
  throw new Error("Provide --bundle for runtime feedback notification.");
39249
39368
  }
39250
- const bundleDir = import_node_path35.default.resolve(projectRoot10, bundle);
39369
+ const bundleDir = import_node_path36.default.resolve(projectRoot10, bundle);
39251
39370
  if (flags26.dryRun) {
39252
39371
  const verified = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(bundleDir);
39253
39372
  console.log(buildRuntimeFeedbackTelegramMessage(verified.replayEvidence));
@@ -40060,13 +40179,13 @@ ${reactions}
40060
40179
  });
40061
40180
 
40062
40181
  // src/lib/runtimeEvidenceSync.ts
40063
- var import_node_child_process10, import_promises39, import_node_path36, import_node_util2, execFileAsync2, isExistingDestinationError, safeSegment2, withTrailingSlash, dateParts, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
40182
+ var import_node_child_process10, import_promises40, import_node_path37, import_node_util2, execFileAsync2, isExistingDestinationError, safeSegment2, withTrailingSlash, dateParts, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
40064
40183
  var init_runtimeEvidenceSync = __esm({
40065
40184
  "src/lib/runtimeEvidenceSync.ts"() {
40066
40185
  "use strict";
40067
40186
  import_node_child_process10 = require("child_process");
40068
- import_promises39 = __toESM(require("fs/promises"));
40069
- import_node_path36 = __toESM(require("path"));
40187
+ import_promises40 = __toESM(require("fs/promises"));
40188
+ import_node_path37 = __toESM(require("path"));
40070
40189
  import_node_util2 = require("util");
40071
40190
  init_runtimeEvidenceArtifacts();
40072
40191
  init_runtimeEvidenceDeployment();
@@ -40100,15 +40219,15 @@ var init_runtimeEvidenceSync = __esm({
40100
40219
  withTrailingSlash(source),
40101
40220
  withTrailingSlash(destination)
40102
40221
  ];
40103
- receiptPath = (receiptsRoot, artifactId) => import_node_path36.default.join(receiptsRoot, `${safeSegment2(artifactId, "artifact")}.json`);
40222
+ receiptPath = (receiptsRoot, artifactId) => import_node_path37.default.join(receiptsRoot, `${safeSegment2(artifactId, "artifact")}.json`);
40104
40223
  compareBundles = (left, right) => left.manifest.window.endTime - right.manifest.window.endTime || left.manifest.createdAt - right.manifest.createdAt;
40105
40224
  listPendingRuntimeEvidenceBundles = async ({
40106
40225
  evidenceRoot,
40107
40226
  deploymentId
40108
40227
  }) => {
40109
40228
  const safeDeploymentId = safeSegment2(deploymentId, "production");
40110
- const artifactsRoot = import_node_path36.default.join(evidenceRoot, "artifacts", safeDeploymentId);
40111
- const receiptsRoot = import_node_path36.default.join(evidenceRoot, "receipts", safeDeploymentId);
40229
+ const artifactsRoot = import_node_path37.default.join(evidenceRoot, "artifacts", safeDeploymentId);
40230
+ const receiptsRoot = import_node_path37.default.join(evidenceRoot, "receipts", safeDeploymentId);
40112
40231
  const bundles = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(artifactsRoot);
40113
40232
  const pending = [];
40114
40233
  for (const bundleDir of bundles) {
@@ -40116,7 +40235,7 @@ var init_runtimeEvidenceSync = __esm({
40116
40235
  if (verified.manifest.deploymentId !== safeDeploymentId) continue;
40117
40236
  (0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
40118
40237
  try {
40119
- await import_promises39.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
40238
+ await import_promises40.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
40120
40239
  continue;
40121
40240
  } catch (error) {
40122
40241
  if (error.code !== "ENOENT") throw error;
@@ -40139,7 +40258,7 @@ var init_runtimeEvidenceSync = __esm({
40139
40258
  `Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
40140
40259
  );
40141
40260
  }
40142
- const receiptsRoot = import_node_path36.default.join(evidenceRoot, "receipts", safeDeploymentId);
40261
+ const receiptsRoot = import_node_path37.default.join(evidenceRoot, "receipts", safeDeploymentId);
40143
40262
  const finalPath = receiptPath(receiptsRoot, verified.manifest.artifactId);
40144
40263
  const temporaryPath = `${finalPath}.tmp-${process.pid}`;
40145
40264
  const receipt = {
@@ -40153,14 +40272,14 @@ var init_runtimeEvidenceSync = __esm({
40153
40272
  replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
40154
40273
  } : {}
40155
40274
  };
40156
- await import_promises39.default.mkdir(receiptsRoot, { recursive: true });
40157
- await import_promises39.default.writeFile(
40275
+ await import_promises40.default.mkdir(receiptsRoot, { recursive: true });
40276
+ await import_promises40.default.writeFile(
40158
40277
  temporaryPath,
40159
40278
  `${JSON.stringify(receipt, null, 2)}
40160
40279
  `,
40161
40280
  "utf8"
40162
40281
  );
40163
- await import_promises39.default.rename(temporaryPath, finalPath);
40282
+ await import_promises40.default.rename(temporaryPath, finalPath);
40164
40283
  return finalPath;
40165
40284
  };
40166
40285
  syncRuntimeEvidenceBundles = async ({
@@ -40175,11 +40294,11 @@ var init_runtimeEvidenceSync = __esm({
40175
40294
  }
40176
40295
  }) => {
40177
40296
  const safeDeploymentId = safeSegment2(deploymentId, "production");
40178
- const inboxRoot = import_node_path36.default.join(evidenceRoot, "inbox", safeDeploymentId);
40179
- const artifactsRoot = import_node_path36.default.join(evidenceRoot, "artifacts", safeDeploymentId);
40297
+ const inboxRoot = import_node_path37.default.join(evidenceRoot, "inbox", safeDeploymentId);
40298
+ const artifactsRoot = import_node_path37.default.join(evidenceRoot, "artifacts", safeDeploymentId);
40180
40299
  await Promise.all([
40181
- import_promises39.default.mkdir(inboxRoot, { recursive: true }),
40182
- import_promises39.default.mkdir(artifactsRoot, { recursive: true })
40300
+ import_promises40.default.mkdir(inboxRoot, { recursive: true }),
40301
+ import_promises40.default.mkdir(artifactsRoot, { recursive: true })
40183
40302
  ]);
40184
40303
  const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
40185
40304
  source,
@@ -40196,14 +40315,14 @@ var init_runtimeEvidenceSync = __esm({
40196
40315
  );
40197
40316
  }
40198
40317
  (0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
40199
- const destinationDir = import_node_path36.default.join(
40318
+ const destinationDir = import_node_path37.default.join(
40200
40319
  artifactsRoot,
40201
40320
  ...dateParts(verified.manifest.window.endTime),
40202
40321
  safeSegment2(verified.manifest.artifactId, "artifact")
40203
40322
  );
40204
- await import_promises39.default.mkdir(import_node_path36.default.dirname(destinationDir), { recursive: true });
40323
+ await import_promises40.default.mkdir(import_node_path37.default.dirname(destinationDir), { recursive: true });
40205
40324
  try {
40206
- await import_promises39.default.rename(bundleDir, destinationDir);
40325
+ await import_promises40.default.rename(bundleDir, destinationDir);
40207
40326
  } catch (error) {
40208
40327
  if (!isExistingDestinationError(error)) throw error;
40209
40328
  const existing = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir);
@@ -40212,7 +40331,7 @@ var init_runtimeEvidenceSync = __esm({
40212
40331
  `Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
40213
40332
  );
40214
40333
  }
40215
- await import_promises39.default.rm(bundleDir, { recursive: true, force: true });
40334
+ await import_promises40.default.rm(bundleDir, { recursive: true, force: true });
40216
40335
  }
40217
40336
  received.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir));
40218
40337
  }
@@ -40232,14 +40351,14 @@ var init_runtimeEvidenceSync = __esm({
40232
40351
  });
40233
40352
 
40234
40353
  // src/lib/runtimeFeedbackProcess.ts
40235
- var import_promises40, import_node_path37, import_node_crypto21, import_diagnostics2, processRuntimeFeedbackPair;
40354
+ var import_promises41, import_node_path38, import_node_crypto20, import_diagnostics3, processRuntimeFeedbackPair;
40236
40355
  var init_runtimeFeedbackProcess = __esm({
40237
40356
  "src/lib/runtimeFeedbackProcess.ts"() {
40238
40357
  "use strict";
40239
- import_promises40 = __toESM(require("fs/promises"));
40240
- import_node_path37 = __toESM(require("path"));
40241
- import_node_crypto21 = require("crypto");
40242
- import_diagnostics2 = require("@tradejs/node/diagnostics");
40358
+ import_promises41 = __toESM(require("fs/promises"));
40359
+ import_node_path38 = __toESM(require("path"));
40360
+ import_node_crypto20 = require("crypto");
40361
+ import_diagnostics3 = require("@tradejs/node/diagnostics");
40243
40362
  init_executionCalibration();
40244
40363
  init_runtimeScorecard();
40245
40364
  init_runtimeEvidenceSync();
@@ -40250,16 +40369,16 @@ var init_runtimeFeedbackProcess = __esm({
40250
40369
  outputRoot,
40251
40370
  historyDir
40252
40371
  }) => {
40253
- const { runtimeEvidence: runtimeEvidence2, feedback } = await (0, import_diagnostics2.verifyRuntimeFeedbackReplaySource)(
40372
+ const { runtimeEvidence: runtimeEvidence2, feedback } = await (0, import_diagnostics3.verifyRuntimeFeedbackReplaySource)(
40254
40373
  { bundleDir: replayDir, runtimeEvidenceBundleDir: runtimeDir }
40255
40374
  );
40256
40375
  const { artifactId, deploymentId } = runtimeEvidence2.manifest;
40257
- const snapshot = (0, import_diagnostics2.parseRuntimeEvidenceDeploymentSnapshot)(
40376
+ const snapshot = (0, import_diagnostics3.parseRuntimeEvidenceDeploymentSnapshot)(
40258
40377
  runtimeEvidence2.artifact.deployment
40259
40378
  );
40260
40379
  if (!snapshot)
40261
40380
  throw new Error("Runtime evidence requires a deployment snapshot");
40262
- const strategies = (0, import_diagnostics2.activeRuntimeEvidenceStrategies)(snapshot);
40381
+ const strategies = (0, import_diagnostics3.activeRuntimeEvidenceStrategies)(snapshot);
40263
40382
  for (const segment of [
40264
40383
  artifactId,
40265
40384
  deploymentId,
@@ -40268,17 +40387,17 @@ var init_runtimeFeedbackProcess = __esm({
40268
40387
  if (!/^[A-Za-z0-9._:-]+$/.test(segment) || segment === "." || segment === "..")
40269
40388
  throw new Error("Invalid feedback output path identity");
40270
40389
  }
40271
- const receiptPath2 = import_node_path37.default.join(
40390
+ const receiptPath2 = import_node_path38.default.join(
40272
40391
  evidenceRoot,
40273
40392
  "receipts",
40274
40393
  deploymentId,
40275
40394
  `${artifactId}.json`
40276
40395
  );
40277
- await import_promises40.default.mkdir(import_node_path37.default.dirname(receiptPath2), { recursive: true });
40396
+ await import_promises41.default.mkdir(import_node_path38.default.dirname(receiptPath2), { recursive: true });
40278
40397
  const lock = receiptPath2 + ".processing";
40279
- await import_promises40.default.mkdir(lock);
40398
+ await import_promises41.default.mkdir(lock);
40280
40399
  try {
40281
- const previous = await import_promises40.default.readFile(receiptPath2, "utf8").catch((error) => {
40400
+ const previous = await import_promises41.default.readFile(receiptPath2, "utf8").catch((error) => {
40282
40401
  if (error.code !== "ENOENT") throw error;
40283
40402
  return null;
40284
40403
  });
@@ -40286,7 +40405,7 @@ var init_runtimeFeedbackProcess = __esm({
40286
40405
  const receipt = JSON.parse(previous);
40287
40406
  if (!receipt || typeof receipt !== "object" || !("schemaVersion" in receipt) || receipt.schemaVersion !== 2 || !("payloadSha256" in receipt) || !("runtimeFeedbackArtifactId" in receipt) || !("replayEvidenceSha256" in receipt) || !("scorecardPath" in receipt) || receipt.payloadSha256 !== runtimeEvidence2.manifest.payload.sha256 || receipt.runtimeFeedbackArtifactId !== feedback.manifest.artifactId || receipt.replayEvidenceSha256 !== feedback.manifest.payloads.replayEvidence.sha256 || typeof receipt.scorecardPath !== "string")
40288
40407
  throw new Error("Processing receipt conflicts with the exact pair");
40289
- await import_promises40.default.access(receipt.scorecardPath);
40408
+ await import_promises41.default.access(receipt.scorecardPath);
40290
40409
  return {
40291
40410
  processed: false,
40292
40411
  receiptPath: receiptPath2,
@@ -40295,17 +40414,17 @@ var init_runtimeFeedbackProcess = __esm({
40295
40414
  }
40296
40415
  const history = [];
40297
40416
  if (historyDir)
40298
- for (const directory of await (0, import_diagnostics2.discoverRuntimeEvidenceBundles)(historyDir))
40299
- history.push((await (0, import_diagnostics2.verifyRuntimeEvidenceBundle)(directory)).artifact);
40300
- const runId = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "") + "-" + (0, import_node_crypto21.randomUUID)();
40301
- const runDir = import_node_path37.default.join(outputRoot, artifactId, runId);
40302
- await import_promises40.default.mkdir(runDir, { recursive: true });
40417
+ for (const directory of await (0, import_diagnostics3.discoverRuntimeEvidenceBundles)(historyDir))
40418
+ history.push((await (0, import_diagnostics3.verifyRuntimeEvidenceBundle)(directory)).artifact);
40419
+ const runId = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "") + "-" + (0, import_node_crypto20.randomUUID)();
40420
+ const runDir = import_node_path38.default.join(outputRoot, artifactId, runId);
40421
+ await import_promises41.default.mkdir(runDir, { recursive: true });
40303
40422
  const calibration = buildExecutionCalibrationReport({
40304
40423
  runtimeArtifact: runtimeEvidence2.artifact,
40305
40424
  replayEvidenceArtifact: feedback.replayEvidence
40306
40425
  });
40307
- await import_promises40.default.writeFile(
40308
- import_node_path37.default.join(runDir, "execution-calibration.json"),
40426
+ await import_promises41.default.writeFile(
40427
+ import_node_path38.default.join(runDir, "execution-calibration.json"),
40309
40428
  JSON.stringify(calibration, null, 2)
40310
40429
  );
40311
40430
  const inputs = {
@@ -40316,21 +40435,21 @@ var init_runtimeFeedbackProcess = __esm({
40316
40435
  };
40317
40436
  for (const strategy of [...strategies.map((s) => s.strategyName), null]) {
40318
40437
  const scorecard = buildRuntimeScorecard({ ...inputs, strategy });
40319
- const base = import_node_path37.default.join(
40438
+ const base = import_node_path38.default.join(
40320
40439
  runDir,
40321
40440
  strategy ? `runtime-scorecard-${strategy}` : "runtime-scorecard"
40322
40441
  );
40323
- await import_promises40.default.writeFile(base + ".json", JSON.stringify(scorecard, null, 2));
40324
- await import_promises40.default.writeFile(
40442
+ await import_promises41.default.writeFile(base + ".json", JSON.stringify(scorecard, null, 2));
40443
+ await import_promises41.default.writeFile(
40325
40444
  base + ".md",
40326
40445
  formatRuntimeScorecardMarkdown(scorecard)
40327
40446
  );
40328
40447
  }
40329
- await (0, import_diagnostics2.verifyRuntimeFeedbackReplaySource)({
40448
+ await (0, import_diagnostics3.verifyRuntimeFeedbackReplaySource)({
40330
40449
  bundleDir: replayDir,
40331
40450
  runtimeEvidenceBundleDir: runtimeDir
40332
40451
  });
40333
- const scorecardPath = import_node_path37.default.join(runDir, "runtime-scorecard.json");
40452
+ const scorecardPath = import_node_path38.default.join(runDir, "runtime-scorecard.json");
40334
40453
  await markRuntimeEvidenceBundleProcessed({
40335
40454
  evidenceRoot,
40336
40455
  deploymentId,
@@ -40343,7 +40462,7 @@ var init_runtimeFeedbackProcess = __esm({
40343
40462
  });
40344
40463
  return { processed: true, receiptPath: receiptPath2, scorecardPath };
40345
40464
  } finally {
40346
- await import_promises40.default.rmdir(lock);
40465
+ await import_promises41.default.rmdir(lock);
40347
40466
  }
40348
40467
  };
40349
40468
  }
@@ -40354,12 +40473,12 @@ var runtimeFeedbackProcess_exports = {};
40354
40473
  __export(runtimeFeedbackProcess_exports, {
40355
40474
  main: () => main43
40356
40475
  });
40357
- var import_args30, import_node_path38, flags27, main43;
40476
+ var import_args30, import_node_path39, flags27, main43;
40358
40477
  var init_runtimeFeedbackProcess2 = __esm({
40359
40478
  "src/scripts/runtimeFeedbackProcess.ts"() {
40360
40479
  "use strict";
40361
40480
  import_args30 = __toESM(require("args"));
40362
- import_node_path38 = __toESM(require("path"));
40481
+ import_node_path39 = __toESM(require("path"));
40363
40482
  init_runtimeFeedbackProcess();
40364
40483
  import_args30.default.option(
40365
40484
  "runtimeDir",
@@ -40382,11 +40501,11 @@ var init_runtimeFeedbackProcess2 = __esm({
40382
40501
  console.log(
40383
40502
  JSON.stringify(
40384
40503
  await processRuntimeFeedbackPair({
40385
- runtimeDir: import_node_path38.default.resolve(root, String(flags27.runtimeDir)),
40386
- replayDir: import_node_path38.default.resolve(root, String(flags27.replayDir)),
40387
- evidenceRoot: import_node_path38.default.join(root, "data/runtime-evidence"),
40388
- outputRoot: import_node_path38.default.join(root, "output/runtime-feedback"),
40389
- historyDir: import_node_path38.default.resolve(root, String(flags27.historyDir))
40504
+ runtimeDir: import_node_path39.default.resolve(root, String(flags27.runtimeDir)),
40505
+ replayDir: import_node_path39.default.resolve(root, String(flags27.replayDir)),
40506
+ evidenceRoot: import_node_path39.default.join(root, "data/runtime-evidence"),
40507
+ outputRoot: import_node_path39.default.join(root, "output/runtime-feedback"),
40508
+ historyDir: import_node_path39.default.resolve(root, String(flags27.historyDir))
40390
40509
  })
40391
40510
  )
40392
40511
  );
@@ -40395,13 +40514,13 @@ var init_runtimeFeedbackProcess2 = __esm({
40395
40514
  });
40396
40515
 
40397
40516
  // src/lib/runtimeFeedbackSync.ts
40398
- var import_node_child_process11, import_promises41, import_node_path39, import_node_util3, execFileAsync3, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
40517
+ var import_node_child_process11, import_promises42, import_node_path40, import_node_util3, execFileAsync3, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
40399
40518
  var init_runtimeFeedbackSync = __esm({
40400
40519
  "src/lib/runtimeFeedbackSync.ts"() {
40401
40520
  "use strict";
40402
40521
  import_node_child_process11 = require("child_process");
40403
- import_promises41 = __toESM(require("fs/promises"));
40404
- import_node_path39 = __toESM(require("path"));
40522
+ import_promises42 = __toESM(require("fs/promises"));
40523
+ import_node_path40 = __toESM(require("path"));
40405
40524
  import_node_util3 = require("util");
40406
40525
  init_runtimeFeedbackArtifacts();
40407
40526
  init_runtimeEvidenceSync();
@@ -40434,11 +40553,11 @@ var init_runtimeFeedbackSync = __esm({
40434
40553
  }
40435
40554
  }) => {
40436
40555
  const safeDeploymentId = safeSegment3(deploymentId, "production");
40437
- const inboxRoot = import_node_path39.default.join(feedbackRoot, "inbox", safeDeploymentId);
40438
- const artifactsRoot = import_node_path39.default.join(feedbackRoot, "artifacts", safeDeploymentId);
40556
+ const inboxRoot = import_node_path40.default.join(feedbackRoot, "inbox", safeDeploymentId);
40557
+ const artifactsRoot = import_node_path40.default.join(feedbackRoot, "artifacts", safeDeploymentId);
40439
40558
  await Promise.all([
40440
- import_promises41.default.mkdir(inboxRoot, { recursive: true }),
40441
- import_promises41.default.mkdir(artifactsRoot, { recursive: true })
40559
+ import_promises42.default.mkdir(inboxRoot, { recursive: true }),
40560
+ import_promises42.default.mkdir(artifactsRoot, { recursive: true })
40442
40561
  ]);
40443
40562
  const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
40444
40563
  source,
@@ -40454,15 +40573,15 @@ var init_runtimeFeedbackSync = __esm({
40454
40573
  `Runtime feedback deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
40455
40574
  );
40456
40575
  }
40457
- const destinationDir = import_node_path39.default.join(
40576
+ const destinationDir = import_node_path40.default.join(
40458
40577
  artifactsRoot,
40459
40578
  ...dateParts2(verified.manifest.window.endTime),
40460
40579
  safeSegment3(verified.manifest.runtimeEvidence.artifactId, "artifact"),
40461
40580
  safeSegment3(verified.manifest.runId, "run")
40462
40581
  );
40463
- await import_promises41.default.mkdir(import_node_path39.default.dirname(destinationDir), { recursive: true });
40582
+ await import_promises42.default.mkdir(import_node_path40.default.dirname(destinationDir), { recursive: true });
40464
40583
  try {
40465
- await import_promises41.default.rename(bundleDir, destinationDir);
40584
+ await import_promises42.default.rename(bundleDir, destinationDir);
40466
40585
  } catch (error) {
40467
40586
  if (!isExistingDestinationError2(error)) throw error;
40468
40587
  const existing = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir);
@@ -40471,7 +40590,7 @@ var init_runtimeFeedbackSync = __esm({
40471
40590
  `Conflicting runtime feedback replay ${verified.manifest.artifactId}`
40472
40591
  );
40473
40592
  }
40474
- await import_promises41.default.rm(bundleDir, { recursive: true, force: true });
40593
+ await import_promises42.default.rm(bundleDir, { recursive: true, force: true });
40475
40594
  }
40476
40595
  received.push(await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir));
40477
40596
  }
@@ -40491,11 +40610,11 @@ __export(runtimeFeedbackSync_exports, {
40491
40610
  main: () => main44,
40492
40611
  runtimeFeedbackSync: () => runtimeFeedbackSync
40493
40612
  });
40494
- var import_node_path40, import_args31, import_chalk46, flags28, projectRoot11, runtimeFeedbackSync, main44;
40613
+ var import_node_path41, import_args31, import_chalk46, flags28, projectRoot11, runtimeFeedbackSync, main44;
40495
40614
  var init_runtimeFeedbackSync2 = __esm({
40496
40615
  "src/scripts/runtimeFeedbackSync.ts"() {
40497
40616
  "use strict";
40498
- import_node_path40 = __toESM(require("path"));
40617
+ import_node_path41 = __toESM(require("path"));
40499
40618
  import_args31 = __toESM(require("args"));
40500
40619
  import_chalk46 = __toESM(require("chalk"));
40501
40620
  init_runtimeFeedbackSync();
@@ -40523,7 +40642,7 @@ var init_runtimeFeedbackSync2 = __esm({
40523
40642
  "Provide --source or RUNTIME_FEEDBACK_RSYNC_SOURCE for runtime feedback sync."
40524
40643
  );
40525
40644
  }
40526
- const feedbackRoot = import_node_path40.default.resolve(projectRoot11, String(flags28.dir));
40645
+ const feedbackRoot = import_node_path41.default.resolve(projectRoot11, String(flags28.dir));
40527
40646
  const result = await syncRuntimeFeedbackReplayBundles({
40528
40647
  source,
40529
40648
  feedbackRoot,
@@ -40555,13 +40674,13 @@ var init_runtimeFeedbackSync2 = __esm({
40555
40674
  });
40556
40675
 
40557
40676
  // src/lib/runtimeEvidenceCompositionSnapshots.ts
40558
- var import_node_crypto22, import_promises42, import_node_path41, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord2, sha256, safeSegment4, isExistingDestinationError3, parseManifest, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
40677
+ var import_node_crypto21, import_promises43, import_node_path42, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord2, sha256, safeSegment4, isExistingDestinationError3, parseManifest, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
40559
40678
  var init_runtimeEvidenceCompositionSnapshots = __esm({
40560
40679
  "src/lib/runtimeEvidenceCompositionSnapshots.ts"() {
40561
40680
  "use strict";
40562
- import_node_crypto22 = require("crypto");
40563
- import_promises42 = __toESM(require("fs/promises"));
40564
- import_node_path41 = __toESM(require("path"));
40681
+ import_node_crypto21 = require("crypto");
40682
+ import_promises43 = __toESM(require("fs/promises"));
40683
+ import_node_path42 = __toESM(require("path"));
40565
40684
  init_runtimeEvidenceDeployment();
40566
40685
  init_runtimeEvidenceProducer();
40567
40686
  SNAPSHOT_FILE = "snapshot.json";
@@ -40582,7 +40701,7 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
40582
40701
  };
40583
40702
  };
40584
40703
  isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
40585
- sha256 = (value) => (0, import_node_crypto22.createHash)("sha256").update(value).digest("hex");
40704
+ sha256 = (value) => (0, import_node_crypto21.createHash)("sha256").update(value).digest("hex");
40586
40705
  safeSegment4 = (value, label) => {
40587
40706
  const normalized = value.trim();
40588
40707
  if (!normalized || !/^[a-zA-Z0-9._:-]+$/.test(normalized)) {
@@ -40604,9 +40723,9 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
40604
40723
  };
40605
40724
  verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
40606
40725
  const [manifestText, payload, completeText] = await Promise.all([
40607
- import_promises42.default.readFile(import_node_path41.default.join(bundleDir, MANIFEST_FILE), "utf8"),
40608
- import_promises42.default.readFile(import_node_path41.default.join(bundleDir, SNAPSHOT_FILE)),
40609
- import_promises42.default.readFile(import_node_path41.default.join(bundleDir, COMPLETE_FILE), "utf8")
40726
+ import_promises43.default.readFile(import_node_path42.default.join(bundleDir, MANIFEST_FILE), "utf8"),
40727
+ import_promises43.default.readFile(import_node_path42.default.join(bundleDir, SNAPSHOT_FILE)),
40728
+ import_promises43.default.readFile(import_node_path42.default.join(bundleDir, COMPLETE_FILE), "utf8")
40610
40729
  ]);
40611
40730
  const manifest = parseManifest(JSON.parse(manifestText));
40612
40731
  if (completeText.trim() !== manifest.deploymentCompositionId) {
@@ -40669,39 +40788,39 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
40669
40788
  bytes: Buffer.byteLength(payload)
40670
40789
  }
40671
40790
  };
40672
- const snapshotsRoot = import_node_path41.default.join(evidenceRoot, "snapshots", deploymentId);
40673
- const bundleDir = import_node_path41.default.join(snapshotsRoot, compositionId);
40674
- const temporaryDir = import_node_path41.default.join(
40791
+ const snapshotsRoot = import_node_path42.default.join(evidenceRoot, "snapshots", deploymentId);
40792
+ const bundleDir = import_node_path42.default.join(snapshotsRoot, compositionId);
40793
+ const temporaryDir = import_node_path42.default.join(
40675
40794
  evidenceRoot,
40676
40795
  "incoming",
40677
- `snapshot-${compositionId}.tmp-${(0, import_node_crypto22.randomUUID)()}`
40796
+ `snapshot-${compositionId}.tmp-${(0, import_node_crypto21.randomUUID)()}`
40678
40797
  );
40679
- await import_promises42.default.mkdir(temporaryDir, { recursive: true });
40798
+ await import_promises43.default.mkdir(temporaryDir, { recursive: true });
40680
40799
  try {
40681
40800
  await Promise.all([
40682
- import_promises42.default.writeFile(import_node_path41.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
40683
- import_promises42.default.writeFile(
40684
- import_node_path41.default.join(temporaryDir, MANIFEST_FILE),
40801
+ import_promises43.default.writeFile(import_node_path42.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
40802
+ import_promises43.default.writeFile(
40803
+ import_node_path42.default.join(temporaryDir, MANIFEST_FILE),
40685
40804
  `${JSON.stringify(manifest, null, 2)}
40686
40805
  `,
40687
40806
  "utf8"
40688
40807
  )
40689
40808
  ]);
40690
- await import_promises42.default.writeFile(
40691
- import_node_path41.default.join(temporaryDir, COMPLETE_FILE),
40809
+ await import_promises43.default.writeFile(
40810
+ import_node_path42.default.join(temporaryDir, COMPLETE_FILE),
40692
40811
  `${compositionId}
40693
40812
  `,
40694
40813
  "utf8"
40695
40814
  );
40696
- await import_promises42.default.mkdir(snapshotsRoot, { recursive: true });
40815
+ await import_promises43.default.mkdir(snapshotsRoot, { recursive: true });
40697
40816
  try {
40698
- await import_promises42.default.rename(temporaryDir, bundleDir);
40817
+ await import_promises43.default.rename(temporaryDir, bundleDir);
40699
40818
  } catch (error) {
40700
40819
  if (!isExistingDestinationError3(error)) throw error;
40701
- await import_promises42.default.rm(temporaryDir, { recursive: true, force: true });
40820
+ await import_promises43.default.rm(temporaryDir, { recursive: true, force: true });
40702
40821
  }
40703
40822
  } catch (error) {
40704
- await import_promises42.default.rm(temporaryDir, { recursive: true, force: true });
40823
+ await import_promises43.default.rm(temporaryDir, { recursive: true, force: true });
40705
40824
  throw error;
40706
40825
  }
40707
40826
  const verified = await verifyRuntimeEvidenceCompositionSnapshot(bundleDir);
@@ -40735,31 +40854,31 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
40735
40854
  );
40736
40855
  }
40737
40856
  await publishRuntimeEvidenceCompositionSnapshot({
40738
- evidenceRoot: import_node_path41.default.join(projectRoot18, "data", "runtime-evidence"),
40857
+ evidenceRoot: import_node_path42.default.join(projectRoot18, "data", "runtime-evidence"),
40739
40858
  userName: userName3,
40740
40859
  deployment,
40741
40860
  producer
40742
40861
  });
40743
40862
  };
40744
40863
  discoverRuntimeEvidenceCompositionSnapshots = async (evidenceRoot) => {
40745
- const rootDir = import_node_path41.default.join(evidenceRoot, "snapshots");
40864
+ const rootDir = import_node_path42.default.join(evidenceRoot, "snapshots");
40746
40865
  const bundleDirs = [];
40747
40866
  let deployments;
40748
40867
  try {
40749
- deployments = await import_promises42.default.readdir(rootDir, { withFileTypes: true });
40868
+ deployments = await import_promises43.default.readdir(rootDir, { withFileTypes: true });
40750
40869
  } catch (error) {
40751
40870
  if (error.code === "ENOENT") return [];
40752
40871
  throw error;
40753
40872
  }
40754
40873
  for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
40755
- const deploymentDir = import_node_path41.default.join(rootDir, deployment.name);
40756
- const compositions = await import_promises42.default.readdir(deploymentDir, {
40874
+ const deploymentDir = import_node_path42.default.join(rootDir, deployment.name);
40875
+ const compositions = await import_promises43.default.readdir(deploymentDir, {
40757
40876
  withFileTypes: true
40758
40877
  });
40759
40878
  bundleDirs.push(
40760
40879
  ...compositions.filter(
40761
40880
  (entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
40762
- ).map((entry) => import_node_path41.default.join(deploymentDir, entry.name))
40881
+ ).map((entry) => import_node_path42.default.join(deploymentDir, entry.name))
40763
40882
  );
40764
40883
  }
40765
40884
  return Promise.all(
@@ -40960,12 +41079,12 @@ __export(runtimeEvidence_exports, {
40960
41079
  main: () => main45,
40961
41080
  runtimeEvidence: () => runtimeEvidence
40962
41081
  });
40963
- var import_promises43, import_node_path42, import_args32, import_chalk47, flags29, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main45;
41082
+ var import_promises44, import_node_path43, import_args32, import_chalk47, flags29, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main45;
40964
41083
  var init_runtimeEvidence = __esm({
40965
41084
  "src/scripts/runtimeEvidence.ts"() {
40966
41085
  "use strict";
40967
- import_promises43 = __toESM(require("fs/promises"));
40968
- import_node_path42 = __toESM(require("path"));
41086
+ import_promises44 = __toESM(require("fs/promises"));
41087
+ import_node_path43 = __toESM(require("path"));
40969
41088
  import_args32 = __toESM(require("args"));
40970
41089
  import_chalk47 = __toESM(require("chalk"));
40971
41090
  init_runtimeDebugEvidence();
@@ -41072,7 +41191,7 @@ var init_runtimeEvidence = __esm({
41072
41191
  deploymentId
41073
41192
  });
41074
41193
  const snapshots = publishDir && producer ? await loadRuntimeEvidenceCompositionSnapshots({
41075
- publishRoot: import_node_path42.default.resolve(projectRoot12, publishDir),
41194
+ publishRoot: import_node_path43.default.resolve(projectRoot12, publishDir),
41076
41195
  currentDeployment: deploymentSnapshot,
41077
41196
  currentProducer: producer
41078
41197
  }) : /* @__PURE__ */ new Map([
@@ -41146,14 +41265,14 @@ var init_runtimeEvidence = __esm({
41146
41265
  throw new Error("Runtime evidence window has no versioned runtime rows");
41147
41266
  }
41148
41267
  const artifact = current.artifact;
41149
- const outPath = import_node_path42.default.resolve(projectRoot12, String(flags29.out));
41150
- await import_promises43.default.mkdir(import_node_path42.default.dirname(outPath), { recursive: true });
41151
- await import_promises43.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
41268
+ const outPath = import_node_path43.default.resolve(projectRoot12, String(flags29.out));
41269
+ await import_promises44.default.mkdir(import_node_path43.default.dirname(outPath), { recursive: true });
41270
+ await import_promises44.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
41152
41271
  `, "utf8");
41153
41272
  const published = publishDir ? await Promise.all(
41154
41273
  artifacts.map(
41155
41274
  ({ artifact: artifact2, composition }) => (0, runtimeEvidenceArtifacts_exports.publishRuntimeEvidenceBundle)({
41156
- publishRoot: import_node_path42.default.resolve(projectRoot12, publishDir),
41275
+ publishRoot: import_node_path43.default.resolve(projectRoot12, publishDir),
41157
41276
  deploymentId,
41158
41277
  userName: String(flags29.user),
41159
41278
  startTime,
@@ -41199,11 +41318,11 @@ __export(runtimeEvidenceSync_exports, {
41199
41318
  main: () => main46,
41200
41319
  runtimeEvidenceSync: () => runtimeEvidenceSync
41201
41320
  });
41202
- var import_node_path43, import_args33, import_chalk48, flags30, projectRoot13, runtimeEvidenceSync, main46;
41321
+ var import_node_path44, import_args33, import_chalk48, flags30, projectRoot13, runtimeEvidenceSync, main46;
41203
41322
  var init_runtimeEvidenceSync2 = __esm({
41204
41323
  "src/scripts/runtimeEvidenceSync.ts"() {
41205
41324
  "use strict";
41206
- import_node_path43 = __toESM(require("path"));
41325
+ import_node_path44 = __toESM(require("path"));
41207
41326
  import_args33 = __toESM(require("args"));
41208
41327
  import_chalk48 = __toESM(require("chalk"));
41209
41328
  init_runtimeEvidenceSync();
@@ -41231,7 +41350,7 @@ var init_runtimeEvidenceSync2 = __esm({
41231
41350
  "Provide --source or RUNTIME_EVIDENCE_RSYNC_SOURCE for runtime evidence sync."
41232
41351
  );
41233
41352
  }
41234
- const evidenceRoot = import_node_path43.default.resolve(projectRoot13, String(flags30.dir));
41353
+ const evidenceRoot = import_node_path44.default.resolve(projectRoot13, String(flags30.dir));
41235
41354
  const result = await syncRuntimeEvidenceBundles({
41236
41355
  source,
41237
41356
  evidenceRoot,
@@ -41488,7 +41607,7 @@ async function collectReleaseEvidenceReferences(references) {
41488
41607
  let artifact;
41489
41608
  try {
41490
41609
  const parsed = JSON.parse(
41491
- await import_promises44.default.readFile(reference.path, "utf8")
41610
+ await import_promises45.default.readFile(reference.path, "utf8")
41492
41611
  );
41493
41612
  assert3(
41494
41613
  parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
@@ -41641,13 +41760,13 @@ async function collectReleaseEvidenceReferences(references) {
41641
41760
  })
41642
41761
  );
41643
41762
  }
41644
- var import_node_crypto23, import_promises44, import_node_path44, import_types9, import_strategyReleaseEvidence3, SHA256_RE3, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment5, compactTimestamp, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber7, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
41763
+ var import_node_crypto22, import_promises45, import_node_path45, import_types9, import_strategyReleaseEvidence3, SHA256_RE3, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment5, compactTimestamp, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber7, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
41645
41764
  var init_strategyRelease = __esm({
41646
41765
  "src/lib/strategyRelease.ts"() {
41647
41766
  "use strict";
41648
- import_node_crypto23 = require("crypto");
41649
- import_promises44 = __toESM(require("fs/promises"));
41650
- import_node_path44 = __toESM(require("path"));
41767
+ import_node_crypto22 = require("crypto");
41768
+ import_promises45 = __toESM(require("fs/promises"));
41769
+ import_node_path45 = __toESM(require("path"));
41651
41770
  import_types9 = require("@tradejs/types");
41652
41771
  import_strategyReleaseEvidence3 = require("@tradejs/infra/strategyReleaseEvidence");
41653
41772
  init_liveDiagnosis();
@@ -41666,11 +41785,11 @@ var init_strategyRelease = __esm({
41666
41785
  const artifact = input.chartArtifact;
41667
41786
  if (!artifact?.path || !SHA256_RE3.test(artifact.sha256)) return false;
41668
41787
  try {
41669
- const artifactPath = import_node_path44.default.resolve(artifact.path);
41788
+ const artifactPath = import_node_path45.default.resolve(artifact.path);
41670
41789
  if (await (0, import_strategyReleaseEvidence3.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
41671
41790
  return false;
41672
41791
  }
41673
- const report = JSON.parse(await import_promises44.default.readFile(artifactPath, "utf8"));
41792
+ const report = JSON.parse(await import_promises45.default.readFile(artifactPath, "utf8"));
41674
41793
  return Boolean(
41675
41794
  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
41676
41795
  );
@@ -41681,11 +41800,11 @@ var init_strategyRelease = __esm({
41681
41800
  readVerifiedJsonArtifact = async (artifact) => {
41682
41801
  if (!artifact?.path || !SHA256_RE3.test(artifact.sha256)) return null;
41683
41802
  try {
41684
- const artifactPath = import_node_path44.default.resolve(artifact.path);
41803
+ const artifactPath = import_node_path45.default.resolve(artifact.path);
41685
41804
  if (await (0, import_strategyReleaseEvidence3.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
41686
41805
  return null;
41687
41806
  }
41688
- return JSON.parse(await import_promises44.default.readFile(artifactPath, "utf8"));
41807
+ return JSON.parse(await import_promises45.default.readFile(artifactPath, "utf8"));
41689
41808
  } catch {
41690
41809
  return null;
41691
41810
  }
@@ -42231,7 +42350,7 @@ var init_strategyRelease = __esm({
42231
42350
  manifest
42232
42351
  });
42233
42352
  verifyStrategyReleaseEnvelope = async (valueOrPath) => {
42234
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises44.default.readFile(valueOrPath, "utf8")) : valueOrPath;
42353
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises45.default.readFile(valueOrPath, "utf8")) : valueOrPath;
42235
42354
  const envelope = value;
42236
42355
  assert3(
42237
42356
  envelope?.schema === "tradejs-strategy-release-envelope/v1",
@@ -42282,7 +42401,7 @@ var init_strategyRelease = __esm({
42282
42401
  return envelope;
42283
42402
  };
42284
42403
  verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
42285
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises44.default.readFile(valueOrPath, "utf8")) : valueOrPath;
42404
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises45.default.readFile(valueOrPath, "utf8")) : valueOrPath;
42286
42405
  return (0, import_strategyReleaseEvidence3.verifyStrategyEvidenceMarkerEnvelope)(value);
42287
42406
  };
42288
42407
  releaseMarkers = (manifest) => {
@@ -42344,14 +42463,14 @@ var init_strategyRelease = __esm({
42344
42463
  };
42345
42464
  writeJsonAtomic2 = async (filePath, value) => {
42346
42465
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
42347
- await import_promises44.default.mkdir(import_node_path44.default.dirname(filePath), { recursive: true });
42348
- await import_promises44.default.writeFile(
42466
+ await import_promises45.default.mkdir(import_node_path45.default.dirname(filePath), { recursive: true });
42467
+ await import_promises45.default.writeFile(
42349
42468
  temporaryPath,
42350
42469
  `${canonicalStrategyReleaseJson(value)}
42351
42470
  `,
42352
42471
  "utf8"
42353
42472
  );
42354
- await import_promises44.default.rename(temporaryPath, filePath);
42473
+ await import_promises45.default.rename(temporaryPath, filePath);
42355
42474
  };
42356
42475
  publishStrategyRelease = async ({
42357
42476
  rootDir,
@@ -42368,13 +42487,13 @@ var init_strategyRelease = __esm({
42368
42487
  path: entry.path
42369
42488
  }))
42370
42489
  });
42371
- const releasePath = import_node_path44.default.join(
42490
+ const releasePath = import_node_path45.default.join(
42372
42491
  rootDir,
42373
42492
  "releases",
42374
42493
  safeSegment5(manifest.strategy, "strategy"),
42375
42494
  `${manifest.releaseId}.json`
42376
42495
  );
42377
- const markerPath = import_node_path44.default.join(
42496
+ const markerPath = import_node_path45.default.join(
42378
42497
  rootDir,
42379
42498
  "markers",
42380
42499
  safeSegment5(manifest.strategy, "strategy"),
@@ -42454,13 +42573,13 @@ var init_strategyRelease = __esm({
42454
42573
  markers,
42455
42574
  sourceArtifacts
42456
42575
  });
42457
- const diagnosisPath = import_node_path44.default.join(
42576
+ const diagnosisPath = import_node_path45.default.join(
42458
42577
  rootDir,
42459
42578
  "diagnoses",
42460
42579
  safeSegment5(diagnosis.strategy, "strategy"),
42461
42580
  `${diagnosisId}.json`
42462
42581
  );
42463
- const markerPath = import_node_path44.default.join(
42582
+ const markerPath = import_node_path45.default.join(
42464
42583
  rootDir,
42465
42584
  "markers",
42466
42585
  safeSegment5(diagnosis.strategy, "strategy"),
@@ -42650,11 +42769,11 @@ var init_strategyRelease = __esm({
42650
42769
  const specSha256 = finiteString3(artifact.specSha256);
42651
42770
  assert3(researchId != null, "core result researchId is required");
42652
42771
  assert3(specSha256 != null, "core result specSha256 is required");
42653
- const researchDir = import_node_path44.default.dirname(resultPath);
42654
- const manifestPath = import_node_path44.default.join(researchDir, "manifest.json");
42655
- const specPath = import_node_path44.default.join(researchDir, "spec.json");
42656
- const manifestBytes = await import_promises44.default.readFile(manifestPath).catch(() => null);
42657
- const specBytes = await import_promises44.default.readFile(specPath).catch(() => null);
42772
+ const researchDir = import_node_path45.default.dirname(resultPath);
42773
+ const manifestPath = import_node_path45.default.join(researchDir, "manifest.json");
42774
+ const specPath = import_node_path45.default.join(researchDir, "spec.json");
42775
+ const manifestBytes = await import_promises45.default.readFile(manifestPath).catch(() => null);
42776
+ const specBytes = await import_promises45.default.readFile(specPath).catch(() => null);
42658
42777
  assert3(
42659
42778
  manifestBytes != null && specBytes != null,
42660
42779
  "core result must belong to a completed core research bundle"
@@ -42663,14 +42782,14 @@ var init_strategyRelease = __esm({
42663
42782
  const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
42664
42783
  const parsedSpec = JSON.parse(specBytes.toString("utf8"));
42665
42784
  assert3(
42666
- manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto23.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
42785
+ manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto22.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
42667
42786
  "core result is not bound by its completed core research manifest"
42668
42787
  );
42669
42788
  for (const [relativePath, expectedSha256] of Object.entries(
42670
42789
  artifactHashes ?? {}
42671
42790
  )) {
42672
42791
  assert3(
42673
- !import_node_path44.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
42792
+ !import_node_path45.default.isAbsolute(relativePath) && !relativePath.split(/[\\/]/).includes(".."),
42674
42793
  `core bundle artifact ${relativePath} escapes its research directory`
42675
42794
  );
42676
42795
  assert3(
@@ -42678,7 +42797,7 @@ var init_strategyRelease = __esm({
42678
42797
  `core bundle artifact ${relativePath} has an invalid checksum`
42679
42798
  );
42680
42799
  const actualSha256 = await (0, import_strategyReleaseEvidence3.strategyEvidenceFileSha256)(
42681
- import_node_path44.default.join(researchDir, relativePath)
42800
+ import_node_path45.default.join(researchDir, relativePath)
42682
42801
  );
42683
42802
  assert3(
42684
42803
  actualSha256 === expectedSha256,
@@ -42695,13 +42814,13 @@ __export(runtimeScorecard_exports, {
42695
42814
  main: () => main47,
42696
42815
  runtimeScorecard: () => runtimeScorecard
42697
42816
  });
42698
- var import_promises45, import_node_crypto24, import_node_path45, import_args34, import_chalk49, flags31, projectRoot14, resolveOptionalPath, readJson2, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main47;
42817
+ var import_promises46, import_node_crypto23, import_node_path46, import_args34, import_chalk49, flags31, projectRoot14, resolveOptionalPath, readJson2, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main47;
42699
42818
  var init_runtimeScorecard2 = __esm({
42700
42819
  "src/scripts/runtimeScorecard.ts"() {
42701
42820
  "use strict";
42702
- import_promises45 = __toESM(require("fs/promises"));
42703
- import_node_crypto24 = require("crypto");
42704
- import_node_path45 = __toESM(require("path"));
42821
+ import_promises46 = __toESM(require("fs/promises"));
42822
+ import_node_crypto23 = require("crypto");
42823
+ import_node_path46 = __toESM(require("path"));
42705
42824
  import_args34 = __toESM(require("args"));
42706
42825
  import_chalk49 = __toESM(require("chalk"));
42707
42826
  init_runtimeEvidenceArtifacts();
@@ -42771,15 +42890,15 @@ var init_runtimeScorecard2 = __esm({
42771
42890
  projectRoot14 = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
42772
42891
  resolveOptionalPath = (value) => {
42773
42892
  const raw = String(value ?? "").trim();
42774
- return raw ? import_node_path45.default.resolve(projectRoot14, raw) : null;
42893
+ return raw ? import_node_path46.default.resolve(projectRoot14, raw) : null;
42775
42894
  };
42776
- readJson2 = async (filePath) => filePath ? JSON.parse(await import_promises45.default.readFile(filePath, "utf8")) : void 0;
42895
+ readJson2 = async (filePath) => filePath ? JSON.parse(await import_promises46.default.readFile(filePath, "utf8")) : void 0;
42777
42896
  assertReportType = (artifact, expected, label) => {
42778
42897
  if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
42779
42898
  throw new Error(`${label} must be a ${expected} artifact`);
42780
42899
  }
42781
42900
  };
42782
- sha256File2 = async (filePath) => (0, import_node_crypto24.createHash)("sha256").update(await import_promises45.default.readFile(filePath)).digest("hex");
42901
+ sha256File2 = async (filePath) => (0, import_node_crypto23.createHash)("sha256").update(await import_promises46.default.readFile(filePath)).digest("hex");
42783
42902
  loadHistoryArtifacts = async (historyDir) => {
42784
42903
  if (!historyDir) return [];
42785
42904
  const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(historyDir);
@@ -42850,13 +42969,13 @@ var init_runtimeScorecard2 = __esm({
42850
42969
  strategy: scorecardStrategy,
42851
42970
  llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
42852
42971
  });
42853
- const outPath = import_node_path45.default.resolve(projectRoot14, String(flags31.out));
42972
+ const outPath = import_node_path46.default.resolve(projectRoot14, String(flags31.out));
42854
42973
  const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
42855
- await import_promises45.default.mkdir(import_node_path45.default.dirname(outPath), { recursive: true });
42974
+ await import_promises46.default.mkdir(import_node_path46.default.dirname(outPath), { recursive: true });
42856
42975
  await Promise.all([
42857
- import_promises45.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
42976
+ import_promises46.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
42858
42977
  `, "utf8"),
42859
- import_promises45.default.writeFile(
42978
+ import_promises46.default.writeFile(
42860
42979
  markdownPath,
42861
42980
  formatRuntimeScorecardMarkdown(scorecard),
42862
42981
  "utf8"
@@ -42870,7 +42989,7 @@ var init_runtimeScorecard2 = __esm({
42870
42989
  const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
42871
42990
  const strategyReleaseRoot = resolveOptionalPath(flags31.strategyReleaseRoot);
42872
42991
  if (diagnosis && diagnosisPath) {
42873
- await import_promises45.default.writeFile(
42992
+ await import_promises46.default.writeFile(
42874
42993
  diagnosisPath,
42875
42994
  `${JSON.stringify(diagnosis, null, 2)}
42876
42995
  `,
@@ -42891,7 +43010,7 @@ var init_runtimeScorecard2 = __esm({
42891
43010
  composition: verifiedRelease?.manifest.composition,
42892
43011
  sourceArtifacts: await Promise.all(
42893
43012
  sourcePaths.map(async (sourcePath) => ({
42894
- artifactId: import_node_path45.default.basename(sourcePath),
43013
+ artifactId: import_node_path46.default.basename(sourcePath),
42895
43014
  path: sourcePath,
42896
43015
  sha256: await sha256File2(sourcePath)
42897
43016
  }))
@@ -42902,11 +43021,11 @@ var init_runtimeScorecard2 = __esm({
42902
43021
  let receiptPath2 = null;
42903
43022
  if (flags31.markProcessed) {
42904
43023
  const runtimeEvidenceBundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(
42905
- import_node_path45.default.dirname(runtimeEvidencePath)
43024
+ import_node_path46.default.dirname(runtimeEvidencePath)
42906
43025
  );
42907
43026
  const feedbackSource = replayEvidencePath ? await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplaySource)({
42908
- bundleDir: import_node_path45.default.dirname(replayEvidencePath),
42909
- runtimeEvidenceBundleDir: import_node_path45.default.dirname(runtimeEvidencePath)
43027
+ bundleDir: import_node_path46.default.dirname(replayEvidencePath),
43028
+ runtimeEvidenceBundleDir: import_node_path46.default.dirname(runtimeEvidencePath)
42910
43029
  }).catch((error) => {
42911
43030
  if (runtimeEvidenceBundle.artifact.producer) throw error;
42912
43031
  return null;
@@ -42917,9 +43036,9 @@ var init_runtimeScorecard2 = __esm({
42917
43036
  );
42918
43037
  }
42919
43038
  receiptPath2 = await markRuntimeEvidenceBundleProcessed({
42920
- evidenceRoot: import_node_path45.default.resolve(projectRoot14, String(flags31.evidenceDir)),
43039
+ evidenceRoot: import_node_path46.default.resolve(projectRoot14, String(flags31.evidenceDir)),
42921
43040
  deploymentId: String(flags31.deployment),
42922
- bundleDir: import_node_path45.default.dirname(runtimeEvidencePath),
43041
+ bundleDir: import_node_path46.default.dirname(runtimeEvidencePath),
42923
43042
  scorecardPath: outPath,
42924
43043
  runtimeFeedback: feedbackSource ? {
42925
43044
  artifactId: feedbackSource.feedback.manifest.artifactId,
@@ -43116,14 +43235,14 @@ __export(strategyRelease_exports, {
43116
43235
  main: () => main49,
43117
43236
  runStrategyReleaseCommand: () => runStrategyReleaseCommand
43118
43237
  });
43119
- var import_promises46, import_node_fs10, import_node_readline5, import_node_path46, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main49;
43238
+ var import_promises47, import_node_fs10, import_node_readline5, import_node_path47, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main49;
43120
43239
  var init_strategyRelease2 = __esm({
43121
43240
  "src/scripts/strategyRelease.ts"() {
43122
43241
  "use strict";
43123
- import_promises46 = __toESM(require("fs/promises"));
43242
+ import_promises47 = __toESM(require("fs/promises"));
43124
43243
  import_node_fs10 = require("fs");
43125
43244
  import_node_readline5 = require("readline");
43126
- import_node_path46 = __toESM(require("path"));
43245
+ import_node_path47 = __toESM(require("path"));
43127
43246
  import_chalk50 = __toESM(require("chalk"));
43128
43247
  init_researchRetention();
43129
43248
  init_strategyRelease();
@@ -43137,17 +43256,17 @@ var init_strategyRelease2 = __esm({
43137
43256
  };
43138
43257
  writeJsonAtomic3 = async (filePath, value) => {
43139
43258
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
43140
- await import_promises46.default.mkdir(import_node_path46.default.dirname(filePath), { recursive: true });
43141
- await import_promises46.default.writeFile(
43259
+ await import_promises47.default.mkdir(import_node_path47.default.dirname(filePath), { recursive: true });
43260
+ await import_promises47.default.writeFile(
43142
43261
  temporaryPath,
43143
43262
  `${JSON.stringify(value, null, 2)}
43144
43263
  `,
43145
43264
  "utf8"
43146
43265
  );
43147
- await import_promises46.default.rename(temporaryPath, filePath);
43266
+ await import_promises47.default.rename(temporaryPath, filePath);
43148
43267
  };
43149
43268
  runStrategyReleaseCommand = async (options) => {
43150
- const inputPath = import_node_path46.default.resolve(options.inputPath);
43269
+ const inputPath = import_node_path47.default.resolve(options.inputPath);
43151
43270
  if (options.command === "verify") {
43152
43271
  const envelope = await verifyStrategyReleaseEnvelope(inputPath);
43153
43272
  return {
@@ -43185,7 +43304,7 @@ var init_strategyRelease2 = __esm({
43185
43304
  endTime,
43186
43305
  days: options.days?.length ? options.days : [7, 30, 90]
43187
43306
  });
43188
- const outputPath = import_node_path46.default.resolve(
43307
+ const outputPath = import_node_path47.default.resolve(
43189
43308
  options.outputPath ?? "output/strategy-monitoring-profile.json"
43190
43309
  );
43191
43310
  await writeJsonAtomic3(outputPath, profile);
@@ -43196,16 +43315,16 @@ var init_strategyRelease2 = __esm({
43196
43315
  profile
43197
43316
  };
43198
43317
  }
43199
- const input = JSON.parse(await import_promises46.default.readFile(inputPath, "utf8"));
43318
+ const input = JSON.parse(await import_promises47.default.readFile(inputPath, "utf8"));
43200
43319
  if (options.command === "decide") {
43201
43320
  const decision = await deriveStrategyReleaseResearchDecision(input);
43202
43321
  if (options.outputPath) {
43203
- await writeJsonAtomic3(import_node_path46.default.resolve(options.outputPath), decision);
43322
+ await writeJsonAtomic3(import_node_path47.default.resolve(options.outputPath), decision);
43204
43323
  }
43205
43324
  return {
43206
43325
  kind: "decided",
43207
43326
  ...decision,
43208
- outputPath: options.outputPath ? import_node_path46.default.resolve(options.outputPath) : null
43327
+ outputPath: options.outputPath ? import_node_path47.default.resolve(options.outputPath) : null
43209
43328
  };
43210
43329
  }
43211
43330
  if (options.command === "retention") {
@@ -43229,7 +43348,7 @@ var init_strategyRelease2 = __esm({
43229
43348
  protectedPaths: [inputPath]
43230
43349
  });
43231
43350
  } else if (options.apply) {
43232
- await Promise.all(plan.delete.map((entry) => import_promises46.default.rm(entry.path)));
43351
+ await Promise.all(plan.delete.map((entry) => import_promises47.default.rm(entry.path)));
43233
43352
  }
43234
43353
  return {
43235
43354
  kind: "retention",
@@ -43243,12 +43362,12 @@ var init_strategyRelease2 = __esm({
43243
43362
  }
43244
43363
  if (options.command === "diagnose") {
43245
43364
  const diagnosis = buildStrategyLiveDiagnosis(input);
43246
- const outputPath = import_node_path46.default.resolve(
43365
+ const outputPath = import_node_path47.default.resolve(
43247
43366
  options.outputPath ?? "output/strategy-live-diagnosis.json"
43248
43367
  );
43249
43368
  await writeJsonAtomic3(outputPath, diagnosis);
43250
43369
  const published2 = options.rootDir ? await publishStrategyLiveDiagnosis({
43251
- rootDir: import_node_path46.default.resolve(options.rootDir),
43370
+ rootDir: import_node_path47.default.resolve(options.rootDir),
43252
43371
  diagnosis,
43253
43372
  sourceArtifacts: input.sourceArtifacts ?? []
43254
43373
  }) : null;
@@ -43265,7 +43384,7 @@ var init_strategyRelease2 = __esm({
43265
43384
  evidence: await collectReleaseEvidenceReferences(input.evidence ?? [])
43266
43385
  });
43267
43386
  const published = await publishStrategyRelease({
43268
- rootDir: import_node_path46.default.resolve(options.rootDir ?? "data/strategy-release"),
43387
+ rootDir: import_node_path47.default.resolve(options.rootDir ?? "data/strategy-release"),
43269
43388
  manifest
43270
43389
  });
43271
43390
  return {
@@ -43325,7 +43444,7 @@ __export(serverHealth_exports, {
43325
43444
  main: () => main50,
43326
43445
  resolveServerHealthThresholds: () => resolveServerHealthThresholds
43327
43446
  });
43328
- var import_config10, import_node_child_process12, import_node_os5, import_node_fs11, import_args35, import_redis23, DEFAULT_STATE, DEFAULT_THRESHOLDS, escapeHtml6, formatPctValue, formatLoadPerCore, formatGiB, formatDuration2, readDiskUsage, parseMeminfoBytes, readMemorySnapshot, runDiagnosticCommand, runDiagnosticCommands, collectServerHealthSnapshot, buildHumanSummaryLines, evaluateServerHealth, shouldRecover, buildAlertMessage, buildRecoveryMessage, buildServerHealthDiagnostics, getStateKey, toFiniteNumber3, resolveServerHealthThresholds, main50;
43447
+ var import_config10, import_node_child_process12, import_node_os5, import_node_fs11, import_args35, import_redis24, DEFAULT_STATE, DEFAULT_THRESHOLDS, escapeHtml6, formatPctValue, formatLoadPerCore, formatGiB, formatDuration2, readDiskUsage, parseMeminfoBytes, readMemorySnapshot, runDiagnosticCommand, runDiagnosticCommands, collectServerHealthSnapshot, buildHumanSummaryLines, evaluateServerHealth, shouldRecover, buildAlertMessage, buildRecoveryMessage, buildServerHealthDiagnostics, getStateKey, toFiniteNumber3, resolveServerHealthThresholds, main50;
43329
43448
  var init_serverHealth = __esm({
43330
43449
  "src/scripts/serverHealth.ts"() {
43331
43450
  "use strict";
@@ -43334,7 +43453,7 @@ var init_serverHealth = __esm({
43334
43453
  import_node_os5 = __toESM(require("os"));
43335
43454
  import_node_fs11 = require("fs");
43336
43455
  import_args35 = __toESM(require("args"));
43337
- import_redis23 = require("@tradejs/infra/redis");
43456
+ import_redis24 = require("@tradejs/infra/redis");
43338
43457
  init_telegramReports();
43339
43458
  DEFAULT_STATE = {
43340
43459
  status: "healthy",
@@ -43367,21 +43486,21 @@ var init_serverHealth = __esm({
43367
43486
  }
43368
43487
  return `${minutes}m`;
43369
43488
  };
43370
- readDiskUsage = (path57) => {
43489
+ readDiskUsage = (path58) => {
43371
43490
  try {
43372
- const stats = (0, import_node_fs11.statfsSync)(path57);
43491
+ const stats = (0, import_node_fs11.statfsSync)(path58);
43373
43492
  const totalBlocks = Number(stats.blocks ?? 0);
43374
43493
  const availableBlocks = Number(stats.bavail ?? 0);
43375
43494
  if (totalBlocks <= 0) {
43376
- return { path: path57, usedPct: null };
43495
+ return { path: path58, usedPct: null };
43377
43496
  }
43378
43497
  const usedPct = (totalBlocks - Math.max(0, availableBlocks)) / totalBlocks * 100;
43379
43498
  return {
43380
- path: path57,
43499
+ path: path58,
43381
43500
  usedPct: Number.isFinite(usedPct) ? usedPct : null
43382
43501
  };
43383
43502
  } catch {
43384
- return { path: path57, usedPct: null };
43503
+ return { path: path58, usedPct: null };
43385
43504
  }
43386
43505
  };
43387
43506
  parseMeminfoBytes = (value) => {
@@ -43744,7 +43863,7 @@ var init_serverHealth = __esm({
43744
43863
  const diskPath = String(flags36.diskPath || "/");
43745
43864
  const snapshot = collectServerHealthSnapshot(diskPath);
43746
43865
  const stateKey = getStateKey(String(flags36.user), snapshot.hostname);
43747
- const prevState = await (0, import_redis23.getData)(stateKey, DEFAULT_STATE) ?? DEFAULT_STATE;
43866
+ const prevState = await (0, import_redis24.getData)(stateKey, DEFAULT_STATE) ?? DEFAULT_STATE;
43748
43867
  const evaluation = evaluateServerHealth(snapshot, thresholds);
43749
43868
  const cooldownMs = Math.max(60, Number(flags36.cooldownSec)) * 1e3;
43750
43869
  const now2 = snapshot.timestamp;
@@ -43757,7 +43876,7 @@ var init_serverHealth = __esm({
43757
43876
  lastOkAt: prevState.lastOkAt,
43758
43877
  activeIssueCodes: evaluation.issues.map((issue) => issue.code)
43759
43878
  };
43760
- await (0, import_redis23.setData)(stateKey, nextState2, { expire: 0 });
43879
+ await (0, import_redis24.setData)(stateKey, nextState2, { expire: 0 });
43761
43880
  if (shouldSend) {
43762
43881
  const message = buildAlertMessage({
43763
43882
  evaluation,
@@ -43786,7 +43905,7 @@ var init_serverHealth = __esm({
43786
43905
  lastOkAt: now2,
43787
43906
  activeIssueCodes: []
43788
43907
  };
43789
- await (0, import_redis23.setData)(stateKey, nextState, { expire: 0 });
43908
+ await (0, import_redis24.setData)(stateKey, nextState, { expire: 0 });
43790
43909
  if (recovered) {
43791
43910
  const message = buildRecoveryMessage({ snapshot, prevState });
43792
43911
  if (flags36.printOnly) {
@@ -45133,18 +45252,18 @@ __export(runtimeParity_exports, {
45133
45252
  main: () => main51,
45134
45253
  runtimeParity: () => runtimeParity
45135
45254
  });
45136
- var import_config11, import_node_crypto25, import_args36, import_chalk52, import_constants20, import_time13, import_logger8, import_redis24, import_cli12, import_backtest8, import_connectors17, flags32, interval3, projectRoot16, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main51;
45255
+ var import_config11, import_node_crypto24, import_args36, import_chalk52, import_constants20, import_time13, import_logger8, import_redis25, import_cli12, import_backtest8, import_connectors17, flags32, interval3, projectRoot16, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main51;
45137
45256
  var init_runtimeParity2 = __esm({
45138
45257
  "src/scripts/runtimeParity.ts"() {
45139
45258
  "use strict";
45140
45259
  import_config11 = require("dotenv/config");
45141
- import_node_crypto25 = require("crypto");
45260
+ import_node_crypto24 = require("crypto");
45142
45261
  import_args36 = __toESM(require("args"));
45143
45262
  import_chalk52 = __toESM(require("chalk"));
45144
45263
  import_constants20 = require("@tradejs/core/constants");
45145
45264
  import_time13 = require("@tradejs/core/time");
45146
45265
  import_logger8 = require("@tradejs/infra/logger");
45147
- import_redis24 = require("@tradejs/infra/redis");
45266
+ import_redis25 = require("@tradejs/infra/redis");
45148
45267
  import_cli12 = require("@tradejs/node/cli");
45149
45268
  import_backtest8 = require("@tradejs/node/backtest");
45150
45269
  import_connectors17 = require("@tradejs/node/connectors");
@@ -45304,8 +45423,8 @@ var init_runtimeParity2 = __esm({
45304
45423
  toleranceMs
45305
45424
  }) => {
45306
45425
  const [userConfig, strategyResults] = await Promise.all([
45307
- (0, import_redis24.getData)(import_redis24.redisKeys.strategyConfig(userName3, strategy), {}),
45308
- (0, import_redis24.getData)(import_redis24.redisKeys.strategyResults(userName3, strategy), {})
45426
+ (0, import_redis25.getData)(import_redis25.redisKeys.strategyConfig(userName3, strategy), {}),
45427
+ (0, import_redis25.getData)(import_redis25.redisKeys.strategyResults(userName3, strategy), {})
45309
45428
  ]);
45310
45429
  const typedResults = strategyResults ?? {};
45311
45430
  const symbolResult = typedResults?.[symbol];
@@ -45521,9 +45640,9 @@ var init_runtimeParity2 = __esm({
45521
45640
  start: window.start,
45522
45641
  end: window.end
45523
45642
  },
45524
- name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto25.randomUUID)().slice(0, 8)}`,
45525
- testId: (0, import_node_crypto25.randomUUID)().slice(0, 8),
45526
- testSuiteId: (0, import_node_crypto25.randomUUID)().slice(0, 8),
45643
+ name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto24.randomUUID)().slice(0, 8)}`,
45644
+ testId: (0, import_node_crypto24.randomUUID)().slice(0, 8),
45645
+ testSuiteId: (0, import_node_crypto24.randomUUID)().slice(0, 8),
45527
45646
  strategyName: target.strategy,
45528
45647
  strategyConfig: replayConfig,
45529
45648
  connectorName,
@@ -45741,11 +45860,11 @@ var init_skipStats = __esm({
45741
45860
  });
45742
45861
 
45743
45862
  // src/lib/signals/evaluations.ts
45744
- var import_redis25, runtimeLineageScopeCache, runtimeLineageScopeCacheDayKey, runtimeLineageScopeCacheLoaded, buildRuntimeSignalEvaluationId, buildLineageField, flushRuntimeSignalEvaluations, createRuntimeSignalEvaluationBuffer;
45863
+ var import_redis26, runtimeLineageScopeCache, runtimeLineageScopeCacheDayKey, runtimeLineageScopeCacheLoaded, buildRuntimeSignalEvaluationId, buildLineageField, flushRuntimeSignalEvaluations, createRuntimeSignalEvaluationBuffer;
45745
45864
  var init_evaluations = __esm({
45746
45865
  "src/lib/signals/evaluations.ts"() {
45747
45866
  "use strict";
45748
- import_redis25 = require("@tradejs/infra/redis");
45867
+ import_redis26 = require("@tradejs/infra/redis");
45749
45868
  init_runtimeSignalsStorage();
45750
45869
  init_runtimeLineage();
45751
45870
  runtimeLineageScopeCache = /* @__PURE__ */ new Map();
@@ -45796,7 +45915,7 @@ var init_evaluations = __esm({
45796
45915
  runtimeLineageScopeCacheDayKey = dayKey;
45797
45916
  runtimeLineageScopeCacheLoaded = false;
45798
45917
  }
45799
- const lineageBucket = import_redis25.redisKeys.runtimeLineageScopeBucket(
45918
+ const lineageBucket = import_redis26.redisKeys.runtimeLineageScopeBucket(
45800
45919
  dayEvaluations[0].userName,
45801
45920
  dayKey
45802
45921
  );
@@ -45804,7 +45923,7 @@ var init_evaluations = __esm({
45804
45923
  (evaluation) => evaluation.runtimeLineage != null
45805
45924
  );
45806
45925
  if (lineageEvaluations.length > 0 && !runtimeLineageScopeCacheLoaded) {
45807
- const storedScopes = await (0, import_redis25.getHashJsonValues)(lineageBucket);
45926
+ const storedScopes = await (0, import_redis26.getHashJsonValues)(lineageBucket);
45808
45927
  for (const scope of storedScopes) {
45809
45928
  const lineageField = buildLineageField(scope);
45810
45929
  runtimeLineageScopeCache.set(`${lineageBucket}:${lineageField}`, scope);
@@ -45849,7 +45968,7 @@ var init_evaluations = __esm({
45849
45968
  lineageWrites.set(lineageField, scope);
45850
45969
  }
45851
45970
  if (lineageWrites.size > 0) {
45852
- await (0, import_redis25.setHashJsonFields)(
45971
+ await (0, import_redis26.setHashJsonFields)(
45853
45972
  lineageBucket,
45854
45973
  [...lineageWrites].map(([field, data]) => ({ field, data })),
45855
45974
  {
@@ -45861,7 +45980,7 @@ var init_evaluations = __esm({
45861
45980
  const statsIncrements = /* @__PURE__ */ new Map();
45862
45981
  for (const evaluation of dayEvaluations) {
45863
45982
  if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
45864
- const bucket = import_redis25.redisKeys.runtimeSignalEvaluationBucket(
45983
+ const bucket = import_redis26.redisKeys.runtimeSignalEvaluationBucket(
45865
45984
  evaluation.userName,
45866
45985
  dayKey,
45867
45986
  evaluation.strategy
@@ -45873,7 +45992,7 @@ var init_evaluations = __esm({
45873
45992
  });
45874
45993
  detailedWrites.set(bucket, entries);
45875
45994
  }
45876
- const statsBucket = import_redis25.redisKeys.runtimeSignalEvaluationStatsBucket(
45995
+ const statsBucket = import_redis26.redisKeys.runtimeSignalEvaluationStatsBucket(
45877
45996
  evaluation.userName,
45878
45997
  dayKey,
45879
45998
  evaluation.strategy,
@@ -45889,12 +46008,12 @@ var init_evaluations = __esm({
45889
46008
  }
45890
46009
  await Promise.all([
45891
46010
  ...[...detailedWrites].map(
45892
- ([bucket, entries]) => (0, import_redis25.setHashJsonFields)(bucket, entries, {
46011
+ ([bucket, entries]) => (0, import_redis26.setHashJsonFields)(bucket, entries, {
45893
46012
  expire: runtimeSignalRetentionTtl
45894
46013
  })
45895
46014
  ),
45896
46015
  ...[...statsIncrements].map(
45897
- ([bucket, increments]) => (0, import_redis25.incrHashFields)(bucket, increments, {
46016
+ ([bucket, increments]) => (0, import_redis26.incrHashFields)(bucket, increments, {
45898
46017
  expire: runtimeSignalRetentionTtl
45899
46018
  })
45900
46019
  )
@@ -45910,7 +46029,7 @@ var init_evaluations = __esm({
45910
46029
  const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
45911
46030
  const signalRefsByBucket = /* @__PURE__ */ new Map();
45912
46031
  for (const { userName: userName3, signal } of pendingSignals) {
45913
- const bucket = import_redis25.redisKeys.runtimeSignalBucket(
46032
+ const bucket = import_redis26.redisKeys.runtimeSignalBucket(
45914
46033
  userName3,
45915
46034
  (0, import_time5.getRuntimeStorageDayKey)(signal.timestamp),
45916
46035
  signal.strategy
@@ -45924,14 +46043,14 @@ var init_evaluations = __esm({
45924
46043
  }
45925
46044
  await Promise.all([
45926
46045
  ...pendingSignals.map(
45927
- ({ signal }) => (0, import_redis25.setData)(
45928
- import_redis25.redisKeys.storeSignal(signal.symbol, signal.signalId),
46046
+ ({ signal }) => (0, import_redis26.setData)(
46047
+ import_redis26.redisKeys.storeSignal(signal.symbol, signal.signalId),
45929
46048
  toStoredRuntimeSignal(signal),
45930
46049
  { expire: runtimeSignalRetentionTtl }
45931
46050
  )
45932
46051
  ),
45933
46052
  ...[...signalRefsByBucket].map(
45934
- ([bucket, entries]) => (0, import_redis25.setHashJsonFields)(bucket, entries, {
46053
+ ([bucket, entries]) => (0, import_redis26.setHashJsonFields)(bucket, entries, {
45935
46054
  expire: runtimeSignalRetentionTtl
45936
46055
  })
45937
46056
  )
@@ -48511,14 +48630,14 @@ var user_add_exports = {};
48511
48630
  __export(user_add_exports, {
48512
48631
  main: () => main57
48513
48632
  });
48514
- var import_args39, import_chalk55, import_bcryptjs, import_redis26, flags35, main57;
48633
+ var import_args39, import_chalk55, import_bcryptjs, import_redis27, flags35, main57;
48515
48634
  var init_user_add = __esm({
48516
48635
  "src/scripts/user-add.ts"() {
48517
48636
  "use strict";
48518
48637
  import_args39 = __toESM(require("args"));
48519
48638
  import_chalk55 = __toESM(require("chalk"));
48520
48639
  import_bcryptjs = __toESM(require("bcryptjs"));
48521
- import_redis26 = require("@tradejs/infra/redis");
48640
+ import_redis27 = require("@tradejs/infra/redis");
48522
48641
  import_args39.default.example("yarn user-add -u myname -p 123456", "Create or update user");
48523
48642
  import_args39.default.option(["u", "user"], "Username", "");
48524
48643
  import_args39.default.option(["p", "password"], "Password (plain text)", "");
@@ -48531,14 +48650,14 @@ var init_user_add = __esm({
48531
48650
  process.exit(1);
48532
48651
  }
48533
48652
  const passwordHash = await import_bcryptjs.default.hash(password, 10);
48534
- const existing = await (0, import_redis26.getData)(import_redis26.redisKeys.user(userName3), null);
48653
+ const existing = await (0, import_redis27.getData)(import_redis27.redisKeys.user(userName3), null);
48535
48654
  const next = {
48536
48655
  ...existing ?? {},
48537
48656
  passwordHash,
48538
48657
  userName: userName3,
48539
48658
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
48540
48659
  };
48541
- await (0, import_redis26.setData)(import_redis26.redisKeys.user(userName3), next, {
48660
+ await (0, import_redis27.setData)(import_redis27.redisKeys.user(userName3), next, {
48542
48661
  expire: 0
48543
48662
  });
48544
48663
  console.log(import_chalk55.default.green(`User ${userName3} updated`));
@@ -48557,7 +48676,7 @@ __export(cli_exports, {
48557
48676
  });
48558
48677
  module.exports = __toCommonJS(cli_exports);
48559
48678
  var import_config16 = require("dotenv/config");
48560
- var import_redis27 = require("@tradejs/infra/redis");
48679
+ var import_redis28 = require("@tradejs/infra/redis");
48561
48680
  var import_client10 = require("@tradejs/infra/timescale/client");
48562
48681
  var scriptLoaders = {
48563
48682
  "research-visuals": () => Promise.resolve().then(() => (init_researchVisuals2(), researchVisuals_exports)),
@@ -48633,7 +48752,7 @@ var runLoadedModule = async (loaded) => {
48633
48752
  }
48634
48753
  };
48635
48754
  var cleanupCliResources = async () => {
48636
- await Promise.allSettled([(0, import_redis27.closeRedisConnection)(), (0, import_client10.closeTimescalePool)()]);
48755
+ await Promise.allSettled([(0, import_redis28.closeRedisConnection)(), (0, import_client10.closeTimescalePool)()]);
48637
48756
  };
48638
48757
  var main58 = async () => {
48639
48758
  const [, scriptPath, command = "", ...args40] = process.argv;