@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, loadCoreResearchSpec, 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,16 +405,32 @@ 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
|
loadCoreResearchSpec = async (specPath) => {
|
|
318
|
-
const resolvedPath =
|
|
427
|
+
const resolvedPath = import_node_path2.default.resolve(specPath);
|
|
319
428
|
const parsed = JSON.parse(await import_promises.default.readFile(resolvedPath, "utf8"));
|
|
320
429
|
const spec = validateCoreResearchSpec(parsed);
|
|
321
430
|
return { resolvedPath, spec, specSha256: sha256Json(spec) };
|
|
322
431
|
};
|
|
323
432
|
writeJsonAtomic = async (filePath, value) => {
|
|
324
|
-
await import_promises.default.mkdir(
|
|
433
|
+
await import_promises.default.mkdir(import_node_path2.default.dirname(filePath), { recursive: true });
|
|
325
434
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
326
435
|
await import_promises.default.writeFile(temporaryPath, `${canonicalJson(value)}
|
|
327
436
|
`, "utf8");
|
|
@@ -342,30 +451,30 @@ __export(io_exports, {
|
|
|
342
451
|
verifyResearchState: () => verifyResearchState,
|
|
343
452
|
withResearchLock: () => withResearchLock
|
|
344
453
|
});
|
|
345
|
-
var import_promises2,
|
|
454
|
+
var import_promises2, import_node_path3, import_node_os, import_node_crypto3, researchDirectory, readJson, boundResearchPath, withResearchLock, verifyResearchState, verifyCompletedResearch, initializeResearchState, isRetainedDeletion;
|
|
346
455
|
var init_io2 = __esm({
|
|
347
456
|
"src/lib/strategyResearch/io.ts"() {
|
|
348
457
|
"use strict";
|
|
349
458
|
import_promises2 = __toESM(require("fs/promises"));
|
|
350
|
-
|
|
459
|
+
import_node_path3 = __toESM(require("path"));
|
|
351
460
|
import_node_os = __toESM(require("os"));
|
|
352
461
|
import_node_crypto3 = require("crypto");
|
|
353
462
|
init_io();
|
|
354
|
-
researchDirectory = (projectRoot, spec) =>
|
|
463
|
+
researchDirectory = (projectRoot, spec) => import_node_path3.default.join(projectRoot, "data/research/strategy", spec.core.researchId);
|
|
355
464
|
readJson = async (file) => JSON.parse(await import_promises2.default.readFile(file, "utf8"));
|
|
356
465
|
boundResearchPath = async (root, relative) => {
|
|
357
|
-
const target =
|
|
466
|
+
const target = import_node_path3.default.resolve(root, relative);
|
|
358
467
|
const realRoot = await import_promises2.default.realpath(root);
|
|
359
468
|
let ancestor = target;
|
|
360
469
|
while (true) {
|
|
361
470
|
try {
|
|
362
471
|
const real = await import_promises2.default.realpath(ancestor);
|
|
363
|
-
if (real !== realRoot && !real.startsWith(`${realRoot}${
|
|
472
|
+
if (real !== realRoot && !real.startsWith(`${realRoot}${import_node_path3.default.sep}`))
|
|
364
473
|
throw new Error(`Research path escapes Project: ${relative}`);
|
|
365
474
|
break;
|
|
366
475
|
} catch (error) {
|
|
367
476
|
if (error.code !== "ENOENT") throw error;
|
|
368
|
-
const parent =
|
|
477
|
+
const parent = import_node_path3.default.dirname(ancestor);
|
|
369
478
|
if (parent === ancestor) throw error;
|
|
370
479
|
ancestor = parent;
|
|
371
480
|
}
|
|
@@ -377,7 +486,7 @@ var init_io2 = __esm({
|
|
|
377
486
|
projectRoot,
|
|
378
487
|
"data/research/strategy/.lock"
|
|
379
488
|
);
|
|
380
|
-
await import_promises2.default.mkdir(
|
|
489
|
+
await import_promises2.default.mkdir(import_node_path3.default.dirname(file), { recursive: true });
|
|
381
490
|
const token = (0, import_node_crypto3.randomUUID)();
|
|
382
491
|
const acquire = () => import_promises2.default.writeFile(
|
|
383
492
|
file,
|
|
@@ -411,7 +520,7 @@ var init_io2 = __esm({
|
|
|
411
520
|
}
|
|
412
521
|
};
|
|
413
522
|
verifyResearchState = async (directory, state) => {
|
|
414
|
-
const frozenSpec = await readJson(
|
|
523
|
+
const frozenSpec = await readJson(import_node_path3.default.join(directory, "spec.json"));
|
|
415
524
|
if (sha256Json(frozenSpec) !== state.specSha256)
|
|
416
525
|
throw new Error("Frozen research spec changed");
|
|
417
526
|
for (const [name, stage] of Object.entries(state.stages)) {
|
|
@@ -430,14 +539,14 @@ var init_io2 = __esm({
|
|
|
430
539
|
};
|
|
431
540
|
verifyCompletedResearch = async (directory, state) => {
|
|
432
541
|
await verifyResearchState(directory, state);
|
|
433
|
-
const manifest = await readJson(
|
|
542
|
+
const manifest = await readJson(import_node_path3.default.join(directory, "manifest.json"));
|
|
434
543
|
if (manifest.specSha256 !== state.specSha256)
|
|
435
544
|
throw new Error("Final manifest spec mismatch");
|
|
436
545
|
for (const [relative, expected] of Object.entries(manifest.artifacts))
|
|
437
546
|
if (await sha256File(await boundResearchPath(directory, relative)) !== expected)
|
|
438
547
|
throw new Error(`Changed final research artifact: ${relative}`);
|
|
439
|
-
const inventory = await readJson(
|
|
440
|
-
const projectRoot =
|
|
548
|
+
const inventory = await readJson(import_node_path3.default.join(directory, "retention.json"));
|
|
549
|
+
const projectRoot = import_node_path3.default.resolve(directory, "../../../..");
|
|
441
550
|
for (const artifact of inventory.research.permanentArtifacts) {
|
|
442
551
|
const file = await boundResearchPath(projectRoot, artifact.path);
|
|
443
552
|
if (await sha256File(file) !== artifact.sha256)
|
|
@@ -446,7 +555,7 @@ var init_io2 = __esm({
|
|
|
446
555
|
};
|
|
447
556
|
initializeResearchState = async (directory, spec, lineage) => {
|
|
448
557
|
await import_promises2.default.mkdir(directory, { recursive: true });
|
|
449
|
-
const file =
|
|
558
|
+
const file = import_node_path3.default.join(directory, "state.json");
|
|
450
559
|
let previous;
|
|
451
560
|
try {
|
|
452
561
|
previous = await readJson(file);
|
|
@@ -470,18 +579,18 @@ var init_io2 = __esm({
|
|
|
470
579
|
status: "running",
|
|
471
580
|
stages: {}
|
|
472
581
|
};
|
|
473
|
-
await writeJsonAtomic(
|
|
582
|
+
await writeJsonAtomic(import_node_path3.default.join(directory, "spec.json"), spec);
|
|
474
583
|
await writeJsonAtomic(file, state);
|
|
475
584
|
return state;
|
|
476
585
|
};
|
|
477
586
|
isRetainedDeletion = async (directory, file, hash2) => {
|
|
478
587
|
try {
|
|
479
|
-
const inventory = await readJson(
|
|
588
|
+
const inventory = await readJson(import_node_path3.default.join(directory, "retention.json"));
|
|
480
589
|
const index = inventory.entries.findIndex(
|
|
481
590
|
(entry) => entry.path === file && entry.sha256 === hash2
|
|
482
591
|
);
|
|
483
592
|
if (index < 0) return false;
|
|
484
|
-
const receipt = await readJson(
|
|
593
|
+
const receipt = await readJson(import_node_path3.default.join(directory, "retention", `${index}.json`));
|
|
485
594
|
return ["applying", "completed"].includes(receipt.status) && receipt.files[0]?.path === file && receipt.files[0]?.sha256 === hash2;
|
|
486
595
|
} catch (error) {
|
|
487
596
|
if (error.code === "ENOENT") return false;
|
|
@@ -2568,7 +2677,7 @@ var decodeResearchMetricSnapshot = (snapshot) => {
|
|
|
2568
2677
|
};
|
|
2569
2678
|
|
|
2570
2679
|
// src/lib/strategyResearch/orchestrator.ts
|
|
2571
|
-
var
|
|
2680
|
+
var import_node_path7 = __toESM(require("path"));
|
|
2572
2681
|
|
|
2573
2682
|
// src/lib/coreResearch/metrics.ts
|
|
2574
2683
|
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
@@ -3769,16 +3878,16 @@ var testCharts = (conclusion) => {
|
|
|
3769
3878
|
|
|
3770
3879
|
// src/lib/strategyResearch/retention.ts
|
|
3771
3880
|
var import_promises4 = __toESM(require("fs/promises"));
|
|
3772
|
-
var
|
|
3881
|
+
var import_node_path6 = __toESM(require("path"));
|
|
3773
3882
|
|
|
3774
3883
|
// src/lib/strategyRelease/researchRetention.ts
|
|
3775
3884
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
3776
|
-
var
|
|
3885
|
+
var import_node_path5 = __toESM(require("path"));
|
|
3777
3886
|
var import_node_crypto4 = require("crypto");
|
|
3778
3887
|
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
3779
3888
|
|
|
3780
3889
|
// src/lib/strategyRelease/researchFileConsumers.ts
|
|
3781
|
-
var
|
|
3890
|
+
var import_node_path4 = __toESM(require("path"));
|
|
3782
3891
|
var import_node_child_process = require("child_process");
|
|
3783
3892
|
var import_node_util = require("util");
|
|
3784
3893
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
@@ -3809,15 +3918,15 @@ print(json.dumps(sorted(opened)))
|
|
|
3809
3918
|
`;
|
|
3810
3919
|
var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
3811
3920
|
const virtualPids = /* @__PURE__ */ new Set();
|
|
3812
|
-
const wanted = new Set(files.map((file) =>
|
|
3813
|
-
let commonRoot = files.length ?
|
|
3921
|
+
const wanted = new Set(files.map((file) => import_node_path4.default.resolve(file)));
|
|
3922
|
+
let commonRoot = files.length ? import_node_path4.default.dirname(files[0]) : "";
|
|
3814
3923
|
while (commonRoot && files.some((file) => {
|
|
3815
|
-
const relative =
|
|
3816
|
-
return relative === ".." || relative.startsWith(`..${
|
|
3924
|
+
const relative = import_node_path4.default.relative(commonRoot, file);
|
|
3925
|
+
return relative === ".." || relative.startsWith(`..${import_node_path4.default.sep}`) || import_node_path4.default.isAbsolute(relative);
|
|
3817
3926
|
}))
|
|
3818
|
-
commonRoot =
|
|
3927
|
+
commonRoot = import_node_path4.default.dirname(commonRoot);
|
|
3819
3928
|
const selectors = [];
|
|
3820
|
-
if (files.length > 1e3 && commonRoot !==
|
|
3929
|
+
if (files.length > 1e3 && commonRoot !== import_node_path4.default.parse(commonRoot).root) {
|
|
3821
3930
|
selectors.push(["+D", commonRoot]);
|
|
3822
3931
|
} else {
|
|
3823
3932
|
for (let offset = 0; offset < files.length; offset += 100)
|
|
@@ -3841,7 +3950,7 @@ var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
|
3841
3950
|
if (line.startsWith("c"))
|
|
3842
3951
|
virtual = line.startsWith("ccom.apple.Virtualization.");
|
|
3843
3952
|
if (line.startsWith("n")) {
|
|
3844
|
-
if (!wanted.has(
|
|
3953
|
+
if (!wanted.has(import_node_path4.default.resolve(line.slice(1)))) continue;
|
|
3845
3954
|
if (!virtual || !/^\d+$/.test(pid))
|
|
3846
3955
|
throw new Error(
|
|
3847
3956
|
`Research cleanup found open files: ${line.slice(1)}`
|
|
@@ -3875,9 +3984,9 @@ var assertNoResearchFileConsumers = async (files, run = runCommand) => {
|
|
|
3875
3984
|
for (const mount of container.Mounts) {
|
|
3876
3985
|
if (mount.Type !== "bind") continue;
|
|
3877
3986
|
for (const file of files) {
|
|
3878
|
-
const relative =
|
|
3879
|
-
if (relative === "" || !relative.startsWith(`..${
|
|
3880
|
-
guestFiles.add(
|
|
3987
|
+
const relative = import_node_path4.default.relative(mount.Source, file);
|
|
3988
|
+
if (relative === "" || !relative.startsWith(`..${import_node_path4.default.sep}`) && relative !== ".." && !import_node_path4.default.isAbsolute(relative)) {
|
|
3989
|
+
guestFiles.add(import_node_path4.default.posix.join(mount.Destination, relative));
|
|
3881
3990
|
covered.add(file);
|
|
3882
3991
|
}
|
|
3883
3992
|
}
|
|
@@ -3925,13 +4034,13 @@ var mapFiles = async (entries, visit) => {
|
|
|
3925
4034
|
};
|
|
3926
4035
|
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);
|
|
3927
4036
|
var inside = (root, file) => {
|
|
3928
|
-
const relative =
|
|
3929
|
-
return relative !== "" && !relative.startsWith(`..${
|
|
4037
|
+
const relative = import_node_path5.default.relative(root, file);
|
|
4038
|
+
return relative !== "" && !relative.startsWith(`..${import_node_path5.default.sep}`) && relative !== ".." && !import_node_path5.default.isAbsolute(relative);
|
|
3930
4039
|
};
|
|
3931
4040
|
var applyResearchRetention = async (options) => {
|
|
3932
4041
|
const projectRoot = await import_promises3.default.realpath(options.projectRoot);
|
|
3933
|
-
const dataRoot =
|
|
3934
|
-
const resolve = (file) =>
|
|
4042
|
+
const dataRoot = import_node_path5.default.join(projectRoot, "data");
|
|
4043
|
+
const resolve = (file) => import_node_path5.default.resolve(projectRoot, file);
|
|
3935
4044
|
const receiptPath = resolve(options.receiptPath);
|
|
3936
4045
|
const journalPath = `${receiptPath}.deleted.jsonl`;
|
|
3937
4046
|
const permanent = new Set(
|
|
@@ -4030,8 +4139,8 @@ var applyResearchRetention = async (options) => {
|
|
|
4030
4139
|
}))
|
|
4031
4140
|
};
|
|
4032
4141
|
if (!options.apply) return receipt;
|
|
4033
|
-
await import_promises3.default.mkdir(
|
|
4034
|
-
if (await import_promises3.default.realpath(
|
|
4142
|
+
await import_promises3.default.mkdir(import_node_path5.default.dirname(receiptPath), { recursive: true });
|
|
4143
|
+
if (await import_promises3.default.realpath(import_node_path5.default.dirname(receiptPath)) !== import_node_path5.default.dirname(receiptPath)) {
|
|
4035
4144
|
throw new Error("Cleanup receipt refuses symlinked directories");
|
|
4036
4145
|
}
|
|
4037
4146
|
const lock = await import_promises3.default.open(`${receiptPath}.lock`, "wx");
|
|
@@ -4077,17 +4186,17 @@ var createResearchRetentionInventory = async (projectRoot, directory, spec, stat
|
|
|
4077
4186
|
const permanentArtifacts = [];
|
|
4078
4187
|
for (const [role, file] of [
|
|
4079
4188
|
["note", notePath],
|
|
4080
|
-
["metrics",
|
|
4081
|
-
["candidates",
|
|
4082
|
-
["candidates",
|
|
4083
|
-
["ledger",
|
|
4084
|
-
["chart",
|
|
4189
|
+
["metrics", import_node_path6.default.join(directory, "result.json")],
|
|
4190
|
+
["candidates", import_node_path6.default.join(directory, "03-freeze-gates/result.json")],
|
|
4191
|
+
["candidates", import_node_path6.default.join(directory, "resolved-spec.json")],
|
|
4192
|
+
["ledger", import_node_path6.default.join(directory, "05-freeze-primary/result.json")],
|
|
4193
|
+
["chart", import_node_path6.default.join(directory, "report.html")],
|
|
4085
4194
|
...[
|
|
4086
4195
|
"source.patch",
|
|
4087
4196
|
"source-baseline.tar",
|
|
4088
4197
|
"source-untracked.json",
|
|
4089
4198
|
"source-jev-models.json"
|
|
4090
|
-
].map((file2) => ["source",
|
|
4199
|
+
].map((file2) => ["source", import_node_path6.default.join(directory, file2)])
|
|
4091
4200
|
]) {
|
|
4092
4201
|
try {
|
|
4093
4202
|
permanentArtifacts.push({
|
|
@@ -4147,13 +4256,13 @@ var createResearchRetentionInventory = async (projectRoot, directory, spec, stat
|
|
|
4147
4256
|
};
|
|
4148
4257
|
var applyRetentionInventory = async (projectRoot, directory) => {
|
|
4149
4258
|
const inventory = await readJson(
|
|
4150
|
-
|
|
4259
|
+
import_node_path6.default.join(directory, "retention.json")
|
|
4151
4260
|
);
|
|
4152
|
-
const receipts =
|
|
4261
|
+
const receipts = import_node_path6.default.join(directory, "retention");
|
|
4153
4262
|
await import_promises4.default.mkdir(receipts, { recursive: true });
|
|
4154
4263
|
for (let index = 0; index < inventory.entries.length; index++) {
|
|
4155
4264
|
const entry = inventory.entries[index];
|
|
4156
|
-
const receiptPath =
|
|
4265
|
+
const receiptPath = import_node_path6.default.join(receipts, `${index}.json`);
|
|
4157
4266
|
let receipt;
|
|
4158
4267
|
try {
|
|
4159
4268
|
receipt = await readJson(receiptPath);
|
|
@@ -4189,13 +4298,13 @@ var applyRetentionInventory = async (projectRoot, directory) => {
|
|
|
4189
4298
|
entries: [entry],
|
|
4190
4299
|
receiptPath,
|
|
4191
4300
|
apply: true,
|
|
4192
|
-
protectedPaths: [
|
|
4301
|
+
protectedPaths: [import_node_path6.default.join(directory, "retention.json")]
|
|
4193
4302
|
});
|
|
4194
4303
|
}
|
|
4195
4304
|
return { status: "completed", files: inventory.entries.length };
|
|
4196
4305
|
};
|
|
4197
4306
|
var finishResearchRetention = async (projectRoot, directory) => {
|
|
4198
|
-
const statusPath =
|
|
4307
|
+
const statusPath = import_node_path6.default.join(directory, "retention-status.json");
|
|
4199
4308
|
try {
|
|
4200
4309
|
const result = await applyRetentionInventory(projectRoot, directory);
|
|
4201
4310
|
await writeJsonAtomic(statusPath, result);
|
|
@@ -4222,7 +4331,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4222
4331
|
const directory = researchDirectory(projectRoot, spec);
|
|
4223
4332
|
const lineage = await backend.lineage();
|
|
4224
4333
|
const state = await initializeResearchState(directory, spec, lineage);
|
|
4225
|
-
const statePath =
|
|
4334
|
+
const statePath = import_node_path7.default.join(directory, "state.json");
|
|
4226
4335
|
const elapsedBefore = state.elapsedMs ?? 0;
|
|
4227
4336
|
const activeStart = Date.now();
|
|
4228
4337
|
const elapsed = () => elapsedBefore + Date.now() - activeStart;
|
|
@@ -4232,7 +4341,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4232
4341
|
directory,
|
|
4233
4342
|
state,
|
|
4234
4343
|
conclusion: await readJson(
|
|
4235
|
-
|
|
4344
|
+
import_node_path7.default.join(directory, "result.json")
|
|
4236
4345
|
)
|
|
4237
4346
|
};
|
|
4238
4347
|
}
|
|
@@ -4242,13 +4351,13 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4242
4351
|
return writeJsonAtomic(statePath, state);
|
|
4243
4352
|
};
|
|
4244
4353
|
const event = async (stage2, status) => import_promises5.default.appendFile(
|
|
4245
|
-
|
|
4354
|
+
import_node_path7.default.join(directory, "events.jsonl"),
|
|
4246
4355
|
`${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), stage: stage2, status, specSha256: state.specSha256 })}
|
|
4247
4356
|
`
|
|
4248
4357
|
);
|
|
4249
4358
|
const stage = async (name, work) => {
|
|
4250
4359
|
const stageDirectory = await boundResearchPath(directory, name);
|
|
4251
|
-
const resultPath =
|
|
4360
|
+
const resultPath = import_node_path7.default.join(stageDirectory, "result.json");
|
|
4252
4361
|
if (state.stages[name]?.status === "completed")
|
|
4253
4362
|
return readJson(resultPath);
|
|
4254
4363
|
if (elapsed() > spec.budget.maxMinutes * 6e4)
|
|
@@ -4267,7 +4376,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4267
4376
|
await save();
|
|
4268
4377
|
await event(name, "started");
|
|
4269
4378
|
await import_promises5.default.writeFile(
|
|
4270
|
-
|
|
4379
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
4271
4380
|
buildStrategyResearchReport({ spec, state, diagnostics })
|
|
4272
4381
|
);
|
|
4273
4382
|
try {
|
|
@@ -4275,7 +4384,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4275
4384
|
await writeJsonAtomic(resultPath, result);
|
|
4276
4385
|
const artifacts = {};
|
|
4277
4386
|
for (const file of await import_promises5.default.readdir(stageDirectory)) {
|
|
4278
|
-
const full =
|
|
4387
|
+
const full = import_node_path7.default.join(stageDirectory, file);
|
|
4279
4388
|
if ((await import_promises5.default.stat(full)).isFile())
|
|
4280
4389
|
artifacts[`${name}/${file}`] = await sha256File(full);
|
|
4281
4390
|
}
|
|
@@ -4287,7 +4396,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4287
4396
|
"source-jev-models.json"
|
|
4288
4397
|
]) {
|
|
4289
4398
|
try {
|
|
4290
|
-
artifacts[file] = await sha256File(
|
|
4399
|
+
artifacts[file] = await sha256File(import_node_path7.default.join(directory, file));
|
|
4291
4400
|
} catch (error) {
|
|
4292
4401
|
if (error.code !== "ENOENT")
|
|
4293
4402
|
throw error;
|
|
@@ -4320,14 +4429,14 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4320
4429
|
let previousRunId;
|
|
4321
4430
|
try {
|
|
4322
4431
|
previousRunId = (await readJson(
|
|
4323
|
-
|
|
4432
|
+
import_node_path7.default.join(folder, "native-run.json")
|
|
4324
4433
|
)).runId;
|
|
4325
4434
|
} catch (error) {
|
|
4326
4435
|
if (error.code !== "ENOENT") throw error;
|
|
4327
4436
|
}
|
|
4328
4437
|
if (!previousRunId) {
|
|
4329
4438
|
try {
|
|
4330
|
-
if ((await import_promises5.default.stat(
|
|
4439
|
+
if ((await import_promises5.default.stat(import_node_path7.default.join(folder, "backtest.log"))).size)
|
|
4331
4440
|
throw new Error(
|
|
4332
4441
|
"Previous native attempt has no recorded run identity; inspect its log before another launch"
|
|
4333
4442
|
);
|
|
@@ -4348,7 +4457,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4348
4457
|
},
|
|
4349
4458
|
variant,
|
|
4350
4459
|
folder,
|
|
4351
|
-
async (runId) => writeJsonAtomic(
|
|
4460
|
+
async (runId) => writeJsonAtomic(import_node_path7.default.join(folder, "native-run.json"), { runId }),
|
|
4352
4461
|
previousRunId,
|
|
4353
4462
|
confirmation
|
|
4354
4463
|
);
|
|
@@ -4363,15 +4472,15 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4363
4472
|
try {
|
|
4364
4473
|
const inventory = await stage("01-preflight", async () => {
|
|
4365
4474
|
const prior = [];
|
|
4366
|
-
const root =
|
|
4475
|
+
const root = import_node_path7.default.dirname(directory);
|
|
4367
4476
|
for (const id of await import_promises5.default.readdir(root)) {
|
|
4368
4477
|
if (id === spec.core.researchId || id.startsWith(".")) continue;
|
|
4369
4478
|
try {
|
|
4370
4479
|
const previous = await readJson(
|
|
4371
|
-
|
|
4480
|
+
import_node_path7.default.join(root, id, "spec.json")
|
|
4372
4481
|
);
|
|
4373
4482
|
const previousState = await readJson(
|
|
4374
|
-
|
|
4483
|
+
import_node_path7.default.join(root, id, "state.json")
|
|
4375
4484
|
);
|
|
4376
4485
|
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);
|
|
4377
4486
|
if (overlap && previousState.holdoutOpenedAt)
|
|
@@ -4397,7 +4506,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4397
4506
|
let previous;
|
|
4398
4507
|
try {
|
|
4399
4508
|
previous = (await readJson(
|
|
4400
|
-
|
|
4509
|
+
import_node_path7.default.join(folder, "native-run.json")
|
|
4401
4510
|
)).runId;
|
|
4402
4511
|
} catch (error) {
|
|
4403
4512
|
if (error.code !== "ENOENT")
|
|
@@ -4407,7 +4516,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4407
4516
|
spec,
|
|
4408
4517
|
control2,
|
|
4409
4518
|
folder,
|
|
4410
|
-
async (runId) => writeJsonAtomic(
|
|
4519
|
+
async (runId) => writeJsonAtomic(import_node_path7.default.join(folder, "native-run.json"), {
|
|
4411
4520
|
runId
|
|
4412
4521
|
}),
|
|
4413
4522
|
previous
|
|
@@ -4421,7 +4530,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4421
4530
|
);
|
|
4422
4531
|
spec = { ...spec, testSince: partition.testSince };
|
|
4423
4532
|
}
|
|
4424
|
-
await writeJsonAtomic(
|
|
4533
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "resolved-spec.json"), spec);
|
|
4425
4534
|
let gates = [];
|
|
4426
4535
|
let primaryId = null;
|
|
4427
4536
|
let frozenSelection;
|
|
@@ -4480,10 +4589,10 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4480
4589
|
core: { ...spec.core, researchId: spec.frozenFrom }
|
|
4481
4590
|
});
|
|
4482
4591
|
const parentState = await readJson(
|
|
4483
|
-
|
|
4592
|
+
import_node_path7.default.join(parentDirectory, "state.json")
|
|
4484
4593
|
);
|
|
4485
4594
|
const parentSpec = await readJson(
|
|
4486
|
-
|
|
4595
|
+
import_node_path7.default.join(parentDirectory, "spec.json")
|
|
4487
4596
|
);
|
|
4488
4597
|
const { verifyCompletedResearch: verifyCompletedResearch2 } = await Promise.resolve().then(() => (init_io2(), io_exports));
|
|
4489
4598
|
await verifyCompletedResearch2(parentDirectory, parentState);
|
|
@@ -4510,10 +4619,10 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4510
4619
|
"Frozen revalidation requires complete, unchanged rules/runtime and a strictly new period"
|
|
4511
4620
|
);
|
|
4512
4621
|
gates = await readJson(
|
|
4513
|
-
|
|
4622
|
+
import_node_path7.default.join(parentDirectory, "03-freeze-gates/result.json")
|
|
4514
4623
|
);
|
|
4515
4624
|
frozenSelection = await readJson(
|
|
4516
|
-
|
|
4625
|
+
import_node_path7.default.join(parentDirectory, "05-freeze-primary/result.json")
|
|
4517
4626
|
);
|
|
4518
4627
|
if (frozenSelection.schema !== "tradejs-research-selection/v1" || !Array.isArray(frozenSelection.compositions))
|
|
4519
4628
|
throw new Error(
|
|
@@ -4642,7 +4751,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4642
4751
|
`06-raw-metrics-${variant.id}`,
|
|
4643
4752
|
async (folder) => {
|
|
4644
4753
|
const resolved = spec.frozenFrom ? (await run(spec, variant, `06-raw-revalidation-${variant.id}`)).variant : (await readJson(
|
|
4645
|
-
|
|
4754
|
+
import_node_path7.default.join(directory, `02-raw-${variant.id}`, "result.json")
|
|
4646
4755
|
)).variant;
|
|
4647
4756
|
const dataset = await backend.loadDataset(
|
|
4648
4757
|
spec,
|
|
@@ -4819,7 +4928,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4819
4928
|
for (const name of Object.keys(state.stages)) {
|
|
4820
4929
|
try {
|
|
4821
4930
|
const result = await readJson(
|
|
4822
|
-
|
|
4931
|
+
import_node_path7.default.join(directory, name, "result.json")
|
|
4823
4932
|
);
|
|
4824
4933
|
if (result?.variant)
|
|
4825
4934
|
executions.push({ stage: name, ...result.variant });
|
|
@@ -4827,7 +4936,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4827
4936
|
if (error.code !== "ENOENT") throw error;
|
|
4828
4937
|
}
|
|
4829
4938
|
}
|
|
4830
|
-
await writeJsonAtomic(
|
|
4939
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "result.json"), {
|
|
4831
4940
|
...conclusion,
|
|
4832
4941
|
executions,
|
|
4833
4942
|
rawCore: Object.entries(rawReports).map(([id, windows]) => ({
|
|
@@ -4841,7 +4950,7 @@ var runStrategyResearch = async (parameters) => {
|
|
|
4841
4950
|
delete state.error;
|
|
4842
4951
|
await save();
|
|
4843
4952
|
await import_promises5.default.writeFile(
|
|
4844
|
-
|
|
4953
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
4845
4954
|
buildStrategyResearchReport({
|
|
4846
4955
|
spec,
|
|
4847
4956
|
state,
|
|
@@ -4929,7 +5038,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4929
5038
|
"Compact permanent note exceeds 8 MiB; archive source separately, never truncate metrics"
|
|
4930
5039
|
);
|
|
4931
5040
|
await import_promises5.default.writeFile(
|
|
4932
|
-
|
|
5041
|
+
import_node_path7.default.join(
|
|
4933
5042
|
noteDirectory,
|
|
4934
5043
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4935
5044
|
),
|
|
@@ -4938,7 +5047,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4938
5047
|
).catch(async (error) => {
|
|
4939
5048
|
if (error.code !== "EEXIST") throw error;
|
|
4940
5049
|
const existing = await import_promises5.default.readFile(
|
|
4941
|
-
|
|
5050
|
+
import_node_path7.default.join(
|
|
4942
5051
|
noteDirectory,
|
|
4943
5052
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4944
5053
|
),
|
|
@@ -4950,19 +5059,19 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4950
5059
|
);
|
|
4951
5060
|
});
|
|
4952
5061
|
await writeJsonAtomic(
|
|
4953
|
-
|
|
5062
|
+
import_node_path7.default.join(directory, "retention.json"),
|
|
4954
5063
|
await createResearchRetentionInventory(
|
|
4955
5064
|
projectRoot,
|
|
4956
5065
|
directory,
|
|
4957
5066
|
spec,
|
|
4958
5067
|
state,
|
|
4959
|
-
|
|
5068
|
+
import_node_path7.default.join(
|
|
4960
5069
|
noteDirectory,
|
|
4961
5070
|
`${spec.core.createdAt.slice(0, 10)}-${spec.core.researchId}.md`
|
|
4962
5071
|
)
|
|
4963
5072
|
)
|
|
4964
5073
|
);
|
|
4965
|
-
await writeJsonAtomic(
|
|
5074
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "manifest.json"), {
|
|
4966
5075
|
schema: "tradejs-strategy-research-manifest/v1",
|
|
4967
5076
|
specSha256: state.specSha256,
|
|
4968
5077
|
artifacts: Object.fromEntries(
|
|
@@ -4976,7 +5085,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4976
5085
|
"retention.json"
|
|
4977
5086
|
].map(async (file) => [
|
|
4978
5087
|
file,
|
|
4979
|
-
await sha256File(
|
|
5088
|
+
await sha256File(import_node_path7.default.join(directory, file))
|
|
4980
5089
|
])
|
|
4981
5090
|
)
|
|
4982
5091
|
)
|
|
@@ -4989,7 +5098,7 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
4989
5098
|
);
|
|
4990
5099
|
}
|
|
4991
5100
|
parameters.onProgress?.(
|
|
4992
|
-
`\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${
|
|
5101
|
+
`\u0418\u0442\u043E\u0433: ${conclusion.status}. \u041E\u0442\u0447\u0451\u0442: ${import_node_path7.default.join(directory, "report.html")}`
|
|
4993
5102
|
);
|
|
4994
5103
|
return { directory, state, conclusion };
|
|
4995
5104
|
} catch (error) {
|
|
@@ -5010,9 +5119,9 @@ ${conclusion.nextAction} Current-snapshot universe; no deployment authorization.
|
|
|
5010
5119
|
frozenGates: 0
|
|
5011
5120
|
}
|
|
5012
5121
|
};
|
|
5013
|
-
await writeJsonAtomic(
|
|
5122
|
+
await writeJsonAtomic(import_node_path7.default.join(directory, "result.json"), conclusion);
|
|
5014
5123
|
await import_promises5.default.writeFile(
|
|
5015
|
-
|
|
5124
|
+
import_node_path7.default.join(directory, "report.html"),
|
|
5016
5125
|
buildStrategyResearchReport({ spec, state, conclusion, diagnostics })
|
|
5017
5126
|
);
|
|
5018
5127
|
throw error;
|
|
@@ -5036,9 +5145,9 @@ var import_connectors = require("@tradejs/node/connectors");
|
|
|
5036
5145
|
|
|
5037
5146
|
// src/lib/coreResearch/dataset.ts
|
|
5038
5147
|
var import_node_crypto5 = require("crypto");
|
|
5039
|
-
var
|
|
5040
|
-
var
|
|
5041
|
-
var
|
|
5148
|
+
var import_node_fs3 = require("fs");
|
|
5149
|
+
var import_node_path8 = __toESM(require("path"));
|
|
5150
|
+
var import_node_readline2 = __toESM(require("readline"));
|
|
5042
5151
|
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
5043
5152
|
var finiteNumber = (value, field) => {
|
|
5044
5153
|
const numeric = Number(value);
|
|
@@ -5248,11 +5357,11 @@ var readCoreResearchVariant = async (variant) => {
|
|
|
5248
5357
|
const seen = /* @__PURE__ */ new Map();
|
|
5249
5358
|
let duplicateRowsDropped = 0;
|
|
5250
5359
|
for (const inputPath of variant.files) {
|
|
5251
|
-
const filePath =
|
|
5252
|
-
const input = (0,
|
|
5360
|
+
const filePath = import_node_path8.default.resolve(inputPath);
|
|
5361
|
+
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
5253
5362
|
const hash2 = (0, import_node_crypto5.createHash)("sha256");
|
|
5254
5363
|
input.on("data", (chunk) => hash2.update(chunk));
|
|
5255
|
-
const lines =
|
|
5364
|
+
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
5256
5365
|
const fileTrades = [];
|
|
5257
5366
|
let lineNumber = 0;
|
|
5258
5367
|
let rows = 0;
|
|
@@ -5537,7 +5646,7 @@ init_io2();
|
|
|
5537
5646
|
var import_node_child_process2 = require("child_process");
|
|
5538
5647
|
var import_node_crypto8 = require("crypto");
|
|
5539
5648
|
var import_promises7 = __toESM(require("fs/promises"));
|
|
5540
|
-
var
|
|
5649
|
+
var import_node_path10 = __toESM(require("path"));
|
|
5541
5650
|
|
|
5542
5651
|
// src/lib/aiTrainMetrics.ts
|
|
5543
5652
|
var DAY_MS3 = 24 * 60 * 60 * 1e3;
|
|
@@ -5550,7 +5659,7 @@ var import_types2 = require("@tradejs/types");
|
|
|
5550
5659
|
var import_node_crypto7 = require("crypto");
|
|
5551
5660
|
var import_node_module = require("module");
|
|
5552
5661
|
var import_promises6 = __toESM(require("fs/promises"));
|
|
5553
|
-
var
|
|
5662
|
+
var import_node_path9 = __toESM(require("path"));
|
|
5554
5663
|
|
|
5555
5664
|
// src/lib/aiTrainResearch.ts
|
|
5556
5665
|
var DAY_MS4 = 24 * 60 * 60 * 1e3;
|
|
@@ -5601,81 +5710,7 @@ var fingerprintResearchContextEnvironment = (env = process.env) => fingerprintRe
|
|
|
5601
5710
|
// src/lib/strategyResearch/native.ts
|
|
5602
5711
|
var import_data = require("@tradejs/core/data");
|
|
5603
5712
|
var import_coreResearch = require("@tradejs/infra/coreResearch");
|
|
5604
|
-
|
|
5605
|
-
// src/lib/coreResearch/trace.ts
|
|
5606
|
-
var import_node_fs3 = require("fs");
|
|
5607
|
-
var import_node_readline2 = __toESM(require("readline"));
|
|
5608
|
-
var import_node_path10 = __toESM(require("path"));
|
|
5609
|
-
var summarizeCoreResearchTrace = async (filePaths = []) => {
|
|
5610
|
-
const events = /* @__PURE__ */ Object.create(null);
|
|
5611
|
-
const skipCounts = /* @__PURE__ */ Object.create(null);
|
|
5612
|
-
const exitCodes = /* @__PURE__ */ Object.create(null);
|
|
5613
|
-
const policyRejections = {};
|
|
5614
|
-
const policyExamples = [];
|
|
5615
|
-
for (const inputPath of filePaths) {
|
|
5616
|
-
const filePath = import_node_path10.default.resolve(inputPath);
|
|
5617
|
-
const input = (0, import_node_fs3.createReadStream)(filePath);
|
|
5618
|
-
const lines = import_node_readline2.default.createInterface({ input, crlfDelay: Infinity });
|
|
5619
|
-
let index = -1;
|
|
5620
|
-
try {
|
|
5621
|
-
for await (const line of lines) {
|
|
5622
|
-
index++;
|
|
5623
|
-
if (!line.trim()) continue;
|
|
5624
|
-
let event;
|
|
5625
|
-
try {
|
|
5626
|
-
event = JSON.parse(line);
|
|
5627
|
-
} catch (error) {
|
|
5628
|
-
throw new Error(
|
|
5629
|
-
`${filePath}:${index + 1} contains invalid trace JSON: ${String(error)}`
|
|
5630
|
-
);
|
|
5631
|
-
}
|
|
5632
|
-
events[event.event] = (events[event.event] ?? 0) + 1;
|
|
5633
|
-
if (event.event === "skip_summary") {
|
|
5634
|
-
for (const [reason, count] of Object.entries(event.skipCounts)) {
|
|
5635
|
-
skipCounts[reason] = (skipCounts[reason] ?? 0) + count;
|
|
5636
|
-
}
|
|
5637
|
-
}
|
|
5638
|
-
if (event.event === "position_exited" && event.exitCode) {
|
|
5639
|
-
exitCodes[event.exitCode] = (exitCodes[event.exitCode] ?? 0) + 1;
|
|
5640
|
-
}
|
|
5641
|
-
if ("researchEntryDecision" in event && event.researchEntryDecision && !event.researchEntryDecision.allowed) {
|
|
5642
|
-
const reason = event.researchEntryDecision.reason;
|
|
5643
|
-
policyRejections[reason] = (policyRejections[reason] ?? 0) + 1;
|
|
5644
|
-
if (policyExamples.length < 20)
|
|
5645
|
-
policyExamples.push({
|
|
5646
|
-
timestamp: event.timestamp,
|
|
5647
|
-
symbol: event.symbol,
|
|
5648
|
-
decision: event.researchEntryDecision
|
|
5649
|
-
});
|
|
5650
|
-
}
|
|
5651
|
-
}
|
|
5652
|
-
} finally {
|
|
5653
|
-
lines.close();
|
|
5654
|
-
input.destroy();
|
|
5655
|
-
}
|
|
5656
|
-
}
|
|
5657
|
-
return {
|
|
5658
|
-
events: Object.fromEntries(Object.entries(events).sort()),
|
|
5659
|
-
skipCounts: Object.fromEntries(
|
|
5660
|
-
Object.entries(skipCounts).sort(
|
|
5661
|
-
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
5662
|
-
)
|
|
5663
|
-
),
|
|
5664
|
-
exitCodes: Object.fromEntries(
|
|
5665
|
-
Object.entries(exitCodes).sort(
|
|
5666
|
-
([leftKey, leftValue], [rightKey, rightValue]) => rightValue - leftValue || (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0)
|
|
5667
|
-
)
|
|
5668
|
-
),
|
|
5669
|
-
...policyExamples.length ? {
|
|
5670
|
-
researchPolicy: {
|
|
5671
|
-
rejections: policyRejections,
|
|
5672
|
-
examples: policyExamples
|
|
5673
|
-
}
|
|
5674
|
-
} : {}
|
|
5675
|
-
};
|
|
5676
|
-
};
|
|
5677
|
-
|
|
5678
|
-
// src/lib/strategyResearch/native.ts
|
|
5713
|
+
init_trace();
|
|
5679
5714
|
var import_jev4 = require("@tradejs/core/jev");
|
|
5680
5715
|
|
|
5681
5716
|
// src/lib/backtest/jevOptions.ts
|
|
@@ -6649,6 +6684,7 @@ init_io();
|
|
|
6649
6684
|
var import_node_crypto9 = require("crypto");
|
|
6650
6685
|
|
|
6651
6686
|
// src/lib/coreResearch/orchestrator.ts
|
|
6687
|
+
init_trace();
|
|
6652
6688
|
init_types();
|
|
6653
6689
|
var createCoreResearchSpecTemplate = (params) => {
|
|
6654
6690
|
const rootDir = import_node_path15.default.relative(
|