@tradejs/cli 3.1.29-beta.290 → 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 +12283 -10394
- package/dist/lib/aiPocketSearch.js +37 -3
- package/dist/lib/aiTrainDataset.js +1 -0
- package/dist/lib/aiTrainEvaluationDump.js +7 -2
- package/dist/lib/aiTrainResearch.js +11 -7
- package/dist/lib/coreResearch.js +273 -119
- package/dist/lib/researchMetricSnapshot.js +74 -0
- package/dist/lib/researchVisuals.js +931 -0
- package/dist/lib/strategyRelease.js +8 -2
- package/dist/lib/strategyResearch.js +334 -199
- package/dist/lib/tickerProfiles.js +76 -0
- package/dist/scripts/aiPocketSearch.js +2959 -2610
- package/dist/scripts/aiTrain.js +29 -17
- package/dist/scripts/coreResearch.js +275 -119
- package/dist/scripts/replay.js +533 -115
- package/dist/scripts/replayRunner.js +533 -115
- package/dist/scripts/researchVisuals.js +976 -0
- package/dist/scripts/strategyRelease.js +59 -7
- package/dist/scripts/strategyResearch.js +339 -203
- package/dist/scripts/tickerProfiles.js +114 -0
- package/package.json +8 -7
|
@@ -42,8 +42,40 @@ var import_chalk = __toESM(require("chalk"));
|
|
|
42
42
|
|
|
43
43
|
// src/lib/strategyRelease/researchRetention.ts
|
|
44
44
|
var import_promises = __toESM(require("fs/promises"));
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
// src/lib/researchMetricSnapshot.ts
|
|
46
47
|
var import_node_crypto = require("crypto");
|
|
48
|
+
var import_node_zlib = require("zlib");
|
|
49
|
+
var MAX_BYTES = 256 * 1024 * 1024;
|
|
50
|
+
var hash = (bytes) => (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
51
|
+
var validatePermanentResearchMetrics = (value) => {
|
|
52
|
+
if (!value || typeof value !== "object") return;
|
|
53
|
+
for (const [key, child] of Object.entries(value)) {
|
|
54
|
+
if (["matchedPairs", "tradeRows", "allProjectedLeaves"].includes(key) && Array.isArray(child) && child.length)
|
|
55
|
+
throw new Error(`Temporary payload ${key} is not a permanent metric`);
|
|
56
|
+
if (key === "trades" && Array.isArray(child) && child.some(
|
|
57
|
+
(row) => row && typeof row === "object" && ("signalId" in row || "entryTimestamp" in row)
|
|
58
|
+
))
|
|
59
|
+
throw new Error("Temporary trade records are not permanent metrics");
|
|
60
|
+
validatePermanentResearchMetrics(child);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var decodeResearchMetricSnapshot = (snapshot) => {
|
|
64
|
+
if (!snapshot || typeof snapshot !== "object" || !("schema" in snapshot) || snapshot.schema !== "tradejs-metric-snapshot/v1" || !("encoding" in snapshot) || snapshot.encoding !== "gzip+base64" || !("decodedBytes" in snapshot) || typeof snapshot.decodedBytes !== "number" || !Number.isSafeInteger(snapshot.decodedBytes) || snapshot.decodedBytes <= 0 || snapshot.decodedBytes > MAX_BYTES || !("sha256" in snapshot) || typeof snapshot.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(snapshot.sha256) || !("payload" in snapshot) || typeof snapshot.payload !== "string")
|
|
65
|
+
throw new Error("Invalid metric snapshot envelope");
|
|
66
|
+
const bytes = (0, import_node_zlib.gunzipSync)(Buffer.from(snapshot.payload, "base64"), {
|
|
67
|
+
maxOutputLength: snapshot.decodedBytes
|
|
68
|
+
});
|
|
69
|
+
if (bytes.length !== snapshot.decodedBytes || hash(bytes) !== snapshot.sha256)
|
|
70
|
+
throw new Error("Metric snapshot checksum or size mismatch");
|
|
71
|
+
const metrics = JSON.parse(bytes.toString("utf8"));
|
|
72
|
+
validatePermanentResearchMetrics(metrics);
|
|
73
|
+
return metrics;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/lib/strategyRelease/researchRetention.ts
|
|
77
|
+
var import_node_path2 = __toESM(require("path"));
|
|
78
|
+
var import_node_crypto2 = require("crypto");
|
|
47
79
|
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
48
80
|
|
|
49
81
|
// src/lib/strategyRelease/researchFileConsumers.ts
|
|
@@ -235,7 +267,7 @@ var mapFiles = async (entries, visit) => {
|
|
|
235
267
|
if (worker.status === "rejected") throw worker.reason;
|
|
236
268
|
return results;
|
|
237
269
|
};
|
|
238
|
-
var fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0,
|
|
270
|
+
var fileSha256 = async (file, bytes) => bytes <= 1024 * 1024 ? (0, import_node_crypto2.createHash)("sha256").update(await import_promises.default.readFile(file)).digest("hex") : (0, import_strategyReleaseEvidence.strategyEvidenceFileSha256)(file);
|
|
239
271
|
var inside = (root, file) => {
|
|
240
272
|
const relative = import_node_path2.default.relative(root, file);
|
|
241
273
|
return relative !== "" && !relative.startsWith(`..${import_node_path2.default.sep}`) && relative !== ".." && !import_node_path2.default.isAbsolute(relative);
|
|
@@ -279,13 +311,27 @@ var applyResearchRetention = async (options) => {
|
|
|
279
311
|
const header = Buffer.alloc(4096);
|
|
280
312
|
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
281
313
|
const frontmatter = header.subarray(0, bytesRead).toString("utf8").match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
282
|
-
if (!frontmatter || !/^schema:\s*tradejs-research\/
|
|
314
|
+
if (!frontmatter || !/^schema:\s*tradejs-research\/v[12]\s*$/m.test(frontmatter[1]) || !(retired ? /^reproduction:\s*(?:complete|partial|blocked|legacy-partial)\s*$/m.test(
|
|
283
315
|
frontmatter[1]
|
|
284
316
|
) : /^reproduction:\s*complete\s*$/m.test(frontmatter[1]))) {
|
|
285
317
|
throw new Error(
|
|
286
318
|
`Research note must have reproduction: complete: ${file}`
|
|
287
319
|
);
|
|
288
320
|
}
|
|
321
|
+
if (!retired && /^schema:\s*tradejs-research\/v2\s*$/m.test(frontmatter[1])) {
|
|
322
|
+
if ((await import_promises.default.stat(file)).size > 8 * 1024 * 1024)
|
|
323
|
+
throw new Error("Compact permanent note exceeds 8 MiB");
|
|
324
|
+
const content = await import_promises.default.readFile(file, "utf8");
|
|
325
|
+
const section = content.split("## Metrics snapshot (machine-readable)")[1]?.split("## Reported metrics")[0] ?? "";
|
|
326
|
+
const blocks = [
|
|
327
|
+
...section.matchAll(/```json\r?\n([\s\S]*?)\r?\n```/g)
|
|
328
|
+
];
|
|
329
|
+
if (blocks.length !== 1)
|
|
330
|
+
throw new Error(
|
|
331
|
+
"Complete v2 note needs one verified metric snapshot"
|
|
332
|
+
);
|
|
333
|
+
decodeResearchMetricSnapshot(JSON.parse(blocks[0][1]));
|
|
334
|
+
}
|
|
289
335
|
} finally {
|
|
290
336
|
await handle.close();
|
|
291
337
|
}
|
|
@@ -369,7 +415,7 @@ var applyResearchRetention = async (options) => {
|
|
|
369
415
|
};
|
|
370
416
|
|
|
371
417
|
// src/lib/strategyRelease.ts
|
|
372
|
-
var
|
|
418
|
+
var import_node_crypto3 = require("crypto");
|
|
373
419
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
374
420
|
var import_node_path3 = __toESM(require("path"));
|
|
375
421
|
var import_types2 = require("@tradejs/types");
|
|
@@ -1539,7 +1585,7 @@ var verifyCompletedCoreResearchBundle = async ({
|
|
|
1539
1585
|
const artifactHashes = manifest.artifactHashes != null && typeof manifest.artifactHashes === "object" && !Array.isArray(manifest.artifactHashes) ? manifest.artifactHashes : null;
|
|
1540
1586
|
const parsedSpec = JSON.parse(specBytes.toString("utf8"));
|
|
1541
1587
|
assert2(
|
|
1542
|
-
manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0,
|
|
1588
|
+
manifest.schema === "tradejs-core-research-manifest/v1" && manifest.status === "completed" && manifest.researchId === researchId && manifest.specSha256 === specSha256 && artifactHashes?.["result.json"] === resultSha256 && (0, import_node_crypto3.createHash)("sha256").update(canonicalStrategyReleaseJson(parsedSpec)).digest("hex") === specSha256,
|
|
1543
1589
|
"core result is not bound by its completed core research manifest"
|
|
1544
1590
|
);
|
|
1545
1591
|
for (const [relativePath, expectedSha256] of Object.entries(
|
|
@@ -1587,12 +1633,18 @@ async function collectReleaseEvidenceReferences(references) {
|
|
|
1587
1633
|
}
|
|
1588
1634
|
const nested = (value) => value != null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
1589
1635
|
const array = (value) => Array.isArray(value) ? value : [];
|
|
1590
|
-
const semanticallyValid = reference.kind === "core_research" ?
|
|
1636
|
+
const semanticallyValid = reference.kind === "core_research" ? [
|
|
1637
|
+
"tradejs-core-research-result/v1",
|
|
1638
|
+
"tradejs-core-research-result/v2"
|
|
1639
|
+
].includes(String(artifact.schema)) || artifact.schema === "tradejs-core-research-manifest/v1" && artifact.status === "completed" : reference.kind === "ai_gate" ? nested(artifact.run)?.mode === "local-deterministic" && nested(artifact.research)?.lineage != null && nested(artifact.outcome) != null : reference.kind === "runtime_parity" ? artifact.reportType === "replay-runtime-evidence" && nested(nested(artifact.replay)?.runtimeComparison) != null : reference.kind === "execution_calibration" ? artifact.reportType === "execution-calibration" && nested(artifact.summary) != null : reference.kind === "runtime_evidence" ? artifact.reportType === "runtime-evidence" : artifact.reportType === "runtime-scorecard";
|
|
1591
1640
|
assert2(
|
|
1592
1641
|
semanticallyValid,
|
|
1593
1642
|
`evidence ${reference.artifactId} does not match ${reference.kind}`
|
|
1594
1643
|
);
|
|
1595
|
-
if (reference.kind === "core_research" &&
|
|
1644
|
+
if (reference.kind === "core_research" && [
|
|
1645
|
+
"tradejs-core-research-result/v1",
|
|
1646
|
+
"tradejs-core-research-result/v2"
|
|
1647
|
+
].includes(String(artifact.schema))) {
|
|
1596
1648
|
await verifyCompletedCoreResearchBundle({
|
|
1597
1649
|
artifact,
|
|
1598
1650
|
resultPath: reference.path,
|