@uns-kit/core 3.0.27 → 3.0.28
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 +22 -0
- package/dist/runtime/process-group-authorization.d.ts +4 -0
- package/dist/runtime/process-group-authorization.d.ts.map +1 -1
- package/dist/runtime/process-group-authorization.js +22 -4
- package/dist/runtime/process-group-authorization.js.map +1 -1
- package/dist/runtime/process-group-supervision.d.ts.map +1 -1
- package/dist/runtime/process-group-supervision.js +2 -1
- package/dist/runtime/process-group-supervision.js.map +1 -1
- package/dist/runtime/process-group-upgrade.d.ts +125 -0
- package/dist/runtime/process-group-upgrade.d.ts.map +1 -0
- package/dist/runtime/process-group-upgrade.js +256 -0
- package/dist/runtime/process-group-upgrade.js.map +1 -0
- package/package.json +1 -1
package/MIGRATIONS.md
CHANGED
|
@@ -9,6 +9,28 @@ 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.28 - Paired process-group version upgrades
|
|
13
|
+
|
|
14
|
+
When crossing `<3.0.28` to `>=3.0.28`, shared schemas and installed-resource review support a
|
|
15
|
+
publisher/receiver version upgrade on the same retained journal. Host launchers
|
|
16
|
+
must consume the shared helpers and enforce authenticated durable orchestration;
|
|
17
|
+
applications must not copy the upgrade protocol or add Controller-specific business
|
|
18
|
+
adapters. Existing protocol 1 applications need no mapping, topic, unit or writer
|
|
19
|
+
change. Historical policy readers remain frozen, while the reviewed new artifact
|
|
20
|
+
uses generic policy schema 3. See `docs/process-group-version-upgrade.md`.
|
|
21
|
+
|
|
22
|
+
The neutral receiver supervisor now treats clean exit `0` and explicit contract
|
|
23
|
+
refusal `78` as terminal; other failures remain subject to bounded restart.
|
|
24
|
+
During planned shutdown the host must park existing supervision as well as verify
|
|
25
|
+
the guarded application exit, including for receivers started by older launchers.
|
|
26
|
+
Do not infer completed drain from PM2 online/stopped or a sent signal.
|
|
27
|
+
|
|
28
|
+
A candidate policy validation is review-only. Actual launch still needs the live
|
|
29
|
+
canonical policy and exact durable operation/launch reservation. Missing responses
|
|
30
|
+
are reconciled on the same operation. SDK publication is a separate manual step;
|
|
31
|
+
downstream releases must install the published version and regenerate registry
|
|
32
|
+
lockfiles before releasing their host integration.
|
|
33
|
+
|
|
12
34
|
## 3.0.26 - Broker-acknowledged input subscriptions
|
|
13
35
|
|
|
14
36
|
When upgrading from `<3.0.26` to `>=3.0.26`, `mqttProxyStatus` includes the additive
|
|
@@ -95,7 +95,11 @@ export interface ProcessGroupAuthorizationContext {
|
|
|
95
95
|
stateRoot?: string;
|
|
96
96
|
initialize?: boolean;
|
|
97
97
|
}
|
|
98
|
+
/** Live authority always comes from the current canonical private policy. */
|
|
98
99
|
export declare function authorizeProcessGroupRuntime(context: ProcessGroupAuthorizationContext): ProcessGroupAuthorization;
|
|
100
|
+
/** Review only: never issues an authorization accepted by runtime/launch checks. */
|
|
101
|
+
export declare function validateProcessGroupPolicyCandidate(context: ProcessGroupAuthorizationContext, bytes: Buffer): void;
|
|
102
|
+
export declare function processGroupAuthorizationFile(context: ProcessGroupAuthorizationContext): string;
|
|
99
103
|
export declare const authorizeHvRuntime: typeof authorizeProcessGroupRuntime;
|
|
100
104
|
export declare function authorizeConfiguredProcessGroupRuntime(pkg: string, dir: string, raw: Record<string, unknown>, controllerName: string, initialize?: boolean): ProcessGroupAuthorization;
|
|
101
105
|
export declare function assertProcessGroupJournalAuthorization(value: ProcessGroupAuthorization | undefined, directory: string, journalId: string | undefined): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-authorization.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,MAAM,MAAM,+CAA+C,CAAC;AAexE,OAAO,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEpH,eAAO,MAAM,4BAA4B,4CAAsC,CAAC;AAahF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiB1C,CAAC;AACH,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAC9F,eAAO,MAAM,0BAA0B;;;;;;;;;;;;kBAarC,CAAC;AACH,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,eAAe,GAAG,oBAAoB,CAAC;AACtF,MAAM,MAAM,eAAe,GAAG,yBAAyB,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC;AACjE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;kBAA+B,CAAC;AAClE,eAAO,MAAM,kBAAkB,8BAA4B,CAAC;AAsC5D;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,GAAG,CAAC,MAAM,CAAC,CAgFzD;AACD,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"process-group-authorization.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"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"}
|
|
@@ -194,14 +194,17 @@ export function configuredGroupProcessNames() {
|
|
|
194
194
|
throw Error("Process-group authorization registry is missing, changed or insecure; review required");
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
|
|
197
|
+
function verifyRuntimePolicy(context, candidate) {
|
|
198
198
|
try {
|
|
199
199
|
const root = context.stateRoot ?? process.env["UNS_PROCESS_GROUP_STATE_ROOT"];
|
|
200
200
|
if (!root || !context.controllerName)
|
|
201
201
|
throw Error();
|
|
202
|
-
const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file), bytes = read(file, true), unparsed = JSON.parse(bytes.toString());
|
|
203
|
-
if (unparsed.schemaVersion !== 3)
|
|
202
|
+
const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file), bytes = candidate ?? read(file, true), unparsed = JSON.parse(bytes.toString());
|
|
203
|
+
if (unparsed.schemaVersion !== 3) {
|
|
204
|
+
if (candidate)
|
|
205
|
+
throw Error("Only generic policies can be staged");
|
|
204
206
|
return legacy.authorizeHvRuntime({ ...context, file, stateRoot: root });
|
|
207
|
+
}
|
|
205
208
|
const p = processGroupAuthorizationSchema.parse(unparsed), d = processGroupDescriptor(context.packageRoot);
|
|
206
209
|
if (!d || d.legacy)
|
|
207
210
|
throw Error("Generic runtime descriptor required");
|
|
@@ -280,13 +283,28 @@ export function authorizeProcessGroupRuntime(context) {
|
|
|
280
283
|
groupProcessName: m.processName,
|
|
281
284
|
namespace: d.namespace,
|
|
282
285
|
});
|
|
283
|
-
|
|
286
|
+
if (!candidate)
|
|
287
|
+
issued.add(result);
|
|
284
288
|
return result;
|
|
285
289
|
}
|
|
286
290
|
catch {
|
|
287
291
|
throw Error("Process-group runtime authorization is missing, changed or does not match this installed placement; review required");
|
|
288
292
|
}
|
|
289
293
|
}
|
|
294
|
+
/** Live authority always comes from the current canonical private policy. */
|
|
295
|
+
export function authorizeProcessGroupRuntime(context) {
|
|
296
|
+
return verifyRuntimePolicy(context);
|
|
297
|
+
}
|
|
298
|
+
/** Review only: never issues an authorization accepted by runtime/launch checks. */
|
|
299
|
+
export function validateProcessGroupPolicyCandidate(context, bytes) {
|
|
300
|
+
verifyRuntimePolicy(context, bytes);
|
|
301
|
+
}
|
|
302
|
+
export function processGroupAuthorizationFile(context) {
|
|
303
|
+
const root = context.stateRoot ?? process.env["UNS_PROCESS_GROUP_STATE_ROOT"];
|
|
304
|
+
if (!root)
|
|
305
|
+
throw Error("Missing process-group state root");
|
|
306
|
+
return selectedFile(context.packageRoot, context.rawConfiguration, root, context.file);
|
|
307
|
+
}
|
|
290
308
|
export const authorizeHvRuntime = authorizeProcessGroupRuntime;
|
|
291
309
|
export function authorizeConfiguredProcessGroupRuntime(pkg, dir, raw, controllerName, initialize = false) {
|
|
292
310
|
return authorizeProcessGroupRuntime({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-group-authorization.js","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport * as legacy from \"./compatibility/energenti-authorization-v1.js\";\nimport {\n type ProcessGroupRuntimeDescriptor,\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport {\n configurationAuthorizationHash,\n groupArtifactHash,\n groupChannelsHash,\n readProcessGroupResource as read,\n sha256 as sha,\n} from \"./process-group-resources.js\";\n\nexport { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash } from \"./process-group-resources.js\";\n\nexport const hasProcessGroupAuthorization = legacy.hasProcessGroupAuthorization;\nconst digest = z.string().regex(/^[a-f0-9]{64}$/),\n id = z.string().regex(/^[a-z][a-z0-9-]{0,99}$/);\nconst absolute = z\n .string()\n .max(512)\n .refine((v) => path.isAbsolute(v) && path.resolve(v) === v);\nconst placement = z.strictObject({\n instanceId: z.string().regex(/^[a-zA-Z0-9-]{1,100}$/),\n processName: id,\n role: z.enum([\"source\", \"target\", \"receiver\"]),\n configurationSha256: digest,\n});\nexport const processGroupAuthorizationSchema = z.strictObject({\n schemaVersion: z.literal(3),\n kind: z.literal(\"uns-process-group-runtime-authorization\"),\n protocolVersion: z.literal(1),\n packageName: z.string().min(1).max(214),\n namespace: id,\n groupId: id,\n descriptorSha256: digest,\n controllerName: z.string().min(1).max(100),\n packageRoot: absolute,\n artifactSha256: digest,\n groupManifestSha256: digest,\n channelsSha256: digest,\n stateRoot: absolute,\n directory: absolute,\n journalId: z.string().uuid().nullable(),\n placements: z.array(placement).min(4).max(18),\n});\nexport type ProcessGroupAuthorizationPolicy = z.infer<typeof processGroupAuthorizationSchema>;\nexport const processGroupManifestSchema = z.strictObject({\n schemaVersion: z.literal(1),\n id,\n inputTopic: z\n .string()\n .min(1)\n .max(512)\n .regex(/^[^#+\\0]+$/),\n processName: id,\n profiles: z\n .array(z.strictObject({ id, processName: id, mappingFile: z.string().min(1).max(512), mappingSha256: digest, dataGroup: id }))\n .min(2)\n .max(16),\n});\ninterface GenericAuthorization {\n readonly sha256: string;\n readonly file: string;\n readonly directory: string;\n readonly journalId: string | null;\n readonly role: \"source\" | \"target\" | \"receiver\";\n readonly groupId: string;\n readonly groupProcessName: string;\n readonly namespace: string;\n}\nexport type ProcessGroupAuthorization = legacy.HvAuthorization | GenericAuthorization;\nexport type HvAuthorization = ProcessGroupAuthorization;\nexport type HvAuthorizationPolicy = legacy.HvAuthorizationPolicy;\nexport const hvAuthorizationSchema = legacy.hvAuthorizationSchema;\nexport const productionGroupIds = legacy.productionGroupIds;\nconst issued = new WeakSet<object>();\nfunction privateDirectory(dir: string): void {\n for (let p = dir; p !== path.dirname(p); p = path.dirname(p)) if (fs.lstatSync(p).isSymbolicLink()) throw Error(\"Linked policy directory\");\n const s = fs.lstatSync(dir);\n if (!s.isDirectory() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0) throw Error(\"Insecure policy directory\");\n}\nfunction registryRoot(root: string, dir: string): string {\n if (!path.isAbsolute(root) || path.resolve(root) !== root || path.resolve(dir) !== dir) throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n if (dir === root) return \"*\"; // Explicit collection of independently owned namespaces.\n const relative = path.relative(root, dir);\n if (!path.isAbsolute(root) || path.resolve(root) !== root || !/^([a-z][a-z0-9-]{0,99})\\/authorizations$/.test(relative))\n throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n privateDirectory(dir);\n return relative.split(\"/\")[0]!;\n}\nfunction selectedFile(pkg: string, raw: Record<string, unknown>, root: string, explicit?: string): string {\n const descriptor = processGroupDescriptor(pkg);\n if (!descriptor) throw Error(\"Missing runtime contract\");\n const c = normalizeProcessGroupConfiguration(raw, descriptor),\n journal = c.journal as Record<string, unknown> | undefined;\n const manifest = descriptor.manifests.find((m) => m.file === journal?.[\"groupManifest\"]);\n if (!manifest) throw Error(\"Unregistered group manifest\");\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (explicit) return explicit;\n if (dir) {\n const selected = registryRoot(root, dir);\n if (selected !== \"*\" && selected !== descriptor.namespace) throw Error(\"Foreign runtime registry\");\n const registry = selected === \"*\" ? path.join(root, descriptor.namespace, \"authorizations\") : dir;\n privateDirectory(registry);\n return path.join(registry, manifest.id + \".json\");\n }\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (!single) throw Error(\"No selected policy\");\n return single;\n}\n/** Bounded private registry enumeration; retained state without its policy fails closed.\n * New groups are operator-owned data and never a release-time enum in the Controller.\n */\nexport function configuredGroupProcessNames(): Set<string> {\n if (!hasProcessGroupAuthorization()) return new Set();\n try {\n const root = process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root) throw Error();\n const files = new Set<string>();\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (single) files.add(single);\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (dir) {\n const selected = registryRoot(root, dir);\n let registries: { namespace: string; directory: string }[];\n if (selected === \"*\") {\n const namespaces = fs.readdirSync(root, { withFileTypes: true });\n if (namespaces.length > 64 || namespaces.some((e) => e.isSymbolicLink())) throw Error(\"Registry namespace budget or link violation\");\n registries = namespaces\n .filter((e) => e.isDirectory())\n .map((e) => {\n if (!id.safeParse(e.name).success) throw Error(\"Invalid registry namespace\");\n privateDirectory(path.join(root, e.name));\n return { namespace: e.name, directory: path.join(root, e.name, \"authorizations\") };\n });\n } else registries = [{ namespace: selected, directory: dir }];\n for (const registry of registries) {\n let entries: fs.Dirent[] = [];\n try {\n privateDirectory(registry.directory);\n entries = fs.readdirSync(registry.directory, { withFileTypes: true });\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n if (entries.length > 64) throw Error(\"Policy registry budget exceeded\");\n for (const entry of entries)\n if (entry.name.endsWith(\".json\")) {\n if (!/^[a-z][a-z0-9-]{0,99}\\.json$/.test(entry.name)) throw Error(\"Invalid registry entry\");\n files.add(path.join(registry.directory, entry.name));\n if (files.size > 64) throw Error(\"Total policy registry budget exceeded\");\n }\n const journals = path.join(root, registry.namespace, \"admission\");\n try {\n // Root/registry permissions already protect visibility; retain old parent modes.\n for (let parent = journals; parent !== path.dirname(parent); parent = path.dirname(parent))\n if (fs.lstatSync(parent).isSymbolicLink()) throw Error(\"Linked journal registry\");\n const retained = fs.readdirSync(journals, { withFileTypes: true });\n if (retained.length > 64) throw Error(\"Retained journal budget exceeded\");\n for (const entry of retained)\n if (\n !id.safeParse(entry.name).success ||\n entry.isSymbolicLink() ||\n !entry.isDirectory() ||\n !files.has(path.join(registry.directory, entry.name + \".json\"))\n )\n throw Error(\"Retained journal has no reviewed policy\");\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n }\n }\n const result = new Set<string>();\n for (const file of files) {\n const raw = JSON.parse(read(file, true).toString());\n const p =\n raw.schemaVersion === 3\n ? processGroupAuthorizationSchema.parse(raw)\n : z.union([legacy.hvAuthorizationSchema, legacy.processGroupAuthorizationSchema]).parse(raw);\n const { namespace, group } = p.schemaVersion === 3 ? { namespace: p.namespace, group: p.groupId } : legacy.legacyPolicyIdentity(p);\n if (\n p.stateRoot !== root ||\n file !== path.join(root, namespace, \"authorizations\", group + \".json\") ||\n p.directory !== path.join(root, namespace, \"admission\", group)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n for (const role of p.placements) result.add(role.processName);\n }\n return result;\n } catch {\n throw Error(\"Process-group authorization registry is missing, changed or insecure; review required\");\n }\n}\nexport interface ProcessGroupAuthorizationContext {\n packageRoot: string;\n instanceDirectory: string;\n rawConfiguration: Record<string, unknown>;\n channels: unknown[];\n controllerName: string;\n file?: string;\n stateRoot?: string;\n initialize?: boolean;\n}\nexport function authorizeProcessGroupRuntime(context: ProcessGroupAuthorizationContext): ProcessGroupAuthorization {\n try {\n const root = context.stateRoot ?? process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root || !context.controllerName) throw Error();\n const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file),\n bytes = read(file, true),\n unparsed = JSON.parse(bytes.toString());\n if (unparsed.schemaVersion !== 3) return legacy.authorizeHvRuntime({ ...context, file, stateRoot: root });\n const p = processGroupAuthorizationSchema.parse(unparsed),\n d = processGroupDescriptor(context.packageRoot);\n if (!d || d.legacy) throw Error(\"Generic runtime descriptor required\");\n const pkg = JSON.parse(read(path.join(context.packageRoot, \"package.json\")).toString());\n const manifest = d.manifests.find((m) => m.id === p.groupId);\n if (\n !manifest ||\n p.packageName !== pkg.name ||\n p.namespace !== d.namespace ||\n p.descriptorSha256 !== configurationAuthorizationHash(pkg.unsDatahub.processGroupRuntime) ||\n p.packageRoot !== context.packageRoot ||\n p.controllerName !== context.controllerName ||\n p.stateRoot !== root ||\n file !== path.join(root, d.namespace, \"authorizations\", p.groupId + \".json\") ||\n p.directory !== path.join(root, d.namespace, \"admission\", p.groupId)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n if (groupArtifactHash(context.packageRoot) !== p.artifactSha256 || groupChannelsHash(context.channels) !== p.channelsSha256) throw Error();\n const manifestBytes = read(path.join(context.packageRoot, manifest.file));\n if (sha(manifestBytes) !== p.groupManifestSha256) throw Error();\n const m = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (m.id !== p.groupId) throw Error();\n const receiver = m.processName + \"-admission\";\n if (\n new Set(m.profiles.map((x) => x.id)).size !== m.profiles.length ||\n new Set(m.profiles.map((x) => x.processName)).size !== m.profiles.length ||\n m.profiles.some((x) => x.processName === m.processName || x.processName === receiver)\n )\n throw Error();\n for (const member of m.profiles) {\n const f = path.resolve(context.packageRoot, path.dirname(manifest.file), member.mappingFile);\n if (!f.startsWith(context.packageRoot + path.sep) || sha(read(f)) !== member.mappingSha256) throw Error();\n }\n const expected = new Map([\n ...m.profiles.map((x) => [x.processName, \"source\"] as const),\n [m.processName, \"target\"] as const,\n [receiver, \"receiver\"] as const,\n ]);\n if (\n p.placements.length !== expected.size ||\n new Set(p.placements.map((x) => x.instanceId)).size !== expected.size ||\n new Set(p.placements.map((x) => x.processName)).size !== expected.size ||\n p.placements.some((x) => expected.get(x.processName) !== x.role)\n )\n throw Error();\n const entry = p.placements.find((x) => context.instanceDirectory === path.join(context.packageRoot, \"instances\", x.instanceId));\n const c = normalizeProcessGroupConfiguration(context.rawConfiguration, d),\n j = c.journal as Record<string, unknown> | undefined,\n k = c.publisher;\n if (\n !entry ||\n !c.matches ||\n entry.processName !== c.uns?.[\"processName\"] ||\n entry.configurationSha256 !== configurationAuthorizationHash(context.rawConfiguration) ||\n !j ||\n j[\"directory\"] !== p.directory ||\n (j[\"journalId\"] ?? null) !== p.journalId ||\n j[\"groupManifest\"] !== manifest.file\n )\n throw Error();\n if (context.initialize ? p.journalId !== null || entry.role !== \"receiver\" : p.journalId === null) throw Error();\n if (entry.role === \"receiver\" ? c.runtimeRole !== \"admission\" : c.runtimeRole !== undefined && c.runtimeRole !== \"publisher\") throw Error();\n const member = m.profiles.find((x) => x.processName === entry.processName),\n mapping = path.resolve(context.packageRoot, String(k[\"mappingFile\"]));\n if (\n entry.role !== \"source\"\n ? k[\"groupManifest\"] !== manifest.file\n : k[\"groupManifest\"] !== undefined ||\n k[\"dataGroup\"] !== member?.dataGroup ||\n !mapping.startsWith(context.packageRoot + path.sep) ||\n sha(read(mapping)) !== member?.mappingSha256\n )\n throw Error();\n const result = Object.freeze({\n sha256: sha(bytes),\n file,\n directory: p.directory,\n journalId: p.journalId,\n role: entry.role,\n groupId: p.groupId,\n groupProcessName: m.processName,\n namespace: d.namespace,\n });\n issued.add(result);\n return result;\n } catch {\n throw Error(\"Process-group runtime authorization is missing, changed or does not match this installed placement; review required\");\n }\n}\nexport const authorizeHvRuntime = authorizeProcessGroupRuntime;\nexport function authorizeConfiguredProcessGroupRuntime(\n pkg: string,\n dir: string,\n raw: Record<string, unknown>,\n controllerName: string,\n initialize = false,\n) {\n return authorizeProcessGroupRuntime({\n packageRoot: pkg,\n instanceDirectory: dir,\n rawConfiguration: raw,\n channels: resolvedProcessGroupChannels(raw),\n controllerName,\n initialize,\n });\n}\nexport function assertProcessGroupJournalAuthorization(\n value: ProcessGroupAuthorization | undefined,\n directory: string,\n journalId: string | undefined,\n): void {\n if (value && issued.has(value)) {\n if (value.directory !== directory || value.journalId !== (journalId ?? null) || sha(read(value.file, true)) !== value.sha256)\n throw Error(\"Exact reviewed process-group authorization required\");\n return;\n }\n legacy.assertHvJournalAuthorization(value as legacy.HvAuthorization | undefined, directory, journalId);\n}\nexport const assertHvJournalAuthorization = assertProcessGroupJournalAuthorization;\nexport function assertProcessGroupStateMount(value: ProcessGroupAuthorization, root: string): void {\n if (!issued.has(value)) {\n legacy.assertHvStateMount(value as legacy.HvAuthorization, root);\n return;\n }\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n if (process.platform !== \"linux\" || !(\"namespace\" in value) || value.directory !== path.join(root, value.namespace, \"admission\", value.groupId))\n throw Error(\"Process group requires its reviewed Linux state mount\");\n const mount = fs\n .readFileSync(\"/proc/self/mountinfo\", \"utf8\")\n .split(\"\\n\")\n .map((l) => l.split(\" \"))\n .filter((f) => f[4] === root)\n .at(-1);\n if (!mount || !mount[5]?.split(\",\").includes(\"rw\") || ![\"xfs\", \"ext4\", \"btrfs\", \"zfs\"].includes(mount[mount.indexOf(\"-\") + 1] ?? \"\"))\n throw Error(\"Process-group state root must be an explicit writable local Linux filesystem mount\");\n}\nexport const assertHvStateMount = assertProcessGroupStateMount;\nexport function assertProcessGroupTargetLaunch(\n value: ProcessGroupAuthorization,\n dir: string,\n operationId: string | undefined,\n launchId: string | undefined,\n): void {\n if (!issued.has(value)) {\n legacy.assertHvTargetLaunch(value as legacy.HvAuthorization, dir, operationId, launchId);\n return;\n }\n if (value.role !== \"target\") return;\n try {\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n const r = JSON.parse(read(path.join(dir, \"process-group-reservation.json\"), true).toString());\n if (\n !z.string().uuid().safeParse(operationId).success ||\n !z.string().uuid().safeParse(launchId).success ||\n r.operationId !== operationId ||\n r.role !== \"target\" ||\n r.lastLaunch?.launchId !== launchId ||\n !z.string().uuid().safeParse(r.lastLaunch?.requestId).success ||\n !digest.safeParse(r.configurationChecksum).success\n )\n throw Error();\n } catch {\n throw Error(\"Target requires its exact reviewed group reservation and launch identity\");\n }\n}\nexport const assertHvTargetLaunch = assertProcessGroupTargetLaunch;\n"]}
|
|
1
|
+
{"version":3,"file":"process-group-authorization.js","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport * as legacy from \"./compatibility/energenti-authorization-v1.js\";\nimport {\n type ProcessGroupRuntimeDescriptor,\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport {\n configurationAuthorizationHash,\n groupArtifactHash,\n groupChannelsHash,\n readProcessGroupResource as read,\n sha256 as sha,\n} from \"./process-group-resources.js\";\n\nexport { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash } from \"./process-group-resources.js\";\n\nexport const hasProcessGroupAuthorization = legacy.hasProcessGroupAuthorization;\nconst digest = z.string().regex(/^[a-f0-9]{64}$/),\n id = z.string().regex(/^[a-z][a-z0-9-]{0,99}$/);\nconst absolute = z\n .string()\n .max(512)\n .refine((v) => path.isAbsolute(v) && path.resolve(v) === v);\nconst placement = z.strictObject({\n instanceId: z.string().regex(/^[a-zA-Z0-9-]{1,100}$/),\n processName: id,\n role: z.enum([\"source\", \"target\", \"receiver\"]),\n configurationSha256: digest,\n});\nexport const processGroupAuthorizationSchema = z.strictObject({\n schemaVersion: z.literal(3),\n kind: z.literal(\"uns-process-group-runtime-authorization\"),\n protocolVersion: z.literal(1),\n packageName: z.string().min(1).max(214),\n namespace: id,\n groupId: id,\n descriptorSha256: digest,\n controllerName: z.string().min(1).max(100),\n packageRoot: absolute,\n artifactSha256: digest,\n groupManifestSha256: digest,\n channelsSha256: digest,\n stateRoot: absolute,\n directory: absolute,\n journalId: z.string().uuid().nullable(),\n placements: z.array(placement).min(4).max(18),\n});\nexport type ProcessGroupAuthorizationPolicy = z.infer<typeof processGroupAuthorizationSchema>;\nexport const processGroupManifestSchema = z.strictObject({\n schemaVersion: z.literal(1),\n id,\n inputTopic: z\n .string()\n .min(1)\n .max(512)\n .regex(/^[^#+\\0]+$/),\n processName: id,\n profiles: z\n .array(z.strictObject({ id, processName: id, mappingFile: z.string().min(1).max(512), mappingSha256: digest, dataGroup: id }))\n .min(2)\n .max(16),\n});\ninterface GenericAuthorization {\n readonly sha256: string;\n readonly file: string;\n readonly directory: string;\n readonly journalId: string | null;\n readonly role: \"source\" | \"target\" | \"receiver\";\n readonly groupId: string;\n readonly groupProcessName: string;\n readonly namespace: string;\n}\nexport type ProcessGroupAuthorization = legacy.HvAuthorization | GenericAuthorization;\nexport type HvAuthorization = ProcessGroupAuthorization;\nexport type HvAuthorizationPolicy = legacy.HvAuthorizationPolicy;\nexport const hvAuthorizationSchema = legacy.hvAuthorizationSchema;\nexport const productionGroupIds = legacy.productionGroupIds;\nconst issued = new WeakSet<object>();\nfunction privateDirectory(dir: string): void {\n for (let p = dir; p !== path.dirname(p); p = path.dirname(p)) if (fs.lstatSync(p).isSymbolicLink()) throw Error(\"Linked policy directory\");\n const s = fs.lstatSync(dir);\n if (!s.isDirectory() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0) throw Error(\"Insecure policy directory\");\n}\nfunction registryRoot(root: string, dir: string): string {\n if (!path.isAbsolute(root) || path.resolve(root) !== root || path.resolve(dir) !== dir) throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n if (dir === root) return \"*\"; // Explicit collection of independently owned namespaces.\n const relative = path.relative(root, dir);\n if (!path.isAbsolute(root) || path.resolve(root) !== root || !/^([a-z][a-z0-9-]{0,99})\\/authorizations$/.test(relative))\n throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n privateDirectory(dir);\n return relative.split(\"/\")[0]!;\n}\nfunction selectedFile(pkg: string, raw: Record<string, unknown>, root: string, explicit?: string): string {\n const descriptor = processGroupDescriptor(pkg);\n if (!descriptor) throw Error(\"Missing runtime contract\");\n const c = normalizeProcessGroupConfiguration(raw, descriptor),\n journal = c.journal as Record<string, unknown> | undefined;\n const manifest = descriptor.manifests.find((m) => m.file === journal?.[\"groupManifest\"]);\n if (!manifest) throw Error(\"Unregistered group manifest\");\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (explicit) return explicit;\n if (dir) {\n const selected = registryRoot(root, dir);\n if (selected !== \"*\" && selected !== descriptor.namespace) throw Error(\"Foreign runtime registry\");\n const registry = selected === \"*\" ? path.join(root, descriptor.namespace, \"authorizations\") : dir;\n privateDirectory(registry);\n return path.join(registry, manifest.id + \".json\");\n }\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (!single) throw Error(\"No selected policy\");\n return single;\n}\n/** Bounded private registry enumeration; retained state without its policy fails closed.\n * New groups are operator-owned data and never a release-time enum in the Controller.\n */\nexport function configuredGroupProcessNames(): Set<string> {\n if (!hasProcessGroupAuthorization()) return new Set();\n try {\n const root = process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root) throw Error();\n const files = new Set<string>();\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (single) files.add(single);\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (dir) {\n const selected = registryRoot(root, dir);\n let registries: { namespace: string; directory: string }[];\n if (selected === \"*\") {\n const namespaces = fs.readdirSync(root, { withFileTypes: true });\n if (namespaces.length > 64 || namespaces.some((e) => e.isSymbolicLink())) throw Error(\"Registry namespace budget or link violation\");\n registries = namespaces\n .filter((e) => e.isDirectory())\n .map((e) => {\n if (!id.safeParse(e.name).success) throw Error(\"Invalid registry namespace\");\n privateDirectory(path.join(root, e.name));\n return { namespace: e.name, directory: path.join(root, e.name, \"authorizations\") };\n });\n } else registries = [{ namespace: selected, directory: dir }];\n for (const registry of registries) {\n let entries: fs.Dirent[] = [];\n try {\n privateDirectory(registry.directory);\n entries = fs.readdirSync(registry.directory, { withFileTypes: true });\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n if (entries.length > 64) throw Error(\"Policy registry budget exceeded\");\n for (const entry of entries)\n if (entry.name.endsWith(\".json\")) {\n if (!/^[a-z][a-z0-9-]{0,99}\\.json$/.test(entry.name)) throw Error(\"Invalid registry entry\");\n files.add(path.join(registry.directory, entry.name));\n if (files.size > 64) throw Error(\"Total policy registry budget exceeded\");\n }\n const journals = path.join(root, registry.namespace, \"admission\");\n try {\n // Root/registry permissions already protect visibility; retain old parent modes.\n for (let parent = journals; parent !== path.dirname(parent); parent = path.dirname(parent))\n if (fs.lstatSync(parent).isSymbolicLink()) throw Error(\"Linked journal registry\");\n const retained = fs.readdirSync(journals, { withFileTypes: true });\n if (retained.length > 64) throw Error(\"Retained journal budget exceeded\");\n for (const entry of retained)\n if (\n !id.safeParse(entry.name).success ||\n entry.isSymbolicLink() ||\n !entry.isDirectory() ||\n !files.has(path.join(registry.directory, entry.name + \".json\"))\n )\n throw Error(\"Retained journal has no reviewed policy\");\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n }\n }\n const result = new Set<string>();\n for (const file of files) {\n const raw = JSON.parse(read(file, true).toString());\n const p =\n raw.schemaVersion === 3\n ? processGroupAuthorizationSchema.parse(raw)\n : z.union([legacy.hvAuthorizationSchema, legacy.processGroupAuthorizationSchema]).parse(raw);\n const { namespace, group } = p.schemaVersion === 3 ? { namespace: p.namespace, group: p.groupId } : legacy.legacyPolicyIdentity(p);\n if (\n p.stateRoot !== root ||\n file !== path.join(root, namespace, \"authorizations\", group + \".json\") ||\n p.directory !== path.join(root, namespace, \"admission\", group)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n for (const role of p.placements) result.add(role.processName);\n }\n return result;\n } catch {\n throw Error(\"Process-group authorization registry is missing, changed or insecure; review required\");\n }\n}\nexport interface ProcessGroupAuthorizationContext {\n packageRoot: string;\n instanceDirectory: string;\n rawConfiguration: Record<string, unknown>;\n channels: unknown[];\n controllerName: string;\n file?: string;\n stateRoot?: string;\n initialize?: boolean;\n}\nfunction verifyRuntimePolicy(context: ProcessGroupAuthorizationContext, candidate?: Buffer): ProcessGroupAuthorization {\n try {\n const root = context.stateRoot ?? process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root || !context.controllerName) throw Error();\n const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file),\n bytes = candidate ?? read(file, true),\n unparsed = JSON.parse(bytes.toString());\n if (unparsed.schemaVersion !== 3) {\n if (candidate) throw Error(\"Only generic policies can be staged\");\n return legacy.authorizeHvRuntime({ ...context, file, stateRoot: root });\n }\n const p = processGroupAuthorizationSchema.parse(unparsed),\n d = processGroupDescriptor(context.packageRoot);\n if (!d || d.legacy) throw Error(\"Generic runtime descriptor required\");\n const pkg = JSON.parse(read(path.join(context.packageRoot, \"package.json\")).toString());\n const manifest = d.manifests.find((m) => m.id === p.groupId);\n if (\n !manifest ||\n p.packageName !== pkg.name ||\n p.namespace !== d.namespace ||\n p.descriptorSha256 !== configurationAuthorizationHash(pkg.unsDatahub.processGroupRuntime) ||\n p.packageRoot !== context.packageRoot ||\n p.controllerName !== context.controllerName ||\n p.stateRoot !== root ||\n file !== path.join(root, d.namespace, \"authorizations\", p.groupId + \".json\") ||\n p.directory !== path.join(root, d.namespace, \"admission\", p.groupId)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n if (groupArtifactHash(context.packageRoot) !== p.artifactSha256 || groupChannelsHash(context.channels) !== p.channelsSha256) throw Error();\n const manifestBytes = read(path.join(context.packageRoot, manifest.file));\n if (sha(manifestBytes) !== p.groupManifestSha256) throw Error();\n const m = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (m.id !== p.groupId) throw Error();\n const receiver = m.processName + \"-admission\";\n if (\n new Set(m.profiles.map((x) => x.id)).size !== m.profiles.length ||\n new Set(m.profiles.map((x) => x.processName)).size !== m.profiles.length ||\n m.profiles.some((x) => x.processName === m.processName || x.processName === receiver)\n )\n throw Error();\n for (const member of m.profiles) {\n const f = path.resolve(context.packageRoot, path.dirname(manifest.file), member.mappingFile);\n if (!f.startsWith(context.packageRoot + path.sep) || sha(read(f)) !== member.mappingSha256) throw Error();\n }\n const expected = new Map([\n ...m.profiles.map((x) => [x.processName, \"source\"] as const),\n [m.processName, \"target\"] as const,\n [receiver, \"receiver\"] as const,\n ]);\n if (\n p.placements.length !== expected.size ||\n new Set(p.placements.map((x) => x.instanceId)).size !== expected.size ||\n new Set(p.placements.map((x) => x.processName)).size !== expected.size ||\n p.placements.some((x) => expected.get(x.processName) !== x.role)\n )\n throw Error();\n const entry = p.placements.find((x) => context.instanceDirectory === path.join(context.packageRoot, \"instances\", x.instanceId));\n const c = normalizeProcessGroupConfiguration(context.rawConfiguration, d),\n j = c.journal as Record<string, unknown> | undefined,\n k = c.publisher;\n if (\n !entry ||\n !c.matches ||\n entry.processName !== c.uns?.[\"processName\"] ||\n entry.configurationSha256 !== configurationAuthorizationHash(context.rawConfiguration) ||\n !j ||\n j[\"directory\"] !== p.directory ||\n (j[\"journalId\"] ?? null) !== p.journalId ||\n j[\"groupManifest\"] !== manifest.file\n )\n throw Error();\n if (context.initialize ? p.journalId !== null || entry.role !== \"receiver\" : p.journalId === null) throw Error();\n if (entry.role === \"receiver\" ? c.runtimeRole !== \"admission\" : c.runtimeRole !== undefined && c.runtimeRole !== \"publisher\") throw Error();\n const member = m.profiles.find((x) => x.processName === entry.processName),\n mapping = path.resolve(context.packageRoot, String(k[\"mappingFile\"]));\n if (\n entry.role !== \"source\"\n ? k[\"groupManifest\"] !== manifest.file\n : k[\"groupManifest\"] !== undefined ||\n k[\"dataGroup\"] !== member?.dataGroup ||\n !mapping.startsWith(context.packageRoot + path.sep) ||\n sha(read(mapping)) !== member?.mappingSha256\n )\n throw Error();\n const result = Object.freeze({\n sha256: sha(bytes),\n file,\n directory: p.directory,\n journalId: p.journalId,\n role: entry.role,\n groupId: p.groupId,\n groupProcessName: m.processName,\n namespace: d.namespace,\n });\n if (!candidate) issued.add(result);\n return result;\n } catch {\n throw Error(\"Process-group runtime authorization is missing, changed or does not match this installed placement; review required\");\n }\n}\n/** Live authority always comes from the current canonical private policy. */\nexport function authorizeProcessGroupRuntime(context: ProcessGroupAuthorizationContext): ProcessGroupAuthorization {\n return verifyRuntimePolicy(context);\n}\n/** Review only: never issues an authorization accepted by runtime/launch checks. */\nexport function validateProcessGroupPolicyCandidate(context: ProcessGroupAuthorizationContext, bytes: Buffer): void {\n verifyRuntimePolicy(context, bytes);\n}\nexport function processGroupAuthorizationFile(context: ProcessGroupAuthorizationContext): string {\n const root = context.stateRoot ?? process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root) throw Error(\"Missing process-group state root\");\n return selectedFile(context.packageRoot, context.rawConfiguration, root, context.file);\n}\nexport const authorizeHvRuntime = authorizeProcessGroupRuntime;\nexport function authorizeConfiguredProcessGroupRuntime(\n pkg: string,\n dir: string,\n raw: Record<string, unknown>,\n controllerName: string,\n initialize = false,\n) {\n return authorizeProcessGroupRuntime({\n packageRoot: pkg,\n instanceDirectory: dir,\n rawConfiguration: raw,\n channels: resolvedProcessGroupChannels(raw),\n controllerName,\n initialize,\n });\n}\nexport function assertProcessGroupJournalAuthorization(\n value: ProcessGroupAuthorization | undefined,\n directory: string,\n journalId: string | undefined,\n): void {\n if (value && issued.has(value)) {\n if (value.directory !== directory || value.journalId !== (journalId ?? null) || sha(read(value.file, true)) !== value.sha256)\n throw Error(\"Exact reviewed process-group authorization required\");\n return;\n }\n legacy.assertHvJournalAuthorization(value as legacy.HvAuthorization | undefined, directory, journalId);\n}\nexport const assertHvJournalAuthorization = assertProcessGroupJournalAuthorization;\nexport function assertProcessGroupStateMount(value: ProcessGroupAuthorization, root: string): void {\n if (!issued.has(value)) {\n legacy.assertHvStateMount(value as legacy.HvAuthorization, root);\n return;\n }\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n if (process.platform !== \"linux\" || !(\"namespace\" in value) || value.directory !== path.join(root, value.namespace, \"admission\", value.groupId))\n throw Error(\"Process group requires its reviewed Linux state mount\");\n const mount = fs\n .readFileSync(\"/proc/self/mountinfo\", \"utf8\")\n .split(\"\\n\")\n .map((l) => l.split(\" \"))\n .filter((f) => f[4] === root)\n .at(-1);\n if (!mount || !mount[5]?.split(\",\").includes(\"rw\") || ![\"xfs\", \"ext4\", \"btrfs\", \"zfs\"].includes(mount[mount.indexOf(\"-\") + 1] ?? \"\"))\n throw Error(\"Process-group state root must be an explicit writable local Linux filesystem mount\");\n}\nexport const assertHvStateMount = assertProcessGroupStateMount;\nexport function assertProcessGroupTargetLaunch(\n value: ProcessGroupAuthorization,\n dir: string,\n operationId: string | undefined,\n launchId: string | undefined,\n): void {\n if (!issued.has(value)) {\n legacy.assertHvTargetLaunch(value as legacy.HvAuthorization, dir, operationId, launchId);\n return;\n }\n if (value.role !== \"target\") return;\n try {\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n const r = JSON.parse(read(path.join(dir, \"process-group-reservation.json\"), true).toString());\n if (\n !z.string().uuid().safeParse(operationId).success ||\n !z.string().uuid().safeParse(launchId).success ||\n r.operationId !== operationId ||\n r.role !== \"target\" ||\n r.lastLaunch?.launchId !== launchId ||\n !z.string().uuid().safeParse(r.lastLaunch?.requestId).success ||\n !digest.safeParse(r.configurationChecksum).success\n )\n throw Error();\n } catch {\n throw Error(\"Target requires its exact reviewed group reservation and launch identity\");\n }\n}\nexport const assertHvTargetLaunch = assertProcessGroupTargetLaunch;\n"]}
|
|
@@ -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,
|
|
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"}
|
|
@@ -24,7 +24,8 @@ export function processGroupReceiverSupervision(raw, descriptor, instanceDirecto
|
|
|
24
24
|
throw Error("Admission supervisor memory limit must be 128–4096 MiB");
|
|
25
25
|
return {
|
|
26
26
|
autorestart: true,
|
|
27
|
-
|
|
27
|
+
// Successful standalone/guarded shutdown and explicit contract refusal are terminal.
|
|
28
|
+
stop_exit_codes: [0, 78],
|
|
28
29
|
min_uptime: 10000,
|
|
29
30
|
max_restarts: 5,
|
|
30
31
|
exp_backoff_restart_delay: 1000,
|
|
@@ -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,eAAe,EAAE,CAAC,EAAE,CAAC;
|
|
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"]}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const processGroupUpgradeInputSchema: z.ZodObject<{
|
|
3
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
4
|
+
source: z.ZodObject<{
|
|
5
|
+
publisher: z.ZodObject<{
|
|
6
|
+
controller: z.ZodString;
|
|
7
|
+
rttNode: z.ZodString;
|
|
8
|
+
version: z.ZodString;
|
|
9
|
+
instanceId: z.ZodString;
|
|
10
|
+
}, z.core.$strict>;
|
|
11
|
+
receiver: z.ZodObject<{
|
|
12
|
+
controller: z.ZodString;
|
|
13
|
+
rttNode: z.ZodString;
|
|
14
|
+
version: z.ZodString;
|
|
15
|
+
instanceId: z.ZodString;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
}, z.core.$strict>;
|
|
18
|
+
target: z.ZodObject<{
|
|
19
|
+
publisher: z.ZodObject<{
|
|
20
|
+
controller: z.ZodString;
|
|
21
|
+
rttNode: z.ZodString;
|
|
22
|
+
version: z.ZodString;
|
|
23
|
+
instanceId: z.ZodString;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
receiver: z.ZodObject<{
|
|
26
|
+
controller: z.ZodString;
|
|
27
|
+
rttNode: z.ZodString;
|
|
28
|
+
version: z.ZodString;
|
|
29
|
+
instanceId: z.ZodString;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
}, z.core.$strict>;
|
|
33
|
+
export type ProcessGroupUpgradeInput = z.infer<typeof processGroupUpgradeInputSchema>;
|
|
34
|
+
export type UpgradeRole = "publisher" | "receiver";
|
|
35
|
+
export type UpgradeConfiguration = {
|
|
36
|
+
packageRoot: string;
|
|
37
|
+
instanceDirectory: string;
|
|
38
|
+
raw: Record<string, unknown>;
|
|
39
|
+
resolved: Record<string, unknown>;
|
|
40
|
+
};
|
|
41
|
+
export type UpgradeConfigurations = Record<"source" | "target", Record<UpgradeRole, UpgradeConfiguration>>;
|
|
42
|
+
export type GroupUpgradeReview = {
|
|
43
|
+
protocolVersion: 1;
|
|
44
|
+
namespace: string;
|
|
45
|
+
groupId: string;
|
|
46
|
+
policyFile: string;
|
|
47
|
+
sourcePolicySha256: string;
|
|
48
|
+
targetPolicySha256: string;
|
|
49
|
+
journalId: string;
|
|
50
|
+
directory: string;
|
|
51
|
+
journalContractSha256: string;
|
|
52
|
+
profiles: Array<{
|
|
53
|
+
processName: string;
|
|
54
|
+
mappingSha256: string;
|
|
55
|
+
dataGroup: string;
|
|
56
|
+
}>;
|
|
57
|
+
members: Array<{
|
|
58
|
+
side: "source" | "target";
|
|
59
|
+
role: UpgradeRole;
|
|
60
|
+
processName: string;
|
|
61
|
+
configurationSha256: string;
|
|
62
|
+
artifactSha256: string;
|
|
63
|
+
}>;
|
|
64
|
+
};
|
|
65
|
+
export type PreparedGroupUpgrade = {
|
|
66
|
+
review: GroupUpgradeReview;
|
|
67
|
+
sourcePolicy: Buffer;
|
|
68
|
+
targetPolicy: Buffer;
|
|
69
|
+
};
|
|
70
|
+
/** Data-only same-host version review. No application JS, journal writes or launch authority. */
|
|
71
|
+
export declare function reviewInstalledProcessGroupUpgrade(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
|
|
72
|
+
/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */
|
|
73
|
+
export declare function replaceReviewedProcessGroupPolicy(file: string, expected: string, bytes: Buffer): void;
|
|
74
|
+
export declare const processGroupUpgradeRequestSchema: z.ZodObject<{
|
|
75
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
76
|
+
controllerName: z.ZodString;
|
|
77
|
+
action: z.ZodEnum<{
|
|
78
|
+
get: "get";
|
|
79
|
+
preview: "preview";
|
|
80
|
+
prepare: "prepare";
|
|
81
|
+
execute: "execute";
|
|
82
|
+
rollback: "rollback";
|
|
83
|
+
}>;
|
|
84
|
+
input: z.ZodOptional<z.ZodObject<{
|
|
85
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
86
|
+
source: z.ZodObject<{
|
|
87
|
+
publisher: z.ZodObject<{
|
|
88
|
+
controller: z.ZodString;
|
|
89
|
+
rttNode: z.ZodString;
|
|
90
|
+
version: z.ZodString;
|
|
91
|
+
instanceId: z.ZodString;
|
|
92
|
+
}, z.core.$strict>;
|
|
93
|
+
receiver: z.ZodObject<{
|
|
94
|
+
controller: z.ZodString;
|
|
95
|
+
rttNode: z.ZodString;
|
|
96
|
+
version: z.ZodString;
|
|
97
|
+
instanceId: z.ZodString;
|
|
98
|
+
}, z.core.$strict>;
|
|
99
|
+
}, z.core.$strict>;
|
|
100
|
+
target: z.ZodObject<{
|
|
101
|
+
publisher: z.ZodObject<{
|
|
102
|
+
controller: z.ZodString;
|
|
103
|
+
rttNode: z.ZodString;
|
|
104
|
+
version: z.ZodString;
|
|
105
|
+
instanceId: z.ZodString;
|
|
106
|
+
}, z.core.$strict>;
|
|
107
|
+
receiver: z.ZodObject<{
|
|
108
|
+
controller: z.ZodString;
|
|
109
|
+
rttNode: z.ZodString;
|
|
110
|
+
version: z.ZodString;
|
|
111
|
+
instanceId: z.ZodString;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
}, z.core.$strict>;
|
|
114
|
+
}, z.core.$strict>>;
|
|
115
|
+
id: z.ZodOptional<z.ZodString>;
|
|
116
|
+
expectedFingerprint: z.ZodOptional<z.ZodString>;
|
|
117
|
+
expectedRevision: z.ZodOptional<z.ZodNumber>;
|
|
118
|
+
}, z.core.$strict>;
|
|
119
|
+
export type ProcessGroupUpgradeRequest = z.infer<typeof processGroupUpgradeRequestSchema>;
|
|
120
|
+
/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */
|
|
121
|
+
export declare function inspectProcessGroupUpgradeJournal(review: GroupUpgradeReview, publisherPid?: number, receiverPid?: number): {
|
|
122
|
+
receiverReady: boolean;
|
|
123
|
+
publisherReady: boolean;
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=process-group-upgrade.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { authorizeProcessGroupRuntime, processGroupAuthorizationFile, processGroupAuthorizationSchema, processGroupManifestSchema, validateProcessGroupPolicyCandidate, } from "./process-group-authorization.js";
|
|
6
|
+
import { normalizeProcessGroupConfiguration, processGroupDescriptor, processGroupJournalContract, processGroupJournalSchema, processGroupSourceIdentity, resolvedProcessGroupChannels, } from "./process-group-contract.js";
|
|
7
|
+
import { groupPlacementSchema, placementKey } from "./process-group-control-contract.js";
|
|
8
|
+
import { groupArtifactHash, groupChannelsHash, configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256, } from "./process-group-resources.js";
|
|
9
|
+
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) => {
|
|
11
|
+
const all = [v.source.publisher, v.source.receiver, v.target.publisher, v.target.receiver];
|
|
12
|
+
if (new Set(all.map(placementKey)).size !== 4 ||
|
|
13
|
+
all.some((p) => p.controller !== all[0].controller || p.rttNode !== all[0].rttNode) ||
|
|
14
|
+
v.source.publisher.version !== v.source.receiver.version ||
|
|
15
|
+
v.target.publisher.version !== v.target.receiver.version ||
|
|
16
|
+
v.source.publisher.version === v.target.publisher.version)
|
|
17
|
+
c.addIssue({ code: "custom", message: "Four distinct placements, one package/controller and two paired versions required" });
|
|
18
|
+
});
|
|
19
|
+
/** Data-only same-host version review. No application JS, journal writes or launch authority. */
|
|
20
|
+
export function reviewInstalledProcessGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields = []) {
|
|
21
|
+
const first = configs.source.publisher;
|
|
22
|
+
const context = (c) => ({
|
|
23
|
+
packageRoot: c.packageRoot,
|
|
24
|
+
instanceDirectory: c.instanceDirectory,
|
|
25
|
+
rawConfiguration: c.raw,
|
|
26
|
+
channels: resolvedProcessGroupChannels(c.resolved),
|
|
27
|
+
controllerName,
|
|
28
|
+
stateRoot,
|
|
29
|
+
});
|
|
30
|
+
const old = authorizeProcessGroupRuntime(context(first));
|
|
31
|
+
const receiver = authorizeProcessGroupRuntime(context(configs.source.receiver));
|
|
32
|
+
if (old.role !== "target" ||
|
|
33
|
+
receiver.role !== "receiver" ||
|
|
34
|
+
old.file !== receiver.file ||
|
|
35
|
+
old.directory !== receiver.directory ||
|
|
36
|
+
!old.journalId ||
|
|
37
|
+
old.journalId !== receiver.journalId)
|
|
38
|
+
throw Error("Exact authorized source publisher/receiver pair required");
|
|
39
|
+
const sourcePolicy = read(old.file, true), previous = JSON.parse(sourcePolicy.toString());
|
|
40
|
+
const target = configs.target.publisher, descriptor = processGroupDescriptor(target.packageRoot);
|
|
41
|
+
if (!descriptor || descriptor.legacy)
|
|
42
|
+
throw Error("Target requires the shared process-group protocol declaration");
|
|
43
|
+
const targetConfig = normalizeProcessGroupConfiguration(target.raw, descriptor);
|
|
44
|
+
const journal = processGroupJournalSchema.parse(targetConfig.journal);
|
|
45
|
+
const resource = descriptor.manifests.find((m) => m.file === journal.groupManifest);
|
|
46
|
+
if (!resource)
|
|
47
|
+
throw Error("Unregistered target manifest");
|
|
48
|
+
const manifestBytes = read(path.join(target.packageRoot, resource.file)), manifest = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));
|
|
49
|
+
if (manifest.id !== resource.id || journal.directory !== old.directory || journal.journalId !== old.journalId)
|
|
50
|
+
throw Error("Journal or manifest identity changed");
|
|
51
|
+
const members = [];
|
|
52
|
+
const portable = (raw) => {
|
|
53
|
+
const copy = structuredClone(raw), uns = { ...copy["uns"] };
|
|
54
|
+
for (const k of excludedUnsFields)
|
|
55
|
+
delete uns[k];
|
|
56
|
+
copy["uns"] = uns;
|
|
57
|
+
return hash(copy);
|
|
58
|
+
};
|
|
59
|
+
for (const role of ["publisher", "receiver"]) {
|
|
60
|
+
const a = configs.source[role], b = configs.target[role];
|
|
61
|
+
if (portable(a.raw) !== portable(b.raw) ||
|
|
62
|
+
groupChannelsHash(resolvedProcessGroupChannels(a.resolved)) !== groupChannelsHash(resolvedProcessGroupChannels(b.resolved)))
|
|
63
|
+
throw Error("Configuration, broker identity, paths or units changed");
|
|
64
|
+
for (const side of ["source", "target"]) {
|
|
65
|
+
const c = configs[side][role], d = processGroupDescriptor(c.packageRoot);
|
|
66
|
+
if (!d)
|
|
67
|
+
throw Error("Missing shared runtime contract");
|
|
68
|
+
const normalized = normalizeProcessGroupConfiguration(c.raw, d), j = processGroupJournalSchema.parse(normalized.journal);
|
|
69
|
+
if (!normalized.matches ||
|
|
70
|
+
(role === "receiver"
|
|
71
|
+
? normalized.runtimeRole !== "admission"
|
|
72
|
+
: normalized.runtimeRole !== undefined && normalized.runtimeRole !== "publisher") ||
|
|
73
|
+
j.directory !== old.directory ||
|
|
74
|
+
j.journalId !== old.journalId ||
|
|
75
|
+
sha256(read(path.join(c.packageRoot, j.groupManifest))) !== sha256(manifestBytes))
|
|
76
|
+
throw Error("Runtime role, manifest or journal differs");
|
|
77
|
+
members.push({
|
|
78
|
+
side,
|
|
79
|
+
role,
|
|
80
|
+
processName: String(normalized.uns["processName"]),
|
|
81
|
+
configurationSha256: hash(c.raw),
|
|
82
|
+
artifactSha256: groupArtifactHash(c.packageRoot),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (members.find((m) => m.role === "publisher")?.processName !== manifest.processName ||
|
|
87
|
+
members.find((m) => m.role === "receiver")?.processName !== manifest.processName + "-admission")
|
|
88
|
+
throw Error("Manifest process identities differ");
|
|
89
|
+
const pkg = JSON.parse(read(path.join(target.packageRoot, "package.json")).toString());
|
|
90
|
+
const historical = previous.placements.filter((p) => p.role === "source");
|
|
91
|
+
const policy = processGroupAuthorizationSchema.parse({
|
|
92
|
+
schemaVersion: 3,
|
|
93
|
+
kind: "uns-process-group-runtime-authorization",
|
|
94
|
+
protocolVersion: 1,
|
|
95
|
+
packageName: pkg.name,
|
|
96
|
+
namespace: descriptor.namespace,
|
|
97
|
+
groupId: manifest.id,
|
|
98
|
+
descriptorSha256: hash(pkg.unsDatahub.processGroupRuntime),
|
|
99
|
+
controllerName,
|
|
100
|
+
packageRoot: target.packageRoot,
|
|
101
|
+
artifactSha256: groupArtifactHash(target.packageRoot),
|
|
102
|
+
groupManifestSha256: sha256(manifestBytes),
|
|
103
|
+
channelsSha256: groupChannelsHash(resolvedProcessGroupChannels(target.resolved)),
|
|
104
|
+
stateRoot,
|
|
105
|
+
directory: old.directory,
|
|
106
|
+
journalId: old.journalId,
|
|
107
|
+
placements: [
|
|
108
|
+
...historical,
|
|
109
|
+
...["publisher", "receiver"].map((role) => ({
|
|
110
|
+
instanceId: path.basename(configs.target[role].instanceDirectory),
|
|
111
|
+
processName: members.find((m) => m.side === "target" && m.role === role).processName,
|
|
112
|
+
role: role === "publisher" ? "target" : "receiver",
|
|
113
|
+
configurationSha256: hash(configs.target[role].raw),
|
|
114
|
+
})),
|
|
115
|
+
],
|
|
116
|
+
});
|
|
117
|
+
const targetPolicy = Buffer.from(JSON.stringify(policy));
|
|
118
|
+
for (const role of ["publisher", "receiver"])
|
|
119
|
+
validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);
|
|
120
|
+
const expected = processGroupJournalContract(processGroupSourceIdentity(resolvedProcessGroupChannels(target.resolved)[1]), journal, manifest.profiles);
|
|
121
|
+
const file = path.join(old.directory, "admission.sqlite");
|
|
122
|
+
if (fs.realpathSync(file) !== file || !fs.lstatSync(file).isFile())
|
|
123
|
+
throw Error("Unsafe journal resource");
|
|
124
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
125
|
+
const db = new DatabaseSync(file, { readOnly: true });
|
|
126
|
+
try {
|
|
127
|
+
db.exec("PRAGMA query_only=ON; PRAGMA busy_timeout=1000;");
|
|
128
|
+
const metadata = Object.fromEntries(db
|
|
129
|
+
.prepare("SELECT key,value FROM metadata WHERE key IN ('id','contract')")
|
|
130
|
+
.all()
|
|
131
|
+
.map((r) => [r["key"], r["value"]]));
|
|
132
|
+
if (metadata["id"] !== old.journalId || metadata["contract"] !== expected)
|
|
133
|
+
throw Error("Installed target cannot reopen the retained journal contract");
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
db.close();
|
|
137
|
+
}
|
|
138
|
+
if (sha256(read(old.file, true)) !== sha256(sourcePolicy))
|
|
139
|
+
throw Error("Source policy changed during review");
|
|
140
|
+
return {
|
|
141
|
+
review: {
|
|
142
|
+
protocolVersion: 1,
|
|
143
|
+
namespace: descriptor.namespace,
|
|
144
|
+
groupId: manifest.id,
|
|
145
|
+
policyFile: processGroupAuthorizationFile(context(target)),
|
|
146
|
+
sourcePolicySha256: sha256(sourcePolicy),
|
|
147
|
+
targetPolicySha256: sha256(targetPolicy),
|
|
148
|
+
journalId: old.journalId,
|
|
149
|
+
directory: old.directory,
|
|
150
|
+
journalContractSha256: sha256(expected),
|
|
151
|
+
profiles: manifest.profiles.map(({ processName, mappingSha256, dataGroup }) => ({ processName, mappingSha256, dataGroup })),
|
|
152
|
+
members,
|
|
153
|
+
},
|
|
154
|
+
sourcePolicy,
|
|
155
|
+
targetPolicy,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Atomic compare-and-swap. The authenticated host must first prove both old owners exited. */
|
|
159
|
+
export function replaceReviewedProcessGroupPolicy(file, expected, bytes) {
|
|
160
|
+
const actual = sha256(read(file, true)), next = sha256(bytes);
|
|
161
|
+
if (actual === next)
|
|
162
|
+
return; // Reconcile an already completed write after a lost reply.
|
|
163
|
+
if (actual !== expected)
|
|
164
|
+
throw Error("Runtime policy changed; review required");
|
|
165
|
+
const temporary = file + ".upgrade-tmp";
|
|
166
|
+
const fd = fs.openSync(temporary, "wx", 0o600);
|
|
167
|
+
try {
|
|
168
|
+
fs.writeFileSync(fd, bytes);
|
|
169
|
+
fs.fsyncSync(fd);
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
fs.closeSync(fd);
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
if (sha256(read(file, true)) !== expected)
|
|
176
|
+
throw Error("Runtime policy changed before replacement");
|
|
177
|
+
fs.renameSync(temporary, file);
|
|
178
|
+
const directory = fs.openSync(path.dirname(file), "r");
|
|
179
|
+
try {
|
|
180
|
+
fs.fsyncSync(directory);
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
fs.closeSync(directory);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
if (fs.existsSync(temporary))
|
|
188
|
+
fs.unlinkSync(temporary);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
export const processGroupUpgradeRequestSchema = z
|
|
192
|
+
.strictObject({
|
|
193
|
+
protocolVersion: z.literal(1),
|
|
194
|
+
controllerName: groupPlacementSchema.shape.controller,
|
|
195
|
+
action: z.enum(["preview", "prepare", "get", "execute", "rollback"]),
|
|
196
|
+
input: processGroupUpgradeInputSchema.optional(),
|
|
197
|
+
id: z.string().uuid().optional(),
|
|
198
|
+
expectedFingerprint: z
|
|
199
|
+
.string()
|
|
200
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
201
|
+
.optional(),
|
|
202
|
+
expectedRevision: z.number().int().positive().optional(),
|
|
203
|
+
})
|
|
204
|
+
.superRefine((v, c) => {
|
|
205
|
+
if ((["preview", "prepare"].includes(v.action) && !v.input) ||
|
|
206
|
+
(v.action !== "preview" && !v.id) ||
|
|
207
|
+
(["prepare", "execute", "rollback"].includes(v.action) && !v.expectedFingerprint) ||
|
|
208
|
+
(["execute", "rollback"].includes(v.action) && !v.expectedRevision) ||
|
|
209
|
+
(v.input && v.input.source.publisher.controller !== v.controllerName))
|
|
210
|
+
c.addIssue({ code: "custom", message: "Exact upgrade selector and reviewed revision required" });
|
|
211
|
+
});
|
|
212
|
+
/** Shared journal observations; only PID/start identity and fresh capture prove readiness. */
|
|
213
|
+
export function inspectProcessGroupUpgradeJournal(review, publisherPid, receiverPid) {
|
|
214
|
+
const file = path.join(review.directory, "admission.sqlite");
|
|
215
|
+
if (fs.realpathSync(file) !== file)
|
|
216
|
+
throw Error("Unsafe retained journal path");
|
|
217
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
218
|
+
const db = new DatabaseSync(file, { readOnly: true });
|
|
219
|
+
try {
|
|
220
|
+
db.exec("PRAGMA query_only=ON; PRAGMA busy_timeout=1000;");
|
|
221
|
+
const meta = Object.fromEntries(db
|
|
222
|
+
.prepare("SELECT key,value FROM metadata WHERE key IN ('id','contract','capture','runtime_namespace')")
|
|
223
|
+
.all()
|
|
224
|
+
.map((r) => [r["key"], r["value"]]));
|
|
225
|
+
if (meta["id"] !== review.journalId || sha256(String(meta["contract"])) !== review.journalContractSha256)
|
|
226
|
+
throw Error("Retained journal contract changed");
|
|
227
|
+
const capture = JSON.parse(String(meta["capture"] ?? "null"));
|
|
228
|
+
const identity = (pid, digest) => {
|
|
229
|
+
if (!pid || !Number.isSafeInteger(pid) || pid <= 0 || typeof digest !== "string" || process.platform !== "linux")
|
|
230
|
+
return false;
|
|
231
|
+
try {
|
|
232
|
+
const namespace = sha256(fs.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim() + ":" + fs.readlinkSync("/proc/self/ns/pid"));
|
|
233
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, "utf8"), start = stat.slice(stat.lastIndexOf(")") + 2).split(" ")[19];
|
|
234
|
+
return meta["runtime_namespace"] === namespace && !!start && digest === sha256(namespace + ":" + pid + ":" + start);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const rows = db.prepare("SELECT name,pid,owner,runtime_identity FROM profiles").all();
|
|
241
|
+
return {
|
|
242
|
+
receiverReady: capture?.pid === receiverPid &&
|
|
243
|
+
["ready", "capacity-blocked"].includes(capture?.state) &&
|
|
244
|
+
Number.isSafeInteger(capture?.heartbeat) &&
|
|
245
|
+
capture.heartbeat <= Date.now() + 1000 &&
|
|
246
|
+
Date.now() - capture.heartbeat <= 5000 &&
|
|
247
|
+
identity(receiverPid, capture.runtimeIdentity),
|
|
248
|
+
publisherReady: rows.length === review.profiles.length &&
|
|
249
|
+
review.profiles.every((p) => rows.some((r) => r["name"] === p.processName && r["pid"] === publisherPid && !!r["owner"] && identity(publisherPid, r["runtime_identity"]))),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
db.close();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=process-group-upgrade.js.map
|
|
@@ -0,0 +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"]}
|