@tradejs/cli 3.1.27-beta.248 → 3.1.27-beta.250
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 +603 -207
- package/dist/lib/runtimeEvidenceCompositionSnapshots.js +432 -0
- package/dist/lib/runtimeEvidenceCompositions.js +548 -0
- package/dist/scripts/runtimeEvidence.js +375 -112
- package/dist/scripts/signals.js +396 -18
- package/dist/scripts/signalsDaemon.js +396 -18
- package/package.json +7 -7
|
@@ -34,8 +34,8 @@ __export(runtimeEvidence_exports, {
|
|
|
34
34
|
runtimeEvidence: () => runtimeEvidence
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(runtimeEvidence_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
37
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
38
|
+
var import_node_path4 = __toESM(require("path"));
|
|
39
39
|
var import_args = __toESM(require("args"));
|
|
40
40
|
var import_chalk = __toESM(require("chalk"));
|
|
41
41
|
|
|
@@ -851,35 +851,51 @@ var verifyRuntimeEvidenceBundle = async (bundleDir) => {
|
|
|
851
851
|
artifact
|
|
852
852
|
};
|
|
853
853
|
};
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
854
|
+
var discoverRuntimeEvidenceBundles = async (rootDir) => {
|
|
855
|
+
const bundles = [];
|
|
856
|
+
const visit = async (directory, depth) => {
|
|
857
|
+
if (depth > 8) return;
|
|
858
|
+
let entries;
|
|
859
|
+
try {
|
|
860
|
+
entries = await import_promises.default.readdir(directory, { withFileTypes: true });
|
|
861
|
+
} catch (error) {
|
|
862
|
+
if (error.code === "ENOENT") return;
|
|
863
|
+
throw error;
|
|
864
|
+
}
|
|
865
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
866
|
+
if (names.has(RUNTIME_EVIDENCE_MANIFEST_FILE) && names.has(RUNTIME_EVIDENCE_PAYLOAD_FILE) && names.has(RUNTIME_EVIDENCE_COMPLETE_FILE)) {
|
|
867
|
+
bundles.push(directory);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
await Promise.all(
|
|
871
|
+
entries.filter(
|
|
872
|
+
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
873
|
+
).map((entry) => visit(import_node_path.default.join(directory, entry.name), depth + 1))
|
|
864
874
|
);
|
|
865
|
-
}
|
|
866
|
-
|
|
875
|
+
};
|
|
876
|
+
await visit(rootDir, 0);
|
|
877
|
+
return bundles.sort();
|
|
867
878
|
};
|
|
868
|
-
var fingerprintRuntimeValue = (value) => (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
869
|
-
var runtimeLineageKey = (lineage) => [
|
|
870
|
-
"v3",
|
|
871
|
-
lineage.deploymentCompositionId,
|
|
872
|
-
lineage.strategyRevision,
|
|
873
|
-
lineage.strategyPackageVersion,
|
|
874
|
-
`deps:${fingerprintRuntimeValue(lineage.strategyDependencyVersions).slice(0, 16)}`,
|
|
875
|
-
lineage.runtimePackageVersion
|
|
876
|
-
].join(":");
|
|
877
879
|
|
|
878
|
-
// src/lib/
|
|
880
|
+
// src/lib/runtimeEvidenceCompositionSnapshots.ts
|
|
879
881
|
var import_node_crypto3 = require("crypto");
|
|
882
|
+
var import_promises3 = __toESM(require("fs/promises"));
|
|
883
|
+
var import_node_path3 = __toESM(require("path"));
|
|
884
|
+
|
|
885
|
+
// src/lib/runtimeEvidenceProducer.ts
|
|
886
|
+
var import_node_crypto2 = require("crypto");
|
|
880
887
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
881
888
|
var import_node_path2 = __toESM(require("path"));
|
|
882
|
-
var
|
|
889
|
+
var isRecord2 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
890
|
+
var sha2562 = (value) => (0, import_node_crypto2.createHash)("sha256").update(value).digest("hex");
|
|
891
|
+
var parseRuntimeEvidenceProducer = (value) => {
|
|
892
|
+
const producer = isRecord2(value) ? value : null;
|
|
893
|
+
const runtimePackageManifest = isRecord2(producer?.runtimePackageManifest) ? producer.runtimePackageManifest : null;
|
|
894
|
+
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)) {
|
|
895
|
+
throw new Error("Runtime evidence producer image identity is invalid");
|
|
896
|
+
}
|
|
897
|
+
return producer;
|
|
898
|
+
};
|
|
883
899
|
var resolveRuntimeEvidenceProducer = async ({
|
|
884
900
|
projectRoot: projectRoot2,
|
|
885
901
|
required
|
|
@@ -925,6 +941,241 @@ var resolveRuntimeEvidenceProducer = async ({
|
|
|
925
941
|
};
|
|
926
942
|
};
|
|
927
943
|
|
|
944
|
+
// src/lib/runtimeEvidenceCompositionSnapshots.ts
|
|
945
|
+
var SNAPSHOT_FILE = "snapshot.json";
|
|
946
|
+
var MANIFEST_FILE = "manifest.json";
|
|
947
|
+
var COMPLETE_FILE = ".complete";
|
|
948
|
+
var isRecord3 = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
949
|
+
var sha2563 = (value) => (0, import_node_crypto3.createHash)("sha256").update(value).digest("hex");
|
|
950
|
+
var parseManifest2 = (value) => {
|
|
951
|
+
const manifest = isRecord3(value) ? value : null;
|
|
952
|
+
const payload = isRecord3(manifest?.payload) ? manifest.payload : null;
|
|
953
|
+
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence-composition-snapshot" || typeof manifest.createdAt !== "number" || typeof manifest.userName !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.deploymentCompositionId !== "string" || payload?.file !== SNAPSHOT_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number") {
|
|
954
|
+
throw new Error("Invalid runtime evidence composition snapshot manifest");
|
|
955
|
+
}
|
|
956
|
+
return manifest;
|
|
957
|
+
};
|
|
958
|
+
var verifyRuntimeEvidenceCompositionSnapshot = async (bundleDir) => {
|
|
959
|
+
const [manifestText, payload, completeText] = await Promise.all([
|
|
960
|
+
import_promises3.default.readFile(import_node_path3.default.join(bundleDir, MANIFEST_FILE), "utf8"),
|
|
961
|
+
import_promises3.default.readFile(import_node_path3.default.join(bundleDir, SNAPSHOT_FILE)),
|
|
962
|
+
import_promises3.default.readFile(import_node_path3.default.join(bundleDir, COMPLETE_FILE), "utf8")
|
|
963
|
+
]);
|
|
964
|
+
const manifest = parseManifest2(JSON.parse(manifestText));
|
|
965
|
+
if (completeText.trim() !== manifest.deploymentCompositionId) {
|
|
966
|
+
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
967
|
+
}
|
|
968
|
+
if (payload.byteLength !== manifest.payload.bytes || sha2563(payload) !== manifest.payload.sha256) {
|
|
969
|
+
throw new Error(
|
|
970
|
+
`Runtime evidence snapshot checksum mismatch in ${bundleDir}`
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
const value = JSON.parse(payload.toString("utf8"));
|
|
974
|
+
const record = isRecord3(value) ? value : null;
|
|
975
|
+
if (record?.schemaVersion !== 1 || record.reportType !== "runtime-evidence-composition-snapshot" || record.userName !== manifest.userName) {
|
|
976
|
+
throw new Error(
|
|
977
|
+
`Invalid runtime evidence snapshot payload in ${bundleDir}`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
const deployment = parseRuntimeEvidenceDeploymentSnapshot(record.deployment);
|
|
981
|
+
const producer = parseRuntimeEvidenceProducer(record.producer);
|
|
982
|
+
if (deployment.id !== manifest.deploymentId || deployment.deploymentCompositionId !== manifest.deploymentCompositionId) {
|
|
983
|
+
throw new Error(
|
|
984
|
+
`Runtime evidence snapshot identity mismatch in ${bundleDir}`
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
return { bundleDir, deployment, producer };
|
|
988
|
+
};
|
|
989
|
+
var discoverRuntimeEvidenceCompositionSnapshots = async (evidenceRoot) => {
|
|
990
|
+
const rootDir = import_node_path3.default.join(evidenceRoot, "snapshots");
|
|
991
|
+
const bundleDirs = [];
|
|
992
|
+
let deployments;
|
|
993
|
+
try {
|
|
994
|
+
deployments = await import_promises3.default.readdir(rootDir, { withFileTypes: true });
|
|
995
|
+
} catch (error) {
|
|
996
|
+
if (error.code === "ENOENT") return [];
|
|
997
|
+
throw error;
|
|
998
|
+
}
|
|
999
|
+
for (const deployment of deployments.filter((entry) => entry.isDirectory())) {
|
|
1000
|
+
const deploymentDir = import_node_path3.default.join(rootDir, deployment.name);
|
|
1001
|
+
const compositions = await import_promises3.default.readdir(deploymentDir, {
|
|
1002
|
+
withFileTypes: true
|
|
1003
|
+
});
|
|
1004
|
+
bundleDirs.push(
|
|
1005
|
+
...compositions.filter(
|
|
1006
|
+
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
1007
|
+
).map((entry) => import_node_path3.default.join(deploymentDir, entry.name))
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
return Promise.all(
|
|
1011
|
+
bundleDirs.sort().map(verifyRuntimeEvidenceCompositionSnapshot)
|
|
1012
|
+
);
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
// src/lib/runtimeEvidenceCompositions.ts
|
|
1016
|
+
var stableSnapshotIdentity = (deployment) => JSON.stringify({ ...deployment, tickers: void 0 });
|
|
1017
|
+
var producerIdentity = (producer) => JSON.stringify(producer);
|
|
1018
|
+
var loadRuntimeEvidenceCompositionSnapshots = async ({
|
|
1019
|
+
publishRoot,
|
|
1020
|
+
currentDeployment,
|
|
1021
|
+
currentProducer
|
|
1022
|
+
}) => {
|
|
1023
|
+
const snapshots = /* @__PURE__ */ new Map();
|
|
1024
|
+
const register = (snapshot) => {
|
|
1025
|
+
const compositionId = snapshot.deployment.deploymentCompositionId;
|
|
1026
|
+
const known = snapshots.get(compositionId);
|
|
1027
|
+
if (known && (stableSnapshotIdentity(known.deployment) !== stableSnapshotIdentity(snapshot.deployment) || producerIdentity(known.producer) !== producerIdentity(snapshot.producer))) {
|
|
1028
|
+
throw new Error(
|
|
1029
|
+
`Conflicting runtime evidence snapshot for composition ${compositionId}`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
snapshots.set(compositionId, snapshot);
|
|
1033
|
+
};
|
|
1034
|
+
const compositionSnapshots = await discoverRuntimeEvidenceCompositionSnapshots(publishRoot);
|
|
1035
|
+
for (const snapshot of compositionSnapshots) {
|
|
1036
|
+
if (snapshot.deployment.id !== currentDeployment.id) continue;
|
|
1037
|
+
register({
|
|
1038
|
+
deployment: { ...snapshot.deployment, tickers: void 0 },
|
|
1039
|
+
producer: snapshot.producer
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
const bundleDirs = await discoverRuntimeEvidenceBundles(publishRoot);
|
|
1043
|
+
for (const bundleDir of bundleDirs) {
|
|
1044
|
+
const bundle = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
1045
|
+
const deployment = parseRuntimeEvidenceDeploymentSnapshot(
|
|
1046
|
+
bundle.artifact.deployment
|
|
1047
|
+
);
|
|
1048
|
+
if (deployment.id !== currentDeployment.id) continue;
|
|
1049
|
+
if (bundle.artifact.producer == null) continue;
|
|
1050
|
+
register({
|
|
1051
|
+
deployment: { ...deployment, tickers: void 0 },
|
|
1052
|
+
producer: parseRuntimeEvidenceProducer(bundle.artifact.producer)
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
const historicalCurrent = snapshots.get(
|
|
1056
|
+
currentDeployment.deploymentCompositionId
|
|
1057
|
+
);
|
|
1058
|
+
if (historicalCurrent && stableSnapshotIdentity(historicalCurrent.deployment) !== stableSnapshotIdentity(currentDeployment)) {
|
|
1059
|
+
throw new Error(
|
|
1060
|
+
`Current runtime deployment conflicts with stored composition ${currentDeployment.deploymentCompositionId}`
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
snapshots.set(currentDeployment.deploymentCompositionId, {
|
|
1064
|
+
deployment: { ...currentDeployment, tickers: void 0 },
|
|
1065
|
+
producer: currentProducer
|
|
1066
|
+
});
|
|
1067
|
+
return snapshots;
|
|
1068
|
+
};
|
|
1069
|
+
var rowCompositionId = (row) => row.runtimeLineage?.deploymentCompositionId ?? row.lineage?.deploymentCompositionId ?? null;
|
|
1070
|
+
var rowTimestamp = (row) => {
|
|
1071
|
+
for (const field of [
|
|
1072
|
+
"firstTimestamp",
|
|
1073
|
+
"entryTimestamp",
|
|
1074
|
+
"timestamp",
|
|
1075
|
+
"lastTimestamp"
|
|
1076
|
+
]) {
|
|
1077
|
+
const value = row[field];
|
|
1078
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1079
|
+
}
|
|
1080
|
+
return Number.POSITIVE_INFINITY;
|
|
1081
|
+
};
|
|
1082
|
+
var belongsToSnapshot = (row, deployment) => {
|
|
1083
|
+
const strategy = activeRuntimeEvidenceStrategies(deployment).find(
|
|
1084
|
+
(candidate) => candidate.strategyName === row.strategy
|
|
1085
|
+
);
|
|
1086
|
+
return Boolean(
|
|
1087
|
+
strategy && row.deploymentId === deployment.id && row.accountId === deployment.accountId && runtimeLineageMatchesStrategySnapshot({
|
|
1088
|
+
lineage: row.runtimeLineage ?? row.lineage,
|
|
1089
|
+
deployment,
|
|
1090
|
+
strategy
|
|
1091
|
+
})
|
|
1092
|
+
);
|
|
1093
|
+
};
|
|
1094
|
+
var splitRuntimeEvidenceByComposition = ({
|
|
1095
|
+
evidence,
|
|
1096
|
+
snapshots,
|
|
1097
|
+
includeEmptyCompositionIds = [],
|
|
1098
|
+
ignoreUnknownCompositions = false
|
|
1099
|
+
}) => {
|
|
1100
|
+
const observed = /* @__PURE__ */ new Set();
|
|
1101
|
+
for (const row of [
|
|
1102
|
+
...evidence.trades,
|
|
1103
|
+
...evidence.signals,
|
|
1104
|
+
...evidence.evaluations,
|
|
1105
|
+
...evidence.lineageScopes
|
|
1106
|
+
]) {
|
|
1107
|
+
const compositionId = rowCompositionId(row);
|
|
1108
|
+
if (compositionId) observed.add(compositionId);
|
|
1109
|
+
}
|
|
1110
|
+
for (const compositionId of includeEmptyCompositionIds) {
|
|
1111
|
+
observed.add(compositionId);
|
|
1112
|
+
}
|
|
1113
|
+
const missing = [...observed].filter(
|
|
1114
|
+
(compositionId) => !snapshots.has(compositionId)
|
|
1115
|
+
);
|
|
1116
|
+
if (missing.length && !ignoreUnknownCompositions) {
|
|
1117
|
+
throw new Error(
|
|
1118
|
+
`Runtime evidence has no verified deployment snapshot for composition(s): ${missing.sort().join(", ")}`
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
return [...observed].filter((compositionId) => snapshots.has(compositionId)).map((compositionId) => snapshots.get(compositionId)).map(({ deployment, producer }) => {
|
|
1122
|
+
const trades = evidence.trades.filter(
|
|
1123
|
+
(row) => belongsToSnapshot(row, deployment)
|
|
1124
|
+
);
|
|
1125
|
+
const signals = evidence.signals.filter(
|
|
1126
|
+
(row) => belongsToSnapshot(row, deployment)
|
|
1127
|
+
);
|
|
1128
|
+
const evaluations = evidence.evaluations.filter(
|
|
1129
|
+
(row) => belongsToSnapshot(row, deployment)
|
|
1130
|
+
);
|
|
1131
|
+
const lineageScopes = evidence.lineageScopes.filter(
|
|
1132
|
+
(row) => belongsToSnapshot(row, deployment)
|
|
1133
|
+
);
|
|
1134
|
+
const timestamps = [
|
|
1135
|
+
...trades,
|
|
1136
|
+
...signals,
|
|
1137
|
+
...evaluations,
|
|
1138
|
+
...lineageScopes
|
|
1139
|
+
].map((row) => rowTimestamp(row));
|
|
1140
|
+
return {
|
|
1141
|
+
deployment,
|
|
1142
|
+
producer,
|
|
1143
|
+
trades,
|
|
1144
|
+
signals,
|
|
1145
|
+
evaluations,
|
|
1146
|
+
lineageScopes,
|
|
1147
|
+
firstTimestamp: Math.min(...timestamps)
|
|
1148
|
+
};
|
|
1149
|
+
}).sort(
|
|
1150
|
+
(left, right) => left.firstTimestamp - right.firstTimestamp || left.deployment.deploymentCompositionId.localeCompare(
|
|
1151
|
+
right.deployment.deploymentCompositionId
|
|
1152
|
+
)
|
|
1153
|
+
);
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1156
|
+
// src/lib/runtimeLineage.ts
|
|
1157
|
+
var import_node_crypto4 = require("crypto");
|
|
1158
|
+
var normalizeForStableJson = (value) => {
|
|
1159
|
+
if (Array.isArray(value)) {
|
|
1160
|
+
return value.map(normalizeForStableJson);
|
|
1161
|
+
}
|
|
1162
|
+
if (value && typeof value === "object") {
|
|
1163
|
+
return Object.fromEntries(
|
|
1164
|
+
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, normalizeForStableJson(entry)])
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
return value;
|
|
1168
|
+
};
|
|
1169
|
+
var fingerprintRuntimeValue = (value) => (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
1170
|
+
var runtimeLineageKey = (lineage) => [
|
|
1171
|
+
"v3",
|
|
1172
|
+
lineage.deploymentCompositionId,
|
|
1173
|
+
lineage.strategyRevision,
|
|
1174
|
+
lineage.strategyPackageVersion,
|
|
1175
|
+
`deps:${fingerprintRuntimeValue(lineage.strategyDependencyVersions).slice(0, 16)}`,
|
|
1176
|
+
lineage.runtimePackageVersion
|
|
1177
|
+
].join(":");
|
|
1178
|
+
|
|
928
1179
|
// src/scripts/runtimeEvidence.ts
|
|
929
1180
|
import_args.default.option(["u", "user"], "Use user config", "root");
|
|
930
1181
|
import_args.default.option(
|
|
@@ -1015,15 +1266,30 @@ var runtimeEvidence = async () => {
|
|
|
1015
1266
|
projectRoot,
|
|
1016
1267
|
deploymentId
|
|
1017
1268
|
});
|
|
1018
|
-
const activeStrategies = activeRuntimeEvidenceStrategies(
|
|
1019
|
-
deploymentSnapshot
|
|
1020
|
-
).map(({ strategyName }) => strategyName);
|
|
1021
1269
|
const requestedStrategies = parseStrategyFilter(flags.strategy);
|
|
1022
|
-
const
|
|
1270
|
+
const evidence = await collectRuntimeDebugEvidence({
|
|
1271
|
+
userName: flags.user,
|
|
1272
|
+
startTime,
|
|
1273
|
+
endTime,
|
|
1274
|
+
strategies: requestedStrategies.length ? requestedStrategies : void 0,
|
|
1275
|
+
deploymentId
|
|
1276
|
+
});
|
|
1277
|
+
const snapshots = publishDir && producer ? await loadRuntimeEvidenceCompositionSnapshots({
|
|
1278
|
+
publishRoot: import_node_path4.default.resolve(projectRoot, publishDir),
|
|
1279
|
+
currentDeployment: deploymentSnapshot,
|
|
1280
|
+
currentProducer: producer
|
|
1281
|
+
}) : /* @__PURE__ */ new Map([
|
|
1282
|
+
[
|
|
1283
|
+
deploymentSnapshot.deploymentCompositionId,
|
|
1284
|
+
{ deployment: deploymentSnapshot, producer }
|
|
1285
|
+
]
|
|
1286
|
+
]);
|
|
1023
1287
|
const declaredStrategies = new Set(
|
|
1024
|
-
|
|
1288
|
+
[...snapshots.values()].flatMap(
|
|
1289
|
+
({ deployment }) => deployment.strategies.map(({ strategyName }) => strategyName)
|
|
1290
|
+
)
|
|
1025
1291
|
);
|
|
1026
|
-
const unknownStrategies =
|
|
1292
|
+
const unknownStrategies = requestedStrategies.filter(
|
|
1027
1293
|
(strategyName) => !declaredStrategies.has(strategyName)
|
|
1028
1294
|
);
|
|
1029
1295
|
if (unknownStrategies.length) {
|
|
@@ -1031,97 +1297,94 @@ var runtimeEvidence = async () => {
|
|
|
1031
1297
|
`Strategies are not declared in ${deploymentId}: ${unknownStrategies.join(", ")}`
|
|
1032
1298
|
);
|
|
1033
1299
|
}
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
deploymentId
|
|
1300
|
+
const compositionRows = splitRuntimeEvidenceByComposition({
|
|
1301
|
+
evidence,
|
|
1302
|
+
snapshots,
|
|
1303
|
+
includeEmptyCompositionIds: publishDir ? [] : [deploymentSnapshot.deploymentCompositionId],
|
|
1304
|
+
ignoreUnknownCompositions: !publishDir
|
|
1040
1305
|
});
|
|
1041
|
-
const
|
|
1042
|
-
activeRuntimeEvidenceStrategies(
|
|
1043
|
-
|
|
1044
|
-
strategy
|
|
1045
|
-
])
|
|
1046
|
-
);
|
|
1047
|
-
const belongsToCurrentDeployment = (row) => {
|
|
1048
|
-
const snapshot = activeSnapshots.get(row.strategy);
|
|
1049
|
-
return Boolean(
|
|
1050
|
-
snapshot && row.deploymentId === deploymentSnapshot.id && row.accountId === deploymentSnapshot.accountId && runtimeLineageMatchesStrategySnapshot({
|
|
1051
|
-
lineage: row.runtimeLineage,
|
|
1052
|
-
deployment: deploymentSnapshot,
|
|
1053
|
-
strategy: snapshot
|
|
1054
|
-
})
|
|
1306
|
+
const artifacts = compositionRows.map((composition) => {
|
|
1307
|
+
const strategies = activeRuntimeEvidenceStrategies(composition.deployment).map(({ strategyName }) => strategyName).filter(
|
|
1308
|
+
(strategyName) => !requestedStrategies.length || requestedStrategies.includes(strategyName)
|
|
1055
1309
|
);
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
const currentEvaluations = evidence.evaluations.filter(
|
|
1059
|
-
belongsToCurrentDeployment
|
|
1060
|
-
);
|
|
1061
|
-
const currentTrades = evidence.trades.filter(belongsToCurrentDeployment);
|
|
1062
|
-
const currentLineageScopes = evidence.lineageScopes.filter(
|
|
1063
|
-
(scope) => belongsToCurrentDeployment({
|
|
1064
|
-
...scope,
|
|
1065
|
-
runtimeLineage: scope.lineage
|
|
1066
|
-
})
|
|
1067
|
-
);
|
|
1068
|
-
const runtime = buildRuntimeEvidenceReportPayload({
|
|
1069
|
-
userName: flags.user,
|
|
1070
|
-
startTime,
|
|
1071
|
-
endTime,
|
|
1072
|
-
signals: currentSignals,
|
|
1073
|
-
evaluations: currentEvaluations,
|
|
1074
|
-
trades: currentTrades,
|
|
1075
|
-
lineageScopes: currentLineageScopes
|
|
1076
|
-
});
|
|
1077
|
-
const deployment = resolveRuntimeEvidenceTickerUniverse({
|
|
1078
|
-
deployment: deploymentSnapshot,
|
|
1079
|
-
lineageScopes: currentLineageScopes
|
|
1080
|
-
});
|
|
1081
|
-
const artifact = {
|
|
1082
|
-
reportType: "runtime-evidence",
|
|
1083
|
-
generatedAt: Date.now(),
|
|
1084
|
-
...producer ? { producer } : {},
|
|
1085
|
-
userName: flags.user,
|
|
1086
|
-
window: {
|
|
1310
|
+
const runtime = buildRuntimeEvidenceReportPayload({
|
|
1311
|
+
userName: flags.user,
|
|
1087
1312
|
startTime,
|
|
1088
1313
|
endTime,
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
deployment
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1314
|
+
signals: composition.signals,
|
|
1315
|
+
evaluations: composition.evaluations,
|
|
1316
|
+
trades: composition.trades,
|
|
1317
|
+
lineageScopes: composition.lineageScopes
|
|
1318
|
+
});
|
|
1319
|
+
const deployment = resolveRuntimeEvidenceTickerUniverse({
|
|
1320
|
+
deployment: composition.deployment,
|
|
1321
|
+
lineageScopes: composition.lineageScopes
|
|
1322
|
+
});
|
|
1323
|
+
return {
|
|
1324
|
+
artifact: {
|
|
1325
|
+
reportType: "runtime-evidence",
|
|
1326
|
+
generatedAt: Date.now(),
|
|
1327
|
+
...composition.producer ? { producer: composition.producer } : {},
|
|
1328
|
+
...producer && composition.producer && composition.producer !== producer ? { collector: producer } : {},
|
|
1329
|
+
userName: flags.user,
|
|
1330
|
+
window: {
|
|
1331
|
+
startTime,
|
|
1332
|
+
endTime,
|
|
1333
|
+
startIso: new Date(startTime).toISOString(),
|
|
1334
|
+
endIso: new Date(endTime).toISOString(),
|
|
1335
|
+
source
|
|
1336
|
+
},
|
|
1337
|
+
strategies,
|
|
1338
|
+
deployment,
|
|
1339
|
+
runtime
|
|
1340
|
+
},
|
|
1341
|
+
composition
|
|
1342
|
+
};
|
|
1343
|
+
});
|
|
1344
|
+
const current = artifacts.find(
|
|
1345
|
+
({ artifact: artifact2 }) => artifact2.deployment.deploymentCompositionId === deploymentSnapshot.deploymentCompositionId
|
|
1346
|
+
) ?? artifacts.at(-1);
|
|
1347
|
+
if (!current) {
|
|
1348
|
+
throw new Error("Runtime evidence window has no versioned runtime rows");
|
|
1349
|
+
}
|
|
1350
|
+
const artifact = current.artifact;
|
|
1351
|
+
const outPath = import_node_path4.default.resolve(projectRoot, String(flags.out));
|
|
1352
|
+
await import_promises4.default.mkdir(import_node_path4.default.dirname(outPath), { recursive: true });
|
|
1353
|
+
await import_promises4.default.writeFile(outPath, `${JSON.stringify(artifact, null, 2)}
|
|
1100
1354
|
`, "utf8");
|
|
1101
|
-
const published = publishDir ? await
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1355
|
+
const published = publishDir ? await Promise.all(
|
|
1356
|
+
artifacts.map(
|
|
1357
|
+
({ artifact: artifact2, composition }) => publishRuntimeEvidenceBundle({
|
|
1358
|
+
publishRoot: import_node_path4.default.resolve(projectRoot, publishDir),
|
|
1359
|
+
deploymentId,
|
|
1360
|
+
userName: String(flags.user),
|
|
1361
|
+
startTime,
|
|
1362
|
+
endTime,
|
|
1363
|
+
artifact: artifact2,
|
|
1364
|
+
counts: artifact2.runtime.counts,
|
|
1365
|
+
lineageKeys: [
|
|
1366
|
+
...composition.signals.map((signal) => signal.runtimeLineage),
|
|
1367
|
+
...composition.evaluations.map(
|
|
1368
|
+
(evaluation) => evaluation.runtimeLineage
|
|
1369
|
+
),
|
|
1370
|
+
...composition.trades.map((trade) => trade.runtimeLineage),
|
|
1371
|
+
...composition.lineageScopes.map((scope) => scope.lineage)
|
|
1372
|
+
].filter((lineage) => lineage != null).map(runtimeLineageKey).filter((key, index, values) => values.indexOf(key) === index)
|
|
1373
|
+
})
|
|
1374
|
+
)
|
|
1375
|
+
) : [];
|
|
1116
1376
|
console.log(import_chalk.default.green(`Wrote ${outPath}`));
|
|
1117
|
-
|
|
1118
|
-
console.log(import_chalk.default.green(`Published ${
|
|
1377
|
+
for (const bundle of published) {
|
|
1378
|
+
console.log(import_chalk.default.green(`Published ${bundle.bundleDir}`));
|
|
1119
1379
|
}
|
|
1120
1380
|
console.log(
|
|
1121
1381
|
JSON.stringify(
|
|
1122
1382
|
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1383
|
+
compositions: artifacts.map(({ artifact: artifact2 }) => ({
|
|
1384
|
+
deploymentCompositionId: artifact2.deployment.deploymentCompositionId,
|
|
1385
|
+
strategies: artifact2.strategies,
|
|
1386
|
+
runtimeCounts: artifact2.runtime.counts
|
|
1387
|
+
}))
|
|
1125
1388
|
},
|
|
1126
1389
|
null,
|
|
1127
1390
|
2
|