@tradejs/cli 3.1.29-beta.277 → 3.1.29-beta.278
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 +288 -316
- package/dist/lib/mcpReplayProcess.js +44 -73
- package/dist/scripts/mcpWorker.js +66 -97
- package/package.json +7 -7
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, (
|
|
24466
|
-
wsServer.emit("connection",
|
|
24465
|
+
wsServer.handleUpgrade(request, socket, head, (client2) => {
|
|
24466
|
+
wsServer.emit("connection", client2, request);
|
|
24467
24467
|
});
|
|
24468
24468
|
});
|
|
24469
|
-
wsServer.on("connection", (
|
|
24470
|
-
subscriptions.set(
|
|
24471
|
-
alive.add(
|
|
24472
|
-
|
|
24473
|
-
|
|
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
|
-
|
|
24476
|
+
client2.send(JSON.stringify({ type: "error", error: "bad_command" }));
|
|
24477
24477
|
return;
|
|
24478
24478
|
}
|
|
24479
24479
|
subscriptions.set(
|
|
24480
|
-
|
|
24480
|
+
client2,
|
|
24481
24481
|
applySubscriptionCommand(
|
|
24482
|
-
subscriptions.get(
|
|
24482
|
+
subscriptions.get(client2) ?? /* @__PURE__ */ new Set(),
|
|
24483
24483
|
command
|
|
24484
24484
|
)
|
|
24485
24485
|
);
|
|
24486
|
-
|
|
24486
|
+
client2.send(
|
|
24487
24487
|
JSON.stringify({
|
|
24488
24488
|
type: "subscribed",
|
|
24489
|
-
topics: [...subscriptions.get(
|
|
24489
|
+
topics: [...subscriptions.get(client2) ?? []]
|
|
24490
24490
|
})
|
|
24491
24491
|
);
|
|
24492
24492
|
});
|
|
24493
|
-
|
|
24493
|
+
client2.on("close", () => subscriptions.delete(client2));
|
|
24494
24494
|
});
|
|
24495
24495
|
const heartbeat = setInterval(() => {
|
|
24496
|
-
for (const
|
|
24497
|
-
if (!alive.has(
|
|
24498
|
-
|
|
24499
|
-
subscriptions.delete(
|
|
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(
|
|
24503
|
-
|
|
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 [
|
|
24513
|
-
if (
|
|
24514
|
-
|
|
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
|
|
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,32 @@ 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
|
-
|
|
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
|
+
try { fs.writeFileSync(file + '.request', request, {flag:'wx'}); }
|
|
24595
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
|
|
24596
|
+
process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
|
|
24597
|
+
const timer = setInterval(() => {
|
|
24598
|
+
try {
|
|
24599
|
+
const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
|
|
24600
|
+
console.log(result.message);
|
|
24601
|
+
clearInterval(timer);
|
|
24602
|
+
process.exit(result.exitCode === 0 ? 0 : 1);
|
|
24603
|
+
} catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
24604
|
+
}, 1000);
|
|
24605
|
+
`;
|
|
24596
24606
|
buildMcpReplayProcess = async ({
|
|
24597
24607
|
evidencePath,
|
|
24598
24608
|
outDir,
|
|
@@ -24600,79 +24610,34 @@ var init_mcpReplayProcess = __esm({
|
|
|
24600
24610
|
projectRoot: projectRoot18,
|
|
24601
24611
|
env
|
|
24602
24612
|
}) => {
|
|
24603
|
-
if (!/^[a-
|
|
24604
|
-
throw new Error("Invalid replay
|
|
24613
|
+
if (!/^[a-f0-9]{64}$/.test(runId))
|
|
24614
|
+
throw new Error("Invalid replay request id");
|
|
24605
24615
|
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path14.default.dirname(evidencePath));
|
|
24606
24616
|
if (import_node_path14.default.resolve(evidencePath) !== import_node_path14.default.resolve(bundle.payloadPath))
|
|
24607
24617
|
throw new Error("Replay requires the verified bundle payload");
|
|
24608
|
-
const
|
|
24609
|
-
if (
|
|
24610
|
-
throw new Error(
|
|
24611
|
-
|
|
24612
|
-
|
|
24613
|
-
|
|
24614
|
-
|
|
24615
|
-
|
|
24616
|
-
|
|
24617
|
-
|
|
24618
|
-
|
|
24619
|
-
|
|
24620
|
-
|
|
24621
|
-
|
|
24622
|
-
|
|
24623
|
-
|
|
24624
|
-
"
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
|
|
24629
|
-
"
|
|
24630
|
-
|
|
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 };
|
|
24618
|
+
const relative = import_node_path14.default.relative(import_node_path14.default.join(projectRoot18, "data"), evidencePath);
|
|
24619
|
+
if (relative.startsWith("..") || import_node_path14.default.isAbsolute(relative))
|
|
24620
|
+
throw new Error("Evidence must be inside Project data");
|
|
24621
|
+
const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path14.default.join(projectRoot18, "data/mcp-replay-requests");
|
|
24622
|
+
const heartbeat = JSON.parse(
|
|
24623
|
+
await import_promises17.default.readFile(import_node_path14.default.join(root, "heartbeat.json"), "utf8")
|
|
24624
|
+
);
|
|
24625
|
+
if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
|
|
24626
|
+
throw new Error("Host replay runner heartbeat is stale");
|
|
24627
|
+
const bytes = await import_promises17.default.readFile(evidencePath);
|
|
24628
|
+
const request = JSON.stringify({
|
|
24629
|
+
schemaVersion: 1,
|
|
24630
|
+
id: runId,
|
|
24631
|
+
evidence: relative,
|
|
24632
|
+
artifactId: bundle.manifest.artifactId,
|
|
24633
|
+
deploymentId: bundle.manifest.deploymentId,
|
|
24634
|
+
payloadSha256: (0, import_node_crypto8.createHash)("sha256").update(bytes).digest("hex")
|
|
24635
|
+
});
|
|
24636
|
+
void outDir;
|
|
24637
|
+
return {
|
|
24638
|
+
executable: process.execPath,
|
|
24639
|
+
args: ["-e", client, root, runId, request]
|
|
24640
|
+
};
|
|
24676
24641
|
};
|
|
24677
24642
|
}
|
|
24678
24643
|
});
|
|
@@ -24682,13 +24647,13 @@ var mcpWorker_exports = {};
|
|
|
24682
24647
|
__export(mcpWorker_exports, {
|
|
24683
24648
|
main: () => main26
|
|
24684
24649
|
});
|
|
24685
|
-
var import_node_child_process4,
|
|
24650
|
+
var import_node_child_process4, import_node_crypto9, import_promises18, import_redis15, import_mcp, pause, leaseKey, LEASE_SECONDS, JOB_TIMEOUT_MS, main26;
|
|
24686
24651
|
var init_mcpWorker = __esm({
|
|
24687
24652
|
"src/scripts/mcpWorker.ts"() {
|
|
24688
24653
|
"use strict";
|
|
24689
24654
|
import_node_child_process4 = require("child_process");
|
|
24690
|
-
|
|
24691
|
-
|
|
24655
|
+
import_node_crypto9 = require("crypto");
|
|
24656
|
+
import_promises18 = require("fs/promises");
|
|
24692
24657
|
import_redis15 = require("@tradejs/infra/redis");
|
|
24693
24658
|
import_mcp = require("@tradejs/node/mcp");
|
|
24694
24659
|
init_mcpReplayProcess();
|
|
@@ -24697,7 +24662,7 @@ var init_mcpWorker = __esm({
|
|
|
24697
24662
|
LEASE_SECONDS = 15;
|
|
24698
24663
|
JOB_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
24699
24664
|
main26 = async (options = {}) => {
|
|
24700
|
-
const owner = (0,
|
|
24665
|
+
const owner = (0, import_node_crypto9.randomUUID)();
|
|
24701
24666
|
if (!await import_redis15.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
|
|
24702
24667
|
throw new Error("Another MCP worker owns this storage");
|
|
24703
24668
|
let stopping = false;
|
|
@@ -24705,6 +24670,18 @@ var init_mcpWorker = __esm({
|
|
|
24705
24670
|
let renewing = false;
|
|
24706
24671
|
let leaseLost = false;
|
|
24707
24672
|
let manifestHash = "";
|
|
24673
|
+
let replayReady = false;
|
|
24674
|
+
const updateReplayReady = async () => {
|
|
24675
|
+
try {
|
|
24676
|
+
const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
|
|
24677
|
+
const heartbeat2 = JSON.parse(
|
|
24678
|
+
await (0, import_promises18.readFile)(`${root}/heartbeat.json`, "utf8")
|
|
24679
|
+
);
|
|
24680
|
+
replayReady = Number.isFinite(heartbeat2.observedAt) && Date.now() - heartbeat2.observedAt >= 0 && Date.now() - heartbeat2.observedAt < 12e4;
|
|
24681
|
+
} catch {
|
|
24682
|
+
replayReady = false;
|
|
24683
|
+
}
|
|
24684
|
+
};
|
|
24708
24685
|
const signalChild = (signal) => {
|
|
24709
24686
|
if (!child?.pid) return;
|
|
24710
24687
|
try {
|
|
@@ -24718,9 +24695,7 @@ var init_mcpWorker = __esm({
|
|
|
24718
24695
|
const heartbeatValue = () => ({
|
|
24719
24696
|
observedAt: Date.now(),
|
|
24720
24697
|
packageManifestSha256: manifestHash,
|
|
24721
|
-
replayAvailable:
|
|
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
|
-
)
|
|
24698
|
+
replayAvailable: replayReady
|
|
24724
24699
|
});
|
|
24725
24700
|
const stop = () => {
|
|
24726
24701
|
stopping = true;
|
|
@@ -24736,6 +24711,7 @@ var init_mcpWorker = __esm({
|
|
|
24736
24711
|
try {
|
|
24737
24712
|
if (!await import_redis15.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
|
|
24738
24713
|
throw new Error("Worker lease lost");
|
|
24714
|
+
await updateReplayReady();
|
|
24739
24715
|
await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
24740
24716
|
} catch {
|
|
24741
24717
|
leaseLost = true;
|
|
@@ -24746,6 +24722,7 @@ var init_mcpWorker = __esm({
|
|
|
24746
24722
|
}, 2e3);
|
|
24747
24723
|
try {
|
|
24748
24724
|
manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
|
|
24725
|
+
await updateReplayReady();
|
|
24749
24726
|
await import_redis15.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
24750
24727
|
let cursor = "0";
|
|
24751
24728
|
do {
|
|
@@ -24810,7 +24787,7 @@ var init_mcpWorker = __esm({
|
|
|
24810
24787
|
);
|
|
24811
24788
|
continue;
|
|
24812
24789
|
}
|
|
24813
|
-
await (0,
|
|
24790
|
+
await (0, import_promises18.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
|
|
24814
24791
|
if (started.kind === "backtest")
|
|
24815
24792
|
await (0, import_redis15.setDataStrict)(
|
|
24816
24793
|
import_redis15.redisKeys.backtestConfig(
|
|
@@ -24833,7 +24810,9 @@ var init_mcpWorker = __esm({
|
|
|
24833
24810
|
};
|
|
24834
24811
|
if (started.kind === "runtime-feedback-replay") {
|
|
24835
24812
|
for (const name of Object.keys(jobEnv)) {
|
|
24836
|
-
if (/secret|token|api.?key|private.?key|cookie|credential/i.test(
|
|
24813
|
+
if (/secret|password|token|api.?key|private.?key|cookie|credential/i.test(
|
|
24814
|
+
name
|
|
24815
|
+
))
|
|
24837
24816
|
delete jobEnv[name];
|
|
24838
24817
|
}
|
|
24839
24818
|
Object.assign(jobEnv, {
|
|
@@ -24874,8 +24853,6 @@ var init_mcpWorker = __esm({
|
|
|
24874
24853
|
);
|
|
24875
24854
|
continue;
|
|
24876
24855
|
}
|
|
24877
|
-
if (started.kind === "runtime-feedback-replay" && process.env.PG_PASSWORD)
|
|
24878
|
-
jobEnv.PG_PASSWORD = process.env.PG_PASSWORD;
|
|
24879
24856
|
child = (0, import_node_child_process4.spawn)(command.executable, command.args, {
|
|
24880
24857
|
cwd: process.env.PROJECT_CWD || process.cwd(),
|
|
24881
24858
|
env: jobEnv,
|
|
@@ -24930,20 +24907,6 @@ var init_mcpWorker = __esm({
|
|
|
24930
24907
|
);
|
|
24931
24908
|
currentChild.once("exit", (code) => resolve({ code }));
|
|
24932
24909
|
});
|
|
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
24910
|
clearTimeout(timeout);
|
|
24948
24911
|
clearInterval(monitor);
|
|
24949
24912
|
child = void 0;
|
|
@@ -25335,13 +25298,13 @@ var hyperliquidWhalesUpdate_exports = {};
|
|
|
25335
25298
|
__export(hyperliquidWhalesUpdate_exports, {
|
|
25336
25299
|
main: () => main29
|
|
25337
25300
|
});
|
|
25338
|
-
var import_config8, import_args21,
|
|
25301
|
+
var import_config8, import_args21, import_node_crypto10, import_strategies12, LEADERBOARD_URL, DAY_MS10, CANDIDATE_LIMIT, flags19, fingerprint, runConcurrent2, main29;
|
|
25339
25302
|
var init_hyperliquidWhalesUpdate = __esm({
|
|
25340
25303
|
"src/scripts/hyperliquidWhalesUpdate.ts"() {
|
|
25341
25304
|
"use strict";
|
|
25342
25305
|
import_config8 = require("dotenv/config");
|
|
25343
25306
|
import_args21 = __toESM(require("args"));
|
|
25344
|
-
|
|
25307
|
+
import_node_crypto10 = require("crypto");
|
|
25345
25308
|
import_strategies12 = require("@tradejs/node/strategies");
|
|
25346
25309
|
init_hyperliquidWhaleBackfill();
|
|
25347
25310
|
init_hyperliquidRateLimiter();
|
|
@@ -25355,7 +25318,7 @@ var init_hyperliquidWhalesUpdate = __esm({
|
|
|
25355
25318
|
);
|
|
25356
25319
|
import_args21.default.option(["d", "days"], "Calibration window in days", 7);
|
|
25357
25320
|
flags19 = import_args21.default.parse(process.argv);
|
|
25358
|
-
fingerprint = (addresses) => (0,
|
|
25321
|
+
fingerprint = (addresses) => (0, import_node_crypto10.createHash)("sha256").update(JSON.stringify(addresses)).digest("hex").slice(0, 16);
|
|
25359
25322
|
runConcurrent2 = async (params) => {
|
|
25360
25323
|
let nextIndex = 0;
|
|
25361
25324
|
await Promise.all(
|
|
@@ -25464,13 +25427,13 @@ var mlExport_exports = {};
|
|
|
25464
25427
|
__export(mlExport_exports, {
|
|
25465
25428
|
main: () => main30
|
|
25466
25429
|
});
|
|
25467
|
-
var import_args22, import_chalk37,
|
|
25430
|
+
var import_args22, import_chalk37, import_promises19, import_path8, import_ml, flags20, resolveRunScopedMlChunks, main30;
|
|
25468
25431
|
var init_mlExport = __esm({
|
|
25469
25432
|
"src/scripts/mlExport.ts"() {
|
|
25470
25433
|
"use strict";
|
|
25471
25434
|
import_args22 = __toESM(require("args"));
|
|
25472
25435
|
import_chalk37 = __toESM(require("chalk"));
|
|
25473
|
-
|
|
25436
|
+
import_promises19 = __toESM(require("fs/promises"));
|
|
25474
25437
|
import_path8 = __toESM(require("path"));
|
|
25475
25438
|
import_ml = require("@tradejs/infra/ml");
|
|
25476
25439
|
init_checkpoint();
|
|
@@ -25521,7 +25484,7 @@ var init_mlExport = __esm({
|
|
|
25521
25484
|
};
|
|
25522
25485
|
main30 = async () => {
|
|
25523
25486
|
const outDir = String(flags20.outDir || "data/ml/export");
|
|
25524
|
-
await
|
|
25487
|
+
await import_promises19.default.mkdir(outDir, { recursive: true });
|
|
25525
25488
|
const strategyName = await resolveExportStrategy({
|
|
25526
25489
|
explicitStrategy: String(flags20.strategy || ""),
|
|
25527
25490
|
outDir,
|
|
@@ -25566,7 +25529,7 @@ var init_mlExport = __esm({
|
|
|
25566
25529
|
const shouldDeleteChunks = !Boolean(flags20.keepChunks);
|
|
25567
25530
|
if (shouldDeleteChunks) {
|
|
25568
25531
|
for (const filePath of chunkFiles) {
|
|
25569
|
-
await
|
|
25532
|
+
await import_promises19.default.rm(filePath, { force: true });
|
|
25570
25533
|
}
|
|
25571
25534
|
}
|
|
25572
25535
|
console.log(import_chalk37.default.green(`Merged dataset saved: ${mergedPath}`));
|
|
@@ -25587,13 +25550,13 @@ var mlInspect_exports = {};
|
|
|
25587
25550
|
__export(mlInspect_exports, {
|
|
25588
25551
|
main: () => main31
|
|
25589
25552
|
});
|
|
25590
|
-
var import_args23, import_chalk38,
|
|
25553
|
+
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
25554
|
var init_mlInspect = __esm({
|
|
25592
25555
|
"src/scripts/mlInspect.ts"() {
|
|
25593
25556
|
"use strict";
|
|
25594
25557
|
import_args23 = __toESM(require("args"));
|
|
25595
25558
|
import_chalk38 = __toESM(require("chalk"));
|
|
25596
|
-
|
|
25559
|
+
import_promises20 = __toESM(require("fs/promises"));
|
|
25597
25560
|
import_fs3 = require("fs");
|
|
25598
25561
|
import_path9 = __toESM(require("path"));
|
|
25599
25562
|
import_readline2 = __toESM(require("readline"));
|
|
@@ -25770,7 +25733,7 @@ var init_mlInspect = __esm({
|
|
|
25770
25733
|
};
|
|
25771
25734
|
findLatestDataset = async (params) => {
|
|
25772
25735
|
const { dir, strategy } = params;
|
|
25773
|
-
const entries = await
|
|
25736
|
+
const entries = await import_promises20.default.readdir(dir, { withFileTypes: true });
|
|
25774
25737
|
const strategyToken = strategy.trim().toLowerCase();
|
|
25775
25738
|
const files = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter((name) => name.endsWith(".jsonl")).filter(
|
|
25776
25739
|
(name) => !name.includes(".train.") && !name.includes(".test.")
|
|
@@ -25782,7 +25745,7 @@ var init_mlInspect = __esm({
|
|
|
25782
25745
|
}
|
|
25783
25746
|
const withMtime = await Promise.all(
|
|
25784
25747
|
files.map(async (name) => {
|
|
25785
|
-
const stat = await
|
|
25748
|
+
const stat = await import_promises20.default.stat(import_path9.default.join(dir, name));
|
|
25786
25749
|
return { name, mtime: stat.mtimeMs };
|
|
25787
25750
|
})
|
|
25788
25751
|
);
|
|
@@ -26027,7 +25990,7 @@ var init_mlInspect = __esm({
|
|
|
26027
25990
|
const relToData = import_path9.default.relative(dataRoot, absDatasetPath);
|
|
26028
25991
|
const inputInContainer = `/app/data/${relToData}`;
|
|
26029
25992
|
const reportDir = import_path9.default.dirname(absDatasetPath);
|
|
26030
|
-
await
|
|
25993
|
+
await import_promises20.default.mkdir(reportDir, { recursive: true });
|
|
26031
25994
|
const reportPath = import_path9.default.join(
|
|
26032
25995
|
reportDir,
|
|
26033
25996
|
`${import_path9.default.basename(datasetPath, import_path9.default.extname(datasetPath))}.profile.html`
|
|
@@ -26123,12 +26086,12 @@ var mlTrainLatestSelect_exports = {};
|
|
|
26123
26086
|
__export(mlTrainLatestSelect_exports, {
|
|
26124
26087
|
main: () => main32
|
|
26125
26088
|
});
|
|
26126
|
-
var import_path10,
|
|
26089
|
+
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
26090
|
var init_mlTrainLatestSelect = __esm({
|
|
26128
26091
|
"src/scripts/mlTrainLatestSelect.ts"() {
|
|
26129
26092
|
"use strict";
|
|
26130
26093
|
import_path10 = __toESM(require("path"));
|
|
26131
|
-
|
|
26094
|
+
import_promises21 = __toESM(require("fs/promises"));
|
|
26132
26095
|
import_fs4 = require("fs");
|
|
26133
26096
|
import_crypto2 = require("crypto");
|
|
26134
26097
|
import_child_process3 = require("child_process");
|
|
@@ -26257,7 +26220,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26257
26220
|
return defaultModel;
|
|
26258
26221
|
};
|
|
26259
26222
|
listDatasetFiles = async (dir, strategyName) => {
|
|
26260
|
-
const entries = await
|
|
26223
|
+
const entries = await import_promises21.default.readdir(dir, { withFileTypes: true });
|
|
26261
26224
|
const prefix = `ml-dataset-${toFileToken6(strategyName)}-`;
|
|
26262
26225
|
const legacyPrefix = "ml-dataset-";
|
|
26263
26226
|
const fileNames = entries.filter((entry) => entry.isFile()).map((entry) => entry.name);
|
|
@@ -26268,7 +26231,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26268
26231
|
).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
26232
|
const withMtime = await Promise.all(
|
|
26270
26233
|
jsonlFiles.map(async (name) => {
|
|
26271
|
-
const stat = await
|
|
26234
|
+
const stat = await import_promises21.default.stat(import_path10.default.join(dir, name));
|
|
26272
26235
|
return { name, mtime: stat.mtimeMs };
|
|
26273
26236
|
})
|
|
26274
26237
|
);
|
|
@@ -26444,13 +26407,13 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26444
26407
|
const metaPath = import_path10.default.join(dir, `${parsed.name}.windows.${key}.meta.json`);
|
|
26445
26408
|
try {
|
|
26446
26409
|
const [metaRaw] = await Promise.all([
|
|
26447
|
-
|
|
26448
|
-
|
|
26449
|
-
|
|
26450
|
-
|
|
26410
|
+
import_promises21.default.readFile(metaPath, "utf8"),
|
|
26411
|
+
import_promises21.default.access(holdoutTrainPath),
|
|
26412
|
+
import_promises21.default.access(holdoutTestPath),
|
|
26413
|
+
import_promises21.default.access(prodPath),
|
|
26451
26414
|
...walkForwardFoldDefs.flatMap((entry) => [
|
|
26452
|
-
|
|
26453
|
-
|
|
26415
|
+
import_promises21.default.access(entry.trainPath),
|
|
26416
|
+
import_promises21.default.access(entry.testPath)
|
|
26454
26417
|
])
|
|
26455
26418
|
]);
|
|
26456
26419
|
const meta2 = JSON.parse(metaRaw);
|
|
@@ -26817,7 +26780,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26817
26780
|
},
|
|
26818
26781
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26819
26782
|
};
|
|
26820
|
-
await
|
|
26783
|
+
await import_promises21.default.writeFile(metaPath, `${JSON.stringify(meta, null, 2)}
|
|
26821
26784
|
`, "utf8");
|
|
26822
26785
|
return {
|
|
26823
26786
|
holdoutTrainPath,
|
|
@@ -26875,7 +26838,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
26875
26838
|
process.exit(1);
|
|
26876
26839
|
}
|
|
26877
26840
|
try {
|
|
26878
|
-
const inputStat = await
|
|
26841
|
+
const inputStat = await import_promises21.default.stat(inputPath);
|
|
26879
26842
|
const totalInputBytes = inputStat.size;
|
|
26880
26843
|
const autoIncrementalThresholdGb = asInt7(
|
|
26881
26844
|
process.env.ML_TRAIN_INCREMENTAL_THRESHOLD_GB,
|
|
@@ -27064,7 +27027,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
27064
27027
|
const modelDir = import_path10.default.join(modelDirRoot, "models");
|
|
27065
27028
|
let savedModels = [];
|
|
27066
27029
|
try {
|
|
27067
|
-
const entries = await
|
|
27030
|
+
const entries = await import_promises21.default.readdir(modelDir, { withFileTypes: true });
|
|
27068
27031
|
savedModels = entries.filter((entry) => entry.isFile()).map((entry) => entry.name).filter(
|
|
27069
27032
|
(name) => name === `${selected}.joblib` || /^.+\.model\d+\.joblib$/.test(name)
|
|
27070
27033
|
).filter((name) => name.startsWith(`${selected}.`)).sort();
|
|
@@ -27086,7 +27049,7 @@ var init_mlTrainLatestSelect = __esm({
|
|
|
27086
27049
|
process.exitCode = finalCode;
|
|
27087
27050
|
} finally {
|
|
27088
27051
|
for (const file of cleanupFiles) {
|
|
27089
|
-
await
|
|
27052
|
+
await import_promises21.default.rm(file, { force: true });
|
|
27090
27053
|
}
|
|
27091
27054
|
}
|
|
27092
27055
|
process.exit(process.exitCode ?? 1);
|
|
@@ -27118,14 +27081,14 @@ __export(researchAuto_exports, {
|
|
|
27118
27081
|
toStrategyConfigGrid: () => toStrategyConfigGrid2,
|
|
27119
27082
|
trimTextTail: () => trimTextTail2
|
|
27120
27083
|
});
|
|
27121
|
-
var import_args25, import_chalk40, import_node_child_process5,
|
|
27084
|
+
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
27085
|
var init_researchAuto = __esm({
|
|
27123
27086
|
"src/scripts/researchAuto.ts"() {
|
|
27124
27087
|
"use strict";
|
|
27125
27088
|
import_args25 = __toESM(require("args"));
|
|
27126
27089
|
import_chalk40 = __toESM(require("chalk"));
|
|
27127
27090
|
import_node_child_process5 = require("child_process");
|
|
27128
|
-
|
|
27091
|
+
import_promises22 = __toESM(require("fs/promises"));
|
|
27129
27092
|
import_node_os2 = __toESM(require("os"));
|
|
27130
27093
|
import_node_path15 = __toESM(require("path"));
|
|
27131
27094
|
import_constants18 = require("@tradejs/core/constants");
|
|
@@ -27172,7 +27135,7 @@ var init_researchAuto = __esm({
|
|
|
27172
27135
|
);
|
|
27173
27136
|
readResearchAutoLock = async (lockPath) => {
|
|
27174
27137
|
try {
|
|
27175
|
-
const raw = await
|
|
27138
|
+
const raw = await import_promises22.default.readFile(lockPath, "utf8");
|
|
27176
27139
|
return JSON.parse(raw);
|
|
27177
27140
|
} catch {
|
|
27178
27141
|
return null;
|
|
@@ -27207,9 +27170,9 @@ var init_researchAuto = __esm({
|
|
|
27207
27170
|
startedAt,
|
|
27208
27171
|
argv: [...process.argv]
|
|
27209
27172
|
};
|
|
27210
|
-
await
|
|
27173
|
+
await import_promises22.default.mkdir(import_node_path15.default.dirname(lockPath), { recursive: true });
|
|
27211
27174
|
const writeLock = async () => {
|
|
27212
|
-
await
|
|
27175
|
+
await import_promises22.default.writeFile(lockPath, JSON.stringify(nextLock, null, 2), {
|
|
27213
27176
|
flag: "wx"
|
|
27214
27177
|
});
|
|
27215
27178
|
};
|
|
@@ -27228,7 +27191,7 @@ var init_researchAuto = __esm({
|
|
|
27228
27191
|
`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
27192
|
);
|
|
27230
27193
|
}
|
|
27231
|
-
await
|
|
27194
|
+
await import_promises22.default.unlink(lockPath).catch(() => void 0);
|
|
27232
27195
|
await writeLock();
|
|
27233
27196
|
return lockPath;
|
|
27234
27197
|
};
|
|
@@ -27240,7 +27203,7 @@ var init_researchAuto = __esm({
|
|
|
27240
27203
|
if (existingLock && existingLock.pid !== process.pid) {
|
|
27241
27204
|
return;
|
|
27242
27205
|
}
|
|
27243
|
-
await
|
|
27206
|
+
await import_promises22.default.unlink(lockPath).catch(() => void 0);
|
|
27244
27207
|
};
|
|
27245
27208
|
resolvePositiveInteger = (value, fallback) => {
|
|
27246
27209
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
@@ -27342,7 +27305,7 @@ var init_researchAuto = __esm({
|
|
|
27342
27305
|
};
|
|
27343
27306
|
listMergedFiles3 = async (outDir, strategyName) => {
|
|
27344
27307
|
try {
|
|
27345
|
-
const entries = await
|
|
27308
|
+
const entries = await import_promises22.default.readdir(outDir);
|
|
27346
27309
|
const prefix = `ai-dataset-${(0, import_ai8.toFileToken)(strategyName)}-merged-`;
|
|
27347
27310
|
return entries.filter((name) => name.startsWith(prefix) && name.endsWith(".jsonl")).sort().map((name) => import_node_path15.default.join(outDir, name));
|
|
27348
27311
|
} catch {
|
|
@@ -28010,13 +27973,13 @@ var init_types = __esm({
|
|
|
28010
27973
|
function assert(condition, message) {
|
|
28011
27974
|
if (!condition) throw new Error(`Invalid core research spec: ${message}`);
|
|
28012
27975
|
}
|
|
28013
|
-
var
|
|
27976
|
+
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
27977
|
var init_io = __esm({
|
|
28015
27978
|
"src/lib/coreResearch/io.ts"() {
|
|
28016
27979
|
"use strict";
|
|
28017
|
-
|
|
27980
|
+
import_node_crypto11 = require("crypto");
|
|
28018
27981
|
import_node_fs3 = require("fs");
|
|
28019
|
-
|
|
27982
|
+
import_promises23 = __toESM(require("fs/promises"));
|
|
28020
27983
|
import_backtest5 = require("@tradejs/core/backtest");
|
|
28021
27984
|
import_node_path16 = __toESM(require("path"));
|
|
28022
27985
|
init_types();
|
|
@@ -28034,10 +27997,10 @@ var init_io = __esm({
|
|
|
28034
27997
|
};
|
|
28035
27998
|
return JSON.stringify(normalize(value));
|
|
28036
27999
|
};
|
|
28037
|
-
sha256Text = (value) => (0,
|
|
28000
|
+
sha256Text = (value) => (0, import_node_crypto11.createHash)("sha256").update(value).digest("hex");
|
|
28038
28001
|
sha256Json = (value) => sha256Text(canonicalJson(value));
|
|
28039
28002
|
sha256File = async (filePath) => {
|
|
28040
|
-
const hash = (0,
|
|
28003
|
+
const hash = (0, import_node_crypto11.createHash)("sha256");
|
|
28041
28004
|
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
28042
28005
|
for await (const chunk of input) hash.update(chunk);
|
|
28043
28006
|
return hash.digest("hex");
|
|
@@ -28278,7 +28241,7 @@ var init_io = __esm({
|
|
|
28278
28241
|
};
|
|
28279
28242
|
loadCoreResearchSpec = async (specPath) => {
|
|
28280
28243
|
const resolvedPath = import_node_path16.default.resolve(specPath);
|
|
28281
|
-
const parsed = JSON.parse(await
|
|
28244
|
+
const parsed = JSON.parse(await import_promises23.default.readFile(resolvedPath, "utf8"));
|
|
28282
28245
|
const spec = validateCoreResearchSpec(parsed);
|
|
28283
28246
|
return { resolvedPath, spec, specSha256: sha256Json(spec) };
|
|
28284
28247
|
};
|
|
@@ -28300,17 +28263,17 @@ var init_io = __esm({
|
|
|
28300
28263
|
};
|
|
28301
28264
|
};
|
|
28302
28265
|
writeJsonAtomic = async (filePath, value) => {
|
|
28303
|
-
await
|
|
28266
|
+
await import_promises23.default.mkdir(import_node_path16.default.dirname(filePath), { recursive: true });
|
|
28304
28267
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
28305
|
-
await
|
|
28268
|
+
await import_promises23.default.writeFile(temporaryPath, `${canonicalJson(value)}
|
|
28306
28269
|
`, "utf8");
|
|
28307
|
-
await
|
|
28270
|
+
await import_promises23.default.rename(temporaryPath, filePath);
|
|
28308
28271
|
};
|
|
28309
28272
|
buildLedgerRecordHash = (record) => sha256Json(record);
|
|
28310
28273
|
readCoreResearchLedger = async (ledgerPath) => {
|
|
28311
28274
|
let text = "";
|
|
28312
28275
|
try {
|
|
28313
|
-
text = await
|
|
28276
|
+
text = await import_promises23.default.readFile(ledgerPath, "utf8");
|
|
28314
28277
|
} catch (error) {
|
|
28315
28278
|
if (error.code === "ENOENT") return [];
|
|
28316
28279
|
throw error;
|
|
@@ -28347,11 +28310,11 @@ var init_io = __esm({
|
|
|
28347
28310
|
};
|
|
28348
28311
|
appendCoreResearchLedger = async (params) => {
|
|
28349
28312
|
const { ledgerPath } = params;
|
|
28350
|
-
await
|
|
28313
|
+
await import_promises23.default.mkdir(import_node_path16.default.dirname(ledgerPath), { recursive: true });
|
|
28351
28314
|
const lockPath = `${ledgerPath}.lock`;
|
|
28352
28315
|
let lock = null;
|
|
28353
28316
|
try {
|
|
28354
|
-
lock = await
|
|
28317
|
+
lock = await import_promises23.default.open(lockPath, "wx");
|
|
28355
28318
|
const records = await readCoreResearchLedger(ledgerPath);
|
|
28356
28319
|
const verified = verifyCoreResearchLedger(records);
|
|
28357
28320
|
const payload = {
|
|
@@ -28370,7 +28333,7 @@ var init_io = __esm({
|
|
|
28370
28333
|
...payload,
|
|
28371
28334
|
recordHash: buildLedgerRecordHash(payload)
|
|
28372
28335
|
};
|
|
28373
|
-
await
|
|
28336
|
+
await import_promises23.default.appendFile(ledgerPath, `${canonicalJson(record)}
|
|
28374
28337
|
`, "utf8");
|
|
28375
28338
|
return record;
|
|
28376
28339
|
} catch (error) {
|
|
@@ -28380,7 +28343,7 @@ var init_io = __esm({
|
|
|
28380
28343
|
throw error;
|
|
28381
28344
|
} finally {
|
|
28382
28345
|
await lock?.close();
|
|
28383
|
-
await
|
|
28346
|
+
await import_promises23.default.rm(lockPath, { force: true });
|
|
28384
28347
|
}
|
|
28385
28348
|
};
|
|
28386
28349
|
validateCoreResearchParentLineage = async (spec) => {
|
|
@@ -28391,9 +28354,9 @@ var init_io = __esm({
|
|
|
28391
28354
|
for (const parentResearchId of spec.parentResearchIds ?? []) {
|
|
28392
28355
|
const parentDir = import_node_path16.default.join(rootDir, parentResearchId);
|
|
28393
28356
|
const [parentSpec, parentManifest, parentResult] = await Promise.all([
|
|
28394
|
-
|
|
28395
|
-
|
|
28396
|
-
|
|
28357
|
+
import_promises23.default.readFile(import_node_path16.default.join(parentDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28358
|
+
import_promises23.default.readFile(import_node_path16.default.join(parentDir, "manifest.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28359
|
+
import_promises23.default.readFile(import_node_path16.default.join(parentDir, "result.json"), "utf8").then((text) => JSON.parse(text))
|
|
28397
28360
|
]);
|
|
28398
28361
|
validateCoreResearchSpec(parentSpec);
|
|
28399
28362
|
if (parentManifest.status !== "completed") {
|
|
@@ -28440,12 +28403,12 @@ var init_io = __esm({
|
|
|
28440
28403
|
await validateCoreResearchParentLineage(spec);
|
|
28441
28404
|
const specSha256 = sha256Json(spec);
|
|
28442
28405
|
const paths = resolveCoreResearchPaths(spec);
|
|
28443
|
-
await
|
|
28406
|
+
await import_promises23.default.mkdir(paths.researchDir, { recursive: true });
|
|
28444
28407
|
let existing = null;
|
|
28445
28408
|
let existingManifest = null;
|
|
28446
28409
|
try {
|
|
28447
28410
|
existing = JSON.parse(
|
|
28448
|
-
await
|
|
28411
|
+
await import_promises23.default.readFile(paths.specPath, "utf8")
|
|
28449
28412
|
);
|
|
28450
28413
|
} catch (error) {
|
|
28451
28414
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -28458,7 +28421,7 @@ var init_io = __esm({
|
|
|
28458
28421
|
if (existing) {
|
|
28459
28422
|
try {
|
|
28460
28423
|
existingManifest = JSON.parse(
|
|
28461
|
-
await
|
|
28424
|
+
await import_promises23.default.readFile(paths.manifestPath, "utf8")
|
|
28462
28425
|
);
|
|
28463
28426
|
} catch (error) {
|
|
28464
28427
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -28497,7 +28460,7 @@ var init_io = __esm({
|
|
|
28497
28460
|
verifyCoreResearchArtifacts = async (spec) => {
|
|
28498
28461
|
const paths = resolveCoreResearchPaths(spec);
|
|
28499
28462
|
const manifest = JSON.parse(
|
|
28500
|
-
await
|
|
28463
|
+
await import_promises23.default.readFile(paths.manifestPath, "utf8")
|
|
28501
28464
|
);
|
|
28502
28465
|
if (manifest.specSha256 !== sha256Json(spec)) {
|
|
28503
28466
|
throw new Error("Manifest spec hash does not match the supplied spec");
|
|
@@ -28525,7 +28488,7 @@ var init_io = __esm({
|
|
|
28525
28488
|
const resolvedRoot = import_node_path16.default.resolve(rootDir);
|
|
28526
28489
|
let entries = [];
|
|
28527
28490
|
try {
|
|
28528
|
-
entries = await
|
|
28491
|
+
entries = await import_promises23.default.readdir(resolvedRoot);
|
|
28529
28492
|
} catch (error) {
|
|
28530
28493
|
if (error.code === "ENOENT") {
|
|
28531
28494
|
return {
|
|
@@ -28541,14 +28504,14 @@ var init_io = __esm({
|
|
|
28541
28504
|
(left, right) => left < right ? -1 : left > right ? 1 : 0
|
|
28542
28505
|
)) {
|
|
28543
28506
|
const researchDir = import_node_path16.default.join(resolvedRoot, entry);
|
|
28544
|
-
const stats = await
|
|
28507
|
+
const stats = await import_promises23.default.stat(researchDir);
|
|
28545
28508
|
if (!stats.isDirectory()) continue;
|
|
28546
28509
|
let spec;
|
|
28547
28510
|
let manifest;
|
|
28548
28511
|
try {
|
|
28549
28512
|
[spec, manifest] = await Promise.all([
|
|
28550
|
-
|
|
28551
|
-
|
|
28513
|
+
import_promises23.default.readFile(import_node_path16.default.join(researchDir, "spec.json"), "utf8").then((text) => JSON.parse(text)),
|
|
28514
|
+
import_promises23.default.readFile(import_node_path16.default.join(researchDir, "manifest.json"), "utf8").then((text) => JSON.parse(text))
|
|
28552
28515
|
]);
|
|
28553
28516
|
} catch (error) {
|
|
28554
28517
|
if (error.code === "ENOENT") continue;
|
|
@@ -28558,7 +28521,7 @@ var init_io = __esm({
|
|
|
28558
28521
|
if (manifest.specSha256 !== sha256Json(spec)) {
|
|
28559
28522
|
throw new Error(`Stage index found a spec hash mismatch for ${entry}`);
|
|
28560
28523
|
}
|
|
28561
|
-
const result = manifest.status === "completed" ? await
|
|
28524
|
+
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
28525
|
familyByResearch.set(spec.researchId, spec.hypothesis.family);
|
|
28563
28526
|
experiments.push({
|
|
28564
28527
|
researchId: spec.researchId,
|
|
@@ -28613,13 +28576,13 @@ var init_io = __esm({
|
|
|
28613
28576
|
});
|
|
28614
28577
|
|
|
28615
28578
|
// src/lib/coreResearch/artifacts.ts
|
|
28616
|
-
var import_node_fs4, import_node_events,
|
|
28579
|
+
var import_node_fs4, import_node_events, import_promises24, import_node_path17, csv, writeLine, closeOutput, writeCoreResearchMatches, writeCoreResearchTrades;
|
|
28617
28580
|
var init_artifacts = __esm({
|
|
28618
28581
|
"src/lib/coreResearch/artifacts.ts"() {
|
|
28619
28582
|
"use strict";
|
|
28620
28583
|
import_node_fs4 = require("fs");
|
|
28621
28584
|
import_node_events = require("events");
|
|
28622
|
-
|
|
28585
|
+
import_promises24 = __toESM(require("fs/promises"));
|
|
28623
28586
|
import_node_path17 = __toESM(require("path"));
|
|
28624
28587
|
init_io();
|
|
28625
28588
|
csv = (value) => {
|
|
@@ -28634,7 +28597,7 @@ var init_artifacts = __esm({
|
|
|
28634
28597
|
await (0, import_node_events.once)(output, "close");
|
|
28635
28598
|
};
|
|
28636
28599
|
writeCoreResearchMatches = async (params) => {
|
|
28637
|
-
await
|
|
28600
|
+
await import_promises24.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
|
|
28638
28601
|
const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
|
|
28639
28602
|
await writeLine(
|
|
28640
28603
|
output,
|
|
@@ -28685,7 +28648,7 @@ var init_artifacts = __esm({
|
|
|
28685
28648
|
await closeOutput(output);
|
|
28686
28649
|
};
|
|
28687
28650
|
writeCoreResearchTrades = async (params) => {
|
|
28688
|
-
await
|
|
28651
|
+
await import_promises24.default.mkdir(import_node_path17.default.dirname(params.filePath), { recursive: true });
|
|
28689
28652
|
const output = (0, import_node_fs4.createWriteStream)(params.filePath, { encoding: "utf8" });
|
|
28690
28653
|
for (const variant of params.variants) {
|
|
28691
28654
|
for (const trade of variant.trades) {
|
|
@@ -28925,14 +28888,14 @@ var init_rules = __esm({
|
|
|
28925
28888
|
});
|
|
28926
28889
|
|
|
28927
28890
|
// src/lib/coreResearch/statistics.ts
|
|
28928
|
-
var
|
|
28891
|
+
var import_node_crypto12, createSeededRandom, percentile, calendarClusterBootstrap, applyHolmCorrection, inverseNormalCdf, erf, normalCdf, deflatedSharpeDiagnostic, combinations, probabilityOfBacktestOverfitting;
|
|
28929
28892
|
var init_statistics = __esm({
|
|
28930
28893
|
"src/lib/coreResearch/statistics.ts"() {
|
|
28931
28894
|
"use strict";
|
|
28932
|
-
|
|
28895
|
+
import_node_crypto12 = require("crypto");
|
|
28933
28896
|
init_metrics();
|
|
28934
28897
|
createSeededRandom = (seedText) => {
|
|
28935
|
-
const digest = (0,
|
|
28898
|
+
const digest = (0, import_node_crypto12.createHash)("sha256").update(seedText).digest();
|
|
28936
28899
|
let state = digest.readUInt32LE(0) || 1;
|
|
28937
28900
|
return () => {
|
|
28938
28901
|
state ^= state << 13;
|
|
@@ -29399,11 +29362,11 @@ var init_comparison = __esm({
|
|
|
29399
29362
|
});
|
|
29400
29363
|
|
|
29401
29364
|
// src/lib/coreResearch/dataset.ts
|
|
29402
|
-
var
|
|
29365
|
+
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
29366
|
var init_dataset2 = __esm({
|
|
29404
29367
|
"src/lib/coreResearch/dataset.ts"() {
|
|
29405
29368
|
"use strict";
|
|
29406
|
-
|
|
29369
|
+
import_node_crypto13 = require("crypto");
|
|
29407
29370
|
import_node_fs5 = require("fs");
|
|
29408
29371
|
import_node_path18 = __toESM(require("path"));
|
|
29409
29372
|
import_node_readline2 = __toESM(require("readline"));
|
|
@@ -29618,7 +29581,7 @@ var init_dataset2 = __esm({
|
|
|
29618
29581
|
for (const inputPath of variant.files) {
|
|
29619
29582
|
const filePath = import_node_path18.default.resolve(inputPath);
|
|
29620
29583
|
const input = (0, import_node_fs5.createReadStream)(filePath);
|
|
29621
|
-
const hash = (0,
|
|
29584
|
+
const hash = (0, import_node_crypto13.createHash)("sha256");
|
|
29622
29585
|
input.on("data", (chunk) => hash.update(chunk));
|
|
29623
29586
|
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
29624
29587
|
const fileTrades = [];
|
|
@@ -30108,11 +30071,11 @@ var init_selection = __esm({
|
|
|
30108
30071
|
});
|
|
30109
30072
|
|
|
30110
30073
|
// src/lib/coreResearch/trace.ts
|
|
30111
|
-
var
|
|
30074
|
+
var import_promises25, import_node_path19, summarizeCoreResearchTrace;
|
|
30112
30075
|
var init_trace = __esm({
|
|
30113
30076
|
"src/lib/coreResearch/trace.ts"() {
|
|
30114
30077
|
"use strict";
|
|
30115
|
-
|
|
30078
|
+
import_promises25 = __toESM(require("fs/promises"));
|
|
30116
30079
|
import_node_path19 = __toESM(require("path"));
|
|
30117
30080
|
summarizeCoreResearchTrace = async (filePaths = []) => {
|
|
30118
30081
|
const events = /* @__PURE__ */ Object.create(null);
|
|
@@ -30120,7 +30083,7 @@ var init_trace = __esm({
|
|
|
30120
30083
|
const exitCodes = /* @__PURE__ */ Object.create(null);
|
|
30121
30084
|
for (const inputPath of filePaths) {
|
|
30122
30085
|
const filePath = import_node_path19.default.resolve(inputPath);
|
|
30123
|
-
const text = await
|
|
30086
|
+
const text = await import_promises25.default.readFile(filePath, "utf8");
|
|
30124
30087
|
for (const [index, line] of text.split("\n").entries()) {
|
|
30125
30088
|
if (!line.trim()) continue;
|
|
30126
30089
|
let event;
|
|
@@ -30160,14 +30123,14 @@ var init_trace = __esm({
|
|
|
30160
30123
|
});
|
|
30161
30124
|
|
|
30162
30125
|
// src/lib/coreResearch/orchestrator.ts
|
|
30163
|
-
var
|
|
30126
|
+
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
30127
|
var init_orchestrator = __esm({
|
|
30165
30128
|
"src/lib/coreResearch/orchestrator.ts"() {
|
|
30166
30129
|
"use strict";
|
|
30167
|
-
|
|
30130
|
+
import_promises26 = __toESM(require("fs/promises"));
|
|
30168
30131
|
import_node_path20 = __toESM(require("path"));
|
|
30169
30132
|
import_node_child_process6 = require("child_process");
|
|
30170
|
-
|
|
30133
|
+
import_node_crypto14 = require("crypto");
|
|
30171
30134
|
import_coreResearch = require("@tradejs/infra/coreResearch");
|
|
30172
30135
|
init_artifacts();
|
|
30173
30136
|
init_io();
|
|
@@ -30456,7 +30419,7 @@ var init_orchestrator = __esm({
|
|
|
30456
30419
|
const tradesByVariant = new Map(
|
|
30457
30420
|
windowed.map((entry) => [entry.variant.id, entry.trades])
|
|
30458
30421
|
);
|
|
30459
|
-
await
|
|
30422
|
+
await import_promises26.default.writeFile(
|
|
30460
30423
|
paths.reportPath,
|
|
30461
30424
|
buildCoreResearchHtml({ spec, result, tradesByVariant }),
|
|
30462
30425
|
"utf8"
|
|
@@ -30476,7 +30439,7 @@ var init_orchestrator = __esm({
|
|
|
30476
30439
|
if (error.code !== "ENOENT") throw error;
|
|
30477
30440
|
}
|
|
30478
30441
|
try {
|
|
30479
|
-
for (const name of await
|
|
30442
|
+
for (const name of await import_promises26.default.readdir(paths.runLogDir)) {
|
|
30480
30443
|
if (!name.endsWith(".log")) continue;
|
|
30481
30444
|
artifactHashes[`runs/${name}`] = await sha256File(
|
|
30482
30445
|
import_node_path20.default.join(paths.runLogDir, name)
|
|
@@ -30569,7 +30532,7 @@ var init_orchestrator = __esm({
|
|
|
30569
30532
|
gitSha,
|
|
30570
30533
|
...sourceRepository ? { sourceRepository } : {},
|
|
30571
30534
|
...dirtyDiff ? {
|
|
30572
|
-
dirtyDiffSha256: (0,
|
|
30535
|
+
dirtyDiffSha256: (0, import_node_crypto14.createHash)("sha256").update(dirtyDiff).digest("hex")
|
|
30573
30536
|
} : {}
|
|
30574
30537
|
};
|
|
30575
30538
|
} catch {
|
|
@@ -30676,7 +30639,7 @@ var init_orchestrator = __esm({
|
|
|
30676
30639
|
};
|
|
30677
30640
|
runCommand2 = async (params) => {
|
|
30678
30641
|
if (!params.command.length) throw new Error("Cannot run an empty command");
|
|
30679
|
-
await
|
|
30642
|
+
await import_promises26.default.mkdir(import_node_path20.default.dirname(params.logPath), { recursive: true });
|
|
30680
30643
|
const chunks = [];
|
|
30681
30644
|
const child = (0, import_node_child_process6.spawn)(params.command[0], params.command.slice(1), {
|
|
30682
30645
|
cwd: params.cwd,
|
|
@@ -30696,7 +30659,7 @@ var init_orchestrator = __esm({
|
|
|
30696
30659
|
child.once("close", (code) => resolve(code ?? 1));
|
|
30697
30660
|
});
|
|
30698
30661
|
const output = chunks.join("");
|
|
30699
|
-
await
|
|
30662
|
+
await import_promises26.default.writeFile(params.logPath, output, "utf8");
|
|
30700
30663
|
if (exitCode !== 0) {
|
|
30701
30664
|
throw new Error(
|
|
30702
30665
|
`Command failed with exit ${exitCode}: ${params.command.join(" ")}`
|
|
@@ -30901,11 +30864,11 @@ var coreResearch_exports = {};
|
|
|
30901
30864
|
__export(coreResearch_exports, {
|
|
30902
30865
|
main: () => main34
|
|
30903
30866
|
});
|
|
30904
|
-
var
|
|
30867
|
+
var import_promises27, import_node_path21, import_chalk41, valueAfter, required, parseTimestamp, readSymbols, printUsage, main34;
|
|
30905
30868
|
var init_coreResearch = __esm({
|
|
30906
30869
|
"src/scripts/coreResearch.ts"() {
|
|
30907
30870
|
"use strict";
|
|
30908
|
-
|
|
30871
|
+
import_promises27 = __toESM(require("fs/promises"));
|
|
30909
30872
|
import_node_path21 = __toESM(require("path"));
|
|
30910
30873
|
import_chalk41 = __toESM(require("chalk"));
|
|
30911
30874
|
init_io();
|
|
@@ -30930,7 +30893,7 @@ var init_coreResearch = __esm({
|
|
|
30930
30893
|
const symbolsFile = valueAfter(argv2, "--symbolsFile");
|
|
30931
30894
|
if (symbolsFile) {
|
|
30932
30895
|
const parsed = JSON.parse(
|
|
30933
|
-
await
|
|
30896
|
+
await import_promises27.default.readFile(import_node_path21.default.resolve(projectRoot18, symbolsFile), "utf8")
|
|
30934
30897
|
);
|
|
30935
30898
|
if (!Array.isArray(parsed) || parsed.some((symbol) => typeof symbol !== "string")) {
|
|
30936
30899
|
throw new Error("--symbolsFile must contain a JSON string array");
|
|
@@ -31655,11 +31618,11 @@ __export(replayRuntimeEvidence_exports, {
|
|
|
31655
31618
|
replayRuntimeEvidence: () => replayRuntimeEvidence,
|
|
31656
31619
|
summarizeReplayComparison: () => summarizeReplayComparison
|
|
31657
31620
|
});
|
|
31658
|
-
var
|
|
31621
|
+
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
31622
|
var init_replayRuntimeEvidence = __esm({
|
|
31660
31623
|
"src/scripts/replayRuntimeEvidence.ts"() {
|
|
31661
31624
|
"use strict";
|
|
31662
|
-
|
|
31625
|
+
import_promises28 = __toESM(require("fs/promises"));
|
|
31663
31626
|
import_node_path22 = __toESM(require("path"));
|
|
31664
31627
|
import_args27 = __toESM(require("args"));
|
|
31665
31628
|
import_chalk43 = __toESM(require("chalk"));
|
|
@@ -31922,7 +31885,7 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
31922
31885
|
const runtimeEvidencePath = typeof runtimeEvidenceFile === "string" && runtimeEvidenceFile.trim() ? import_node_path22.default.resolve(projectRoot18, runtimeEvidenceFile.trim()) : null;
|
|
31923
31886
|
if (runtimeEvidencePath) {
|
|
31924
31887
|
const artifact = JSON.parse(
|
|
31925
|
-
await
|
|
31888
|
+
await import_promises28.default.readFile(runtimeEvidencePath, "utf8")
|
|
31926
31889
|
);
|
|
31927
31890
|
return {
|
|
31928
31891
|
source: "file",
|
|
@@ -32009,8 +31972,8 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
32009
31972
|
runtime: runtime.payload
|
|
32010
31973
|
};
|
|
32011
31974
|
const outPath = import_node_path22.default.resolve(projectRoot18, String(flags35.out));
|
|
32012
|
-
await
|
|
32013
|
-
await
|
|
31975
|
+
await import_promises28.default.mkdir(import_node_path22.default.dirname(outPath), { recursive: true });
|
|
31976
|
+
await import_promises28.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
32014
31977
|
`, "utf8");
|
|
32015
31978
|
console.log(import_chalk43.default.green(`Wrote ${outPath}`));
|
|
32016
31979
|
console.log(
|
|
@@ -32032,6 +31995,15 @@ var init_replayRuntimeEvidence = __esm({
|
|
|
32032
31995
|
}
|
|
32033
31996
|
});
|
|
32034
31997
|
|
|
31998
|
+
// src/lib/runtimeEvidenceProducer.ts
|
|
31999
|
+
var runtimeEvidenceProducer_exports = {};
|
|
32000
|
+
var init_runtimeEvidenceProducer = __esm({
|
|
32001
|
+
"src/lib/runtimeEvidenceProducer.ts"() {
|
|
32002
|
+
"use strict";
|
|
32003
|
+
__reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
|
|
32004
|
+
}
|
|
32005
|
+
});
|
|
32006
|
+
|
|
32035
32007
|
// src/lib/runtimeFeedbackArtifacts.ts
|
|
32036
32008
|
var runtimeFeedbackArtifacts_exports = {};
|
|
32037
32009
|
var init_runtimeFeedbackArtifacts = __esm({
|
|
@@ -32042,12 +32014,12 @@ var init_runtimeFeedbackArtifacts = __esm({
|
|
|
32042
32014
|
});
|
|
32043
32015
|
|
|
32044
32016
|
// src/lib/runtimeFeedbackReplay.ts
|
|
32045
|
-
var import_node_child_process7,
|
|
32017
|
+
var import_node_child_process7, import_promises29, import_node_path23, REQUIRED_ENV, FORBIDDEN_SECRET_ENV, unsafeRedisHosts, safeSegment, assertRuntimeFeedbackReplaySafety, buildRuntimeFeedbackReplayCommands, runLoggedCommand, runRuntimeFeedbackReplay;
|
|
32046
32018
|
var init_runtimeFeedbackReplay = __esm({
|
|
32047
32019
|
"src/lib/runtimeFeedbackReplay.ts"() {
|
|
32048
32020
|
"use strict";
|
|
32049
32021
|
import_node_child_process7 = require("child_process");
|
|
32050
|
-
|
|
32022
|
+
import_promises29 = __toESM(require("fs/promises"));
|
|
32051
32023
|
import_node_path23 = __toESM(require("path"));
|
|
32052
32024
|
init_runtimeEvidenceDeployment();
|
|
32053
32025
|
init_runtimeEvidenceArtifacts();
|
|
@@ -32264,15 +32236,15 @@ $ ${[executable, ...command].join(" ")}
|
|
|
32264
32236
|
if (!intervals.size) {
|
|
32265
32237
|
throw new Error("Runtime feedback replay requires an active interval");
|
|
32266
32238
|
}
|
|
32267
|
-
await
|
|
32268
|
-
const existing = await
|
|
32239
|
+
await import_promises29.default.mkdir(outDir, { recursive: true });
|
|
32240
|
+
const existing = await import_promises29.default.readdir(outDir);
|
|
32269
32241
|
if (existing.length) {
|
|
32270
32242
|
throw new Error(
|
|
32271
32243
|
`Runtime feedback output directory must be empty: ${outDir}`
|
|
32272
32244
|
);
|
|
32273
32245
|
}
|
|
32274
32246
|
const replayEvidencePath = import_node_path23.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_REPLAY_FILE);
|
|
32275
|
-
const logHandle = await
|
|
32247
|
+
const logHandle = await import_promises29.default.open(
|
|
32276
32248
|
import_node_path23.default.join(outDir, runtimeFeedbackArtifacts_exports.RUNTIME_FEEDBACK_LOG_FILE),
|
|
32277
32249
|
"wx"
|
|
32278
32250
|
);
|
|
@@ -32530,12 +32502,12 @@ var init_runtimeFeedbackNotify = __esm({
|
|
|
32530
32502
|
});
|
|
32531
32503
|
|
|
32532
32504
|
// src/lib/runtimeEvidenceSync.ts
|
|
32533
|
-
var import_node_child_process8,
|
|
32505
|
+
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
32506
|
var init_runtimeEvidenceSync = __esm({
|
|
32535
32507
|
"src/lib/runtimeEvidenceSync.ts"() {
|
|
32536
32508
|
"use strict";
|
|
32537
32509
|
import_node_child_process8 = require("child_process");
|
|
32538
|
-
|
|
32510
|
+
import_promises30 = __toESM(require("fs/promises"));
|
|
32539
32511
|
import_node_path26 = __toESM(require("path"));
|
|
32540
32512
|
import_node_util = require("util");
|
|
32541
32513
|
init_runtimeEvidenceArtifacts();
|
|
@@ -32586,7 +32558,7 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32586
32558
|
if (verified.manifest.deploymentId !== safeDeploymentId) continue;
|
|
32587
32559
|
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
|
|
32588
32560
|
try {
|
|
32589
|
-
await
|
|
32561
|
+
await import_promises30.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
|
|
32590
32562
|
continue;
|
|
32591
32563
|
} catch (error) {
|
|
32592
32564
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -32623,14 +32595,14 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32623
32595
|
replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
|
|
32624
32596
|
} : {}
|
|
32625
32597
|
};
|
|
32626
|
-
await
|
|
32627
|
-
await
|
|
32598
|
+
await import_promises30.default.mkdir(receiptsRoot, { recursive: true });
|
|
32599
|
+
await import_promises30.default.writeFile(
|
|
32628
32600
|
temporaryPath,
|
|
32629
32601
|
`${JSON.stringify(receipt, null, 2)}
|
|
32630
32602
|
`,
|
|
32631
32603
|
"utf8"
|
|
32632
32604
|
);
|
|
32633
|
-
await
|
|
32605
|
+
await import_promises30.default.rename(temporaryPath, finalPath);
|
|
32634
32606
|
return finalPath;
|
|
32635
32607
|
};
|
|
32636
32608
|
syncRuntimeEvidenceBundles = async ({
|
|
@@ -32648,8 +32620,8 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32648
32620
|
const inboxRoot = import_node_path26.default.join(evidenceRoot, "inbox", safeDeploymentId);
|
|
32649
32621
|
const artifactsRoot = import_node_path26.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
32650
32622
|
await Promise.all([
|
|
32651
|
-
|
|
32652
|
-
|
|
32623
|
+
import_promises30.default.mkdir(inboxRoot, { recursive: true }),
|
|
32624
|
+
import_promises30.default.mkdir(artifactsRoot, { recursive: true })
|
|
32653
32625
|
]);
|
|
32654
32626
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
32655
32627
|
source,
|
|
@@ -32671,9 +32643,9 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32671
32643
|
...dateParts(verified.manifest.window.endTime),
|
|
32672
32644
|
safeSegment2(verified.manifest.artifactId, "artifact")
|
|
32673
32645
|
);
|
|
32674
|
-
await
|
|
32646
|
+
await import_promises30.default.mkdir(import_node_path26.default.dirname(destinationDir), { recursive: true });
|
|
32675
32647
|
try {
|
|
32676
|
-
await
|
|
32648
|
+
await import_promises30.default.rename(bundleDir, destinationDir);
|
|
32677
32649
|
} catch (error) {
|
|
32678
32650
|
if (!isExistingDestinationError(error)) throw error;
|
|
32679
32651
|
const existing = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir);
|
|
@@ -32682,7 +32654,7 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32682
32654
|
`Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
|
|
32683
32655
|
);
|
|
32684
32656
|
}
|
|
32685
|
-
await
|
|
32657
|
+
await import_promises30.default.rm(bundleDir, { recursive: true, force: true });
|
|
32686
32658
|
}
|
|
32687
32659
|
received.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir));
|
|
32688
32660
|
}
|
|
@@ -32702,12 +32674,12 @@ var init_runtimeEvidenceSync = __esm({
|
|
|
32702
32674
|
});
|
|
32703
32675
|
|
|
32704
32676
|
// src/lib/runtimeFeedbackSync.ts
|
|
32705
|
-
var import_node_child_process9,
|
|
32677
|
+
var import_node_child_process9, import_promises31, import_node_path27, import_node_util2, execFileAsync2, isExistingDestinationError2, safeSegment3, dateParts2, syncRuntimeFeedbackReplayBundles;
|
|
32706
32678
|
var init_runtimeFeedbackSync = __esm({
|
|
32707
32679
|
"src/lib/runtimeFeedbackSync.ts"() {
|
|
32708
32680
|
"use strict";
|
|
32709
32681
|
import_node_child_process9 = require("child_process");
|
|
32710
|
-
|
|
32682
|
+
import_promises31 = __toESM(require("fs/promises"));
|
|
32711
32683
|
import_node_path27 = __toESM(require("path"));
|
|
32712
32684
|
import_node_util2 = require("util");
|
|
32713
32685
|
init_runtimeFeedbackArtifacts();
|
|
@@ -32744,8 +32716,8 @@ var init_runtimeFeedbackSync = __esm({
|
|
|
32744
32716
|
const inboxRoot = import_node_path27.default.join(feedbackRoot, "inbox", safeDeploymentId);
|
|
32745
32717
|
const artifactsRoot = import_node_path27.default.join(feedbackRoot, "artifacts", safeDeploymentId);
|
|
32746
32718
|
await Promise.all([
|
|
32747
|
-
|
|
32748
|
-
|
|
32719
|
+
import_promises31.default.mkdir(inboxRoot, { recursive: true }),
|
|
32720
|
+
import_promises31.default.mkdir(artifactsRoot, { recursive: true })
|
|
32749
32721
|
]);
|
|
32750
32722
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
32751
32723
|
source,
|
|
@@ -32767,9 +32739,9 @@ var init_runtimeFeedbackSync = __esm({
|
|
|
32767
32739
|
safeSegment3(verified.manifest.runtimeEvidence.artifactId, "artifact"),
|
|
32768
32740
|
safeSegment3(verified.manifest.runId, "run")
|
|
32769
32741
|
);
|
|
32770
|
-
await
|
|
32742
|
+
await import_promises31.default.mkdir(import_node_path27.default.dirname(destinationDir), { recursive: true });
|
|
32771
32743
|
try {
|
|
32772
|
-
await
|
|
32744
|
+
await import_promises31.default.rename(bundleDir, destinationDir);
|
|
32773
32745
|
} catch (error) {
|
|
32774
32746
|
if (!isExistingDestinationError2(error)) throw error;
|
|
32775
32747
|
const existing = await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir);
|
|
@@ -32778,7 +32750,7 @@ var init_runtimeFeedbackSync = __esm({
|
|
|
32778
32750
|
`Conflicting runtime feedback replay ${verified.manifest.artifactId}`
|
|
32779
32751
|
);
|
|
32780
32752
|
}
|
|
32781
|
-
await
|
|
32753
|
+
await import_promises31.default.rm(bundleDir, { recursive: true, force: true });
|
|
32782
32754
|
}
|
|
32783
32755
|
received.push(await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplayBundle)(destinationDir));
|
|
32784
32756
|
}
|
|
@@ -32862,12 +32834,12 @@ var init_runtimeFeedbackSync2 = __esm({
|
|
|
32862
32834
|
});
|
|
32863
32835
|
|
|
32864
32836
|
// src/lib/runtimeEvidenceCompositionSnapshots.ts
|
|
32865
|
-
var
|
|
32837
|
+
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
32838
|
var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
32867
32839
|
"src/lib/runtimeEvidenceCompositionSnapshots.ts"() {
|
|
32868
32840
|
"use strict";
|
|
32869
|
-
|
|
32870
|
-
|
|
32841
|
+
import_node_crypto15 = require("crypto");
|
|
32842
|
+
import_promises32 = __toESM(require("fs/promises"));
|
|
32871
32843
|
import_node_path29 = __toESM(require("path"));
|
|
32872
32844
|
init_runtimeEvidenceDeployment();
|
|
32873
32845
|
init_runtimeEvidenceProducer();
|
|
@@ -32889,7 +32861,7 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
32889
32861
|
};
|
|
32890
32862
|
};
|
|
32891
32863
|
isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
32892
|
-
sha256 = (value) => (0,
|
|
32864
|
+
sha256 = (value) => (0, import_node_crypto15.createHash)("sha256").update(value).digest("hex");
|
|
32893
32865
|
safeSegment4 = (value, label) => {
|
|
32894
32866
|
const normalized = value.trim();
|
|
32895
32867
|
if (!normalized || !/^[a-zA-Z0-9._:-]+$/.test(normalized)) {
|
|
@@ -32911,9 +32883,9 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
32911
32883
|
};
|
|
32912
32884
|
verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
|
|
32913
32885
|
const [manifestText, payload, completeText] = await Promise.all([
|
|
32914
|
-
|
|
32915
|
-
|
|
32916
|
-
|
|
32886
|
+
import_promises32.default.readFile(import_node_path29.default.join(bundleDir, MANIFEST_FILE), "utf8"),
|
|
32887
|
+
import_promises32.default.readFile(import_node_path29.default.join(bundleDir, SNAPSHOT_FILE)),
|
|
32888
|
+
import_promises32.default.readFile(import_node_path29.default.join(bundleDir, COMPLETE_FILE), "utf8")
|
|
32917
32889
|
]);
|
|
32918
32890
|
const manifest = parseManifest(JSON.parse(manifestText));
|
|
32919
32891
|
if (completeText.trim() !== manifest.deploymentCompositionId) {
|
|
@@ -32981,34 +32953,34 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
32981
32953
|
const temporaryDir = import_node_path29.default.join(
|
|
32982
32954
|
evidenceRoot,
|
|
32983
32955
|
"incoming",
|
|
32984
|
-
`snapshot-${compositionId}.tmp-${(0,
|
|
32956
|
+
`snapshot-${compositionId}.tmp-${(0, import_node_crypto15.randomUUID)()}`
|
|
32985
32957
|
);
|
|
32986
|
-
await
|
|
32958
|
+
await import_promises32.default.mkdir(temporaryDir, { recursive: true });
|
|
32987
32959
|
try {
|
|
32988
32960
|
await Promise.all([
|
|
32989
|
-
|
|
32990
|
-
|
|
32961
|
+
import_promises32.default.writeFile(import_node_path29.default.join(temporaryDir, SNAPSHOT_FILE), payload, "utf8"),
|
|
32962
|
+
import_promises32.default.writeFile(
|
|
32991
32963
|
import_node_path29.default.join(temporaryDir, MANIFEST_FILE),
|
|
32992
32964
|
`${JSON.stringify(manifest, null, 2)}
|
|
32993
32965
|
`,
|
|
32994
32966
|
"utf8"
|
|
32995
32967
|
)
|
|
32996
32968
|
]);
|
|
32997
|
-
await
|
|
32969
|
+
await import_promises32.default.writeFile(
|
|
32998
32970
|
import_node_path29.default.join(temporaryDir, COMPLETE_FILE),
|
|
32999
32971
|
`${compositionId}
|
|
33000
32972
|
`,
|
|
33001
32973
|
"utf8"
|
|
33002
32974
|
);
|
|
33003
|
-
await
|
|
32975
|
+
await import_promises32.default.mkdir(snapshotsRoot, { recursive: true });
|
|
33004
32976
|
try {
|
|
33005
|
-
await
|
|
32977
|
+
await import_promises32.default.rename(temporaryDir, bundleDir);
|
|
33006
32978
|
} catch (error) {
|
|
33007
32979
|
if (!isExistingDestinationError3(error)) throw error;
|
|
33008
|
-
await
|
|
32980
|
+
await import_promises32.default.rm(temporaryDir, { recursive: true, force: true });
|
|
33009
32981
|
}
|
|
33010
32982
|
} catch (error) {
|
|
33011
|
-
await
|
|
32983
|
+
await import_promises32.default.rm(temporaryDir, { recursive: true, force: true });
|
|
33012
32984
|
throw error;
|
|
33013
32985
|
}
|
|
33014
32986
|
const verified = await verifyRuntimeEvidenceCompositionSnapshot(bundleDir);
|
|
@@ -33053,14 +33025,14 @@ var init_runtimeEvidenceCompositionSnapshots = __esm({
|
|
|
33053
33025
|
const bundleDirs = [];
|
|
33054
33026
|
let deployments;
|
|
33055
33027
|
try {
|
|
33056
|
-
deployments = await
|
|
33028
|
+
deployments = await import_promises32.default.readdir(rootDir, { withFileTypes: true });
|
|
33057
33029
|
} catch (error) {
|
|
33058
33030
|
if (error.code === "ENOENT") return [];
|
|
33059
33031
|
throw error;
|
|
33060
33032
|
}
|
|
33061
33033
|
for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
|
|
33062
33034
|
const deploymentDir = import_node_path29.default.join(rootDir, deployment.name);
|
|
33063
|
-
const compositions = await
|
|
33035
|
+
const compositions = await import_promises32.default.readdir(deploymentDir, {
|
|
33064
33036
|
withFileTypes: true
|
|
33065
33037
|
});
|
|
33066
33038
|
bundleDirs.push(
|
|
@@ -33245,11 +33217,11 @@ __export(runtimeEvidence_exports, {
|
|
|
33245
33217
|
main: () => main40,
|
|
33246
33218
|
runtimeEvidence: () => runtimeEvidence
|
|
33247
33219
|
});
|
|
33248
|
-
var
|
|
33220
|
+
var import_promises33, import_node_path30, import_args31, import_chalk47, flags28, projectRoot12, toEpochMs3, resolveWindow2, parseStrategyFilter2, runtimeEvidence, main40;
|
|
33249
33221
|
var init_runtimeEvidence = __esm({
|
|
33250
33222
|
"src/scripts/runtimeEvidence.ts"() {
|
|
33251
33223
|
"use strict";
|
|
33252
|
-
|
|
33224
|
+
import_promises33 = __toESM(require("fs/promises"));
|
|
33253
33225
|
import_node_path30 = __toESM(require("path"));
|
|
33254
33226
|
import_args31 = __toESM(require("args"));
|
|
33255
33227
|
import_chalk47 = __toESM(require("chalk"));
|
|
@@ -33432,8 +33404,8 @@ var init_runtimeEvidence = __esm({
|
|
|
33432
33404
|
}
|
|
33433
33405
|
const artifact = current.artifact;
|
|
33434
33406
|
const outPath = import_node_path30.default.resolve(projectRoot12, String(flags28.out));
|
|
33435
|
-
await
|
|
33436
|
-
await
|
|
33407
|
+
await import_promises33.default.mkdir(import_node_path30.default.dirname(outPath), { recursive: true });
|
|
33408
|
+
await import_promises33.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
33437
33409
|
`, "utf8");
|
|
33438
33410
|
const published = publishDir ? await Promise.all(
|
|
33439
33411
|
artifacts.map(
|
|
@@ -34620,7 +34592,7 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
34620
34592
|
let artifact;
|
|
34621
34593
|
try {
|
|
34622
34594
|
const parsed = JSON.parse(
|
|
34623
|
-
await
|
|
34595
|
+
await import_promises34.default.readFile(reference.path, "utf8")
|
|
34624
34596
|
);
|
|
34625
34597
|
assert3(
|
|
34626
34598
|
parsed != null && typeof parsed === "object" && !Array.isArray(parsed),
|
|
@@ -34767,12 +34739,12 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
34767
34739
|
})
|
|
34768
34740
|
);
|
|
34769
34741
|
}
|
|
34770
|
-
var
|
|
34742
|
+
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
34743
|
var init_strategyRelease = __esm({
|
|
34772
34744
|
"src/lib/strategyRelease.ts"() {
|
|
34773
34745
|
"use strict";
|
|
34774
|
-
|
|
34775
|
-
|
|
34746
|
+
import_node_crypto16 = require("crypto");
|
|
34747
|
+
import_promises34 = __toESM(require("fs/promises"));
|
|
34776
34748
|
import_node_path32 = __toESM(require("path"));
|
|
34777
34749
|
import_types9 = require("@tradejs/types");
|
|
34778
34750
|
import_strategyReleaseEvidence2 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
@@ -34796,7 +34768,7 @@ var init_strategyRelease = __esm({
|
|
|
34796
34768
|
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
34797
34769
|
return false;
|
|
34798
34770
|
}
|
|
34799
|
-
const report = JSON.parse(await
|
|
34771
|
+
const report = JSON.parse(await import_promises34.default.readFile(artifactPath, "utf8"));
|
|
34800
34772
|
return Boolean(
|
|
34801
34773
|
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
34774
|
);
|
|
@@ -34811,7 +34783,7 @@ var init_strategyRelease = __esm({
|
|
|
34811
34783
|
if (await (0, import_strategyReleaseEvidence2.strategyEvidenceFileSha256)(artifactPath) !== artifact.sha256) {
|
|
34812
34784
|
return null;
|
|
34813
34785
|
}
|
|
34814
|
-
return JSON.parse(await
|
|
34786
|
+
return JSON.parse(await import_promises34.default.readFile(artifactPath, "utf8"));
|
|
34815
34787
|
} catch {
|
|
34816
34788
|
return null;
|
|
34817
34789
|
}
|
|
@@ -35357,7 +35329,7 @@ var init_strategyRelease = __esm({
|
|
|
35357
35329
|
manifest
|
|
35358
35330
|
});
|
|
35359
35331
|
verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
35360
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
35332
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises34.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
35361
35333
|
const envelope = value;
|
|
35362
35334
|
assert3(
|
|
35363
35335
|
envelope?.schema === "tradejs-strategy-release-envelope/v1",
|
|
@@ -35408,7 +35380,7 @@ var init_strategyRelease = __esm({
|
|
|
35408
35380
|
return envelope;
|
|
35409
35381
|
};
|
|
35410
35382
|
verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
|
|
35411
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
35383
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises34.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
35412
35384
|
return (0, import_strategyReleaseEvidence2.verifyStrategyEvidenceMarkerEnvelope)(value);
|
|
35413
35385
|
};
|
|
35414
35386
|
releaseMarkers = (manifest) => {
|
|
@@ -35470,14 +35442,14 @@ var init_strategyRelease = __esm({
|
|
|
35470
35442
|
};
|
|
35471
35443
|
writeJsonAtomic2 = async (filePath, value) => {
|
|
35472
35444
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
35473
|
-
await
|
|
35474
|
-
await
|
|
35445
|
+
await import_promises34.default.mkdir(import_node_path32.default.dirname(filePath), { recursive: true });
|
|
35446
|
+
await import_promises34.default.writeFile(
|
|
35475
35447
|
temporaryPath,
|
|
35476
35448
|
`${canonicalStrategyReleaseJson(value)}
|
|
35477
35449
|
`,
|
|
35478
35450
|
"utf8"
|
|
35479
35451
|
);
|
|
35480
|
-
await
|
|
35452
|
+
await import_promises34.default.rename(temporaryPath, filePath);
|
|
35481
35453
|
};
|
|
35482
35454
|
publishStrategyRelease = async ({
|
|
35483
35455
|
rootDir,
|
|
@@ -35779,8 +35751,8 @@ var init_strategyRelease = __esm({
|
|
|
35779
35751
|
const researchDir = import_node_path32.default.dirname(resultPath);
|
|
35780
35752
|
const manifestPath = import_node_path32.default.join(researchDir, "manifest.json");
|
|
35781
35753
|
const specPath = import_node_path32.default.join(researchDir, "spec.json");
|
|
35782
|
-
const manifestBytes = await
|
|
35783
|
-
const specBytes = await
|
|
35754
|
+
const manifestBytes = await import_promises34.default.readFile(manifestPath).catch(() => null);
|
|
35755
|
+
const specBytes = await import_promises34.default.readFile(specPath).catch(() => null);
|
|
35784
35756
|
assert3(
|
|
35785
35757
|
manifestBytes != null && specBytes != null,
|
|
35786
35758
|
"core result must belong to a completed core research bundle"
|
|
@@ -35789,7 +35761,7 @@ var init_strategyRelease = __esm({
|
|
|
35789
35761
|
const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
|
|
35790
35762
|
const parsedSpec = JSON.parse(specBytes.toString("utf8"));
|
|
35791
35763
|
assert3(
|
|
35792
|
-
manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0,
|
|
35764
|
+
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
35765
|
"core result is not bound by its completed core research manifest"
|
|
35794
35766
|
);
|
|
35795
35767
|
for (const [relativePath, expectedSha256] of Object.entries(
|
|
@@ -35821,12 +35793,12 @@ __export(runtimeScorecard_exports, {
|
|
|
35821
35793
|
main: () => main42,
|
|
35822
35794
|
runtimeScorecard: () => runtimeScorecard
|
|
35823
35795
|
});
|
|
35824
|
-
var
|
|
35796
|
+
var import_promises35, import_node_crypto17, import_node_path33, import_args33, import_chalk49, flags30, projectRoot14, resolveOptionalPath, readJson, assertReportType, sha256File2, loadHistoryArtifacts, runtimeScorecard, main42;
|
|
35825
35797
|
var init_runtimeScorecard2 = __esm({
|
|
35826
35798
|
"src/scripts/runtimeScorecard.ts"() {
|
|
35827
35799
|
"use strict";
|
|
35828
|
-
|
|
35829
|
-
|
|
35800
|
+
import_promises35 = __toESM(require("fs/promises"));
|
|
35801
|
+
import_node_crypto17 = require("crypto");
|
|
35830
35802
|
import_node_path33 = __toESM(require("path"));
|
|
35831
35803
|
import_args33 = __toESM(require("args"));
|
|
35832
35804
|
import_chalk49 = __toESM(require("chalk"));
|
|
@@ -35899,13 +35871,13 @@ var init_runtimeScorecard2 = __esm({
|
|
|
35899
35871
|
const raw = String(value ?? "").trim();
|
|
35900
35872
|
return raw ? import_node_path33.default.resolve(projectRoot14, raw) : null;
|
|
35901
35873
|
};
|
|
35902
|
-
readJson = async (filePath) => filePath ? JSON.parse(await
|
|
35874
|
+
readJson = async (filePath) => filePath ? JSON.parse(await import_promises35.default.readFile(filePath, "utf8")) : void 0;
|
|
35903
35875
|
assertReportType = (artifact, expected, label) => {
|
|
35904
35876
|
if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
|
|
35905
35877
|
throw new Error(`${label} must be a ${expected} artifact`);
|
|
35906
35878
|
}
|
|
35907
35879
|
};
|
|
35908
|
-
sha256File2 = async (filePath) => (0,
|
|
35880
|
+
sha256File2 = async (filePath) => (0, import_node_crypto17.createHash)("sha256").update(await import_promises35.default.readFile(filePath)).digest("hex");
|
|
35909
35881
|
loadHistoryArtifacts = async (historyDir) => {
|
|
35910
35882
|
if (!historyDir) return [];
|
|
35911
35883
|
const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(historyDir);
|
|
@@ -35978,11 +35950,11 @@ var init_runtimeScorecard2 = __esm({
|
|
|
35978
35950
|
});
|
|
35979
35951
|
const outPath = import_node_path33.default.resolve(projectRoot14, String(flags30.out));
|
|
35980
35952
|
const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
|
|
35981
|
-
await
|
|
35953
|
+
await import_promises35.default.mkdir(import_node_path33.default.dirname(outPath), { recursive: true });
|
|
35982
35954
|
await Promise.all([
|
|
35983
|
-
|
|
35955
|
+
import_promises35.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
|
|
35984
35956
|
`, "utf8"),
|
|
35985
|
-
|
|
35957
|
+
import_promises35.default.writeFile(
|
|
35986
35958
|
markdownPath,
|
|
35987
35959
|
formatRuntimeScorecardMarkdown(scorecard),
|
|
35988
35960
|
"utf8"
|
|
@@ -35996,7 +35968,7 @@ var init_runtimeScorecard2 = __esm({
|
|
|
35996
35968
|
const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
|
|
35997
35969
|
const strategyReleaseRoot = resolveOptionalPath(flags30.strategyReleaseRoot);
|
|
35998
35970
|
if (diagnosis && diagnosisPath) {
|
|
35999
|
-
await
|
|
35971
|
+
await import_promises35.default.writeFile(
|
|
36000
35972
|
diagnosisPath,
|
|
36001
35973
|
`${JSON.stringify(diagnosis, null, 2)}
|
|
36002
35974
|
`,
|
|
@@ -36369,13 +36341,13 @@ print(json.dumps(sorted(opened)))
|
|
|
36369
36341
|
});
|
|
36370
36342
|
|
|
36371
36343
|
// src/lib/strategyRelease/researchRetention.ts
|
|
36372
|
-
var
|
|
36344
|
+
var import_promises36, import_node_path35, import_node_crypto18, import_strategyReleaseEvidence3, SHA256_RE3, mapFiles, fileSha256, inside, applyResearchRetention;
|
|
36373
36345
|
var init_researchRetention = __esm({
|
|
36374
36346
|
"src/lib/strategyRelease/researchRetention.ts"() {
|
|
36375
36347
|
"use strict";
|
|
36376
|
-
|
|
36348
|
+
import_promises36 = __toESM(require("fs/promises"));
|
|
36377
36349
|
import_node_path35 = __toESM(require("path"));
|
|
36378
|
-
|
|
36350
|
+
import_node_crypto18 = require("crypto");
|
|
36379
36351
|
import_strategyReleaseEvidence3 = require("@tradejs/infra/strategyReleaseEvidence");
|
|
36380
36352
|
init_researchFileConsumers();
|
|
36381
36353
|
init_evidenceRetention();
|
|
@@ -36395,13 +36367,13 @@ var init_researchRetention = __esm({
|
|
|
36395
36367
|
if (worker.status === "rejected") throw worker.reason;
|
|
36396
36368
|
return results2;
|
|
36397
36369
|
};
|
|
36398
|
-
fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0,
|
|
36370
|
+
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
36371
|
inside = (root, file) => {
|
|
36400
36372
|
const relative = import_node_path35.default.relative(root, file);
|
|
36401
36373
|
return relative !== "" && !relative.startsWith(`..${import_node_path35.default.sep}`) && relative !== ".." && !import_node_path35.default.isAbsolute(relative);
|
|
36402
36374
|
};
|
|
36403
36375
|
applyResearchRetention = async (options) => {
|
|
36404
|
-
const projectRoot18 = await
|
|
36376
|
+
const projectRoot18 = await import_promises36.default.realpath(options.projectRoot);
|
|
36405
36377
|
const dataRoot = import_node_path35.default.join(projectRoot18, "data");
|
|
36406
36378
|
const resolve = (file) => import_node_path35.default.resolve(projectRoot18, file);
|
|
36407
36379
|
const receiptPath2 = resolve(options.receiptPath);
|
|
@@ -36428,13 +36400,13 @@ var init_researchRetention = __esm({
|
|
|
36428
36400
|
}
|
|
36429
36401
|
await mapFiles(options.research.permanentArtifacts, async (artifact) => {
|
|
36430
36402
|
const file = resolve(artifact.path);
|
|
36431
|
-
if (!inside(projectRoot18, await
|
|
36403
|
+
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
36404
|
throw new Error(
|
|
36433
36405
|
`Permanent research artifact checksum/path mismatch: ${file}`
|
|
36434
36406
|
);
|
|
36435
36407
|
}
|
|
36436
36408
|
if (artifact.role === "note") {
|
|
36437
|
-
const handle = await
|
|
36409
|
+
const handle = await import_promises36.default.open(file, "r");
|
|
36438
36410
|
try {
|
|
36439
36411
|
const header = Buffer.alloc(4096);
|
|
36440
36412
|
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
@@ -36460,9 +36432,9 @@ var init_researchRetention = __esm({
|
|
|
36460
36432
|
if (checkedPaths.has(file))
|
|
36461
36433
|
throw new Error(`Duplicate cleanup path: ${file}`);
|
|
36462
36434
|
checkedPaths.add(file);
|
|
36463
|
-
if (await
|
|
36435
|
+
if (await import_promises36.default.realpath(file) !== file)
|
|
36464
36436
|
throw new Error(`Research cleanup refuses symlinks: ${file}`);
|
|
36465
|
-
const stat = await
|
|
36437
|
+
const stat = await import_promises36.default.lstat(file);
|
|
36466
36438
|
if (!stat.isFile() || stat.size !== entry.bytes || await fileSha256(file, stat.size) !== entry.sha256) {
|
|
36467
36439
|
throw new Error(
|
|
36468
36440
|
`Disposable research file checksum/size mismatch: ${file}`
|
|
@@ -36488,29 +36460,29 @@ var init_researchRetention = __esm({
|
|
|
36488
36460
|
}))
|
|
36489
36461
|
};
|
|
36490
36462
|
if (!options.apply) return receipt;
|
|
36491
|
-
await
|
|
36492
|
-
if (await
|
|
36463
|
+
await import_promises36.default.mkdir(import_node_path35.default.dirname(receiptPath2), { recursive: true });
|
|
36464
|
+
if (await import_promises36.default.realpath(import_node_path35.default.dirname(receiptPath2)) !== import_node_path35.default.dirname(receiptPath2)) {
|
|
36493
36465
|
throw new Error("Cleanup receipt refuses symlinked directories");
|
|
36494
36466
|
}
|
|
36495
|
-
const lock = await
|
|
36467
|
+
const lock = await import_promises36.default.open(`${receiptPath2}.lock`, "wx");
|
|
36496
36468
|
let journal;
|
|
36497
36469
|
const writeReceipt = async () => {
|
|
36498
36470
|
const temp = `${receiptPath2}.${process.pid}.tmp`;
|
|
36499
|
-
await
|
|
36471
|
+
await import_promises36.default.writeFile(temp, `${JSON.stringify(receipt, null, 2)}
|
|
36500
36472
|
`, "utf8");
|
|
36501
|
-
await
|
|
36473
|
+
await import_promises36.default.rename(temp, receiptPath2);
|
|
36502
36474
|
};
|
|
36503
36475
|
try {
|
|
36504
|
-
journal = await
|
|
36476
|
+
journal = await import_promises36.default.open(journalPath, "wx");
|
|
36505
36477
|
receipt.status = "applying";
|
|
36506
36478
|
await writeReceipt();
|
|
36507
36479
|
for (let index = 0; index < checked.length; index += 1) {
|
|
36508
36480
|
const { file, entry, ino, mtimeMs } = checked[index];
|
|
36509
|
-
const stat = await
|
|
36481
|
+
const stat = await import_promises36.default.lstat(file);
|
|
36510
36482
|
if (!stat.isFile() || stat.ino !== ino || stat.mtimeMs !== mtimeMs || stat.size !== entry.bytes) {
|
|
36511
36483
|
throw new Error(`Research file changed during cleanup: ${file}`);
|
|
36512
36484
|
}
|
|
36513
|
-
await
|
|
36485
|
+
await import_promises36.default.unlink(file);
|
|
36514
36486
|
receipt.files[index].removed = true;
|
|
36515
36487
|
await journal.write(`${JSON.stringify(receipt.files[index])}
|
|
36516
36488
|
`);
|
|
@@ -36524,7 +36496,7 @@ var init_researchRetention = __esm({
|
|
|
36524
36496
|
} finally {
|
|
36525
36497
|
await journal?.close();
|
|
36526
36498
|
await lock.close();
|
|
36527
|
-
await
|
|
36499
|
+
await import_promises36.default.unlink(`${receiptPath2}.lock`);
|
|
36528
36500
|
}
|
|
36529
36501
|
};
|
|
36530
36502
|
}
|
|
@@ -36536,11 +36508,11 @@ __export(strategyRelease_exports, {
|
|
|
36536
36508
|
main: () => main44,
|
|
36537
36509
|
runStrategyReleaseCommand: () => runStrategyReleaseCommand
|
|
36538
36510
|
});
|
|
36539
|
-
var
|
|
36511
|
+
var import_promises37, import_node_fs6, import_node_readline3, import_node_path36, import_chalk50, valueAfter2, required3, writeJsonAtomic3, runStrategyReleaseCommand, printUsage2, main44;
|
|
36540
36512
|
var init_strategyRelease2 = __esm({
|
|
36541
36513
|
"src/scripts/strategyRelease.ts"() {
|
|
36542
36514
|
"use strict";
|
|
36543
|
-
|
|
36515
|
+
import_promises37 = __toESM(require("fs/promises"));
|
|
36544
36516
|
import_node_fs6 = require("fs");
|
|
36545
36517
|
import_node_readline3 = require("readline");
|
|
36546
36518
|
import_node_path36 = __toESM(require("path"));
|
|
@@ -36557,14 +36529,14 @@ var init_strategyRelease2 = __esm({
|
|
|
36557
36529
|
};
|
|
36558
36530
|
writeJsonAtomic3 = async (filePath, value) => {
|
|
36559
36531
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
36560
|
-
await
|
|
36561
|
-
await
|
|
36532
|
+
await import_promises37.default.mkdir(import_node_path36.default.dirname(filePath), { recursive: true });
|
|
36533
|
+
await import_promises37.default.writeFile(
|
|
36562
36534
|
temporaryPath,
|
|
36563
36535
|
`${JSON.stringify(value, null, 2)}
|
|
36564
36536
|
`,
|
|
36565
36537
|
"utf8"
|
|
36566
36538
|
);
|
|
36567
|
-
await
|
|
36539
|
+
await import_promises37.default.rename(temporaryPath, filePath);
|
|
36568
36540
|
};
|
|
36569
36541
|
runStrategyReleaseCommand = async (options) => {
|
|
36570
36542
|
const inputPath = import_node_path36.default.resolve(options.inputPath);
|
|
@@ -36616,7 +36588,7 @@ var init_strategyRelease2 = __esm({
|
|
|
36616
36588
|
profile
|
|
36617
36589
|
};
|
|
36618
36590
|
}
|
|
36619
|
-
const input = JSON.parse(await
|
|
36591
|
+
const input = JSON.parse(await import_promises37.default.readFile(inputPath, "utf8"));
|
|
36620
36592
|
if (options.command === "decide") {
|
|
36621
36593
|
const decision = await deriveStrategyReleaseResearchDecision(input);
|
|
36622
36594
|
if (options.outputPath) {
|
|
@@ -36649,7 +36621,7 @@ var init_strategyRelease2 = __esm({
|
|
|
36649
36621
|
protectedPaths: [inputPath]
|
|
36650
36622
|
});
|
|
36651
36623
|
} else if (options.apply) {
|
|
36652
|
-
await Promise.all(plan.delete.map((entry) =>
|
|
36624
|
+
await Promise.all(plan.delete.map((entry) => import_promises37.default.rm(entry.path)));
|
|
36653
36625
|
}
|
|
36654
36626
|
return {
|
|
36655
36627
|
kind: "retention",
|
|
@@ -38553,12 +38525,12 @@ __export(runtimeParity_exports, {
|
|
|
38553
38525
|
main: () => main46,
|
|
38554
38526
|
runtimeParity: () => runtimeParity
|
|
38555
38527
|
});
|
|
38556
|
-
var import_config11,
|
|
38528
|
+
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
38529
|
var init_runtimeParity2 = __esm({
|
|
38558
38530
|
"src/scripts/runtimeParity.ts"() {
|
|
38559
38531
|
"use strict";
|
|
38560
38532
|
import_config11 = require("dotenv/config");
|
|
38561
|
-
|
|
38533
|
+
import_node_crypto19 = require("crypto");
|
|
38562
38534
|
import_args35 = __toESM(require("args"));
|
|
38563
38535
|
import_chalk52 = __toESM(require("chalk"));
|
|
38564
38536
|
import_constants19 = require("@tradejs/core/constants");
|
|
@@ -38941,9 +38913,9 @@ var init_runtimeParity2 = __esm({
|
|
|
38941
38913
|
start: window.start,
|
|
38942
38914
|
end: window.end
|
|
38943
38915
|
},
|
|
38944
|
-
name: `${target.symbol}_${target.strategy}_${(0,
|
|
38945
|
-
testId: (0,
|
|
38946
|
-
testSuiteId: (0,
|
|
38916
|
+
name: `${target.symbol}_${target.strategy}_${(0, import_node_crypto19.randomUUID)().slice(0, 8)}`,
|
|
38917
|
+
testId: (0, import_node_crypto19.randomUUID)().slice(0, 8),
|
|
38918
|
+
testSuiteId: (0, import_node_crypto19.randomUUID)().slice(0, 8),
|
|
38947
38919
|
strategyName: target.strategy,
|
|
38948
38920
|
strategyConfig: replayConfig,
|
|
38949
38921
|
connectorName,
|