@tradejs/cli 3.1.29-beta.261 → 3.1.29-beta.263
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/README.md +47 -8
- package/dist/cli.js +990 -1448
- package/dist/lib/aiPocketSearch.js +16 -0
- package/dist/lib/aiPocketSearchCli.js +3 -3
- package/dist/lib/jevMicroReferences.js +73 -0
- package/dist/lib/jevResearch.js +11 -0
- package/dist/lib/runtimeEvidenceArtifacts.js +3 -416
- package/dist/lib/runtimeEvidenceCompositionSnapshots.js +42 -211
- package/dist/lib/runtimeEvidenceCompositions.js +33 -310
- package/dist/lib/runtimeEvidenceDeployment.js +3 -315
- package/dist/lib/runtimeEvidenceProducer.js +3 -77
- package/dist/lib/runtimeEvidenceSync.js +32 -299
- package/dist/lib/runtimeFeedbackArtifacts.js +3 -545
- package/dist/lib/runtimeFeedbackNotification.js +7 -195
- package/dist/lib/runtimeFeedbackReplay.js +26 -525
- package/dist/lib/runtimeFeedbackSync.js +26 -219
- package/dist/lib/runtimeScorecard.js +5 -163
- package/dist/scripts/aiPocketSearch.js +101 -23
- package/dist/scripts/backtest.js +10 -1
- package/dist/scripts/jev.js +11 -0
- package/dist/scripts/mcpWorker.js +273 -0
- package/dist/scripts/replay.js +14 -250
- package/dist/scripts/replayRunner.js +14 -250
- package/dist/scripts/runtimeEvidence.js +47 -597
- package/dist/scripts/runtimeEvidenceSync.js +29 -296
- package/dist/scripts/runtimeFeedbackNotify.js +10 -188
- package/dist/scripts/runtimeFeedbackReplay.js +29 -528
- package/dist/scripts/runtimeFeedbackSync.js +28 -221
- package/dist/scripts/runtimeScorecard.js +88 -503
- package/dist/scripts/signals.js +55 -224
- package/dist/scripts/signalsDaemon.js +55 -224
- package/package.json +9 -8
|
@@ -17,6 +17,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
}
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
21
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
22
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
23
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -34,453 +35,37 @@ __export(runtimeScorecard_exports, {
|
|
|
34
35
|
runtimeScorecard: () => runtimeScorecard
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(runtimeScorecard_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
38
|
+
var import_promises3 = __toESM(require("fs/promises"));
|
|
39
|
+
var import_node_crypto3 = require("crypto");
|
|
40
|
+
var import_node_path3 = __toESM(require("path"));
|
|
40
41
|
var import_args = __toESM(require("args"));
|
|
41
42
|
var import_chalk = __toESM(require("chalk"));
|
|
42
43
|
|
|
43
44
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
var import_node_path = __toESM(require("path"));
|
|
47
|
-
|
|
48
|
-
// src/lib/runtimeEvidenceDeployment.ts
|
|
49
|
-
var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
50
|
-
var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
51
|
-
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
52
|
-
var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
53
|
-
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
54
|
-
);
|
|
55
|
-
var INTERVALS = /* @__PURE__ */ new Set([
|
|
56
|
-
"1",
|
|
57
|
-
"3",
|
|
58
|
-
"5",
|
|
59
|
-
"15",
|
|
60
|
-
"30",
|
|
61
|
-
"60",
|
|
62
|
-
"120",
|
|
63
|
-
"240",
|
|
64
|
-
"360",
|
|
65
|
-
"720",
|
|
66
|
-
"D",
|
|
67
|
-
"W",
|
|
68
|
-
"M"
|
|
69
|
-
]);
|
|
70
|
-
var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
71
|
-
var isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
|
|
72
|
-
var samePackageVersions = (left, right) => {
|
|
73
|
-
if (!left || !right) return false;
|
|
74
|
-
const leftEntries = Object.entries(left).sort(
|
|
75
|
-
([a], [b]) => a.localeCompare(b)
|
|
76
|
-
);
|
|
77
|
-
const rightEntries = Object.entries(right).sort(
|
|
78
|
-
([a], [b]) => a.localeCompare(b)
|
|
79
|
-
);
|
|
80
|
-
return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
|
|
81
|
-
};
|
|
82
|
-
var runtimeLineageMatchesStrategySnapshot = ({
|
|
83
|
-
lineage,
|
|
84
|
-
deployment,
|
|
85
|
-
strategy
|
|
86
|
-
}) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
|
|
87
|
-
lineage.strategyDependencyVersions,
|
|
88
|
-
strategy.strategyDependencyVersions
|
|
89
|
-
);
|
|
90
|
-
var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
91
|
-
if (!isRecord(value) || value.schemaVersion !== 2 || !isNonEmptyString(value.id) || !isNonEmptyString(value.deploymentCompositionId) || !/^dc1:[a-f0-9]{16}$/.test(value.deploymentCompositionId) || !isNonEmptyString(value.label) || !isNonEmptyString(value.connectorName) || !isNonEmptyString(value.provider) || !isNonEmptyString(value.accountId) || typeof value.enabled !== "boolean" || !Array.isArray(value.strategies)) {
|
|
92
|
-
throw new Error(
|
|
93
|
-
"Runtime evidence deployment snapshot is missing or invalid"
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
const strategies = value.strategies.map((candidate) => {
|
|
97
|
-
if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !isNonEmptyString(candidate.strategyRevision) || !/^sr1:[a-f0-9]{16}$/.test(candidate.strategyRevision) || typeof candidate.enabled !== "boolean" || !["active", "entries_paused"].includes(String(candidate.controlState)) || !INTERVALS.has(String(candidate.interval)) || !UNIVERSES.has(String(candidate.universe)) || !isNonEmptyString(candidate.strategyPackage) || !isNonEmptyString(candidate.strategyPackageVersion) || !isPackageVersionMap(candidate.strategyDependencyVersions) || !isNonEmptyString(candidate.runtimePackageVersion) || !isRecord(candidate.strategyConfig) || !isRuntimeStrategySelection(candidate.selection)) {
|
|
98
|
-
throw new Error(
|
|
99
|
-
"Runtime evidence deployment strategy snapshot is invalid"
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
103
|
-
throw new Error(
|
|
104
|
-
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
108
|
-
throw new Error(
|
|
109
|
-
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
return candidate;
|
|
113
|
-
});
|
|
114
|
-
const identities = /* @__PURE__ */ new Set();
|
|
115
|
-
for (const strategy of strategies) {
|
|
116
|
-
if (identities.has(strategy.strategyName)) {
|
|
117
|
-
throw new Error(
|
|
118
|
-
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
identities.add(strategy.strategyName);
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
...value,
|
|
125
|
-
strategies
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
129
|
-
var unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
130
|
-
const record = isRecord(candidate) ? candidate : null;
|
|
131
|
-
const nested = record && isRecord(record[field]) ? record[field] : null;
|
|
132
|
-
return nested ?? record;
|
|
133
|
-
}).filter((record) => record != null);
|
|
134
|
-
var assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
135
|
-
if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
136
|
-
throw new Error("Invalid runtime evidence artifact");
|
|
137
|
-
}
|
|
138
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
139
|
-
artifact.deployment
|
|
140
|
-
);
|
|
141
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
142
|
-
if (activeStrategies.length === 0) {
|
|
143
|
-
throw new Error("Runtime evidence deployment has no enabled strategies");
|
|
144
|
-
}
|
|
145
|
-
const runtime = isRecord(artifact.runtime) ? artifact.runtime : null;
|
|
146
|
-
if (!runtime) {
|
|
147
|
-
throw new Error("Runtime evidence payload is missing");
|
|
148
|
-
}
|
|
149
|
-
if ("strategyConfigs" in runtime) {
|
|
150
|
-
throw new Error(
|
|
151
|
-
"Runtime evidence payload contains removed strategyConfigs data"
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
if ("evaluationStatsBuckets" in runtime) {
|
|
155
|
-
throw new Error(
|
|
156
|
-
"Runtime evidence payload contains removed lineage-less evaluationStatsBuckets data"
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
const rowFields = [
|
|
160
|
-
"trades",
|
|
161
|
-
"signals",
|
|
162
|
-
"evaluations",
|
|
163
|
-
"lineageScopes"
|
|
164
|
-
];
|
|
165
|
-
for (const field of rowFields) {
|
|
166
|
-
if (!Array.isArray(runtime[field])) {
|
|
167
|
-
throw new Error(`Runtime evidence payload ${field} must be an array`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
const snapshots = new Map(
|
|
171
|
-
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
172
|
-
);
|
|
173
|
-
const assertRows = (label, rows, lineageField) => {
|
|
174
|
-
for (const row of rows) {
|
|
175
|
-
const strategyName = String(row.strategy ?? "").trim();
|
|
176
|
-
const strategy = snapshots.get(strategyName);
|
|
177
|
-
if (!strategy || row.deploymentId !== deployment.id || row.accountId !== deployment.accountId || !runtimeLineageMatchesStrategySnapshot({
|
|
178
|
-
lineage: isRecord(row[lineageField]) ? row[lineageField] : void 0,
|
|
179
|
-
deployment,
|
|
180
|
-
strategy
|
|
181
|
-
})) {
|
|
182
|
-
throw new Error(
|
|
183
|
-
`Runtime evidence ${label} row is outside the current embedded deployment lineage`
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
assertRows(
|
|
189
|
-
"trade",
|
|
190
|
-
unwrapRuntimeEvidenceRows(runtime.trades, "trade"),
|
|
191
|
-
"runtimeLineage"
|
|
192
|
-
);
|
|
193
|
-
assertRows(
|
|
194
|
-
"signal",
|
|
195
|
-
unwrapRuntimeEvidenceRows(runtime.signals, "signal"),
|
|
196
|
-
"runtimeLineage"
|
|
197
|
-
);
|
|
198
|
-
assertRows(
|
|
199
|
-
"evaluation",
|
|
200
|
-
unwrapRuntimeEvidenceRows(runtime.evaluations, "evaluation"),
|
|
201
|
-
"runtimeLineage"
|
|
202
|
-
);
|
|
203
|
-
assertRows(
|
|
204
|
-
"lineage scope",
|
|
205
|
-
unwrapRuntimeEvidenceRows(runtime.lineageScopes, "lineageScope"),
|
|
206
|
-
"lineage"
|
|
207
|
-
);
|
|
208
|
-
return deployment;
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
// src/lib/runtimeEvidenceArtifacts.ts
|
|
212
|
-
var RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
|
|
213
|
-
var RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
|
|
214
|
-
var RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
|
|
215
|
-
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
216
|
-
var sha256 = (value) => (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
|
|
217
|
-
var assertFiniteTimestamp = (value, label) => {
|
|
218
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
219
|
-
throw new Error(`Invalid runtime evidence ${label}`);
|
|
220
|
-
}
|
|
221
|
-
return value;
|
|
222
|
-
};
|
|
223
|
-
var parseManifest = (value) => {
|
|
224
|
-
const manifest = asRecord(value);
|
|
225
|
-
const window = asRecord(manifest?.window);
|
|
226
|
-
const payload = asRecord(manifest?.payload);
|
|
227
|
-
const counts = asRecord(manifest?.counts);
|
|
228
|
-
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence" || typeof manifest.artifactId !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.userName !== "string" || typeof manifest.createdAt !== "number" || payload?.file !== RUNTIME_EVIDENCE_PAYLOAD_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number" || !Array.isArray(manifest.lineageKeys)) {
|
|
229
|
-
throw new Error("Invalid runtime evidence manifest");
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
schemaVersion: 1,
|
|
233
|
-
artifactId: manifest.artifactId,
|
|
234
|
-
reportType: "runtime-evidence",
|
|
235
|
-
deploymentId: manifest.deploymentId,
|
|
236
|
-
userName: manifest.userName,
|
|
237
|
-
createdAt: manifest.createdAt,
|
|
238
|
-
window: {
|
|
239
|
-
startTime: assertFiniteTimestamp(window?.startTime, "window.startTime"),
|
|
240
|
-
endTime: assertFiniteTimestamp(window?.endTime, "window.endTime")
|
|
241
|
-
},
|
|
242
|
-
payload: {
|
|
243
|
-
file: RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
244
|
-
sha256: payload.sha256,
|
|
245
|
-
bytes: payload.bytes
|
|
246
|
-
},
|
|
247
|
-
counts: Object.fromEntries(
|
|
248
|
-
Object.entries(counts ?? {}).filter(
|
|
249
|
-
(entry) => typeof entry[1] === "number" && Number.isFinite(entry[1])
|
|
250
|
-
)
|
|
251
|
-
),
|
|
252
|
-
lineageKeys: manifest.lineageKeys.filter(
|
|
253
|
-
(value2) => typeof value2 === "string" && value2.length > 0
|
|
254
|
-
)
|
|
255
|
-
};
|
|
256
|
-
};
|
|
257
|
-
var verifyRuntimeEvidenceBundle = async (bundleDir) => {
|
|
258
|
-
const manifestPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_MANIFEST_FILE);
|
|
259
|
-
const payloadPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_PAYLOAD_FILE);
|
|
260
|
-
const completePath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_COMPLETE_FILE);
|
|
261
|
-
const [manifestText, payload, completeText] = await Promise.all([
|
|
262
|
-
import_promises.default.readFile(manifestPath, "utf8"),
|
|
263
|
-
import_promises.default.readFile(payloadPath),
|
|
264
|
-
import_promises.default.readFile(completePath, "utf8")
|
|
265
|
-
]);
|
|
266
|
-
const manifest = parseManifest(JSON.parse(manifestText));
|
|
267
|
-
if (completeText.trim() !== manifest.artifactId) {
|
|
268
|
-
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
269
|
-
}
|
|
270
|
-
if (payload.byteLength !== manifest.payload.bytes) {
|
|
271
|
-
throw new Error(`Runtime evidence size mismatch in ${bundleDir}`);
|
|
272
|
-
}
|
|
273
|
-
if (sha256(payload) !== manifest.payload.sha256) {
|
|
274
|
-
throw new Error(`Runtime evidence checksum mismatch in ${bundleDir}`);
|
|
275
|
-
}
|
|
276
|
-
const artifact = asRecord(JSON.parse(payload.toString("utf8")));
|
|
277
|
-
const artifactWindow = asRecord(artifact?.window);
|
|
278
|
-
if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
|
|
279
|
-
throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
|
|
280
|
-
}
|
|
281
|
-
const deployment = assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
282
|
-
if (deployment.id !== manifest.deploymentId) {
|
|
283
|
-
throw new Error(`Runtime evidence deployment mismatch in ${bundleDir}`);
|
|
284
|
-
}
|
|
285
|
-
return {
|
|
286
|
-
bundleDir,
|
|
287
|
-
manifestPath,
|
|
288
|
-
payloadPath,
|
|
289
|
-
manifest,
|
|
290
|
-
artifact
|
|
291
|
-
};
|
|
292
|
-
};
|
|
293
|
-
var discoverRuntimeEvidenceBundles = async (rootDir) => {
|
|
294
|
-
const bundles = [];
|
|
295
|
-
const visit = async (directory, depth) => {
|
|
296
|
-
if (depth > 8) return;
|
|
297
|
-
let entries;
|
|
298
|
-
try {
|
|
299
|
-
entries = await import_promises.default.readdir(directory, { withFileTypes: true });
|
|
300
|
-
} catch (error) {
|
|
301
|
-
if (error.code === "ENOENT") return;
|
|
302
|
-
throw error;
|
|
303
|
-
}
|
|
304
|
-
const names = new Set(entries.map((entry) => entry.name));
|
|
305
|
-
if (names.has(RUNTIME_EVIDENCE_MANIFEST_FILE) && names.has(RUNTIME_EVIDENCE_PAYLOAD_FILE) && names.has(RUNTIME_EVIDENCE_COMPLETE_FILE)) {
|
|
306
|
-
bundles.push(directory);
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
await Promise.all(
|
|
310
|
-
entries.filter(
|
|
311
|
-
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
312
|
-
).map((entry) => visit(import_node_path.default.join(directory, entry.name), depth + 1))
|
|
313
|
-
);
|
|
314
|
-
};
|
|
315
|
-
await visit(rootDir, 0);
|
|
316
|
-
return bundles.sort();
|
|
317
|
-
};
|
|
45
|
+
var runtimeEvidenceArtifacts_exports = {};
|
|
46
|
+
__reExport(runtimeEvidenceArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
318
47
|
|
|
319
48
|
// src/lib/runtimeFeedbackArtifacts.ts
|
|
320
|
-
var
|
|
321
|
-
|
|
322
|
-
var import_node_path3 = __toESM(require("path"));
|
|
323
|
-
|
|
324
|
-
// src/lib/runtimeEvidenceProducer.ts
|
|
325
|
-
var import_node_crypto2 = require("crypto");
|
|
326
|
-
var import_promises2 = __toESM(require("fs/promises"));
|
|
327
|
-
var import_node_path2 = __toESM(require("path"));
|
|
328
|
-
var isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
329
|
-
var parseRuntimeEvidenceProducer = (value) => {
|
|
330
|
-
const producer = isRecord2(value) ? value : null;
|
|
331
|
-
const runtimePackageManifest = isRecord2(producer?.runtimePackageManifest) ? producer.runtimePackageManifest : null;
|
|
332
|
-
if (producer?.schemaVersion !== 1 || typeof producer.projectSha !== "string" || !/^[a-f0-9]{40}$/.test(producer.projectSha) || typeof producer.imageDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(producer.imageDigest) || runtimePackageManifest?.file !== "runtime-package-manifest.json" || typeof runtimePackageManifest.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(runtimePackageManifest.sha256)) {
|
|
333
|
-
throw new Error("Runtime evidence producer image identity is invalid");
|
|
334
|
-
}
|
|
335
|
-
return producer;
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
// src/lib/runtimeFeedbackArtifacts.ts
|
|
339
|
-
var RUNTIME_FEEDBACK_MANIFEST_FILE = "manifest.json";
|
|
340
|
-
var RUNTIME_FEEDBACK_REPLAY_FILE = "replay-runtime-evidence.json";
|
|
341
|
-
var RUNTIME_FEEDBACK_LOG_FILE = "replay.log";
|
|
342
|
-
var RUNTIME_FEEDBACK_COMPLETE_FILE = ".complete";
|
|
343
|
-
var isRecord3 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
344
|
-
var sha2562 = (value) => (0, import_node_crypto3.createHash)("sha256").update(value).digest("hex");
|
|
345
|
-
var parsePayload = (value, expectedFile) => {
|
|
346
|
-
const payload = isRecord3(value) ? value : null;
|
|
347
|
-
if (payload?.file !== expectedFile || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number" || !Number.isFinite(payload.bytes) || payload.bytes < 0) {
|
|
348
|
-
throw new Error(`Invalid runtime feedback payload: ${expectedFile}`);
|
|
349
|
-
}
|
|
350
|
-
return payload;
|
|
351
|
-
};
|
|
352
|
-
var parseManifest2 = (value) => {
|
|
353
|
-
const manifest = isRecord3(value) ? value : null;
|
|
354
|
-
const window = isRecord3(manifest?.window) ? manifest.window : null;
|
|
355
|
-
const runtimeEvidence = isRecord3(manifest?.runtimeEvidence) ? manifest.runtimeEvidence : null;
|
|
356
|
-
const safety = isRecord3(manifest?.safety) ? manifest.safety : null;
|
|
357
|
-
const payloads = isRecord3(manifest?.payloads) ? manifest.payloads : null;
|
|
358
|
-
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-feedback-replay" || typeof manifest.artifactId !== "string" || !manifest.artifactId.trim() || typeof manifest.runId !== "string" || !manifest.runId.trim() || typeof manifest.deploymentId !== "string" || !manifest.deploymentId.trim() || typeof manifest.deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(manifest.deploymentCompositionId) || typeof manifest.userName !== "string" || !manifest.userName.trim() || typeof manifest.createdAt !== "number" || typeof window?.startTime !== "number" || typeof window.endTime !== "number" || typeof runtimeEvidence?.artifactId !== "string" || typeof runtimeEvidence.payloadSha256 !== "string" || !/^[a-f0-9]{64}$/.test(runtimeEvidence.payloadSha256) || !Array.isArray(manifest.activeStrategies) || manifest.activeStrategies.length === 0 || !manifest.activeStrategies.every(
|
|
359
|
-
(strategy) => typeof strategy === "string" && strategy.trim()
|
|
360
|
-
) || typeof manifest.cycleCount !== "number" || !Number.isFinite(manifest.cycleCount) || manifest.cycleCount <= 0 || safety?.cacheOnly !== true || safety.externalOrderPlacement !== false || safety.redis !== "isolated" || safety.timescale !== "read_only") {
|
|
361
|
-
throw new Error("Invalid runtime feedback replay manifest");
|
|
362
|
-
}
|
|
363
|
-
const replayEvidence = parsePayload(
|
|
364
|
-
payloads?.replayEvidence,
|
|
365
|
-
RUNTIME_FEEDBACK_REPLAY_FILE
|
|
366
|
-
);
|
|
367
|
-
const log = parsePayload(payloads?.log, RUNTIME_FEEDBACK_LOG_FILE);
|
|
368
|
-
return {
|
|
369
|
-
...manifest,
|
|
370
|
-
producer: parseRuntimeEvidenceProducer(manifest.producer),
|
|
371
|
-
payloads: {
|
|
372
|
-
replayEvidence: {
|
|
373
|
-
...replayEvidence,
|
|
374
|
-
file: RUNTIME_FEEDBACK_REPLAY_FILE
|
|
375
|
-
},
|
|
376
|
-
log: { ...log, file: RUNTIME_FEEDBACK_LOG_FILE }
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
};
|
|
380
|
-
var assertReplayMatchesRuntimeEvidence = ({
|
|
381
|
-
replayEvidence,
|
|
382
|
-
runtimeEvidence
|
|
383
|
-
}) => {
|
|
384
|
-
if (replayEvidence.reportType !== "replay-runtime-evidence") {
|
|
385
|
-
throw new Error("Runtime feedback replay payload has the wrong reportType");
|
|
386
|
-
}
|
|
387
|
-
const replayWindow = isRecord3(replayEvidence.window) ? replayEvidence.window : null;
|
|
388
|
-
if (replayWindow?.startTime !== runtimeEvidence.manifest.window.startTime || replayWindow.endTime !== runtimeEvidence.manifest.window.endTime) {
|
|
389
|
-
throw new Error("Runtime feedback replay window does not match evidence");
|
|
390
|
-
}
|
|
391
|
-
const runtimeDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
392
|
-
runtimeEvidence.artifact.deployment
|
|
393
|
-
);
|
|
394
|
-
const replayDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
395
|
-
replayEvidence.deployment
|
|
396
|
-
);
|
|
397
|
-
if (replayDeployment.id !== runtimeDeployment.id || replayDeployment.deploymentCompositionId !== runtimeDeployment.deploymentCompositionId) {
|
|
398
|
-
throw new Error(
|
|
399
|
-
"Runtime feedback replay deployment does not match evidence"
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
var verifyRuntimeFeedbackReplayBundle = async (bundleDir) => {
|
|
404
|
-
const manifestPath = import_node_path3.default.join(bundleDir, RUNTIME_FEEDBACK_MANIFEST_FILE);
|
|
405
|
-
const replayEvidencePath = import_node_path3.default.join(bundleDir, RUNTIME_FEEDBACK_REPLAY_FILE);
|
|
406
|
-
const logPath = import_node_path3.default.join(bundleDir, RUNTIME_FEEDBACK_LOG_FILE);
|
|
407
|
-
const completePath = import_node_path3.default.join(bundleDir, RUNTIME_FEEDBACK_COMPLETE_FILE);
|
|
408
|
-
const [manifestText, replayPayload, logPayload, completeText] = await Promise.all([
|
|
409
|
-
import_promises3.default.readFile(manifestPath, "utf8"),
|
|
410
|
-
import_promises3.default.readFile(replayEvidencePath),
|
|
411
|
-
import_promises3.default.readFile(logPath),
|
|
412
|
-
import_promises3.default.readFile(completePath, "utf8")
|
|
413
|
-
]);
|
|
414
|
-
const manifest = parseManifest2(JSON.parse(manifestText));
|
|
415
|
-
if (completeText.trim() !== manifest.artifactId) {
|
|
416
|
-
throw new Error(`Invalid runtime feedback completion marker: ${bundleDir}`);
|
|
417
|
-
}
|
|
418
|
-
for (const [payload, descriptor] of [
|
|
419
|
-
[replayPayload, manifest.payloads.replayEvidence],
|
|
420
|
-
[logPayload, manifest.payloads.log]
|
|
421
|
-
]) {
|
|
422
|
-
if (payload.byteLength !== descriptor.bytes) {
|
|
423
|
-
throw new Error(
|
|
424
|
-
`Runtime feedback payload size mismatch: ${descriptor.file}`
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
if (sha2562(payload) !== descriptor.sha256) {
|
|
428
|
-
throw new Error(
|
|
429
|
-
`Runtime feedback payload checksum mismatch: ${descriptor.file}`
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
const replayEvidence = JSON.parse(replayPayload.toString("utf8"));
|
|
434
|
-
if (replayEvidence.reportType !== "replay-runtime-evidence") {
|
|
435
|
-
throw new Error("Invalid runtime feedback replay evidence payload");
|
|
436
|
-
}
|
|
437
|
-
const replayWindow = isRecord3(replayEvidence.window) ? replayEvidence.window : null;
|
|
438
|
-
const replay = isRecord3(replayEvidence.replay) ? replayEvidence.replay : null;
|
|
439
|
-
const replayDeployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
440
|
-
replayEvidence.deployment
|
|
441
|
-
);
|
|
442
|
-
const replayStrategies = activeRuntimeEvidenceStrategies(replayDeployment).map(({ strategyName }) => strategyName).sort();
|
|
443
|
-
if (replayEvidence.userName !== manifest.userName || replayWindow?.startTime !== manifest.window.startTime || replayWindow.endTime !== manifest.window.endTime || replayDeployment.id !== manifest.deploymentId || replayDeployment.deploymentCompositionId !== manifest.deploymentCompositionId || Number(replay?.cycleCount) !== manifest.cycleCount || JSON.stringify(replayStrategies) !== JSON.stringify([...manifest.activeStrategies].sort())) {
|
|
444
|
-
throw new Error("Runtime feedback replay payload does not match manifest");
|
|
445
|
-
}
|
|
446
|
-
return {
|
|
447
|
-
bundleDir,
|
|
448
|
-
manifestPath,
|
|
449
|
-
replayEvidencePath,
|
|
450
|
-
logPath,
|
|
451
|
-
manifest,
|
|
452
|
-
replayEvidence
|
|
453
|
-
};
|
|
454
|
-
};
|
|
455
|
-
var verifyRuntimeFeedbackReplaySource = async ({
|
|
456
|
-
bundleDir,
|
|
457
|
-
runtimeEvidenceBundleDir
|
|
458
|
-
}) => {
|
|
459
|
-
const [feedback, runtimeEvidence] = await Promise.all([
|
|
460
|
-
verifyRuntimeFeedbackReplayBundle(bundleDir),
|
|
461
|
-
verifyRuntimeEvidenceBundle(runtimeEvidenceBundleDir)
|
|
462
|
-
]);
|
|
463
|
-
if (feedback.manifest.runtimeEvidence.artifactId !== runtimeEvidence.manifest.artifactId || feedback.manifest.runtimeEvidence.payloadSha256 !== runtimeEvidence.manifest.payload.sha256) {
|
|
464
|
-
throw new Error("Runtime feedback bundle references different evidence");
|
|
465
|
-
}
|
|
466
|
-
assertReplayMatchesRuntimeEvidence({
|
|
467
|
-
replayEvidence: feedback.replayEvidence,
|
|
468
|
-
runtimeEvidence
|
|
469
|
-
});
|
|
470
|
-
return { feedback, runtimeEvidence };
|
|
471
|
-
};
|
|
49
|
+
var runtimeFeedbackArtifacts_exports = {};
|
|
50
|
+
__reExport(runtimeFeedbackArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
472
51
|
|
|
473
52
|
// src/lib/runtimeEvidenceSync.ts
|
|
474
53
|
var import_node_child_process = require("child_process");
|
|
475
|
-
var
|
|
476
|
-
var
|
|
54
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
55
|
+
var import_node_path = __toESM(require("path"));
|
|
477
56
|
var import_node_util = require("util");
|
|
57
|
+
|
|
58
|
+
// src/lib/runtimeEvidenceDeployment.ts
|
|
59
|
+
var runtimeEvidenceDeployment_exports = {};
|
|
60
|
+
__reExport(runtimeEvidenceDeployment_exports, require("@tradejs/node/diagnostics"));
|
|
61
|
+
|
|
62
|
+
// src/lib/runtimeEvidenceSync.ts
|
|
478
63
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
479
64
|
var safeSegment = (value, fallback) => {
|
|
480
65
|
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
481
66
|
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
482
67
|
};
|
|
483
|
-
var receiptPath = (receiptsRoot, artifactId) =>
|
|
68
|
+
var receiptPath = (receiptsRoot, artifactId) => import_node_path.default.join(receiptsRoot, `${safeSegment(artifactId, "artifact")}.json`);
|
|
484
69
|
var markRuntimeEvidenceBundleProcessed = async ({
|
|
485
70
|
evidenceRoot,
|
|
486
71
|
deploymentId,
|
|
@@ -489,13 +74,13 @@ var markRuntimeEvidenceBundleProcessed = async ({
|
|
|
489
74
|
runtimeFeedback
|
|
490
75
|
}) => {
|
|
491
76
|
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
492
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
77
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
493
78
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
494
79
|
throw new Error(
|
|
495
80
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
496
81
|
);
|
|
497
82
|
}
|
|
498
|
-
const receiptsRoot =
|
|
83
|
+
const receiptsRoot = import_node_path.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
499
84
|
const finalPath = receiptPath(receiptsRoot, verified.manifest.artifactId);
|
|
500
85
|
const temporaryPath = `${finalPath}.tmp-${process.pid}`;
|
|
501
86
|
const receipt = {
|
|
@@ -509,19 +94,19 @@ var markRuntimeEvidenceBundleProcessed = async ({
|
|
|
509
94
|
replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
|
|
510
95
|
} : {}
|
|
511
96
|
};
|
|
512
|
-
await
|
|
513
|
-
await
|
|
97
|
+
await import_promises.default.mkdir(receiptsRoot, { recursive: true });
|
|
98
|
+
await import_promises.default.writeFile(
|
|
514
99
|
temporaryPath,
|
|
515
100
|
`${JSON.stringify(receipt, null, 2)}
|
|
516
101
|
`,
|
|
517
102
|
"utf8"
|
|
518
103
|
);
|
|
519
|
-
await
|
|
104
|
+
await import_promises.default.rename(temporaryPath, finalPath);
|
|
520
105
|
return finalPath;
|
|
521
106
|
};
|
|
522
107
|
|
|
523
108
|
// src/lib/runtimeLineage.ts
|
|
524
|
-
var
|
|
109
|
+
var import_node_crypto = require("crypto");
|
|
525
110
|
var normalizeForStableJson = (value) => {
|
|
526
111
|
if (Array.isArray(value)) {
|
|
527
112
|
return value.map(normalizeForStableJson);
|
|
@@ -533,7 +118,7 @@ var normalizeForStableJson = (value) => {
|
|
|
533
118
|
}
|
|
534
119
|
return value;
|
|
535
120
|
};
|
|
536
|
-
var fingerprintRuntimeValue = (value) => (0,
|
|
121
|
+
var fingerprintRuntimeValue = (value) => (0, import_node_crypto.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
537
122
|
var runtimeLineageKey = (lineage) => [
|
|
538
123
|
"v3",
|
|
539
124
|
lineage.deploymentCompositionId,
|
|
@@ -544,12 +129,12 @@ var runtimeLineageKey = (lineage) => [
|
|
|
544
129
|
].join(":");
|
|
545
130
|
|
|
546
131
|
// src/lib/runtimeScorecard.ts
|
|
547
|
-
var
|
|
132
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
548
133
|
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
549
134
|
var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
550
135
|
var finiteString = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
551
136
|
var packageVersionMap = (value) => {
|
|
552
|
-
const record =
|
|
137
|
+
const record = asRecord(value);
|
|
553
138
|
if (!record || Object.keys(record).length === 0) return null;
|
|
554
139
|
const entries = Object.entries(record);
|
|
555
140
|
if (entries.some(
|
|
@@ -562,14 +147,14 @@ var packageVersionMap = (value) => {
|
|
|
562
147
|
);
|
|
563
148
|
};
|
|
564
149
|
var round = (value, decimals = 6) => Number(value.toFixed(decimals));
|
|
565
|
-
var unwrapRows = (value, key) => asArray(value).map((item) =>
|
|
150
|
+
var unwrapRows = (value, key) => asArray(value).map((item) => asRecord(asRecord(item)?.[key]) ?? asRecord(item)).filter((item) => item != null);
|
|
566
151
|
var runtimePayload = (artifact) => {
|
|
567
|
-
const root =
|
|
568
|
-
return
|
|
152
|
+
const root = asRecord(artifact) ?? {};
|
|
153
|
+
return asRecord(root.runtime) ?? root;
|
|
569
154
|
};
|
|
570
155
|
var runtimeWindow = (artifact) => {
|
|
571
|
-
const root =
|
|
572
|
-
return
|
|
156
|
+
const root = asRecord(artifact) ?? {};
|
|
157
|
+
return asRecord(root.window) ?? asRecord(runtimePayload(artifact).window) ?? {};
|
|
573
158
|
};
|
|
574
159
|
var extractRuntimeRows = (artifact) => {
|
|
575
160
|
const runtime = runtimePayload(artifact);
|
|
@@ -585,7 +170,7 @@ var buildEmbeddedLineageScope = ({
|
|
|
585
170
|
rows,
|
|
586
171
|
strategy
|
|
587
172
|
}) => {
|
|
588
|
-
const deployment =
|
|
173
|
+
const deployment = asRecord(asRecord(artifact)?.deployment);
|
|
589
174
|
if (finiteNumber(deployment?.schemaVersion) !== 2) return null;
|
|
590
175
|
const deploymentId = finiteString(deployment?.id);
|
|
591
176
|
const accountId = finiteString(deployment?.accountId);
|
|
@@ -593,7 +178,7 @@ var buildEmbeddedLineageScope = ({
|
|
|
593
178
|
deployment?.deploymentCompositionId
|
|
594
179
|
);
|
|
595
180
|
if (!deploymentId || !accountId || !deploymentCompositionId) return null;
|
|
596
|
-
const snapshots = asArray(deployment?.strategies).map(
|
|
181
|
+
const snapshots = asArray(deployment?.strategies).map(asRecord).filter((item) => item != null).filter((item) => item.enabled === true).filter(
|
|
597
182
|
(item) => !strategy || finiteString(item.strategyName) === strategy
|
|
598
183
|
);
|
|
599
184
|
const targetSeeds = snapshots.map((snapshot) => {
|
|
@@ -635,10 +220,10 @@ var buildEmbeddedLineageScope = ({
|
|
|
635
220
|
const targets = /* @__PURE__ */ new Map();
|
|
636
221
|
for (const seed of targetSeeds) {
|
|
637
222
|
const matchingRows = lineageRows.filter(
|
|
638
|
-
(row) => finiteString(row.strategy) === seed.strategyName && finiteString(row.deploymentId) === deploymentId && finiteString(row.accountId) === accountId && identityMatches(
|
|
223
|
+
(row) => finiteString(row.strategy) === seed.strategyName && finiteString(row.deploymentId) === deploymentId && finiteString(row.accountId) === accountId && identityMatches(asRecord(row.runtimeLineage), seed)
|
|
639
224
|
);
|
|
640
225
|
const riskValues = new Set(
|
|
641
|
-
matchingRows.map((row) => finiteNumber(
|
|
226
|
+
matchingRows.map((row) => finiteNumber(asRecord(row.runtimeLineage)?.maxLossValue)).filter((value) => value != null)
|
|
642
227
|
);
|
|
643
228
|
targets.set(seed.strategyName, {
|
|
644
229
|
...seed,
|
|
@@ -650,7 +235,7 @@ var buildEmbeddedLineageScope = ({
|
|
|
650
235
|
const belongs = (row) => {
|
|
651
236
|
const strategyName = finiteString(row.strategy);
|
|
652
237
|
const target = strategyName ? targets.get(strategyName) : null;
|
|
653
|
-
const lineage =
|
|
238
|
+
const lineage = asRecord(row.runtimeLineage);
|
|
654
239
|
return Boolean(
|
|
655
240
|
target && target.maxLossValue != null && identityMatches(lineage, target) && finiteNumber(lineage?.maxLossValue) === target.maxLossValue
|
|
656
241
|
);
|
|
@@ -707,7 +292,7 @@ var buildEmbeddedLineageScope = ({
|
|
|
707
292
|
};
|
|
708
293
|
};
|
|
709
294
|
var runtimeDeploymentBinding = (artifact) => {
|
|
710
|
-
const deployment =
|
|
295
|
+
const deployment = asRecord(asRecord(artifact)?.deployment);
|
|
711
296
|
return {
|
|
712
297
|
deploymentId: finiteString(deployment?.id),
|
|
713
298
|
accountId: finiteString(deployment?.accountId)
|
|
@@ -717,7 +302,7 @@ var belongsToRuntimeDeployment = (row, binding) => binding.deploymentId == null
|
|
|
717
302
|
var belongsToStrategy = (row, strategy) => strategy == null || finiteString(row.strategy) === strategy;
|
|
718
303
|
var filterArtifactByStrategy = (artifact, strategy) => {
|
|
719
304
|
if (!strategy) return artifact;
|
|
720
|
-
const root =
|
|
305
|
+
const root = asRecord(artifact) ?? {};
|
|
721
306
|
const runtime = runtimePayload(artifact);
|
|
722
307
|
return {
|
|
723
308
|
...root,
|
|
@@ -725,24 +310,24 @@ var filterArtifactByStrategy = (artifact, strategy) => {
|
|
|
725
310
|
...runtime,
|
|
726
311
|
evaluations: asArray(runtime.evaluations).filter(
|
|
727
312
|
(item) => belongsToStrategy(
|
|
728
|
-
|
|
313
|
+
asRecord(asRecord(item)?.evaluation) ?? asRecord(item) ?? {},
|
|
729
314
|
strategy
|
|
730
315
|
)
|
|
731
316
|
),
|
|
732
317
|
signals: asArray(runtime.signals).filter(
|
|
733
318
|
(item) => belongsToStrategy(
|
|
734
|
-
|
|
319
|
+
asRecord(asRecord(item)?.signal) ?? asRecord(item) ?? {},
|
|
735
320
|
strategy
|
|
736
321
|
)
|
|
737
322
|
),
|
|
738
323
|
trades: asArray(runtime.trades).filter(
|
|
739
324
|
(item) => belongsToStrategy(
|
|
740
|
-
|
|
325
|
+
asRecord(asRecord(item)?.trade) ?? asRecord(item) ?? {},
|
|
741
326
|
strategy
|
|
742
327
|
)
|
|
743
328
|
),
|
|
744
329
|
lineageScopes: asArray(runtime.lineageScopes).filter(
|
|
745
|
-
(item) => belongsToStrategy(
|
|
330
|
+
(item) => belongsToStrategy(asRecord(item) ?? {}, strategy)
|
|
746
331
|
)
|
|
747
332
|
}
|
|
748
333
|
};
|
|
@@ -759,7 +344,7 @@ var countBy = (items, getter) => {
|
|
|
759
344
|
);
|
|
760
345
|
};
|
|
761
346
|
var resolveGateDecision = (evaluation) => {
|
|
762
|
-
const analysis =
|
|
347
|
+
const analysis = asRecord(evaluation.aiAnalysis);
|
|
763
348
|
const explicit = finiteString(analysis?.gateDecision);
|
|
764
349
|
if (explicit === "approved" || explicit === "rejected") {
|
|
765
350
|
return { decision: explicit, source: "gate_decision" };
|
|
@@ -790,7 +375,7 @@ var buildDistributions = ({
|
|
|
790
375
|
(signal) => finiteString(signal.orderSkipReason)
|
|
791
376
|
),
|
|
792
377
|
aiQuality: countBy(candidates, (evaluation) => {
|
|
793
|
-
const quality = finiteNumber(
|
|
378
|
+
const quality = finiteNumber(asRecord(evaluation.aiAnalysis)?.quality);
|
|
794
379
|
return quality == null ? null : String(quality);
|
|
795
380
|
})
|
|
796
381
|
};
|
|
@@ -875,13 +460,13 @@ var buildRollingPerformance = ({
|
|
|
875
460
|
};
|
|
876
461
|
};
|
|
877
462
|
var getReplayComparison = (artifact) => {
|
|
878
|
-
const root =
|
|
879
|
-
return
|
|
463
|
+
const root = asRecord(artifact) ?? {};
|
|
464
|
+
return asRecord(asRecord(root.replay)?.runtimeComparison) ?? null;
|
|
880
465
|
};
|
|
881
466
|
var replayCountsForStrategy = (replayComparison, strategy) => {
|
|
882
467
|
if (strategy) {
|
|
883
|
-
const byStrategy =
|
|
884
|
-
const strategyCounts =
|
|
468
|
+
const byStrategy = asRecord(replayComparison?.byStrategy);
|
|
469
|
+
const strategyCounts = asRecord(byStrategy?.[strategy]);
|
|
885
470
|
if (strategyCounts) {
|
|
886
471
|
return {
|
|
887
472
|
matched: finiteNumber(strategyCounts.matched) ?? 0,
|
|
@@ -890,7 +475,7 @@ var replayCountsForStrategy = (replayComparison, strategy) => {
|
|
|
890
475
|
};
|
|
891
476
|
}
|
|
892
477
|
}
|
|
893
|
-
const counts =
|
|
478
|
+
const counts = asRecord(replayComparison?.counts);
|
|
894
479
|
return {
|
|
895
480
|
matched: finiteNumber(counts?.matched) ?? 0,
|
|
896
481
|
backtestOnly: finiteNumber(counts?.backtestOnly) ?? 0,
|
|
@@ -898,7 +483,7 @@ var replayCountsForStrategy = (replayComparison, strategy) => {
|
|
|
898
483
|
};
|
|
899
484
|
};
|
|
900
485
|
var getProspectiveSummary = (artifact) => {
|
|
901
|
-
const root =
|
|
486
|
+
const root = asRecord(artifact);
|
|
902
487
|
if (!root || root.reportType !== "strategy-prospective-evidence") return null;
|
|
903
488
|
return {
|
|
904
489
|
rawCoreExpectancy: finiteNumber(root.rawCoreExpectancy),
|
|
@@ -922,9 +507,9 @@ var buildRuntimeScorecard = ({
|
|
|
922
507
|
strategy = null,
|
|
923
508
|
llmComparatorPolicy = "ai_approved_only"
|
|
924
509
|
}) => {
|
|
925
|
-
assertCurrentRuntimeEvidenceArtifact(runtimeArtifact);
|
|
510
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(runtimeArtifact);
|
|
926
511
|
for (const artifact of historyRuntimeArtifacts) {
|
|
927
|
-
assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
512
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(artifact);
|
|
928
513
|
}
|
|
929
514
|
const scopedRuntimeArtifact = filterArtifactByStrategy(
|
|
930
515
|
runtimeArtifact,
|
|
@@ -959,7 +544,7 @@ var buildRuntimeScorecard = ({
|
|
|
959
544
|
(evaluation) => resolveGateDecision(evaluation)?.decision === "approved"
|
|
960
545
|
) : signalEvaluations;
|
|
961
546
|
const gateComparisons = llmEligibleEvaluations.map((evaluation) => {
|
|
962
|
-
const analysis =
|
|
547
|
+
const analysis = asRecord(evaluation.aiAnalysis);
|
|
963
548
|
const gateDecision = resolveGateDecision(evaluation)?.decision ?? null;
|
|
964
549
|
const llmDecision = finiteString(analysis?.llmDecision);
|
|
965
550
|
if (gateDecision !== "approved" && gateDecision !== "rejected" || llmDecision !== "approved" && llmDecision !== "rejected") {
|
|
@@ -969,8 +554,8 @@ var buildRuntimeScorecard = ({
|
|
|
969
554
|
}).filter(
|
|
970
555
|
(comparison) => Boolean(comparison)
|
|
971
556
|
);
|
|
972
|
-
const allocatorDecisions = signalEvaluations.map((evaluation) =>
|
|
973
|
-
const riskDecisions = signalEvaluations.map((evaluation) =>
|
|
557
|
+
const allocatorDecisions = signalEvaluations.map((evaluation) => asRecord(evaluation.allocatorDecision)).filter((item) => item != null);
|
|
558
|
+
const riskDecisions = signalEvaluations.map((evaluation) => asRecord(evaluation.riskDecision)).filter((item) => item != null);
|
|
974
559
|
const orderAttempts = rows.signals.filter(
|
|
975
560
|
(signal) => signal.orderStatus === "completed" || signal.orderStatus === "failed"
|
|
976
561
|
);
|
|
@@ -985,10 +570,10 @@ var buildRuntimeScorecard = ({
|
|
|
985
570
|
const runtimeOnly = replayCounts.runtimeOnly;
|
|
986
571
|
const comparisonTotal = matched + backtestOnly + runtimeOnly;
|
|
987
572
|
const parityRatio = comparisonTotal > 0 ? matched / comparisonTotal : null;
|
|
988
|
-
const lineage =
|
|
573
|
+
const lineage = asRecord(replayComparison?.lineage);
|
|
989
574
|
const lineageReason = finiteString(lineage?.reason);
|
|
990
|
-
const calibrationRoot =
|
|
991
|
-
const calibrationSamples = asArray(calibrationRoot.samples).map(
|
|
575
|
+
const calibrationRoot = asRecord(calibrationArtifact) ?? {};
|
|
576
|
+
const calibrationSamples = asArray(calibrationRoot.samples).map(asRecord).filter((item) => item != null).filter((item) => !strategy || finiteString(item.strategy) === strategy).filter((item) => embeddedLineageScope.belongs(item));
|
|
992
577
|
const averageSampleMetric = (field) => {
|
|
993
578
|
const values = calibrationSamples.map((sample) => finiteNumber(sample[field])).filter((value) => value != null);
|
|
994
579
|
return values.length ? round(sum(values) / values.length) : null;
|
|
@@ -1331,9 +916,9 @@ ${reactions}
|
|
|
1331
916
|
};
|
|
1332
917
|
|
|
1333
918
|
// src/lib/strategyRelease.ts
|
|
1334
|
-
var
|
|
1335
|
-
var
|
|
1336
|
-
var
|
|
919
|
+
var import_node_crypto2 = require("crypto");
|
|
920
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
921
|
+
var import_node_path2 = __toESM(require("path"));
|
|
1337
922
|
var import_types2 = require("@tradejs/types");
|
|
1338
923
|
var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
|
|
1339
924
|
|
|
@@ -1807,10 +1392,10 @@ var createStrategyReleaseManifest = (input) => {
|
|
|
1807
1392
|
strategy: input.strategy,
|
|
1808
1393
|
createdAt: input.createdAt,
|
|
1809
1394
|
compositionId,
|
|
1810
|
-
evidence: input.evidence.map(({ kind, artifactId, sha256
|
|
1395
|
+
evidence: input.evidence.map(({ kind, artifactId, sha256 }) => ({
|
|
1811
1396
|
kind,
|
|
1812
1397
|
artifactId,
|
|
1813
|
-
sha256
|
|
1398
|
+
sha256
|
|
1814
1399
|
})),
|
|
1815
1400
|
verdict
|
|
1816
1401
|
};
|
|
@@ -1834,7 +1419,7 @@ var createStrategyReleaseManifest = (input) => {
|
|
|
1834
1419
|
};
|
|
1835
1420
|
};
|
|
1836
1421
|
var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
1837
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
1422
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises2.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
1838
1423
|
const envelope = value;
|
|
1839
1424
|
assert(
|
|
1840
1425
|
envelope?.schema === "tradejs-strategy-release-envelope/v1",
|
|
@@ -1885,19 +1470,19 @@ var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
|
|
|
1885
1470
|
return envelope;
|
|
1886
1471
|
};
|
|
1887
1472
|
var verifyStrategyEvidenceMarkerEnvelope = async (valueOrPath) => {
|
|
1888
|
-
const value = typeof valueOrPath === "string" ? JSON.parse(await
|
|
1473
|
+
const value = typeof valueOrPath === "string" ? JSON.parse(await import_promises2.default.readFile(valueOrPath, "utf8")) : valueOrPath;
|
|
1889
1474
|
return (0, import_strategyReleaseEvidence.verifyStrategyEvidenceMarkerEnvelope)(value);
|
|
1890
1475
|
};
|
|
1891
1476
|
var writeJsonAtomic = async (filePath, value) => {
|
|
1892
1477
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
1893
|
-
await
|
|
1894
|
-
await
|
|
1478
|
+
await import_promises2.default.mkdir(import_node_path2.default.dirname(filePath), { recursive: true });
|
|
1479
|
+
await import_promises2.default.writeFile(
|
|
1895
1480
|
temporaryPath,
|
|
1896
1481
|
`${canonicalStrategyReleaseJson(value)}
|
|
1897
1482
|
`,
|
|
1898
1483
|
"utf8"
|
|
1899
1484
|
);
|
|
1900
|
-
await
|
|
1485
|
+
await import_promises2.default.rename(temporaryPath, filePath);
|
|
1901
1486
|
};
|
|
1902
1487
|
var publishStrategyLiveDiagnosis = async ({
|
|
1903
1488
|
rootDir,
|
|
@@ -1963,13 +1548,13 @@ var publishStrategyLiveDiagnosis = async ({
|
|
|
1963
1548
|
markers,
|
|
1964
1549
|
sourceArtifacts
|
|
1965
1550
|
});
|
|
1966
|
-
const diagnosisPath =
|
|
1551
|
+
const diagnosisPath = import_node_path2.default.join(
|
|
1967
1552
|
rootDir,
|
|
1968
1553
|
"diagnoses",
|
|
1969
1554
|
safeSegment2(diagnosis.strategy, "strategy"),
|
|
1970
1555
|
`${diagnosisId}.json`
|
|
1971
1556
|
);
|
|
1972
|
-
const markerPath =
|
|
1557
|
+
const markerPath = import_node_path2.default.join(
|
|
1973
1558
|
rootDir,
|
|
1974
1559
|
"markers",
|
|
1975
1560
|
safeSegment2(diagnosis.strategy, "strategy"),
|
|
@@ -2046,21 +1631,21 @@ var flags = import_args.default.parse(process.argv);
|
|
|
2046
1631
|
var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
2047
1632
|
var resolveOptionalPath = (value) => {
|
|
2048
1633
|
const raw = String(value ?? "").trim();
|
|
2049
|
-
return raw ?
|
|
1634
|
+
return raw ? import_node_path3.default.resolve(projectRoot, raw) : null;
|
|
2050
1635
|
};
|
|
2051
|
-
var readJson = async (filePath) => filePath ? JSON.parse(await
|
|
1636
|
+
var readJson = async (filePath) => filePath ? JSON.parse(await import_promises3.default.readFile(filePath, "utf8")) : void 0;
|
|
2052
1637
|
var assertReportType = (artifact, expected, label) => {
|
|
2053
1638
|
if (artifact != null && (!artifact || typeof artifact !== "object" || Array.isArray(artifact) || artifact.reportType !== expected)) {
|
|
2054
1639
|
throw new Error(`${label} must be a ${expected} artifact`);
|
|
2055
1640
|
}
|
|
2056
1641
|
};
|
|
2057
|
-
var sha256File = async (filePath) => (0,
|
|
1642
|
+
var sha256File = async (filePath) => (0, import_node_crypto3.createHash)("sha256").update(await import_promises3.default.readFile(filePath)).digest("hex");
|
|
2058
1643
|
var loadHistoryArtifacts = async (historyDir) => {
|
|
2059
1644
|
if (!historyDir) return [];
|
|
2060
|
-
const bundleDirs = await discoverRuntimeEvidenceBundles(historyDir);
|
|
1645
|
+
const bundleDirs = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(historyDir);
|
|
2061
1646
|
const bundles = [];
|
|
2062
1647
|
for (const bundleDir of bundleDirs) {
|
|
2063
|
-
bundles.push(await verifyRuntimeEvidenceBundle(bundleDir));
|
|
1648
|
+
bundles.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir));
|
|
2064
1649
|
}
|
|
2065
1650
|
return bundles.map((bundle) => bundle.artifact);
|
|
2066
1651
|
};
|
|
@@ -2125,13 +1710,13 @@ var runtimeScorecard = async () => {
|
|
|
2125
1710
|
strategy: scorecardStrategy,
|
|
2126
1711
|
llmComparatorPolicy: verifiedRelease?.manifest.prospective.llmComparatorPolicy ?? "ai_approved_only"
|
|
2127
1712
|
});
|
|
2128
|
-
const outPath =
|
|
1713
|
+
const outPath = import_node_path3.default.resolve(projectRoot, String(flags.out));
|
|
2129
1714
|
const markdownPath = outPath.replace(/\.json$/i, "") + ".md";
|
|
2130
|
-
await
|
|
1715
|
+
await import_promises3.default.mkdir(import_node_path3.default.dirname(outPath), { recursive: true });
|
|
2131
1716
|
await Promise.all([
|
|
2132
|
-
|
|
1717
|
+
import_promises3.default.writeFile(outPath, `${JSON.stringify(scorecard, null, 2)}
|
|
2133
1718
|
`, "utf8"),
|
|
2134
|
-
|
|
1719
|
+
import_promises3.default.writeFile(
|
|
2135
1720
|
markdownPath,
|
|
2136
1721
|
formatRuntimeScorecardMarkdown(scorecard),
|
|
2137
1722
|
"utf8"
|
|
@@ -2145,7 +1730,7 @@ var runtimeScorecard = async () => {
|
|
|
2145
1730
|
const diagnosisPath = diagnosis ? outPath.replace(/\.json$/i, "") + ".diagnosis.json" : null;
|
|
2146
1731
|
const strategyReleaseRoot = resolveOptionalPath(flags.strategyReleaseRoot);
|
|
2147
1732
|
if (diagnosis && diagnosisPath) {
|
|
2148
|
-
await
|
|
1733
|
+
await import_promises3.default.writeFile(
|
|
2149
1734
|
diagnosisPath,
|
|
2150
1735
|
`${JSON.stringify(diagnosis, null, 2)}
|
|
2151
1736
|
`,
|
|
@@ -2166,7 +1751,7 @@ var runtimeScorecard = async () => {
|
|
|
2166
1751
|
composition: verifiedRelease?.manifest.composition,
|
|
2167
1752
|
sourceArtifacts: await Promise.all(
|
|
2168
1753
|
sourcePaths.map(async (sourcePath) => ({
|
|
2169
|
-
artifactId:
|
|
1754
|
+
artifactId: import_node_path3.default.basename(sourcePath),
|
|
2170
1755
|
path: sourcePath,
|
|
2171
1756
|
sha256: await sha256File(sourcePath)
|
|
2172
1757
|
}))
|
|
@@ -2176,12 +1761,12 @@ var runtimeScorecard = async () => {
|
|
|
2176
1761
|
}
|
|
2177
1762
|
let receiptPath2 = null;
|
|
2178
1763
|
if (flags.markProcessed) {
|
|
2179
|
-
const runtimeEvidenceBundle = await verifyRuntimeEvidenceBundle(
|
|
2180
|
-
|
|
1764
|
+
const runtimeEvidenceBundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(
|
|
1765
|
+
import_node_path3.default.dirname(runtimeEvidencePath)
|
|
2181
1766
|
);
|
|
2182
|
-
const feedbackSource = replayEvidencePath ? await verifyRuntimeFeedbackReplaySource({
|
|
2183
|
-
bundleDir:
|
|
2184
|
-
runtimeEvidenceBundleDir:
|
|
1767
|
+
const feedbackSource = replayEvidencePath ? await (0, runtimeFeedbackArtifacts_exports.verifyRuntimeFeedbackReplaySource)({
|
|
1768
|
+
bundleDir: import_node_path3.default.dirname(replayEvidencePath),
|
|
1769
|
+
runtimeEvidenceBundleDir: import_node_path3.default.dirname(runtimeEvidencePath)
|
|
2185
1770
|
}).catch((error) => {
|
|
2186
1771
|
if (runtimeEvidenceBundle.artifact.producer) throw error;
|
|
2187
1772
|
return null;
|
|
@@ -2192,9 +1777,9 @@ var runtimeScorecard = async () => {
|
|
|
2192
1777
|
);
|
|
2193
1778
|
}
|
|
2194
1779
|
receiptPath2 = await markRuntimeEvidenceBundleProcessed({
|
|
2195
|
-
evidenceRoot:
|
|
1780
|
+
evidenceRoot: import_node_path3.default.resolve(projectRoot, String(flags.evidenceDir)),
|
|
2196
1781
|
deploymentId: String(flags.deployment),
|
|
2197
|
-
bundleDir:
|
|
1782
|
+
bundleDir: import_node_path3.default.dirname(runtimeEvidencePath),
|
|
2198
1783
|
scorecardPath: outPath,
|
|
2199
1784
|
runtimeFeedback: feedbackSource ? {
|
|
2200
1785
|
artifactId: feedbackSource.feedback.manifest.artifactId,
|