@uns-kit/core 3.0.31 → 3.0.32

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 CHANGED
@@ -9,6 +9,33 @@ Agents must inspect the application's existing ownership and shutdown flow
9
9
  before editing it. The examples below describe the intended behavior, not a
10
10
  mechanical search-and-replace operation.
11
11
 
12
+ ## 3.0.32 - Reviewed process-group MQTT output enablement
13
+
14
+ When crossing `<3.0.32` to `>=3.0.32`, ordinary services, input journals and
15
+ existing outboxes remain unchanged. Output persistence is never enabled by a
16
+ package update. Hosts may explicitly review nested paired transition protocol 3
17
+ through `runtime/process-group-upgrade.js`; ordinary version/generation reviews
18
+ retain their strict configuration comparison.
19
+
20
+ Applications opting in declare
21
+ `unsDatahub.processGroupMqttOutputRuntime = { protocolVersion: 1, instanceName }`,
22
+ matching the actual SDK output proxy. Keep parsing, profiles, resources, paths and
23
+ units in the application; do not add a service-name branch to a host.
24
+
25
+ Use a separate reviewed permanent output mount and retain the exact input journal.
26
+ On rollback, stop admission and drain already admitted input before stopping the
27
+ publisher. Pending output, changed storage/owner/destination and unknown outcomes
28
+ block restoration; preserve both journals and reconcile the same operation. Never
29
+ rename an owner, choose another directory or remove data to bypass these checks.
30
+ The managed outbox format remains schema2 and the stable identity serialization
31
+ is byte compatible with3.0.31. A matching host implementation is required for the
32
+ optional transition; applications without the capability require no migration.
33
+
34
+ See the SDK developer guide
35
+ [reviewed MQTT output enablement](https://github.com/uns-openhub/uns-kit/blob/master/docs/process-group-mqtt-output-transition.md)
36
+ for declarations, proxy configuration, review examples and recovery limits.
37
+ Source preparation and owner-operated npm publication are separate steps.
38
+
12
39
  ## 3.0.31 - Explicit Runtime-managed MQTT outbox storage
13
40
 
14
41
  For an optional Runtime-managed MQTT outbox set `output.publishQueue.storage` to
@@ -26,3 +26,7 @@ export function validateOutputSnapshot(directory: string, limits: unknown): { qu
26
26
  export function outputStateRelative(root: string, directory: string): string;
27
27
 
28
28
  export function outputStateMain(args?: string[]): Promise<void>;
29
+
30
+ export function inspectManagedOutputQueue(root: string, directory: string, identity: string, limits: unknown, requireStopped?: boolean): {
31
+ rootId: string; relative: string; identity: string; records: number; bytes: number; exists: boolean; ownerActive:boolean;
32
+ };
@@ -187,6 +187,56 @@ export function openManagedOutputRoot(directory, root) {
187
187
  throw e;
188
188
  }
189
189
  }
190
+ /** Read-only reviewed handoff evidence. Never initializes, deletes or rebinds a queue. */
191
+ export function inspectManagedOutputQueue(root, directory, identity, limits, requireStopped = true) {
192
+ outputStateLimits(limits);
193
+ assertOutputStateRoot(root);
194
+ const relative = outputStateRelative(root, directory);
195
+ noLinks(directory);
196
+ const { DatabaseSync } = sqlite();
197
+ const file = path.join(root, guardName);
198
+ check(file);
199
+ check(file + "-journal", false, true);
200
+ const guard = new DatabaseSync(file, { readOnly: true });
201
+ let owner;
202
+ try {
203
+ guard.exec("PRAGMA busy_timeout=1000; BEGIN");
204
+ const meta = Object.fromEntries(guard.prepare("SELECT key,value FROM metadata").all().map(r => [r.key,r.value]));
205
+ if (!exactKeys(meta, ["schema", "id"]) || meta.schema !== "mqtt-output-root-1" || !uuid.test(meta.id)) fail();
206
+ const marker = path.join(root, markerName);
207
+ if (fs.existsSync(marker)) {
208
+ const m = privateJson(marker);
209
+ if (!exactKeys(m,["schemaVersion","state","sourceSha","rootId"]) || m.schemaVersion !== 1 ||
210
+ m.state !== "complete" || !hex.test(m.sourceSha) || m.rootId !== meta.id) fail();
211
+ }
212
+ if (fs.existsSync(path.join(root, stageName))) fail();
213
+ check(path.dirname(directory), true, true);
214
+ const base = {rootId: meta.id, relative, identity};
215
+ if (!check(directory, true, true)) return {...base, records:0, bytes:0, exists:false, ownerActive:false};
216
+ const entries = fs.opendirSync(directory);
217
+ const names = [];
218
+ try { let e; while ((e=entries.readSync())) { if (names.length >= 5) fail(); names.push(e.name); } }
219
+ finally { entries.closeSync(); }
220
+ if (names.length === 0) return {...base, records:0, bytes:0, exists:false, ownerActive:false};
221
+ if (names.some(n => !["mqtt-outbox.sqlite","mqtt-outbox.sqlite-wal","mqtt-outbox.sqlite-shm","mqtt-outbox-owner.sqlite","mqtt-outbox-owner.sqlite-journal"].includes(n))) fail();
222
+ let physicalBytes=0;
223
+ for (const name of names) { physicalBytes+=check(path.join(directory,name)).size; if(physicalBytes>limits.maximumSnapshotBytes) fail(); }
224
+ const ownerFile = path.join(directory,"mqtt-outbox-owner.sqlite");
225
+ check(ownerFile);
226
+ // Existing writer's exclusive lease must be released, even when usage is zero.
227
+ let ownerActive=false;
228
+ owner = new DatabaseSync(ownerFile);
229
+ try { owner.exec("PRAGMA busy_timeout=0; BEGIN EXCLUSIVE"); }
230
+ catch(e) { if(requireStopped || e.errcode!==5) throw e; ownerActive=true; }
231
+
232
+ const dbFile = path.join(directory,"mqtt-outbox.sqlite");
233
+ if (check(dbFile).size > limits.maximumSnapshotBytes) fail();
234
+ const status = inspectDatabase(dbFile,{rootId:meta.id,relative},limits);
235
+ if (status.identity !== identity) fail();
236
+ return {...base, records:status.records, bytes:status.bytes, exists:true, ownerActive};
237
+ } finally { owner?.close(); guard.close(); }
238
+ }
239
+
190
240
  export function validateOutputRow(row) {
191
241
  if (typeof row.record !== "string" || sha(row.record) !== row.sha256) throw Error("MQTT outbox integrity check failed; pending work preserved");
192
242
  const r = JSON.parse(row.record);
@@ -219,6 +269,7 @@ function inspectDatabase(file, binding, limits) {
219
269
  const { DatabaseSync } = sqlite(),
220
270
  db = new DatabaseSync(file, { readOnly: true });
221
271
  try {
272
+ db.exec("PRAGMA busy_timeout=1000; BEGIN");
222
273
  if (db.prepare("PRAGMA quick_check").get().quick_check !== "ok") fail();
223
274
  const meta = Object.fromEntries(
224
275
  db
@@ -1,4 +1,5 @@
1
1
  import type { PreparedGroupUpgrade, UpgradeConfigurations } from "./process-group-upgrade.js";
2
2
  /** Same generation, different paired artifacts. Never initializes or rewrites the journal. */
3
3
  export declare function reviewInstalledConfigurationGroupUpgrade(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
4
+ export declare function reviewInstalledConfigurationGroupMqttOutput(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
4
5
  //# sourceMappingURL=process-group-configured-upgrade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-group-configured-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAA6B,oBAAoB,EAAwB,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAE/I,8FAA8F;AAC9F,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAyGtB"}
1
+ {"version":3,"file":"process-group-configured-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAGV,oBAAoB,EAEpB,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AAEpC,8FAA8F;AAC9F,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAEtB;AACD,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAYtB"}
@@ -4,9 +4,26 @@ import { configurationResourceHash } from "./configuration-group-contract.js";
4
4
  import { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from "./process-group-authorization.js";
5
5
  import { resolvedProcessGroupChannels } from "./process-group-contract.js";
6
6
  import { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from "./process-group-generation.js";
7
+ import { mqttOutputPortableConfiguration, reviewProcessGroupMqttOutput } from "./process-group-mqtt-output.js";
7
8
  import { groupArtifactHash, groupChannelsHash, configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256, } from "./process-group-resources.js";
8
9
  /** Same generation, different paired artifacts. Never initializes or rewrites the journal. */
9
10
  export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields = []) {
11
+ return reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, false);
12
+ }
13
+ export function reviewInstalledConfigurationGroupMqttOutput(configs, controllerName, stateRoot, excludedUnsFields = []) {
14
+ const mqttOutput = reviewProcessGroupMqttOutput(configs, process.env["UNS_MQTT_OUTPUT_STATE_ROOT"], stateRoot);
15
+ const result = reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, true);
16
+ return {
17
+ ...result,
18
+ review: {
19
+ ...result.review,
20
+ protocolVersion: 3,
21
+ mqttOutput,
22
+ delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },
23
+ },
24
+ };
25
+ }
26
+ function reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, mqttOutput) {
10
27
  const context = (c) => ({
11
28
  packageRoot: c.packageRoot,
12
29
  instanceDirectory: c.instanceDirectory,
@@ -19,12 +36,12 @@ export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName
19
36
  if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))
20
37
  throw Error("Unchanged configuration generation required; review resource changes as a separate generation");
21
38
  const pkg = (c) => JSON.parse(read(path.join(c.packageRoot, "package.json")).toString()), sourcePackage = pkg(source), targetPackage = pkg(target);
22
- if (!sourcePackage.version || !targetPackage.version || sourcePackage.version === targetPackage.version)
39
+ if (!sourcePackage.version || !targetPackage.version || (!mqttOutput && sourcePackage.version === targetPackage.version))
23
40
  throw Error("Two different installed paired versions required");
24
41
  const old = authorizeProcessGroupRuntime(context(source));
25
42
  const sourcePolicy = read(old.file, true), previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));
26
- const portable = (raw) => {
27
- const copy = structuredClone(raw), uns = { ...copy["uns"] };
43
+ const portable = (raw, role) => {
44
+ const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw), uns = { ...copy["uns"] };
28
45
  for (const key of excludedUnsFields)
29
46
  delete uns[key];
30
47
  copy["uns"] = uns;
@@ -46,7 +63,7 @@ export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName
46
63
  (role === "receiver"
47
64
  ? g.normalized.runtimeRole !== "admission"
48
65
  : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== "publisher") ||
49
- portable(c.raw) !== portable(configs.source[role].raw) ||
66
+ portable(c.raw, role) !== portable(configs.source[role].raw, role) ||
50
67
  groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||
51
68
  processGroupAuthorizationFile(context(c)) !== old.file)
52
69
  throw Error("Exact paired configuration, resources, broker identity and retained journal required");
@@ -1 +1 @@
1
- {"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type { GroupVersionUpgradeReview, PreparedGroupUpgrade, UpgradeConfiguration, UpgradeConfigurations } from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\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 source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || sourcePackage.version === targetPackage.version)\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw) !== portable(configs.source[role].raw) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\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: configurationResourceHash(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 inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\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: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
1
+ {"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport { mqttOutputPortableConfiguration, reviewProcessGroupMqttOutput } from \"./process-group-mqtt-output.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type {\n GroupMqttOutputReview,\n GroupVersionUpgradeReview,\n PreparedGroupUpgrade,\n UpgradeConfiguration,\n UpgradeConfigurations,\n} from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n return reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, false);\n}\nexport function reviewInstalledConfigurationGroupMqttOutput(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const mqttOutput = reviewProcessGroupMqttOutput(configs, process.env[\"UNS_MQTT_OUTPUT_STATE_ROOT\"], stateRoot);\n const result = reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, true);\n return {\n ...result,\n review: {\n ...result.review,\n protocolVersion: 3,\n mqttOutput,\n delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },\n } as GroupMqttOutputReview,\n };\n}\nfunction reviewConfigurationGroup(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[],\n mqttOutput: boolean,\n): PreparedGroupUpgrade {\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 source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || (!mqttOutput && sourcePackage.version === targetPackage.version))\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>, role: \"publisher\" | \"receiver\") => {\n const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw, role) !== portable(configs.source[role].raw, role) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\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: configurationResourceHash(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 inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\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: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import type { UpgradeConfigurations } from "./process-group-upgrade.js";
3
+ export declare const processGroupMqttOutputRuntimeSchema: z.ZodObject<{
4
+ protocolVersion: z.ZodLiteral<1>;
5
+ instanceName: z.ZodString;
6
+ }, z.core.$strict>;
7
+ /** An explicit output enablement, never an incidental version/configuration change. */
8
+ export declare const processGroupMqttOutputInputSchema: z.ZodObject<{
9
+ protocolVersion: z.ZodLiteral<3>;
10
+ source: z.ZodObject<{
11
+ publisher: z.ZodObject<{
12
+ controller: z.ZodString;
13
+ rttNode: z.ZodString;
14
+ version: z.ZodString;
15
+ instanceId: z.ZodString;
16
+ }, z.core.$strict>;
17
+ receiver: z.ZodObject<{
18
+ controller: z.ZodString;
19
+ rttNode: z.ZodString;
20
+ version: z.ZodString;
21
+ instanceId: z.ZodString;
22
+ }, z.core.$strict>;
23
+ }, z.core.$strict>;
24
+ target: z.ZodObject<{
25
+ publisher: z.ZodObject<{
26
+ controller: z.ZodString;
27
+ rttNode: z.ZodString;
28
+ version: z.ZodString;
29
+ instanceId: z.ZodString;
30
+ }, z.core.$strict>;
31
+ receiver: z.ZodObject<{
32
+ controller: z.ZodString;
33
+ rttNode: z.ZodString;
34
+ version: z.ZodString;
35
+ instanceId: z.ZodString;
36
+ }, z.core.$strict>;
37
+ }, z.core.$strict>;
38
+ acknowledgeInputPause: z.ZodLiteral<true>;
39
+ acknowledgePossibleReplay: z.ZodLiteral<true>;
40
+ acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
41
+ }, z.core.$strict>;
42
+ export type GroupMqttOutputReference = {
43
+ root: string;
44
+ directory: string;
45
+ rootId: string;
46
+ relative: string;
47
+ identity: string;
48
+ optionsSha256: string;
49
+ };
50
+ /** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */
51
+ export declare function mqttOutputPortableConfiguration(raw: Record<string, unknown>, role: "publisher" | "receiver"): Record<string, unknown>;
52
+ export declare function reviewProcessGroupMqttOutput(configs: UpgradeConfigurations, root: string | undefined, stateRoot: string): GroupMqttOutputReference;
53
+ /** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */
54
+ export declare function inspectReviewedProcessGroupMqttOutput(reference: GroupMqttOutputReference, requireStopped?: boolean): {
55
+ rootId: string;
56
+ relative: string;
57
+ identity: string;
58
+ records: number;
59
+ bytes: number;
60
+ exists: boolean;
61
+ ownerActive: boolean;
62
+ };
63
+ //# sourceMappingURL=process-group-mqtt-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-group-mqtt-output.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-mqtt-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,eAAO,MAAM,mCAAmC;;;kBAG9C,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkB1C,CAAC;AACL,MAAM,MAAM,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AACtJ,sGAAsG;AACtG,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,2BAe3G;AACD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,wBAAwB,CA6BlJ;AACD,mGAAmG;AACnG,wBAAgB,qCAAqC,CAAC,SAAS,EAAE,wBAAwB,EAAE,cAAc,UAAO;;;;;;;;EAI/G"}
@@ -0,0 +1,89 @@
1
+ import path from "node:path";
2
+ import { z } from "zod";
3
+ import { mqttPublishQueueIdentity, mqttPublishQueueSchema } from "../uns-mqtt/publish-queue-contract.js";
4
+ import { managedMqttOutputBinding, mqttOutputStateLimits } from "./mqtt-output-state-contract.js";
5
+ import { inspectManagedOutputQueue } from "./mqtt-output-state-program.mjs";
6
+ import { resolvedProcessGroupChannels } from "./process-group-contract.js";
7
+ import { groupPlacementSchema, placementKey } from "./process-group-control-contract.js";
8
+ import { configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256 } from "./process-group-resources.js";
9
+ export const processGroupMqttOutputRuntimeSchema = z.strictObject({
10
+ protocolVersion: z.literal(1),
11
+ instanceName: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/),
12
+ });
13
+ const pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });
14
+ /** An explicit output enablement, never an incidental version/configuration change. */
15
+ export const processGroupMqttOutputInputSchema = z
16
+ .strictObject({
17
+ protocolVersion: z.literal(3),
18
+ source: pair,
19
+ target: pair,
20
+ acknowledgeInputPause: z.literal(true),
21
+ acknowledgePossibleReplay: z.literal(true),
22
+ acknowledgePendingOutputBlocksRollback: z.literal(true),
23
+ })
24
+ .superRefine((v, c) => {
25
+ const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];
26
+ if (new Set(all.map(placementKey)).size !== 4 ||
27
+ all.some((p) => p.controller !== all[0].controller || p.rttNode !== all[0].rttNode) ||
28
+ v.source.publisher.version !== v.source.receiver.version ||
29
+ v.target.publisher.version !== v.target.receiver.version)
30
+ c.addIssue({ code: "custom", message: "Four distinct same-host paired placements required" });
31
+ });
32
+ /** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */
33
+ export function mqttOutputPortableConfiguration(raw, role) {
34
+ const copy = structuredClone(raw);
35
+ if (role === "publisher") {
36
+ const output = copy["output"];
37
+ if (output) {
38
+ delete output["publishQueue"];
39
+ if (!Object.keys(output).length)
40
+ delete copy["output"];
41
+ }
42
+ const uns = copy["uns"];
43
+ if (uns) {
44
+ delete uns["handover"];
45
+ delete uns["instanceMode"];
46
+ }
47
+ }
48
+ return copy;
49
+ }
50
+ export function reviewProcessGroupMqttOutput(configs, root, stateRoot) {
51
+ const source = configs.source.publisher, target = configs.target.publisher;
52
+ for (const role of ["publisher", "receiver"]) {
53
+ const raw = configs.source[role].raw;
54
+ if (raw.output?.publishQueue !== undefined)
55
+ throw Error("Output enablement requires a source without an MQTT queue");
56
+ }
57
+ if (configs.target.receiver.raw["output"]?.publishQueue !== undefined)
58
+ throw Error("Admission receiver cannot own the publisher output queue");
59
+ const queue = mqttPublishQueueSchema.parse(target.raw["output"]?.publishQueue);
60
+ if (queue.mode !== "durable" || queue.storage !== "runtime")
61
+ throw Error("Reviewed output enablement requires durable Runtime storage");
62
+ const uns = target.raw["uns"];
63
+ if (uns["handover"] !== false || !["force", "wait"].includes(String(uns["instanceMode"])))
64
+ throw Error("MQTT output enablement requires explicit stop-before-start configuration");
65
+ if (!root || path.resolve(root) === path.resolve(stateRoot) || queue.directory.startsWith(path.resolve(stateRoot) + path.sep))
66
+ throw Error("A separate permanent MQTT output mount is required");
67
+ const binding = managedMqttOutputBinding(target.raw, root);
68
+ const pkg = JSON.parse(read(path.join(target.packageRoot, "package.json")).toString());
69
+ const sourcePackage = JSON.parse(read(path.join(source.packageRoot, "package.json")).toString());
70
+ if (pkg.name !== sourcePackage.name)
71
+ throw Error("Publisher package identity changed");
72
+ const declaration = processGroupMqttOutputRuntimeSchema.parse(pkg.unsDatahub?.processGroupMqttOutputRuntime);
73
+ const processName = String(target.raw["uns"]["processName"]);
74
+ if (processName !== String(source.raw["uns"]["processName"]))
75
+ throw Error("Publisher identity changed");
76
+ const identity = sha256(mqttPublishQueueIdentity(pkg.name, processName + "-" + declaration.instanceName, resolvedProcessGroupChannels(target.resolved)[2]));
77
+ const status = inspectManagedOutputQueue(root, binding.directory, identity, mqttOutputStateLimits);
78
+ if (status.records || status.bytes)
79
+ throw Error("Output enablement requires an empty original-destination queue; preserve pending work");
80
+ return { root, directory: binding.directory, rootId: status.rootId, relative: binding.relative, identity, optionsSha256: hash(queue) };
81
+ }
82
+ /** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */
83
+ export function inspectReviewedProcessGroupMqttOutput(reference, requireStopped = true) {
84
+ const status = inspectManagedOutputQueue(reference.root, reference.directory, reference.identity, mqttOutputStateLimits, requireStopped);
85
+ if (status.rootId !== reference.rootId || status.relative !== reference.relative)
86
+ throw Error("Reviewed MQTT output storage identity changed");
87
+ return status;
88
+ }
89
+ //# sourceMappingURL=process-group-mqtt-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-group-mqtt-output.js","sourceRoot":"","sources":["../../src/runtime/process-group-mqtt-output.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { z } from \"zod\";\n\nimport { mqttPublishQueueIdentity, mqttPublishQueueSchema } from \"../uns-mqtt/publish-queue-contract.js\";\nimport { managedMqttOutputBinding, mqttOutputStateLimits } from \"./mqtt-output-state-contract.js\";\nimport { inspectManagedOutputQueue } from \"./mqtt-output-state-program.mjs\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { groupPlacementSchema, placementKey } from \"./process-group-control-contract.js\";\nimport { configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256 } from \"./process-group-resources.js\";\nimport type { UpgradeConfigurations } from \"./process-group-upgrade.js\";\n\nexport const processGroupMqttOutputRuntimeSchema = z.strictObject({\n protocolVersion: z.literal(1),\n instanceName: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/),\n});\nconst pair = z.strictObject({ publisher: groupPlacementSchema, receiver: groupPlacementSchema });\n/** An explicit output enablement, never an incidental version/configuration change. */\nexport const processGroupMqttOutputInputSchema = z\n .strictObject({\n protocolVersion: z.literal(3),\n source: pair,\n target: pair,\n acknowledgeInputPause: z.literal(true),\n acknowledgePossibleReplay: z.literal(true),\n acknowledgePendingOutputBlocksRollback: z.literal(true),\n })\n .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 )\n c.addIssue({ code: \"custom\", message: \"Four distinct same-host paired placements required\" });\n });\nexport type GroupMqttOutputReference = { root: string; directory: string; rootId: string; relative: string; identity: string; optionsSha256: string };\n/** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */\nexport function mqttOutputPortableConfiguration(raw: Record<string, unknown>, role: \"publisher\" | \"receiver\") {\n const copy = structuredClone(raw);\n if (role === \"publisher\") {\n const output = copy[\"output\"] as Record<string, unknown> | undefined;\n if (output) {\n delete output[\"publishQueue\"];\n if (!Object.keys(output).length) delete copy[\"output\"];\n }\n const uns = copy[\"uns\"] as Record<string, unknown> | undefined;\n if (uns) {\n delete uns[\"handover\"];\n delete uns[\"instanceMode\"];\n }\n }\n return copy;\n}\nexport function reviewProcessGroupMqttOutput(configs: UpgradeConfigurations, root: string | undefined, stateRoot: string): GroupMqttOutputReference {\n const source = configs.source.publisher,\n target = configs.target.publisher;\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const raw = configs.source[role].raw as { output?: { publishQueue?: unknown } };\n if (raw.output?.publishQueue !== undefined) throw Error(\"Output enablement requires a source without an MQTT queue\");\n }\n if ((configs.target.receiver.raw[\"output\"] as { publishQueue?: unknown } | undefined)?.publishQueue !== undefined)\n throw Error(\"Admission receiver cannot own the publisher output queue\");\n const queue = mqttPublishQueueSchema.parse((target.raw[\"output\"] as { publishQueue?: unknown } | undefined)?.publishQueue);\n if (queue.mode !== \"durable\" || queue.storage !== \"runtime\") throw Error(\"Reviewed output enablement requires durable Runtime storage\");\n const uns = target.raw[\"uns\"] as Record<string, unknown>;\n if (uns[\"handover\"] !== false || ![\"force\", \"wait\"].includes(String(uns[\"instanceMode\"])))\n throw Error(\"MQTT output enablement requires explicit stop-before-start configuration\");\n if (!root || path.resolve(root) === path.resolve(stateRoot) || queue.directory.startsWith(path.resolve(stateRoot) + path.sep))\n throw Error(\"A separate permanent MQTT output mount is required\");\n const binding = managedMqttOutputBinding(target.raw, root)!;\n const pkg = JSON.parse(read(path.join(target.packageRoot, \"package.json\")).toString());\n const sourcePackage = JSON.parse(read(path.join(source.packageRoot, \"package.json\")).toString());\n if (pkg.name !== sourcePackage.name) throw Error(\"Publisher package identity changed\");\n const declaration = processGroupMqttOutputRuntimeSchema.parse(pkg.unsDatahub?.processGroupMqttOutputRuntime);\n const processName = String((target.raw[\"uns\"] as Record<string, unknown>)[\"processName\"]);\n if (processName !== String((source.raw[\"uns\"] as Record<string, unknown>)[\"processName\"])) throw Error(\"Publisher identity changed\");\n const identity = sha256(\n mqttPublishQueueIdentity(pkg.name, processName + \"-\" + declaration.instanceName, resolvedProcessGroupChannels(target.resolved)[2]!),\n );\n const status = inspectManagedOutputQueue(root, binding.directory, identity, mqttOutputStateLimits);\n if (status.records || status.bytes) throw Error(\"Output enablement requires an empty original-destination queue; preserve pending work\");\n return { root, directory: binding.directory, rootId: status.rootId, relative: binding.relative, identity, optionsSha256: hash(queue) };\n}\n/** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */\nexport function inspectReviewedProcessGroupMqttOutput(reference: GroupMqttOutputReference, requireStopped = true) {\n const status = inspectManagedOutputQueue(reference.root, reference.directory, reference.identity, mqttOutputStateLimits, requireStopped);\n if (status.rootId !== reference.rootId || status.relative !== reference.relative) throw Error(\"Reviewed MQTT output storage identity changed\");\n return status;\n}\n"]}
@@ -1,5 +1,6 @@
1
- import { type GroupGenerationReview, type GenerationJournalReference } from "./process-group-generation.js";
2
1
  import { z } from "zod";
2
+ import { type GenerationJournalReference, type GroupGenerationReview } from "./process-group-generation.js";
3
+ import { type GroupMqttOutputReference } from "./process-group-mqtt-output.js";
3
4
  export declare const processGroupUpgradeInputSchema: z.ZodUnion<readonly [z.ZodObject<{
4
5
  protocolVersion: z.ZodLiteral<1>;
5
6
  source: z.ZodObject<{
@@ -63,6 +64,39 @@ export declare const processGroupUpgradeInputSchema: z.ZodUnion<readonly [z.ZodO
63
64
  acknowledgeInputPause: z.ZodLiteral<true>;
64
65
  acknowledgeResourceReview: z.ZodLiteral<true>;
65
66
  acknowledgePossibleReplay: z.ZodLiteral<true>;
67
+ }, z.core.$strict>, z.ZodObject<{
68
+ protocolVersion: z.ZodLiteral<3>;
69
+ source: z.ZodObject<{
70
+ publisher: z.ZodObject<{
71
+ controller: z.ZodString;
72
+ rttNode: z.ZodString;
73
+ version: z.ZodString;
74
+ instanceId: z.ZodString;
75
+ }, z.core.$strict>;
76
+ receiver: z.ZodObject<{
77
+ controller: z.ZodString;
78
+ rttNode: z.ZodString;
79
+ version: z.ZodString;
80
+ instanceId: z.ZodString;
81
+ }, z.core.$strict>;
82
+ }, z.core.$strict>;
83
+ target: z.ZodObject<{
84
+ publisher: z.ZodObject<{
85
+ controller: z.ZodString;
86
+ rttNode: z.ZodString;
87
+ version: z.ZodString;
88
+ instanceId: z.ZodString;
89
+ }, z.core.$strict>;
90
+ receiver: z.ZodObject<{
91
+ controller: z.ZodString;
92
+ rttNode: z.ZodString;
93
+ version: z.ZodString;
94
+ instanceId: z.ZodString;
95
+ }, z.core.$strict>;
96
+ }, z.core.$strict>;
97
+ acknowledgeInputPause: z.ZodLiteral<true>;
98
+ acknowledgePossibleReplay: z.ZodLiteral<true>;
99
+ acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
66
100
  }, z.core.$strict>]>;
67
101
  export type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;
68
102
  export type UpgradeRole = "publisher" | "receiver";
@@ -98,7 +132,16 @@ export type GroupVersionUpgradeReview = {
98
132
  artifactSha256: string;
99
133
  }>;
100
134
  };
101
- export type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview;
135
+ export type GroupMqttOutputReview = Omit<GroupVersionUpgradeReview, "protocolVersion"> & {
136
+ protocolVersion: 3;
137
+ mqttOutput: GroupMqttOutputReference;
138
+ delivery: {
139
+ inputPausePossible: true;
140
+ exactlyOnceOutput: false;
141
+ pendingOutputBlocksRollback: true;
142
+ };
143
+ };
144
+ export type GroupUpgradeReview = GroupVersionUpgradeReview | GroupGenerationReview | GroupMqttOutputReview;
102
145
  export type PreparedGroupUpgrade = {
103
146
  review: GroupUpgradeReview;
104
147
  sourcePolicy: Buffer;
@@ -106,6 +149,8 @@ export type PreparedGroupUpgrade = {
106
149
  };
107
150
  /** Data-only same-host version review. No application JS, journal writes or launch authority. */
108
151
  export declare function reviewInstalledProcessGroupUpgrade(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
152
+ /** Explicit shared output capability. Ordinary upgrades keep their strict comparison. */
153
+ export declare function reviewInstalledProcessGroupMqttOutput(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[], outputRoot?: string): PreparedGroupUpgrade;
109
154
  /** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */
110
155
  export declare function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void;
111
156
  export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
@@ -181,6 +226,39 @@ export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
181
226
  acknowledgeInputPause: z.ZodLiteral<true>;
182
227
  acknowledgeResourceReview: z.ZodLiteral<true>;
183
228
  acknowledgePossibleReplay: z.ZodLiteral<true>;
229
+ }, z.core.$strict>, z.ZodObject<{
230
+ protocolVersion: z.ZodLiteral<3>;
231
+ source: z.ZodObject<{
232
+ publisher: z.ZodObject<{
233
+ controller: z.ZodString;
234
+ rttNode: z.ZodString;
235
+ version: z.ZodString;
236
+ instanceId: z.ZodString;
237
+ }, z.core.$strict>;
238
+ receiver: z.ZodObject<{
239
+ controller: z.ZodString;
240
+ rttNode: z.ZodString;
241
+ version: z.ZodString;
242
+ instanceId: z.ZodString;
243
+ }, z.core.$strict>;
244
+ }, z.core.$strict>;
245
+ target: z.ZodObject<{
246
+ publisher: z.ZodObject<{
247
+ controller: z.ZodString;
248
+ rttNode: z.ZodString;
249
+ version: z.ZodString;
250
+ instanceId: z.ZodString;
251
+ }, z.core.$strict>;
252
+ receiver: z.ZodObject<{
253
+ controller: z.ZodString;
254
+ rttNode: z.ZodString;
255
+ version: z.ZodString;
256
+ instanceId: z.ZodString;
257
+ }, z.core.$strict>;
258
+ }, z.core.$strict>;
259
+ acknowledgeInputPause: z.ZodLiteral<true>;
260
+ acknowledgePossibleReplay: z.ZodLiteral<true>;
261
+ acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
184
262
  }, z.core.$strict>]>>;
185
263
  id: z.ZodOptional<z.ZodString>;
186
264
  expectedFingerprint: z.ZodOptional<z.ZodString>;
@@ -192,4 +270,9 @@ export declare function inspectProcessGroupUpgradeJournal(review: Pick<GroupVers
192
270
  receiverReady: boolean;
193
271
  publisherReady: boolean;
194
272
  };
273
+ /** Bounded, read-only usage for a retained file/configuration input journal. */
274
+ export declare function inspectProcessGroupUpgradeUsage(review: Pick<GroupVersionUpgradeReview, "directory" | "journalId" | "journalContractSha256">): {
275
+ records: number;
276
+ bytes: number;
277
+ };
195
278
  //# sourceMappingURL=process-group-upgrade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process-group-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-upgrade.ts"],"names":[],"mappings":"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"}