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