@uns-kit/core 3.0.28 → 3.0.30
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/MIGRATIONS.md +100 -0
- package/README.md +10 -0
- package/dist/config/app-config.d.ts +14 -0
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/configuration-group-authorization.d.ts +50 -0
- package/dist/runtime/configuration-group-authorization.d.ts.map +1 -0
- package/dist/runtime/configuration-group-authorization.js +113 -0
- package/dist/runtime/configuration-group-authorization.js.map +1 -0
- package/dist/runtime/configuration-group-contract.d.ts +75 -0
- package/dist/runtime/configuration-group-contract.d.ts.map +1 -0
- package/dist/runtime/configuration-group-contract.js +233 -0
- package/dist/runtime/configuration-group-contract.js.map +1 -0
- package/dist/runtime/process-group-authorization.d.ts +2 -0
- package/dist/runtime/process-group-authorization.d.ts.map +1 -1
- package/dist/runtime/process-group-authorization.js +34 -12
- package/dist/runtime/process-group-authorization.js.map +1 -1
- package/dist/runtime/process-group-backup-contract.d.ts +22 -0
- package/dist/runtime/process-group-backup-contract.d.ts.map +1 -0
- package/dist/runtime/process-group-backup-contract.js +20 -0
- package/dist/runtime/process-group-backup-contract.js.map +1 -0
- package/dist/runtime/process-group-backup-contract.json +7 -0
- package/dist/runtime/process-group-configured-upgrade.d.ts +4 -0
- package/dist/runtime/process-group-configured-upgrade.d.ts.map +1 -0
- package/dist/runtime/process-group-configured-upgrade.js +107 -0
- package/dist/runtime/process-group-configured-upgrade.js.map +1 -0
- package/dist/runtime/process-group-generation.d.ts +166 -0
- package/dist/runtime/process-group-generation.d.ts.map +1 -0
- package/dist/runtime/process-group-generation.js +278 -0
- package/dist/runtime/process-group-generation.js.map +1 -0
- package/dist/runtime/process-group-inspection.d.ts +2 -0
- package/dist/runtime/process-group-inspection.d.ts.map +1 -1
- package/dist/runtime/process-group-inspection.js +120 -40
- package/dist/runtime/process-group-inspection.js.map +1 -1
- package/dist/runtime/process-group-resources.d.ts +1 -0
- package/dist/runtime/process-group-resources.d.ts.map +1 -1
- package/dist/runtime/process-group-resources.js +8 -0
- package/dist/runtime/process-group-resources.js.map +1 -1
- package/dist/runtime/process-group-runtime-selection.d.ts +14 -0
- package/dist/runtime/process-group-runtime-selection.d.ts.map +1 -0
- package/dist/runtime/process-group-runtime-selection.js +29 -0
- package/dist/runtime/process-group-runtime-selection.js.map +1 -0
- package/dist/runtime/process-group-snapshot.mjs +60 -8
- package/dist/runtime/process-group-staging.d.ts +2 -2
- package/dist/runtime/process-group-staging.d.ts.map +1 -1
- package/dist/runtime/process-group-staging.js +6 -4
- package/dist/runtime/process-group-staging.js.map +1 -1
- package/dist/runtime/process-group-supervision.d.ts +2 -2
- package/dist/runtime/process-group-supervision.d.ts.map +1 -1
- package/dist/runtime/process-group-supervision.js +3 -2
- package/dist/runtime/process-group-supervision.js.map +1 -1
- package/dist/runtime/process-group-upgrade.d.ts +76 -6
- package/dist/runtime/process-group-upgrade.d.ts.map +1 -1
- package/dist/runtime/process-group-upgrade.js +7 -1
- package/dist/runtime/process-group-upgrade.js.map +1 -1
- package/dist/uns/uns-interfaces.d.ts +3 -0
- package/dist/uns/uns-interfaces.d.ts.map +1 -1
- package/dist/uns/uns-interfaces.js.map +1 -1
- package/dist/uns/uns-proxy-process.d.ts.map +1 -1
- package/dist/uns/uns-proxy-process.js +3 -0
- package/dist/uns/uns-proxy-process.js.map +1 -1
- package/dist/uns-config/config-schema.d.ts +16 -0
- package/dist/uns-config/config-schema.d.ts.map +1 -1
- package/dist/uns-config/mqtt-channel.d.ts +1 -1
- package/dist/uns-config/mqtt-channel.d.ts.map +1 -1
- package/dist/uns-config/mqtt-channel.js +3 -0
- package/dist/uns-config/mqtt-channel.js.map +1 -1
- package/dist/uns-config/uns-core-schema.d.ts +137 -0
- package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
- package/dist/uns-config/uns-core-schema.js +6 -1
- package/dist/uns-config/uns-core-schema.js.map +1 -1
- package/dist/uns-mqtt/mqtt-interfaces.d.ts +5 -0
- package/dist/uns-mqtt/mqtt-interfaces.d.ts.map +1 -1
- package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
- package/dist/uns-mqtt/mqtt-proxy.d.ts +3 -0
- package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
- package/dist/uns-mqtt/mqtt-proxy.js +26 -1
- package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
- package/dist/uns-mqtt/mqtt-worker.d.ts +3 -1
- package/dist/uns-mqtt/mqtt-worker.d.ts.map +1 -1
- package/dist/uns-mqtt/mqtt-worker.js +45 -8
- package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
- package/dist/uns-mqtt/publish-queue-contract.d.ts +33 -0
- package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -0
- package/dist/uns-mqtt/publish-queue-contract.js +18 -0
- package/dist/uns-mqtt/publish-queue-contract.js.map +1 -0
- package/dist/uns-mqtt/publish-queue-store.d.ts +33 -0
- package/dist/uns-mqtt/publish-queue-store.d.ts.map +1 -0
- package/dist/uns-mqtt/publish-queue-store.js +177 -0
- package/dist/uns-mqtt/publish-queue-store.js.map +1 -0
- package/dist/uns-mqtt/publish-queue.d.ts +43 -0
- package/dist/uns-mqtt/publish-queue.d.ts.map +1 -0
- package/dist/uns-mqtt/publish-queue.js +235 -0
- package/dist/uns-mqtt/publish-queue.js.map +1 -0
- package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +7 -0
- package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
- package/dist/uns-mqtt/uns-mqtt-proxy.js +98 -5
- package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,16 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { DatabaseSync, backup } from "node:sqlite";
|
|
6
6
|
|
|
7
|
-
const [root, output] = process.argv.slice(2);
|
|
7
|
+
const [root, output, suppliedContract] = process.argv.slice(2);
|
|
8
|
+
// The host passes the fixed SDK contract, never request-controlled limits. Legacy
|
|
9
|
+
// two-argument callers retain their historical nine-journal bound.
|
|
10
|
+
const limits = suppliedContract === undefined
|
|
11
|
+
? {schemaVersion:1,maximumJournals:9,maximumManifestBytes:262144,maximumSnapshotBytes:536870912,maximumCapsuleBytes:1073741824}
|
|
12
|
+
: JSON.parse(suppliedContract);
|
|
13
|
+
if (JSON.stringify(Object.keys(limits).sort()) !== JSON.stringify(["schemaVersion","maximumJournals","maximumManifestBytes","maximumSnapshotBytes","maximumCapsuleBytes"].sort()) ||
|
|
14
|
+
limits.schemaVersion !== 1 || !Number.isSafeInteger(limits.maximumJournals) || limits.maximumJournals < 1 || limits.maximumJournals > 128 ||
|
|
15
|
+
limits.maximumManifestBytes !== 262144 || limits.maximumSnapshotBytes !== 536870912 || limits.maximumCapsuleBytes !== 1073741824)
|
|
16
|
+
throw Error("Unsupported fixed snapshot contract");
|
|
8
17
|
const hash = (b) => crypto.createHash("sha256").update(b).digest("hex");
|
|
9
18
|
const fileHash = (p) => {
|
|
10
19
|
const h = crypto.createHash("sha256"),
|
|
@@ -83,9 +92,9 @@ for (const namespace of namespaces) {
|
|
|
83
92
|
}
|
|
84
93
|
check(admittedRoot, true);
|
|
85
94
|
const groups = fs.readdirSync(admittedRoot).sort();
|
|
86
|
-
if (groups.length >
|
|
95
|
+
if (groups.length > limits.maximumJournals) fail();
|
|
87
96
|
for (const group of groups) {
|
|
88
|
-
if (!/^[a-z][a-z0-9-]{0,99}$/.test(group) || capturedGroups.has(group) || capturedGroups.size >=
|
|
97
|
+
if (!/^[a-z][a-z0-9-]{0,99}$/.test(group) || capturedGroups.has(group) || capturedGroups.size >= limits.maximumJournals) fail();
|
|
89
98
|
capturedGroups.add(group);
|
|
90
99
|
const source = path.join(admittedRoot, group);
|
|
91
100
|
check(source, true);
|
|
@@ -102,7 +111,7 @@ for (const namespace of namespaces) {
|
|
|
102
111
|
}
|
|
103
112
|
}, 0);
|
|
104
113
|
capturedBytes += sourceSize;
|
|
105
|
-
if (capturedBytes >
|
|
114
|
+
if (capturedBytes > limits.maximumSnapshotBytes) fail();
|
|
106
115
|
const space = fs.statfsSync(output, { bigint: true });
|
|
107
116
|
if (space.bavail * space.bsize < BigInt(sourceSize * 2 + 64 * 1024 * 1024)) fail();
|
|
108
117
|
const target = path.join(output, group);
|
|
@@ -123,7 +132,7 @@ for (const namespace of namespaces) {
|
|
|
123
132
|
space = fs.statfsSync(output, { bigint: true });
|
|
124
133
|
if (
|
|
125
134
|
!Number.isSafeInteger(bytes) ||
|
|
126
|
-
bytes >
|
|
135
|
+
bytes > limits.maximumSnapshotBytes - snapshotBytes ||
|
|
127
136
|
space.bavail * space.bsize < BigInt(bytes + 64 * 1024 * 1024)
|
|
128
137
|
)
|
|
129
138
|
fail();
|
|
@@ -148,7 +157,45 @@ for (const namespace of namespaces) {
|
|
|
148
157
|
if (!/^[0-9a-f-]{36}$/.test(meta.id ?? "")) fail();
|
|
149
158
|
const contract = JSON.parse(meta.contract);
|
|
150
159
|
const profiles = snap.prepare("SELECT name,contract,completed,last_seq FROM profiles ORDER BY name").all();
|
|
151
|
-
if (
|
|
160
|
+
if (
|
|
161
|
+
profiles.length < 1 ||
|
|
162
|
+
profiles.length > 19 ||
|
|
163
|
+
![1, 2].includes(contract.version) ||
|
|
164
|
+
!Array.isArray(contract.profiles) ||
|
|
165
|
+
contract.profiles.length !== profiles.length
|
|
166
|
+
)
|
|
167
|
+
fail();
|
|
168
|
+
if (contract.version === 2) {
|
|
169
|
+
if (
|
|
170
|
+
contract.generationId !== group ||
|
|
171
|
+
!/^[a-f0-9]{64}$/.test(contract.groupSha256 ?? "") ||
|
|
172
|
+
!/^[a-f0-9]{64}$/.test(contract.sourceIdentity ?? "") ||
|
|
173
|
+
profiles.length < 2 ||
|
|
174
|
+
profiles.length > 16 ||
|
|
175
|
+
new Set(contract.profiles.map((p) => p.processName)).size !== profiles.length ||
|
|
176
|
+
!Number.isSafeInteger(contract.maxRecords) ||
|
|
177
|
+
contract.maxRecords < 1 ||
|
|
178
|
+
contract.maxRecords > 100000 ||
|
|
179
|
+
!Number.isSafeInteger(contract.maxBytes) ||
|
|
180
|
+
contract.maxBytes < 1024 ||
|
|
181
|
+
contract.maxBytes > 256 * 1024 * 1024
|
|
182
|
+
)
|
|
183
|
+
fail();
|
|
184
|
+
for (const row of profiles) {
|
|
185
|
+
const binding = JSON.parse(row.contract),
|
|
186
|
+
expected = contract.profiles.find((p) => p.processName === row.name);
|
|
187
|
+
if (
|
|
188
|
+
!expected ||
|
|
189
|
+
!/^[a-z][a-z0-9-]{0,99}$/.test(row.name) ||
|
|
190
|
+
!/^[a-f0-9]{64}$/.test(expected.resourceSha256 ?? "") ||
|
|
191
|
+
!/^[a-z][a-z0-9-]{0,99}$/.test(expected.dataGroup ?? "") ||
|
|
192
|
+
binding.processName !== row.name ||
|
|
193
|
+
binding.resourceSha256 !== expected.resourceSha256 ||
|
|
194
|
+
binding.dataGroup !== expected.dataGroup
|
|
195
|
+
)
|
|
196
|
+
fail();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
152
199
|
const usage = snap.prepare("SELECT records,bytes,admitted FROM usage WHERE id=1").get();
|
|
153
200
|
const actual = snap.prepare("SELECT count(*) records,coalesce(sum(bytes),0) bytes FROM tasks").get();
|
|
154
201
|
if (
|
|
@@ -162,6 +209,9 @@ for (const namespace of namespaces) {
|
|
|
162
209
|
info = {
|
|
163
210
|
group,
|
|
164
211
|
namespace,
|
|
212
|
+
...(contract.version === 2
|
|
213
|
+
? { journalContractVersion: 2, generationId: contract.generationId, configurationGroupSha256: contract.groupSha256 }
|
|
214
|
+
: {}),
|
|
165
215
|
journalId: meta.id,
|
|
166
216
|
clientId: namespace + "-admission-" + meta.id,
|
|
167
217
|
contractSha256: hash(meta.contract),
|
|
@@ -187,7 +237,7 @@ for (const namespace of namespaces) {
|
|
|
187
237
|
fs.closeSync(fd);
|
|
188
238
|
}
|
|
189
239
|
snapshotBytes += fs.statSync(p).size;
|
|
190
|
-
if (snapshotBytes >
|
|
240
|
+
if (snapshotBytes > limits.maximumSnapshotBytes) fail();
|
|
191
241
|
info[name === "admission.sqlite" ? "admissionSha256" : "ownershipSha256"] = fileHash(p);
|
|
192
242
|
}
|
|
193
243
|
manifest.groups.push(info);
|
|
@@ -195,5 +245,7 @@ for (const namespace of namespaces) {
|
|
|
195
245
|
}
|
|
196
246
|
const remaining = fs.statfsSync(output, { bigint: true });
|
|
197
247
|
if (remaining.bavail * remaining.bsize < BigInt(snapshotBytes + 64 * 1024 * 1024)) fail();
|
|
198
|
-
|
|
248
|
+
const manifestBytes = JSON.stringify(manifest) + "\n";
|
|
249
|
+
if (Buffer.byteLength(manifestBytes) > limits.maximumManifestBytes) fail();
|
|
250
|
+
fs.writeFileSync(path.join(output, "manifest.json"), manifestBytes, { mode: 0o600, flag: "wx" });
|
|
199
251
|
// No source payloads, credentials, paths or process metadata on stdout/stderr.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RuntimeGroupDescriptor } from "./process-group-runtime-selection.js";
|
|
2
2
|
export declare const stagedJournalFile = "process-group-staged-journal.json";
|
|
3
3
|
/** An explicit, config-bound declaration, not permission to initialize or run. */
|
|
4
|
-
export declare function refreshProcessGroupStagedJournal(instanceDir: string, stopped: boolean, descriptor:
|
|
4
|
+
export declare function refreshProcessGroupStagedJournal(instanceDir: string, stopped: boolean, descriptor: RuntimeGroupDescriptor | undefined): void;
|
|
5
5
|
//# sourceMappingURL=process-group-staging.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-staging.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-staging.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-group-staging.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-staging.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,sBAAsB,EAAgC,MAAM,sCAAsC,CAAC;AAEjH,eAAO,MAAM,iBAAiB,sCAAsC,CAAC;AACrE,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,sBAAsB,GAAG,SAAS,GAAG,IAAI,CAoD5I"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { configurationGroupJournalSchema } from "./configuration-group-contract.js";
|
|
5
|
+
import { normalizeRuntimeProcessGroup } from "./process-group-runtime-selection.js";
|
|
5
6
|
export const stagedJournalFile = "process-group-staged-journal.json";
|
|
6
7
|
/** An explicit, config-bound declaration, not permission to initialize or run. */
|
|
7
8
|
export function refreshProcessGroupStagedJournal(instanceDir, stopped, descriptor) {
|
|
@@ -14,13 +15,14 @@ export function refreshProcessGroupStagedJournal(instanceDir, stopped, descripto
|
|
|
14
15
|
throw new Error("Staged configuration must be a bounded regular file.");
|
|
15
16
|
const raw = fs.readFileSync(configFile);
|
|
16
17
|
const config = JSON.parse(raw.toString("utf8"));
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
: undefined;
|
|
18
|
+
const selected = descriptor ? normalizeRuntimeProcessGroup(config, descriptor) : undefined;
|
|
19
|
+
const journal = selected?.journal;
|
|
20
20
|
if (!stopped || !journal || journal.journalId !== undefined) {
|
|
21
21
|
fs.rmSync(marker, { force: true });
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
+
if (selected?.configurationSnapshot && configurationGroupJournalSchema.parse(journal).groupSha256 !== selected.configurationSnapshot.sha256)
|
|
25
|
+
throw Error("Staged journal differs from its configured resource snapshot");
|
|
24
26
|
if (typeof journal.directory !== "string" || !path.isAbsolute(journal.directory) || path.normalize(journal.directory) !== journal.directory)
|
|
25
27
|
throw new Error("Staged journal requires a normalized absolute directory.");
|
|
26
28
|
// Existing/unknown data must never be declared uninitialized, including links.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-staging.js","sourceRoot":"","sources":["../../src/runtime/process-group-staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,
|
|
1
|
+
{"version":3,"file":"process-group-staging.js","sourceRoot":"","sources":["../../src/runtime/process-group-staging.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { configurationGroupJournalSchema } from \"./configuration-group-contract.js\";\nimport { type RuntimeGroupDescriptor, normalizeRuntimeProcessGroup } from \"./process-group-runtime-selection.js\";\n\nexport const stagedJournalFile = \"process-group-staged-journal.json\";\n/** An explicit, config-bound declaration, not permission to initialize or run. */\nexport function refreshProcessGroupStagedJournal(instanceDir: string, stopped: boolean, descriptor: RuntimeGroupDescriptor | undefined): void {\n const marker = path.join(instanceDir, stagedJournalFile);\n const configFile = path.join(instanceDir, \"config.json\");\n if (!fs.existsSync(configFile)) return;\n const stat = fs.lstatSync(configFile);\n if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1024 * 1024) throw new Error(\"Staged configuration must be a bounded regular file.\");\n const raw = fs.readFileSync(configFile);\n const config = JSON.parse(raw.toString(\"utf8\")) as Record<string, unknown>;\n const selected = descriptor ? normalizeRuntimeProcessGroup(config, descriptor) : undefined;\n const journal = selected?.journal as { directory?: unknown; journalId?: unknown } | undefined;\n if (!stopped || !journal || journal.journalId !== undefined) {\n fs.rmSync(marker, { force: true });\n return;\n }\n if (selected?.configurationSnapshot && configurationGroupJournalSchema.parse(journal).groupSha256 !== selected.configurationSnapshot.sha256)\n throw Error(\"Staged journal differs from its configured resource snapshot\");\n if (typeof journal.directory !== \"string\" || !path.isAbsolute(journal.directory) || path.normalize(journal.directory) !== journal.directory)\n throw new Error(\"Staged journal requires a normalized absolute directory.\");\n // Existing/unknown data must never be declared uninitialized, including links.\n for (let dir = journal.directory; dir !== path.dirname(dir); dir = path.dirname(dir)) {\n try {\n const stat = fs.lstatSync(dir);\n if (stat.isSymbolicLink() || dir === journal.directory) throw new Error(\"Existing journal cannot be marked uninitialized.\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n }\n if (fs.existsSync(path.join(instanceDir, \"handover-source-guard.json.launch\")))\n throw new Error(\"A previously launched instance requires journal review.\");\n const temporary = marker + \".\" + randomUUID() + \".tmp\";\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(\n fd,\n JSON.stringify({\n schemaVersion: 1,\n kind: \"uns-process-group-staged-journal\",\n configurationSha256: createHash(\"sha256\").update(raw).digest(\"hex\"),\n directory: journal.directory,\n }) + \"\\n\",\n );\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n fs.renameSync(temporary, marker);\n const parent = fs.openSync(instanceDir, \"r\");\n try {\n fs.fsyncSync(parent);\n } finally {\n fs.closeSync(parent);\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RuntimeGroupDescriptor } from "./process-group-runtime-selection.js";
|
|
2
2
|
/** SDK receiver contract; host launchers translate these neutral settings to PM2/systemd. */
|
|
3
|
-
export declare function processGroupReceiverSupervision(raw: Record<string, unknown>, descriptor:
|
|
3
|
+
export declare function processGroupReceiverSupervision(raw: Record<string, unknown>, descriptor: RuntimeGroupDescriptor | undefined, instanceDirectory: string, capabilities: {
|
|
4
4
|
supervised: boolean;
|
|
5
5
|
persistent: boolean;
|
|
6
6
|
authorized: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-supervision.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-supervision.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-group-supervision.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-supervision.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,sBAAsB,EAAgC,MAAM,sCAAsC,CAAC;AAEjH,6FAA6F;AAC7F,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,UAAU,EAAE,sBAAsB,GAAG,SAAS,EAC9C,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,EAC/E,UAAU,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,kBAAkB,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACjH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0BzB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isUnsupportedLegacyReceiver } from "./compatibility/energenti-descriptor-v1.js";
|
|
2
|
-
import { isLocalPilotPath
|
|
2
|
+
import { isLocalPilotPath } from "./process-group-contract.js";
|
|
3
|
+
import { normalizeRuntimeProcessGroup } from "./process-group-runtime-selection.js";
|
|
3
4
|
/** SDK receiver contract; host launchers translate these neutral settings to PM2/systemd. */
|
|
4
5
|
export function processGroupReceiverSupervision(raw, descriptor, instanceDirectory, capabilities, supervisor) {
|
|
5
6
|
if (!descriptor) {
|
|
@@ -7,7 +8,7 @@ export function processGroupReceiverSupervision(raw, descriptor, instanceDirecto
|
|
|
7
8
|
throw Error("Installed package has no supported receiver contract");
|
|
8
9
|
return {};
|
|
9
10
|
}
|
|
10
|
-
const c =
|
|
11
|
+
const c = normalizeRuntimeProcessGroup(raw, descriptor);
|
|
11
12
|
if (c.runtimeRole !== "admission")
|
|
12
13
|
return {};
|
|
13
14
|
if (!c.matches || !c.journal || (!isLocalPilotPath(instanceDirectory) && !capabilities.authorized))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-supervision.js","sourceRoot":"","sources":["../../src/runtime/process-group-supervision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AACzF,OAAO,
|
|
1
|
+
{"version":3,"file":"process-group-supervision.js","sourceRoot":"","sources":["../../src/runtime/process-group-supervision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAA+B,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAEjH,6FAA6F;AAC7F,MAAM,UAAU,+BAA+B,CAC7C,GAA4B,EAC5B,UAA8C,EAC9C,iBAAyB,EACzB,YAA+E,EAC/E,UAAkH;IAElH,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,2BAA2B,CAAC,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1G,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,CAAC,GAAG,4BAA4B,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;QAChG,MAAM,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACtF,IAAI,CAAC,YAAY,CAAC,UAAU;QAAE,MAAM,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAC9G,MAAM,SAAS,GAAI,CAAC,CAAC,OAAmC,CAAC,WAAW,CAAC,CAAC;IACtE,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU;QAC3F,MAAM,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACnF,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,IAAI,UAAU,CAAC,kBAAkB;QACnF,MAAM,KAAK,CAAC,+FAA+F,CAAC,CAAC;IAC/G,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,IAAI,GAAG,CAAC;IAC1C,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI;QAAE,MAAM,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACnG,OAAO;QACL,WAAW,EAAE,IAAI;QACjB,qFAAqF;QACrF,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QACxB,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,CAAC;QACf,yBAAyB,EAAE,IAAI;QAC/B,kBAAkB,EAAE,GAAG,GAAG,GAAG;KAC9B,CAAC;AACJ,CAAC","sourcesContent":["import { isUnsupportedLegacyReceiver } from \"./compatibility/energenti-descriptor-v1.js\";\nimport { isLocalPilotPath } from \"./process-group-contract.js\";\nimport { type RuntimeGroupDescriptor, normalizeRuntimeProcessGroup } from \"./process-group-runtime-selection.js\";\n\n/** SDK receiver contract; host launchers translate these neutral settings to PM2/systemd. */\nexport function processGroupReceiverSupervision(\n raw: Record<string, unknown>,\n descriptor: RuntimeGroupDescriptor | undefined,\n instanceDirectory: string,\n capabilities: { supervised: boolean; persistent: boolean; authorized: boolean },\n supervisor: { enabled: boolean; restartOnExit: boolean; restartOnUnhealthy: boolean; maxMemoryMb?: number | null },\n): Record<string, unknown> {\n if (!descriptor) {\n if (isUnsupportedLegacyReceiver(raw)) throw Error(\"Installed package has no supported receiver contract\");\n return {};\n }\n const c = normalizeRuntimeProcessGroup(raw, descriptor);\n if (c.runtimeRole !== \"admission\") return {};\n if (!c.matches || !c.journal || (!isLocalPilotPath(instanceDirectory) && !capabilities.authorized))\n throw Error(\"Admission supervision requires an explicit reviewed journal instance\");\n if (!capabilities.supervised) throw Error(\"Installed package does not support the supervised admission role\");\n const directory = (c.journal as Record<string, unknown>)[\"directory\"];\n if (typeof directory === \"string\" && !isLocalPilotPath(directory) && !capabilities.persistent)\n throw Error(\"Installed package does not support persistent admission ownership\");\n if (!supervisor.enabled || !supervisor.restartOnExit || supervisor.restartOnUnhealthy)\n throw Error(\"Admission requires restart-on-exit supervision; generic MQTT unhealthy restart is unsupported\");\n const max = supervisor.maxMemoryMb ?? 256;\n if (max < 128 || max > 4096) throw Error(\"Admission supervisor memory limit must be 128–4096 MiB\");\n return {\n autorestart: true,\n // Successful standalone/guarded shutdown and explicit contract refusal are terminal.\n stop_exit_codes: [0, 78],\n min_uptime: 10000,\n max_restarts: 5,\n exp_backoff_restart_delay: 1000,\n max_memory_restart: `${max}M`,\n };\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type GroupGenerationReview, type GenerationJournalReference } from "./process-group-generation.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
|
-
export declare const processGroupUpgradeInputSchema: z.ZodObject<{
|
|
3
|
+
export declare const processGroupUpgradeInputSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
3
4
|
protocolVersion: z.ZodLiteral<1>;
|
|
4
5
|
source: z.ZodObject<{
|
|
5
6
|
publisher: z.ZodObject<{
|
|
@@ -29,7 +30,40 @@ export declare const processGroupUpgradeInputSchema: z.ZodObject<{
|
|
|
29
30
|
instanceId: z.ZodString;
|
|
30
31
|
}, z.core.$strict>;
|
|
31
32
|
}, z.core.$strict>;
|
|
32
|
-
}, z.core.$strict
|
|
33
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
34
|
+
protocolVersion: z.ZodLiteral<2>;
|
|
35
|
+
source: z.ZodObject<{
|
|
36
|
+
publisher: z.ZodObject<{
|
|
37
|
+
controller: z.ZodString;
|
|
38
|
+
rttNode: z.ZodString;
|
|
39
|
+
version: z.ZodString;
|
|
40
|
+
instanceId: z.ZodString;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
receiver: z.ZodObject<{
|
|
43
|
+
controller: z.ZodString;
|
|
44
|
+
rttNode: z.ZodString;
|
|
45
|
+
version: z.ZodString;
|
|
46
|
+
instanceId: z.ZodString;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
}, z.core.$strict>;
|
|
49
|
+
target: z.ZodObject<{
|
|
50
|
+
publisher: z.ZodObject<{
|
|
51
|
+
controller: z.ZodString;
|
|
52
|
+
rttNode: z.ZodString;
|
|
53
|
+
version: z.ZodString;
|
|
54
|
+
instanceId: z.ZodString;
|
|
55
|
+
}, z.core.$strict>;
|
|
56
|
+
receiver: z.ZodObject<{
|
|
57
|
+
controller: z.ZodString;
|
|
58
|
+
rttNode: z.ZodString;
|
|
59
|
+
version: z.ZodString;
|
|
60
|
+
instanceId: z.ZodString;
|
|
61
|
+
}, z.core.$strict>;
|
|
62
|
+
}, z.core.$strict>;
|
|
63
|
+
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
64
|
+
acknowledgeResourceReview: z.ZodLiteral<true>;
|
|
65
|
+
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
66
|
+
}, z.core.$strict>]>;
|
|
33
67
|
export type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;
|
|
34
68
|
export type UpgradeRole = "publisher" | "receiver";
|
|
35
69
|
export type UpgradeConfiguration = {
|
|
@@ -39,8 +73,10 @@ export type UpgradeConfiguration = {
|
|
|
39
73
|
resolved: Record<string, unknown>;
|
|
40
74
|
};
|
|
41
75
|
export type UpgradeConfigurations = Record<"source" | "target", Record<UpgradeRole, UpgradeConfiguration>>;
|
|
42
|
-
export type
|
|
76
|
+
export type GroupVersionUpgradeReview = {
|
|
43
77
|
protocolVersion: 1;
|
|
78
|
+
/** Present only for configuration-owned protocol-2 resources retained across a version change. */
|
|
79
|
+
retainedJournal?: GenerationJournalReference;
|
|
44
80
|
namespace: string;
|
|
45
81
|
groupId: string;
|
|
46
82
|
policyFile: string;
|
|
@@ -62,6 +98,7 @@ export type GroupUpgradeReview = {
|
|
|
62
98
|
artifactSha256: string;
|
|
63
99
|
}>;
|
|
64
100
|
};
|
|
101
|
+
export type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview;
|
|
65
102
|
export type PreparedGroupUpgrade = {
|
|
66
103
|
review: GroupUpgradeReview;
|
|
67
104
|
sourcePolicy: Buffer;
|
|
@@ -81,7 +118,7 @@ export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
|
|
|
81
118
|
execute: "execute";
|
|
82
119
|
rollback: "rollback";
|
|
83
120
|
}>;
|
|
84
|
-
input: z.ZodOptional<z.ZodObject<{
|
|
121
|
+
input: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
85
122
|
protocolVersion: z.ZodLiteral<1>;
|
|
86
123
|
source: z.ZodObject<{
|
|
87
124
|
publisher: z.ZodObject<{
|
|
@@ -111,14 +148,47 @@ export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
|
|
|
111
148
|
instanceId: z.ZodString;
|
|
112
149
|
}, z.core.$strict>;
|
|
113
150
|
}, z.core.$strict>;
|
|
114
|
-
}, z.core.$strict
|
|
151
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
152
|
+
protocolVersion: z.ZodLiteral<2>;
|
|
153
|
+
source: z.ZodObject<{
|
|
154
|
+
publisher: z.ZodObject<{
|
|
155
|
+
controller: z.ZodString;
|
|
156
|
+
rttNode: z.ZodString;
|
|
157
|
+
version: z.ZodString;
|
|
158
|
+
instanceId: z.ZodString;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
receiver: z.ZodObject<{
|
|
161
|
+
controller: z.ZodString;
|
|
162
|
+
rttNode: z.ZodString;
|
|
163
|
+
version: z.ZodString;
|
|
164
|
+
instanceId: z.ZodString;
|
|
165
|
+
}, z.core.$strict>;
|
|
166
|
+
}, z.core.$strict>;
|
|
167
|
+
target: z.ZodObject<{
|
|
168
|
+
publisher: z.ZodObject<{
|
|
169
|
+
controller: z.ZodString;
|
|
170
|
+
rttNode: z.ZodString;
|
|
171
|
+
version: z.ZodString;
|
|
172
|
+
instanceId: z.ZodString;
|
|
173
|
+
}, z.core.$strict>;
|
|
174
|
+
receiver: z.ZodObject<{
|
|
175
|
+
controller: z.ZodString;
|
|
176
|
+
rttNode: z.ZodString;
|
|
177
|
+
version: z.ZodString;
|
|
178
|
+
instanceId: z.ZodString;
|
|
179
|
+
}, z.core.$strict>;
|
|
180
|
+
}, z.core.$strict>;
|
|
181
|
+
acknowledgeInputPause: z.ZodLiteral<true>;
|
|
182
|
+
acknowledgeResourceReview: z.ZodLiteral<true>;
|
|
183
|
+
acknowledgePossibleReplay: z.ZodLiteral<true>;
|
|
184
|
+
}, z.core.$strict>]>>;
|
|
115
185
|
id: z.ZodOptional<z.ZodString>;
|
|
116
186
|
expectedFingerprint: z.ZodOptional<z.ZodString>;
|
|
117
187
|
expectedRevision: z.ZodOptional<z.ZodNumber>;
|
|
118
188
|
}, z.core.$strict>;
|
|
119
189
|
export type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;
|
|
120
190
|
/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */
|
|
121
|
-
export declare function inspectProcessGroupUpgradeJournal(review:
|
|
191
|
+
export declare function inspectProcessGroupUpgradeJournal(review: Pick<GroupVersionUpgradeReview, "directory" | "journalId" | "journalContractSha256" | "profiles">, publisherPid?: number, receiverPid?: number): {
|
|
122
192
|
receiverReady: boolean;
|
|
123
193
|
publisherReady: boolean;
|
|
124
194
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { reviewInstalledConfigurationGroupUpgrade } from "./process-group-configured-upgrade.js";
|
|
2
|
+
import { selectedProcessGroupDescriptor } from "./process-group-runtime-selection.js";
|
|
3
|
+
import { processGroupGenerationInputSchema } from "./process-group-generation.js";
|
|
1
4
|
import fs from "node:fs";
|
|
2
5
|
import { createRequire } from "node:module";
|
|
3
6
|
import path from "node:path";
|
|
@@ -7,7 +10,7 @@ import { normalizeProcessGroupConfiguration, processGroupDescriptor, processGrou
|
|
|
7
10
|
import { groupPlacementSchema, placementKey } from "./process-group-control-contract.js";
|
|
8
11
|
import { groupArtifactHash, groupChannelsHash, configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256, } from "./process-group-resources.js";
|
|
9
12
|
const pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });
|
|
10
|
-
|
|
13
|
+
const processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).superRefine((v, c) => {
|
|
11
14
|
const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];
|
|
12
15
|
if (new Set(all.map(placementKey)).size !== 4 ||
|
|
13
16
|
all.some((p) => p.controller !== all[0].controller || p.rttNode !== all[0].rttNode) ||
|
|
@@ -16,8 +19,11 @@ export const processGroupUpgradeInputSchema = z.strictObject({ protocolVersion:
|
|
|
16
19
|
v.source.publisher.version === v.target.publisher.version)
|
|
17
20
|
c.addIssue({ code: "custom", message: "Four distinct placements, one package/controller and two paired versions required" });
|
|
18
21
|
});
|
|
22
|
+
export const processGroupUpgradeInputSchema = z.union([processGroupVersionUpgradeInputSchema, processGroupGenerationInputSchema]);
|
|
19
23
|
/** Data-only same-host version review. No application JS, journal writes or launch authority. */
|
|
20
24
|
export function reviewInstalledProcessGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields = []) {
|
|
25
|
+
if (Object.values(configs).flatMap(Object.values).some(c => selectedProcessGroupDescriptor(c.packageRoot, c.raw)?.protocolVersion === 2))
|
|
26
|
+
return reviewInstalledConfigurationGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields);
|
|
21
27
|
const first = configs.source.publisher;
|
|
22
28
|
const context = (c) => ({
|
|
23
29
|
packageRoot: c.packageRoot,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,EAC1B,mCAAmC,GACpC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,kCAAkC,EAClC,sBAAsB,EACtB,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,IAAI,IAAI,EACtC,wBAAwB,IAAI,IAAI,EAChC,MAAM,GACP,MAAM,8BAA8B,CAAC;AAEtC,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;AACjG,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;IAC/I,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3F,IACE,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAE,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC;QACrF,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO;QACxD,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO;QACxD,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO;QAEzD,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,mFAAmF,EAAE,CAAC,CAAC;AACjI,CAAC,CAAC,CAAC;AAyBH,iGAAiG;AACjG,MAAM,UAAU,kCAAkC,CAChD,OAA8B,EAC9B,cAAsB,EACtB,SAAiB,EACjB,oBAAuC,EAAE;IAEzC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;IACvC,MAAM,OAAO,GAAG,CAAC,CAAuB,EAAE,EAAE,CAAC,CAAC;QAC5C,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;QACtC,gBAAgB,EAAE,CAAC,CAAC,GAAG;QACvB,QAAQ,EAAE,4BAA4B,CAAC,CAAC,CAAC,QAAQ,CAAC;QAClD,cAAc;QACd,SAAS;KACV,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,4BAA4B,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,4BAA4B,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChF,IACE,GAAG,CAAC,IAAI,KAAK,QAAQ;QACrB,QAAQ,CAAC,IAAI,KAAK,UAAU;QAC5B,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAC1B,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS;QACpC,CAAC,GAAG,CAAC,SAAS;QACd,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS;QAEpC,MAAM,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EACvC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EACrC,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM;QAAE,MAAM,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnH,MAAM,YAAY,GAAG,kCAAkC,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpF,IAAI,CAAC,QAAQ;QAAE,MAAM,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EACtE,QAAQ,GAAG,0BAA0B,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS;QAC3G,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAkC,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,CAAC,GAA4B,EAAE,EAAE;QAChD,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,EAC/B,GAAG,GAAG,EAAE,GAAI,IAAI,CAAC,KAAK,CAA6B,EAAE,CAAC;QACxD,KAAK,MAAM,CAAC,IAAI,iBAAiB;YAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,CAAU,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAC5B,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,IACE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;YACnC,iBAAiB,CAAC,4BAA4B,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,iBAAiB,CAAC,4BAA4B,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAE3H,MAAM,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAU,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAC3B,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YAC5C,IAAI,CAAC,CAAC;gBAAE,MAAM,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,kCAAkC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAC7D,CAAC,GAAG,yBAAyB,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC1D,IACE,CAAC,UAAU,CAAC,OAAO;gBACnB,CAAC,IAAI,KAAK,UAAU;oBAClB,CAAC,CAAC,UAAU,CAAC,WAAW,KAAK,WAAW;oBACxC,CAAC,CAAC,UAAU,CAAC,WAAW,KAAK,SAAS,IAAI,UAAU,CAAC,WAAW,KAAK,WAAW,CAAC;gBACnF,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS;gBAC7B,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS;gBAC7B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,aAAa,CAAC;gBAEjF,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,IAAI;gBACJ,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAClD,mBAAmB,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;gBAChC,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC;aACjD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,IACE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,WAAW,KAAK,QAAQ,CAAC,WAAW;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,WAAW,KAAK,QAAQ,CAAC,WAAW,GAAG,YAAY;QAE/F,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvF,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,+BAA+B,CAAC,KAAK,CAAC;QACnD,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,yCAAyC;QAC/C,eAAe,EAAE,CAAC;QAClB,WAAW,EAAE,GAAG,CAAC,IAAI;QACrB,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,OAAO,EAAE,QAAQ,CAAC,EAAE;QACpB,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAC1D,cAAc;QACd,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc,EAAE,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC;QACrD,mBAAmB,EAAE,MAAM,CAAC,aAAa,CAAC;QAC1C,cAAc,EAAE,iBAAiB,CAAC,4BAA4B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChF,SAAS;QACT,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,UAAU,EAAE;YACV,GAAG,UAAU;YACb,GAAI,CAAC,WAAW,EAAE,UAAU,CAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrD,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC;gBACjE,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAE,CAAC,WAAW;gBACrF,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;gBAClD,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;aACpD,CAAC,CAAC;SACJ;KACF,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,CAAU;QAAE,mCAAmC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IACxI,MAAM,QAAQ,GAAG,2BAA2B,CAC1C,0BAA0B,CAAC,4BAA4B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,CAAC,EAC7E,OAAO,EACP,QAAQ,CAAC,QAAQ,CAClB,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;QAAE,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC3G,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,CAAiC,CAAC;IACvG,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CACjC,EAAE;aACC,OAAO,CAAC,+DAA+D,CAAC;aACxE,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACtC,CAAC;QACF,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,QAAQ;YACvE,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAChF,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,YAAY,CAAC;QAAE,MAAM,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC9G,OAAO;QACL,MAAM,EAAE;YACN,eAAe,EAAE,CAAC;YAClB,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,OAAO,EAAE,QAAQ,CAAC,EAAE;YACpB,UAAU,EAAE,6BAA6B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC1D,kBAAkB,EAAE,MAAM,CAAC,YAAY,CAAC;YACxC,kBAAkB,EAAE,MAAM,CAAC,YAAY,CAAC;YACxC,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,qBAAqB,EAAE,MAAM,CAAC,QAAQ,CAAC;YACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;YAC3H,OAAO;SACR;QACD,YAAY;QACZ,YAAY;KACb,CAAC;AACJ,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,iCAAiC,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAa;IAC7F,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EACrC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,CAAC,2DAA2D;IACxF,IAAI,MAAM,KAAK,QAAQ;QAAE,MAAM,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,IAAI,GAAG,cAAc,CAAC;IACxC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,CAAC;QACH,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACpG,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,YAAY,CAAC;IACZ,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7B,cAAc,EAAE,oBAAoB,CAAC,KAAK,CAAC,UAAU;IACrD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpE,KAAK,EAAE,8BAA8B,CAAC,QAAQ,EAAE;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAChC,mBAAmB,EAAE,CAAC;SACnB,MAAM,EAAE;SACR,KAAK,CAAC,gBAAgB,CAAC;SACvB,QAAQ,EAAE;IACb,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACzD,CAAC;KACD,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;IACpB,IACE,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QACvD,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACjF,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACnE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,KAAK,CAAC,CAAC,cAAc,CAAC;QAErE,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,uDAAuD,EAAE,CAAC,CAAC;AACrG,CAAC,CAAC,CAAC;AAEL,8FAA8F;AAC9F,MAAM,UAAU,iCAAiC,CAAC,MAA0B,EAAE,YAAqB,EAAE,WAAoB;IACvH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC7D,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,MAAM,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAChF,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,CAAiC,CAAC;IACvG,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAC7B,EAAE;aACC,OAAO,CAAC,6FAA6F,CAAC;aACtG,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACtC,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,qBAAqB;YACtG,MAAM,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,CAAC,GAAuB,EAAE,MAAe,EAAE,EAAE;YAC5D,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;gBAAE,OAAO,KAAK,CAAC;YAC/H,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,iCAAiC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACzI,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,OAAO,EAAE,MAAM,CAAC,EACvD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC/D,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC;YACtH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,EAAE,CAAC;QACtF,OAAO;YACL,aAAa,EACX,OAAO,EAAE,GAAG,KAAK,WAAW;gBAC5B,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;gBACtD,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC;gBACxC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;gBACtC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI;gBACtC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,eAAe,CAAC;YAChD,cAAc,EACZ,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM;gBACtC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAC5I;SACJ,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC","sourcesContent":["import fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport {\n authorizeProcessGroupRuntime,\n processGroupAuthorizationFile,\n processGroupAuthorizationSchema,\n processGroupManifestSchema,\n validateProcessGroupPolicyCandidate,\n} from \"./process-group-authorization.js\";\nimport {\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n processGroupJournalContract,\n processGroupJournalSchema,\n processGroupSourceIdentity,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\n\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\nexport const processGroupUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).superRefine((v, c) => {\n const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];\n if (\n new Set(all.map(placementKey)).size !== 4 ||\n all.some((p) => p.controller !== all[0]!.controller || p.rttNode !== all[0]!.rttNode) ||\n v.source.publisher.version !== v.source.receiver.version ||\n v.target.publisher.version !== v.target.receiver.version ||\n v.source.publisher.version === v.target.publisher.version\n )\n c.addIssue({ code: \"custom\", message: \"Four distinct placements, one package/controller and two paired versions required\" });\n});\nexport type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;\nexport type UpgradeRole = \"publisher\" | \"receiver\";\nexport type UpgradeConfiguration = {\n packageRoot: string;\n instanceDirectory: string;\n raw: Record<string, unknown>;\n resolved: Record<string, unknown>;\n};\nexport type UpgradeConfigurations = Record<\"source\" | \"target\", Record<UpgradeRole, UpgradeConfiguration>>;\nexport type GroupUpgradeReview = {\n protocolVersion: 1;\n namespace: string;\n groupId: string;\n policyFile: string;\n sourcePolicySha256: string;\n targetPolicySha256: string;\n journalId: string;\n directory: string;\n journalContractSha256: string;\n profiles: Array<{ processName: string; mappingSha256: string; dataGroup: string }>;\n members: Array<{ side: \"source\" | \"target\"; role: UpgradeRole; processName: string; configurationSha256: string; artifactSha256: string }>;\n};\nexport type PreparedGroupUpgrade = { review: GroupUpgradeReview; sourcePolicy: Buffer; targetPolicy: Buffer };\n\n/** Data-only same-host version review. No application JS, journal writes or launch authority. */\nexport function reviewInstalledProcessGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const first = configs.source.publisher;\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const old = authorizeProcessGroupRuntime(context(first));\n const receiver = authorizeProcessGroupRuntime(context(configs.source.receiver));\n if (\n old.role !== \"target\" ||\n receiver.role !== \"receiver\" ||\n old.file !== receiver.file ||\n old.directory !== receiver.directory ||\n !old.journalId ||\n old.journalId !== receiver.journalId\n )\n throw Error(\"Exact authorized source publisher/receiver pair required\");\n const sourcePolicy = read(old.file, true),\n previous = JSON.parse(sourcePolicy.toString());\n const target = configs.target.publisher,\n descriptor = processGroupDescriptor(target.packageRoot);\n if (!descriptor || descriptor.legacy) throw Error(\"Target requires the shared process-group protocol declaration\");\n const targetConfig = normalizeProcessGroupConfiguration(target.raw, descriptor);\n const journal = processGroupJournalSchema.parse(targetConfig.journal);\n const resource = descriptor.manifests.find((m) => m.file === journal.groupManifest);\n if (!resource) throw Error(\"Unregistered target manifest\");\n const manifestBytes = read(path.join(target.packageRoot, resource.file)),\n manifest = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)\n throw Error(\"Journal or manifest identity changed\");\n const members: GroupUpgradeReview[\"members\"] = [];\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const k of excludedUnsFields) delete uns[k];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const a = configs.source[role],\n b = configs.target[role];\n if (\n portable(a.raw) !== portable(b.raw) ||\n groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved))\n )\n throw Error(\"Configuration, broker identity, paths or units changed\");\n for (const side of [\"source\", \"target\"] as const) {\n const c = configs[side][role],\n d = processGroupDescriptor(c.packageRoot);\n if (!d) throw Error(\"Missing shared runtime contract\");\n const normalized = normalizeProcessGroupConfiguration(c.raw, d),\n j = processGroupJournalSchema.parse(normalized.journal);\n if (\n !normalized.matches ||\n (role === \"receiver\"\n ? normalized.runtimeRole !== \"admission\"\n : normalized.runtimeRole !== undefined && normalized.runtimeRole !== \"publisher\") ||\n j.directory !== old.directory ||\n j.journalId !== old.journalId ||\n sha256(read(path.join(c.packageRoot, j.groupManifest))) !== sha256(manifestBytes)\n )\n throw Error(\"Runtime role, manifest or journal differs\");\n members.push({\n side,\n role,\n processName: String(normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n }\n if (\n members.find((m) => m.role === \"publisher\")?.processName !== manifest.processName ||\n members.find((m) => m.role === \"receiver\")?.processName !== manifest.processName + \"-admission\"\n )\n throw Error(\"Manifest process identities differ\");\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const historical = previous.placements.filter((p: { role: string }) => p.role === \"source\");\n const policy = processGroupAuthorizationSchema.parse({\n schemaVersion: 3,\n kind: \"uns-process-group-runtime-authorization\",\n protocolVersion: 1,\n packageName: pkg.name,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n descriptorSha256: hash(pkg.unsDatahub.processGroupRuntime),\n controllerName,\n packageRoot: target.packageRoot,\n artifactSha256: groupArtifactHash(target.packageRoot),\n groupManifestSha256: sha256(manifestBytes),\n channelsSha256: groupChannelsHash(resolvedProcessGroupChannels(target.resolved)),\n stateRoot,\n directory: old.directory,\n journalId: old.journalId,\n placements: [\n ...historical,\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: hash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n const expected = processGroupJournalContract(\n processGroupSourceIdentity(resolvedProcessGroupChannels(target.resolved)[1]!),\n journal,\n manifest.profiles,\n );\n const file = path.join(old.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file || !fs.lstatSync(file).isFile()) throw Error(\"Unsafe journal resource\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const metadata = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (metadata[\"id\"] !== old.journalId || metadata[\"contract\"] !== expected)\n throw Error(\"Installed target cannot reopen the retained journal contract\");\n } finally {\n db.close();\n }\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n policyFile: processGroupAuthorizationFile(context(target)),\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: old.journalId,\n directory: old.directory,\n journalContractSha256: sha256(expected),\n profiles: manifest.profiles.map(({ processName, mappingSha256, dataGroup }) => ({ processName, mappingSha256, dataGroup })),\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n\n/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */\nexport function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void {\n const actual = sha256(read(file, true)),\n next = sha256(bytes);\n if (actual === next) return; // Reconcile an already completed write after a lost reply.\n if (actual !== expected) throw Error(\"Runtime policy changed; review required\");\n const temporary = file + \".upgrade-tmp\";\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, bytes);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n try {\n if (sha256(read(file, true)) !== expected) throw Error(\"Runtime policy changed before replacement\");\n fs.renameSync(temporary, file);\n const directory = fs.openSync(path.dirname(file), \"r\");\n try {\n fs.fsyncSync(directory);\n } finally {\n fs.closeSync(directory);\n }\n } finally {\n if (fs.existsSync(temporary)) fs.unlinkSync(temporary);\n }\n}\n\nexport const processGroupUpgradeRequestSchema = z\n .strictObject({\n protocolVersion: z.literal(1),\n controllerName: groupPlacementSchema.shape.controller,\n action: z.enum([\"preview\", \"prepare\", \"get\", \"execute\", \"rollback\"]),\n input: processGroupUpgradeInputSchema.optional(),\n id: z.string().uuid().optional(),\n expectedFingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .optional(),\n expectedRevision: z.number().int().positive().optional(),\n })\n .superRefine((v, c) => {\n if (\n ([\"preview\", \"prepare\"].includes(v.action) && !v.input) ||\n (v.action !== \"preview\" && !v.id) ||\n ([\"prepare\", \"execute\", \"rollback\"].includes(v.action) && !v.expectedFingerprint) ||\n ([\"execute\", \"rollback\"].includes(v.action) && !v.expectedRevision) ||\n (v.input && v.input.source.publisher.controller !== v.controllerName)\n )\n c.addIssue({ code: \"custom\", message: \"Exact upgrade selector and reviewed revision required\" });\n });\nexport type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;\n/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */\nexport function inspectProcessGroupUpgradeJournal(review: GroupUpgradeReview, publisherPid?: number, receiverPid?: number) {\n const file = path.join(review.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file) throw Error(\"Unsafe retained journal path\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const meta = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract','capture','runtime_namespace')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (meta[\"id\"] !== review.journalId || sha256(String(meta[\"contract\"])) !== review.journalContractSha256)\n throw Error(\"Retained journal contract changed\");\n const capture = JSON.parse(String(meta[\"capture\"] ?? \"null\"));\n const identity = (pid: number | undefined, digest: unknown) => {\n if (!pid || !Number.isSafeInteger(pid) || pid <= 0 || typeof digest !== \"string\" || process.platform !== \"linux\") return false;\n try {\n const namespace = sha256(fs.readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim() + \":\" + fs.readlinkSync(\"/proc/self/ns/pid\"));\n const stat = fs.readFileSync(`/proc/${pid}/stat`, \"utf8\"),\n start = stat.slice(stat.lastIndexOf(\")\") + 2).split(\" \")[19];\n return meta[\"runtime_namespace\"] === namespace && !!start && digest === sha256(namespace + \":\" + pid + \":\" + start);\n } catch {\n return false;\n }\n };\n const rows = db.prepare(\"SELECT name,pid,owner,runtime_identity FROM profiles\").all();\n return {\n receiverReady:\n capture?.pid === receiverPid &&\n [\"ready\", \"capacity-blocked\"].includes(capture?.state) &&\n Number.isSafeInteger(capture?.heartbeat) &&\n capture.heartbeat <= Date.now() + 1000 &&\n Date.now() - capture.heartbeat <= 5000 &&\n identity(receiverPid, capture.runtimeIdentity),\n publisherReady:\n rows.length === review.profiles.length &&\n review.profiles.every((p) =>\n rows.some((r) => r[\"name\"] === p.processName && r[\"pid\"] === publisherPid && !!r[\"owner\"] && identity(publisherPid, r[\"runtime_identity\"])),\n ),\n };\n } finally {\n db.close();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"process-group-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import { reviewInstalledConfigurationGroupUpgrade } from \"./process-group-configured-upgrade.js\";\nimport { selectedProcessGroupDescriptor } from \"./process-group-runtime-selection.js\";\nimport {processGroupGenerationInputSchema,type GroupGenerationReview,type GenerationJournalReference} from \"./process-group-generation.js\";\nimport fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport {\n authorizeProcessGroupRuntime,\n processGroupAuthorizationFile,\n processGroupAuthorizationSchema,\n processGroupManifestSchema,\n validateProcessGroupPolicyCandidate,\n} from \"./process-group-authorization.js\";\nimport {\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n processGroupJournalContract,\n processGroupJournalSchema,\n processGroupSourceIdentity,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\n\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\nconst processGroupVersionUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).superRefine((v, c) => {\n const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];\n if (\n new Set(all.map(placementKey)).size !== 4 ||\n all.some((p) => p.controller !== all[0]!.controller || p.rttNode !== all[0]!.rttNode) ||\n v.source.publisher.version !== v.source.receiver.version ||\n v.target.publisher.version !== v.target.receiver.version ||\n v.source.publisher.version === v.target.publisher.version\n )\n c.addIssue({ code: \"custom\", message: \"Four distinct placements, one package/controller and two paired versions required\" });\n});\nexport const processGroupUpgradeInputSchema=z.union([processGroupVersionUpgradeInputSchema,processGroupGenerationInputSchema]);\nexport type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;\nexport type UpgradeRole = \"publisher\" | \"receiver\";\nexport type UpgradeConfiguration = {\n packageRoot: string;\n instanceDirectory: string;\n raw: Record<string, unknown>;\n resolved: Record<string, unknown>;\n};\nexport type UpgradeConfigurations = Record<\"source\" | \"target\", Record<UpgradeRole, UpgradeConfiguration>>;\nexport type GroupVersionUpgradeReview = {\n protocolVersion: 1;\n /** Present only for configuration-owned protocol-2 resources retained across a version change. */\n retainedJournal?: GenerationJournalReference;\n namespace: string;\n groupId: string;\n policyFile: string;\n sourcePolicySha256: string;\n targetPolicySha256: string;\n journalId: string;\n directory: string;\n journalContractSha256: string;\n profiles: Array<{ processName: string; mappingSha256: string; dataGroup: string }>;\n members: Array<{ side: \"source\" | \"target\"; role: UpgradeRole; processName: string; configurationSha256: string; artifactSha256: string }>;\n};\nexport type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview;\nexport type PreparedGroupUpgrade = { review: GroupUpgradeReview; sourcePolicy: Buffer; targetPolicy: Buffer };\n\n/** Data-only same-host version review. No application JS, journal writes or launch authority. */\nexport function reviewInstalledProcessGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n if (Object.values(configs).flatMap(Object.values).some(c => selectedProcessGroupDescriptor(c.packageRoot, c.raw)?.protocolVersion === 2))\n return reviewInstalledConfigurationGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields);\n const first = configs.source.publisher;\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const old = authorizeProcessGroupRuntime(context(first));\n const receiver = authorizeProcessGroupRuntime(context(configs.source.receiver));\n if (\n old.role !== \"target\" ||\n receiver.role !== \"receiver\" ||\n old.file !== receiver.file ||\n old.directory !== receiver.directory ||\n !old.journalId ||\n old.journalId !== receiver.journalId\n )\n throw Error(\"Exact authorized source publisher/receiver pair required\");\n const sourcePolicy = read(old.file, true),\n previous = JSON.parse(sourcePolicy.toString());\n const target = configs.target.publisher,\n descriptor = processGroupDescriptor(target.packageRoot);\n if (!descriptor || descriptor.legacy) throw Error(\"Target requires the shared process-group protocol declaration\");\n const targetConfig = normalizeProcessGroupConfiguration(target.raw, descriptor);\n const journal = processGroupJournalSchema.parse(targetConfig.journal);\n const resource = descriptor.manifests.find((m) => m.file === journal.groupManifest);\n if (!resource) throw Error(\"Unregistered target manifest\");\n const manifestBytes = read(path.join(target.packageRoot, resource.file)),\n manifest = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)\n throw Error(\"Journal or manifest identity changed\");\n const members: GroupUpgradeReview[\"members\"] = [];\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const k of excludedUnsFields) delete uns[k];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const a = configs.source[role],\n b = configs.target[role];\n if (\n portable(a.raw) !== portable(b.raw) ||\n groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved))\n )\n throw Error(\"Configuration, broker identity, paths or units changed\");\n for (const side of [\"source\", \"target\"] as const) {\n const c = configs[side][role],\n d = processGroupDescriptor(c.packageRoot);\n if (!d) throw Error(\"Missing shared runtime contract\");\n const normalized = normalizeProcessGroupConfiguration(c.raw, d),\n j = processGroupJournalSchema.parse(normalized.journal);\n if (\n !normalized.matches ||\n (role === \"receiver\"\n ? normalized.runtimeRole !== \"admission\"\n : normalized.runtimeRole !== undefined && normalized.runtimeRole !== \"publisher\") ||\n j.directory !== old.directory ||\n j.journalId !== old.journalId ||\n sha256(read(path.join(c.packageRoot, j.groupManifest))) !== sha256(manifestBytes)\n )\n throw Error(\"Runtime role, manifest or journal differs\");\n members.push({\n side,\n role,\n processName: String(normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n }\n if (\n members.find((m) => m.role === \"publisher\")?.processName !== manifest.processName ||\n members.find((m) => m.role === \"receiver\")?.processName !== manifest.processName + \"-admission\"\n )\n throw Error(\"Manifest process identities differ\");\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const historical = previous.placements.filter((p: { role: string }) => p.role === \"source\");\n const policy = processGroupAuthorizationSchema.parse({\n schemaVersion: 3,\n kind: \"uns-process-group-runtime-authorization\",\n protocolVersion: 1,\n packageName: pkg.name,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n descriptorSha256: hash(pkg.unsDatahub.processGroupRuntime),\n controllerName,\n packageRoot: target.packageRoot,\n artifactSha256: groupArtifactHash(target.packageRoot),\n groupManifestSha256: sha256(manifestBytes),\n channelsSha256: groupChannelsHash(resolvedProcessGroupChannels(target.resolved)),\n stateRoot,\n directory: old.directory,\n journalId: old.journalId,\n placements: [\n ...historical,\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: hash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n const expected = processGroupJournalContract(\n processGroupSourceIdentity(resolvedProcessGroupChannels(target.resolved)[1]!),\n journal,\n manifest.profiles,\n );\n const file = path.join(old.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file || !fs.lstatSync(file).isFile()) throw Error(\"Unsafe journal resource\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const metadata = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (metadata[\"id\"] !== old.journalId || metadata[\"contract\"] !== expected)\n throw Error(\"Installed target cannot reopen the retained journal contract\");\n } finally {\n db.close();\n }\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: descriptor.namespace,\n groupId: manifest.id,\n policyFile: processGroupAuthorizationFile(context(target)),\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: old.journalId,\n directory: old.directory,\n journalContractSha256: sha256(expected),\n profiles: manifest.profiles.map(({ processName, mappingSha256, dataGroup }) => ({ processName, mappingSha256, dataGroup })),\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n\n/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */\nexport function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void {\n const actual = sha256(read(file, true)),\n next = sha256(bytes);\n if (actual === next) return; // Reconcile an already completed write after a lost reply.\n if (actual !== expected) throw Error(\"Runtime policy changed; review required\");\n const temporary = file + \".upgrade-tmp\";\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, bytes);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n try {\n if (sha256(read(file, true)) !== expected) throw Error(\"Runtime policy changed before replacement\");\n fs.renameSync(temporary, file);\n const directory = fs.openSync(path.dirname(file), \"r\");\n try {\n fs.fsyncSync(directory);\n } finally {\n fs.closeSync(directory);\n }\n } finally {\n if (fs.existsSync(temporary)) fs.unlinkSync(temporary);\n }\n}\n\nexport const processGroupUpgradeRequestSchema = z\n .strictObject({\n protocolVersion: z.literal(1),\n controllerName: groupPlacementSchema.shape.controller,\n action: z.enum([\"preview\", \"prepare\", \"get\", \"execute\", \"rollback\"]),\n input: processGroupUpgradeInputSchema.optional(),\n id: z.string().uuid().optional(),\n expectedFingerprint: z\n .string()\n .regex(/^[a-f0-9]{64}$/)\n .optional(),\n expectedRevision: z.number().int().positive().optional(),\n })\n .superRefine((v, c) => {\n if (\n ([\"preview\", \"prepare\"].includes(v.action) && !v.input) ||\n (v.action !== \"preview\" && !v.id) ||\n ([\"prepare\", \"execute\", \"rollback\"].includes(v.action) && !v.expectedFingerprint) ||\n ([\"execute\", \"rollback\"].includes(v.action) && !v.expectedRevision) ||\n (v.input && v.input.source.publisher.controller !== v.controllerName)\n )\n c.addIssue({ code: \"custom\", message: \"Exact upgrade selector and reviewed revision required\" });\n });\nexport type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;\n/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */\nexport function inspectProcessGroupUpgradeJournal(review: Pick<GroupVersionUpgradeReview,\"directory\"|\"journalId\"|\"journalContractSha256\"|\"profiles\">, publisherPid?: number, receiverPid?: number) {\n const file = path.join(review.directory, \"admission.sqlite\");\n if (fs.realpathSync(file) !== file) throw Error(\"Unsafe retained journal path\");\n const { DatabaseSync } = createRequire(import.meta.url)(\"node:sqlite\") as typeof import(\"node:sqlite\");\n const db = new DatabaseSync(file, { readOnly: true });\n try {\n db.exec(\"PRAGMA query_only=ON; PRAGMA busy_timeout=1000;\");\n const meta = Object.fromEntries(\n db\n .prepare(\"SELECT key,value FROM metadata WHERE key IN ('id','contract','capture','runtime_namespace')\")\n .all()\n .map((r) => [r[\"key\"], r[\"value\"]]),\n );\n if (meta[\"id\"] !== review.journalId || sha256(String(meta[\"contract\"])) !== review.journalContractSha256)\n throw Error(\"Retained journal contract changed\");\n const capture = JSON.parse(String(meta[\"capture\"] ?? \"null\"));\n const identity = (pid: number | undefined, digest: unknown) => {\n if (!pid || !Number.isSafeInteger(pid) || pid <= 0 || typeof digest !== \"string\" || process.platform !== \"linux\") return false;\n try {\n const namespace = sha256(fs.readFileSync(\"/proc/sys/kernel/random/boot_id\", \"utf8\").trim() + \":\" + fs.readlinkSync(\"/proc/self/ns/pid\"));\n const stat = fs.readFileSync(`/proc/${pid}/stat`, \"utf8\"),\n start = stat.slice(stat.lastIndexOf(\")\") + 2).split(\" \")[19];\n return meta[\"runtime_namespace\"] === namespace && !!start && digest === sha256(namespace + \":\" + pid + \":\" + start);\n } catch {\n return false;\n }\n };\n const rows = db.prepare(\"SELECT name,pid,owner,runtime_identity FROM profiles\").all();\n return {\n receiverReady:\n capture?.pid === receiverPid &&\n [\"ready\", \"capacity-blocked\"].includes(capture?.state) &&\n Number.isSafeInteger(capture?.heartbeat) &&\n capture.heartbeat <= Date.now() + 1000 &&\n Date.now() - capture.heartbeat <= 5000 &&\n identity(receiverPid, capture.runtimeIdentity),\n publisherReady:\n rows.length === review.profiles.length &&\n review.profiles.every((p) =>\n rows.some((r) => r[\"name\"] === p.processName && r[\"pid\"] === publisherPid && !!r[\"owner\"] && identity(publisherPid, r[\"runtime_identity\"])),\n ),\n };\n } finally {\n db.close();\n }\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MqttPublishQueueOptions } from "../uns-mqtt/publish-queue-contract.js";
|
|
1
2
|
import type { HandoverShutdownHooks } from "./handover-shutdown.js";
|
|
2
3
|
import { UnsAttributeType } from "../graphql/schema.js";
|
|
3
4
|
import { MeasurementUnit } from "./uns-measurements.js";
|
|
@@ -48,6 +49,8 @@ export type QuestDbPrimitiveType = (typeof questDbPrimitiveTypes)[number];
|
|
|
48
49
|
export type QuestDbType = QuestDbPrimitiveType | `geohash(${number}${"b" | "c"})` | `decimal(${number},${number})` | `array<${string}>`;
|
|
49
50
|
export declare function isQuestDbType(value: unknown): value is QuestDbType;
|
|
50
51
|
export interface IUnsParameters {
|
|
52
|
+
/** Optional MQTT output persistence; absence keeps issued queue behavior. */
|
|
53
|
+
publishQueue?: MqttPublishQueueOptions;
|
|
51
54
|
mqttSubToTopics?: string | string[];
|
|
52
55
|
username?: string;
|
|
53
56
|
password?: string;
|