create-principles-disciple 1.132.2 → 1.132.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/codex-adapter/dist/codec/index.d.ts +6 -0
  2. package/codex-adapter/dist/codec/index.js +5 -0
  3. package/codex-adapter/dist/codec/input-decoder.d.ts +13 -0
  4. package/codex-adapter/dist/codec/input-decoder.js +103 -0
  5. package/codex-adapter/dist/codec/output-encoder.d.ts +32 -0
  6. package/codex-adapter/dist/codec/output-encoder.js +51 -0
  7. package/codex-adapter/dist/host-adapter.d.ts +30 -0
  8. package/codex-adapter/dist/host-adapter.js +28 -0
  9. package/codex-adapter/dist/index.d.ts +25 -0
  10. package/codex-adapter/dist/index.js +19 -0
  11. package/codex-adapter/dist/ingestion/admission.d.ts +54 -0
  12. package/codex-adapter/dist/ingestion/admission.js +137 -0
  13. package/codex-adapter/dist/ingestion/catch-up.d.ts +41 -0
  14. package/codex-adapter/dist/ingestion/catch-up.js +94 -0
  15. package/codex-adapter/dist/ingestion/codex-home.d.ts +19 -0
  16. package/codex-adapter/dist/ingestion/codex-home.js +43 -0
  17. package/codex-adapter/dist/ingestion/codex-version.d.ts +30 -0
  18. package/codex-adapter/dist/ingestion/codex-version.js +53 -0
  19. package/codex-adapter/dist/ingestion/ingestion-fields.d.ts +17 -0
  20. package/codex-adapter/dist/ingestion/ingestion-fields.js +28 -0
  21. package/codex-adapter/dist/ingestion/ingestion.d.ts +71 -0
  22. package/codex-adapter/dist/ingestion/ingestion.js +248 -0
  23. package/codex-adapter/dist/ingestion/transcript-decoder.d.ts +72 -0
  24. package/codex-adapter/dist/ingestion/transcript-decoder.js +485 -0
  25. package/codex-adapter/dist/ingestion/transcript-locate.d.ts +13 -0
  26. package/codex-adapter/dist/ingestion/transcript-locate.js +75 -0
  27. package/codex-adapter/dist/ingestion/transcript-path.d.ts +25 -0
  28. package/codex-adapter/dist/ingestion/transcript-path.js +87 -0
  29. package/codex-adapter/dist/pd-hook.d.ts +9 -0
  30. package/codex-adapter/dist/pd-hook.js +159 -0
  31. package/codex-adapter/dist/tool-semantics.d.ts +20 -0
  32. package/codex-adapter/dist/tool-semantics.js +27 -0
  33. package/codex-adapter/dist/worker/workspace-worker.d.ts +59 -0
  34. package/codex-adapter/dist/worker/workspace-worker.js +270 -0
  35. package/codex-adapter/package.json +52 -0
  36. package/console/dist/server/routes/update.js +187 -19
  37. package/console/dist/server/update/mutation-controller.d.ts +18 -0
  38. package/console/dist/server/update/mutation-controller.js +29 -0
  39. package/console/dist/server/utils/installed-layout.d.ts +1 -0
  40. package/console/dist/server/utils/installed-layout.js +2 -0
  41. package/console/package.json +1 -0
  42. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +15 -0
  43. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  44. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.d.ts +2 -0
  45. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.d.ts.map +1 -0
  46. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.js +71 -0
  47. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.js.map +1 -0
  48. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.d.ts +2 -0
  49. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.d.ts.map +1 -0
  50. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.js +219 -0
  51. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.js.map +1 -0
  52. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.d.ts.map +1 -1
  53. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.js +2 -3
  54. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.js.map +1 -1
  55. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts +12 -1
  56. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts.map +1 -1
  57. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js +15 -2
  58. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js.map +1 -1
  59. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.d.ts +50 -0
  60. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.d.ts.map +1 -0
  61. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.js +93 -0
  62. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.js.map +1 -0
  63. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  64. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +5 -0
  65. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  66. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js +152 -0
  67. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js.map +1 -1
  68. package/core/dist/runtime-v2/internalization/owner-review.d.ts +7 -1
  69. package/core/dist/runtime-v2/internalization/owner-review.d.ts.map +1 -1
  70. package/core/dist/runtime-v2/internalization/owner-review.js +22 -3
  71. package/core/dist/runtime-v2/internalization/owner-review.js.map +1 -1
  72. package/core/package.json +3 -2
  73. package/dist/installer.d.ts +32 -0
  74. package/dist/installer.d.ts.map +1 -1
  75. package/dist/installer.js +198 -2
  76. package/dist/installer.js.map +1 -1
  77. package/dist/installers/codex-host-installer.d.ts.map +1 -1
  78. package/dist/installers/codex-host-installer.js +5 -3
  79. package/dist/installers/codex-host-installer.js.map +1 -1
  80. package/dist/update/release-manager-authority.d.ts +69 -0
  81. package/dist/update/release-manager-authority.d.ts.map +1 -0
  82. package/dist/update/release-manager-authority.js +125 -0
  83. package/dist/update/release-manager-authority.js.map +1 -0
  84. package/dist/utils/workspace-divergence.d.ts +36 -0
  85. package/dist/utils/workspace-divergence.d.ts.map +1 -0
  86. package/dist/utils/workspace-divergence.js +87 -0
  87. package/dist/utils/workspace-divergence.js.map +1 -0
  88. package/install-layout/dist/index.d.ts +5 -0
  89. package/install-layout/dist/index.js +1 -0
  90. package/install-layout/package.json +1 -1
  91. package/package.json +4 -2
  92. package/plugin/dist/bundle.js +870 -734
  93. package/plugin/dist/governance-audit.js +381 -247
  94. package/plugin/dist/openclaw-sdk.d.ts +3 -0
  95. package/plugin/dist/rulehost-evidence.js +420 -286
  96. package/plugin/dist/service/subagent-workflow/types.d.ts +2 -2
  97. package/plugin/dist/utils/retry.d.ts +1 -1
  98. package/plugin/dist/utils/workspace-resolver.d.ts +35 -4
  99. package/plugin/openclaw.plugin.json +1 -1
  100. package/plugin/package.json +1 -1
  101. package/release-manager/dist/i18n.d.ts +6 -0
  102. package/release-manager/dist/i18n.d.ts.map +1 -0
  103. package/release-manager/dist/i18n.js +234 -0
  104. package/release-manager/dist/i18n.js.map +1 -0
  105. package/release-manager/dist/index.d.ts +7 -0
  106. package/release-manager/dist/index.d.ts.map +1 -0
  107. package/release-manager/dist/index.js +474 -0
  108. package/release-manager/dist/index.js.map +1 -0
  109. package/release-manager/dist/installer.d.ts +217 -0
  110. package/release-manager/dist/installer.d.ts.map +1 -0
  111. package/release-manager/dist/installer.js +2451 -0
  112. package/release-manager/dist/installer.js.map +1 -0
  113. package/release-manager/dist/installers/codex-host-installer.d.ts +29 -0
  114. package/release-manager/dist/installers/codex-host-installer.d.ts.map +1 -0
  115. package/release-manager/dist/installers/codex-host-installer.js +496 -0
  116. package/release-manager/dist/installers/codex-host-installer.js.map +1 -0
  117. package/release-manager/dist/installers/index.d.ts +40 -0
  118. package/release-manager/dist/installers/index.d.ts.map +1 -0
  119. package/release-manager/dist/installers/index.js +35 -0
  120. package/release-manager/dist/installers/index.js.map +1 -0
  121. package/release-manager/dist/installers/openclaw-host-installer.d.ts +18 -0
  122. package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +1 -0
  123. package/release-manager/dist/installers/openclaw-host-installer.js +414 -0
  124. package/release-manager/dist/installers/openclaw-host-installer.js.map +1 -0
  125. package/release-manager/dist/mvp-config.d.ts +197 -0
  126. package/release-manager/dist/mvp-config.d.ts.map +1 -0
  127. package/release-manager/dist/mvp-config.js +509 -0
  128. package/release-manager/dist/mvp-config.js.map +1 -0
  129. package/release-manager/dist/prompts.d.ts +30 -0
  130. package/release-manager/dist/prompts.d.ts.map +1 -0
  131. package/release-manager/dist/prompts.js +231 -0
  132. package/release-manager/dist/prompts.js.map +1 -0
  133. package/release-manager/dist/skill-language.d.ts +32 -0
  134. package/release-manager/dist/skill-language.d.ts.map +1 -0
  135. package/release-manager/dist/skill-language.js +107 -0
  136. package/release-manager/dist/skill-language.js.map +1 -0
  137. package/release-manager/dist/uninstaller.d.ts +55 -0
  138. package/release-manager/dist/uninstaller.d.ts.map +1 -0
  139. package/release-manager/dist/uninstaller.js +409 -0
  140. package/release-manager/dist/uninstaller.js.map +1 -0
  141. package/release-manager/dist/update/atomic-file.d.ts +35 -0
  142. package/release-manager/dist/update/atomic-file.d.ts.map +1 -0
  143. package/release-manager/dist/update/atomic-file.js +120 -0
  144. package/release-manager/dist/update/atomic-file.js.map +1 -0
  145. package/release-manager/dist/update/bootstrap-protocol.d.ts +55 -0
  146. package/release-manager/dist/update/bootstrap-protocol.d.ts.map +1 -0
  147. package/release-manager/dist/update/bootstrap-protocol.js +132 -0
  148. package/release-manager/dist/update/bootstrap-protocol.js.map +1 -0
  149. package/release-manager/dist/update/channel-metadata.d.ts +28 -0
  150. package/release-manager/dist/update/channel-metadata.d.ts.map +1 -0
  151. package/release-manager/dist/update/channel-metadata.js +90 -0
  152. package/release-manager/dist/update/channel-metadata.js.map +1 -0
  153. package/release-manager/dist/update/channel-promotion.d.ts +39 -0
  154. package/release-manager/dist/update/channel-promotion.d.ts.map +1 -0
  155. package/release-manager/dist/update/channel-promotion.js +55 -0
  156. package/release-manager/dist/update/channel-promotion.js.map +1 -0
  157. package/release-manager/dist/update/data-compatibility.d.ts +35 -0
  158. package/release-manager/dist/update/data-compatibility.d.ts.map +1 -0
  159. package/release-manager/dist/update/data-compatibility.js +45 -0
  160. package/release-manager/dist/update/data-compatibility.js.map +1 -0
  161. package/release-manager/dist/update/install-layout.d.ts +59 -0
  162. package/release-manager/dist/update/install-layout.d.ts.map +1 -0
  163. package/release-manager/dist/update/install-layout.js +127 -0
  164. package/release-manager/dist/update/install-layout.js.map +1 -0
  165. package/release-manager/dist/update/legacy-migration.d.ts +56 -0
  166. package/release-manager/dist/update/legacy-migration.d.ts.map +1 -0
  167. package/release-manager/dist/update/legacy-migration.js +254 -0
  168. package/release-manager/dist/update/legacy-migration.js.map +1 -0
  169. package/release-manager/dist/update/product-identity.d.ts +50 -0
  170. package/release-manager/dist/update/product-identity.d.ts.map +1 -0
  171. package/release-manager/dist/update/product-identity.js +63 -0
  172. package/release-manager/dist/update/product-identity.js.map +1 -0
  173. package/release-manager/dist/update/release-asset-manifest.d.ts +31 -0
  174. package/release-manager/dist/update/release-asset-manifest.d.ts.map +1 -0
  175. package/release-manager/dist/update/release-asset-manifest.js +161 -0
  176. package/release-manager/dist/update/release-asset-manifest.js.map +1 -0
  177. package/release-manager/dist/update/release-identity.d.ts +33 -0
  178. package/release-manager/dist/update/release-identity.d.ts.map +1 -0
  179. package/release-manager/dist/update/release-identity.js +108 -0
  180. package/release-manager/dist/update/release-identity.js.map +1 -0
  181. package/release-manager/dist/update/release-manager-authority.d.ts +69 -0
  182. package/release-manager/dist/update/release-manager-authority.d.ts.map +1 -0
  183. package/release-manager/dist/update/release-manager-authority.js +125 -0
  184. package/release-manager/dist/update/release-manager-authority.js.map +1 -0
  185. package/release-manager/dist/update/release-manager.d.ts +96 -0
  186. package/release-manager/dist/update/release-manager.d.ts.map +1 -0
  187. package/release-manager/dist/update/release-manager.js +253 -0
  188. package/release-manager/dist/update/release-manager.js.map +1 -0
  189. package/release-manager/dist/update/release-metadata.d.ts +57 -0
  190. package/release-manager/dist/update/release-metadata.d.ts.map +1 -0
  191. package/release-manager/dist/update/release-metadata.js +200 -0
  192. package/release-manager/dist/update/release-metadata.js.map +1 -0
  193. package/release-manager/dist/update/release-policy.d.ts +51 -0
  194. package/release-manager/dist/update/release-policy.d.ts.map +1 -0
  195. package/release-manager/dist/update/release-policy.js +103 -0
  196. package/release-manager/dist/update/release-policy.js.map +1 -0
  197. package/release-manager/dist/update/rollback-policy.d.ts +56 -0
  198. package/release-manager/dist/update/rollback-policy.d.ts.map +1 -0
  199. package/release-manager/dist/update/rollback-policy.js +61 -0
  200. package/release-manager/dist/update/rollback-policy.js.map +1 -0
  201. package/release-manager/dist/update/transaction-journal.d.ts +131 -0
  202. package/release-manager/dist/update/transaction-journal.d.ts.map +1 -0
  203. package/release-manager/dist/update/transaction-journal.js +346 -0
  204. package/release-manager/dist/update/transaction-journal.js.map +1 -0
  205. package/release-manager/dist/update/trust-metadata.d.ts +55 -0
  206. package/release-manager/dist/update/trust-metadata.d.ts.map +1 -0
  207. package/release-manager/dist/update/trust-metadata.js +170 -0
  208. package/release-manager/dist/update/trust-metadata.js.map +1 -0
  209. package/release-manager/dist/update/update-history.d.ts +46 -0
  210. package/release-manager/dist/update/update-history.d.ts.map +1 -0
  211. package/release-manager/dist/update/update-history.js +123 -0
  212. package/release-manager/dist/update/update-history.js.map +1 -0
  213. package/release-manager/dist/utils/config-file-io.d.ts +26 -0
  214. package/release-manager/dist/utils/config-file-io.d.ts.map +1 -0
  215. package/release-manager/dist/utils/config-file-io.js +128 -0
  216. package/release-manager/dist/utils/config-file-io.js.map +1 -0
  217. package/release-manager/dist/utils/env.d.ts +60 -0
  218. package/release-manager/dist/utils/env.d.ts.map +1 -0
  219. package/release-manager/dist/utils/env.js +308 -0
  220. package/release-manager/dist/utils/env.js.map +1 -0
  221. package/release-manager/dist/utils/logger.d.ts +15 -0
  222. package/release-manager/dist/utils/logger.d.ts.map +1 -0
  223. package/release-manager/dist/utils/logger.js +30 -0
  224. package/release-manager/dist/utils/logger.js.map +1 -0
  225. package/release-manager/dist/utils/workspace-divergence.d.ts +36 -0
  226. package/release-manager/dist/utils/workspace-divergence.d.ts.map +1 -0
  227. package/release-manager/dist/utils/workspace-divergence.js +87 -0
  228. package/release-manager/dist/utils/workspace-divergence.js.map +1 -0
  229. package/release-manager/package.json +79 -0
