@tradejs/cli 3.1.29-beta.291 → 3.1.29-beta.292
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 +10497 -9777
- package/dist/lib/coreResearch.js +261 -115
- package/dist/lib/researchVisuals.js +27 -6
- package/dist/lib/strategyResearch.js +202 -167
- package/dist/scripts/aiPocketSearch.js +3343 -3029
- package/dist/scripts/coreResearch.js +263 -115
- package/dist/scripts/replay.js +480 -111
- package/dist/scripts/replayRunner.js +480 -111
- package/dist/scripts/researchVisuals.js +27 -6
- package/dist/scripts/strategyResearch.js +204 -168
- package/package.json +7 -7
|
@@ -35,6 +35,98 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
35
35
|
));
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
|
|
38
|
+
// src/lib/coreResearch/trace.ts
|
|
39
|
+
async function* readCoreResearchTrace(filePaths) {
|
|
40
|
+
for (const inputPath of filePaths) {
|
|
41
|
+
const filePath = import_node_path.default.resolve(inputPath);
|
|
42
|
+
const input = (0, import_node_fs.createReadStream)(filePath);
|
|
43
|
+
const lines = import_node_readline.default.createInterface({ input, crlfDelay: Infinity });
|
|
44
|
+
let index = -1;
|
|
45
|
+
try {
|
|
46
|
+
for await (const line of lines) {
|
|
47
|
+
index++;
|
|
48
|
+
if (!line.trim()) continue;
|
|
49
|
+
let event;
|
|
50
|
+
try {
|
|
51
|
+
event = JSON.parse(line);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`${filePath}:${index + 1} contains invalid trace JSON: ${String(error)}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
yield event;
|
|
58
|
+
}
|
|
59
|
+
} finally {
|
|
60
|
+
lines.close();
|
|
61
|
+
input.destroy();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
var import_node_fs, import_node_readline, import_node_path, summarizeCoreResearchTrace;
|
|
66
|
+
var init_trace = __esm({
|
|
67
|
+
"src/lib/coreResearch/trace.ts"() {
|
|
68
|
+
"use strict";
|
|
69
|
+
import_node_fs = require("fs");
|
|
70
|
+
import_node_readline = __toESM(require("readline"));
|
|
71
|
+
import_node_path = __toESM(require("path"));
|
|
72
|
+
summarizeCoreResearchTrace = async (filePaths = []) => {
|
|
73
|
+
const events = /* @__PURE__ */ Object.create(null);
|
|
74
|
+
const skipCounts = /* @__PURE__ */ Object.create(null);
|
|
75
|
+
const exitCodes = /* @__PURE__ */ Object.create(null);
|
|
76
|
+
const policyRejections = {};
|
|
77
|
+
const policyExamples = [];
|
|
78
|
+
for await (const event of readCoreResearchTrace(filePaths)) {
|
|
79
|
+
events[event.event] = (events[event.event] ?? 0) + 1;
|
|
80
|
+
if (event.event === "skip_summary") {
|
|
81
|
+
for (const [reason, count] of Object.entries(event.skipCounts)) {
|
|
82
|
+
skipCounts[reason] = (skipCounts[reason] ?? 0) + count;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (event.event === "position_exited" && event.exitCode) {
|
|
86
|
+
exitCodes[event.exitCode] = (exitCodes[event.exitCode] ?? 0) + 1;
|
|
87
|
+
}
|
|
88
|
+
if ("researchEntryDecision" in event && event.researchEntryDecision && !event.researchEntryDecision.allowed) {
|
|
89
|
+
const reason = event.researchEntryDecision.reason;
|
|
90
|
+
policyRejections[reason] = (policyRejections[reason] ?? 0) + 1;
|
|
91
|
+
if (policyExamples.length < 20)
|
|
92
|
+
policyExamples.push({
|
|
93
|
+
timestamp: event.timestamp,
|
|
94
|
+
symbol: event.symbol,
|
|
95
|
+
decision: event.researchEntryDecision
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
events: Object.fromEntries(Object.entries(events).sort()),
|
|
101
|
+
skipCounts: Object.fromEntries(
|
|
102
|
+
Object.entries(skipCounts).sort(
|
|
103
|
+
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
104
|
+
)
|
|
105
|
+
),
|
|
106
|
+
exitCodes: Object.fromEntries(
|
|
107
|
+
Object.entries(exitCodes).sort(
|
|
108
|
+
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
...policyExamples.length ? {
|
|
112
|
+
researchPolicy: {
|
|
113
|
+
rejections: policyRejections,
|
|
114
|
+
examples: policyExamples
|
|
115
|
+
}
|
|
116
|
+
} : {}
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// src/lib/coreResearch/support.ts
|
|
123
|
+
var init_support = __esm({
|
|
124
|
+
"src/lib/coreResearch/support.ts"() {
|
|
125
|
+
"use strict";
|
|
126
|
+
init_trace();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
38
130
|
// src/lib/coreResearch/types.ts
|
|
39
131
|
var CORE_RESEARCH_SCHEMA;
|
|
40
132
|
var init_types = __esm({
|
|
@@ -48,15 +140,16 @@ var init_types = __esm({
|
|
|
48
140
|
function assert(condition, message) {
|
|
49
141
|
if (!condition) throw new Error(`Invalid core research spec: ${message}`);
|
|
50
142
|
}
|
|
51
|
-
var import_node_crypto,
|
|
143
|
+
var import_node_crypto, import_node_fs2, import_promises, import_backtest, import_node_path2, RESEARCH_ID_RE, SHA256_RE, canonicalJson, sha256Text, sha256Json, sha256File, assertFinite, validateCoreResearchSpec, writeJsonAtomic;
|
|
52
144
|
var init_io = __esm({
|
|
53
145
|
"src/lib/coreResearch/io.ts"() {
|
|
54
146
|
"use strict";
|
|
55
147
|
import_node_crypto = require("crypto");
|
|
56
|
-
|
|
148
|
+
import_node_fs2 = require("fs");
|
|
57
149
|
import_promises = __toESM(require("fs/promises"));
|
|
58
150
|
import_backtest = require("@tradejs/core/backtest");
|
|
59
|
-
|
|
151
|
+
import_node_path2 = __toESM(require("path"));
|
|
152
|
+
init_support();
|
|
60
153
|
init_types();
|
|
61
154
|
RESEARCH_ID_RE = /^[a-z0-9][a-z0-9._-]{2,120}$/;
|
|
62
155
|
SHA256_RE = /^[a-f0-9]{64}$/;
|
|
@@ -76,7 +169,7 @@ var init_io = __esm({
|
|
|
76
169
|
sha256Json = (value) => sha256Text(canonicalJson(value));
|
|
77
170
|
sha256File = async (filePath) => {
|
|
78
171
|
const hash2 = (0, import_node_crypto.createHash)("sha256");
|
|
79
|
-
const input = (0,
|
|
172
|
+
const input = (0, import_node_fs2.createReadStream)(filePath);
|
|
80
173
|
for await (const chunk of input) hash2.update(chunk);
|
|
81
174
|
return hash2.digest("hex");
|
|
82
175
|
};
|
|
@@ -312,10 +405,26 @@ var init_io = __esm({
|
|
|
312
405
|
Boolean(spec.artifacts?.ledgerPath?.trim()),
|
|
313
406
|
"artifacts.ledgerPath is required"
|
|
314
407
|
);
|
|
408
|
+
if (spec.support !== void 0) {
|
|
409
|
+
assert(
|
|
410
|
+
spec.support && typeof spec.support === "object",
|
|
411
|
+
"support must be an object"
|
|
412
|
+
);
|
|
413
|
+
for (const [key, value2] of [
|
|
414
|
+
["minimumEvents", spec.support.minimumEvents],
|
|
415
|
+
["minimumBlocks", spec.support.minimumBlocks],
|
|
416
|
+
...spec.support.minimumCommonSetups === void 0 ? [] : [["minimumCommonSetups", spec.support.minimumCommonSetups]]
|
|
417
|
+
]) {
|
|
418
|
+
assert(
|
|
419
|
+
typeof value2 === "number" && Number.isSafeInteger(value2) && value2 > 0,
|
|
420
|
+
`support.${key} must be a positive integer`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
315
424
|
return spec;
|
|
316
425
|
};
|
|
317
426
|
writeJsonAtomic = async (filePath, value) => {
|
|
318
|
-
await import_promises.default.mkdir(
|
|
427
|
+
await import_promises.default.mkdir(import_node_path2.default.dirname(filePath), { recursive: true });
|
|
319
428
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
320
429
|
await import_promises.default.writeFile(temporaryPath, `${canonicalJson(value)}
|
|
321
430
|
`, "utf8");
|
|
@@ -336,30 +445,30 @@ __export(io_exports, {
|
|
|
336
445
|
verifyResearchState: () => verifyResearchState,
|
|
337
446
|
withResearchLock: () => withResearchLock
|
|
338
447
|
});
|
|
339
|
-
var import_promises2,
|
|
448
|
+
var import_promises2, import_node_path3, import_node_os, import_node_crypto3, researchDirectory, readJson, boundResearchPath, withResearchLock, verifyResearchState, verifyCompletedResearch, initializeResearchState, isRetainedDeletion;
|
|
340
449
|
var init_io2 = __esm({
|
|
341
450
|
"src/lib/strategyResearch/io.ts"() {
|
|
342
451
|
"use strict";
|
|
343
452
|
import_promises2 = __toESM(require("fs/promises"));
|
|
344
|
-
|
|
453
|
+
import_node_path3 = __toESM(require("path"));
|
|
345
454
|
import_node_os = __toESM(require("os"));
|
|
346
455
|
import_node_crypto3 = require("crypto");
|
|
347
456
|
init_io();
|
|
348
|
-
researchDirectory = (projectRoot, spec) =>
|
|
457
|
+
researchDirectory = (projectRoot, spec) => import_node_path3.default.join(projectRoot, "data/research/strategy", spec.core.researchId);
|
|
349
458
|
readJson = async (file) => JSON.parse(await import_promises2.default.readFile(file, "utf8"));
|
|
350
459
|
boundResearchPath = async (root, relative) => {
|
|
351
|
-
const target =
|
|
460
|
+
const target = import_node_path3.default.resolve(root, relative);
|
|
352
461
|
const realRoot = await import_promises2.default.realpath(root);
|
|
353
462
|
let ancestor = target;
|
|
354
463
|
while (true) {
|
|
355
464
|
try {
|
|
356
465
|
const real = await import_promises2.default.realpath(ancestor);
|
|
357
|
-
if (real !== realRoot && !real.startsWith(`${realRoot}${
|
|
466
|
+
if (real !== realRoot && !real.startsWith(`${realRoot}${import_node_path3.default.sep}`))
|
|
358
467
|
throw new Error(`Research path escapes Project: ${relative}`);
|
|
359
468
|
break;
|
|
360
469
|
} catch (error) {
|
|
361
470
|
if (error.code !== "ENOENT") throw error;
|
|
362
|
-
const parent =
|
|
471
|
+
const parent = import_node_path3.default.dirname(ancestor);
|
|
363
472
|
if (parent === ancestor) throw error;
|
|
364
473
|
ancestor = parent;
|
|
365
474
|
}
|
|
@@ -371,7 +480,7 @@ var init_io2 = __esm({
|
|
|
371
480
|
projectRoot,
|
|
372
481
|
"data/research/strategy/.lock"
|
|
373
482
|
);
|
|
374
|
-
await import_promises2.default.mkdir(
|
|
483
|
+
await import_promises2.default.mkdir(import_node_path3.default.dirname(file), { recursive: true });
|
|
375
484
|
const token = (0, import_node_crypto3.randomUUID)();
|
|
376
485
|
const acquire = () => import_promises2.default.writeFile(
|
|
377
486
|
file,
|
|
@@ -405,7 +514,7 @@ var init_io2 = __esm({
|
|
|
405
514
|
}
|
|
406
515
|
};
|
|
407
516
|
verifyResearchState = async (directory, state) => {
|
|
408
|
-
const frozenSpec = await readJson(
|
|
517
|
+
const frozenSpec = await readJson(import_node_path3.default.join(directory, "spec.json"));
|
|
409
518
|
if (sha256Json(frozenSpec) !== state.specSha256)
|
|
410
519
|
throw new Error("Frozen research spec changed");
|
|
411
520
|
for (const [name, stage] of Object.entries(state.stages)) {
|
|
@@ -424,14 +533,14 @@ var init_io2 = __esm({
|
|
|
424
533
|
};
|
|
425
534
|
verifyCompletedResearch = async (directory, state) => {
|
|
426
535
|
await verifyResearchState(directory, state);
|
|
427
|
-
const manifest = await readJson(
|
|
536
|
+
const manifest = await readJson(import_node_path3.default.join(directory, "manifest.json"));
|
|
428
537
|
if (manifest.specSha256 !== state.specSha256)
|
|
429
538
|
throw new Error("Final manifest spec mismatch");
|
|
430
539
|
for (const [relative, expected] of Object.entries(manifest.artifacts))
|
|
431
540
|
if (await sha256File(await boundResearchPath(directory, relative)) !== expected)
|
|
432
541
|
throw new Error(`Changed final research artifact: ${relative}`);
|
|
433
|
-
const inventory = await readJson(
|
|
434
|
-
const projectRoot =
|
|
542
|
+
const inventory = await readJson(import_node_path3.default.join(directory, "retention.json"));
|
|
543
|
+
const projectRoot = import_node_path3.default.resolve(directory, "../../../..");
|
|
435
544
|
for (const artifact of inventory.research.permanentArtifacts) {
|
|
436
545
|
const file = await boundResearchPath(projectRoot, artifact.path);
|
|
437
546
|
if (await sha256File(file) !== artifact.sha256)
|
|
@@ -440,7 +549,7 @@ var init_io2 = __esm({
|
|
|
440
549
|
};
|
|
441
550
|
initializeResearchState = async (directory, spec, lineage) => {
|
|
442
551
|
await import_promises2.default.mkdir(directory, { recursive: true });
|
|
443
|
-
const file =
|
|
552
|
+
const file = import_node_path3.default.join(directory, "state.json");
|
|
444
553
|
let previous;
|
|
445
554
|
try {
|
|
446
555
|
previous = await readJson(file);
|
|
@@ -464,18 +573,18 @@ var init_io2 = __esm({
|
|
|
464
573
|
status: "running",
|
|
465
574
|
stages: {}
|
|
466
575
|
};
|
|
467
|
-
await writeJsonAtomic(
|
|
576
|
+
await writeJsonAtomic(import_node_path3.default.join(directory, "spec.json"), spec);
|
|
468
577
|
await writeJsonAtomic(file, state);
|
|
469
578
|
return state;
|
|
470
579
|
};
|
|
471
580
|
isRetainedDeletion = async (directory, file, hash2) => {
|
|
472
581
|
try {
|
|
473
|
-
const inventory = await readJson(
|
|
582
|
+
const inventory = await readJson(import_node_path3.default.join(directory, "retention.json"));
|
|
474
583
|
const index = inventory.entries.findIndex(
|
|
475
584
|
(entry) => entry.path === file && entry.sha256 === hash2
|
|
476
585
|
);
|
|
477
586
|
if (index < 0) return false;
|
|
478
|
-
const receipt = await readJson(
|
|
587
|
+
const receipt = await readJson(import_node_path3.default.join(directory, "retention", `${index}.json`));
|
|
479
588
|
return ["applying", "completed"].includes(receipt.status) && receipt.files[0]?.path === file && receipt.files[0]?.sha256 === hash2;
|
|
480
589
|
} catch (error) {
|
|
481
590
|
if (error.code === "ENOENT") return false;
|
|
@@ -2563,7 +2672,7 @@ var decodeResearchMetricSnapshot = (snapshot) => {
|
|
|
2563
2672
|
};
|
|
2564
2673
|
|
|
2565
2674
|
// src/lib/strategyResearch/orchestrator.ts
|
|
2566
|
-
var
|
|
2675
|
+
var import_node_path7 = __toESM(require("path"));
|
|
2567
2676
|
|
|
2568
2677
|
// src/lib/coreResearch/metrics.ts
|
|
2569
2678
|
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
@@ -3764,16 +3873,16 @@ var testCharts = (conclusion) => {
|
|
|
3764
3873
|
|
|
3765
3874
|
// src/lib/strategyResearch/retention.ts
|
|
3766
3875
|
var import_promises4 = __toESM(require("fs/promises"));
|
|
3767
|
-
var
|
|
3876
|
+
var import_node_path6 = __toESM(require("path"));
|
|
3768
3877
|
|
|
3769
3878
|
// src/lib/strategyRelease/researchRetention.ts
|
|
3770
3879
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
3771
|
-
var
|
|
3880
|
+
var import_node_path5 = __toESM(require("path"));
|
|
3772
3881
|
var import_node_crypto4 = require("crypto");
|
|
3773
3882
|
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
3774
3883
|
|
|
3775
3884
|
// src/lib/strategyRelease/researchFileConsumers.ts
|
|
3776
|
-
var
|
|
3885
|
+
var import_node_path4 = __toESM(require("path"));
|
|
3777
3886
|
var import_node_child_process = require("child_process");
|
|
3778
3887
|
var import_node_util = require("util");
|
|
3779
3888
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
@@ -3804,15 +3913,15 @@ print(json.dumps(sorted(opened)))
|
|
|
3804
3913
|
`;
|
|
3805
3914
|
var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
3806
3915
|
const virtualPids = /* @__PURE__ */ new Set();
|
|
3807
|
-
const wanted = new Set(files.map((file) =>
|
|
3808
|
-
let commonRoot = files.length ?
|
|
3916
|
+
const wanted = new Set(files.map((file) => import_node_path4.default.resolve(file)));
|
|
3917
|
+
let commonRoot = files.length ? import_node_path4.default.dirname(files[0]) : "";
|
|
3809
3918
|
while (commonRoot && files.some((file) => {
|
|
3810
|
-
const relative =
|
|
3811
|
-
return relative === ".." || relative.startsWith(`..${
|
|
3919
|
+
const relative = import_node_path4.default.relative(commonRoot, file);
|
|
3920
|
+
return relative === ".." || relative.startsWith(`..${import_node_path4.default.sep}`) || import_node_path4.default.isAbsolute(relative);
|
|
3812
3921
|
}))
|
|
3813
|
-
commonRoot =
|
|
3922
|
+
commonRoot = import_node_path4.default.dirname(commonRoot);
|
|
3814
3923
|
const selectors = [];
|
|
3815
|
-
if (files.length > 1e3 && commonRoot !==
|
|
3924
|
+
if (files.length > 1e3 && commonRoot !== import_node_path4.default.parse(commonRoot).root) {
|
|
3816
3925
|
selectors.push(["+D", commonRoot]);
|
|
3817
3926
|
} else {
|
|
3818
3927
|
for (let offset = 0; offset < files.length; offset += 100)
|
|
@@ -3836,7 +3945,7 @@ var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
|
3836
3945
|
if (line.startsWith("c"))
|
|
3837
3946
|
virtual = line.startsWith("ccom.apple.Virtualization.");
|
|
3838
3947
|
if (line.startsWith("n")) {
|
|
3839
|
-
if (!wanted.has(
|
|
3948
|
+
if (!wanted.has(import_node_path4.default.resolve(line.slice(1)))) continue;
|
|
3840
3949
|
if (!virtual || !/^\d+$/.test(pid))
|
|
3841
3950
|
throw new Error(
|
|
3842
3951
|
`Research cleanup found open files: ${line.slice(1)}`
|
|
@@ -3870,9 +3979,9 @@ var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
|
3870
3979
|
for (const mount of container.Mounts) {
|
|
3871
3980
|
if (mount.Type !== "bind") continue;
|
|
3872
3981
|
for (const file of files) {
|
|
3873
|
-
const relative =
|
|
3874
|
-
if (relative === "" || !relative.startsWith(`..${
|
|
3875
|
-
guestFiles.add(
|
|
3982
|
+
const relative = import_node_path4.default.relative(mount.Source, file);
|
|
3983
|
+
if (relative === "" || !relative.startsWith(`..${import_node_path4.default.sep}`) && relative !== ".." && !import_node_path4.default.isAbsolute(relative)) {
|
|
3984
|
+
guestFiles.add(import_node_path4.default.posix.join(mount.Destination, relative));
|
|
3876
3985
|
covered.add(file);
|
|
3877
3986
|
}
|
|
3878
3987
|
}
|
|
@@ -3920,13 +4029,13 @@ var mapFiles = async (entries, visit) => {
|
|
|
3920
4029
|
};
|
|
3921
4030
|
var fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto4.createHash)("sha256").update(await import_promises3.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence.strategyEvidenceFileSha256)(file);
|
|
3922
4031
|
var inside = (root, file) => {
|
|
3923
|
-
const relative =
|
|
3924
|
-
return relative !== "" && !relative.startsWith(`..${
|
|
4032
|
+
const relative = import_node_path5.default.relative(root, file);
|
|
4033
|
+
return relative !== "" && !relative.startsWith(`..${import_node_path5.default.sep}`) && relative !== ".." && !import_node_path5.default.isAbsolute(relative);
|
|
3925
4034
|
};
|
|
3926
4035
|
var applyResearchRetention = async (options) => {
|
|
3927
4036
|
const projectRoot = await import_promises3.default.realpath(options.projectRoot);
|
|
3928
|
-
const dataRoot =
|
|
3929
|
-
const resolve = (file) =>
|
|
4037
|
+
const dataRoot = import_node_path5.default.join(projectRoot, "data");
|
|
4038
|
+
const resolve = (file) => import_node_path5.default.resolve(projectRoot, file);
|
|
3930
4039
|
const receiptPath = resolve(options.receiptPath);
|
|
3931
4040
|
const journalPath = `${receiptPath}.deleted.jsonl`;
|
|
3932
4041
|
const permanent = new Set(
|
|
@@ -4025,8 +4134,8 @@ var applyResearchRetention = async (options) => {
|
|
|
4025
4134
|
}))
|
|
4026
4135
|
};
|
|
4027
4136
|
if (!options.apply) return receipt;
|
|
4028
|
-
await import_promises3.default.mkdir(
|
|
4029
|
-
if (await import_promises3.default.realpath(
|
|
4137
|
+
await import_promises3.default.mkdir(import_node_path5.default.dirname(receiptPath), { recursive: true });
|
|
4138
|
+
if (await import_promises3.default.realpath(import_node_path5.default.dirname(receiptPath)) !== import_node_path5.default.dirname(receiptPath)) {
|
|
4030
4139
|
throw new Error("Cleanup receipt refuses symlinked directories");
|
|
4031
4140
|
}
|
|
4032
4141
|
const lock = await import_promises3.default.open(`${receiptPath}.lock`, "wx");
|
|
@@ -4072,17 +4181,17 @@ var createResearchRetentionInventory = async (projectRoot, directory, spec, stat
|
|
|
4072
4181
|
const permanentArtifacts = [];
|
|
4073
4182
|
for (const [role, file] of [
|
|
4074
4183
|
["note", notePath],
|
|
4075
|
-
["metrics",
|
|
4076
|
-
["candidates",
|
|
4077
|
-
["candidates",
|
|
4078
|
-
["ledger",
|
|
4079
|
-
["chart",
|
|
4184
|
+
["metrics", import_node_path6.default.join(directory, "result.json")],
|
|
4185
|
+
["candidates", import_node_path6.default.join(directory, "03-freeze-gates/result.json")],
|
|
4186
|
+
["candidates", import_node_path6.default.join(directory, "resolved-spec.json")],
|
|
4187
|
+
["ledger", import_node_path6.default.join(directory, "05-freeze-primary/result.json")],
|
|
4188
|
+
["chart", import_node_path6.default.join(directory, "report.html")],
|
|
4080
4189
|
...[
|
|
4081
4190
|
"source.patch",
|
|
4082
4191
|
"source-baseline.tar",
|
|
4083
4192
|
"source-untracked.json",
|
|
4084
4193
|
"source-jev-models.json"
|
|
4085
|
-
].map((file2) => ["source",
|
|
4194
|
+
].map((file2) => ["source", import_node_path6.default.join(directory, file2)])
|
|
4086
4195
|
]) {
|
|
4087
4196
|
try {
|
|
4088
4197
|
permanentArtifacts.push({
|
|
@@ -4142,13 +4251,13 @@ var createResearchRetentionInventory = async (projectRoot, directory, spec, stat
|
|
|
4142
4251
|
};
|
|
4143
4252
|
var applyRetentionInventory = async (projectRoot, directory) => {
|
|
4144
4253
|
const inventory = await readJson(
|
|
4145
|
-
|
|
4254
|
+
import_node_path6.default.join(directory, "retention.json")
|
|
4146
4255
|
);
|
|
4147
|
-
const receipts =
|
|
4256
|
+
const receipts = import_node_path6.default.join(directory, "retention");
|
|
4148
4257
|
await import_promises4.default.mkdir(receipts, { recursive: true });
|
|
4149
4258
|
for (let index = 0; index < inventory.entries.length; index++) {
|
|
4150
4259
|
const entry = inventory.entries[index];
|
|
4151
|
-
const receiptPath =
|
|
4260
|
+
const receiptPath = import_node_path6.default.join(receipts, `${index}.json`);
|
|
4152
4261
|
let receipt;
|
|
4153
4262
|
try {
|
|
4154
4263
|
receipt = await readJson(receiptPath);
|
|
@@ -4184,13 +4293,13 @@ var applyRetentionInventory = async (projectRoot, directory) => {
|
|
|
4184
4293
|
entries: [entry],
|
|
4185
4294
|
receiptPath,
|
|
4186
4295
|
apply: true,
|
|
4187
|
-
protectedPaths: [
|
|
4296
|
+
protectedPaths: [import_node_path6.default.join(directory, "retention.json")]
|
|
4188
4297
|
});
|
|
4189
4298
|
}
|
|
4190
4299
|
return { status: "completed", files: inventory.entries.length };
|
|
4191
4300
|
};
|
|
4192
4301
|
var finishResearchRetention = async (projectRoot, directory) => {
|
|
4193
|
-
const statusPath =
|
|
4302
|
+
const statusPath = import_node_path6.default.join(directory, "retention-status.json");
|
|
4194
4303
|
try {
|
|
4195
4304
|
const result = await applyRetentionInventory(projectRoot, directory);
|
|
4196
4305
|
await writeJsonAtomic(statusPath, result);
|
|
@@ -4217,7 +4326,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4217
4326
|
const directory = researchDirectory(projectRoot, spec);
|
|
4218
4327
|
const lineage = await backend.lineage();
|
|
4219
4328
|
const state = await initializeResearchState(directory, spec, lineage);
|
|
4220
|
-
const statePath =
|
|
4329
|
+
const statePath = import_node_path7.default.join(directory, "state.json");
|
|
4221
4330
|
const elapsedBefore = state.elapsedMs ?? 0;
|
|
4222
4331
|
const activeStart = Date.now();
|
|
4223
4332
|
const elapsed = () => elapsedBefore + Date.now() - activeStart;
|
|
@@ -4227,7 +4336,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4227
4336
|
directory,
|
|
4228
4337
|
state,
|
|
4229
4338
|
conclusion: await readJson(
|
|
4230
|
-
|
|
4339
|
+
import_node_path7.default.join(directory, "result.json")
|
|
4231
4340
|
)
|
|
4232
4341
|
};
|
|
4233
4342
|
}
|
|
@@ -4237,13 +4346,13 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4237
4346
|
return writeJsonAtomic(statePath, state);
|
|
4238
4347
|
};
|
|
4239
4348
|
const event = async (stage2, status) => import_promises5.default.appendFile(
|
|
4240
|
-
|
|
4349
|
+
import_node_path7.default.join(directory, "events.jsonl"),
|
|
4241
4350
|
`${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), stage: stage2, status, specSha256: state.specSha256 })}
|
|
4242
4351
|
`
|
|
4243
4352
|
);
|
|
4244
4353
|
const stage = async (name, work) => {
|
|
4245
4354
|
const stageDirectory = await boundResearchPath(directory, name);
|
|
4246
|
-
const resultPath =
|
|
4355
|
+
const resultPath = import_node_path7.default.join(stageDirectory, "result.json");
|
|
4247
4356
|
if (state.stages[name]?.status === "completed")
|
|
4248
4357
|
return readJson(resultPath);
|
|
4249
4358
|
if (elapsed() > spec.budget.maxMinutes * 6e4)
|
|
@@ -4262,7 +4371,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4262
4371
|
await save();
|
|
4263
4372
|
await event(name, "started");
|
|
4264
4373
|
await import_promises5.default.writeFile(
|
|
4265
|
-
|
|
4374
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
4266
4375
|
buildStrategyResearchReport({ spec, state, diagnostics })
|
|
4267
4376
|
);
|
|
4268
4377
|
try {
|
|
@@ -4270,7 +4379,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4270
4379
|
await writeJsonAtomic(resultPath, result);
|
|
4271
4380
|
const artifacts = {};
|
|
4272
4381
|
for (const file of await import_promises5.default.readdir(stageDirectory)) {
|
|
4273
|
-
const full =
|
|
4382
|
+
const full = import_node_path7.default.join(stageDirectory, file);
|
|
4274
4383
|
if ((await import_promises5.default.stat(full)).isFile())
|
|
4275
4384
|
artifacts[`${name}/${file}`] = await sha256File(full);
|
|
4276
4385
|
}
|
|
@@ -4282,7 +4391,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4282
4391
|
"source-jev-models.json"
|
|
4283
4392
|
]) {
|
|
4284
4393
|
try {
|
|
4285
|
-
artifacts[file] = await sha256File(
|
|
4394
|
+
artifacts[file] = await sha256File(import_node_path7.default.join(directory, file));
|
|
4286
4395
|
} catch (error) {
|
|
4287
4396
|
if (error.code !== "ENOENT")
|
|
4288
4397
|
throw error;
|
|
@@ -4315,14 +4424,14 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4315
4424
|
let previousRunId;
|
|
4316
4425
|
try {
|
|
4317
4426
|
previousRunId = (await readJson(
|
|
4318
|
-
|
|
4427
|
+
import_node_path7.default.join(folder, "native-run.json")
|
|
4319
4428
|
)).runId;
|
|
4320
4429
|
} catch (error) {
|
|
4321
4430
|
if (error.code !== "ENOENT") throw error;
|
|
4322
4431
|
}
|
|
4323
4432
|
if (!previousRunId) {
|
|
4324
4433
|
try {
|
|
4325
|
-
if ((await import_promises5.default.stat(
|
|
4434
|
+
if ((await import_promises5.default.stat(import_node_path7.default.join(folder, "backtest.log"))).size)
|
|
4326
4435
|
throw new Error(
|
|
4327
4436
|
"Previous native attempt has no recorded run identity; inspect its log before another launch"
|
|
4328
4437
|
);
|
|
@@ -4343,7 +4452,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4343
4452
|
},
|
|
4344
4453
|
variant,
|
|
4345
4454
|
folder,
|
|
4346
|
-
async (runId) => writeJsonAtomic(
|
|
4455
|
+
async (runId) => writeJsonAtomic(import_node_path7.default.join(folder, "native-run.json"), { runId }),
|
|
4347
4456
|
previousRunId,
|
|
4348
4457
|
confirmation
|
|
4349
4458
|
);
|
|
@@ -4358,15 +4467,15 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4358
4467
|
try {
|
|
4359
4468
|
const inventory = await stage("01-preflight", async () => {
|
|
4360
4469
|
const prior = [];
|
|
4361
|
-
const root =
|
|
4470
|
+
const root = import_node_path7.default.dirname(directory);
|
|
4362
4471
|
for (const id of await import_promises5.default.readdir(root)) {
|
|
4363
4472
|
if (id === spec.core.researchId || id.startsWith(".")) continue;
|
|
4364
4473
|
try {
|
|
4365
4474
|
const previous = await readJson(
|
|
4366
|
-
|
|
4475
|
+
import_node_path7.default.join(root, id, "spec.json")
|
|
4367
4476
|
);
|
|
4368
4477
|
const previousState = await readJson(
|
|
4369
|
-
|
|
4478
|
+
import_node_path7.default.join(root, id, "state.json")
|
|
4370
4479
|
);
|
|
4371
4480
|
const overlap = previous.core.strategy === spec.core.strategy && previous.core.window.start < spec.core.window.end && previous.core.window.end > (spec.testSince || spec.core.window.start);
|
|
4372
4481
|
if (overlap && previousState.holdoutOpenedAt)
|
|
@@ -4392,7 +4501,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4392
4501
|
let previous;
|
|
4393
4502
|
try {
|
|
4394
4503
|
previous = (await readJson(
|
|
4395
|
-
|
|
4504
|
+
import_node_path7.default.join(folder, "native-run.json")
|
|
4396
4505
|
)).runId;
|
|
4397
4506
|
} catch (error) {
|
|
4398
4507
|
if (error.code !== "ENOENT")
|
|
@@ -4402,7 +4511,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4402
4511
|
spec,
|
|
4403
4512
|
control2,
|
|
4404
4513
|
folder,
|
|
4405
|
-
async (runId) => writeJsonAtomic(
|
|
4514
|
+
async (runId) => writeJsonAtomic(import_node_path7.default.join(folder, "native-run.json"), {
|
|
4406
4515
|
runId
|
|
4407
4516
|
}),
|
|
4408
4517
|
previous
|
|
@@ -4416,7 +4525,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4416
4525
|
);
|
|
4417
4526
|
spec = { ...spec, testSince: partition.testSince };
|
|
4418
4527
|
}
|
|
4419
|
-
await writeJsonAtomic(
|
|
4528
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "resolved-spec.json"), spec);
|
|
4420
4529
|
let gates = [];
|
|
4421
4530
|
let primaryId = null;
|
|
4422
4531
|
let frozenSelection;
|
|
@@ -4475,10 +4584,10 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4475
4584
|
core: { ...spec.core, researchId: spec.frozenFrom }
|
|
4476
4585
|
});
|
|
4477
4586
|
const parentState = await readJson(
|
|
4478
|
-
|
|
4587
|
+
import_node_path7.default.join(parentDirectory, "state.json")
|
|
4479
4588
|
);
|
|
4480
4589
|
const parentSpec = await readJson(
|
|
4481
|
-
|
|
4590
|
+
import_node_path7.default.join(parentDirectory, "spec.json")
|
|
4482
4591
|
);
|
|
4483
4592
|
const { verifyCompletedResearch: verifyCompletedResearch2 } = await Promise.resolve().then(() => (init_io2(), io_exports));
|
|
4484
4593
|
await verifyCompletedResearch2(parentDirectory, parentState);
|
|
@@ -4505,10 +4614,10 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4505
4614
|
"Frozen revalidation requires complete, unchanged rules/runtime and a strictly new period"
|
|
4506
4615
|
);
|
|
4507
4616
|
gates = await readJson(
|
|
4508
|
-
|
|
4617
|
+
import_node_path7.default.join(parentDirectory, "03-freeze-gates/result.json")
|
|
4509
4618
|
);
|
|
4510
4619
|
frozenSelection = await readJson(
|
|
4511
|
-
|
|
4620
|
+
import_node_path7.default.join(parentDirectory, "05-freeze-primary/result.json")
|
|
4512
4621
|
);
|
|
4513
4622
|
if (frozenSelection.schema !== "tradejs-research-selection/v1" || !Array.isArray(frozenSelection.compositions))
|
|
4514
4623
|
throw new Error(
|
|
@@ -4637,7 +4746,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4637
4746
|
`06-raw-metrics-${variant.id}`,
|
|
4638
4747
|
async (folder) => {
|
|
4639
4748
|
const resolved = spec.frozenFrom ? (await run(spec, variant, `06-raw-revalidation-${variant.id}`)).variant : (await readJson(
|
|
4640
|
-
|
|
4749
|
+
import_node_path7.default.join(directory, `02-raw-${variant.id}`, "result.json")
|
|
4641
4750
|
)).variant;
|
|
4642
4751
|
const dataset = await backend.loadDataset(
|
|
4643
4752
|
spec,
|
|
@@ -4814,7 +4923,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4814
4923
|
for (const name of Object.keys(state.stages)) {
|
|
4815
4924
|
try {
|
|
4816
4925
|
const result = await readJson(
|
|
4817
|
-
|
|
4926
|
+
import_node_path7.default.join(directory, name, "result.json")
|
|
4818
4927
|
);
|
|
4819
4928
|
if (result?.variant)
|
|
4820
4929
|
executions.push({ stage: name, ...result.variant });
|
|
@@ -4822,7 +4931,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4822
4931
|
if (error.code !== "ENOENT") throw error;
|
|
4823
4932
|
}
|
|
4824
4933
|
}
|
|
4825
|
-
await writeJsonAtomic(
|
|
4934
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "result.json"), {
|
|
4826
4935
|
...conclusion,
|
|
4827
4936
|
executions,
|
|
4828
4937
|
rawCore: Object.entries(rawReports).map(([id, windows]) => ({
|
|
@@ -4836,7 +4945,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4836
4945
|
delete state.error;
|
|
4837
4946
|
await save();
|
|
4838
4947
|
await import_promises5.default.writeFile(
|
|
4839
|
-
|
|
4948
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
4840
4949
|
buildStrategyResearchReport({
|
|
4841
4950
|
spec,
|
|
4842
4951
|
state,
|
|
@@ -4924,7 +5033,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4924
5033
|
"Compact permanent note exceeds 8 MiB; archive source separately, never truncate metrics"
|
|
4925
5034
|
);
|
|
4926
5035
|
await import_promises5.default.writeFile(
|
|
4927
|
-
|
|
5036
|
+
import_node_path7.default.join(
|
|
4928
5037
|
noteDirectory,
|
|
4929
5038
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4930
5039
|
),
|
|
@@ -4933,7 +5042,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4933
5042
|
).catch(async (error) => {
|
|
4934
5043
|
if (error.code !== "EEXIST") throw error;
|
|
4935
5044
|
const existing = await import_promises5.default.readFile(
|
|
4936
|
-
|
|
5045
|
+
import_node_path7.default.join(
|
|
4937
5046
|
noteDirectory,
|
|
4938
5047
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4939
5048
|
),
|
|
@@ -4945,19 +5054,19 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4945
5054
|
);
|
|
4946
5055
|
});
|
|
4947
5056
|
await writeJsonAtomic(
|
|
4948
|
-
|
|
5057
|
+
import_node_path7.default.join(directory, "retention.json"),
|
|
4949
5058
|
await createResearchRetentionInventory(
|
|
4950
5059
|
projectRoot,
|
|
4951
5060
|
directory,
|
|
4952
5061
|
spec,
|
|
4953
5062
|
state,
|
|
4954
|
-
|
|
5063
|
+
import_node_path7.default.join(
|
|
4955
5064
|
noteDirectory,
|
|
4956
5065
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4957
5066
|
)
|
|
4958
5067
|
)
|
|
4959
5068
|
);
|
|
4960
|
-
await writeJsonAtomic(
|
|
5069
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "manifest.json"), {
|
|
4961
5070
|
schema: "tradejs-strategy-research-manifest/v1",
|
|
4962
5071
|
specSha256: state.specSha256,
|
|
4963
5072
|
artifacts: Object.fromEntries(
|
|
@@ -4971,7 +5080,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4971
5080
|
"retention.json"
|
|
4972
5081
|
].map(async (file) => [
|
|
4973
5082
|
file,
|
|
4974
|
-
await sha256File(
|
|
5083
|
+
await sha256File(import_node_path7.default.join(directory, file))
|
|
4975
5084
|
])
|
|
4976
5085
|
)
|
|
4977
5086
|
)
|
|
@@ -4984,7 +5093,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4984
5093
|
);
|
|
4985
5094
|
}
|
|
4986
5095
|
parameters.onProgress?.(
|
|
4987
|
-
`\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${
|
|
5096
|
+
`\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${import_node_path7.default.join(directory, "report.html")}`
|
|
4988
5097
|
);
|
|
4989
5098
|
return { directory, state, conclusion };
|
|
4990
5099
|
} catch (error) {
|
|
@@ -5005,9 +5114,9 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
5005
5114
|
frozenGates: 0
|
|
5006
5115
|
}
|
|
5007
5116
|
};
|
|
5008
|
-
await writeJsonAtomic(
|
|
5117
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "result.json"), conclusion);
|
|
5009
5118
|
await import_promises5.default.writeFile(
|
|
5010
|
-
|
|
5119
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
5011
5120
|
buildStrategyResearchReport({ spec, state, conclusion, diagnostics })
|
|
5012
5121
|
);
|
|
5013
5122
|
throw error;
|
|
@@ -5031,9 +5140,9 @@ var import_connectors = require("@tradejs/node/connectors");
|
|
|
5031
5140
|
|
|
5032
5141
|
// src/lib/coreResearch/dataset.ts
|
|
5033
5142
|
var import_node_crypto5 = require("crypto");
|
|
5034
|
-
var
|
|
5035
|
-
var
|
|
5036
|
-
var
|
|
5143
|
+
var import_node_fs3 = require("fs");
|
|
5144
|
+
var import_node_path8 = __toESM(require("path"));
|
|
5145
|
+
var import_node_readline2 = __toESM(require("readline"));
|
|
5037
5146
|
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5038
5147
|
var finiteNumber = (value, field) => {
|
|
5039
5148
|
const numeric = Number(value);
|
|
@@ -5243,11 +5352,11 @@ var readCoreResearchVariant = async (variant) => {
|
|
|
5243
5352
|
const seen = /* @__PURE__ */ new Map();
|
|
5244
5353
|
let duplicateRowsDropped = 0;
|
|
5245
5354
|
for (const inputPath of variant.files) {
|
|
5246
|
-
const filePath =
|
|
5247
|
-
const input = (0,
|
|
5355
|
+
const filePath = import_node_path8.default.resolve(inputPath);
|
|
5356
|
+
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
5248
5357
|
const hash2 = (0, import_node_crypto5.createHash)("sha256");
|
|
5249
5358
|
input.on("data", (chunk) => hash2.update(chunk));
|
|
5250
|
-
const lines =
|
|
5359
|
+
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
5251
5360
|
const fileTrades = [];
|
|
5252
5361
|
let lineNumber = 0;
|
|
5253
5362
|
let rows = 0;
|
|
@@ -5532,7 +5641,7 @@ init_io2();
|
|
|
5532
5641
|
var import_node_child_process2 = require("child_process");
|
|
5533
5642
|
var import_node_crypto8 = require("crypto");
|
|
5534
5643
|
var import_promises7 = __toESM(require("fs/promises"));
|
|
5535
|
-
var
|
|
5644
|
+
var import_node_path10 = __toESM(require("path"));
|
|
5536
5645
|
|
|
5537
5646
|
// src/lib/aiTrainMetrics.ts
|
|
5538
5647
|
var DAY_MS3 = 24 * 60 * 60 * 1e3;
|
|
@@ -5545,7 +5654,7 @@ var import_types2 = require("@tradejs/types");
|
|
|
5545
5654
|
var import_node_crypto7 = require("crypto");
|
|
5546
5655
|
var import_node_module = require("module");
|
|
5547
5656
|
var import_promises6 = __toESM(require("fs/promises"));
|
|
5548
|
-
var
|
|
5657
|
+
var import_node_path9 = __toESM(require("path"));
|
|
5549
5658
|
|
|
5550
5659
|
// src/lib/aiTrainResearch.ts
|
|
5551
5660
|
var DAY_MS4 = 24 * 60 * 60 * 1e3;
|
|
@@ -5596,81 +5705,7 @@ var fingerprintResearchContextEnvironment = (env = process.env) => fingerprintRe
|
|
|
5596
5705
|
// src/lib/strategyResearch/native.ts
|
|
5597
5706
|
var import_data = require("@tradejs/core/data");
|
|
5598
5707
|
var import_coreResearch = require("@tradejs/infra/coreResearch");
|
|
5599
|
-
|
|
5600
|
-
// src/lib/coreResearch/trace.ts
|
|
5601
|
-
var import_node_fs3 = require("fs");
|
|
5602
|
-
var import_node_readline2 = __toESM(require("readline"));
|
|
5603
|
-
var import_node_path10 = __toESM(require("path"));
|
|
5604
|
-
var summarizeCoreResearchTrace = async (filePaths = []) => {
|
|
5605
|
-
const events = /* @__PURE__ */ Object.create(null);
|
|
5606
|
-
const skipCounts = /* @__PURE__ */ Object.create(null);
|
|
5607
|
-
const exitCodes = /* @__PURE__ */ Object.create(null);
|
|
5608
|
-
const policyRejections = {};
|
|
5609
|
-
const policyExamples = [];
|
|
5610
|
-
for (const inputPath of filePaths) {
|
|
5611
|
-
const filePath = import_node_path10.default.resolve(inputPath);
|
|
5612
|
-
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
5613
|
-
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
5614
|
-
let index = -1;
|
|
5615
|
-
try {
|
|
5616
|
-
for await (const line of lines) {
|
|
5617
|
-
index++;
|
|
5618
|
-
if (!line.trim()) continue;
|
|
5619
|
-
let event;
|
|
5620
|
-
try {
|
|
5621
|
-
event = JSON.parse(line);
|
|
5622
|
-
} catch (error) {
|
|
5623
|
-
throw new Error(
|
|
5624
|
-
`${filePath}:${index + 1} contains invalid trace JSON: ${String(error)}`
|
|
5625
|
-
);
|
|
5626
|
-
}
|
|
5627
|
-
events[event.event] = (events[event.event] ?? 0) + 1;
|
|
5628
|
-
if (event.event === "skip_summary") {
|
|
5629
|
-
for (const [reason, count] of Object.entries(event.skipCounts)) {
|
|
5630
|
-
skipCounts[reason] = (skipCounts[reason] ?? 0) + count;
|
|
5631
|
-
}
|
|
5632
|
-
}
|
|
5633
|
-
if (event.event === "position_exited" && event.exitCode) {
|
|
5634
|
-
exitCodes[event.exitCode] = (exitCodes[event.exitCode] ?? 0) + 1;
|
|
5635
|
-
}
|
|
5636
|
-
if ("researchEntryDecision" in event && event.researchEntryDecision && !event.researchEntryDecision.allowed) {
|
|
5637
|
-
const reason = event.researchEntryDecision.reason;
|
|
5638
|
-
policyRejections[reason] = (policyRejections[reason] ?? 0) + 1;
|
|
5639
|
-
if (policyExamples.length < 20)
|
|
5640
|
-
policyExamples.push({
|
|
5641
|
-
timestamp: event.timestamp,
|
|
5642
|
-
symbol: event.symbol,
|
|
5643
|
-
decision: event.researchEntryDecision
|
|
5644
|
-
});
|
|
5645
|
-
}
|
|
5646
|
-
}
|
|
5647
|
-
} finally {
|
|
5648
|
-
lines.close();
|
|
5649
|
-
input.destroy();
|
|
5650
|
-
}
|
|
5651
|
-
}
|
|
5652
|
-
return {
|
|
5653
|
-
events: Object.fromEntries(Object.entries(events).sort()),
|
|
5654
|
-
skipCounts: Object.fromEntries(
|
|
5655
|
-
Object.entries(skipCounts).sort(
|
|
5656
|
-
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
5657
|
-
)
|
|
5658
|
-
),
|
|
5659
|
-
exitCodes: Object.fromEntries(
|
|
5660
|
-
Object.entries(exitCodes).sort(
|
|
5661
|
-
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
5662
|
-
)
|
|
5663
|
-
),
|
|
5664
|
-
...policyExamples.length ? {
|
|
5665
|
-
researchPolicy: {
|
|
5666
|
-
rejections: policyRejections,
|
|
5667
|
-
examples: policyExamples
|
|
5668
|
-
}
|
|
5669
|
-
} : {}
|
|
5670
|
-
};
|
|
5671
|
-
};
|
|
5672
|
-
|
|
5673
|
-
// src/lib/strategyResearch/native.ts
|
|
5708
|
+
init_trace();
|
|
5674
5709
|
var import_jev4 = require("@tradejs/core/jev");
|
|
5675
5710
|
|
|
5676
5711
|
// src/lib/backtest/jevOptions.ts
|