@tradejs/cli 3.1.29-beta.262 → 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/dist/cli.js +864 -1424
- 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/backtest.js +6 -1
- 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 +7 -7
|
@@ -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-
|
|
@@ -37,285 +38,17 @@ __export(runtimeEvidenceSync_exports, {
|
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(runtimeEvidenceSync_exports);
|
|
39
40
|
var import_node_child_process = require("child_process");
|
|
40
|
-
var
|
|
41
|
-
var
|
|
41
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
42
|
+
var import_node_path = __toESM(require("path"));
|
|
42
43
|
var import_node_util = require("util");
|
|
43
44
|
|
|
44
45
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
var import_node_path = __toESM(require("path"));
|
|
46
|
+
var runtimeEvidenceArtifacts_exports = {};
|
|
47
|
+
__reExport(runtimeEvidenceArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
48
48
|
|
|
49
49
|
// src/lib/runtimeEvidenceDeployment.ts
|
|
50
|
-
var
|
|
51
|
-
|
|
52
|
-
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
53
|
-
var isPackageVersionMap = (value) => isRecord(value) && Object.keys(value).length > 0 && Object.entries(value).every(
|
|
54
|
-
([name, version]) => name.startsWith("@tradejs/") && isNonEmptyString(version)
|
|
55
|
-
);
|
|
56
|
-
var INTERVALS = /* @__PURE__ */ new Set([
|
|
57
|
-
"1",
|
|
58
|
-
"3",
|
|
59
|
-
"5",
|
|
60
|
-
"15",
|
|
61
|
-
"30",
|
|
62
|
-
"60",
|
|
63
|
-
"120",
|
|
64
|
-
"240",
|
|
65
|
-
"360",
|
|
66
|
-
"720",
|
|
67
|
-
"D",
|
|
68
|
-
"W",
|
|
69
|
-
"M"
|
|
70
|
-
]);
|
|
71
|
-
var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
72
|
-
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));
|
|
73
|
-
var samePackageVersions = (left, right) => {
|
|
74
|
-
if (!left || !right) return false;
|
|
75
|
-
const leftEntries = Object.entries(left).sort(
|
|
76
|
-
([a], [b]) => a.localeCompare(b)
|
|
77
|
-
);
|
|
78
|
-
const rightEntries = Object.entries(right).sort(
|
|
79
|
-
([a], [b]) => a.localeCompare(b)
|
|
80
|
-
);
|
|
81
|
-
return JSON.stringify(leftEntries) === JSON.stringify(rightEntries);
|
|
82
|
-
};
|
|
83
|
-
var runtimeLineageMatchesStrategySnapshot = ({
|
|
84
|
-
lineage,
|
|
85
|
-
deployment,
|
|
86
|
-
strategy
|
|
87
|
-
}) => lineage?.schemaVersion === 3 && lineage.strategyRevision === strategy.strategyRevision && lineage.deploymentCompositionId === deployment.deploymentCompositionId && lineage.strategyPackageVersion === strategy.strategyPackageVersion && lineage.runtimePackageVersion === strategy.runtimePackageVersion && samePackageVersions(
|
|
88
|
-
lineage.strategyDependencyVersions,
|
|
89
|
-
strategy.strategyDependencyVersions
|
|
90
|
-
);
|
|
91
|
-
var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
92
|
-
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)) {
|
|
93
|
-
throw new Error(
|
|
94
|
-
"Runtime evidence deployment snapshot is missing or invalid"
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
const strategies = value.strategies.map((candidate) => {
|
|
98
|
-
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)) {
|
|
99
|
-
throw new Error(
|
|
100
|
-
"Runtime evidence deployment strategy snapshot is invalid"
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
109
|
-
throw new Error(
|
|
110
|
-
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
return candidate;
|
|
114
|
-
});
|
|
115
|
-
const identities = /* @__PURE__ */ new Set();
|
|
116
|
-
for (const strategy of strategies) {
|
|
117
|
-
if (identities.has(strategy.strategyName)) {
|
|
118
|
-
throw new Error(
|
|
119
|
-
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
identities.add(strategy.strategyName);
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
...value,
|
|
126
|
-
strategies
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
130
|
-
var unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
131
|
-
const record = isRecord(candidate) ? candidate : null;
|
|
132
|
-
const nested = record && isRecord(record[field]) ? record[field] : null;
|
|
133
|
-
return nested ?? record;
|
|
134
|
-
}).filter((record) => record != null);
|
|
135
|
-
var assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
136
|
-
if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
137
|
-
throw new Error("Invalid runtime evidence artifact");
|
|
138
|
-
}
|
|
139
|
-
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
140
|
-
artifact.deployment
|
|
141
|
-
);
|
|
142
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(deployment);
|
|
143
|
-
if (activeStrategies.length === 0) {
|
|
144
|
-
throw new Error("Runtime evidence deployment has no enabled strategies");
|
|
145
|
-
}
|
|
146
|
-
const runtime = isRecord(artifact.runtime) ? artifact.runtime : null;
|
|
147
|
-
if (!runtime) {
|
|
148
|
-
throw new Error("Runtime evidence payload is missing");
|
|
149
|
-
}
|
|
150
|
-
if ("strategyConfigs" in runtime) {
|
|
151
|
-
throw new Error(
|
|
152
|
-
"Runtime evidence payload contains removed strategyConfigs data"
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
if ("evaluationStatsBuckets" in runtime) {
|
|
156
|
-
throw new Error(
|
|
157
|
-
"Runtime evidence payload contains removed lineage-less evaluationStatsBuckets data"
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
const rowFields = [
|
|
161
|
-
"trades",
|
|
162
|
-
"signals",
|
|
163
|
-
"evaluations",
|
|
164
|
-
"lineageScopes"
|
|
165
|
-
];
|
|
166
|
-
for (const field of rowFields) {
|
|
167
|
-
if (!Array.isArray(runtime[field])) {
|
|
168
|
-
throw new Error(`Runtime evidence payload ${field} must be an array`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
const snapshots = new Map(
|
|
172
|
-
activeStrategies.map((strategy) => [strategy.strategyName, strategy])
|
|
173
|
-
);
|
|
174
|
-
const assertRows = (label, rows, lineageField) => {
|
|
175
|
-
for (const row of rows) {
|
|
176
|
-
const strategyName = String(row.strategy ?? "").trim();
|
|
177
|
-
const strategy = snapshots.get(strategyName);
|
|
178
|
-
if (!strategy || row.deploymentId !== deployment.id || row.accountId !== deployment.accountId || !runtimeLineageMatchesStrategySnapshot({
|
|
179
|
-
lineage: isRecord(row[lineageField]) ? row[lineageField] : void 0,
|
|
180
|
-
deployment,
|
|
181
|
-
strategy
|
|
182
|
-
})) {
|
|
183
|
-
throw new Error(
|
|
184
|
-
`Runtime evidence ${label} row is outside the current embedded deployment lineage`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
assertRows(
|
|
190
|
-
"trade",
|
|
191
|
-
unwrapRuntimeEvidenceRows(runtime.trades, "trade"),
|
|
192
|
-
"runtimeLineage"
|
|
193
|
-
);
|
|
194
|
-
assertRows(
|
|
195
|
-
"signal",
|
|
196
|
-
unwrapRuntimeEvidenceRows(runtime.signals, "signal"),
|
|
197
|
-
"runtimeLineage"
|
|
198
|
-
);
|
|
199
|
-
assertRows(
|
|
200
|
-
"evaluation",
|
|
201
|
-
unwrapRuntimeEvidenceRows(runtime.evaluations, "evaluation"),
|
|
202
|
-
"runtimeLineage"
|
|
203
|
-
);
|
|
204
|
-
assertRows(
|
|
205
|
-
"lineage scope",
|
|
206
|
-
unwrapRuntimeEvidenceRows(runtime.lineageScopes, "lineageScope"),
|
|
207
|
-
"lineage"
|
|
208
|
-
);
|
|
209
|
-
return deployment;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
// src/lib/runtimeEvidenceArtifacts.ts
|
|
213
|
-
var RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
|
|
214
|
-
var RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
|
|
215
|
-
var RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
|
|
216
|
-
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
217
|
-
var sha256 = (value) => (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
|
|
218
|
-
var assertFiniteTimestamp = (value, label) => {
|
|
219
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
220
|
-
throw new Error(`Invalid runtime evidence ${label}`);
|
|
221
|
-
}
|
|
222
|
-
return value;
|
|
223
|
-
};
|
|
224
|
-
var parseManifest = (value) => {
|
|
225
|
-
const manifest = asRecord(value);
|
|
226
|
-
const window = asRecord(manifest?.window);
|
|
227
|
-
const payload = asRecord(manifest?.payload);
|
|
228
|
-
const counts = asRecord(manifest?.counts);
|
|
229
|
-
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)) {
|
|
230
|
-
throw new Error("Invalid runtime evidence manifest");
|
|
231
|
-
}
|
|
232
|
-
return {
|
|
233
|
-
schemaVersion: 1,
|
|
234
|
-
artifactId: manifest.artifactId,
|
|
235
|
-
reportType: "runtime-evidence",
|
|
236
|
-
deploymentId: manifest.deploymentId,
|
|
237
|
-
userName: manifest.userName,
|
|
238
|
-
createdAt: manifest.createdAt,
|
|
239
|
-
window: {
|
|
240
|
-
startTime: assertFiniteTimestamp(window?.startTime, "window.startTime"),
|
|
241
|
-
endTime: assertFiniteTimestamp(window?.endTime, "window.endTime")
|
|
242
|
-
},
|
|
243
|
-
payload: {
|
|
244
|
-
file: RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
245
|
-
sha256: payload.sha256,
|
|
246
|
-
bytes: payload.bytes
|
|
247
|
-
},
|
|
248
|
-
counts: Object.fromEntries(
|
|
249
|
-
Object.entries(counts ?? {}).filter(
|
|
250
|
-
(entry) => typeof entry[1] === "number" && Number.isFinite(entry[1])
|
|
251
|
-
)
|
|
252
|
-
),
|
|
253
|
-
lineageKeys: manifest.lineageKeys.filter(
|
|
254
|
-
(value2) => typeof value2 === "string" && value2.length > 0
|
|
255
|
-
)
|
|
256
|
-
};
|
|
257
|
-
};
|
|
258
|
-
var verifyRuntimeEvidenceBundle = async (bundleDir) => {
|
|
259
|
-
const manifestPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_MANIFEST_FILE);
|
|
260
|
-
const payloadPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_PAYLOAD_FILE);
|
|
261
|
-
const completePath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_COMPLETE_FILE);
|
|
262
|
-
const [manifestText, payload, completeText] = await Promise.all([
|
|
263
|
-
import_promises.default.readFile(manifestPath, "utf8"),
|
|
264
|
-
import_promises.default.readFile(payloadPath),
|
|
265
|
-
import_promises.default.readFile(completePath, "utf8")
|
|
266
|
-
]);
|
|
267
|
-
const manifest = parseManifest(JSON.parse(manifestText));
|
|
268
|
-
if (completeText.trim() !== manifest.artifactId) {
|
|
269
|
-
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
270
|
-
}
|
|
271
|
-
if (payload.byteLength !== manifest.payload.bytes) {
|
|
272
|
-
throw new Error(`Runtime evidence size mismatch in ${bundleDir}`);
|
|
273
|
-
}
|
|
274
|
-
if (sha256(payload) !== manifest.payload.sha256) {
|
|
275
|
-
throw new Error(`Runtime evidence checksum mismatch in ${bundleDir}`);
|
|
276
|
-
}
|
|
277
|
-
const artifact = asRecord(JSON.parse(payload.toString("utf8")));
|
|
278
|
-
const artifactWindow = asRecord(artifact?.window);
|
|
279
|
-
if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
|
|
280
|
-
throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
|
|
281
|
-
}
|
|
282
|
-
const deployment = assertCurrentRuntimeEvidenceArtifact(artifact);
|
|
283
|
-
if (deployment.id !== manifest.deploymentId) {
|
|
284
|
-
throw new Error(`Runtime evidence deployment mismatch in ${bundleDir}`);
|
|
285
|
-
}
|
|
286
|
-
return {
|
|
287
|
-
bundleDir,
|
|
288
|
-
manifestPath,
|
|
289
|
-
payloadPath,
|
|
290
|
-
manifest,
|
|
291
|
-
artifact
|
|
292
|
-
};
|
|
293
|
-
};
|
|
294
|
-
var discoverRuntimeEvidenceBundles = async (rootDir) => {
|
|
295
|
-
const bundles = [];
|
|
296
|
-
const visit = async (directory, depth) => {
|
|
297
|
-
if (depth > 8) return;
|
|
298
|
-
let entries;
|
|
299
|
-
try {
|
|
300
|
-
entries = await import_promises.default.readdir(directory, { withFileTypes: true });
|
|
301
|
-
} catch (error) {
|
|
302
|
-
if (error.code === "ENOENT") return;
|
|
303
|
-
throw error;
|
|
304
|
-
}
|
|
305
|
-
const names = new Set(entries.map((entry) => entry.name));
|
|
306
|
-
if (names.has(RUNTIME_EVIDENCE_MANIFEST_FILE) && names.has(RUNTIME_EVIDENCE_PAYLOAD_FILE) && names.has(RUNTIME_EVIDENCE_COMPLETE_FILE)) {
|
|
307
|
-
bundles.push(directory);
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
await Promise.all(
|
|
311
|
-
entries.filter(
|
|
312
|
-
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
313
|
-
).map((entry) => visit(import_node_path.default.join(directory, entry.name), depth + 1))
|
|
314
|
-
);
|
|
315
|
-
};
|
|
316
|
-
await visit(rootDir, 0);
|
|
317
|
-
return bundles.sort();
|
|
318
|
-
};
|
|
50
|
+
var runtimeEvidenceDeployment_exports = {};
|
|
51
|
+
__reExport(runtimeEvidenceDeployment_exports, require("@tradejs/node/diagnostics"));
|
|
319
52
|
|
|
320
53
|
// src/lib/runtimeEvidenceSync.ts
|
|
321
54
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
@@ -348,23 +81,23 @@ var buildRuntimeEvidenceRsyncArgs = ({
|
|
|
348
81
|
withTrailingSlash(source),
|
|
349
82
|
withTrailingSlash(destination)
|
|
350
83
|
];
|
|
351
|
-
var receiptPath = (receiptsRoot, artifactId) =>
|
|
84
|
+
var receiptPath = (receiptsRoot, artifactId) => import_node_path.default.join(receiptsRoot, `${safeSegment(artifactId, "artifact")}.json`);
|
|
352
85
|
var compareBundles = (left, right) => left.manifest.window.endTime - right.manifest.window.endTime || left.manifest.createdAt - right.manifest.createdAt;
|
|
353
86
|
var listPendingRuntimeEvidenceBundles = async ({
|
|
354
87
|
evidenceRoot,
|
|
355
88
|
deploymentId
|
|
356
89
|
}) => {
|
|
357
90
|
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
358
|
-
const artifactsRoot =
|
|
359
|
-
const receiptsRoot =
|
|
360
|
-
const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
|
|
91
|
+
const artifactsRoot = import_node_path.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
92
|
+
const receiptsRoot = import_node_path.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
93
|
+
const bundles = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(artifactsRoot);
|
|
361
94
|
const pending = [];
|
|
362
95
|
for (const bundleDir of bundles) {
|
|
363
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
96
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
364
97
|
if (verified.manifest.deploymentId !== safeDeploymentId) continue;
|
|
365
|
-
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
98
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
|
|
366
99
|
try {
|
|
367
|
-
await
|
|
100
|
+
await import_promises.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
|
|
368
101
|
continue;
|
|
369
102
|
} catch (error) {
|
|
370
103
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -381,13 +114,13 @@ var markRuntimeEvidenceBundleProcessed = async ({
|
|
|
381
114
|
runtimeFeedback
|
|
382
115
|
}) => {
|
|
383
116
|
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
384
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
117
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
385
118
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
386
119
|
throw new Error(
|
|
387
120
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
388
121
|
);
|
|
389
122
|
}
|
|
390
|
-
const receiptsRoot =
|
|
123
|
+
const receiptsRoot = import_node_path.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
391
124
|
const finalPath = receiptPath(receiptsRoot, verified.manifest.artifactId);
|
|
392
125
|
const temporaryPath = `${finalPath}.tmp-${process.pid}`;
|
|
393
126
|
const receipt = {
|
|
@@ -401,14 +134,14 @@ var markRuntimeEvidenceBundleProcessed = async ({
|
|
|
401
134
|
replayEvidenceSha256: runtimeFeedback.replayEvidenceSha256
|
|
402
135
|
} : {}
|
|
403
136
|
};
|
|
404
|
-
await
|
|
405
|
-
await
|
|
137
|
+
await import_promises.default.mkdir(receiptsRoot, { recursive: true });
|
|
138
|
+
await import_promises.default.writeFile(
|
|
406
139
|
temporaryPath,
|
|
407
140
|
`${JSON.stringify(receipt, null, 2)}
|
|
408
141
|
`,
|
|
409
142
|
"utf8"
|
|
410
143
|
);
|
|
411
|
-
await
|
|
144
|
+
await import_promises.default.rename(temporaryPath, finalPath);
|
|
412
145
|
return finalPath;
|
|
413
146
|
};
|
|
414
147
|
var syncRuntimeEvidenceBundles = async ({
|
|
@@ -423,46 +156,46 @@ var syncRuntimeEvidenceBundles = async ({
|
|
|
423
156
|
}
|
|
424
157
|
}) => {
|
|
425
158
|
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
426
|
-
const inboxRoot =
|
|
427
|
-
const artifactsRoot =
|
|
159
|
+
const inboxRoot = import_node_path.default.join(evidenceRoot, "inbox", safeDeploymentId);
|
|
160
|
+
const artifactsRoot = import_node_path.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
428
161
|
await Promise.all([
|
|
429
|
-
|
|
430
|
-
|
|
162
|
+
import_promises.default.mkdir(inboxRoot, { recursive: true }),
|
|
163
|
+
import_promises.default.mkdir(artifactsRoot, { recursive: true })
|
|
431
164
|
]);
|
|
432
165
|
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
433
166
|
source,
|
|
434
167
|
destination: inboxRoot
|
|
435
168
|
});
|
|
436
169
|
const transfer = await runRsync(rsyncArgs);
|
|
437
|
-
const discovered = await discoverRuntimeEvidenceBundles(inboxRoot);
|
|
170
|
+
const discovered = await (0, runtimeEvidenceArtifacts_exports.discoverRuntimeEvidenceBundles)(inboxRoot);
|
|
438
171
|
const received = [];
|
|
439
172
|
for (const bundleDir of discovered) {
|
|
440
|
-
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
173
|
+
const verified = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(bundleDir);
|
|
441
174
|
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
442
175
|
throw new Error(
|
|
443
176
|
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
444
177
|
);
|
|
445
178
|
}
|
|
446
|
-
assertCurrentRuntimeEvidenceArtifact(verified.artifact);
|
|
447
|
-
const destinationDir =
|
|
179
|
+
(0, runtimeEvidenceDeployment_exports.assertCurrentRuntimeEvidenceArtifact)(verified.artifact);
|
|
180
|
+
const destinationDir = import_node_path.default.join(
|
|
448
181
|
artifactsRoot,
|
|
449
182
|
...dateParts(verified.manifest.window.endTime),
|
|
450
183
|
safeSegment(verified.manifest.artifactId, "artifact")
|
|
451
184
|
);
|
|
452
|
-
await
|
|
185
|
+
await import_promises.default.mkdir(import_node_path.default.dirname(destinationDir), { recursive: true });
|
|
453
186
|
try {
|
|
454
|
-
await
|
|
187
|
+
await import_promises.default.rename(bundleDir, destinationDir);
|
|
455
188
|
} catch (error) {
|
|
456
189
|
if (!isExistingDestinationError(error)) throw error;
|
|
457
|
-
const existing = await verifyRuntimeEvidenceBundle(destinationDir);
|
|
190
|
+
const existing = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir);
|
|
458
191
|
if (existing.manifest.payload.sha256 !== verified.manifest.payload.sha256) {
|
|
459
192
|
throw new Error(
|
|
460
193
|
`Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
|
|
461
194
|
);
|
|
462
195
|
}
|
|
463
|
-
await
|
|
196
|
+
await import_promises.default.rm(bundleDir, { recursive: true, force: true });
|
|
464
197
|
}
|
|
465
|
-
received.push(await verifyRuntimeEvidenceBundle(destinationDir));
|
|
198
|
+
received.push(await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(destinationDir));
|
|
466
199
|
}
|
|
467
200
|
const pending = await listPendingRuntimeEvidenceBundles({
|
|
468
201
|
evidenceRoot,
|