@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.
Files changed (103) hide show
  1. package/MIGRATIONS.md +100 -0
  2. package/README.md +10 -0
  3. package/dist/config/app-config.d.ts +14 -0
  4. package/dist/config/app-config.d.ts.map +1 -1
  5. package/dist/config/app-config.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/runtime/configuration-group-authorization.d.ts +50 -0
  11. package/dist/runtime/configuration-group-authorization.d.ts.map +1 -0
  12. package/dist/runtime/configuration-group-authorization.js +113 -0
  13. package/dist/runtime/configuration-group-authorization.js.map +1 -0
  14. package/dist/runtime/configuration-group-contract.d.ts +75 -0
  15. package/dist/runtime/configuration-group-contract.d.ts.map +1 -0
  16. package/dist/runtime/configuration-group-contract.js +233 -0
  17. package/dist/runtime/configuration-group-contract.js.map +1 -0
  18. package/dist/runtime/process-group-authorization.d.ts +2 -0
  19. package/dist/runtime/process-group-authorization.d.ts.map +1 -1
  20. package/dist/runtime/process-group-authorization.js +34 -12
  21. package/dist/runtime/process-group-authorization.js.map +1 -1
  22. package/dist/runtime/process-group-backup-contract.d.ts +22 -0
  23. package/dist/runtime/process-group-backup-contract.d.ts.map +1 -0
  24. package/dist/runtime/process-group-backup-contract.js +20 -0
  25. package/dist/runtime/process-group-backup-contract.js.map +1 -0
  26. package/dist/runtime/process-group-backup-contract.json +7 -0
  27. package/dist/runtime/process-group-configured-upgrade.d.ts +4 -0
  28. package/dist/runtime/process-group-configured-upgrade.d.ts.map +1 -0
  29. package/dist/runtime/process-group-configured-upgrade.js +107 -0
  30. package/dist/runtime/process-group-configured-upgrade.js.map +1 -0
  31. package/dist/runtime/process-group-generation.d.ts +166 -0
  32. package/dist/runtime/process-group-generation.d.ts.map +1 -0
  33. package/dist/runtime/process-group-generation.js +278 -0
  34. package/dist/runtime/process-group-generation.js.map +1 -0
  35. package/dist/runtime/process-group-inspection.d.ts +2 -0
  36. package/dist/runtime/process-group-inspection.d.ts.map +1 -1
  37. package/dist/runtime/process-group-inspection.js +120 -40
  38. package/dist/runtime/process-group-inspection.js.map +1 -1
  39. package/dist/runtime/process-group-resources.d.ts +1 -0
  40. package/dist/runtime/process-group-resources.d.ts.map +1 -1
  41. package/dist/runtime/process-group-resources.js +8 -0
  42. package/dist/runtime/process-group-resources.js.map +1 -1
  43. package/dist/runtime/process-group-runtime-selection.d.ts +14 -0
  44. package/dist/runtime/process-group-runtime-selection.d.ts.map +1 -0
  45. package/dist/runtime/process-group-runtime-selection.js +29 -0
  46. package/dist/runtime/process-group-runtime-selection.js.map +1 -0
  47. package/dist/runtime/process-group-snapshot.mjs +60 -8
  48. package/dist/runtime/process-group-staging.d.ts +2 -2
  49. package/dist/runtime/process-group-staging.d.ts.map +1 -1
  50. package/dist/runtime/process-group-staging.js +6 -4
  51. package/dist/runtime/process-group-staging.js.map +1 -1
  52. package/dist/runtime/process-group-supervision.d.ts +2 -2
  53. package/dist/runtime/process-group-supervision.d.ts.map +1 -1
  54. package/dist/runtime/process-group-supervision.js +3 -2
  55. package/dist/runtime/process-group-supervision.js.map +1 -1
  56. package/dist/runtime/process-group-upgrade.d.ts +76 -6
  57. package/dist/runtime/process-group-upgrade.d.ts.map +1 -1
  58. package/dist/runtime/process-group-upgrade.js +7 -1
  59. package/dist/runtime/process-group-upgrade.js.map +1 -1
  60. package/dist/uns/uns-interfaces.d.ts +3 -0
  61. package/dist/uns/uns-interfaces.d.ts.map +1 -1
  62. package/dist/uns/uns-interfaces.js.map +1 -1
  63. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  64. package/dist/uns/uns-proxy-process.js +3 -0
  65. package/dist/uns/uns-proxy-process.js.map +1 -1
  66. package/dist/uns-config/config-schema.d.ts +16 -0
  67. package/dist/uns-config/config-schema.d.ts.map +1 -1
  68. package/dist/uns-config/mqtt-channel.d.ts +1 -1
  69. package/dist/uns-config/mqtt-channel.d.ts.map +1 -1
  70. package/dist/uns-config/mqtt-channel.js +3 -0
  71. package/dist/uns-config/mqtt-channel.js.map +1 -1
  72. package/dist/uns-config/uns-core-schema.d.ts +137 -0
  73. package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
  74. package/dist/uns-config/uns-core-schema.js +6 -1
  75. package/dist/uns-config/uns-core-schema.js.map +1 -1
  76. package/dist/uns-mqtt/mqtt-interfaces.d.ts +5 -0
  77. package/dist/uns-mqtt/mqtt-interfaces.d.ts.map +1 -1
  78. package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
  79. package/dist/uns-mqtt/mqtt-proxy.d.ts +3 -0
  80. package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
  81. package/dist/uns-mqtt/mqtt-proxy.js +26 -1
  82. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  83. package/dist/uns-mqtt/mqtt-worker.d.ts +3 -1
  84. package/dist/uns-mqtt/mqtt-worker.d.ts.map +1 -1
  85. package/dist/uns-mqtt/mqtt-worker.js +45 -8
  86. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  87. package/dist/uns-mqtt/publish-queue-contract.d.ts +33 -0
  88. package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -0
  89. package/dist/uns-mqtt/publish-queue-contract.js +18 -0
  90. package/dist/uns-mqtt/publish-queue-contract.js.map +1 -0
  91. package/dist/uns-mqtt/publish-queue-store.d.ts +33 -0
  92. package/dist/uns-mqtt/publish-queue-store.d.ts.map +1 -0
  93. package/dist/uns-mqtt/publish-queue-store.js +177 -0
  94. package/dist/uns-mqtt/publish-queue-store.js.map +1 -0
  95. package/dist/uns-mqtt/publish-queue.d.ts +43 -0
  96. package/dist/uns-mqtt/publish-queue.d.ts.map +1 -0
  97. package/dist/uns-mqtt/publish-queue.js +235 -0
  98. package/dist/uns-mqtt/publish-queue.js.map +1 -0
  99. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +7 -0
  100. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
  101. package/dist/uns-mqtt/uns-mqtt-proxy.js +98 -5
  102. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  103. 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 > 9) fail();
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 >= 9) fail();
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 > 512 * 1024 * 1024) fail();
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 > 512 * 1024 * 1024 - snapshotBytes ||
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 (profiles.length < 1 || profiles.length > 19 || contract.version !== 1 || contract.profiles.length !== profiles.length) fail();
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 > 512 * 1024 * 1024) fail();
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
- fs.writeFileSync(path.join(output, "manifest.json"), JSON.stringify(manifest) + "\n", { mode: 0o600, flag: "wx" });
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 ProcessGroupRuntimeDescriptor } from "./process-group-contract.js";
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: ProcessGroupRuntimeDescriptor | undefined): void;
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":"AAIA,OAAO,EAAE,KAAK,6BAA6B,EAAsC,MAAM,6BAA6B,CAAC;AAErH,eAAO,MAAM,iBAAiB,sCAAsC,CAAC;AACrE,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,6BAA6B,GAAG,SAAS,GAAG,IAAI,CAmDnJ"}
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 { normalizeProcessGroupConfiguration } from "./process-group-contract.js";
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 journal = descriptor
18
- ? normalizeProcessGroupConfiguration(config, descriptor).journal
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":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { type ProcessGroupRuntimeDescriptor, normalizeProcessGroupConfiguration } from \"./process-group-contract.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: ProcessGroupRuntimeDescriptor | 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 journal = descriptor\n ? (normalizeProcessGroupConfiguration(config, descriptor).journal as { directory?: unknown; journalId?: unknown } | undefined)\n : undefined;\n if (!stopped || !journal || journal.journalId !== undefined) {\n fs.rmSync(marker, { force: true });\n return;\n }\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
+ {"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 ProcessGroupRuntimeDescriptor } from "./process-group-contract.js";
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: ProcessGroupRuntimeDescriptor | undefined, instanceDirectory: string, capabilities: {
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":"AACA,OAAO,EAAE,KAAK,6BAA6B,EAAwD,MAAM,6BAA6B,CAAC;AAEvI,6FAA6F;AAC7F,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,UAAU,EAAE,6BAA6B,GAAG,SAAS,EACrD,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
+ {"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, normalizeProcessGroupConfiguration } from "./process-group-contract.js";
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 = normalizeProcessGroupConfiguration(raw, descriptor);
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,EAAsC,gBAAgB,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AAEvI,6FAA6F;AAC7F,MAAM,UAAU,+BAA+B,CAC7C,GAA4B,EAC5B,UAAqD,EACrD,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,kCAAkC,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC9D,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 { type ProcessGroupRuntimeDescriptor, isLocalPilotPath, normalizeProcessGroupConfiguration } from \"./process-group-contract.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: ProcessGroupRuntimeDescriptor | 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 = normalizeProcessGroupConfiguration(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
+ {"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 GroupUpgradeReview = {
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: GroupUpgradeReview, publisherPid?: number, receiverPid?: number): {
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":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2BxB,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AACtF,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AACnD,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,QAAQ,GAAG,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAC3G,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5I,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9G,iGAAiG;AACjG,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAsJtB;AAED,+FAA+F;AAC/F,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAyBrG;AAED,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsBzC,CAAC;AACL,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC1F,8FAA8F;AAC9F,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,kBAAkB,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;;;EA6CxH"}
1
+ {"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmC,KAAK,qBAAqB,EAAC,KAAK,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAI3I,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsCxB,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAmF,CAAC;AAC/H,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AACtF,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AACnD,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,QAAQ,GAAG,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAC3G,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,EAAE,CAAC,CAAC;IACnB,kGAAkG;IAClG,eAAe,CAAC,EAAE,0BAA0B,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5I,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,GAAG,qBAAqB,CAAC;AACnF,MAAM,MAAM,oBAAoB,GAAG;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9G,iGAAiG;AACjG,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAwJtB;AAED,+FAA+F;AAC/F,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAyBrG;AAED,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsBzC,CAAC;AACL,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC1F,8FAA8F;AAC9F,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,IAAI,CAAC,yBAAyB,EAAC,WAAW,GAAC,WAAW,GAAC,uBAAuB,GAAC,UAAU,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;;;EA6ChM"}
@@ -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
- export const processGroupUpgradeInputSchema = z.strictObject({ protocolVersion: z.literal(1), source: pair, target: pair }).superRefine((v, c) => {
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":"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","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;