@@ -0,0 +1,161 @@
1
+ import { createHash } from 'node:crypto';
2
+ import * as fs from 'node:fs';
3
+ import { readFile } from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ export class ReleaseAssetManifestError extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.name = 'ReleaseAssetManifestError';
10
+ this.code = code;
11
+ }
12
+ }
13
+ function isSafeRelativePath(value) {
14
+ return value.length > 0
15
+ && !path.isAbsolute(value)
16
+ && !value.split(/[\\/]/).some((segment) => segment.length === 0 || segment === '.' || segment === '..');
17
+ }
18
+ function listPayloadFilePaths(assetDir) {
19
+ const rootDir = path.resolve(assetDir);
20
+ if (!fs.existsSync(rootDir) || !fs.statSync(rootDir).isDirectory()) {
21
+ throw new ReleaseAssetManifestError('asset_directory_missing', `Release asset directory does not exist: ${rootDir}`);
22
+ }
23
+ const files = [];
24
+ const visit = (directory) => {
25
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
26
+ const absolutePath = path.resolve(directory, entry.name);
27
+ // Containment guard: enumeration must never escape the asset root.
28
+ if (absolutePath !== rootDir && !absolutePath.startsWith(rootDir + path.sep)) {
29
+ throw new ReleaseAssetManifestError('asset_path_unsafe', `Release asset enumeration escaped the asset root: ${absolutePath}`);
30
+ }
31
+ const relativePath = path.relative(rootDir, absolutePath).split(path.sep).join('/');
32
+ if (relativePath === '_release')
33
+ continue;
34
+ // Depth-0 node_modules is the package's own toolchain install, excluded
35
+ // from the manifest by build-release-asset — the verifier must apply
36
+ // the identical rule or every packaged install would report unexpected
37
+ // files.
38
+ if (relativePath === 'node_modules')
39
+ continue;
40
+ if (entry.isSymbolicLink()) {
41
+ throw new ReleaseAssetManifestError('asset_path_unsafe', `Release asset must not contain symlinks: ${relativePath}`);
42
+ }
43
+ if (entry.isDirectory()) {
44
+ visit(absolutePath);
45
+ continue;
46
+ }
47
+ if (!entry.isFile() || !isSafeRelativePath(relativePath)) {
48
+ throw new ReleaseAssetManifestError('asset_path_unsafe', `Release asset contains an unsafe entry: ${relativePath}`);
49
+ }
50
+ files.push({ absolutePath, relativePath });
51
+ }
52
+ };
53
+ visit(rootDir);
54
+ return files.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
55
+ }
56
+ function readPayloadFiles(assetDir) {
57
+ return listPayloadFilePaths(assetDir).map(({ absolutePath, relativePath }) => {
58
+ const bytes = fs.readFileSync(absolutePath);
59
+ return {
60
+ path: relativePath,
61
+ sha256: createHash('sha256').update(bytes).digest('hex'),
62
+ size: bytes.length,
63
+ };
64
+ });
65
+ }
66
+ function isRecord(value) {
67
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
68
+ }
69
+ export function parseReleaseAssetManifest(value) {
70
+ if (!isRecord(value) || value.schemaVersion !== 1 || !Array.isArray(value.files)) {
71
+ throw new ReleaseAssetManifestError('asset_manifest_invalid', 'Release asset manifest has an unsupported schema.');
72
+ }
73
+ const files = [];
74
+ const seenPaths = new Set();
75
+ for (const file of value.files) {
76
+ if (!isRecord(file)) {
77
+ throw new ReleaseAssetManifestError('asset_manifest_invalid', 'Release asset manifest contains an invalid file record.');
78
+ }
79
+ const { path: filePath, sha256, size } = file;
80
+ if (typeof filePath !== 'string' || !isSafeRelativePath(filePath) || seenPaths.has(filePath)) {
81
+ throw new ReleaseAssetManifestError('asset_manifest_invalid', 'Release asset manifest contains an unsafe or duplicate path.');
82
+ }
83
+ if (typeof size !== 'number' || !Number.isSafeInteger(size) || size < 0 || typeof sha256 !== 'string' || !/^[a-f0-9]{64}$/i.test(sha256)) {
84
+ throw new ReleaseAssetManifestError('asset_manifest_invalid', `Release asset manifest has invalid integrity data for ${filePath}.`);
85
+ }
86
+ seenPaths.add(filePath);
87
+ files.push({ path: filePath, size, sha256: sha256.toLowerCase() });
88
+ }
89
+ return { schemaVersion: 1, files };
90
+ }
91
+ export function parseReleaseAssetIdentity(value) {
92
+ if (!isRecord(value) || value.schemaVersion !== 1) {
93
+ throw new ReleaseAssetManifestError('asset_identity_invalid', 'Release asset identity has an unsupported schema.');
94
+ }
95
+ const platform = Object.hasOwn(value, 'platform') ? value.platform : undefined;
96
+ const arch = Object.hasOwn(value, 'arch') ? value.arch : undefined;
97
+ const nodeAbi = Object.hasOwn(value, 'nodeAbi') ? value.nodeAbi : undefined;
98
+ if (typeof platform !== 'string' || platform.trim().length === 0
99
+ || typeof arch !== 'string' || arch.trim().length === 0
100
+ || typeof nodeAbi !== 'string' || !/^\d+$/.test(nodeAbi)) {
101
+ throw new ReleaseAssetManifestError('asset_identity_invalid', 'Release asset identity must declare platform, architecture, and numeric Node ABI.');
102
+ }
103
+ return { schemaVersion: 1, platform, arch, nodeAbi };
104
+ }
105
+ export function verifyReleaseAssetTarget(identity, target) {
106
+ const validatedIdentity = parseReleaseAssetIdentity(identity);
107
+ if (validatedIdentity.platform !== target.platform
108
+ || validatedIdentity.arch !== target.arch
109
+ || validatedIdentity.nodeAbi !== target.nodeAbi) {
110
+ throw new ReleaseAssetManifestError('asset_target_mismatch', `Release asset target ${validatedIdentity.platform}/${validatedIdentity.arch}/abi${validatedIdentity.nodeAbi} does not match this runtime ${target.platform}/${target.arch}/abi${target.nodeAbi}.`);
111
+ }
112
+ }
113
+ export function createReleaseAssetManifest(assetDir) {
114
+ return { schemaVersion: 1, files: readPayloadFiles(assetDir) };
115
+ }
116
+ export function verifyReleaseAssetManifest(assetDir, manifest) {
117
+ const validatedManifest = parseReleaseAssetManifest(manifest);
118
+ const actualFiles = readPayloadFiles(assetDir);
119
+ const expectedByPath = new Map(validatedManifest.files.map((file) => [file.path, file]));
120
+ if (actualFiles.length !== expectedByPath.size) {
121
+ throw new ReleaseAssetManifestError('asset_file_unexpected', 'Release asset file set does not match its manifest.');
122
+ }
123
+ for (const actualFile of actualFiles) {
124
+ const expectedFile = expectedByPath.get(actualFile.path);
125
+ if (!expectedFile) {
126
+ throw new ReleaseAssetManifestError('asset_file_unexpected', `Release asset contains an unexpected file: ${actualFile.path}`);
127
+ }
128
+ if (actualFile.size !== expectedFile.size || actualFile.sha256 !== expectedFile.sha256.toLowerCase()) {
129
+ throw new ReleaseAssetManifestError('asset_digest_mismatch', `Release asset integrity check failed: ${actualFile.path}`);
130
+ }
131
+ }
132
+ }
133
+ export async function verifyReleaseAssetManifestAsync(assetDir, manifest) {
134
+ const validatedManifest = parseReleaseAssetManifest(manifest);
135
+ const payloadPaths = listPayloadFilePaths(assetDir);
136
+ const expectedByPath = new Map(validatedManifest.files.map((file) => [file.path, file]));
137
+ if (payloadPaths.length !== expectedByPath.size) {
138
+ throw new ReleaseAssetManifestError('asset_file_unexpected', 'Release asset file set does not match its manifest.');
139
+ }
140
+ const concurrency = Math.min(64, Math.max(1, payloadPaths.length));
141
+ let nextIndex = 0;
142
+ await Promise.all(Array.from({ length: concurrency }, async () => {
143
+ while (nextIndex < payloadPaths.length) {
144
+ const index = nextIndex;
145
+ nextIndex += 1;
146
+ const payload = payloadPaths[index];
147
+ if (!payload)
148
+ throw new ReleaseAssetManifestError('asset_manifest_invalid', 'Release asset verification lost its file cursor.');
149
+ const expected = expectedByPath.get(payload.relativePath);
150
+ if (!expected) {
151
+ throw new ReleaseAssetManifestError('asset_file_unexpected', `Release asset contains an unexpected file: ${payload.relativePath}`);
152
+ }
153
+ const bytes = await readFile(payload.absolutePath);
154
+ const digest = createHash('sha256').update(bytes).digest('hex');
155
+ if (bytes.length !== expected.size || digest !== expected.sha256) {
156
+ throw new ReleaseAssetManifestError('asset_digest_mismatch', `Release asset integrity check failed: ${payload.relativePath}`);
157
+ }
158
+ }
159
+ }));
160
+ }
161
+ //# sourceMappingURL=release-asset-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-asset-manifest.js","sourceRoot":"","sources":["../../src/update/release-asset-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Immutable release identity derivation (SPEC §4.1, §4.3).
3
+ *
4
+ * releaseId = sha256 over the canonical identity inputs: product version,
5
+ * source commit, the sorted platform asset identities, the minimum bootstrap
6
+ * version, and the digest of the metadata content that excludes releaseId
7
+ * itself (avoiding circular hashing, per SPEC §4.2's detached-digest rule).
8
+ * Informational build time is never an identity input.
9
+ */
10
+ export interface ReleaseAssetIdentity {
11
+ readonly platform: string;
12
+ readonly arch: string;
13
+ readonly nodeAbi: string;
14
+ readonly archiveSha256: string;
15
+ readonly archiveSizeBytes: number;
16
+ }
17
+ export interface ReleaseIdentityInputs {
18
+ readonly productVersion: string;
19
+ readonly sourceCommit: string;
20
+ readonly minBootstrapVersion: string;
21
+ readonly assets: readonly ReleaseAssetIdentity[];
22
+ }
23
+ /** Deterministic JSON: sorted keys, no insignificant whitespace. */
24
+ export declare function canonicalJson(value: unknown): string;
25
+ /** Content digest of the identity-relevant metadata, with `releaseId` removed. */
26
+ export declare function computeReleaseContentDigest(contentWithoutReleaseId: unknown): string;
27
+ /**
28
+ * Derives the immutable release ID. Same source + same declared inputs MUST
29
+ * produce the same ID; any input change produces a different ID. Deterministic
30
+ * across platforms (canonical JSON, sorted assets, LF strings).
31
+ */
32
+ export declare function deriveReleaseId(inputs: ReleaseIdentityInputs): string;
33
+ //# sourceMappingURL=release-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-identity.d.ts","sourceRoot":"","sources":["../../src/update/release-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAClD;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWpD;AAgCD,kFAAkF;AAClF,wBAAgB,2BAA2B,CAAC,uBAAuB,EAAE,OAAO,GAAG,MAAM,CAEpF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA6CrE"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Immutable release identity derivation (SPEC §4.1, §4.3).
3
+ *
4
+ * releaseId = sha256 over the canonical identity inputs: product version,
5
+ * source commit, the sorted platform asset identities, the minimum bootstrap
6
+ * version, and the digest of the metadata content that excludes releaseId
7
+ * itself (avoiding circular hashing, per SPEC §4.2's detached-digest rule).
8
+ * Informational build time is never an identity input.
9
+ */
10
+ import { createHash } from 'node:crypto';
11
+ import { assertGitCommit, assertSha256Hex, parseProductVersion, ProductIdentityError, } from './product-identity.js';
12
+ /** Deterministic JSON: sorted keys, no insignificant whitespace. */
13
+ export function canonicalJson(value) {
14
+ if (Array.isArray(value)) {
15
+ return `[${value.map(canonicalJson).join(',')}]`;
16
+ }
17
+ if (typeof value === 'object' && value !== null) {
18
+ const entries = Object.entries(value)
19
+ .filter(([, v]) => v !== undefined)
20
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
21
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`;
22
+ }
23
+ return JSON.stringify(value);
24
+ }
25
+ function validateAssetIdentity(asset, index) {
26
+ if (typeof asset !== 'object' || asset === null || Array.isArray(asset)) {
27
+ throw new ProductIdentityError('assets', `assets[${index}] must be an object`);
28
+ }
29
+ const record = asset;
30
+ const { platform } = record;
31
+ const { arch } = record;
32
+ const { nodeAbi } = record;
33
+ const { archiveSha256 } = record;
34
+ const { archiveSizeBytes } = record;
35
+ for (const [field, value] of [['platform', platform], ['arch', arch], ['nodeAbi', nodeAbi]]) {
36
+ if (typeof value !== 'string' || value.length === 0 || !/^[a-z0-9-]+$/.test(value)) {
37
+ throw new ProductIdentityError('assets', `assets[${index}].${field} must be a non-empty lowercase identifier, got: ${JSON.stringify(value)}`);
38
+ }
39
+ }
40
+ if (typeof nodeAbi !== 'string' || !/^\d+$/.test(nodeAbi)) {
41
+ throw new ProductIdentityError('assets', `assets[${index}].nodeAbi must be a numeric Node ABI string (e.g. "147"), got: ${JSON.stringify(nodeAbi)}`);
42
+ }
43
+ if (typeof archiveSizeBytes !== 'number' || !Number.isSafeInteger(archiveSizeBytes) || archiveSizeBytes <= 0) {
44
+ throw new ProductIdentityError('assets', `assets[${index}].archiveSizeBytes must be a positive safe integer, got: ${JSON.stringify(archiveSizeBytes)}`);
45
+ }
46
+ return {
47
+ platform,
48
+ arch,
49
+ nodeAbi,
50
+ archiveSha256: assertSha256Hex(archiveSha256, `assets[${index}].archiveSha256`),
51
+ archiveSizeBytes,
52
+ };
53
+ }
54
+ /** Content digest of the identity-relevant metadata, with `releaseId` removed. */
55
+ export function computeReleaseContentDigest(contentWithoutReleaseId) {
56
+ return createHash('sha256').update(canonicalJson(contentWithoutReleaseId), 'utf8').digest('hex');
57
+ }
58
+ /**
59
+ * Derives the immutable release ID. Same source + same declared inputs MUST
60
+ * produce the same ID; any input change produces a different ID. Deterministic
61
+ * across platforms (canonical JSON, sorted assets, LF strings).
62
+ */
63
+ export function deriveReleaseId(inputs) {
64
+ const productVersion = parseProductVersion(inputs.productVersion);
65
+ parseProductVersion(inputs.minBootstrapVersion, 'minBootstrapVersion');
66
+ assertGitCommit(inputs.sourceCommit, 'sourceCommit');
67
+ if (!Array.isArray(inputs.assets) || inputs.assets.length === 0) {
68
+ throw new ProductIdentityError('assets', 'a release must declare at least one platform asset');
69
+ }
70
+ const assets = inputs.assets.map(validateAssetIdentity);
71
+ // Duplicate detection runs BEFORE sorting as an explicit pass — sort
72
+ // comparators are not guaranteed to compare every element pair, so a
73
+ // duplicate key could slip into the identity input unnoticed.
74
+ const seenKeys = new Set();
75
+ for (const asset of assets) {
76
+ const key = `${asset.platform}/${asset.arch}/abi${asset.nodeAbi}`;
77
+ if (seenKeys.has(key)) {
78
+ throw new ProductIdentityError('assets', `duplicate platform asset declared: ${key}`);
79
+ }
80
+ seenKeys.add(key);
81
+ }
82
+ const sortedAssets = [...assets].sort((a, b) => {
83
+ const keyA = `${a.platform}/${a.arch}/abi${a.nodeAbi}`;
84
+ const keyB = `${b.platform}/${b.arch}/abi${b.nodeAbi}`;
85
+ return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
86
+ });
87
+ const identityContent = {
88
+ kind: 'pd-release-identity-v1',
89
+ productVersion: productVersion.productVersion,
90
+ sourceCommit: inputs.sourceCommit,
91
+ minBootstrapVersion: inputs.minBootstrapVersion,
92
+ assets: sortedAssets.map((asset) => ({
93
+ platform: asset.platform,
94
+ arch: asset.arch,
95
+ nodeAbi: asset.nodeAbi,
96
+ archiveSha256: asset.archiveSha256,
97
+ archiveSizeBytes: asset.archiveSizeBytes,
98
+ })),
99
+ };
100
+ const contentDigest = computeReleaseContentDigest(identityContent);
101
+ // The SPEC's "release metadata digest" input is the digest of the identity
102
+ // content above — hashed again with the kind tag so releaseId ≠ any
103
+ // intermediate digest.
104
+ return createHash('sha256')
105
+ .update(`pd-release-id-v1:${contentDigest}`, 'utf8')
106
+ .digest('hex');
107
+ }
108
+ //# sourceMappingURL=release-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-identity.js","sourceRoot":"","sources":["../../src/update/release-identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * ReleaseManager mutation authority surface (PRI-672 — the "PRI-661" adoption task).
3
+ *
4
+ * This module is the narrow seam between the Console's MutationController
5
+ * (PRI-659 migration boundary) and the ReleaseManager deep module. It exposes:
6
+ *
7
+ * - `createReleaseManagerAuthority()` — constructs the ReleaseManager for a
8
+ * pdHome and reports per-mutation-kind readiness with stable, structured
9
+ * reason codes (ADR-0024 §2.4: refusal over silent degradation);
10
+ * - `mapReleaseManagerErrorToFallback()` — maps ReleaseManager refusals onto
11
+ * the explicit-fallback reason vocabulary the console surfaces in the
12
+ * `X-PD-Mutation-Fallback-Reason` response header.
13
+ *
14
+ * Boundary (ADR-0024 §2.1): the authority module DECIDES; it never deploys.
15
+ * Artifact deployment stays with the installer; the transaction journal stays
16
+ * the single source of truth for runtime mutations. Readiness probing performs
17
+ * zero filesystem writes. The governed shadow check (kind `check`) refreshes
18
+ * only ReleaseManager-owned verified-metadata caches under `~/.pd/trust` and
19
+ * `~/.pd/channels` — never `~/.pd/runtime`, never the extension directory.
20
+ *
21
+ * Journal readiness semantics: `journal_not_supported` gates MUTATION kinds as
22
+ * a hard precondition (ADR-0024 D-2 — an unjournaled runtime mutation must be
23
+ * refused, never degraded to). It is reported for `check` only as a
24
+ * conservative coupling — on a dual-slot install, a corrupt active.json is
25
+ * recovered FROM the journal, so a check that cannot trust journal-recoverable
26
+ * state must not claim readiness. Relaxing it for `check` alone is a Phase 4
27
+ * decision that must stay explicit (see the analysis doc §4.3); it can never
28
+ * be relaxed for apply/apply-full/rollback.
29
+ *
30
+ * apply/apply-full/rollback stay structurally not-ready until the Phase 4
31
+ * activation rollout opens the `shadow_mode_read_only` gate (its own go/no-go);
32
+ * until then these kinds explicitly fall back to the legacy console updater —
33
+ * TEMPORARY migration debt per ADR-0024 D-1, not a supported long-term state.
34
+ */
35
+ import { ReleaseManager, type InstallStatus, type LegacyUpdaterDecision } from './release-manager.js';
36
+ /** Mutation kinds the console MutationController routes (PRI-659 contract). */
37
+ export declare const RELEASE_MANAGER_AUTHORITY_KINDS: readonly ['check', 'apply', 'apply-full', 'rollback'];
38
+ export type ReleaseManagerAuthorityKind = (typeof RELEASE_MANAGER_AUTHORITY_KINDS)[number];
39
+ export type ReleaseManagerAuthorityReason = 'metadata_source_unconfigured' | 'bootstrap_not_installed' | 'install_state_corrupt' | 'journal_not_supported' | 'rollback_not_available';
40
+ export interface ReleaseManagerAuthorityReadiness {
41
+ readonly ready: boolean;
42
+ readonly reasons: readonly ReleaseManagerAuthorityReason[];
43
+ }
44
+ export interface ReleaseManagerAuthorityOptions {
45
+ readonly pdHome: string;
46
+ /** Signed release metadata repository base URL; absent ⇒ not ready (no guessing). */
47
+ readonly metadataBaseUrl: string | undefined;
48
+ readonly openclawHome?: string;
49
+ readonly now?: () => Date;
50
+ /** Legacy-updater decision source for the shadow comparison (console-computed). */
51
+ readonly legacyCheck?: (currentVersion: string) => Promise<LegacyUpdaterDecision | null>;
52
+ }
53
+ export interface ReleaseManagerAuthority {
54
+ readonly manager: ReleaseManager;
55
+ /** Install status snapshot; null when the install state failed a strict reader. */
56
+ readonly installStatus: InstallStatus | null;
57
+ readonly kinds: Readonly<Record<ReleaseManagerAuthorityKind, ReleaseManagerAuthorityReadiness>>;
58
+ }
59
+ export declare function createReleaseManagerAuthority(options: ReleaseManagerAuthorityOptions): ReleaseManagerAuthority;
60
+ /**
61
+ * Map a ReleaseManager refusal onto the console's explicit-fallback reason
62
+ * vocabulary (rc-9: degradation must be observable with a stable reason).
63
+ */
64
+ export declare function mapReleaseManagerErrorToFallback(error: unknown): {
65
+ reason: string;
66
+ message: string;
67
+ nextAction: string | null;
68
+ };
69
+ //# sourceMappingURL=release-manager-authority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-manager-authority.d.ts","sourceRoot":"","sources":["../../src/update/release-manager-authority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EACL,cAAc,EAEd,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAC;AAG9B,+EAA+E;AAC/E,eAAO,MAAM,+BAA+B,YAAI,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,CAAU,CAAC;AACrG,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3F,MAAM,MAAM,6BAA6B,GACrC,8BAA8B,GAC9B,yBAAyB,GACzB,uBAAuB,GACvB,uBAAuB,GACvB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,6BAA6B,EAAE,CAAC;CAC5D;AAKD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qFAAqF;IACrF,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,2BAA2B,EAAE,gCAAgC,CAAC,CAAC,CAAC;CACjG;AAkBD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,uBAAuB,CAuDzB;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CASA"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * ReleaseManager mutation authority surface (PRI-672 — the "PRI-661" adoption task).
3
+ *
4
+ * This module is the narrow seam between the Console's MutationController
5
+ * (PRI-659 migration boundary) and the ReleaseManager deep module. It exposes:
6
+ *
7
+ * - `createReleaseManagerAuthority()` — constructs the ReleaseManager for a
8
+ * pdHome and reports per-mutation-kind readiness with stable, structured
9
+ * reason codes (ADR-0024 §2.4: refusal over silent degradation);
10
+ * - `mapReleaseManagerErrorToFallback()` — maps ReleaseManager refusals onto
11
+ * the explicit-fallback reason vocabulary the console surfaces in the
12
+ * `X-PD-Mutation-Fallback-Reason` response header.
13
+ *
14
+ * Boundary (ADR-0024 §2.1): the authority module DECIDES; it never deploys.
15
+ * Artifact deployment stays with the installer; the transaction journal stays
16
+ * the single source of truth for runtime mutations. Readiness probing performs
17
+ * zero filesystem writes. The governed shadow check (kind `check`) refreshes
18
+ * only ReleaseManager-owned verified-metadata caches under `~/.pd/trust` and
19
+ * `~/.pd/channels` — never `~/.pd/runtime`, never the extension directory.
20
+ *
21
+ * Journal readiness semantics: `journal_not_supported` gates MUTATION kinds as
22
+ * a hard precondition (ADR-0024 D-2 — an unjournaled runtime mutation must be
23
+ * refused, never degraded to). It is reported for `check` only as a
24
+ * conservative coupling — on a dual-slot install, a corrupt active.json is
25
+ * recovered FROM the journal, so a check that cannot trust journal-recoverable
26
+ * state must not claim readiness. Relaxing it for `check` alone is a Phase 4
27
+ * decision that must stay explicit (see the analysis doc §4.3); it can never
28
+ * be relaxed for apply/apply-full/rollback.
29
+ *
30
+ * apply/apply-full/rollback stay structurally not-ready until the Phase 4
31
+ * activation rollout opens the `shadow_mode_read_only` gate (its own go/no-go);
32
+ * until then these kinds explicitly fall back to the legacy console updater —
33
+ * TEMPORARY migration debt per ADR-0024 D-1, not a supported long-term state.
34
+ */
35
+ import * as fs from 'node:fs';
36
+ import { ReleaseManager, ReleaseManagerError, } from './release-manager.js';
37
+ import { InstallLayoutError, resolvePdHomePaths } from './install-layout.js';
38
+ /** Mutation kinds the console MutationController routes (PRI-659 contract). */
39
+ export const RELEASE_MANAGER_AUTHORITY_KINDS = ['check', 'apply', 'apply-full', 'rollback'];
40
+ /** Structural gate: activation/rollback arrive with the Phase 4 transaction rollout. */
41
+ const ACTIVATION_AVAILABLE = false;
42
+ /**
43
+ * Probe the transactions directory WITHOUT writing: an existing directory must
44
+ * be writable (the journal is a mandatory mutation contract, ADR-0024 D-2), a
45
+ * missing directory means the installer has not journaled on this installation
46
+ * yet — reported, never created from here.
47
+ */
48
+ function probeTransactionJournalDir(pdHome) {
49
+ const { transactionsDir } = resolvePdHomePaths(pdHome);
50
+ try {
51
+ fs.accessSync(transactionsDir, fs.constants.R_OK | fs.constants.W_OK);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ export function createReleaseManagerAuthority(options) {
59
+ const reasons = new Set();
60
+ if (options.metadataBaseUrl === undefined || options.metadataBaseUrl.length === 0) {
61
+ reasons.add('metadata_source_unconfigured');
62
+ }
63
+ const manager = new ReleaseManager({
64
+ pdHome: options.pdHome,
65
+ metadataBaseUrl: options.metadataBaseUrl ?? '',
66
+ ...(options.openclawHome !== undefined ? { openclawHome: options.openclawHome } : {}),
67
+ ...(options.now !== undefined ? { now: options.now } : {}),
68
+ ...(options.legacyCheck !== undefined ? { legacyCheck: options.legacyCheck } : {}),
69
+ });
70
+ let installStatus = null;
71
+ try {
72
+ installStatus = manager.inspect();
73
+ }
74
+ catch (error) {
75
+ // rc-3: corrupt installation state is surfaced, never silently skipped.
76
+ if (error instanceof InstallLayoutError || error instanceof ReleaseManagerError) {
77
+ reasons.add('install_state_corrupt');
78
+ }
79
+ else {
80
+ throw error;
81
+ }
82
+ }
83
+ if (installStatus !== null && installStatus.layout === 'none') {
84
+ reasons.add('bootstrap_not_installed');
85
+ }
86
+ if (!probeTransactionJournalDir(options.pdHome)) {
87
+ reasons.add('journal_not_supported');
88
+ }
89
+ const baseReady = reasons.size === 0;
90
+ const baseReasons = [...reasons];
91
+ const kinds = {
92
+ check: {
93
+ ready: baseReady,
94
+ reasons: baseReasons,
95
+ },
96
+ apply: {
97
+ ready: false,
98
+ reasons: ACTIVATION_AVAILABLE ? baseReasons : [...baseReasons, 'rollback_not_available'],
99
+ },
100
+ 'apply-full': {
101
+ ready: false,
102
+ reasons: ACTIVATION_AVAILABLE ? baseReasons : [...baseReasons, 'rollback_not_available'],
103
+ },
104
+ rollback: {
105
+ ready: false,
106
+ reasons: ACTIVATION_AVAILABLE ? baseReasons : [...baseReasons, 'rollback_not_available'],
107
+ },
108
+ };
109
+ return { manager, installStatus, kinds };
110
+ }
111
+ /**
112
+ * Map a ReleaseManager refusal onto the console's explicit-fallback reason
113
+ * vocabulary (rc-9: degradation must be observable with a stable reason).
114
+ */
115
+ export function mapReleaseManagerErrorToFallback(error) {
116
+ if (error instanceof ReleaseManagerError) {
117
+ return { reason: error.reason, message: error.message, nextAction: error.nextAction };
118
+ }
119
+ return {
120
+ reason: 'release_manager_check_failed',
121
+ message: error instanceof Error ? error.message : String(error),
122
+ nextAction: null,
123
+ };
124
+ }
125
+ //# sourceMappingURL=release-manager-authority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-manager-authority.js","sourceRoot":"","sources":["../../src/update/release-manager-authority.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * ReleaseManager — the deep module behind every update surface (SPEC §6.2).
3
+ *
4
+ * External surface is intentionally small: inspect / check / apply /
5
+ * rollback. The module hides metadata validation, download, extraction,
6
+ * staging, probes, journaling, host control, rollback, and cleanup. In this
7
+ * phase (shadow mode) apply/rollback refuse read-only: activation lands with
8
+ * the transaction state machine, never by loosening this gate.
9
+ *
10
+ * Every refusal carries a stable reason and an Owner-visible next action
11
+ * (rc-9) and is computed BEFORE any installation state is mutated.
12
+ */
13
+ import { resolveTrustedReleaseTarget, type TrustedReleaseTarget } from './trust-metadata.js';
14
+ import { buildReleaseMetadata } from './release-metadata.js';
15
+ import { type ReleasePolicyDecision } from './release-policy.js';
16
+ import type { ReleaseChannelName } from './product-identity.js';
17
+ export type ReleaseManagerReason = 'shadow_mode_read_only' | 'bootstrap_not_installed' | 'metadata_refresh_failed' | 'release_metadata_unavailable' | 'release_metadata_invalid' | 'active_record_corrupt';
18
+ export declare class ReleaseManagerError extends Error {
19
+ readonly reason: ReleaseManagerReason;
20
+ readonly nextAction: string;
21
+ constructor(reason: ReleaseManagerReason, message: string, nextAction: string);
22
+ }
23
+ export type InstallationLayout = 'dual-slot' | 'legacy-overlay' | 'none';
24
+ export interface InstallStatus {
25
+ readonly layout: InstallationLayout;
26
+ readonly productVersion: string | null;
27
+ readonly releaseId: string | null;
28
+ readonly generation: number | null;
29
+ readonly bootstrapVersion: string | null;
30
+ readonly channel: ReleaseChannelName;
31
+ }
32
+ /** What the legacy updater decided for the same question (shadow comparison). */
33
+ export interface LegacyUpdaterDecision {
34
+ readonly source: 'legacy-updater';
35
+ readonly latestVersion: string | null;
36
+ readonly updateAvailable: boolean | null;
37
+ }
38
+ export interface UpdateCheck {
39
+ readonly channel: ReleaseChannelName;
40
+ readonly candidate: {
41
+ readonly productVersion: string;
42
+ readonly releaseId: string;
43
+ readonly publicationSequence: number;
44
+ readonly assets: readonly {
45
+ platform: string;
46
+ arch: string;
47
+ nodeAbi: string;
48
+ }[];
49
+ } | null;
50
+ readonly decision: ReleasePolicyDecision;
51
+ readonly trustedTarget: TrustedReleaseTarget | null;
52
+ readonly shadowComparison: {
53
+ readonly legacy: LegacyUpdaterDecision | null;
54
+ readonly agrees: boolean | null;
55
+ readonly note: string | null;
56
+ };
57
+ }
58
+ export interface ReleaseManagerOptions {
59
+ readonly pdHome: string;
60
+ readonly metadataBaseUrl: string;
61
+ readonly fetcher?: Parameters<typeof resolveTrustedReleaseTarget>[0]['fetcher'];
62
+ readonly now?: () => Date;
63
+ /** Injected in production from the legacy updater; tests inject fakes. */
64
+ readonly legacyCheck?: (currentVersion: string) => Promise<LegacyUpdaterDecision | null>;
65
+ /**
66
+ * Explicit OpenClaw home directory for legacy-overlay detection. When
67
+ * omitted, falls back to `~/.openclaw` relative to the OS home — correct
68
+ * for standard installs but WRONG for custom pdHome roots (test dirs,
69
+ * enterprise installs, containers). Callers that pass a custom pdHome
70
+ * MUST also pass the matching openclawHome.
71
+ */
72
+ readonly openclawHome?: string;
73
+ }
74
+ /**
75
+ * The signed channel document is fetched from the trusted TUF target
76
+ * `channels/<channel>.json`; its payload is the ChannelMetadata. The release
77
+ * metadata document comes from `releases/<release-id>/metadata.json` —
78
+ * already verified as a trusted target with an exact digest.
79
+ */
80
+ export declare class ReleaseManager {
81
+ private readonly paths;
82
+ private readonly options;
83
+ constructor(options: ReleaseManagerOptions);
84
+ inspect(): InstallStatus;
85
+ check(channel: ReleaseChannelName): Promise<UpdateCheck>;
86
+ apply(): Promise<never>;
87
+ rollback(): Promise<never>;
88
+ private legacyOverlayMarker;
89
+ private readChannelMetadataPayload;
90
+ private readActiveReleaseMetadata;
91
+ private readReleaseMetadataDocument;
92
+ private compareWithLegacyUpdater;
93
+ }
94
+ /** Producer helper re-exported for the publication pipeline. */
95
+ export { buildReleaseMetadata };
96
+ //# sourceMappingURL=release-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-manager.d.ts","sourceRoot":"","sources":["../../src/update/release-manager.ts"],"names":[],"mappings":"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"}