@tradejs/cli 3.1.29-beta.277 → 3.1.29-beta.280

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
@@ -24462,45 +24462,45 @@ var init_marketWsGateway = __esm({
24462
24462
  socket.destroy();
24463
24463
  return;
24464
24464
  }
24465
- wsServer.handleUpgrade(request, socket, head, (client) => {
24466
- wsServer.emit("connection", client, request);
24465
+ wsServer.handleUpgrade(request, socket, head, (client2) => {
24466
+ wsServer.emit("connection", client2, request);
24467
24467
  });
24468
24468
  });
24469
- wsServer.on("connection", (client) => {
24470
- subscriptions.set(client, /* @__PURE__ */ new Set());
24471
- alive.add(client);
24472
- client.on("pong", () => alive.add(client));
24473
- client.on("message", (raw) => {
24469
+ wsServer.on("connection", (client2) => {
24470
+ subscriptions.set(client2, /* @__PURE__ */ new Set());
24471
+ alive.add(client2);
24472
+ client2.on("pong", () => alive.add(client2));
24473
+ client2.on("message", (raw) => {
24474
24474
  const command = parseSubscriptionCommand(raw.toString());
24475
24475
  if (!command) {
24476
- client.send(JSON.stringify({ type: "error", error: "bad_command" }));
24476
+ client2.send(JSON.stringify({ type: "error", error: "bad_command" }));
24477
24477
  return;
24478
24478
  }
24479
24479
  subscriptions.set(
24480
- client,
24480
+ client2,
24481
24481
  applySubscriptionCommand(
24482
- subscriptions.get(client) ?? /* @__PURE__ */ new Set(),
24482
+ subscriptions.get(client2) ?? /* @__PURE__ */ new Set(),
24483
24483
  command
24484
24484
  )
24485
24485
  );
24486
- client.send(
24486
+ client2.send(
24487
24487
  JSON.stringify({
24488
24488
  type: "subscribed",
24489
- topics: [...subscriptions.get(client) ?? []]
24489
+ topics: [...subscriptions.get(client2) ?? []]
24490
24490
  })
24491
24491
  );
24492
24492
  });
24493
- client.on("close", () => subscriptions.delete(client));
24493
+ client2.on("close", () => subscriptions.delete(client2));
24494
24494
  });
24495
24495
  const heartbeat = setInterval(() => {
24496
- for (const client of subscriptions.keys()) {
24497
- if (!alive.has(client)) {
24498
- client.terminate();
24499
- subscriptions.delete(client);
24496
+ for (const client2 of subscriptions.keys()) {
24497
+ if (!alive.has(client2)) {
24498
+ client2.terminate();
24499
+ subscriptions.delete(client2);
24500
24500
  continue;
24501
24501
  }
24502
- alive.delete(client);
24503
- client.ping();
24502
+ alive.delete(client2);
24503
+ client2.ping();
24504
24504
  }
24505
24505
  }, 3e4);
24506
24506
  subscriber.on("message", (channel, payload) => {
@@ -24509,9 +24509,9 @@ var init_marketWsGateway = __esm({
24509
24509
  if (!event) return;
24510
24510
  const topic = buildMarketKlineTopic(event);
24511
24511
  const message = JSON.stringify({ type: "kline", topic, event });
24512
- for (const [client, topics] of subscriptions) {
24513
- if (client.readyState === import_ws.WebSocket.OPEN && topics.has(topic)) {
24514
- client.send(message);
24512
+ for (const [client2, topics] of subscriptions) {
24513
+ if (client2.readyState === import_ws.WebSocket.OPEN && topics.has(topic)) {
24514
+ client2.send(message);
24515
24515
  }
24516
24516
  }
24517
24517
  });
@@ -24527,7 +24527,7 @@ var init_marketWsGateway = __esm({
24527
24527
  return {
24528
24528
  close: async () => {
24529
24529
  clearInterval(heartbeat);
24530
- for (const client of subscriptions.keys()) client.close();
24530
+ for (const client2 of subscriptions.keys()) client2.close();
24531
24531
  subscriptions.clear();
24532
24532
  await subscriber.unsubscribe(MARKET_KLINE_CHANNEL);
24533
24533
  subscriber.disconnect();
@@ -24567,15 +24567,6 @@ var init_marketWs = __esm({
24567
24567
  }
24568
24568
  });
24569
24569
 
24570
- // src/lib/runtimeEvidenceProducer.ts
24571
- var runtimeEvidenceProducer_exports = {};
24572
- var init_runtimeEvidenceProducer = __esm({
24573
- "src/lib/runtimeEvidenceProducer.ts"() {
24574
- "use strict";
24575
- __reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
24576
- }
24577
- });
24578
-
24579
24570
  // src/lib/runtimeEvidenceArtifacts.ts
24580
24571
  var runtimeEvidenceArtifacts_exports = {};
24581
24572
  var init_runtimeEvidenceArtifacts = __esm({
@@ -24586,13 +24577,35 @@ var init_runtimeEvidenceArtifacts = __esm({
24586
24577
  });
24587
24578
 
24588
24579
  // src/lib/mcpReplayProcess.ts
24589
- var import_node_path14, buildMcpReplayProcess;
24580
+ var import_node_path14, import_node_crypto8, import_promises17, client, buildMcpReplayProcess;
24590
24581
  var init_mcpReplayProcess = __esm({
24591
24582
  "src/lib/mcpReplayProcess.ts"() {
24592
24583
  "use strict";
24593
24584
  import_node_path14 = __toESM(require("path"));
24594
- init_runtimeEvidenceProducer();
24585
+ import_node_crypto8 = require("crypto");
24586
+ import_promises17 = __toESM(require("fs/promises"));
24595
24587
  init_runtimeEvidenceArtifacts();
24588
+ client = `
24589
+ const fs = require('node:fs');
24590
+ const path = require('node:path');
24591
+ const [root, id, request] = process.argv.slice(1);
24592
+ const file = path.join(root, id);
24593
+ fs.mkdirSync(root, {recursive:true});
24594
+ const temporary = file + '.request.tmp-' + process.pid;
24595
+ fs.writeFileSync(temporary, request, {flag:'wx'});
24596
+ try { fs.linkSync(temporary, file + '.request'); }
24597
+ catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
24598
+ finally { fs.unlinkSync(temporary); }
24599
+ process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
24600
+ const timer = setInterval(() => {
24601
+ try {
24602
+ const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
24603
+ console.log(result.message);
24604
+ clearInterval(timer);
24605
+ process.exit(result.exitCode === 0 ? 0 : 1);
24606
+ } catch (error) { if (error.code !== 'ENOENT') throw error; }
24607
+ }, 1000);
24608
+ `;
24596
24609
  buildMcpReplayProcess = async ({
24597
24610
  evidencePath,
24598
24611
  outDir,
@@ -24600,79 +24613,34 @@ var init_mcpReplayProcess = __esm({
24600
24613
  projectRoot: projectRoot18,
24601
24614
  env
24602
24615
  }) => {
24603
- if (!/^[a-zA-Z0-9_-]{1,100}$/.test(runId))
24604
- throw new Error("Invalid replay container run id");
24616
+ if (!/^[a-f0-9]{64}$/.test(runId))
24617
+ throw new Error("Invalid replay request id");
24605
24618
  const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path14.default.dirname(evidencePath));
24606
24619
  if (import_node_path14.default.resolve(evidencePath) !== import_node_path14.default.resolve(bundle.payloadPath))
24607
24620
  throw new Error("Replay requires the verified bundle payload");
24608
- const producer = (0, runtimeEvidenceProducer_exports.parseRuntimeEvidenceProducer)(bundle.artifact.producer);
24609
- if (!env.MCP_REPLAY_HOST_PROJECT_ROOT || !env.MCP_REPLAY_NETWORK || !env.MCP_REPLAY_IMAGE_REPOSITORY)
24610
- throw new Error(
24611
- "Image-bound replay requires MCP_REPLAY_HOST_PROJECT_ROOT MCP_REPLAY_NETWORK and MCP_REPLAY_IMAGE_REPOSITORY"
24612
- );
24613
- const hostPath = (file) => {
24614
- const relative = import_node_path14.default.relative(projectRoot18, file);
24615
- if (relative.startsWith("..") || import_node_path14.default.isAbsolute(relative))
24616
- throw new Error("Replay mounts must be inside the Project");
24617
- return import_node_path14.default.join(env.MCP_REPLAY_HOST_PROJECT_ROOT, relative);
24618
- };
24619
- const args39 = [
24620
- "run",
24621
- "--rm",
24622
- "--name",
24623
- `tradejs-replay-${runId}`,
24624
- "--memory=1536m",
24625
- "--cpus=1",
24626
- "--pids-limit=512",
24627
- "--read-only",
24628
- "--cap-drop=ALL",
24629
- "--security-opt=no-new-privileges",
24630
- "--network",
24631
- env.MCP_REPLAY_NETWORK,
24632
- "--tmpfs",
24633
- "/tmp",
24634
- "--tmpfs",
24635
- "/app/data",
24636
- "--entrypoint",
24637
- "/app/node_modules/.bin/tradejs",
24638
- "--mount",
24639
- `type=bind,src=${hostPath(import_node_path14.default.dirname(evidencePath))},dst=/evidence,readonly`,
24640
- "--mount",
24641
- `type=bind,src=${hostPath(outDir)},dst=/replay-output`
24642
- ];
24643
- const safeEnv = {
24644
- PROJECT_CWD: "/app",
24645
- DOTENV_CONFIG_PATH: "/dev/null",
24646
- TRADEJS_PROJECT_SHA: producer.projectSha,
24647
- TRADEJS_PROJECT_IMAGE_DIGEST: producer.imageDigest,
24648
- NODE_OPTIONS: "--max-old-space-size=1024",
24649
- MAKE_ORDERS: "false",
24650
- TRADEJS_EXTERNAL_ORDER_PLACEMENT: "false",
24651
- AI_ENABLED: "false",
24652
- ML_ENABLED: "false",
24653
- RUNTIME_FEEDBACK_ISOLATED_REDIS: "true",
24654
- REDIS_HOST: env.MCP_REPLAY_REDIS_HOST,
24655
- REDIS_PORT: "6379",
24656
- REDIS_DB: "0",
24657
- PGOPTIONS: "-c default_transaction_read_only=on",
24658
- TRADEJS_TIMESCALE_READ_ONLY: "true"
24659
- };
24660
- for (const name of ["PG_HOST", "PG_PORT", "PG_USER", "PG_DATABASE", "PG_DB"])
24661
- if (env[name]) safeEnv[name] = env[name];
24662
- for (const [name, value] of Object.entries(safeEnv))
24663
- if (value !== void 0) args39.push("--env", `${name}=${value}`);
24664
- if (env.PG_PASSWORD) args39.push("--env", "PG_PASSWORD");
24665
- args39.push(
24666
- `${env.MCP_REPLAY_IMAGE_REPOSITORY}@${producer.imageDigest}`,
24667
- "runtime-feedback-replay",
24668
- "--runtimeEvidence",
24669
- `/evidence/${import_node_path14.default.basename(evidencePath)}`,
24670
- "--outDir",
24671
- "/replay-output",
24672
- "--runId",
24673
- runId
24674
- );
24675
- return { executable: "docker", args: args39 };
24621
+ const relative = import_node_path14.default.relative(import_node_path14.default.join(projectRoot18, "data"), evidencePath);
24622
+ if (relative.startsWith("..") || import_node_path14.default.isAbsolute(relative))
24623
+ throw new Error("Evidence must be inside Project data");
24624
+ const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path14.default.join(projectRoot18, "data/mcp-replay-requests");
24625
+ const heartbeat = JSON.parse(
24626
+ await import_promises17.default.readFile(import_node_path14.default.join(root, "heartbeat.json"), "utf8")
24627
+ );
24628
+ if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
24629
+ throw new Error("Host replay runner heartbeat is stale");
24630
+ const bytes = await import_promises17.default.readFile(evidencePath);
24631
+ const request = JSON.stringify({
24632
+ schemaVersion: 1,
24633
+ id: runId,
24634
+ evidence: relative,
24635
+ artifactId: bundle.manifest.artifactId,
24636
+ deploymentId: bundle.manifest.deploymentId,
24637
+ payloadSha256: (0, import_node_crypto8.createHash)("sha256").update(bytes).digest("hex")
24638
+ });
24639
+ void outDir;
24640
+ return {
24641
+ executable: process.execPath,
24642
+ args: ["-e", client, root, runId, request]
24643
+ };
24676
24644
  };
24677
24645
  }
24678
24646
  });
@@ -24682,13 +24650,13 @@ var mcpWorker_exports = {};
24682
24650
  __export(mcpWorker_exports, {
24683
24651
  main: () => main26
24684
24652
  });
24685
- var import_node_child_process4, import_node_crypto8, import_promises17, import_redis15, import_mcp, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main26;
24653
+ var import_node_child_process4, import_node_crypto9, import_promises18, import_redis15, import_mcp, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main26;
24686
24654
  var init_mcpWorker = __esm({
24687
24655
  "src/scripts/mcpWorker.ts"() {
24688
24656
  "use strict";
24689
24657
  import_node_child_process4 = require("child_process");
24690
- import_node_crypto8 = require("crypto");
24691
- import_promises17 = require("fs/promises");
24658
+ import_node_crypto9 = require("crypto");
24659
+ import_promises18 = require("fs/promises");
24692
24660
  import_redis15 = require("@tradejs/infra/redis");
24693
24661
  import_mcp = require("@tradejs/node/mcp");
24694
24662
  init_mcpReplayProcess();
@@ -24697,7 +24665,7 @@ var init_mcpWorker = __esm({
24697
24665
  LEASE_SECONDS = 15;
24698
24666
  JOB_TIMEOUT_MS = 60 * 60 * 1e3;
24699
24667
  main26 = async (options = {}) => {
24700
- const owner = (0, import_node_crypto8.randomUUID)();
24668
+ const owner = (0, import_node_crypto9.randomUUID)();
24701
24669
  if (!await import_redis15.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
24702
24670
  throw new Error("Another MCP worker owns this storage");
24703
24671
  let stopping = false;
@@ -24705,6 +24673,18 @@ var init_mcpWorker = __esm({
24705
24673
  let renewing = false;
24706
24674
  let leaseLost = false;
24707
24675
  let manifestHash = "";
24676
+ let replayReady = false;
24677
+ const updateReplayReady = async () => {
24678
+ try {
24679
+ const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
24680
+ const heartbeat2 = JSON.parse(
24681
+ await (0, import_promises18.readFile)(`${root}/heartbeat.json`, "utf8")
24682
+ );
24683
+ replayReady = Number.isFinite(heartbeat2.observedAt) && Date.now() - heartbeat2.observedAt >= 0 && Date.now() - heartbeat2.observedAt < 12e4;
24684
+ } catch {
24685
+ replayReady = false;
24686
+ }
24687
+ };
24708
24688
  const signalChild = (signal) => {
24709
24689
  if (!child?.pid) return;
24710
24690
  try {
@@ -24718,9 +24698,7 @@ var init_mcpWorker = __esm({
24718
24698
  const heartbeatValue = () => ({
24719
24699
  observedAt: Date.now(),
24720
24700
  packageManifestSha256: manifestHash,
24721
- replayAvailable: Boolean(
24722
- process.env.MCP_REPLAY_REDIS_HOST && process.env.MCP_REPLAY_HOST_PROJECT_ROOT && process.env.MCP_REPLAY_NETWORK && process.env.MCP_REPLAY_IMAGE_REPOSITORY
24723
- )
24701
+ replayAvailable: replayReady
24724
24702
  });
24725
24703
  const stop = () => {
24726
24704
  stopping = true;
@@ -24736,6 +24714,7 @@ var init_mcpWorker = __esm({
24736
24714
  try {
24737
24715
  if (!await import_redis15.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
24738
24716
  throw new Error("Worker lease lost");
24717
+ await updateReplayReady();
24739
24718
  await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
24740
24719
  } catch {
24741
24720
  leaseLost = true;
@@ -24746,6 +24725,7 @@ var init_mcpWorker = __esm({
24746
24725
  }, 2e3);
24747
24726
  try {
24748
24727
  manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
24728
+ await updateReplayReady();
24749
24729
  await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
24750
24730
  let cursor = "0";
24751
24731
  do {
@@ -24810,7 +24790,7 @@ var init_mcpWorker = __esm({
24810
24790
  );
24811
24791
  continue;
24812
24792
  }
24813
- await (0, import_promises17.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
24793
+ await (0, import_promises18.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
24814
24794
  if (started.kind === "backtest")
24815
24795
  await (0, import_redis15.setDataStrict)(
24816
24796
  import_redis15.redisKeys.backtestConfig(
@@ -24833,7 +24813,9 @@ var init_mcpWorker = __esm({
24833
24813
  };
24834
24814
  if (started.kind === "runtime-feedback-replay") {
24835
24815
  for (const name of Object.keys(jobEnv)) {
24836
- if (/secret|token|api.?key|private.?key|cookie|credential/i.test(name))
24816
+ if (/secret|password|token|api.?key|private.?key|cookie|credential/i.test(
24817
+ name
24818
+ ))
24837
24819
  delete jobEnv[name];
24838
24820
  }
24839
24821
  Object.assign(jobEnv, {
@@ -24874,8 +24856,6 @@ var init_mcpWorker = __esm({
24874
24856
  );
24875
24857
  continue;
24876
24858
  }
24877
- if (started.kind === "runtime-feedback-replay" && process.env.PG_PASSWORD)
24878
- jobEnv.PG_PASSWORD = process.env.PG_PASSWORD;
24879
24859
  child = (0, import_node_child_process4.spawn)(command.executable, command.args, {
24880
24860
  cwd: process.env.PROJECT_CWD || process.cwd(),
24881
24861
  env: jobEnv,
@@ -24930,20 +24910,6 @@ var init_mcpWorker = __esm({
24930
24910
  );
24931
24911
  currentChild.once("exit", (code) => resolve({ code }));
24932
24912
  });
24933
- if (started.kind === "runtime-feedback-replay") {
24934
- await new Promise((resolve) => {
24935
- const cleanup = (0, import_node_child_process4.spawn)(
24936
- "docker",
24937
- ["rm", "--force", `tradejs-replay-${started.id}`],
24938
- {
24939
- stdio: "ignore",
24940
- timeout: 1e4
24941
- }
24942
- );
24943
- cleanup.once("error", () => resolve());
24944
- cleanup.once("close", () => resolve());
24945
- });
24946
- }
24947
24913
  clearTimeout(timeout);
24948
24914
  clearInterval(monitor);
24949
24915
  child = void 0;
@@ -25335,13 +25301,13 @@ var hyperliquidWhalesUpdate_exports = {};
25335
25301
  __export(hyperliquidWhalesUpdate_exports, {
25336
25302
  main: () => main29
25337
25303
  });
25338
- var import_config8, import_args21, import_node_crypto9, import_strategies12, LEADERBOARD_URL, DAY_MS10, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main29;
25304
+ var import_config8, import_args21, import_node_crypto10, import_strategies12, LEADERBOARD_URL, DAY_MS10, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main29;
25339
25305
  var init_hyperliquidWhalesUpdate = __esm({
25340
25306
  "src/scripts/hyperliquidWhalesUpdate.ts"() {
25341
25307
  "use strict";
25342
25308
  import_config8 = require("dotenv/config");
25343
25309
  import_args21 = __toESM(require("args"));
25344
- import_node_crypto9 = require("crypto");
25310
+ import_node_crypto10 = require("crypto");
25345
25311
  import_strategies12 = require("@tradejs/node/strategies");
25346
25312
  init_hyperliquidWhaleBackfill();
25347
25313
  init_hyperliquidRateLimiter();
@@ -25355,7 +25321,7 @@ var init_hyperliquidWhalesUpdate = __esm({
25355
25321
  );
25356
25322
  import_args21.default.option(["d", "days"], "Calibration window in days", 7);
25357
25323
  flags19 = import_args21.default.parse(process.argv);
25358
- fingerprint = (addresses) => (0, import_node_crypto9.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
25324
+ fingerprint = (addresses) => (0, import_node_crypto10.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
25359
25325
  runConcurrent2 = async (params) => {
25360
25326
  let nextIndex = 0;
25361
25327
  await Promise.all(
@@ -25464,13 +25430,13 @@ var mlExport_exports = {};
25464
25430
  __export(mlExport_exports, {
25465
25431
  main: () => main30
25466
25432
  });
25467
- var import_args22, import_chalk37, import_promises18, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main30;
25433
+ var import_args22, import_chalk37, import_promises19, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main30;
25468
25434
  var init_mlExport = __esm({
25469
25435
  "src/scripts/mlExport.ts"() {
25470
25436
  "use strict";
25471
25437
  import_args22 = __toESM(require("args"));
25472
25438
  import_chalk37 = __toESM(require("chalk"));
25473
- import_promises18 = __toESM(require("fs/promises"));
25439
+ import_promises19 = __toESM(require("fs/promises"));
25474
25440
  import_path8 = __toESM(require("path"));
25475
25441
  import_ml = require("@tradejs/infra/ml");
25476
25442
  init_checkpoint();
@@ -25521,7 +25487,7 @@ var init_mlExport = __esm({
25521
25487
  };
25522
25488
  main30 = async () => {
25523
25489
  const outDir = String(flags20.outDir || "data/ml/export");
25524
- await import_promises18.default.mkdir(outDir, { recursive: true });
25490
+ await import_promises19.default.mkdir(outDir, { recursive: true });
25525
25491
  const strategyName = await resolveExportStrategy({
25526
25492
  explicitStrategy: String(flags20.strategy || ""),
25527
25493
  outDir,
@@ -25566,7 +25532,7 @@ var init_mlExport = __esm({
25566
25532
  const shouldDeleteChunks = !Boolean(flags20.keepChunks);
25567
25533
  if (shouldDeleteChunks) {
25568
25534
  for (const filePath of chunkFiles) {
25569
- await import_promises18.default.rm(filePath, { force: true });
25535
+ await import_promises19.default.rm(filePath, { force: true });
25570
25536
  }
25571
25537
  }
25572
25538
  console.log(import_chalk37.default.green(`Merged dataset saved: ${mergedPath}`));
@@ -25587,13 +25553,13 @@ var mlInspect_exports = {};
25587
25553
  __export(mlInspect_exports, {
25588
25554
  main: () => main31
25589
25555
  });
25590
- var import_args23, import_chalk38, import_promises19, import_fs3, import_path9, import_readline2, import_child_process2, flags21, toMode, toInspectTool, selectInspectTool, asPositiveInt, readRowsHead, readRowsTail, readRowsSample, quantileSorted, mean2, std, findLatestDataset, buildNumericStats, formatNumber5, runQuickInspect, runYDataInspect, main31;
25556
+ var import_args23, import_chalk38, import_promises20, import_fs3, import_path9, import_readline2, import_child_process2, flags21, toMode, toInspectTool, selectInspectTool, asPositiveInt, readRowsHead, readRowsTail, readRowsSample, quantileSorted, mean2, std, findLatestDataset, buildNumericStats, formatNumber5, runQuickInspect, runYDataInspect, main31;
25591
25557
  var init_mlInspect = __esm({
25592
25558
  "src/scripts/mlInspect.ts"() {
25593
25559
  "use strict";
25594
25560
  import_args23 = __toESM(require("args"));
25595
25561
  import_chalk38 = __toESM(require("chalk"));
25596
- import_promises19 = __toESM(require("fs/promises"));
25562
+ import_promises20 = __toESM(require("fs/promises"));
25597
25563
  import_fs3 = require("fs");
25598
25564
  import_path9 = __toESM(require("path"));
25599
25565
  import_readline2 = __toESM(require("readline"));
@@ -25770,7 +25736,7 @@ var init_mlInspect = __esm({
25770
25736
  };
25771
25737
  findLatestDataset = async (params) => {
25772
25738
  const { dir, strategy } = params;
25773
- const entries = await import_promises19.default.readdir(dir, { withFileTypes: true });
25739
+ const entries = await import_promises20.default.readdir(dir, { withFileTypes: true });
25774
25740
  const strategyToken = strategy.trim().toLowerCase();
25775
25741
  const files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.endsWith(".jsonl")).filter(
25776
25742
  (name) => !name.includes(".train.") && !name.includes(".test.")
@@ -25782,7 +25748,7 @@ var init_mlInspect = __esm({
25782
25748
  }
25783
25749
  const withMtime = await Promise.all(
25784
25750
  files.map(async (name) => {
25785
- const stat = await import_promises19.default.stat(import_path9.default.join(dir, name));
25751
+ const stat = await import_promises20.default.stat(import_path9.default.join(dir, name));
25786
25752
  return { name, mtime: stat.mtimeMs };
25787
25753
  })
25788
25754
  );
@@ -26027,7 +25993,7 @@ var init_mlInspect = __esm({
26027
25993
  const relToData = import_path9.default.relative(dataRoot, absDatasetPath);
26028
25994
  const inputInContainer = `/app/data/${relToData}`;
26029
25995
  const reportDir = import_path9.default.dirname(absDatasetPath);
26030
- await import_promises19.default.mkdir(reportDir, { recursive: true });
25996
+ await import_promises20.default.mkdir(reportDir, { recursive: true });
26031
25997
  const reportPath = import_path9.default.join(
26032
25998
  reportDir,
26033
25999
  `${import_path9.default.basename(datasetPath, import_path9.default.extname(datasetPath))}.profile.html`
@@ -26123,12 +26089,12 @@ var mlTrainLatestSelect_exports = {};
26123
26089
  __export(mlTrainLatestSelect_exports, {
26124
26090
  main: () => main32
26125
26091
  });
26126
- var import_path10, import_promises20, import_fs4, import_crypto2, import_child_process3, import_events, import_readline3, import_args24, import_chalk39, import_ml2, toFileToken6, asBool, asInt7, asNonNegativeInt, formatBytes, getMlContainerMemUsage, MODEL_TYPES, STRATEGIES, flags22, parseStrategy, parseModelType, selectModelType, listDatasetFiles, concatFiles, pipeNormalized, DAY_MS11, SPLIT_PROGRESS_EVERY, parseTimestampMs, scanMaxLabeledTimestampMs, scanMaxTrainTimestampMs, hashFileNameSha1, prepareTrainWindowFiles, main32;
26092
+ var import_path10, import_promises21, import_fs4, import_crypto2, import_child_process3, import_events, import_readline3, import_args24, import_chalk39, import_ml2, toFileToken6, asBool, asInt7, asNonNegativeInt, formatBytes, getMlContainerMemUsage, MODEL_TYPES, STRATEGIES, flags22, parseStrategy, parseModelType, selectModelType, listDatasetFiles, concatFiles, pipeNormalized, DAY_MS11, SPLIT_PROGRESS_EVERY, parseTimestampMs, scanMaxLabeledTimestampMs, scanMaxTrainTimestampMs, hashFileNameSha1, prepareTrainWindowFiles, main32;
26127
26093
  var init_mlTrainLatestSelect = __esm({
26128
26094
  "src/scripts/mlTrainLatestSelect.ts"() {
26129
26095
  "use strict";
26130
26096
  import_path10 = __toESM(require("path"));
26131
- import_promises20 = __toESM(require("fs/promises"));
26097
+ import_promises21 = __toESM(require("fs/promises"));
26132
26098
  import_fs4 = require("fs");
26133
26099
  import_crypto2 = require("crypto");
26134
26100
  import_child_process3 = require("child_process");
@@ -26257,7 +26223,7 @@ var init_mlTrainLatestSelect = __esm({
26257
26223
  return defaultModel;
26258
26224
  };
26259
26225
  listDatasetFiles = async (dir, strategyName) => {
26260
- const entries = await import_promises20.default.readdir(dir, { withFileTypes: true });
26226
+ const entries = await import_promises21.default.readdir(dir, { withFileTypes: true });
26261
26227
  const prefix = `ml-dataset-${toFileToken6(strategyName)}-`;
26262
26228
  const legacyPrefix = "ml-dataset-";
26263
26229
  const fileNames = entries.filter((entry) => entry.isFile()).map((entry) => entry.name);
@@ -26268,7 +26234,7 @@ var init_mlTrainLatestSelect = __esm({
26268
26234
  ).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."));
26269
26235
  const withMtime = await Promise.all(
26270
26236
  jsonlFiles.map(async (name) => {
26271
- const stat = await import_promises20.default.stat(import_path10.default.join(dir, name));
26237
+ const stat = await import_promises21.default.stat(import_path10.default.join(dir, name));
26272
26238
  return { name, mtime: stat.mtimeMs };
26273
26239
  })
26274
26240
  );
@@ -26444,13 +26410,13 @@ var init_mlTrainLatestSelect = __esm({
26444
26410
  const metaPath = import_path10.default.join(dir, `${parsed.name}.windows.${key}.meta.json`);
26445
26411
  try {
26446
26412
  const [metaRaw] = await Promise.all([
26447
- import_promises20.default.readFile(metaPath, "utf8"),
26448
- import_promises20.default.access(holdoutTrainPath),
26449
- import_promises20.default.access(holdoutTestPath),
26450
- import_promises20.default.access(prodPath),
26413
+ import_promises21.default.readFile(metaPath, "utf8"),
26414
+ import_promises21.default.access(holdoutTrainPath),
26415
+ import_promises21.default.access(holdoutTestPath),
26416
+ import_promises21.default.access(prodPath),
26451
26417
  ...walkForwardFoldDefs.flatMap((entry) => [
26452
- import_promises20.default.access(entry.trainPath),
26453
- import_promises20.default.access(entry.testPath)
26418
+ import_promises21.default.access(entry.trainPath),
26419
+ import_promises21.default.access(entry.testPath)
26454
26420
  ])
26455
26421
  ]);
26456
26422
  const meta2 = JSON.parse(metaRaw);
@@ -26817,7 +26783,7 @@ var init_mlTrainLatestSelect = __esm({
26817
26783
  },
26818
26784
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
26819
26785
  };
26820
- await import_promises20.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
26786
+ await import_promises21.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
26821
26787
  `, "utf8");
26822
26788
  return {
26823
26789
  holdoutTrainPath,
@@ -26875,7 +26841,7 @@ var init_mlTrainLatestSelect = __esm({
26875
26841
  process.exit(1);
26876
26842
  }
26877
26843
  try {
26878
- const inputStat = await import_promises20.default.stat(inputPath);
26844
+ const inputStat = await import_promises21.default.stat(inputPath);
26879
26845
  const totalInputBytes = inputStat.size;
26880
26846
  const autoIncrementalThresholdGb = asInt7(
26881
26847
  process.env.ML_TRAIN_INCREMENTAL_THRESHOLD_GB,
@@ -27064,7 +27030,7 @@ var init_mlTrainLatestSelect = __esm({
27064
27030
  const modelDir = import_path10.default.join(modelDirRoot, "models");
27065
27031
  let savedModels = [];
27066
27032
  try {
27067
- const entries = await import_promises20.default.readdir(modelDir, { withFileTypes: true });
27033
+ const entries = await import_promises21.default.readdir(modelDir, { withFileTypes: true });
27068
27034
  savedModels = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter(
27069
27035
  (name) => name === `${selected}.joblib` || /^.+\.model\d+\.joblib$/.test(name)
27070
27036
  ).filter((name) => name.startsWith(`${selected}.`)).sort();
@@ -27086,7 +27052,7 @@ var init_mlTrainLatestSelect = __esm({
27086
27052
  process.exitCode = finalCode;
27087
27053
  } finally {
27088
27054
  for (const file of cleanupFiles) {
27089
- await import_promises20.default.rm(file, { force: true });
27055
+ await import_promises21.default.rm(file, { force: true });
27090
27056
  }
27091
27057
  }
27092
27058
  process.exit(process.exitCode ?? 1);
@@ -27118,14 +27084,14 @@ __export(researchAuto_exports, {
27118
27084
  toStrategyConfigGrid: () => toStrategyConfigGrid2,
27119
27085
  trimTextTail: () => trimTextTail2
27120
27086
  });
27121
- var import_args25, import_chalk40, import_node_child_process5, import_promises21, import_node_os2, import_node_path15, import_constants18, import_ai8, import_logger6, import_redis16, import_registry4, flags23, projectRoot8, dotenvPath, getResearchAutoLockPath, readResearchAutoLock, isProcessAlive, acquireResearchAutoLock, releaseResearchAutoLock, resolvePositiveInteger, resolveHeapMbFromEnv, buildNodeOptions, RESEARCH_AUTO_PARENT_HEAP_MB, RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB, RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB, RESEARCH_AUTO_AGENT_PARENT_HEAP_MB, trimTextTail2, escapeHtml3, createEmptySteps, saveRun, listMergedFiles3, getBacktestResultsPrefix, listRuntimeStrategyNames, toStrategyConfigGrid2, formatMskDateTime, buildTelegramReport, runCliCommand, resolveTarget, parseJsonOutput, logResearch, executeNonBlockingStep, main33;
27087
+ var import_args25, import_chalk40, import_node_child_process5, import_promises22, import_node_os2, import_node_path15, import_constants18, import_ai8, import_logger6, import_redis16, import_registry4, flags23, projectRoot8, dotenvPath, getResearchAutoLockPath, readResearchAutoLock, isProcessAlive, acquireResearchAutoLock, releaseResearchAutoLock, resolvePositiveInteger, resolveHeapMbFromEnv, buildNodeOptions, RESEARCH_AUTO_PARENT_HEAP_MB, RESEARCH_AUTO_BACKTEST_PARENT_HEAP_MB, RESEARCH_AUTO_AI_TRAIN_PARENT_HEAP_MB, RESEARCH_AUTO_AGENT_PARENT_HEAP_MB, trimTextTail2, escapeHtml3, createEmptySteps, saveRun, listMergedFiles3, getBacktestResultsPrefix, listRuntimeStrategyNames, toStrategyConfigGrid2, formatMskDateTime, buildTelegramReport, runCliCommand, resolveTarget, parseJsonOutput, logResearch, executeNonBlockingStep, main33;
27122
27088
  var init_researchAuto = __esm({
27123
27089
  "src/scripts/researchAuto.ts"() {
27124
27090
  "use strict";
27125
27091
  import_args25 = __toESM(require("args"));
27126
27092
  import_chalk40 = __toESM(require("chalk"));
27127
27093
  import_node_child_process5 = require("child_process");
27128
- import_promises21 = __toESM(require("fs/promises"));
27094
+ import_promises22 = __toESM(require("fs/promises"));
27129
27095
  import_node_os2 = __toESM(require("os"));
27130
27096
  import_node_path15 = __toESM(require("path"));
27131
27097
  import_constants18 = require("@tradejs/core/constants");
@@ -27172,7 +27138,7 @@ var init_researchAuto = __esm({
27172
27138
  );
27173
27139
  readResearchAutoLock = async (lockPath) => {
27174
27140
  try {
27175
- const raw = await import_promises21.default.readFile(lockPath, "utf8");
27141
+ const raw = await import_promises22.default.readFile(lockPath, "utf8");
27176
27142
  return JSON.parse(raw);
27177
27143
  } catch {
27178
27144
  return null;
@@ -27207,9 +27173,9 @@ var init_researchAuto = __esm({
27207
27173
  startedAt,
27208
27174
  argv: [...process.argv]
27209
27175
  };
27210
- await import_promises21.default.mkdir(import_node_path15.default.dirname(lockPath), { recursive: true });
27176
+ await import_promises22.default.mkdir(import_node_path15.default.dirname(lockPath), { recursive: true });
27211
27177
  const writeLock = async () => {
27212
- await import_promises21.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
27178
+ await import_promises22.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
27213
27179
  flag: "wx"
27214
27180
  });
27215
27181
  };
@@ -27228,7 +27194,7 @@ var init_researchAuto = __esm({
27228
27194
  `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})`
27229
27195
  );
27230
27196
  }
27231
- await import_promises21.default.unlink(lockPath).catch(() => void 0);
27197
+ await import_promises22.default.unlink(lockPath).catch(() => void 0);
27232
27198
  await writeLock();
27233
27199
  return lockPath;
27234
27200
  };
@@ -27240,7 +27206,7 @@ var init_researchAuto = __esm({
27240
27206
  if (existingLock && existingLock.pid !== process.pid) {
27241
27207
  return;
27242
27208
  }
27243
- await import_promises21.default.unlink(lockPath).catch(() => void 0);
27209
+ await import_promises22.default.unlink(lockPath).catch(() => void 0);
27244
27210
  };
27245
27211
  resolvePositiveInteger = (value, fallback) => {
27246
27212
  const parsed = Number.parseInt(String(value ?? ""), 10);
@@ -27342,7 +27308,7 @@ var init_researchAuto = __esm({
27342
27308
  };
27343
27309
  listMergedFiles3 = async (outDir, strategyName) => {
27344
27310
  try {
27345
- const entries = await import_promises21.default.readdir(outDir);
27311
+ const entries = await import_promises22.default.readdir(outDir);
27346
27312
  const prefix = `ai-dataset-${(0, import_ai8.toFileToken)(strategyName)}-merged-`;
27347
27313
  return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).sort().map((name) => import_node_path15.default.join(outDir, name));
27348
27314
  } catch {
@@ -28010,13 +27976,13 @@ var init_types = __esm({
28010
27976
  function assert(condition, message) {
28011
27977
  if (!condition) throw new Error(`Invalid core research spec: ${message}`);
28012
27978
  }
28013
- var import_node_crypto10, import_node_fs3, import_promises22, import_backtest5, import_node_path16, RESEARCH_ID_RE, SHA256_RE, canonicalJson, sha256Text, sha256Json, sha256File, assertFinite, validateCoreResearchSpec, loadCoreResearchSpec, resolveCoreResearchPaths, writeJsonAtomic, buildLedgerRecordHash, readCoreResearchLedger, verifyCoreResearchLedger, appendCoreResearchLedger, validateCoreResearchParentLineage, prepareCoreResearch, verifyCoreResearchArtifacts, scanCoreResearchStages, writeCoreResearchStageIndex;
27979
+ var import_node_crypto11, import_node_fs3, import_promises23, import_backtest5, import_node_path16, RESEARCH_ID_RE, SHA256_RE, canonicalJson, sha256Text, sha256Json, sha256File, assertFinite, validateCoreResearchSpec, loadCoreResearchSpec, resolveCoreResearchPaths, writeJsonAtomic, buildLedgerRecordHash, readCoreResearchLedger, verifyCoreResearchLedger, appendCoreResearchLedger, validateCoreResearchParentLineage, prepareCoreResearch, verifyCoreResearchArtifacts, scanCoreResearchStages, writeCoreResearchStageIndex;
28014
27980
  var init_io = __esm({
28015
27981
  "src/lib/coreResearch/io.ts"() {
28016
27982
  "use strict";
28017
- import_node_crypto10 = require("crypto");
27983
+ import_node_crypto11 = require("crypto");
28018
27984
  import_node_fs3 = require("fs");
28019
- import_promises22 = __toESM(require("fs/promises"));
27985
+ import_promises23 = __toESM(require("fs/promises"));
28020
27986
  import_backtest5 = require("@tradejs/core/backtest");
28021
27987
  import_node_path16 = __toESM(require("path"));
28022
27988
  init_types();
@@ -28034,10 +28000,10 @@ var init_io = __esm({
28034
28000
  };
28035
28001
  return JSON.stringify(normalize(value));
28036
28002
  };
28037
- sha256Text = (value) => (0, import_node_crypto10.createHash)("sha256").update(value).digest("hex");
28003
+ sha256Text = (value) => (0, import_node_crypto11.createHash)("sha256").update(value).digest("hex");
28038
28004
  sha256Json = (value) => sha256Text(canonicalJson(value));
28039
28005
  sha256File = async (filePath) => {
28040
- const hash = (0, import_node_crypto10.createHash)("sha256");
28006
+ const hash = (0, import_node_crypto11.createHash)("sha256");
28041
28007
  const input = (0, import_node_fs3.createReadStream)(filePath);
28042
28008
  for await (const chunk of input) hash.update(chunk);
28043
28009
  return hash.digest("hex");
@@ -28278,7 +28244,7 @@ var init_io = __esm({
28278
28244
  };
28279
28245
  loadCoreResearchSpec = async (specPath) => {
28280
28246
  const resolvedPath = import_node_path16.default.resolve(specPath);
28281
- const parsed = JSON.parse(await import_promises22.default.readFile(resolvedPath, "utf8"));
28247
+ const parsed = JSON.parse(await import_promises23.default.readFile(resolvedPath, "utf8"));
28282
28248
  const spec = validateCoreResearchSpec(parsed);
28283
28249
  return { resolvedPath, spec, specSha256: sha256Json(spec) };
28284
28250
  };
@@ -28300,17 +28266,17 @@ var init_io = __esm({
28300
28266
  };
28301
28267
  };
28302
28268
  writeJsonAtomic = async (filePath, value) => {
28303
- await import_promises22.default.mkdir(import_node_path16.default.dirname(filePath), { recursive: true });
28269
+ await import_promises23.default.mkdir(import_node_path16.default.dirname(filePath), { recursive: true });
28304
28270
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
28305
- await import_promises22.default.writeFile(temporaryPath, `${canonicalJson(value)}
28271
+ await import_promises23.default.writeFile(temporaryPath, `${canonicalJson(value)}
28306
28272
  `, "utf8");
28307
- await import_promises22.default.rename(temporaryPath, filePath);
28273
+ await import_promises23.default.rename(temporaryPath, filePath);
28308
28274
  };
28309
28275
  buildLedgerRecordHash = (record) => sha256Json(record);
28310
28276
  readCoreResearchLedger = async (ledgerPath) => {
28311
28277
  let text = "";
28312
28278
  try {
28313
- text = await import_promises22.default.readFile(ledgerPath, "utf8");
28279
+ text = await import_promises23.default.readFile(ledgerPath, "utf8");
28314
28280
  } catch (error) {
28315
28281
  if (error.code === "ENOENT") return [];
28316
28282
  throw error;
@@ -28347,11 +28313,11 @@ var init_io = __esm({
28347
28313
  };
28348
28314
  appendCoreResearchLedger = async (params) => {
28349
28315
  const { ledgerPath } = params;
28350
- await import_promises22.default.mkdir(import_node_path16.default.dirname(ledgerPath), { recursive: true });
28316
+ await import_promises23.default.mkdir(import_node_path16.default.dirname(ledgerPath), { recursive: true });
28351
28317
  const lockPath = `${ledgerPath}.lock`;
28352
28318
  let lock = null;
28353
28319
  try {
28354
- lock = await import_promises22.default.open(lockPath, "wx");
28320
+ lock = await import_promises23.default.open(lockPath, "wx");
28355
28321
  const records = await readCoreResearchLedger(ledgerPath);
28356
28322
  const verified = verifyCoreResearchLedger(records);
28357
28323
  const payload = {
@@ -28370,7 +28336,7 @@ var init_io = __esm({
28370
28336
  ...payload,
28371
28337
  recordHash: buildLedgerRecordHash(payload)
28372
28338
  };
28373
- await import_promises22.default.appendFile(ledgerPath, `${canonicalJson(record)}
28339
+ await import_promises23.default.appendFile(ledgerPath, `${canonicalJson(record)}
28374
28340
  `, "utf8");
28375
28341
  return record;
28376
28342
  } catch (error) {
@@ -28380,7 +28346,7 @@ var init_io = __esm({
28380
28346
  throw error;
28381
28347
  } finally {
28382
28348
  await lock?.close();
28383
- await import_promises22.default.rm(lockPath, { force: true });
28349
+ await import_promises23.default.rm(lockPath, { force: true });
28384
28350
  }
28385
28351
  };
28386
28352
  validateCoreResearchParentLineage = async (spec) => {
@@ -28391,9 +28357,9 @@ var init_io = __esm({
28391
28357
  for (const parentResearchId of spec.parentResearchIds ?? []) {
28392
28358
  const parentDir = import_node_path16.default.join(rootDir, parentResearchId);
28393
28359
  const [parentSpec, parentManifest, parentResult] = await Promise.all([
28394
- import_promises22.default.readFile(import_node_path16.default.join(parentDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
28395
- import_promises22.default.readFile(import_node_path16.default.join(parentDir, "manifest.json"), "utf8").then((text) => JSON.parse(text)),
28396
- import_promises22.default.readFile(import_node_path16.default.join(parentDir, "result.json"), "utf8").then((text) => JSON.parse(text))
28360
+ import_promises23.default.readFile(import_node_path16.default.join(parentDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
28361
+ import_promises23.default.readFile(import_node_path16.default.join(parentDir, "manifest.json"), "utf8").then((text) => JSON.parse(text)),
28362
+ import_promises23.default.readFile(import_node_path16.default.join(parentDir, "result.json"), "utf8").then((text) => JSON.parse(text))
28397
28363
  ]);
28398
28364
  validateCoreResearchSpec(parentSpec);
28399
28365
  if (parentManifest.status !== "completed") {
@@ -28440,12 +28406,12 @@ var init_io = __esm({
28440
28406
  await validateCoreResearchParentLineage(spec);
28441
28407
  const specSha256 = sha256Json(spec);
28442
28408
  const paths = resolveCoreResearchPaths(spec);
28443
- await import_promises22.default.mkdir(paths.researchDir, { recursive: true });
28409
+ await import_promises23.default.mkdir(paths.researchDir, { recursive: true });
28444
28410
  let existing = null;
28445
28411
  let existingManifest = null;
28446
28412
  try {
28447
28413
  existing = JSON.parse(
28448
- await import_promises22.default.readFile(paths.specPath, "utf8")
28414
+ await import_promises23.default.readFile(paths.specPath, "utf8")
28449
28415
  );
28450
28416
  } catch (error) {
28451
28417
  if (error.code !== "ENOENT") throw error;
@@ -28458,7 +28424,7 @@ var init_io = __esm({
28458
28424
  if (existing) {
28459
28425
  try {
28460
28426
  existingManifest = JSON.parse(
28461
- await import_promises22.default.readFile(paths.manifestPath, "utf8")
28427
+ await import_promises23.default.readFile(paths.manifestPath, "utf8")
28462
28428
  );
28463
28429
  } catch (error) {
28464
28430
  if (error.code !== "ENOENT") throw error;
@@ -28497,7 +28463,7 @@ var init_io = __esm({
28497
28463
  verifyCoreResearchArtifacts = async (spec) => {
28498
28464
  const paths = resolveCoreResearchPaths(spec);
28499
28465
  const manifest = JSON.parse(
28500
- await import_promises22.default.readFile(paths.manifestPath, "utf8")
28466
+ await import_promises23.default.readFile(paths.manifestPath, "utf8")
28501
28467
  );
28502
28468
  if (manifest.specSha256 !== sha256Json(spec)) {
28503
28469
  throw new Error("Manifest spec hash does not match the supplied spec");
@@ -28525,7 +28491,7 @@ var init_io = __esm({
28525
28491
  const resolvedRoot = import_node_path16.default.resolve(rootDir);
28526
28492
  let entries = [];
28527
28493
  try {
28528
- entries = await import_promises22.default.readdir(resolvedRoot);
28494
+ entries = await import_promises23.default.readdir(resolvedRoot);
28529
28495
  } catch (error) {
28530
28496
  if (error.code === "ENOENT") {
28531
28497
  return {
@@ -28541,14 +28507,14 @@ var init_io = __esm({
28541
28507
  (left, right) => left < right ? -1 : left > right ? 1 : 0
28542
28508
  )) {
28543
28509
  const researchDir = import_node_path16.default.join(resolvedRoot, entry);
28544
- const stats = await import_promises22.default.stat(researchDir);
28510
+ const stats = await import_promises23.default.stat(researchDir);
28545
28511
  if (!stats.isDirectory()) continue;
28546
28512
  let spec;
28547
28513
  let manifest;
28548
28514
  try {
28549
28515
  [spec, manifest] = await Promise.all([
28550
- import_promises22.default.readFile(import_node_path16.default.join(researchDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
28551
- import_promises22.default.readFile(import_node_path16.default.join(researchDir, "manifest.json"), "utf8").then((text) => JSON.parse(text))
28516
+ import_promises23.default.readFile(import_node_path16.default.join(researchDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
28517
+ import_promises23.default.readFile(import_node_path16.default.join(researchDir, "manifest.json"), "utf8").then((text) => JSON.parse(text))
28552
28518
  ]);
28553
28519
  } catch (error) {
28554
28520
  if (error.code === "ENOENT") continue;
@@ -28558,7 +28524,7 @@ var init_io = __esm({
28558
28524
  if (manifest.specSha256 !== sha256Json(spec)) {
28559
28525
  throw new Error(`Stage index found a spec hash mismatch for ${entry}`);
28560
28526
  }
28561
- const result = manifest.status === "completed" ? await import_promises22.default.readFile(import_node_path16.default.join(researchDir, "result.json"), "utf8").then((text) => JSON.parse(text)) : null;
28527
+ const result = manifest.status === "completed" ? await import_promises23.default.readFile(import_node_path16.default.join(researchDir, "result.json"), "utf8").then((text) => JSON.parse(text)) : null;
28562
28528
  familyByResearch.set(spec.researchId, spec.hypothesis.family);
28563
28529
  experiments.push({
28564
28530
  researchId: spec.researchId,
@@ -28613,13 +28579,13 @@ var init_io = __esm({
28613
28579
  });
28614
28580
 
28615
28581
  // src/lib/coreResearch/artifacts.ts
28616
- var import_node_fs4, import_node_events, import_promises23, import_node_path17, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades;
28582
+ var import_node_fs4, import_node_events, import_promises24, import_node_path17, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades;
28617
28583
  var init_artifacts = __esm({
28618
28584
  "src/lib/coreResearch/artifacts.ts"() {
28619
28585
  "use strict";
28620
28586
  import_node_fs4 = require("fs");
28621
28587
  import_node_events = require("events");
28622
- import_promises23 = __toESM(require("fs/promises"));
28588
+ import_promises24 = __toESM(require("fs/promises"));
28623
28589
  import_node_path17 = __toESM(require("path"));
28624
28590
  init_io();
28625
28591
  csv = (value) => {
@@ -28634,7 +28600,7 @@ var init_artifacts = __esm({
28634
28600
  await (0, import_node_events.once)(output, "close");
28635
28601
  };
28636
28602
  writeCoreResearchMatches = async (params) => {
28637
- await import_promises23.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
28603
+ await import_promises24.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
28638
28604
  const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
28639
28605
  await writeLine(
28640
28606
  output,
@@ -28685,7 +28651,7 @@ var init_artifacts = __esm({
28685
28651
  await closeOutput(output);
28686
28652
  };
28687
28653
  writeCoreResearchTrades = async (params) => {
28688
- await import_promises23.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
28654
+ await import_promises24.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
28689
28655
  const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
28690
28656
  for (const variant of params.variants) {
28691
28657
  for (const trade of variant.trades) {
@@ -28925,14 +28891,14 @@ var init_rules = __esm({
28925
28891
  });
28926
28892
 
28927
28893
  // src/lib/coreResearch/statistics.ts
28928
- var import_node_crypto11, createSeededRandom, percentile, calendarClusterBootstrap, applyHolmCorrection, inverseNormalCdf, erf, normalCdf, deflatedSharpeDiagnostic, combinations, probabilityOfBacktestOverfitting;
28894
+ var import_node_crypto12, createSeededRandom, percentile, calendarClusterBootstrap, applyHolmCorrection, inverseNormalCdf, erf, normalCdf, deflatedSharpeDiagnostic, combinations, probabilityOfBacktestOverfitting;
28929
28895
  var init_statistics = __esm({
28930
28896
  "src/lib/coreResearch/statistics.ts"() {
28931
28897
  "use strict";
28932
- import_node_crypto11 = require("crypto");
28898
+ import_node_crypto12 = require("crypto");
28933
28899
  init_metrics();
28934
28900
  createSeededRandom = (seedText) => {
28935
- const digest = (0, import_node_crypto11.createHash)("sha256").update(seedText).digest();
28901
+ const digest = (0, import_node_crypto12.createHash)("sha256").update(seedText).digest();
28936
28902
  let state = digest.readUInt32LE(0) || 1;
28937
28903
  return () => {
28938
28904
  state ^= state << 13;
@@ -29399,11 +29365,11 @@ var init_comparison = __esm({
29399
29365
  });
29400
29366
 
29401
29367
  // src/lib/coreResearch/dataset.ts
29402
- var import_node_crypto12, import_node_fs5, import_node_path18, import_node_readline2, asRecord4, finiteNumber4, normalizeDirection, findStrategySetupIdentity, classifyBreadth, classifyDerivatives, resolveCoreResearchRegime, normalizeCompletedTrade, completedTradeIdentity, positionCycleIdentity, sumBy, weightedPrice, aggregatePositionCycles, compareText, compareTrades, readCoreResearchVariant;
29368
+ var import_node_crypto13, import_node_fs5, import_node_path18, import_node_readline2, asRecord4, finiteNumber4, normalizeDirection, findStrategySetupIdentity, classifyBreadth, classifyDerivatives, resolveCoreResearchRegime, normalizeCompletedTrade, completedTradeIdentity, positionCycleIdentity, sumBy, weightedPrice, aggregatePositionCycles, compareText, compareTrades, readCoreResearchVariant;
29403
29369
  var init_dataset2 = __esm({
29404
29370
  "src/lib/coreResearch/dataset.ts"() {
29405
29371
  "use strict";
29406
- import_node_crypto12 = require("crypto");
29372
+ import_node_crypto13 = require("crypto");
29407
29373
  import_node_fs5 = require("fs");
29408
29374
  import_node_path18 = __toESM(require("path"));
29409
29375
  import_node_readline2 = __toESM(require("readline"));
@@ -29618,7 +29584,7 @@ var init_dataset2 = __esm({
29618
29584
  for (const inputPath of variant.files) {
29619
29585
  const filePath = import_node_path18.default.resolve(inputPath);
29620
29586
  const input = (0, import_node_fs5.createReadStream)(filePath);
29621
- const hash = (0, import_node_crypto12.createHash)("sha256");
29587
+ const hash = (0, import_node_crypto13.createHash)("sha256");
29622
29588
  input.on("data", (chunk) => hash.update(chunk));
29623
29589
  const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
29624
29590
  const fileTrades = [];
@@ -30108,11 +30074,11 @@ var init_selection = __esm({
30108
30074
  });
30109
30075
 
30110
30076
  // src/lib/coreResearch/trace.ts
30111
- var import_promises24, import_node_path19, summarizeCoreResearchTrace;
30077
+ var import_promises25, import_node_path19, summarizeCoreResearchTrace;
30112
30078
  var init_trace = __esm({
30113
30079
  "src/lib/coreResearch/trace.ts"() {
30114
30080
  "use strict";
30115
- import_promises24 = __toESM(require("fs/promises"));
30081
+ import_promises25 = __toESM(require("fs/promises"));
30116
30082
  import_node_path19 = __toESM(require("path"));
30117
30083
  summarizeCoreResearchTrace = async (filePaths = []) => {
30118
30084
  const events = /* @__PURE__ */ Object.create(null);
@@ -30120,7 +30086,7 @@ var init_trace = __esm({
30120
30086
  const exitCodes = /* @__PURE__ */ Object.create(null);
30121
30087
  for (const inputPath of filePaths) {
30122
30088
  const filePath = import_node_path19.default.resolve(inputPath);
30123
- const text = await import_promises24.default.readFile(filePath, "utf8");
30089
+ const text = await import_promises25.default.readFile(filePath, "utf8");
30124
30090
  for (const [index, line] of text.split("\n").entries()) {
30125
30091
  if (!line.trim()) continue;
30126
30092
  let event;
@@ -30160,14 +30126,14 @@ var init_trace = __esm({
30160
30126
  });
30161
30127
 
30162
30128
  // src/lib/coreResearch/orchestrator.ts
30163
- var import_promises25, import_node_path20, import_node_child_process6, import_node_crypto13, import_coreResearch, summarizeSupplementalFiles, analyzeCoreResearchPrepared, analyzeCoreResearch, createCoreResearchSpecTemplate, runCommand2, commandValue, commandHas, validateCoreResearchRunCommand, runCoreResearch;
30129
+ var import_promises26, import_node_path20, import_node_child_process6, import_node_crypto14, import_coreResearch, summarizeSupplementalFiles, analyzeCoreResearchPrepared, analyzeCoreResearch, createCoreResearchSpecTemplate, runCommand2, commandValue, commandHas, validateCoreResearchRunCommand, runCoreResearch;
30164
30130
  var init_orchestrator = __esm({
30165
30131
  "src/lib/coreResearch/orchestrator.ts"() {
30166
30132
  "use strict";
30167
- import_promises25 = __toESM(require("fs/promises"));
30133
+ import_promises26 = __toESM(require("fs/promises"));
30168
30134
  import_node_path20 = __toESM(require("path"));
30169
30135
  import_node_child_process6 = require("child_process");
30170
- import_node_crypto13 = require("crypto");
30136
+ import_node_crypto14 = require("crypto");
30171
30137
  import_coreResearch = require("@tradejs/infra/coreResearch");
30172
30138
  init_artifacts();
30173
30139
  init_io();
@@ -30456,7 +30422,7 @@ var init_orchestrator = __esm({
30456
30422
  const tradesByVariant = new Map(
30457
30423
  windowed.map((entry) => [entry.variant.id, entry.trades])
30458
30424
  );
30459
- await import_promises25.default.writeFile(
30425
+ await import_promises26.default.writeFile(
30460
30426
  paths.reportPath,
30461
30427
  buildCoreResearchHtml({ spec, result, tradesByVariant }),
30462
30428
  "utf8"
@@ -30476,7 +30442,7 @@ var init_orchestrator = __esm({
30476
30442
  if (error.code !== "ENOENT") throw error;
30477
30443
  }
30478
30444
  try {
30479
- for (const name of await import_promises25.default.readdir(paths.runLogDir)) {
30445
+ for (const name of await import_promises26.default.readdir(paths.runLogDir)) {
30480
30446
  if (!name.endsWith(".log")) continue;
30481
30447
  artifactHashes[`runs/${name}`] = await sha256File(
30482
30448
  import_node_path20.default.join(paths.runLogDir, name)
@@ -30569,7 +30535,7 @@ var init_orchestrator = __esm({
30569
30535
  gitSha,
30570
30536
  ...sourceRepository ? { sourceRepository } : {},
30571
30537
  ...dirtyDiff ? {
30572
- dirtyDiffSha256: (0, import_node_crypto13.createHash)("sha256").update(dirtyDiff).digest("hex")
30538
+ dirtyDiffSha256: (0, import_node_crypto14.createHash)("sha256").update(dirtyDiff).digest("hex")
30573
30539
  } : {}
30574
30540
  };
30575
30541
  } catch {
@@ -30676,7 +30642,7 @@ var init_orchestrator = __esm({
30676
30642
  };
30677
30643
  runCommand2 = async (params) => {
30678
30644
  if (!params.command.length) throw new Error("Cannot run an empty command");
30679
- await import_promises25.default.mkdir(import_node_path20.default.dirname(params.logPath), { recursive: true });
30645
+ await import_promises26.default.mkdir(import_node_path20.default.dirname(params.logPath), { recursive: true });
30680
30646
  const chunks = [];
30681
30647
  const child = (0, import_node_child_process6.spawn)(params.command[0], params.command.slice(1), {
30682
30648
  cwd: params.cwd,
@@ -30696,7 +30662,7 @@ var init_orchestrator = __esm({
30696
30662
  child.once("close", (code) => resolve(code ?? 1));
30697
30663
  });
30698
30664
  const output = chunks.join("");
30699
- await import_promises25.default.writeFile(params.logPath, output, "utf8");
30665
+ await import_promises26.default.writeFile(params.logPath, output, "utf8");
30700
30666
  if (exitCode !== 0) {
30701
30667
  throw new Error(
30702
30668
  `Command failed with exit ${exitCode}: ${params.command.join(" ")}`
@@ -30901,11 +30867,11 @@ var coreResearch_exports = {};
30901
30867
  __export(coreResearch_exports, {
30902
30868
  main: () => main34
30903
30869
  });
30904
- var import_promises26, import_node_path21, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main34;
30870
+ var import_promises27, import_node_path21, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main34;
30905
30871
  var init_coreResearch = __esm({
30906
30872
  "src/scripts/coreResearch.ts"() {
30907
30873
  "use strict";
30908
- import_promises26 = __toESM(require("fs/promises"));
30874
+ import_promises27 = __toESM(require("fs/promises"));
30909
30875
  import_node_path21 = __toESM(require("path"));
30910
30876
  import_chalk41 = __toESM(require("chalk"));
30911
30877
  init_io();
@@ -30930,7 +30896,7 @@ var init_coreResearch = __esm({
30930
30896
  const symbolsFile = valueAfter(argv2, "--symbolsFile");
30931
30897
  if (symbolsFile) {
30932
30898
  const parsed = JSON.parse(
30933
- await import_promises26.default.readFile(import_node_path21.default.resolve(projectRoot18, symbolsFile), "utf8")
30899
+ await import_promises27.default.readFile(import_node_path21.default.resolve(projectRoot18, symbolsFile), "utf8")
30934
30900
  );
30935
30901
  if (!Array.isArray(parsed) || parsed.some((symbol) => typeof symbol !== "string")) {
30936
30902
  throw new Error("--symbolsFile must contain a JSON string array");
@@ -31655,11 +31621,11 @@ __export(replayRuntimeEvidence_exports, {
31655
31621
  replayRuntimeEvidence: () => replayRuntimeEvidence,
31656
31622
  summarizeReplayComparison: () => summarizeReplayComparison
31657
31623
  });
31658
- var import_promises27, import_node_path22, import_args27, import_chalk43, import_redis19, toEpochMs2, resolveWindow, parseStrategyFilter, asRecord5, asArray2, sum, groupCount, compactMatched, resolveItemStrategy, summarizeReplayComparison, loadReplayResult, getReplayStrategies, loadRuntimePayload, replayRuntimeEvidence, main36;
31624
+ var import_promises28, import_node_path22, import_args27, import_chalk43, import_redis19, toEpochMs2, resolveWindow, parseStrategyFilter, asRecord5, asArray2, sum, groupCount, compactMatched, resolveItemStrategy, summarizeReplayComparison, loadReplayResult, getReplayStrategies, loadRuntimePayload, replayRuntimeEvidence, main36;
31659
31625
  var init_replayRuntimeEvidence = __esm({
31660
31626
  "src/scripts/replayRuntimeEvidence.ts"() {
31661
31627
  "use strict";
31662
- import_promises27 = __toESM(require("fs/promises"));
31628
+ import_promises28 = __toESM(require("fs/promises"));
31663
31629
  import_node_path22 = __toESM(require("path"));
31664
31630
  import_args27 = __toESM(require("args"));
31665
31631
  import_chalk43 = __toESM(require("chalk"));
@@ -31922,7 +31888,7 @@ var init_replayRuntimeEvidence = __esm({
31922
31888
  const runtimeEvidencePath = typeof runtimeEvidenceFile === "string" && runtimeEvidenceFile.trim() ? import_node_path22.default.resolve(projectRoot18, runtimeEvidenceFile.trim()) : null;
31923
31889
  if (runtimeEvidencePath) {
31924
31890
  const artifact = JSON.parse(
31925
- await import_promises27.default.readFile(runtimeEvidencePath, "utf8")
31891
+ await import_promises28.default.readFile(runtimeEvidencePath, "utf8")
31926
31892
  );
31927
31893
  return {
31928
31894
  source: "file",
@@ -32009,8 +31975,8 @@ var init_replayRuntimeEvidence = __esm({
32009
31975
  runtime: runtime.payload
32010
31976
  };
32011
31977
  const outPath = import_node_path22.default.resolve(projectRoot18, String(flags35.out));
32012
- await import_promises27.default.mkdir(import_node_path22.default.dirname(outPath), { recursive: true });
32013
- await import_promises27.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
31978
+ await import_promises28.default.mkdir(import_node_path22.default.dirname(outPath), { recursive: true });
31979
+ await import_promises28.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
32014
31980
  `, "utf8");
32015
31981
  console.log(import_chalk43.default.green(`Wrote ${outPath}`));
32016
31982
  console.log(
@@ -32032,6 +31998,15 @@ var init_replayRuntimeEvidence = __esm({
32032
31998
  }
32033
31999
  });
32034
32000
 
32001
+ // src/lib/runtimeEvidenceProducer.ts
32002
+ var runtimeEvidenceProducer_exports = {};
32003
+ var init_runtimeEvidenceProducer = __esm({
32004
+ "src/lib/runtimeEvidenceProducer.ts"() {
32005
+ "use strict";
32006
+ __reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
32007
+ }
32008
+ });
32009
+
32035
32010
  // src/lib/runtimeFeedbackArtifacts.ts
32036
32011
  var runtimeFeedbackArtifacts_exports = {};
32037
32012
  var init_runtimeFeedbackArtifacts = __esm({
@@ -32042,12 +32017,12 @@ var init_runtimeFeedbackArtifacts = __esm({
32042
32017
  });
32043
32018
 
32044
32019
  // src/lib/runtimeFeedbackReplay.ts
32045
- var import_node_child_process7, import_promises28, import_node_path23, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
32020
+ var import_node_child_process7, import_promises29, import_node_path23, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
32046
32021
  var init_runtimeFeedbackReplay = __esm({
32047
32022
  "src/lib/runtimeFeedbackReplay.ts"() {
32048
32023
  "use strict";
32049
32024
  import_node_child_process7 = require("child_process");
32050
- import_promises28 = __toESM(require("fs/promises"));
32025
+ import_promises29 = __toESM(require("fs/promises"));
32051
32026
  import_node_path23 = __toESM(require("path"));
32052
32027
  init_runtimeEvidenceDeployment();
32053
32028
  init_runtimeEvidenceArtifacts();
@@ -32264,15 +32239,15 @@ $ ${[executable, ...command].join(" ")}
32264
32239
  if (!intervals.size) {
32265
32240
  throw new Error("Runtime feedback replay requires an active interval");
32266
32241
  }
32267
- await import_promises28.default.mkdir(outDir, { recursive: true });
32268
- const existing = await import_promises28.default.readdir(outDir);
32242
+ await import_promises29.default.mkdir(outDir, { recursive: true });
32243
+ const existing = await import_promises29.default.readdir(outDir);
32269
32244
  if (existing.length) {
32270
32245
  throw new Error(
32271
32246
  `Runtime feedback output directory must be empty: ${outDir}`
32272
32247
  );
32273
32248
  }
32274
32249
  const replayEvidencePath = import_node_path23.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_REPLAY_FILE);
32275
- const logHandle = await import_promises28.default.open(
32250
+ const logHandle = await import_promises29.default.open(
32276
32251
  import_node_path23.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_LOG_FILE),
32277
32252
  "wx"
32278
32253
  );
@@ -32530,12 +32505,12 @@ var init_runtimeFeedbackNotify = __esm({
32530
32505
  });
32531
32506
 
32532
32507
  // src/lib/runtimeEvidenceSync.ts
32533
- var import_node_child_process8, import_promises29, import_node_path26, import_node_util, execFileAsync, isExistingDestinationError, safeSegment2, withTrailingSlash, dateParts, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
32508
+ var import_node_child_process8, import_promises30, import_node_path26, import_node_util, execFileAsync, isExistingDestinationError, safeSegment2, withTrailingSlash, dateParts, buildRuntimeEvidenceRsyncArgs, receiptPath, compareBundles, listPendingRuntimeEvidenceBundles, markRuntimeEvidenceBundleProcessed, syncRuntimeEvidenceBundles;
32534
32509
  var init_runtimeEvidenceSync = __esm({
32535
32510
  "src/lib/runtimeEvidenceSync.ts"() {
32536
32511
  "use strict";
32537
32512
  import_node_child_process8 = require("child_process");
32538
- import_promises29 = __toESM(require("fs/promises"));
32513
+ import_promises30 = __toESM(require("fs/promises"));
32539
32514
  import_node_path26 = __toESM(require("path"));
32540
32515
  import_node_util = require("util");
32541
32516
  init_runtimeEvidenceArtifacts();
@@ -32586,7 +32561,7 @@ var init_runtimeEvidenceSync = __esm({
32586
32561
  if (verified.manifest.deploymentId !== safeDeploymentId) continue;
32587
32562
  (0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
32588
32563
  try {
32589
- await import_promises29.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
32564
+ await import_promises30.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
32590
32565
  continue;
32591
32566
  } catch (error) {
32592
32567
  if (error.code !== "ENOENT") throw error;
@@ -32623,14 +32598,14 @@ var init_runtimeEvidenceSync = __esm({
32623
32598
  replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
32624
32599
  } : {}
32625
32600
  };
32626
- await import_promises29.default.mkdir(receiptsRoot, { recursive: true });
32627
- await import_promises29.default.writeFile(
32601
+ await import_promises30.default.mkdir(receiptsRoot, { recursive: true });
32602
+ await import_promises30.default.writeFile(
32628
32603
  temporaryPath,
32629
32604
  `${JSON.stringify(receipt, null, 2)}
32630
32605
  `,
32631
32606
  "utf8"
32632
32607
  );
32633
- await import_promises29.default.rename(temporaryPath, finalPath);
32608
+ await import_promises30.default.rename(temporaryPath, finalPath);
32634
32609
  return finalPath;
32635
32610
  };
32636
32611
  syncRuntimeEvidenceBundles = async ({
@@ -32648,8 +32623,8 @@ var init_runtimeEvidenceSync = __esm({
32648
32623
  const inboxRoot = import_node_path26.default.join(evidenceRoot, "inbox", safeDeploymentId);
32649
32624
  const artifactsRoot = import_node_path26.default.join(evidenceRoot, "artifacts", safeDeploymentId);
32650
32625
  await Promise.all([
32651
- import_promises29.default.mkdir(inboxRoot, { recursive: true }),
32652
- import_promises29.default.mkdir(artifactsRoot, { recursive: true })
32626
+ import_promises30.default.mkdir(inboxRoot, { recursive: true }),
32627
+ import_promises30.default.mkdir(artifactsRoot, { recursive: true })
32653
32628
  ]);
32654
32629
  const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
32655
32630
  source,
@@ -32671,9 +32646,9 @@ var init_runtimeEvidenceSync = __esm({
32671
32646
  ...dateParts(verified.manifest.window.endTime),
32672
32647
  safeSegment2(verified.manifest.artifactId, "artifact")
32673
32648
  );
32674
- await import_promises29.default.mkdir(import_node_path26.default.dirname(destinationDir), { recursive: true });
32649
+ await import_promises30.default.mkdir(import_node_path26.default.dirname(destinationDir), { recursive: true });
32675
32650
  try {
32676
- await import_promises29.default.rename(bundleDir, destinationDir);
32651
+ await import_promises30.default.rename(bundleDir, destinationDir);
32677
32652
  } catch (error) {
32678
32653
  if (!isExistingDestinationError(error)) throw error;
32679
32654
  const existing = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir);
@@ -32682,7 +32657,7 @@ var init_runtimeEvidenceSync = __esm({
32682
32657
  `Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
32683
32658
  );
32684
32659
  }
32685
- await import_promises29.default.rm(bundleDir, { recursive: true, force: true });
32660
+ await import_promises30.default.rm(bundleDir, { recursive: true, force: true });
32686
32661
  }
32687
32662
  received.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir));
32688
32663
  }
@@ -32702,12 +32677,12 @@ var init_runtimeEvidenceSync = __esm({
32702
32677
  });
32703
32678
 
32704
32679
  // src/lib/runtimeFeedbackSync.ts
32705
- var import_node_child_process9, import_promises30, import_node_path27, import_node_util2, execFileAsync2, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
32680
+ var import_node_child_process9, import_promises31, import_node_path27, import_node_util2, execFileAsync2, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
32706
32681
  var init_runtimeFeedbackSync = __esm({
32707
32682
  "src/lib/runtimeFeedbackSync.ts"() {
32708
32683
  "use strict";
32709
32684
  import_node_child_process9 = require("child_process");
32710
- import_promises30 = __toESM(require("fs/promises"));
32685
+ import_promises31 = __toESM(require("fs/promises"));
32711
32686
  import_node_path27 = __toESM(require("path"));
32712
32687
  import_node_util2 = require("util");
32713
32688
  init_runtimeFeedbackArtifacts();
@@ -32744,8 +32719,8 @@ var init_runtimeFeedbackSync = __esm({
32744
32719
  const inboxRoot = import_node_path27.default.join(feedbackRoot, "inbox", safeDeploymentId);
32745
32720
  const artifactsRoot = import_node_path27.default.join(feedbackRoot, "artifacts", safeDeploymentId);
32746
32721
  await Promise.all([
32747
- import_promises30.default.mkdir(inboxRoot, { recursive: true }),
32748
- import_promises30.default.mkdir(artifactsRoot, { recursive: true })
32722
+ import_promises31.default.mkdir(inboxRoot, { recursive: true }),
32723
+ import_promises31.default.mkdir(artifactsRoot, { recursive: true })
32749
32724
  ]);
32750
32725
  const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
32751
32726
  source,
@@ -32767,9 +32742,9 @@ var init_runtimeFeedbackSync = __esm({
32767
32742
  safeSegment3(verified.manifest.runtimeEvidence.artifactId, "artifact"),
32768
32743
  safeSegment3(verified.manifest.runId, "run")
32769
32744
  );
32770
- await import_promises30.default.mkdir(import_node_path27.default.dirname(destinationDir), { recursive: true });
32745
+ await import_promises31.default.mkdir(import_node_path27.default.dirname(destinationDir), { recursive: true });
32771
32746
  try {
32772
- await import_promises30.default.rename(bundleDir, destinationDir);
32747
+ await import_promises31.default.rename(bundleDir, destinationDir);
32773
32748
  } catch (error) {
32774
32749
  if (!isExistingDestinationError2(error)) throw error;
32775
32750
  const existing = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir);
@@ -32778,7 +32753,7 @@ var init_runtimeFeedbackSync = __esm({
32778
32753
  `Conflicting runtime feedback replay ${verified.manifest.artifactId}`
32779
32754
  );
32780
32755
  }
32781
- await import_promises30.default.rm(bundleDir, { recursive: true, force: true });
32756
+ await import_promises31.default.rm(bundleDir, { recursive: true, force: true });
32782
32757
  }
32783
32758
  received.push(await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir));
32784
32759
  }
@@ -32862,12 +32837,12 @@ var init_runtimeFeedbackSync2 = __esm({
32862
32837
  });
32863
32838
 
32864
32839
  // src/lib/runtimeEvidenceCompositionSnapshots.ts
32865
- var import_node_crypto14, import_promises31, import_node_path29, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord2, sha256, safeSegment4, isExistingDestinationError3, parseManifest, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
32840
+ var import_node_crypto15, import_promises32, import_node_path29, SNAPSHOT_FILE, MANIFEST_FILE, COMPLETE_FILE, createRuntimeEvidenceCompositionSnapshotRecorder, isRecord2, sha256, safeSegment4, isExistingDestinationError3, parseManifest, verifyRuntimeEvidenceCompositionSnapshot, sameSnapshot, publishRuntimeEvidenceCompositionSnapshot, captureRuntimeEvidenceCompositionSnapshot, discoverRuntimeEvidenceCompositionSnapshots;
32866
32841
  var init_runtimeEvidenceCompositionSnapshots = __esm({
32867
32842
  "src/lib/runtimeEvidenceCompositionSnapshots.ts"() {
32868
32843
  "use strict";
32869
- import_node_crypto14 = require("crypto");
32870
- import_promises31 = __toESM(require("fs/promises"));
32844
+ import_node_crypto15 = require("crypto");
32845
+ import_promises32 = __toESM(require("fs/promises"));
32871
32846
  import_node_path29 = __toESM(require("path"));
32872
32847
  init_runtimeEvidenceDeployment();
32873
32848
  init_runtimeEvidenceProducer();
@@ -32889,7 +32864,7 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
32889
32864
  };
32890
32865
  };
32891
32866
  isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
32892
- sha256 = (value) => (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex");
32867
+ sha256 = (value) => (0, import_node_crypto15.createHash)("sha256").update(value).digest("hex");
32893
32868
  safeSegment4 = (value, label) => {
32894
32869
  const normalized = value.trim();
32895
32870
  if (!normalized || !/^[a-zA-Z0-9._:-]+$/.test(normalized)) {
@@ -32911,9 +32886,9 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
32911
32886
  };
32912
32887
  verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
32913
32888
  const [manifestText, payload, completeText] = await Promise.all([
32914
- import_promises31.default.readFile(import_node_path29.default.join(bundleDir, MANIFEST_FILE), "utf8"),
32915
- import_promises31.default.readFile(import_node_path29.default.join(bundleDir, SNAPSHOT_FILE)),
32916
- import_promises31.default.readFile(import_node_path29.default.join(bundleDir, COMPLETE_FILE), "utf8")
32889
+ import_promises32.default.readFile(import_node_path29.default.join(bundleDir, MANIFEST_FILE), "utf8"),
32890
+ import_promises32.default.readFile(import_node_path29.default.join(bundleDir, SNAPSHOT_FILE)),
32891
+ import_promises32.default.readFile(import_node_path29.default.join(bundleDir, COMPLETE_FILE), "utf8")
32917
32892
  ]);
32918
32893
  const manifest = parseManifest(JSON.parse(manifestText));
32919
32894
  if (completeText.trim() !== manifest.deploymentCompositionId) {
@@ -32981,34 +32956,34 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
32981
32956
  const temporaryDir = import_node_path29.default.join(
32982
32957
  evidenceRoot,
32983
32958
  "incoming",
32984
- `snapshot-${compositionId}.tmp-${(0, import_node_crypto14.randomUUID)()}`
32959
+ `snapshot-${compositionId}.tmp-${(0, import_node_crypto15.randomUUID)()}`
32985
32960
  );
32986
- await import_promises31.default.mkdir(temporaryDir, { recursive: true });
32961
+ await import_promises32.default.mkdir(temporaryDir, { recursive: true });
32987
32962
  try {
32988
32963
  await Promise.all([
32989
- import_promises31.default.writeFile(import_node_path29.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
32990
- import_promises31.default.writeFile(
32964
+ import_promises32.default.writeFile(import_node_path29.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
32965
+ import_promises32.default.writeFile(
32991
32966
  import_node_path29.default.join(temporaryDir, MANIFEST_FILE),
32992
32967
  `${JSON.stringify(manifest, null, 2)}
32993
32968
  `,
32994
32969
  "utf8"
32995
32970
  )
32996
32971
  ]);
32997
- await import_promises31.default.writeFile(
32972
+ await import_promises32.default.writeFile(
32998
32973
  import_node_path29.default.join(temporaryDir, COMPLETE_FILE),
32999
32974
  `${compositionId}
33000
32975
  `,
33001
32976
  "utf8"
33002
32977
  );
33003
- await import_promises31.default.mkdir(snapshotsRoot, { recursive: true });
32978
+ await import_promises32.default.mkdir(snapshotsRoot, { recursive: true });
33004
32979
  try {
33005
- await import_promises31.default.rename(temporaryDir, bundleDir);
32980
+ await import_promises32.default.rename(temporaryDir, bundleDir);
33006
32981
  } catch (error) {
33007
32982
  if (!isExistingDestinationError3(error)) throw error;
33008
- await import_promises31.default.rm(temporaryDir, { recursive: true, force: true });
32983
+ await import_promises32.default.rm(temporaryDir, { recursive: true, force: true });
33009
32984
  }
33010
32985
  } catch (error) {
33011
- await import_promises31.default.rm(temporaryDir, { recursive: true, force: true });
32986
+ await import_promises32.default.rm(temporaryDir, { recursive: true, force: true });
33012
32987
  throw error;
33013
32988
  }
33014
32989
  const verified = await verifyRuntimeEvidenceCompositionSnapshot(bundleDir);
@@ -33053,14 +33028,14 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
33053
33028
  const bundleDirs = [];
33054
33029
  let deployments;
33055
33030
  try {
33056
- deployments = await import_promises31.default.readdir(rootDir, { withFileTypes: true });
33031
+ deployments = await import_promises32.default.readdir(rootDir, { withFileTypes: true });
33057
33032
  } catch (error) {
33058
33033
  if (error.code === "ENOENT") return [];
33059
33034
  throw error;
33060
33035
  }
33061
33036
  for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
33062
33037
  const deploymentDir = import_node_path29.default.join(rootDir, deployment.name);
33063
- const compositions = await import_promises31.default.readdir(deploymentDir, {
33038
+ const compositions = await import_promises32.default.readdir(deploymentDir, {
33064
33039
  withFileTypes: true
33065
33040
  });
33066
33041
  bundleDirs.push(
@@ -33245,11 +33220,11 @@ __export(runtimeEvidence_exports, {
33245
33220
  main: () => main40,
33246
33221
  runtimeEvidence: () => runtimeEvidence
33247
33222
  });
33248
- var import_promises32, import_node_path30, import_args31, import_chalk47, flags28, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main40;
33223
+ var import_promises33, import_node_path30, import_args31, import_chalk47, flags28, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main40;
33249
33224
  var init_runtimeEvidence = __esm({
33250
33225
  "src/scripts/runtimeEvidence.ts"() {
33251
33226
  "use strict";
33252
- import_promises32 = __toESM(require("fs/promises"));
33227
+ import_promises33 = __toESM(require("fs/promises"));
33253
33228
  import_node_path30 = __toESM(require("path"));
33254
33229
  import_args31 = __toESM(require("args"));
33255
33230
  import_chalk47 = __toESM(require("chalk"));
@@ -33432,8 +33407,8 @@ var init_runtimeEvidence = __esm({
33432
33407
  }
33433
33408
  const artifact = current.artifact;
33434
33409
  const outPath = import_node_path30.default.resolve(projectRoot12, String(flags28.out));
33435
- await import_promises32.default.mkdir(import_node_path30.default.dirname(outPath), { recursive: true });
33436
- await import_promises32.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
33410
+ await import_promises33.default.mkdir(import_node_path30.default.dirname(outPath), { recursive: true });
33411
+ await import_promises33.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
33437
33412
  `, "utf8");
33438
33413
  const published = publishDir ? await Promise.all(
33439
33414
  artifacts.map(
@@ -34620,7 +34595,7 @@ async function collectReleaseEvidenceReferences(references) {
34620
34595
  let artifact;
34621
34596
  try {
34622
34597
  const parsed = JSON.parse(
34623
- await import_promises33.default.readFile(reference.path, "utf8")
34598
+ await import_promises34.default.readFile(reference.path, "utf8")
34624
34599
  );
34625
34600
  assert3(
34626
34601
  parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
@@ -34767,12 +34742,12 @@ async function collectReleaseEvidenceReferences(references) {
34767
34742
  })
34768
34743
  );
34769
34744
  }
34770
- var import_node_crypto15, import_promises33, import_node_path32, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment5, compactTimestamp, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber7, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
34745
+ var import_node_crypto16, import_promises34, import_node_path32, import_types9, import_strategyReleaseEvidence2, SHA256_RE2, LINEAGE_FINGERPRINT_RE, STRATEGY_REVISION_RE, DEPLOYMENT_COMPOSITION_ID_RE, REQUIRED_LONG_WINDOWS, REQUIRED_DIAGNOSTIC_TERMINAL_WINDOWS, MIN_RECENT_DIRECTION_REPAIR_EVENTS, safeSegment5, compactTimestamp, verifyFullPeriodChartArtifact, readVerifiedJsonArtifact, verifyResearchDecisionLineage, hasExactRuntimeTarget, deriveStrategyReleaseResearchDecision, canonicalStrategyReleaseJson, strategyReleaseSha256, assertFingerprint, assertLineageFingerprint, releaseReasons, deriveReleaseGates, verifyEvidenceComposition, createStrategyReleaseManifest, createStrategyReleaseEnvelope, verifyStrategyReleaseEnvelope, verifyStrategyEvidenceMarkerEnvelope, releaseMarkers, writeJsonAtomic2, publishStrategyRelease, publishStrategyLiveDiagnosis, finiteString3, finiteNumber7, finiteDirectionPolicy, uniqueStrings, incompleteEvidenceLineage, extractEvidenceLineage, verifyCompletedCoreResearchBundle;
34771
34746
  var init_strategyRelease = __esm({
34772
34747
  "src/lib/strategyRelease.ts"() {
34773
34748
  "use strict";
34774
- import_node_crypto15 = require("crypto");
34775
- import_promises33 = __toESM(require("fs/promises"));
34749
+ import_node_crypto16 = require("crypto");
34750
+ import_promises34 = __toESM(require("fs/promises"));
34776
34751
  import_node_path32 = __toESM(require("path"));
34777
34752
  import_types9 = require("@tradejs/types");
34778
34753
  import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
@@ -34796,7 +34771,7 @@ var init_strategyRelease = __esm({
34796
34771
  if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
34797
34772
  return false;
34798
34773
  }
34799
- const report = JSON.parse(await import_promises33.default.readFile(artifactPath, "utf8"));
34774
+ const report = JSON.parse(await import_promises34.default.readFile(artifactPath, "utf8"));
34800
34775
  return Boolean(
34801
34776
  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
34802
34777
  );
@@ -34811,7 +34786,7 @@ var init_strategyRelease = __esm({
34811
34786
  if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
34812
34787
  return null;
34813
34788
  }
34814
- return JSON.parse(await import_promises33.default.readFile(artifactPath, "utf8"));
34789
+ return JSON.parse(await import_promises34.default.readFile(artifactPath, "utf8"));
34815
34790
  } catch {
34816
34791
  return null;
34817
34792
  }
@@ -35357,7 +35332,7 @@ var init_strategyRelease = __esm({
35357
35332
  manifest
35358
35333
  });
35359
35334
  verifyStrategyReleaseEnvelope = async (valueOrPath) => {
35360
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises33.default.readFile(valueOrPath, "utf8")) : valueOrPath;
35335
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises34.default.readFile(valueOrPath, "utf8")) : valueOrPath;
35361
35336
  const envelope = value;
35362
35337
  assert3(
35363
35338
  envelope?.schema === "tradejs-strategy-release-envelope/v1",
@@ -35408,7 +35383,7 @@ var init_strategyRelease = __esm({
35408
35383
  return envelope;
35409
35384
  };
35410
35385
  verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
35411
- const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises33.default.readFile(valueOrPath, "utf8")) : valueOrPath;
35386
+ const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises34.default.readFile(valueOrPath, "utf8")) : valueOrPath;
35412
35387
  return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
35413
35388
  };
35414
35389
  releaseMarkers = (manifest) => {
@@ -35470,14 +35445,14 @@ var init_strategyRelease = __esm({
35470
35445
  };
35471
35446
  writeJsonAtomic2 = async (filePath, value) => {
35472
35447
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
35473
- await import_promises33.default.mkdir(import_node_path32.default.dirname(filePath), { recursive: true });
35474
- await import_promises33.default.writeFile(
35448
+ await import_promises34.default.mkdir(import_node_path32.default.dirname(filePath), { recursive: true });
35449
+ await import_promises34.default.writeFile(
35475
35450
  temporaryPath,
35476
35451
  `${canonicalStrategyReleaseJson(value)}
35477
35452
  `,
35478
35453
  "utf8"
35479
35454
  );
35480
- await import_promises33.default.rename(temporaryPath, filePath);
35455
+ await import_promises34.default.rename(temporaryPath, filePath);
35481
35456
  };
35482
35457
  publishStrategyRelease = async ({
35483
35458
  rootDir,
@@ -35779,8 +35754,8 @@ var init_strategyRelease = __esm({
35779
35754
  const researchDir = import_node_path32.default.dirname(resultPath);
35780
35755
  const manifestPath = import_node_path32.default.join(researchDir, "manifest.json");
35781
35756
  const specPath = import_node_path32.default.join(researchDir, "spec.json");
35782
- const manifestBytes = await import_promises33.default.readFile(manifestPath).catch(() => null);
35783
- const specBytes = await import_promises33.default.readFile(specPath).catch(() => null);
35757
+ const manifestBytes = await import_promises34.default.readFile(manifestPath).catch(() => null);
35758
+ const specBytes = await import_promises34.default.readFile(specPath).catch(() => null);
35784
35759
  assert3(
35785
35760
  manifestBytes != null && specBytes != null,
35786
35761
  "core result must belong to a completed core research bundle"
@@ -35789,7 +35764,7 @@ var init_strategyRelease = __esm({
35789
35764
  const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
35790
35765
  const parsedSpec = JSON.parse(specBytes.toString("utf8"));
35791
35766
  assert3(
35792
- manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto15.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
35767
+ manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto16.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
35793
35768
  "core result is not bound by its completed core research manifest"
35794
35769
  );
35795
35770
  for (const [relativePath, expectedSha256] of Object.entries(
@@ -35821,12 +35796,12 @@ __export(runtimeScorecard_exports, {
35821
35796
  main: () => main42,
35822
35797
  runtimeScorecard: () => runtimeScorecard
35823
35798
  });
35824
- var import_promises34, import_node_crypto16, import_node_path33, import_args33, import_chalk49, flags30, projectRoot14, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main42;
35799
+ var import_promises35, import_node_crypto17, import_node_path33, import_args33, import_chalk49, flags30, projectRoot14, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main42;
35825
35800
  var init_runtimeScorecard2 = __esm({
35826
35801
  "src/scripts/runtimeScorecard.ts"() {
35827
35802
  "use strict";
35828
- import_promises34 = __toESM(require("fs/promises"));
35829
- import_node_crypto16 = require("crypto");
35803
+ import_promises35 = __toESM(require("fs/promises"));
35804
+ import_node_crypto17 = require("crypto");
35830
35805
  import_node_path33 = __toESM(require("path"));
35831
35806
  import_args33 = __toESM(require("args"));
35832
35807
  import_chalk49 = __toESM(require("chalk"));
@@ -35899,13 +35874,13 @@ var init_runtimeScorecard2 = __esm({
35899
35874
  const raw = String(value ?? "").trim();
35900
35875
  return raw ? import_node_path33.default.resolve(projectRoot14, raw) : null;
35901
35876
  };
35902
- readJson = async (filePath) => filePath ? JSON.parse(await import_promises34.default.readFile(filePath, "utf8")) : void 0;
35877
+ readJson = async (filePath) => filePath ? JSON.parse(await import_promises35.default.readFile(filePath, "utf8")) : void 0;
35903
35878
  assertReportType = (artifact, expected, label) => {
35904
35879
  if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
35905
35880
  throw new Error(`${label} must be a ${expected} artifact`);
35906
35881
  }
35907
35882
  };
35908
- sha256File2 = async (filePath) => (0, import_node_crypto16.createHash)("sha256").update(await import_promises34.default.readFile(filePath)).digest("hex");
35883
+ sha256File2 = async (filePath) => (0, import_node_crypto17.createHash)("sha256").update(await import_promises35.default.readFile(filePath)).digest("hex");
35909
35884
  loadHistoryArtifacts = async (historyDir) => {
35910
35885
  if (!historyDir) return [];
35911
35886
  const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(historyDir);
@@ -35978,11 +35953,11 @@ var init_runtimeScorecard2 = __esm({
35978
35953
  });
35979
35954
  const outPath = import_node_path33.default.resolve(projectRoot14, String(flags30.out));
35980
35955
  const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
35981
- await import_promises34.default.mkdir(import_node_path33.default.dirname(outPath), { recursive: true });
35956
+ await import_promises35.default.mkdir(import_node_path33.default.dirname(outPath), { recursive: true });
35982
35957
  await Promise.all([
35983
- import_promises34.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
35958
+ import_promises35.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
35984
35959
  `, "utf8"),
35985
- import_promises34.default.writeFile(
35960
+ import_promises35.default.writeFile(
35986
35961
  markdownPath,
35987
35962
  formatRuntimeScorecardMarkdown(scorecard),
35988
35963
  "utf8"
@@ -35996,7 +35971,7 @@ var init_runtimeScorecard2 = __esm({
35996
35971
  const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
35997
35972
  const strategyReleaseRoot = resolveOptionalPath(flags30.strategyReleaseRoot);
35998
35973
  if (diagnosis && diagnosisPath) {
35999
- await import_promises34.default.writeFile(
35974
+ await import_promises35.default.writeFile(
36000
35975
  diagnosisPath,
36001
35976
  `${JSON.stringify(diagnosis, null, 2)}
36002
35977
  `,
@@ -36369,13 +36344,13 @@ print(json.dumps(sorted(opened)))
36369
36344
  });
36370
36345
 
36371
36346
  // src/lib/strategyRelease/researchRetention.ts
36372
- var import_promises35, import_node_path35, import_node_crypto17, import_strategyReleaseEvidence3, SHA256_RE3, mapFiles, fileSha256, inside, applyResearchRetention;
36347
+ var import_promises36, import_node_path35, import_node_crypto18, import_strategyReleaseEvidence3, SHA256_RE3, mapFiles, fileSha256, inside, applyResearchRetention;
36373
36348
  var init_researchRetention = __esm({
36374
36349
  "src/lib/strategyRelease/researchRetention.ts"() {
36375
36350
  "use strict";
36376
- import_promises35 = __toESM(require("fs/promises"));
36351
+ import_promises36 = __toESM(require("fs/promises"));
36377
36352
  import_node_path35 = __toESM(require("path"));
36378
- import_node_crypto17 = require("crypto");
36353
+ import_node_crypto18 = require("crypto");
36379
36354
  import_strategyReleaseEvidence3 = require("@tradejs/infra/strategyReleaseEvidence");
36380
36355
  init_researchFileConsumers();
36381
36356
  init_evidenceRetention();
@@ -36395,13 +36370,13 @@ var init_researchRetention = __esm({
36395
36370
  if (worker.status === "rejected") throw worker.reason;
36396
36371
  return results2;
36397
36372
  };
36398
- fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto17.createHash)("sha256").update(await import_promises35.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence3.strategyEvidenceFileSha256)(file);
36373
+ fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto18.createHash)("sha256").update(await import_promises36.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence3.strategyEvidenceFileSha256)(file);
36399
36374
  inside = (root, file) => {
36400
36375
  const relative = import_node_path35.default.relative(root, file);
36401
36376
  return relative !== "" && !relative.startsWith(`..${import_node_path35.default.sep}`) && relative !== ".." && !import_node_path35.default.isAbsolute(relative);
36402
36377
  };
36403
36378
  applyResearchRetention = async (options) => {
36404
- const projectRoot18 = await import_promises35.default.realpath(options.projectRoot);
36379
+ const projectRoot18 = await import_promises36.default.realpath(options.projectRoot);
36405
36380
  const dataRoot = import_node_path35.default.join(projectRoot18, "data");
36406
36381
  const resolve = (file) => import_node_path35.default.resolve(projectRoot18, file);
36407
36382
  const receiptPath2 = resolve(options.receiptPath);
@@ -36428,13 +36403,13 @@ var init_researchRetention = __esm({
36428
36403
  }
36429
36404
  await mapFiles(options.research.permanentArtifacts, async (artifact) => {
36430
36405
  const file = resolve(artifact.path);
36431
- if (!inside(projectRoot18, await import_promises35.default.realpath(file)) || !SHA256_RE3.test(artifact.sha256) || await fileSha256(file, (await import_promises35.default.stat(file)).size) !== artifact.sha256) {
36406
+ if (!inside(projectRoot18, await import_promises36.default.realpath(file)) || !SHA256_RE3.test(artifact.sha256) || await fileSha256(file, (await import_promises36.default.stat(file)).size) !== artifact.sha256) {
36432
36407
  throw new Error(
36433
36408
  `Permanent research artifact checksum/path mismatch: ${file}`
36434
36409
  );
36435
36410
  }
36436
36411
  if (artifact.role === "note") {
36437
- const handle = await import_promises35.default.open(file, "r");
36412
+ const handle = await import_promises36.default.open(file, "r");
36438
36413
  try {
36439
36414
  const header = Buffer.alloc(4096);
36440
36415
  const { bytesRead } = await handle.read(header, 0, header.length, 0);
@@ -36460,9 +36435,9 @@ var init_researchRetention = __esm({
36460
36435
  if (checkedPaths.has(file))
36461
36436
  throw new Error(`Duplicate cleanup path: ${file}`);
36462
36437
  checkedPaths.add(file);
36463
- if (await import_promises35.default.realpath(file) !== file)
36438
+ if (await import_promises36.default.realpath(file) !== file)
36464
36439
  throw new Error(`Research cleanup refuses symlinks: ${file}`);
36465
- const stat = await import_promises35.default.lstat(file);
36440
+ const stat = await import_promises36.default.lstat(file);
36466
36441
  if (!stat.isFile() || stat.size !== entry.bytes || await fileSha256(file, stat.size) !== entry.sha256) {
36467
36442
  throw new Error(
36468
36443
  `Disposable research file checksum/size mismatch: ${file}`
@@ -36488,29 +36463,29 @@ var init_researchRetention = __esm({
36488
36463
  }))
36489
36464
  };
36490
36465
  if (!options.apply) return receipt;
36491
- await import_promises35.default.mkdir(import_node_path35.default.dirname(receiptPath2), { recursive: true });
36492
- if (await import_promises35.default.realpath(import_node_path35.default.dirname(receiptPath2)) !== import_node_path35.default.dirname(receiptPath2)) {
36466
+ await import_promises36.default.mkdir(import_node_path35.default.dirname(receiptPath2), { recursive: true });
36467
+ if (await import_promises36.default.realpath(import_node_path35.default.dirname(receiptPath2)) !== import_node_path35.default.dirname(receiptPath2)) {
36493
36468
  throw new Error("Cleanup receipt refuses symlinked directories");
36494
36469
  }
36495
- const lock = await import_promises35.default.open(`${receiptPath2}.lock`, "wx");
36470
+ const lock = await import_promises36.default.open(`${receiptPath2}.lock`, "wx");
36496
36471
  let journal;
36497
36472
  const writeReceipt = async () => {
36498
36473
  const temp = `${receiptPath2}.${process.pid}.tmp`;
36499
- await import_promises35.default.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
36474
+ await import_promises36.default.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
36500
36475
  `, "utf8");
36501
- await import_promises35.default.rename(temp, receiptPath2);
36476
+ await import_promises36.default.rename(temp, receiptPath2);
36502
36477
  };
36503
36478
  try {
36504
- journal = await import_promises35.default.open(journalPath, "wx");
36479
+ journal = await import_promises36.default.open(journalPath, "wx");
36505
36480
  receipt.status = "applying";
36506
36481
  await writeReceipt();
36507
36482
  for (let index = 0; index < checked.length; index += 1) {
36508
36483
  const { file, entry, ino, mtimeMs } = checked[index];
36509
- const stat = await import_promises35.default.lstat(file);
36484
+ const stat = await import_promises36.default.lstat(file);
36510
36485
  if (!stat.isFile() || stat.ino !== ino || stat.mtimeMs !== mtimeMs || stat.size !== entry.bytes) {
36511
36486
  throw new Error(`Research file changed during cleanup: ${file}`);
36512
36487
  }
36513
- await import_promises35.default.unlink(file);
36488
+ await import_promises36.default.unlink(file);
36514
36489
  receipt.files[index].removed = true;
36515
36490
  await journal.write(`${JSON.stringify(receipt.files[index])}
36516
36491
  `);
@@ -36524,7 +36499,7 @@ var init_researchRetention = __esm({
36524
36499
  } finally {
36525
36500
  await journal?.close();
36526
36501
  await lock.close();
36527
- await import_promises35.default.unlink(`${receiptPath2}.lock`);
36502
+ await import_promises36.default.unlink(`${receiptPath2}.lock`);
36528
36503
  }
36529
36504
  };
36530
36505
  }
@@ -36536,11 +36511,11 @@ __export(strategyRelease_exports, {
36536
36511
  main: () => main44,
36537
36512
  runStrategyReleaseCommand: () => runStrategyReleaseCommand
36538
36513
  });
36539
- var import_promises36, import_node_fs6, import_node_readline3, import_node_path36, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main44;
36514
+ var import_promises37, import_node_fs6, import_node_readline3, import_node_path36, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main44;
36540
36515
  var init_strategyRelease2 = __esm({
36541
36516
  "src/scripts/strategyRelease.ts"() {
36542
36517
  "use strict";
36543
- import_promises36 = __toESM(require("fs/promises"));
36518
+ import_promises37 = __toESM(require("fs/promises"));
36544
36519
  import_node_fs6 = require("fs");
36545
36520
  import_node_readline3 = require("readline");
36546
36521
  import_node_path36 = __toESM(require("path"));
@@ -36557,14 +36532,14 @@ var init_strategyRelease2 = __esm({
36557
36532
  };
36558
36533
  writeJsonAtomic3 = async (filePath, value) => {
36559
36534
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
36560
- await import_promises36.default.mkdir(import_node_path36.default.dirname(filePath), { recursive: true });
36561
- await import_promises36.default.writeFile(
36535
+ await import_promises37.default.mkdir(import_node_path36.default.dirname(filePath), { recursive: true });
36536
+ await import_promises37.default.writeFile(
36562
36537
  temporaryPath,
36563
36538
  `${JSON.stringify(value, null, 2)}
36564
36539
  `,
36565
36540
  "utf8"
36566
36541
  );
36567
- await import_promises36.default.rename(temporaryPath, filePath);
36542
+ await import_promises37.default.rename(temporaryPath, filePath);
36568
36543
  };
36569
36544
  runStrategyReleaseCommand = async (options) => {
36570
36545
  const inputPath = import_node_path36.default.resolve(options.inputPath);
@@ -36616,7 +36591,7 @@ var init_strategyRelease2 = __esm({
36616
36591
  profile
36617
36592
  };
36618
36593
  }
36619
- const input = JSON.parse(await import_promises36.default.readFile(inputPath, "utf8"));
36594
+ const input = JSON.parse(await import_promises37.default.readFile(inputPath, "utf8"));
36620
36595
  if (options.command === "decide") {
36621
36596
  const decision = await deriveStrategyReleaseResearchDecision(input);
36622
36597
  if (options.outputPath) {
@@ -36649,7 +36624,7 @@ var init_strategyRelease2 = __esm({
36649
36624
  protectedPaths: [inputPath]
36650
36625
  });
36651
36626
  } else if (options.apply) {
36652
- await Promise.all(plan.delete.map((entry) => import_promises36.default.rm(entry.path)));
36627
+ await Promise.all(plan.delete.map((entry) => import_promises37.default.rm(entry.path)));
36653
36628
  }
36654
36629
  return {
36655
36630
  kind: "retention",
@@ -38553,12 +38528,12 @@ __export(runtimeParity_exports, {
38553
38528
  main: () => main46,
38554
38529
  runtimeParity: () => runtimeParity
38555
38530
  });
38556
- var import_config11, import_node_crypto18, import_args35, import_chalk52, import_constants19, import_time13, import_logger7, import_redis21, import_cli12, import_backtest7, import_connectors15, flags31, interval3, projectRoot16, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main46;
38531
+ var import_config11, import_node_crypto19, import_args35, import_chalk52, import_constants19, import_time13, import_logger7, import_redis21, import_cli12, import_backtest7, import_connectors15, flags31, interval3, projectRoot16, DEFAULT_LOOKBACK_DAYS, DETAIL_LIMIT2, DEFAULT_REPLAY_ENV, resolveParityConnectorName, createConnector, buildReplayAiAnalyses, formatReplayEnvSummary, buildReplayConfig, warmReplayHistory, runtimeParity, main46;
38557
38532
  var init_runtimeParity2 = __esm({
38558
38533
  "src/scripts/runtimeParity.ts"() {
38559
38534
  "use strict";
38560
38535
  import_config11 = require("dotenv/config");
38561
- import_node_crypto18 = require("crypto");
38536
+ import_node_crypto19 = require("crypto");
38562
38537
  import_args35 = __toESM(require("args"));
38563
38538
  import_chalk52 = __toESM(require("chalk"));
38564
38539
  import_constants19 = require("@tradejs/core/constants");
@@ -38941,9 +38916,9 @@ var init_runtimeParity2 = __esm({
38941
38916
  start: window.start,
38942
38917
  end: window.end
38943
38918
  },
38944
- name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto18.randomUUID)().slice(0, 8)}`,
38945
- testId: (0, import_node_crypto18.randomUUID)().slice(0, 8),
38946
- testSuiteId: (0, import_node_crypto18.randomUUID)().slice(0, 8),
38919
+ name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto19.randomUUID)().slice(0, 8)}`,
38920
+ testId: (0, import_node_crypto19.randomUUID)().slice(0, 8),
38921
+ testSuiteId: (0, import_node_crypto19.randomUUID)().slice(0, 8),
38947
38922
  strategyName: target.strategy,
38948
38923
  strategyConfig: replayConfig,
38949
38924
  connectorName,