agl 1.0.17 → 21.0.2

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 (277) hide show
  1. package/.smartconfig.json +55 -0
  2. package/changelog.md +1026 -0
  3. package/cli.js +14 -0
  4. package/dist_serve/bundle.js +44778 -0
  5. package/dist_serve/index.html +13 -0
  6. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  7. package/dist_ts/00_commitinfo_data.js +9 -0
  8. package/dist_ts/classes.authmodels.d.ts +126 -0
  9. package/dist_ts/classes.authmodels.js +1422 -0
  10. package/dist_ts/classes.authstore.d.ts +160 -0
  11. package/dist_ts/classes.authstore.js +2483 -0
  12. package/dist_ts/classes.browserresourcehost.d.ts +85 -0
  13. package/dist_ts/classes.browserresourcehost.js +912 -0
  14. package/dist_ts/classes.cli.d.ts +21 -0
  15. package/dist_ts/classes.cli.js +1082 -0
  16. package/dist_ts/classes.config.d.ts +23 -0
  17. package/dist_ts/classes.config.js +267 -0
  18. package/dist_ts/classes.controller.d.ts +523 -0
  19. package/dist_ts/classes.controller.js +10611 -0
  20. package/dist_ts/classes.controllermanagement.d.ts +32 -0
  21. package/dist_ts/classes.controllermanagement.js +222 -0
  22. package/dist_ts/classes.draftmanager.d.ts +30 -0
  23. package/dist_ts/classes.draftmanager.js +179 -0
  24. package/dist_ts/classes.embeddeddb.d.ts +30 -0
  25. package/dist_ts/classes.embeddeddb.js +159 -0
  26. package/dist_ts/classes.flexframedtransport.d.ts +56 -0
  27. package/dist_ts/classes.flexframedtransport.js +275 -0
  28. package/dist_ts/classes.flexmodels.private.d.ts +231 -0
  29. package/dist_ts/classes.flexmodels.private.js +985 -0
  30. package/dist_ts/classes.flexmodels.public.d.ts +207 -0
  31. package/dist_ts/classes.flexmodels.public.js +885 -0
  32. package/dist_ts/classes.flexprojectionreader.d.ts +89 -0
  33. package/dist_ts/classes.flexprojectionreader.js +580 -0
  34. package/dist_ts/classes.flexservice.d.ts +196 -0
  35. package/dist_ts/classes.flexservice.js +3704 -0
  36. package/dist_ts/classes.flexstore.d.ts +174 -0
  37. package/dist_ts/classes.flexstore.js +3400 -0
  38. package/dist_ts/classes.flexsupervisor.d.ts +105 -0
  39. package/dist_ts/classes.flexsupervisor.js +1191 -0
  40. package/dist_ts/classes.gitreversion.d.ts +431 -0
  41. package/dist_ts/classes.gitreversion.js +10592 -0
  42. package/dist_ts/classes.harnessoperationmanager.d.ts +113 -0
  43. package/dist_ts/classes.harnessoperationmanager.js +602 -0
  44. package/dist_ts/classes.opencodeclient.d.ts +146 -0
  45. package/dist_ts/classes.opencodeclient.js +3003 -0
  46. package/dist_ts/classes.opencodesupervisor.d.ts +60 -0
  47. package/dist_ts/classes.opencodesupervisor.js +1003 -0
  48. package/dist_ts/classes.passkeymanager.d.ts +34 -0
  49. package/dist_ts/classes.passkeymanager.js +456 -0
  50. package/dist_ts/classes.processinspection.d.ts +50 -0
  51. package/dist_ts/classes.processinspection.js +484 -0
  52. package/dist_ts/classes.resourcecoordinator.d.ts +64 -0
  53. package/dist_ts/classes.resourcecoordinator.js +294 -0
  54. package/dist_ts/classes.sessionintelligencereader.d.ts +13 -0
  55. package/dist_ts/classes.sessionintelligencereader.js +40 -0
  56. package/dist_ts/classes.systemmetricssampler.d.ts +53 -0
  57. package/dist_ts/classes.systemmetricssampler.js +168 -0
  58. package/dist_ts/classes.terminalmanager.d.ts +95 -0
  59. package/dist_ts/classes.terminalmanager.js +981 -0
  60. package/dist_ts/classes.terminalresourcehost.d.ts +20 -0
  61. package/dist_ts/classes.terminalresourcehost.js +84 -0
  62. package/dist_ts/classes.upgradecoordinator.d.ts +244 -0
  63. package/dist_ts/classes.upgradecoordinator.js +2155 -0
  64. package/dist_ts/classes.upgradetransaction.d.ts +92 -0
  65. package/dist_ts/classes.upgradetransaction.js +2125 -0
  66. package/dist_ts/classes.uploadmanager.d.ts +24 -0
  67. package/dist_ts/classes.uploadmanager.js +210 -0
  68. package/dist_ts/classes.validation.d.ts +91 -0
  69. package/dist_ts/classes.validation.js +1087 -0
  70. package/dist_ts/flexharness.child.d.ts +1 -0
  71. package/dist_ts/flexharness.child.js +28 -0
  72. package/dist_ts/functions.canonicaldirectory.d.ts +21 -0
  73. package/dist_ts/functions.canonicaldirectory.js +144 -0
  74. package/dist_ts/functions.controllerdataroot.d.ts +15 -0
  75. package/dist_ts/functions.controllerdataroot.js +76 -0
  76. package/dist_ts/functions.embeddeddb.d.ts +2 -0
  77. package/dist_ts/functions.embeddeddb.js +21 -0
  78. package/dist_ts/functions.flexcredentialstore.d.ts +16 -0
  79. package/dist_ts/functions.flexcredentialstore.js +93 -0
  80. package/dist_ts/functions.opencodeauth.d.ts +3 -0
  81. package/dist_ts/functions.opencodeauth.js +31 -0
  82. package/dist_ts/functions.runtimeenvironment.d.ts +2 -0
  83. package/dist_ts/functions.runtimeenvironment.js +79 -0
  84. package/dist_ts/functions.upgradefollower.d.ts +3 -0
  85. package/dist_ts/functions.upgradefollower.js +95 -0
  86. package/dist_ts/index.d.ts +24 -0
  87. package/dist_ts/index.js +25 -0
  88. package/dist_ts/interfaces.auth.d.ts +181 -0
  89. package/dist_ts/interfaces.auth.js +82 -0
  90. package/dist_ts/interfaces.config.d.ts +34 -0
  91. package/dist_ts/interfaces.config.js +2 -0
  92. package/dist_ts/interfaces.flexipc.d.ts +939 -0
  93. package/dist_ts/interfaces.flexipc.js +1492 -0
  94. package/dist_ts/interfaces.gitreversion.d.ts +246 -0
  95. package/dist_ts/interfaces.gitreversion.js +2 -0
  96. package/dist_ts/interfaces.lifecycle.d.ts +37 -0
  97. package/dist_ts/interfaces.lifecycle.js +2 -0
  98. package/dist_ts/interfaces.opencode.d.ts +101 -0
  99. package/dist_ts/interfaces.opencode.js +3 -0
  100. package/dist_ts/interfaces.projects.d.ts +156 -0
  101. package/dist_ts/interfaces.projects.js +5 -0
  102. package/dist_ts/plugins.d.ts +36 -0
  103. package/dist_ts/plugins.js +40 -0
  104. package/dist_ts_interfaces/index.d.ts +2 -0
  105. package/dist_ts_interfaces/index.js +3 -0
  106. package/dist_ts_interfaces/interfaces.d.ts +747 -0
  107. package/dist_ts_interfaces/interfaces.js +47 -0
  108. package/dist_ts_interfaces/plugins.d.ts +4 -0
  109. package/dist_ts_interfaces/plugins.js +3 -0
  110. package/dist_ts_interfaces/requests.d.ts +806 -0
  111. package/dist_ts_interfaces/requests.js +2 -0
  112. package/dist_ts_migration/classes.documentmigrationrunner.d.ts +8 -0
  113. package/dist_ts_migration/classes.documentmigrationrunner.js +24 -0
  114. package/dist_ts_migration/classes.flexmigrationrunner.d.ts +11 -0
  115. package/dist_ts_migration/classes.flexmigrationrunner.js +25 -0
  116. package/dist_ts_migration/classes.flexpostharnessmigrationrunner.d.ts +10 -0
  117. package/dist_ts_migration/classes.flexpostharnessmigrationrunner.js +15 -0
  118. package/dist_ts_migration/classes.migrationrunner.d.ts +8 -0
  119. package/dist_ts_migration/classes.migrationrunner.js +34 -0
  120. package/dist_ts_migration/index.d.ts +12 -0
  121. package/dist_ts_migration/index.js +13 -0
  122. package/dist_ts_migration/v10_flexharnessv3migration.d.ts +11 -0
  123. package/dist_ts_migration/v10_flexharnessv3migration.js +23 -0
  124. package/dist_ts_migration/v13_flexprojectionorder.d.ts +11 -0
  125. package/dist_ts_migration/v13_flexprojectionorder.js +23 -0
  126. package/dist_ts_migration/v16_flexprovidercredentials.d.ts +22 -0
  127. package/dist_ts_migration/v16_flexprovidercredentials.js +149 -0
  128. package/dist_ts_migration/v18_resourcelayout.d.ts +22 -0
  129. package/dist_ts_migration/v18_resourcelayout.js +23 -0
  130. package/dist_ts_migration/v18_resourcelayoutmigration.d.ts +6 -0
  131. package/dist_ts_migration/v18_resourcelayoutmigration.js +61 -0
  132. package/dist_ts_migration/v19_flexprojectmanagement.d.ts +11 -0
  133. package/dist_ts_migration/v19_flexprojectmanagement.js +21 -0
  134. package/dist_ts_migration/v1_embeddeddatabaselocation.d.ts +28 -0
  135. package/dist_ts_migration/v1_embeddeddatabaselocation.js +415 -0
  136. package/dist_ts_migration/v22_projectfilesystemidentitymigration.d.ts +7 -0
  137. package/dist_ts_migration/v22_projectfilesystemidentitymigration.js +105 -0
  138. package/dist_ts_migration/v2_controllerdataroot.d.ts +130 -0
  139. package/dist_ts_migration/v2_controllerdataroot.js +1887 -0
  140. package/dist_ts_migration/v6_protocoldocumentmigration.d.ts +7 -0
  141. package/dist_ts_migration/v6_protocoldocumentmigration.js +100 -0
  142. package/dist_ts_migration/v6_protocoldocuments.d.ts +7 -0
  143. package/dist_ts_migration/v6_protocoldocuments.js +138 -0
  144. package/html/index.html +13 -0
  145. package/{LICENSE → license.md} +2 -2
  146. package/package.json +86 -48
  147. package/readme.md +480 -0
  148. package/readme.plan.md +188 -0
  149. package/ts/00_commitinfo_data.ts +8 -0
  150. package/ts/classes.authmodels.ts +1245 -0
  151. package/ts/classes.authstore.ts +3274 -0
  152. package/ts/classes.browserresourcehost.ts +1205 -0
  153. package/ts/classes.cli.ts +1254 -0
  154. package/ts/classes.config.ts +351 -0
  155. package/ts/classes.controller.ts +14426 -0
  156. package/ts/classes.controllermanagement.ts +330 -0
  157. package/ts/classes.draftmanager.ts +232 -0
  158. package/ts/classes.embeddeddb.ts +166 -0
  159. package/ts/classes.flexframedtransport.ts +283 -0
  160. package/ts/classes.flexmodels.private.ts +823 -0
  161. package/ts/classes.flexmodels.public.ts +732 -0
  162. package/ts/classes.flexprojectionreader.ts +816 -0
  163. package/ts/classes.flexservice.ts +4302 -0
  164. package/ts/classes.flexstore.ts +4565 -0
  165. package/ts/classes.flexsupervisor.ts +1453 -0
  166. package/ts/classes.gitreversion.ts +13353 -0
  167. package/ts/classes.harnessoperationmanager.ts +870 -0
  168. package/ts/classes.opencodeclient.ts +4110 -0
  169. package/ts/classes.opencodesupervisor.ts +1280 -0
  170. package/ts/classes.passkeymanager.ts +570 -0
  171. package/ts/classes.processinspection.ts +623 -0
  172. package/ts/classes.resourcecoordinator.ts +436 -0
  173. package/ts/classes.sessionintelligencereader.ts +52 -0
  174. package/ts/classes.systemmetricssampler.ts +215 -0
  175. package/ts/classes.terminalmanager.ts +1207 -0
  176. package/ts/classes.terminalresourcehost.ts +122 -0
  177. package/ts/classes.upgradecoordinator.ts +2675 -0
  178. package/ts/classes.upgradetransaction.ts +2900 -0
  179. package/ts/classes.uploadmanager.ts +240 -0
  180. package/ts/classes.validation.ts +1409 -0
  181. package/ts/flexharness.child.ts +35 -0
  182. package/ts/functions.canonicaldirectory.ts +213 -0
  183. package/ts/functions.controllerdataroot.ts +107 -0
  184. package/ts/functions.embeddeddb.ts +22 -0
  185. package/ts/functions.flexcredentialstore.ts +128 -0
  186. package/ts/functions.opencodeauth.ts +34 -0
  187. package/ts/functions.runtimeenvironment.ts +90 -0
  188. package/ts/functions.upgradefollower.ts +115 -0
  189. package/ts/index.ts +36 -6
  190. package/ts/interfaces.auth.ts +316 -0
  191. package/ts/interfaces.config.ts +37 -0
  192. package/ts/interfaces.flexipc.ts +2586 -0
  193. package/ts/interfaces.gitreversion.ts +336 -0
  194. package/ts/interfaces.lifecycle.ts +46 -0
  195. package/ts/interfaces.opencode.ts +153 -0
  196. package/ts/interfaces.projects.ts +182 -0
  197. package/ts/plugins.ts +64 -0
  198. package/ts_interfaces/index.ts +2 -0
  199. package/ts_interfaces/interfaces.ts +827 -0
  200. package/ts_interfaces/plugins.ts +15 -0
  201. package/ts_interfaces/requests.ts +1186 -0
  202. package/ts_migration/classes.documentmigrationrunner.ts +32 -0
  203. package/ts_migration/classes.flexmigrationrunner.ts +33 -0
  204. package/ts_migration/classes.flexpostharnessmigrationrunner.ts +22 -0
  205. package/ts_migration/classes.migrationrunner.ts +40 -0
  206. package/ts_migration/index.ts +12 -0
  207. package/ts_migration/v10_flexharnessv3migration.ts +35 -0
  208. package/ts_migration/v13_flexprojectionorder.ts +33 -0
  209. package/ts_migration/v16_flexprovidercredentials.ts +196 -0
  210. package/ts_migration/v18_resourcelayout.ts +55 -0
  211. package/ts_migration/v18_resourcelayoutmigration.ts +68 -0
  212. package/ts_migration/v19_flexprojectmanagement.ts +28 -0
  213. package/ts_migration/v1_embeddeddatabaselocation.ts +560 -0
  214. package/ts_migration/v22_projectfilesystemidentitymigration.ts +121 -0
  215. package/ts_migration/v2_controllerdataroot.ts +2349 -0
  216. package/ts_migration/v6_protocoldocumentmigration.ts +144 -0
  217. package/ts_migration/v6_protocoldocuments.ts +198 -0
  218. package/ts_web/00_commitinfo_data.ts +8 -0
  219. package/ts_web/classes.controllersocketclient.ts +517 -0
  220. package/ts_web/classes.sessiondraftsync.ts +390 -0
  221. package/ts_web/elements.harnesscontrollerapp.ts +11494 -0
  222. package/ts_web/index.ts +2 -0
  223. package/ts_web/plugins.ts +31 -0
  224. package/.gitlab-ci.yml +0 -71
  225. package/.npmignore +0 -5
  226. package/README.md +0 -40
  227. package/dist/cli.js +0 -2
  228. package/dist/index.d.ts +0 -0
  229. package/dist/index.js +0 -9
  230. package/dist/mod_bundle/index.d.ts +0 -1
  231. package/dist/mod_bundle/index.js +0 -18
  232. package/dist/mod_bundle/mod.plugins.d.ts +0 -4
  233. package/dist/mod_bundle/mod.plugins.js +0 -11
  234. package/dist/mod_install/index.d.ts +0 -4
  235. package/dist/mod_install/index.js +0 -21
  236. package/dist/mod_install/mod.plugins.d.ts +0 -1
  237. package/dist/mod_install/mod.plugins.js +0 -7
  238. package/dist/mod_standard/index.d.ts +0 -4
  239. package/dist/mod_standard/index.js +0 -21
  240. package/dist/mod_standard/mod.browser.d.ts +0 -6
  241. package/dist/mod_standard/mod.browser.js +0 -14
  242. package/dist/mod_standard/mod.clean.d.ts +0 -4
  243. package/dist/mod_standard/mod.clean.js +0 -12
  244. package/dist/mod_standard/mod.compile.d.ts +0 -4
  245. package/dist/mod_standard/mod.compile.js +0 -21
  246. package/dist/mod_standard/mod.plugins.d.ts +0 -8
  247. package/dist/mod_standard/mod.plugins.js +0 -19
  248. package/dist/mod_standard/mod.test.d.ts +0 -4
  249. package/dist/mod_standard/mod.test.js +0 -12
  250. package/dist/plr.cli.d.ts +0 -3
  251. package/dist/plr.cli.js +0 -57
  252. package/dist/plr.config.d.ts +0 -11
  253. package/dist/plr.config.js +0 -26
  254. package/dist/plr.mods.d.ts +0 -17
  255. package/dist/plr.mods.js +0 -17
  256. package/dist/plr.paths.d.ts +0 -19
  257. package/dist/plr.paths.js +0 -26
  258. package/dist/plr.plugins.d.ts +0 -8
  259. package/dist/plr.plugins.js +0 -16
  260. package/npmextra.json +0 -10
  261. package/ts/mod_bundle/index.ts +0 -20
  262. package/ts/mod_bundle/mod.plugins.ts +0 -9
  263. package/ts/mod_install/index.ts +0 -20
  264. package/ts/mod_install/mod.plugins.ts +0 -1
  265. package/ts/mod_standard/index.ts +0 -23
  266. package/ts/mod_standard/mod.browser.ts +0 -17
  267. package/ts/mod_standard/mod.clean.ts +0 -13
  268. package/ts/mod_standard/mod.compile.ts +0 -23
  269. package/ts/mod_standard/mod.plugins.ts +0 -17
  270. package/ts/mod_standard/mod.test.ts +0 -13
  271. package/ts/plr.cli.ts +0 -60
  272. package/ts/plr.config.ts +0 -36
  273. package/ts/plr.mods.ts +0 -25
  274. package/ts/plr.paths.ts +0 -29
  275. package/ts/plr.plugins.ts +0 -17
  276. package/tslint.json +0 -3
  277. package/yarn.lock +0 -3464
@@ -0,0 +1,1887 @@
1
+ import * as plugins from '../dist_ts/plugins.js';
2
+ import { readControllerProcessIdentity, } from '../dist_ts/classes.processinspection.js';
3
+ import { embeddedDatabaseSocketPath, isSocketListening as defaultIsSocketListening, } from '../dist_ts/functions.embeddeddb.js';
4
+ import { EmbeddedDatabaseLocationMigration, rebaseCompletedEmbeddedDatabaseLocationMigration, } from './v1_embeddeddatabaselocation.js';
5
+ import { flexProviderCredentialStoreId } from './v16_flexprovidercredentials.js';
6
+ const migrationVersion = 2;
7
+ const journalFileName = '.hcon-controller-data-root-migration.json';
8
+ const lockFileName = '.hcon-controller-data-root-migration.lock';
9
+ const markerFileName = '.hcon-controller-data-root-marker.json';
10
+ const embeddedDatabaseJournalFileName = '.smartdb-location-migration.json';
11
+ const maximumJournalBytes = 512 * 1024;
12
+ const maximumLockBytes = 16 * 1024;
13
+ const maximumMarkerBytes = 4 * 1024;
14
+ const maximumSmartDbRelocationReceiptBytes = 16 * 1024;
15
+ const maximumRootEntries = 2_048;
16
+ const maximumCredentialStores = 512;
17
+ const maximumMigrationTemporaryFiles = 32;
18
+ const maximumControllerLogs = 256;
19
+ const maximumUpgradeLogs = 64;
20
+ const maximumLockArtifacts = 64;
21
+ const maximumLockAttempts = 200;
22
+ const lockWaitMilliseconds = 50;
23
+ const credentialHashPattern = /^[a-f0-9]{64}$/;
24
+ const digestPattern = /^[a-f0-9]{64}$/;
25
+ const noncePattern = /^[a-f0-9]{64}$/;
26
+ const decimalPattern = /^(0|[1-9][0-9]*)$/;
27
+ const controllerLogPattern = /^controller-([1-9][0-9]{0,4})\.log(?:\.old)?$/;
28
+ const upgradeLogPattern = /^upgrade-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}\.[0-9]{3}Z-[A-Za-z0-9_-]{10}\.log$/;
29
+ const embeddedDatabaseJournalTemporaryPattern = /^\.smartdb-location-migration\.json\.[1-9][0-9]*-[a-f0-9]{16}\.tmp$/;
30
+ const currentUid = () => {
31
+ if (typeof process.getuid !== 'function') {
32
+ throw new Error('Controller data-root migration requires a POSIX user identity.');
33
+ }
34
+ return process.getuid();
35
+ };
36
+ const isMissingError = (errorArg) => errorArg.code === 'ENOENT';
37
+ const pathIdentity = (statsArg) => ({
38
+ device: statsArg.dev.toString(10),
39
+ inode: statsArg.ino.toString(10),
40
+ });
41
+ const identitiesEqual = (leftArg, rightArg) => leftArg.device === rightArg.device && leftArg.inode === rightArg.inode;
42
+ const assertAbsoluteNormalizedPath = (pathArg, labelArg) => {
43
+ if (typeof pathArg !== 'string'
44
+ || !plugins.path.isAbsolute(pathArg)
45
+ || plugins.path.resolve(pathArg) !== pathArg
46
+ || pathArg === plugins.path.parse(pathArg).root) {
47
+ throw new Error(`${labelArg} must be a normalized absolute non-root path.`);
48
+ }
49
+ return pathArg;
50
+ };
51
+ const assertPlainRecord = (valueArg, labelArg) => {
52
+ if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg)) {
53
+ throw new Error(`${labelArg} is malformed.`);
54
+ }
55
+ const prototype = Object.getPrototypeOf(valueArg);
56
+ if (prototype !== Object.prototype && prototype !== null) {
57
+ throw new Error(`${labelArg} is malformed.`);
58
+ }
59
+ return valueArg;
60
+ };
61
+ const assertExactKeys = (valueArg, expectedArg, labelArg) => {
62
+ const actual = Object.keys(valueArg).sort();
63
+ const expected = [...expectedArg].sort();
64
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
65
+ throw new Error(`${labelArg} has unexpected fields.`);
66
+ }
67
+ };
68
+ const requireString = (valueArg, labelArg, maximumBytesArg = 16 * 1024) => {
69
+ if (typeof valueArg !== 'string'
70
+ || valueArg.length === 0
71
+ || Buffer.byteLength(valueArg, 'utf8') > maximumBytesArg)
72
+ throw new Error(`${labelArg} is invalid.`);
73
+ return valueArg;
74
+ };
75
+ const requireNullableString = (valueArg, labelArg) => valueArg === null ? null : requireString(valueArg, labelArg);
76
+ const requireNullableDecimal = (valueArg, labelArg) => {
77
+ const value = requireNullableString(valueArg, labelArg);
78
+ if (value !== null && !decimalPattern.test(value))
79
+ throw new Error(`${labelArg} is invalid.`);
80
+ return value;
81
+ };
82
+ const assertNullableIdentityPair = (deviceArg, inodeArg, labelArg) => {
83
+ if ((deviceArg === null) !== (inodeArg === null)) {
84
+ throw new Error(`${labelArg} identity is incomplete.`);
85
+ }
86
+ };
87
+ const parseCredentialTuple = (valueArg) => {
88
+ const value = assertPlainRecord(valueArg, 'Controller credential migration tuple');
89
+ assertExactKeys(value, [
90
+ 'controllerHash',
91
+ 'service',
92
+ 'storeId',
93
+ 'sourceDirectory',
94
+ 'destinationDirectory',
95
+ 'complete',
96
+ ], 'Controller credential migration tuple');
97
+ const controllerHash = requireString(value.controllerHash, 'Controller credential hash', 64);
98
+ if (!credentialHashPattern.test(controllerHash)) {
99
+ throw new Error('Controller credential hash is invalid.');
100
+ }
101
+ if (typeof value.complete !== 'boolean') {
102
+ throw new Error('Controller credential completion state is invalid.');
103
+ }
104
+ return {
105
+ controllerHash,
106
+ service: requireString(value.service, 'Controller credential service', 200),
107
+ storeId: requireString(value.storeId, 'Controller credential store ID', 200),
108
+ sourceDirectory: requireString(value.sourceDirectory, 'Controller credential source path'),
109
+ destinationDirectory: requireString(value.destinationDirectory, 'Controller credential destination path'),
110
+ complete: value.complete,
111
+ };
112
+ };
113
+ const parseDatabaseJournal = (valueArg) => {
114
+ const value = assertPlainRecord(valueArg, 'Controller database root migration journal');
115
+ assertExactKeys(value, [
116
+ 'mode',
117
+ 'strategy',
118
+ 'phase',
119
+ 'configurationDigestSha256',
120
+ 'oldDirectory',
121
+ 'targetDirectory',
122
+ 'historicalDirectory',
123
+ 'sourcePath',
124
+ 'sourceDevice',
125
+ 'sourceInode',
126
+ 'destinationDevice',
127
+ 'destinationInode',
128
+ 'contentDigestSha256',
129
+ 'v1JournalLocation',
130
+ ], 'Controller database root migration journal');
131
+ if (value.mode !== 'external' && value.mode !== 'override' && value.mode !== 'default') {
132
+ throw new Error('Controller database migration mode is invalid.');
133
+ }
134
+ if (value.strategy !== 'unchanged'
135
+ && value.strategy !== 'fresh'
136
+ && value.strategy !== 'historical-direct'
137
+ && value.strategy !== 'old-relocation')
138
+ throw new Error('Controller database migration strategy is invalid.');
139
+ if (value.phase !== 'pending'
140
+ && value.phase !== 'prepared'
141
+ && value.phase !== 'moved'
142
+ && value.phase !== 'verified')
143
+ throw new Error('Controller database migration phase is invalid.');
144
+ if (value.v1JournalLocation !== 'none'
145
+ && value.v1JournalLocation !== 'legacy'
146
+ && value.v1JournalLocation !== 'target')
147
+ throw new Error('Controller database v1 journal location is invalid.');
148
+ const configurationDigestSha256 = requireString(value.configurationDigestSha256, 'Controller database configuration digest', 64);
149
+ if (!digestPattern.test(configurationDigestSha256)) {
150
+ throw new Error('Controller database configuration digest is invalid.');
151
+ }
152
+ const sourceDevice = requireNullableDecimal(value.sourceDevice, 'Controller database source device');
153
+ const sourceInode = requireNullableDecimal(value.sourceInode, 'Controller database source inode');
154
+ const destinationDevice = requireNullableDecimal(value.destinationDevice, 'Controller database destination device');
155
+ const destinationInode = requireNullableDecimal(value.destinationInode, 'Controller database destination inode');
156
+ assertNullableIdentityPair(sourceDevice, sourceInode, 'Controller database source');
157
+ assertNullableIdentityPair(destinationDevice, destinationInode, 'Controller database destination');
158
+ const contentDigestSha256 = requireNullableString(value.contentDigestSha256, 'Controller database content digest');
159
+ if (contentDigestSha256 !== null && !digestPattern.test(contentDigestSha256)) {
160
+ throw new Error('Controller database content digest is invalid.');
161
+ }
162
+ return {
163
+ mode: value.mode,
164
+ strategy: value.strategy,
165
+ phase: value.phase,
166
+ configurationDigestSha256,
167
+ oldDirectory: requireNullableString(value.oldDirectory, 'Controller old database path'),
168
+ targetDirectory: requireNullableString(value.targetDirectory, 'Controller target database path'),
169
+ historicalDirectory: requireNullableString(value.historicalDirectory, 'Controller historical database path'),
170
+ sourcePath: requireNullableString(value.sourcePath, 'Controller database source path'),
171
+ sourceDevice,
172
+ sourceInode,
173
+ destinationDevice,
174
+ destinationInode,
175
+ contentDigestSha256,
176
+ v1JournalLocation: value.v1JournalLocation,
177
+ };
178
+ };
179
+ const parseJournal = (valueArg) => {
180
+ const value = assertPlainRecord(valueArg, 'Controller data-root migration journal');
181
+ assertExactKeys(value, [
182
+ 'version',
183
+ 'phase',
184
+ 'sourcePath',
185
+ 'sourceDevice',
186
+ 'sourceInode',
187
+ 'destinationPath',
188
+ 'destinationDevice',
189
+ 'destinationInode',
190
+ 'targetCreationNonce',
191
+ 'database',
192
+ 'credentials',
193
+ ], 'Controller data-root migration journal');
194
+ if (value.version !== migrationVersion) {
195
+ throw new Error('Controller data-root migration journal version is unsupported.');
196
+ }
197
+ if (value.phase !== 'legacy-authoritative'
198
+ && value.phase !== 'target-staged'
199
+ && value.phase !== 'target-committed')
200
+ throw new Error('Controller data-root migration journal phase is invalid.');
201
+ const sourceDevice = requireNullableDecimal(value.sourceDevice, 'Controller source root device');
202
+ const sourceInode = requireNullableDecimal(value.sourceInode, 'Controller source root inode');
203
+ const destinationDevice = requireNullableDecimal(value.destinationDevice, 'Controller destination root device');
204
+ const destinationInode = requireNullableDecimal(value.destinationInode, 'Controller destination root inode');
205
+ assertNullableIdentityPair(sourceDevice, sourceInode, 'Controller source root');
206
+ assertNullableIdentityPair(destinationDevice, destinationInode, 'Controller destination root');
207
+ const targetCreationNonce = requireString(value.targetCreationNonce, 'Controller target creation nonce', 64);
208
+ if (!noncePattern.test(targetCreationNonce)) {
209
+ throw new Error('Controller target creation nonce is invalid.');
210
+ }
211
+ if (!Array.isArray(value.credentials) || value.credentials.length > maximumCredentialStores) {
212
+ throw new Error('Controller credential migration tuple list is invalid.');
213
+ }
214
+ const credentials = value.credentials.map(parseCredentialTuple);
215
+ return {
216
+ version: migrationVersion,
217
+ phase: value.phase,
218
+ sourcePath: requireString(value.sourcePath, 'Controller source root path'),
219
+ sourceDevice,
220
+ sourceInode,
221
+ destinationPath: requireString(value.destinationPath, 'Controller destination root path'),
222
+ destinationDevice,
223
+ destinationInode,
224
+ targetCreationNonce,
225
+ database: parseDatabaseJournal(value.database),
226
+ credentials,
227
+ };
228
+ };
229
+ const parseMarker = (valueArg) => {
230
+ const value = assertPlainRecord(valueArg, 'Controller target marker');
231
+ assertExactKeys(value, ['version', 'targetCreationNonce'], 'Controller target marker');
232
+ if (value.version !== migrationVersion)
233
+ throw new Error('Controller target marker version is invalid.');
234
+ const targetCreationNonce = requireString(value.targetCreationNonce, 'Controller target marker nonce', 64);
235
+ if (!noncePattern.test(targetCreationNonce))
236
+ throw new Error('Controller target marker nonce is invalid.');
237
+ return { version: migrationVersion, targetCreationNonce };
238
+ };
239
+ const parseLockOwner = (valueArg) => {
240
+ const value = assertPlainRecord(valueArg, 'Controller data-root migration lock owner');
241
+ assertExactKeys(value, [
242
+ 'version',
243
+ 'uid',
244
+ 'pid',
245
+ 'processFingerprint',
246
+ 'nonce',
247
+ ], 'Controller data-root migration lock owner');
248
+ if (value.version !== 1)
249
+ throw new Error('Controller data-root migration lock version is invalid.');
250
+ if (!Number.isSafeInteger(value.uid) || value.uid < 0) {
251
+ throw new Error('Controller data-root migration lock UID is invalid.');
252
+ }
253
+ if (!Number.isSafeInteger(value.pid) || value.pid < 2) {
254
+ throw new Error('Controller data-root migration lock PID is invalid.');
255
+ }
256
+ const processFingerprint = requireString(value.processFingerprint, 'Controller data-root migration lock process fingerprint', 4 * 1024);
257
+ const nonce = requireString(value.nonce, 'Controller data-root migration lock nonce', 64);
258
+ if (!noncePattern.test(nonce))
259
+ throw new Error('Controller data-root migration lock nonce is invalid.');
260
+ return {
261
+ version: 1,
262
+ uid: value.uid,
263
+ pid: value.pid,
264
+ processFingerprint,
265
+ nonce,
266
+ };
267
+ };
268
+ const syncDirectory = async (directoryArg) => {
269
+ const handle = await plugins.fs.promises.open(directoryArg, plugins.fs.constants.O_RDONLY | plugins.fs.constants.O_DIRECTORY);
270
+ try {
271
+ await handle.sync();
272
+ }
273
+ finally {
274
+ await handle.close();
275
+ }
276
+ };
277
+ const readDirectoryIdentity = async (directoryArg, labelArg, exactModeArg) => {
278
+ let handle;
279
+ try {
280
+ handle = await plugins.fs.promises.open(directoryArg, plugins.fs.constants.O_RDONLY
281
+ | plugins.fs.constants.O_DIRECTORY
282
+ | plugins.fs.constants.O_NOFOLLOW);
283
+ }
284
+ catch (errorArg) {
285
+ if (isMissingError(errorArg))
286
+ return undefined;
287
+ throw new Error(`${labelArg} must be a real private directory: ${directoryArg}`, {
288
+ cause: errorArg,
289
+ });
290
+ }
291
+ try {
292
+ const stats = await handle.stat({ bigint: true });
293
+ const mode = Number(stats.mode & 511n);
294
+ if (!stats.isDirectory()
295
+ || stats.uid !== BigInt(currentUid())
296
+ || (exactModeArg === undefined ? (mode & 0o077) !== 0 : mode !== exactModeArg)) {
297
+ throw new Error(`${labelArg} must be a real private directory: ${directoryArg}`);
298
+ }
299
+ return pathIdentity(stats);
300
+ }
301
+ finally {
302
+ await handle.close();
303
+ }
304
+ };
305
+ const inspectPrivateNode = async (pathArg, kindArg, labelArg, exactModeArg) => {
306
+ let stats;
307
+ try {
308
+ stats = await plugins.fs.promises.lstat(pathArg, { bigint: true });
309
+ }
310
+ catch (errorArg) {
311
+ if (isMissingError(errorArg))
312
+ return undefined;
313
+ throw errorArg;
314
+ }
315
+ const mode = Number(stats.mode & 511n);
316
+ const expectedKind = kindArg === 'file' ? stats.isFile() : stats.isDirectory();
317
+ if (!expectedKind
318
+ || stats.isSymbolicLink()
319
+ || stats.uid !== BigInt(currentUid())
320
+ || (exactModeArg === undefined ? (mode & 0o077) !== 0 : mode !== exactModeArg))
321
+ throw new Error(`${labelArg} is unsafe: ${pathArg}`);
322
+ return pathIdentity(stats);
323
+ };
324
+ const readPrivateJson = async (pathArg, maximumBytesArg, parserArg, labelArg, exactModeArg = 0o600) => {
325
+ let handle;
326
+ try {
327
+ handle = await plugins.fs.promises.open(pathArg, plugins.fs.constants.O_RDONLY | plugins.fs.constants.O_NOFOLLOW);
328
+ }
329
+ catch (errorArg) {
330
+ if (isMissingError(errorArg))
331
+ return undefined;
332
+ throw new Error(`${labelArg} is not a safe regular file.`, { cause: errorArg });
333
+ }
334
+ try {
335
+ const stats = await handle.stat({ bigint: true });
336
+ if (!stats.isFile()
337
+ || stats.uid !== BigInt(currentUid())
338
+ || Number(stats.mode & 511n) !== exactModeArg
339
+ || stats.size < 2n
340
+ || stats.size > BigInt(maximumBytesArg))
341
+ throw new Error(`${labelArg} is not a bounded mode-${exactModeArg.toString(8)} regular file.`);
342
+ let parsed;
343
+ try {
344
+ parsed = JSON.parse(await handle.readFile('utf8'));
345
+ }
346
+ catch (errorArg) {
347
+ throw new Error(`${labelArg} contains malformed JSON.`, { cause: errorArg });
348
+ }
349
+ return { value: parserArg(parsed), identity: pathIdentity(stats) };
350
+ }
351
+ finally {
352
+ await handle.close();
353
+ }
354
+ };
355
+ const unlinkExactPath = async (pathArg, identityArg) => {
356
+ let current;
357
+ try {
358
+ current = await plugins.fs.promises.lstat(pathArg, { bigint: true });
359
+ }
360
+ catch (errorArg) {
361
+ if (isMissingError(errorArg))
362
+ return;
363
+ throw errorArg;
364
+ }
365
+ if (!identitiesEqual(pathIdentity(current), identityArg)) {
366
+ throw new Error(`Refusing to remove a replaced migration artifact: ${pathArg}`);
367
+ }
368
+ await plugins.fs.promises.unlink(pathArg);
369
+ };
370
+ const writePrivateJsonAtomic = async (targetPathArg, valueArg, maximumBytesArg) => {
371
+ const serialized = `${JSON.stringify(valueArg)}\n`;
372
+ if (Buffer.byteLength(serialized, 'utf8') > maximumBytesArg) {
373
+ throw new Error('Controller migration record exceeds its size limit.');
374
+ }
375
+ const parent = plugins.path.dirname(targetPathArg);
376
+ const temporaryPath = `${targetPathArg}.tmp-${process.pid}-${plugins.crypto.randomBytes(8).toString('hex')}`;
377
+ let handle;
378
+ let temporaryIdentity;
379
+ try {
380
+ handle = await plugins.fs.promises.open(temporaryPath, plugins.fs.constants.O_WRONLY
381
+ | plugins.fs.constants.O_CREAT
382
+ | plugins.fs.constants.O_EXCL
383
+ | plugins.fs.constants.O_NOFOLLOW, 0o600);
384
+ await handle.chmod(0o600);
385
+ await handle.writeFile(serialized, 'utf8');
386
+ await handle.sync();
387
+ temporaryIdentity = pathIdentity(await handle.stat({ bigint: true }));
388
+ await handle.close();
389
+ handle = undefined;
390
+ await plugins.fs.promises.rename(temporaryPath, targetPathArg);
391
+ temporaryIdentity = undefined;
392
+ await syncDirectory(parent);
393
+ }
394
+ catch (errorArg) {
395
+ if (handle)
396
+ await handle.close().catch(() => undefined);
397
+ if (temporaryIdentity)
398
+ await unlinkExactPath(temporaryPath, temporaryIdentity).catch(() => undefined);
399
+ throw errorArg;
400
+ }
401
+ };
402
+ const delay = async (millisecondsArg, signalArg) => {
403
+ signalArg?.throwIfAborted();
404
+ const signal = signalArg;
405
+ await new Promise((resolve, reject) => {
406
+ const timer = setTimeout(() => {
407
+ signal?.removeEventListener('abort', onAbort);
408
+ resolve();
409
+ }, millisecondsArg);
410
+ const onAbort = () => {
411
+ clearTimeout(timer);
412
+ signal?.removeEventListener('abort', onAbort);
413
+ reject(signal?.reason ?? new Error('Controller data-root migration was aborted.'));
414
+ };
415
+ signal?.addEventListener('abort', onAbort, { once: true });
416
+ });
417
+ };
418
+ const databaseConfigurationDigest = (valueArg) => plugins.crypto
419
+ .createHash('sha256')
420
+ .update(JSON.stringify(valueArg), 'utf8')
421
+ .digest('hex');
422
+ const aggregateDatabaseDigests = (digestsArg) => {
423
+ const hash = plugins.crypto.createHash('sha256');
424
+ for (const [databaseName, digest] of [...digestsArg.entries()].sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))) {
425
+ hash.update(databaseName, 'utf8');
426
+ hash.update('\0');
427
+ hash.update(digest.sha256, 'ascii');
428
+ hash.update('\0');
429
+ }
430
+ return hash.digest('hex');
431
+ };
432
+ const inspectDatabaseContentDigest = async (directoryArg) => {
433
+ const database = new plugins.smartdb.LocalSmartDb({ folderPath: directoryArg });
434
+ retainedMigratedLocalSmartDbs.add(database);
435
+ let operationError;
436
+ let result;
437
+ try {
438
+ await database.start();
439
+ const server = database.getServer();
440
+ const names = [...new Set((await server.getCollections()).map((entry) => entry.db))].sort();
441
+ const digests = new Map();
442
+ for (const name of names) {
443
+ digests.set(name, await server.getDatabaseContentDigest({ databaseName: name }));
444
+ }
445
+ result = aggregateDatabaseDigests(digests);
446
+ }
447
+ catch (errorArg) {
448
+ operationError = errorArg;
449
+ }
450
+ try {
451
+ await stopLocalSmartDbConfirmed(database, 'Controller database inspection SmartDB');
452
+ retainedMigratedLocalSmartDbs.delete(database);
453
+ }
454
+ catch (errorArg) {
455
+ operationError = operationError
456
+ ? new AggregateError([operationError, errorArg], 'Controller database inspection and cleanup both failed.', { cause: operationError })
457
+ : errorArg;
458
+ }
459
+ if (operationError)
460
+ throw operationError;
461
+ return result;
462
+ };
463
+ const closeKernelStoreConfirmed = async (kernelStoreArg) => {
464
+ const errors = [];
465
+ for (let attempt = 0; attempt < 2; attempt += 1) {
466
+ try {
467
+ await kernelStoreArg.close();
468
+ return;
469
+ }
470
+ catch (errorArg) {
471
+ errors.push(errorArg);
472
+ }
473
+ }
474
+ throw new AggregateError(errors, 'SmartSecret kernel-store closure could not be confirmed.');
475
+ };
476
+ const retainedEmbeddedDatabaseMigrations = new Set();
477
+ const retainedMigratedLocalSmartDbs = new Set();
478
+ const stopLocalSmartDbConfirmed = async (localDbArg, labelArg) => {
479
+ const errors = [];
480
+ for (let attempt = 0; attempt < 2; attempt += 1) {
481
+ try {
482
+ await localDbArg.stop();
483
+ return;
484
+ }
485
+ catch (errorArg) {
486
+ errors.push(errorArg);
487
+ }
488
+ }
489
+ throw new AggregateError(errors, `${labelArg} could not be stopped cleanly.`);
490
+ };
491
+ const drainRetainedEmbeddedDatabaseMigrationResources = async () => {
492
+ for (const retainedLocalDb of retainedMigratedLocalSmartDbs) {
493
+ await stopLocalSmartDbConfirmed(retainedLocalDb, 'Retained controller migration SmartDB');
494
+ retainedMigratedLocalSmartDbs.delete(retainedLocalDb);
495
+ }
496
+ for (const retainedMigration of retainedEmbeddedDatabaseMigrations) {
497
+ const cleanupErrors = [];
498
+ for (let attempt = 0; attempt < 2 && retainedMigration.hasOwnedResources; attempt += 1) {
499
+ try {
500
+ await retainedMigration.stop();
501
+ }
502
+ catch (errorArg) {
503
+ cleanupErrors.push(errorArg);
504
+ }
505
+ }
506
+ if (retainedMigration.hasOwnedResources) {
507
+ throw new AggregateError(cleanupErrors, 'A retained embedded database migration still owns resources.');
508
+ }
509
+ retainedEmbeddedDatabaseMigrations.delete(retainedMigration);
510
+ }
511
+ };
512
+ const runEmbeddedDatabaseLocationMigration = async (migrationArg) => {
513
+ await drainRetainedEmbeddedDatabaseMigrationResources();
514
+ retainedEmbeddedDatabaseMigrations.add(migrationArg);
515
+ let operationError;
516
+ let result = undefined;
517
+ try {
518
+ result = await migrationArg.run();
519
+ }
520
+ catch (errorArg) {
521
+ operationError = errorArg;
522
+ }
523
+ if (result) {
524
+ retainedMigratedLocalSmartDbs.add(result.localDb);
525
+ try {
526
+ await stopLocalSmartDbConfirmed(result.localDb, 'Migrated controller SmartDB');
527
+ retainedMigratedLocalSmartDbs.delete(result.localDb);
528
+ }
529
+ catch (errorArg) {
530
+ operationError = operationError
531
+ ? new AggregateError([operationError, errorArg], 'Embedded database migration and transferred-engine cleanup both failed.', { cause: operationError })
532
+ : errorArg;
533
+ }
534
+ }
535
+ if (migrationArg.hasOwnedResources) {
536
+ const cleanupErrors = [];
537
+ for (let attempt = 0; attempt < 2 && migrationArg.hasOwnedResources; attempt += 1) {
538
+ try {
539
+ await migrationArg.stop();
540
+ }
541
+ catch (errorArg) {
542
+ cleanupErrors.push(errorArg);
543
+ }
544
+ }
545
+ if (migrationArg.hasOwnedResources) {
546
+ const cleanupError = new AggregateError(cleanupErrors, 'Embedded database migration retained resources after cleanup retries.');
547
+ operationError = operationError
548
+ ? new AggregateError([operationError, cleanupError], 'Embedded database migration and owned-resource cleanup both failed.', { cause: operationError })
549
+ : cleanupError;
550
+ }
551
+ }
552
+ if (!migrationArg.hasOwnedResources)
553
+ retainedEmbeddedDatabaseMigrations.delete(migrationArg);
554
+ if (operationError)
555
+ throw operationError;
556
+ };
557
+ const defaultRelocateCredentialStore = async (intentArg, signalArg) => {
558
+ signalArg?.throwIfAborted();
559
+ let kernelStore;
560
+ let sealedStore;
561
+ let operationError;
562
+ try {
563
+ kernelStore = await plugins.smartsecret.SmartSecretKernelStore.create({
564
+ service: intentArg.service,
565
+ });
566
+ signalArg?.throwIfAborted();
567
+ sealedStore = await plugins.smartsecret.SmartSecretSealedFileStore.relocate({
568
+ kernelStore,
569
+ storeId: intentArg.storeId,
570
+ sourceDirectoryPath: intentArg.sourceDirectory,
571
+ destinationDirectoryPath: intentArg.destinationDirectory,
572
+ });
573
+ await sealedStore.close();
574
+ sealedStore = undefined;
575
+ }
576
+ catch (errorArg) {
577
+ operationError = errorArg;
578
+ }
579
+ if (sealedStore) {
580
+ try {
581
+ await sealedStore.close();
582
+ }
583
+ catch (errorArg) {
584
+ operationError = operationError
585
+ ? new AggregateError([operationError, errorArg], 'SmartSecret relocation and sealed-store cleanup both failed.', { cause: operationError })
586
+ : errorArg;
587
+ }
588
+ }
589
+ if (kernelStore) {
590
+ try {
591
+ await closeKernelStoreConfirmed(kernelStore);
592
+ }
593
+ catch (errorArg) {
594
+ operationError = operationError
595
+ ? new AggregateError([operationError, errorArg], 'SmartSecret relocation and kernel-store cleanup both failed.', { cause: operationError })
596
+ : errorArg;
597
+ }
598
+ }
599
+ if (operationError)
600
+ throw operationError;
601
+ };
602
+ export class ControllerDataRootMigrationRunner {
603
+ options;
604
+ oldRoot;
605
+ newRoot;
606
+ commonParent;
607
+ journalPath;
608
+ lockPath;
609
+ markerPath;
610
+ databaseConfiguration;
611
+ isSocketListening;
612
+ relocateCredentialStore;
613
+ relocateStoppedDatabaseRoot;
614
+ constructor(options) {
615
+ this.options = options;
616
+ this.oldRoot = assertAbsoluteNormalizedPath(options.oldRoot, 'Old controller root');
617
+ this.newRoot = assertAbsoluteNormalizedPath(options.newRoot, 'New controller root');
618
+ if (this.oldRoot === this.newRoot)
619
+ throw new Error('Controller roots must be different.');
620
+ if (plugins.path.dirname(this.oldRoot) !== plugins.path.dirname(this.newRoot)) {
621
+ throw new Error('Controller roots must be siblings under one common parent.');
622
+ }
623
+ this.commonParent = plugins.path.dirname(this.oldRoot);
624
+ this.journalPath = plugins.path.join(this.commonParent, journalFileName);
625
+ this.lockPath = plugins.path.join(this.commonParent, lockFileName);
626
+ this.markerPath = plugins.path.join(this.newRoot, markerFileName);
627
+ assertAbsoluteNormalizedPath(options.oldEmbeddedSocketPath, 'Old embedded database socket path');
628
+ assertAbsoluteNormalizedPath(options.newEmbeddedSocketPath, 'New embedded database socket path');
629
+ if (!Number.isSafeInteger(options.invokerPid) || options.invokerPid < 2) {
630
+ throw new Error('Controller data-root migration invoker PID is invalid.');
631
+ }
632
+ if (typeof options.listDataWriterProcesses !== 'function') {
633
+ throw new Error('Controller data-root migration requires a data-writer process callback.');
634
+ }
635
+ this.databaseConfiguration = this.normalizeDatabaseConfiguration(options.databaseConfig);
636
+ this.isSocketListening = options.isSocketListening ?? defaultIsSocketListening;
637
+ this.relocateCredentialStore = options.relocateCredentialStore
638
+ ?? defaultRelocateCredentialStore;
639
+ this.relocateStoppedDatabaseRoot = options.relocateStoppedDatabaseRoot
640
+ ?? (async (inputArg, signalArg) => await plugins.smartdb.LocalSmartDb.relocateStoppedStorageRoot({ ...inputArg }, signalArg ? { signal: signalArg } : undefined));
641
+ }
642
+ async prepareStartup() {
643
+ const parentExists = await this.validateCommonParent(false);
644
+ if (!parentExists) {
645
+ return { directoryPath: this.newRoot, createDirectory: true };
646
+ }
647
+ const journal = await this.readJournal();
648
+ if (journal) {
649
+ if (journal.phase === 'target-committed') {
650
+ this.assertJournalRootBinding(journal);
651
+ await this.assertTargetIdentity(journal);
652
+ await this.assertTargetMarker(journal.targetCreationNonce);
653
+ return { directoryPath: journal.destinationPath, createDirectory: false };
654
+ }
655
+ this.assertJournalMatches(journal);
656
+ await this.assertSourceIdentity(journal);
657
+ return { directoryPath: journal.sourcePath, createDirectory: false };
658
+ }
659
+ const sourceIdentity = await readDirectoryIdentity(this.oldRoot, 'Legacy controller root');
660
+ if (sourceIdentity)
661
+ return { directoryPath: this.oldRoot, createDirectory: false };
662
+ await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
663
+ return { directoryPath: this.newRoot, createDirectory: true };
664
+ }
665
+ async run() {
666
+ this.options.signal?.throwIfAborted();
667
+ if (this.options.invokerPid !== process.pid) {
668
+ throw new Error('Controller data-root migration invoker PID is not the current process.');
669
+ }
670
+ const invokerIdentity = await readControllerProcessIdentity(this.options.invokerPid);
671
+ if (!invokerIdentity || invokerIdentity.pid !== this.options.invokerPid) {
672
+ throw new Error('Controller data-root migration invoker identity cannot be verified.');
673
+ }
674
+ await this.ensureCommonParent();
675
+ const lease = await this.acquireLock(invokerIdentity);
676
+ let operationError;
677
+ let result;
678
+ try {
679
+ result = await this.runLocked(invokerIdentity);
680
+ }
681
+ catch (errorArg) {
682
+ operationError = errorArg;
683
+ }
684
+ try {
685
+ await this.releaseLock(lease);
686
+ }
687
+ catch (errorArg) {
688
+ operationError = operationError
689
+ ? new AggregateError([operationError, errorArg], 'Controller data-root migration and lock release both failed.', { cause: operationError })
690
+ : errorArg;
691
+ }
692
+ if (operationError)
693
+ throw operationError;
694
+ return result;
695
+ }
696
+ normalizeDatabaseConfiguration(configArg) {
697
+ const value = assertPlainRecord(configArg, 'Controller database configuration');
698
+ const allowedKeys = new Set([
699
+ 'mongoDbUrl',
700
+ 'mongoDbName',
701
+ 'embeddedDataDirectory',
702
+ 'legacyEmbeddedDataDirectory',
703
+ ]);
704
+ if (Object.keys(value).some((key) => !allowedKeys.has(key))) {
705
+ throw new Error('Controller database configuration has unexpected fields.');
706
+ }
707
+ const mongoDbName = requireString(value.mongoDbName, 'Controller MongoDB database name', 256);
708
+ const oldDirectory = plugins.path.join(this.oldRoot, 'smartdb');
709
+ const targetDirectory = plugins.path.join(this.newRoot, 'smartdb');
710
+ if (value.mongoDbUrl !== undefined) {
711
+ const mongoDbUrl = requireString(value.mongoDbUrl, 'Controller MongoDB URL');
712
+ if (value.embeddedDataDirectory !== undefined || value.legacyEmbeddedDataDirectory !== undefined) {
713
+ throw new Error('External MongoDB configuration must not include embedded database paths.');
714
+ }
715
+ return {
716
+ mode: 'external',
717
+ configurationDigestSha256: databaseConfigurationDigest({
718
+ mode: 'external',
719
+ mongoDbUrl,
720
+ mongoDbName,
721
+ }),
722
+ oldDirectory: null,
723
+ targetDirectory: null,
724
+ historicalDirectory: null,
725
+ effectiveConfig: { mongoDbUrl, mongoDbName },
726
+ };
727
+ }
728
+ const embeddedDataDirectory = assertAbsoluteNormalizedPath(requireString(value.embeddedDataDirectory, 'Controller embedded database path'), 'Controller embedded database path');
729
+ const historicalDirectory = value.legacyEmbeddedDataDirectory === undefined
730
+ ? null
731
+ : assertAbsoluteNormalizedPath(requireString(value.legacyEmbeddedDataDirectory, 'Historical embedded database path'), 'Historical embedded database path');
732
+ if (embeddedDataDirectory !== oldDirectory && embeddedDataDirectory !== targetDirectory) {
733
+ if (historicalDirectory !== null) {
734
+ throw new Error('An explicit embedded database override must not include a historical path.');
735
+ }
736
+ return {
737
+ mode: 'override',
738
+ configurationDigestSha256: databaseConfigurationDigest({
739
+ mode: 'override',
740
+ mongoDbName,
741
+ embeddedDataDirectory,
742
+ }),
743
+ oldDirectory: null,
744
+ targetDirectory: null,
745
+ historicalDirectory: null,
746
+ effectiveConfig: { mongoDbName, embeddedDataDirectory },
747
+ };
748
+ }
749
+ if (historicalDirectory === oldDirectory || historicalDirectory === targetDirectory) {
750
+ throw new Error('Historical embedded database path must be outside both product roots.');
751
+ }
752
+ return {
753
+ mode: 'default',
754
+ configurationDigestSha256: databaseConfigurationDigest({
755
+ mode: 'default',
756
+ mongoDbName,
757
+ historicalDirectory,
758
+ }),
759
+ oldDirectory,
760
+ targetDirectory,
761
+ historicalDirectory,
762
+ effectiveConfig: { mongoDbName, embeddedDataDirectory: targetDirectory },
763
+ };
764
+ }
765
+ async validateCommonParent(requiredArg) {
766
+ let stats;
767
+ try {
768
+ stats = await plugins.fs.promises.lstat(this.commonParent, { bigint: true });
769
+ }
770
+ catch (errorArg) {
771
+ if (!requiredArg && isMissingError(errorArg))
772
+ return false;
773
+ throw errorArg;
774
+ }
775
+ if (!stats.isDirectory()
776
+ || stats.isSymbolicLink()
777
+ || stats.uid !== BigInt(currentUid())
778
+ || (Number(stats.mode & 511n) & 0o022) !== 0)
779
+ throw new Error(`Controller roots require a private real common parent: ${this.commonParent}`);
780
+ if (await plugins.fs.promises.realpath(this.commonParent) !== this.commonParent) {
781
+ throw new Error('Controller root common parent must not traverse symbolic links.');
782
+ }
783
+ return true;
784
+ }
785
+ async ensureCommonParent() {
786
+ await plugins.fs.promises.mkdir(this.commonParent, { recursive: true, mode: 0o700 });
787
+ if (!await this.validateCommonParent(true)) {
788
+ throw new Error('Controller root common parent could not be created.');
789
+ }
790
+ }
791
+ async readJournal() {
792
+ return (await readPrivateJson(this.journalPath, maximumJournalBytes, parseJournal, 'Controller data-root migration journal'))?.value;
793
+ }
794
+ async writeJournal(journalArg) {
795
+ await this.cleanupJournalTemporaryFiles();
796
+ await writePrivateJsonAtomic(this.journalPath, journalArg, maximumJournalBytes);
797
+ const persisted = await this.readJournal();
798
+ if (!persisted || JSON.stringify(persisted) !== JSON.stringify(journalArg)) {
799
+ throw new Error('Controller data-root migration journal was not persisted exactly.');
800
+ }
801
+ }
802
+ async cleanupJournalTemporaryFiles() {
803
+ const prefix = `${plugins.path.basename(this.journalPath)}.tmp-`;
804
+ const entries = await plugins.fs.promises.readdir(this.commonParent, { withFileTypes: true });
805
+ const temporaryNames = entries
806
+ .map((entry) => entry.name)
807
+ .filter((name) => name.startsWith(prefix));
808
+ if (temporaryNames.length > maximumMigrationTemporaryFiles) {
809
+ throw new Error('Too many controller migration journal artifacts exist.');
810
+ }
811
+ for (const name of temporaryNames) {
812
+ if (!new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[1-9][0-9]*-[a-f0-9]{16}$`).test(name)) {
813
+ throw new Error(`Unknown controller migration journal artifact: ${name}`);
814
+ }
815
+ const path = plugins.path.join(this.commonParent, name);
816
+ const identity = await inspectPrivateNode(path, 'file', 'Controller migration journal artifact', 0o600);
817
+ if (identity)
818
+ await unlinkExactPath(path, identity);
819
+ }
820
+ if (temporaryNames.length > 0)
821
+ await syncDirectory(this.commonParent);
822
+ }
823
+ assertJournalMatches(journalArg) {
824
+ this.assertJournalRootBinding(journalArg);
825
+ if (journalArg.database.configurationDigestSha256
826
+ !== this.databaseConfiguration.configurationDigestSha256) {
827
+ throw new Error('Controller database configuration changed during root migration.');
828
+ }
829
+ const database = journalArg.database;
830
+ if (database.mode !== this.databaseConfiguration.mode
831
+ || database.oldDirectory !== this.databaseConfiguration.oldDirectory
832
+ || database.targetDirectory !== this.databaseConfiguration.targetDirectory
833
+ || database.historicalDirectory !== this.databaseConfiguration.historicalDirectory)
834
+ throw new Error('Controller database migration journal paths do not match current inputs.');
835
+ if (database.mode !== 'default') {
836
+ if (database.strategy !== 'unchanged'
837
+ || database.phase !== 'verified'
838
+ || database.v1JournalLocation !== 'none'
839
+ || database.sourceDevice !== null
840
+ || database.destinationDevice !== null
841
+ || database.contentDigestSha256 !== null)
842
+ throw new Error('Unchanged controller database journal state is invalid.');
843
+ }
844
+ else if (database.strategy === 'fresh') {
845
+ if (database.phase !== 'verified'
846
+ || database.sourcePath !== null
847
+ || database.sourceDevice !== null
848
+ || database.destinationDevice !== null
849
+ || database.contentDigestSha256 !== null
850
+ || database.v1JournalLocation !== 'none')
851
+ throw new Error('Fresh controller database journal state is invalid.');
852
+ }
853
+ else if (database.strategy === 'historical-direct') {
854
+ if (database.sourcePath !== database.historicalDirectory
855
+ || database.v1JournalLocation !== 'target'
856
+ || database.phase === 'prepared'
857
+ || database.phase === 'moved')
858
+ throw new Error('Historical controller database journal state is invalid.');
859
+ }
860
+ else if (database.strategy === 'old-relocation') {
861
+ if (database.sourcePath !== database.oldDirectory
862
+ || database.v1JournalLocation === 'target')
863
+ throw new Error('Old controller database relocation journal state is invalid.');
864
+ }
865
+ else {
866
+ throw new Error('Default controller database migration strategy is invalid.');
867
+ }
868
+ if (database.phase === 'pending' && database.strategy === 'old-relocation') {
869
+ if (database.sourceDevice !== null
870
+ || database.destinationDevice !== null
871
+ || database.contentDigestSha256 !== null)
872
+ throw new Error('Pending controller database relocation state is invalid.');
873
+ }
874
+ if (database.phase === 'prepared') {
875
+ if (database.sourceDevice === null
876
+ || database.destinationDevice !== null
877
+ || database.contentDigestSha256 === null)
878
+ throw new Error('Prepared controller database relocation state is invalid.');
879
+ }
880
+ if (database.phase === 'moved' || (database.phase === 'verified'
881
+ && (database.strategy === 'historical-direct' || database.strategy === 'old-relocation'))) {
882
+ if (database.destinationDevice === null || database.contentDigestSha256 === null) {
883
+ throw new Error('Moved controller database relocation state is invalid.');
884
+ }
885
+ }
886
+ const seenHashes = new Set();
887
+ for (let index = 0; index < journalArg.credentials.length; index += 1) {
888
+ const tuple = journalArg.credentials[index];
889
+ if (seenHashes.has(tuple.controllerHash)) {
890
+ throw new Error('Controller credential migration journal contains duplicate hashes.');
891
+ }
892
+ seenHashes.add(tuple.controllerHash);
893
+ if ((index > 0 && journalArg.credentials[index - 1].controllerHash > tuple.controllerHash)
894
+ || tuple.service !== `modelprofile.flexharness.${tuple.controllerHash.slice(0, 32)}`
895
+ || tuple.storeId !== flexProviderCredentialStoreId
896
+ || tuple.sourceDirectory !== plugins.path.join(this.oldRoot, 'flex-provider-credentials', tuple.controllerHash)
897
+ || tuple.destinationDirectory !== plugins.path.join(this.newRoot, 'flex-provider-credentials', tuple.controllerHash))
898
+ throw new Error('Controller credential migration tuple does not match its roots.');
899
+ }
900
+ }
901
+ assertJournalRootBinding(journalArg) {
902
+ if (journalArg.sourcePath !== this.oldRoot || journalArg.destinationPath !== this.newRoot) {
903
+ throw new Error('Controller data-root migration journal belongs to different roots.');
904
+ }
905
+ const destinationIdentityPresent = journalArg.destinationDevice !== null;
906
+ if ((journalArg.phase === 'legacy-authoritative') === destinationIdentityPresent) {
907
+ throw new Error('Controller data-root migration destination identity conflicts with its phase.');
908
+ }
909
+ }
910
+ async assertSourceIdentity(journalArg) {
911
+ const identity = await readDirectoryIdentity(this.oldRoot, 'Legacy controller root');
912
+ if (journalArg.sourceDevice === null) {
913
+ if (identity)
914
+ throw new Error('Legacy controller root appeared after migration preparation.');
915
+ return;
916
+ }
917
+ if (!identity || !identitiesEqual(identity, {
918
+ device: journalArg.sourceDevice,
919
+ inode: journalArg.sourceInode,
920
+ }))
921
+ throw new Error('Legacy controller root identity changed during migration.');
922
+ }
923
+ async assertTargetIdentity(journalArg) {
924
+ if (journalArg.destinationDevice === null) {
925
+ throw new Error('Controller target root identity was not recorded.');
926
+ }
927
+ const identity = await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
928
+ if (!identity || !identitiesEqual(identity, {
929
+ device: journalArg.destinationDevice,
930
+ inode: journalArg.destinationInode,
931
+ }))
932
+ throw new Error('Controller target root identity changed during migration.');
933
+ }
934
+ async assertTargetMarker(nonceArg) {
935
+ const marker = await readPrivateJson(this.markerPath, maximumMarkerBytes, parseMarker, 'Controller target marker');
936
+ if (!marker || marker.value.targetCreationNonce !== nonceArg) {
937
+ throw new Error('Controller target marker is missing or belongs to another migration.');
938
+ }
939
+ }
940
+ async runLocked(invokerIdentityArg) {
941
+ let journal = await this.readJournal();
942
+ if (journal?.phase === 'target-committed') {
943
+ this.assertJournalRootBinding(journal);
944
+ await this.assertTargetIdentity(journal);
945
+ await this.assertTargetMarker(journal.targetCreationNonce);
946
+ return this.result();
947
+ }
948
+ if (journal)
949
+ this.assertJournalMatches(journal);
950
+ await this.assertNoConflictingWriters(invokerIdentityArg);
951
+ await drainRetainedEmbeddedDatabaseMigrationResources();
952
+ await this.cleanupJournalTemporaryFiles();
953
+ journal = await this.readJournal();
954
+ if (journal)
955
+ this.assertJournalMatches(journal);
956
+ if (!journal)
957
+ journal = await this.createInitialJournal();
958
+ await this.assertSourceIdentity(journal);
959
+ await this.inspectLegacyRootInventory(journal);
960
+ await this.validateCredentialLocations(journal, false);
961
+ if (journal.database.mode === 'default')
962
+ await this.assertDefaultDatabaseSocketsIdle();
963
+ if (journal.database.strategy === 'old-relocation'
964
+ && journal.database.phase === 'pending')
965
+ journal = await this.prepareOldDatabaseRelocation(journal);
966
+ journal = await this.ensureTargetStaged(journal);
967
+ journal = await this.performDatabaseMigration(journal);
968
+ journal = await this.performCredentialMigrations(journal);
969
+ if (journal.database.phase !== 'verified') {
970
+ throw new Error('Controller database migration is not verified.');
971
+ }
972
+ if (journal.credentials.some((tuple) => !tuple.complete)) {
973
+ throw new Error('Controller credential migration is not complete.');
974
+ }
975
+ await this.validateCredentialLocations(journal, true);
976
+ await this.inspectTargetStagingInventory(journal);
977
+ await this.assertTargetIdentity(journal);
978
+ const committed = {
979
+ ...journal,
980
+ phase: 'target-committed',
981
+ };
982
+ await this.writeJournal(committed);
983
+ return this.result();
984
+ }
985
+ result() {
986
+ return {
987
+ directoryPath: this.newRoot,
988
+ databaseConfig: { ...this.databaseConfiguration.effectiveConfig },
989
+ };
990
+ }
991
+ async assertNoConflictingWriters(invokerIdentityArg) {
992
+ const records = await this.options.listDataWriterProcesses();
993
+ if (!Array.isArray(records) || records.length > 1_024) {
994
+ throw new Error('Controller data-writer process inventory is invalid.');
995
+ }
996
+ for (const record of records) {
997
+ if (!record
998
+ || (record.kind !== 'controller'
999
+ && record.kind !== 'temp-password'
1000
+ && record.kind !== 'flex-child')
1001
+ || !Number.isSafeInteger(record.identity?.pid)
1002
+ || record.identity.pid < 2
1003
+ || typeof record.identity.fingerprint !== 'string'
1004
+ || record.identity.fingerprint.length === 0)
1005
+ throw new Error('Controller data-writer process record is invalid.');
1006
+ if (record.identity.pid === invokerIdentityArg.pid
1007
+ && record.identity.fingerprint === invokerIdentityArg.fingerprint)
1008
+ continue;
1009
+ throw new Error(`Controller data-root migration is blocked by ${record.kind} writer PID ${record.identity.pid}.`);
1010
+ }
1011
+ }
1012
+ async createInitialJournal() {
1013
+ const sourceIdentity = await readDirectoryIdentity(this.oldRoot, 'Legacy controller root');
1014
+ const targetIdentity = await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
1015
+ if (sourceIdentity && targetIdentity) {
1016
+ throw new Error('Both unjournaled controller product roots exist; refusing to choose authority.');
1017
+ }
1018
+ if (sourceIdentity)
1019
+ await this.inspectLegacyRootInventory();
1020
+ if (targetIdentity) {
1021
+ const entries = await this.readBoundedDirectory(this.newRoot, 'Target controller root');
1022
+ if (entries.length !== 0) {
1023
+ throw new Error('An unjournaled target controller root is not empty.');
1024
+ }
1025
+ }
1026
+ const credentials = await this.initialCredentialTuples(sourceIdentity !== undefined);
1027
+ const database = await this.initialDatabaseJournal();
1028
+ const journal = {
1029
+ version: migrationVersion,
1030
+ phase: 'legacy-authoritative',
1031
+ sourcePath: this.oldRoot,
1032
+ sourceDevice: sourceIdentity?.device ?? null,
1033
+ sourceInode: sourceIdentity?.inode ?? null,
1034
+ destinationPath: this.newRoot,
1035
+ destinationDevice: null,
1036
+ destinationInode: null,
1037
+ targetCreationNonce: plugins.crypto.randomBytes(32).toString('hex'),
1038
+ database,
1039
+ credentials,
1040
+ };
1041
+ this.assertJournalMatches(journal);
1042
+ await this.writeJournal(journal);
1043
+ return journal;
1044
+ }
1045
+ async readBoundedDirectory(directoryArg, labelArg) {
1046
+ const entries = await plugins.fs.promises.readdir(directoryArg, { withFileTypes: true });
1047
+ if (entries.length > maximumRootEntries)
1048
+ throw new Error(`${labelArg} has too many entries.`);
1049
+ return entries.map((entry) => entry.name).sort();
1050
+ }
1051
+ async inspectLegacyRootInventory(journalArg) {
1052
+ const identity = await readDirectoryIdentity(this.oldRoot, 'Legacy controller root');
1053
+ if (!identity)
1054
+ return;
1055
+ const names = await this.readBoundedDirectory(this.oldRoot, 'Legacy controller root');
1056
+ let migrationTemporaryFiles = 0;
1057
+ let controllerLogs = 0;
1058
+ let upgradeLogs = 0;
1059
+ for (const name of names) {
1060
+ const path = plugins.path.join(this.oldRoot, name);
1061
+ if (name === 'smartdb') {
1062
+ const databaseMayBeRelocated = journalArg?.database.strategy === 'old-relocation'
1063
+ && journalArg.database.phase !== 'pending';
1064
+ if (databaseMayBeRelocated) {
1065
+ const stats = await plugins.fs.promises.lstat(path);
1066
+ if (stats.isFile()) {
1067
+ await this.requirePrivateNode(path, 'file', 'Legacy controller smartdb receipt', 0o600);
1068
+ }
1069
+ else {
1070
+ await this.requirePrivateNode(path, 'directory', 'Legacy controller smartdb');
1071
+ }
1072
+ }
1073
+ else {
1074
+ await this.requirePrivateNode(path, 'directory', 'Legacy controller smartdb');
1075
+ }
1076
+ continue;
1077
+ }
1078
+ if (name === 'browser-runtime') {
1079
+ await this.requirePrivateNode(path, 'directory', `Legacy controller ${name}`);
1080
+ continue;
1081
+ }
1082
+ if (name === 'flex-provider-credentials') {
1083
+ await this.requirePrivateNode(path, 'directory', 'Legacy Flex credential root', 0o700);
1084
+ continue;
1085
+ }
1086
+ if (name === embeddedDatabaseJournalFileName) {
1087
+ await this.requirePrivateNode(path, 'file', 'Legacy embedded database journal');
1088
+ continue;
1089
+ }
1090
+ if (embeddedDatabaseJournalTemporaryPattern.test(name)) {
1091
+ migrationTemporaryFiles += 1;
1092
+ await this.requirePrivateNode(path, 'file', 'Legacy embedded database journal artifact');
1093
+ continue;
1094
+ }
1095
+ const controllerLogMatch = controllerLogPattern.exec(name);
1096
+ if (controllerLogMatch && Number(controllerLogMatch[1]) <= 65_535) {
1097
+ controllerLogs += 1;
1098
+ await this.requirePrivateNode(path, 'file', 'Legacy controller log');
1099
+ continue;
1100
+ }
1101
+ if (upgradeLogPattern.test(name)) {
1102
+ upgradeLogs += 1;
1103
+ await this.requirePrivateNode(path, 'file', 'Legacy controller upgrade log');
1104
+ continue;
1105
+ }
1106
+ throw new Error(`Unknown authoritative entry in legacy controller root: ${name}`);
1107
+ }
1108
+ if (migrationTemporaryFiles > maximumMigrationTemporaryFiles
1109
+ || controllerLogs > maximumControllerLogs
1110
+ || upgradeLogs > maximumUpgradeLogs)
1111
+ throw new Error('Legacy controller root contains too many bounded migration assets.');
1112
+ if (journalArg)
1113
+ await this.assertSourceIdentity(journalArg);
1114
+ }
1115
+ async requirePrivateNode(pathArg, kindArg, labelArg, exactModeArg) {
1116
+ const identity = await inspectPrivateNode(pathArg, kindArg, labelArg, exactModeArg);
1117
+ if (!identity)
1118
+ throw new Error(`${labelArg} disappeared during inspection.`);
1119
+ return identity;
1120
+ }
1121
+ async initialCredentialTuples(sourceRootExistsArg) {
1122
+ if (!sourceRootExistsArg)
1123
+ return [];
1124
+ const credentialRoot = plugins.path.join(this.oldRoot, 'flex-provider-credentials');
1125
+ const identity = await readDirectoryIdentity(credentialRoot, 'Legacy Flex credential root', 0o700);
1126
+ if (!identity)
1127
+ return [];
1128
+ const hashes = await this.readCredentialHashes(credentialRoot, 'Legacy Flex credential root');
1129
+ return hashes.map((controllerHash) => ({
1130
+ controllerHash,
1131
+ service: `modelprofile.flexharness.${controllerHash.slice(0, 32)}`,
1132
+ storeId: flexProviderCredentialStoreId,
1133
+ sourceDirectory: plugins.path.join(credentialRoot, controllerHash),
1134
+ destinationDirectory: plugins.path.join(this.newRoot, 'flex-provider-credentials', controllerHash),
1135
+ complete: false,
1136
+ }));
1137
+ }
1138
+ async readCredentialHashes(directoryArg, labelArg) {
1139
+ const entries = await plugins.fs.promises.readdir(directoryArg, { withFileTypes: true });
1140
+ if (entries.length > maximumCredentialStores) {
1141
+ throw new Error(`${labelArg} contains too many credential stores.`);
1142
+ }
1143
+ const hashes = entries.map((entry) => entry.name).sort();
1144
+ for (const hash of hashes) {
1145
+ if (!credentialHashPattern.test(hash)) {
1146
+ throw new Error(`${labelArg} contains an unexpected entry: ${hash}`);
1147
+ }
1148
+ await this.requirePrivateNode(plugins.path.join(directoryArg, hash), 'directory', 'Flex credential store directory', 0o700);
1149
+ }
1150
+ return hashes;
1151
+ }
1152
+ async initialDatabaseJournal() {
1153
+ const configuration = this.databaseConfiguration;
1154
+ if (configuration.mode !== 'default') {
1155
+ return {
1156
+ mode: configuration.mode,
1157
+ strategy: 'unchanged',
1158
+ phase: 'verified',
1159
+ configurationDigestSha256: configuration.configurationDigestSha256,
1160
+ oldDirectory: null,
1161
+ targetDirectory: null,
1162
+ historicalDirectory: null,
1163
+ sourcePath: configuration.mode === 'override'
1164
+ ? configuration.effectiveConfig.embeddedDataDirectory
1165
+ : null,
1166
+ sourceDevice: null,
1167
+ sourceInode: null,
1168
+ destinationDevice: null,
1169
+ destinationInode: null,
1170
+ contentDigestSha256: null,
1171
+ v1JournalLocation: 'none',
1172
+ };
1173
+ }
1174
+ const oldDirectory = configuration.oldDirectory;
1175
+ const targetDirectory = configuration.targetDirectory;
1176
+ const historicalDirectory = configuration.historicalDirectory;
1177
+ const oldIdentity = await readDirectoryIdentity(oldDirectory, 'Legacy config-root database');
1178
+ const historicalIdentity = historicalDirectory
1179
+ ? await readDirectoryIdentity(historicalDirectory, 'Historical state-root database')
1180
+ : undefined;
1181
+ const oldV1JournalPath = plugins.path.join(this.oldRoot, embeddedDatabaseJournalFileName);
1182
+ const oldV1Journal = await inspectPrivateNode(oldV1JournalPath, 'file', 'Legacy embedded database journal');
1183
+ if (oldV1Journal && !historicalDirectory) {
1184
+ throw new Error('Legacy embedded database journal has no configured historical source path.');
1185
+ }
1186
+ if (historicalIdentity && oldIdentity && !oldV1Journal) {
1187
+ throw new Error('Historical and config-root controller databases collide without a matching v1 journal.');
1188
+ }
1189
+ if (oldV1Journal || oldIdentity) {
1190
+ return {
1191
+ mode: 'default',
1192
+ strategy: 'old-relocation',
1193
+ phase: 'pending',
1194
+ configurationDigestSha256: configuration.configurationDigestSha256,
1195
+ oldDirectory,
1196
+ targetDirectory,
1197
+ historicalDirectory,
1198
+ sourcePath: oldDirectory,
1199
+ sourceDevice: null,
1200
+ sourceInode: null,
1201
+ destinationDevice: null,
1202
+ destinationInode: null,
1203
+ contentDigestSha256: null,
1204
+ v1JournalLocation: oldV1Journal ? 'legacy' : 'none',
1205
+ };
1206
+ }
1207
+ if (historicalIdentity) {
1208
+ return {
1209
+ mode: 'default',
1210
+ strategy: 'historical-direct',
1211
+ phase: 'pending',
1212
+ configurationDigestSha256: configuration.configurationDigestSha256,
1213
+ oldDirectory,
1214
+ targetDirectory,
1215
+ historicalDirectory,
1216
+ sourcePath: historicalDirectory,
1217
+ sourceDevice: historicalIdentity.device,
1218
+ sourceInode: historicalIdentity.inode,
1219
+ destinationDevice: null,
1220
+ destinationInode: null,
1221
+ contentDigestSha256: null,
1222
+ v1JournalLocation: 'target',
1223
+ };
1224
+ }
1225
+ return {
1226
+ mode: 'default',
1227
+ strategy: 'fresh',
1228
+ phase: 'verified',
1229
+ configurationDigestSha256: configuration.configurationDigestSha256,
1230
+ oldDirectory,
1231
+ targetDirectory,
1232
+ historicalDirectory,
1233
+ sourcePath: null,
1234
+ sourceDevice: null,
1235
+ sourceInode: null,
1236
+ destinationDevice: null,
1237
+ destinationInode: null,
1238
+ contentDigestSha256: null,
1239
+ v1JournalLocation: 'none',
1240
+ };
1241
+ }
1242
+ async assertDefaultDatabaseSocketsIdle() {
1243
+ for (const socketPath of [
1244
+ this.options.oldEmbeddedSocketPath,
1245
+ this.options.newEmbeddedSocketPath,
1246
+ ]) {
1247
+ this.options.signal?.throwIfAborted();
1248
+ if (await this.isSocketListening(socketPath)) {
1249
+ throw new Error(`Controller embedded database socket is still active: ${socketPath}`);
1250
+ }
1251
+ }
1252
+ }
1253
+ async prepareOldDatabaseRelocation(journalArg) {
1254
+ const database = journalArg.database;
1255
+ if (database.strategy !== 'old-relocation' || database.phase !== 'pending')
1256
+ return journalArg;
1257
+ if (database.v1JournalLocation === 'legacy') {
1258
+ if (!database.historicalDirectory || !database.oldDirectory) {
1259
+ throw new Error('Legacy database migration journal paths are incomplete.');
1260
+ }
1261
+ const migration = new EmbeddedDatabaseLocationMigration({
1262
+ sourceDirectory: database.historicalDirectory,
1263
+ destinationDirectory: database.oldDirectory,
1264
+ sourceSocketPath: embeddedDatabaseSocketPath(database.historicalDirectory),
1265
+ destinationSocketPath: this.options.oldEmbeddedSocketPath,
1266
+ });
1267
+ await runEmbeddedDatabaseLocationMigration(migration);
1268
+ }
1269
+ const sourceIdentity = await readDirectoryIdentity(database.oldDirectory, 'Legacy config-root database');
1270
+ if (!sourceIdentity)
1271
+ throw new Error('Legacy config-root database is missing before relocation.');
1272
+ this.options.signal?.throwIfAborted();
1273
+ const contentDigestSha256 = await inspectDatabaseContentDigest(database.oldDirectory);
1274
+ const prepared = {
1275
+ ...journalArg,
1276
+ database: {
1277
+ ...database,
1278
+ phase: 'prepared',
1279
+ sourceDevice: sourceIdentity.device,
1280
+ sourceInode: sourceIdentity.inode,
1281
+ contentDigestSha256,
1282
+ },
1283
+ };
1284
+ await this.writeJournal(prepared);
1285
+ return prepared;
1286
+ }
1287
+ async ensureTargetStaged(journalArg) {
1288
+ if (journalArg.phase !== 'legacy-authoritative') {
1289
+ await this.assertTargetIdentity(journalArg);
1290
+ await this.assertTargetMarker(journalArg.targetCreationNonce);
1291
+ await this.inspectTargetStagingInventory(journalArg);
1292
+ return journalArg;
1293
+ }
1294
+ let targetIdentity = await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
1295
+ if (!targetIdentity) {
1296
+ await plugins.fs.promises.mkdir(this.newRoot, { mode: 0o700 });
1297
+ await syncDirectory(this.commonParent);
1298
+ targetIdentity = await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
1299
+ if (!targetIdentity)
1300
+ throw new Error('Target controller root was not created.');
1301
+ }
1302
+ const entries = await this.readBoundedDirectory(this.newRoot, 'Target controller root');
1303
+ if (entries.length > 1
1304
+ || (entries.length === 1 && entries[0] !== markerFileName)) {
1305
+ throw new Error('Legacy-authoritative retry found an unexpected staged target entry.');
1306
+ }
1307
+ await this.ensureTargetMarker(journalArg.targetCreationNonce);
1308
+ await syncDirectory(this.newRoot);
1309
+ const stagedIdentity = await readDirectoryIdentity(this.newRoot, 'Target controller root', 0o700);
1310
+ if (!stagedIdentity || !identitiesEqual(stagedIdentity, targetIdentity)) {
1311
+ throw new Error('Target controller root identity changed while it was staged.');
1312
+ }
1313
+ const staged = {
1314
+ ...journalArg,
1315
+ phase: 'target-staged',
1316
+ destinationDevice: stagedIdentity.device,
1317
+ destinationInode: stagedIdentity.inode,
1318
+ };
1319
+ await this.writeJournal(staged);
1320
+ return staged;
1321
+ }
1322
+ async ensureTargetMarker(nonceArg) {
1323
+ const existing = await readPrivateJson(this.markerPath, maximumMarkerBytes, parseMarker, 'Controller target marker');
1324
+ if (existing) {
1325
+ if (existing.value.targetCreationNonce !== nonceArg) {
1326
+ throw new Error('Controller target marker belongs to another migration.');
1327
+ }
1328
+ return;
1329
+ }
1330
+ const temporaryPath = plugins.path.join(this.commonParent, `${markerFileName}.tmp-${nonceArg}`);
1331
+ let temporary = await readPrivateJson(temporaryPath, maximumMarkerBytes, parseMarker, 'Controller target marker artifact');
1332
+ if (!temporary) {
1333
+ const marker = { version: migrationVersion, targetCreationNonce: nonceArg };
1334
+ const serialized = `${JSON.stringify(marker)}\n`;
1335
+ let handle;
1336
+ let temporaryIdentity;
1337
+ try {
1338
+ handle = await plugins.fs.promises.open(temporaryPath, plugins.fs.constants.O_WRONLY
1339
+ | plugins.fs.constants.O_CREAT
1340
+ | plugins.fs.constants.O_EXCL
1341
+ | plugins.fs.constants.O_NOFOLLOW, 0o600);
1342
+ temporaryIdentity = pathIdentity(await handle.stat({ bigint: true }));
1343
+ await handle.chmod(0o600);
1344
+ await handle.writeFile(serialized, 'utf8');
1345
+ await handle.sync();
1346
+ await handle.close();
1347
+ handle = undefined;
1348
+ await syncDirectory(this.commonParent);
1349
+ temporary = await readPrivateJson(temporaryPath, maximumMarkerBytes, parseMarker, 'Controller target marker artifact');
1350
+ temporaryIdentity = undefined;
1351
+ }
1352
+ catch (errorArg) {
1353
+ const cleanupErrors = [];
1354
+ if (handle) {
1355
+ try {
1356
+ await handle.close();
1357
+ }
1358
+ catch (cleanupErrorArg) {
1359
+ cleanupErrors.push(cleanupErrorArg);
1360
+ }
1361
+ }
1362
+ if (temporaryIdentity) {
1363
+ try {
1364
+ await unlinkExactPath(temporaryPath, temporaryIdentity);
1365
+ await syncDirectory(this.commonParent);
1366
+ }
1367
+ catch (cleanupErrorArg) {
1368
+ cleanupErrors.push(cleanupErrorArg);
1369
+ }
1370
+ }
1371
+ if (cleanupErrors.length > 0) {
1372
+ throw new AggregateError([errorArg, ...cleanupErrors], 'Controller target marker publication failed and cleanup was incomplete.', { cause: errorArg });
1373
+ }
1374
+ throw errorArg;
1375
+ }
1376
+ }
1377
+ if (!temporary || temporary.value.targetCreationNonce !== nonceArg) {
1378
+ throw new Error('Controller target marker artifact belongs to another migration.');
1379
+ }
1380
+ await plugins.fs.promises.rename(temporaryPath, this.markerPath);
1381
+ await syncDirectory(this.newRoot);
1382
+ await syncDirectory(this.commonParent);
1383
+ await this.assertTargetMarker(nonceArg);
1384
+ }
1385
+ async inspectTargetStagingInventory(journalArg) {
1386
+ await this.assertTargetIdentity(journalArg);
1387
+ await this.assertTargetMarker(journalArg.targetCreationNonce);
1388
+ const names = await this.readBoundedDirectory(this.newRoot, 'Staged target controller root');
1389
+ let migrationTemporaryFiles = 0;
1390
+ for (const name of names) {
1391
+ const path = plugins.path.join(this.newRoot, name);
1392
+ if (name === markerFileName)
1393
+ continue;
1394
+ if (name === 'smartdb') {
1395
+ await this.requirePrivateNode(path, 'directory', 'Staged target controller database');
1396
+ continue;
1397
+ }
1398
+ if (name === 'flex-provider-credentials') {
1399
+ await this.requirePrivateNode(path, 'directory', 'Staged target Flex credential root', 0o700);
1400
+ continue;
1401
+ }
1402
+ if (name === embeddedDatabaseJournalFileName) {
1403
+ await this.requirePrivateNode(path, 'file', 'Staged target embedded database journal');
1404
+ continue;
1405
+ }
1406
+ if (embeddedDatabaseJournalTemporaryPattern.test(name)) {
1407
+ migrationTemporaryFiles += 1;
1408
+ await this.requirePrivateNode(path, 'file', 'Staged embedded database journal artifact');
1409
+ continue;
1410
+ }
1411
+ throw new Error(`Unexpected entry in staged target controller root: ${name}`);
1412
+ }
1413
+ if (migrationTemporaryFiles > maximumMigrationTemporaryFiles) {
1414
+ throw new Error('Staged target has too many embedded database journal artifacts.');
1415
+ }
1416
+ }
1417
+ async performDatabaseMigration(journalArg) {
1418
+ if (journalArg.database.phase === 'verified') {
1419
+ if (journalArg.database.strategy === 'old-relocation') {
1420
+ await this.confirmOldDatabaseRelocation(journalArg);
1421
+ await this.assertRelocatedDatabaseDigest(journalArg);
1422
+ }
1423
+ return journalArg;
1424
+ }
1425
+ if (journalArg.database.strategy === 'historical-direct') {
1426
+ return await this.performDirectHistoricalDatabaseMigration(journalArg);
1427
+ }
1428
+ if (journalArg.database.strategy !== 'old-relocation') {
1429
+ throw new Error('Controller database migration journal is not actionable.');
1430
+ }
1431
+ let journal = journalArg;
1432
+ if (journal.database.phase === 'prepared')
1433
+ journal = await this.moveOldDatabase(journal);
1434
+ if (journal.database.phase !== 'moved') {
1435
+ throw new Error('Controller database relocation did not reach its moved phase.');
1436
+ }
1437
+ await this.confirmOldDatabaseRelocation(journal);
1438
+ const database = journal.database;
1439
+ await this.assertRelocatedDatabaseDigest(journal);
1440
+ if (database.v1JournalLocation === 'legacy') {
1441
+ await rebaseCompletedEmbeddedDatabaseLocationMigration({
1442
+ sourceDirectory: database.historicalDirectory,
1443
+ previousDestinationDirectory: database.oldDirectory,
1444
+ destinationDirectory: database.targetDirectory,
1445
+ });
1446
+ }
1447
+ const verified = {
1448
+ ...journal,
1449
+ database: { ...database, phase: 'verified' },
1450
+ };
1451
+ await this.writeJournal(verified);
1452
+ return verified;
1453
+ }
1454
+ async moveOldDatabase(journalArg) {
1455
+ const database = journalArg.database;
1456
+ const destinationIdentity = await this.confirmOldDatabaseRelocation(journalArg);
1457
+ const moved = {
1458
+ ...journalArg,
1459
+ database: {
1460
+ ...database,
1461
+ phase: 'moved',
1462
+ destinationDevice: destinationIdentity.device,
1463
+ destinationInode: destinationIdentity.inode,
1464
+ },
1465
+ };
1466
+ await this.writeJournal(moved);
1467
+ return moved;
1468
+ }
1469
+ async confirmOldDatabaseRelocation(journalArg) {
1470
+ const database = journalArg.database;
1471
+ if (database.strategy !== 'old-relocation'
1472
+ || database.phase === 'pending'
1473
+ || !database.oldDirectory
1474
+ || !database.targetDirectory
1475
+ || !database.sourceDevice
1476
+ || !database.sourceInode)
1477
+ throw new Error('Controller database relocation is not prepared for replay.');
1478
+ const input = {
1479
+ sourceFolderPath: database.oldDirectory,
1480
+ destinationFolderPath: database.targetDirectory,
1481
+ relocationId: `hcon-controller-data-root-v2:${journalArg.targetCreationNonce}:smartdb`,
1482
+ };
1483
+ this.options.signal?.throwIfAborted();
1484
+ const receipt = await this.relocateStoppedDatabaseRoot(input, this.options.signal);
1485
+ const receiptRecord = assertPlainRecord(receipt, 'Controller SmartDB relocation receipt');
1486
+ const receiptKeys = [
1487
+ 'format',
1488
+ 'version',
1489
+ 'relocationId',
1490
+ 'sourceFolderPath',
1491
+ 'destinationFolderPath',
1492
+ 'providerRootId',
1493
+ 'storageRootDevice',
1494
+ 'storageRootInode',
1495
+ 'receiptSha256',
1496
+ 'sourceReceiptRetained',
1497
+ ];
1498
+ assertExactKeys(receiptRecord, receiptKeys, 'Controller SmartDB relocation receipt');
1499
+ if (receipt.format !== 'smartdb.storage-root-relocation.receipt.v1'
1500
+ || receipt.version !== 1
1501
+ || receipt.relocationId !== input.relocationId
1502
+ || receipt.sourceFolderPath !== input.sourceFolderPath
1503
+ || receipt.destinationFolderPath !== input.destinationFolderPath
1504
+ || !digestPattern.test(receipt.providerRootId)
1505
+ || !digestPattern.test(receipt.receiptSha256)
1506
+ || receipt.storageRootDevice !== database.sourceDevice
1507
+ || receipt.storageRootInode !== database.sourceInode
1508
+ || (database.phase !== 'prepared' && (receipt.storageRootDevice !== database.destinationDevice
1509
+ || receipt.storageRootInode !== database.destinationInode))
1510
+ || receipt.sourceReceiptRetained !== true)
1511
+ throw new Error('Controller SmartDB relocation receipt does not match its prepared source.');
1512
+ const retainedReceipt = await readPrivateJson(database.oldDirectory, maximumSmartDbRelocationReceiptBytes, (valueArg) => {
1513
+ const value = assertPlainRecord(valueArg, 'Retained controller SmartDB relocation receipt');
1514
+ assertExactKeys(value, receiptKeys, 'Retained controller SmartDB relocation receipt');
1515
+ return value;
1516
+ }, 'Retained controller SmartDB relocation receipt');
1517
+ if (!retainedReceipt
1518
+ || receiptKeys.some((key) => retainedReceipt.value[key] !== receiptRecord[key]))
1519
+ throw new Error('Retained controller SmartDB relocation receipt does not match the API receipt.');
1520
+ const destinationIdentity = await readDirectoryIdentity(database.targetDirectory, 'Target controller database');
1521
+ const receiptIdentity = {
1522
+ device: receipt.storageRootDevice,
1523
+ inode: receipt.storageRootInode,
1524
+ };
1525
+ if (!destinationIdentity || !identitiesEqual(destinationIdentity, receiptIdentity)) {
1526
+ throw new Error('Controller database relocation identity could not be confirmed.');
1527
+ }
1528
+ return destinationIdentity;
1529
+ }
1530
+ async assertRelocatedDatabaseDigest(journalArg) {
1531
+ const database = journalArg.database;
1532
+ const digest = await inspectDatabaseContentDigest(database.targetDirectory);
1533
+ if (digest !== database.contentDigestSha256) {
1534
+ throw new Error('Relocated controller database content digest does not match its source.');
1535
+ }
1536
+ }
1537
+ async performDirectHistoricalDatabaseMigration(journalArg) {
1538
+ const database = journalArg.database;
1539
+ if (database.phase !== 'pending' || !database.historicalDirectory) {
1540
+ throw new Error('Direct historical database migration state is invalid.');
1541
+ }
1542
+ const sourceIdentity = await readDirectoryIdentity(database.historicalDirectory, 'Historical state-root database');
1543
+ if (!sourceIdentity || !identitiesEqual(sourceIdentity, {
1544
+ device: database.sourceDevice,
1545
+ inode: database.sourceInode,
1546
+ }))
1547
+ throw new Error('Historical controller database identity changed before migration.');
1548
+ const migration = new EmbeddedDatabaseLocationMigration({
1549
+ sourceDirectory: database.historicalDirectory,
1550
+ destinationDirectory: database.targetDirectory,
1551
+ sourceSocketPath: embeddedDatabaseSocketPath(database.historicalDirectory),
1552
+ destinationSocketPath: this.options.newEmbeddedSocketPath,
1553
+ });
1554
+ await runEmbeddedDatabaseLocationMigration(migration);
1555
+ const destinationIdentity = await readDirectoryIdentity(database.targetDirectory, 'Target controller database');
1556
+ if (!destinationIdentity)
1557
+ throw new Error('Directly migrated controller database is missing.');
1558
+ const contentDigestSha256 = await inspectDatabaseContentDigest(database.targetDirectory);
1559
+ const verified = {
1560
+ ...journalArg,
1561
+ database: {
1562
+ ...database,
1563
+ phase: 'verified',
1564
+ destinationDevice: destinationIdentity.device,
1565
+ destinationInode: destinationIdentity.inode,
1566
+ contentDigestSha256,
1567
+ },
1568
+ };
1569
+ await this.writeJournal(verified);
1570
+ return verified;
1571
+ }
1572
+ async performCredentialMigrations(journalArg) {
1573
+ let journal = journalArg;
1574
+ if (journal.credentials.length === 0)
1575
+ return journal;
1576
+ const destinationRoot = plugins.path.join(this.newRoot, 'flex-provider-credentials');
1577
+ const existingDestinationRoot = await readDirectoryIdentity(destinationRoot, 'Target Flex credential root', 0o700);
1578
+ if (!existingDestinationRoot) {
1579
+ await plugins.fs.promises.mkdir(destinationRoot, { mode: 0o700 });
1580
+ await syncDirectory(this.newRoot);
1581
+ }
1582
+ await readDirectoryIdentity(destinationRoot, 'Target Flex credential root', 0o700);
1583
+ for (let index = 0; index < journal.credentials.length; index += 1) {
1584
+ const tuple = journal.credentials[index];
1585
+ if (tuple.complete)
1586
+ continue;
1587
+ this.options.signal?.throwIfAborted();
1588
+ await this.relocateCredentialStore({
1589
+ controllerHash: tuple.controllerHash,
1590
+ service: tuple.service,
1591
+ storeId: tuple.storeId,
1592
+ sourceDirectory: tuple.sourceDirectory,
1593
+ destinationDirectory: tuple.destinationDirectory,
1594
+ }, this.options.signal);
1595
+ const sourceIdentity = await readDirectoryIdentity(tuple.sourceDirectory, 'Relocated Flex credential source', 0o700);
1596
+ const destinationIdentity = await readDirectoryIdentity(tuple.destinationDirectory, 'Relocated Flex credential destination', 0o700);
1597
+ if (sourceIdentity || !destinationIdentity) {
1598
+ throw new Error(`Flex credential relocation was not confirmed: ${tuple.controllerHash}`);
1599
+ }
1600
+ const credentials = journal.credentials.map((entry, entryIndex) => entryIndex === index
1601
+ ? { ...entry, complete: true }
1602
+ : entry);
1603
+ journal = { ...journal, credentials };
1604
+ await this.writeJournal(journal);
1605
+ }
1606
+ return journal;
1607
+ }
1608
+ async validateCredentialLocations(journalArg, requireCompleteArg) {
1609
+ if (journalArg.credentials.length === 0)
1610
+ return;
1611
+ const sourceRoot = plugins.path.join(this.oldRoot, 'flex-provider-credentials');
1612
+ const destinationRoot = plugins.path.join(this.newRoot, 'flex-provider-credentials');
1613
+ const sourceRootIdentity = await readDirectoryIdentity(sourceRoot, 'Legacy Flex credential root', 0o700);
1614
+ if (!sourceRootIdentity)
1615
+ throw new Error('Legacy Flex credential root disappeared during migration.');
1616
+ const destinationRootIdentity = await readDirectoryIdentity(destinationRoot, 'Target Flex credential root', 0o700);
1617
+ if (journalArg.phase !== 'legacy-authoritative' && !destinationRootIdentity) {
1618
+ const hasDestinationStore = journalArg.credentials.some((tuple) => tuple.complete);
1619
+ if (hasDestinationStore)
1620
+ throw new Error('Target Flex credential root is missing.');
1621
+ }
1622
+ const sourceHashes = new Set(await this.readCredentialHashes(sourceRoot, 'Legacy Flex credential root'));
1623
+ const destinationHashes = destinationRootIdentity
1624
+ ? new Set(await this.readCredentialHashes(destinationRoot, 'Target Flex credential root'))
1625
+ : new Set();
1626
+ const expectedHashes = new Set(journalArg.credentials.map((tuple) => tuple.controllerHash));
1627
+ for (const hash of [...sourceHashes, ...destinationHashes]) {
1628
+ if (!expectedHashes.has(hash)) {
1629
+ throw new Error(`Unexpected Flex credential store appeared during migration: ${hash}`);
1630
+ }
1631
+ }
1632
+ for (const tuple of journalArg.credentials) {
1633
+ const sourcePresent = sourceHashes.has(tuple.controllerHash);
1634
+ const destinationPresent = destinationHashes.has(tuple.controllerHash);
1635
+ if (sourcePresent === destinationPresent) {
1636
+ throw new Error(`Flex credential store has ambiguous location: ${tuple.controllerHash}`);
1637
+ }
1638
+ if ((tuple.complete || requireCompleteArg) && !destinationPresent) {
1639
+ throw new Error(`Completed Flex credential store is not at its target: ${tuple.controllerHash}`);
1640
+ }
1641
+ }
1642
+ }
1643
+ async acquireLock(invokerIdentityArg) {
1644
+ await this.cleanupStaleLockTemporaries();
1645
+ const owner = {
1646
+ version: 1,
1647
+ uid: currentUid(),
1648
+ pid: invokerIdentityArg.pid,
1649
+ processFingerprint: invokerIdentityArg.fingerprint,
1650
+ nonce: plugins.crypto.randomBytes(32).toString('hex'),
1651
+ };
1652
+ const temporaryPath = `${this.lockPath}.tmp-${owner.uid}-${owner.pid}-${owner.nonce}`;
1653
+ const serialized = `${JSON.stringify(owner)}\n`;
1654
+ let temporaryHandle;
1655
+ let temporaryIdentity;
1656
+ let publishedLockIdentity;
1657
+ try {
1658
+ temporaryHandle = await plugins.fs.promises.open(temporaryPath, plugins.fs.constants.O_WRONLY
1659
+ | plugins.fs.constants.O_CREAT
1660
+ | plugins.fs.constants.O_EXCL
1661
+ | plugins.fs.constants.O_NOFOLLOW, 0o600);
1662
+ temporaryIdentity = pathIdentity(await temporaryHandle.stat({ bigint: true }));
1663
+ await temporaryHandle.chmod(0o600);
1664
+ await temporaryHandle.writeFile(serialized, 'utf8');
1665
+ await temporaryHandle.sync();
1666
+ await temporaryHandle.close();
1667
+ temporaryHandle = undefined;
1668
+ const publishedTemporaryIdentity = temporaryIdentity;
1669
+ for (let attempt = 0; attempt < maximumLockAttempts; attempt += 1) {
1670
+ this.options.signal?.throwIfAborted();
1671
+ if ((await this.listLockArtifacts()).guards.length > 0) {
1672
+ await this.cleanupStaleLockTemporaries();
1673
+ await delay(lockWaitMilliseconds, this.options.signal);
1674
+ continue;
1675
+ }
1676
+ try {
1677
+ await plugins.fs.promises.link(temporaryPath, this.lockPath);
1678
+ publishedLockIdentity = publishedTemporaryIdentity;
1679
+ await syncDirectory(this.commonParent);
1680
+ const published = await this.readLockSnapshot(this.lockPath);
1681
+ if (!published
1682
+ || !identitiesEqual(published.identity, publishedTemporaryIdentity)
1683
+ || JSON.stringify(published.owner) !== JSON.stringify(owner))
1684
+ throw new Error('Published controller migration lock does not match its owner record.');
1685
+ await unlinkExactPath(temporaryPath, publishedTemporaryIdentity);
1686
+ temporaryIdentity = undefined;
1687
+ await syncDirectory(this.commonParent);
1688
+ publishedLockIdentity = undefined;
1689
+ return { owner, identity: published.identity };
1690
+ }
1691
+ catch (errorArg) {
1692
+ if (errorArg.code !== 'EEXIST')
1693
+ throw errorArg;
1694
+ }
1695
+ const existing = await this.readLockSnapshot(this.lockPath);
1696
+ if (!existing)
1697
+ continue;
1698
+ if (existing.owner.uid !== currentUid()) {
1699
+ throw new Error('Controller data-root migration lock belongs to another user.');
1700
+ }
1701
+ if (await this.lockOwnerIsLive(existing.owner)) {
1702
+ await delay(lockWaitMilliseconds, this.options.signal);
1703
+ continue;
1704
+ }
1705
+ await this.reclaimStaleLock(existing);
1706
+ }
1707
+ throw new Error('Timed out waiting for the controller data-root migration lock.');
1708
+ }
1709
+ catch (errorArg) {
1710
+ const cleanupErrors = [];
1711
+ let directoryChanged = false;
1712
+ if (temporaryHandle) {
1713
+ try {
1714
+ await temporaryHandle.close();
1715
+ temporaryHandle = undefined;
1716
+ }
1717
+ catch (cleanupErrorArg) {
1718
+ cleanupErrors.push(cleanupErrorArg);
1719
+ }
1720
+ }
1721
+ if (publishedLockIdentity) {
1722
+ try {
1723
+ await unlinkExactPath(this.lockPath, publishedLockIdentity);
1724
+ directoryChanged = true;
1725
+ }
1726
+ catch (cleanupErrorArg) {
1727
+ cleanupErrors.push(cleanupErrorArg);
1728
+ }
1729
+ }
1730
+ if (temporaryIdentity) {
1731
+ try {
1732
+ await unlinkExactPath(temporaryPath, temporaryIdentity);
1733
+ directoryChanged = true;
1734
+ }
1735
+ catch (cleanupErrorArg) {
1736
+ cleanupErrors.push(cleanupErrorArg);
1737
+ }
1738
+ }
1739
+ if (directoryChanged) {
1740
+ try {
1741
+ await syncDirectory(this.commonParent);
1742
+ }
1743
+ catch (cleanupErrorArg) {
1744
+ cleanupErrors.push(cleanupErrorArg);
1745
+ }
1746
+ }
1747
+ if (cleanupErrors.length > 0) {
1748
+ throw new AggregateError([errorArg, ...cleanupErrors], 'Controller migration lock publication failed and cleanup was incomplete.', { cause: errorArg });
1749
+ }
1750
+ throw errorArg;
1751
+ }
1752
+ }
1753
+ async readLockSnapshot(pathArg) {
1754
+ const snapshot = await readPrivateJson(pathArg, maximumLockBytes, parseLockOwner, 'Controller data-root migration lock');
1755
+ return snapshot ? { owner: snapshot.value, identity: snapshot.identity } : undefined;
1756
+ }
1757
+ async lockOwnerIsLive(ownerArg) {
1758
+ const identity = await readControllerProcessIdentity(ownerArg.pid);
1759
+ return identity !== null && identity.fingerprint === ownerArg.processFingerprint;
1760
+ }
1761
+ async reclaimStaleLock(snapshotArg) {
1762
+ const guardPath = `${this.lockPath}.guard-${snapshotArg.owner.nonce}`;
1763
+ let guardCreated = false;
1764
+ let guardIdentity;
1765
+ let operationError;
1766
+ try {
1767
+ try {
1768
+ await plugins.fs.promises.link(this.lockPath, guardPath);
1769
+ guardCreated = true;
1770
+ guardIdentity = snapshotArg.identity;
1771
+ }
1772
+ catch (errorArg) {
1773
+ if (errorArg.code === 'EEXIST')
1774
+ return;
1775
+ throw errorArg;
1776
+ }
1777
+ await syncDirectory(this.commonParent);
1778
+ const guard = await this.readLockSnapshot(guardPath);
1779
+ const stable = await this.readLockSnapshot(this.lockPath);
1780
+ if (!guard
1781
+ || !stable
1782
+ || !identitiesEqual(guard.identity, snapshotArg.identity)
1783
+ || !identitiesEqual(stable.identity, snapshotArg.identity)
1784
+ || JSON.stringify(guard.owner) !== JSON.stringify(snapshotArg.owner))
1785
+ throw new Error('Controller migration stale-lock guard does not match the guarded owner.');
1786
+ guardIdentity = guard.identity;
1787
+ if (await this.lockOwnerIsLive(guard.owner)) {
1788
+ throw new Error('Controller migration lock owner became live during stale reclaim.');
1789
+ }
1790
+ const stableBeforeUnlink = await this.readLockSnapshot(this.lockPath);
1791
+ if (!stableBeforeUnlink || !identitiesEqual(stableBeforeUnlink.identity, guard.identity)) {
1792
+ throw new Error('Controller migration lock changed during stale reclaim.');
1793
+ }
1794
+ await plugins.fs.promises.unlink(this.lockPath);
1795
+ await syncDirectory(this.commonParent);
1796
+ await unlinkExactPath(guardPath, guard.identity);
1797
+ guardCreated = false;
1798
+ guardIdentity = undefined;
1799
+ await syncDirectory(this.commonParent);
1800
+ }
1801
+ catch (errorArg) {
1802
+ operationError = errorArg;
1803
+ }
1804
+ const cleanupErrors = [];
1805
+ if (guardCreated && guardIdentity) {
1806
+ try {
1807
+ await unlinkExactPath(guardPath, guardIdentity);
1808
+ await syncDirectory(this.commonParent);
1809
+ }
1810
+ catch (cleanupErrorArg) {
1811
+ cleanupErrors.push(cleanupErrorArg);
1812
+ }
1813
+ }
1814
+ if (operationError) {
1815
+ if (cleanupErrors.length > 0) {
1816
+ throw new AggregateError([operationError, ...cleanupErrors], 'Controller stale-lock reclaim failed and guard cleanup was incomplete.', { cause: operationError });
1817
+ }
1818
+ throw operationError;
1819
+ }
1820
+ if (cleanupErrors.length > 0) {
1821
+ throw new AggregateError(cleanupErrors, 'Controller stale-lock guard cleanup was incomplete.');
1822
+ }
1823
+ }
1824
+ async releaseLock(leaseArg) {
1825
+ const current = await this.readLockSnapshot(this.lockPath);
1826
+ if (!current
1827
+ || !identitiesEqual(current.identity, leaseArg.identity)
1828
+ || current.owner.nonce !== leaseArg.owner.nonce
1829
+ || JSON.stringify(current.owner) !== JSON.stringify(leaseArg.owner))
1830
+ throw new Error('Controller data-root migration lock release is ambiguous.');
1831
+ await plugins.fs.promises.unlink(this.lockPath);
1832
+ await syncDirectory(this.commonParent);
1833
+ }
1834
+ async listLockArtifacts() {
1835
+ const base = plugins.path.basename(this.lockPath);
1836
+ const entries = await plugins.fs.promises.readdir(this.commonParent, { withFileTypes: true });
1837
+ const related = entries.map((entry) => entry.name).filter((name) => name.startsWith(`${base}.`));
1838
+ if (related.length > maximumLockArtifacts) {
1839
+ throw new Error('Too many controller migration lock artifacts exist.');
1840
+ }
1841
+ const temporaryPattern = new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.tmp-[0-9]+-[1-9][0-9]*-[a-f0-9]{64}$`);
1842
+ const guardPattern = new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.guard-[a-f0-9]{64}$`);
1843
+ const temporaries = [];
1844
+ const guards = [];
1845
+ for (const name of related) {
1846
+ if (temporaryPattern.test(name))
1847
+ temporaries.push(name);
1848
+ else if (guardPattern.test(name))
1849
+ guards.push(name);
1850
+ else
1851
+ throw new Error(`Unknown controller migration lock artifact: ${name}`);
1852
+ }
1853
+ return { temporaries: temporaries.sort(), guards: guards.sort() };
1854
+ }
1855
+ async cleanupStaleLockTemporaries() {
1856
+ const artifacts = await this.listLockArtifacts();
1857
+ let directoryChanged = false;
1858
+ for (const name of artifacts.temporaries) {
1859
+ const path = plugins.path.join(this.commonParent, name);
1860
+ const snapshot = await this.readLockSnapshot(path);
1861
+ if (!snapshot || snapshot.owner.uid !== currentUid()) {
1862
+ throw new Error('Controller migration lock temporary artifact is invalid.');
1863
+ }
1864
+ if (!await this.lockOwnerIsLive(snapshot.owner)) {
1865
+ await unlinkExactPath(path, snapshot.identity);
1866
+ directoryChanged = true;
1867
+ }
1868
+ }
1869
+ for (const name of artifacts.guards) {
1870
+ const path = plugins.path.join(this.commonParent, name);
1871
+ const guard = await this.readLockSnapshot(path);
1872
+ if (!guard)
1873
+ throw new Error('Controller migration lock guard disappeared during inspection.');
1874
+ if (guard.owner.uid !== currentUid()) {
1875
+ throw new Error('Controller migration lock guard belongs to another user.');
1876
+ }
1877
+ if (!await this.lockOwnerIsLive(guard.owner)) {
1878
+ await unlinkExactPath(path, guard.identity);
1879
+ directoryChanged = true;
1880
+ }
1881
+ }
1882
+ if (directoryChanged) {
1883
+ await syncDirectory(this.commonParent);
1884
+ }
1885
+ }
1886
+ }
1887
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidjJfY29udHJvbGxlcmRhdGFyb290LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfbWlncmF0aW9uL3YyX2NvbnRyb2xsZXJkYXRhcm9vdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sRUFDTCw2QkFBNkIsR0FFOUIsTUFBTSxvQ0FBb0MsQ0FBQztBQUM1QyxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLGlCQUFpQixJQUFJLHdCQUF3QixHQUM5QyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFDTCxpQ0FBaUMsRUFDakMsZ0RBQWdELEdBQ2pELE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFakYsTUFBTSxnQkFBZ0IsR0FBRyxDQUFVLENBQUM7QUFDcEMsTUFBTSxlQUFlLEdBQUcsMkNBQTJDLENBQUM7QUFDcEUsTUFBTSxZQUFZLEdBQUcsMkNBQTJDLENBQUM7QUFDakUsTUFBTSxjQUFjLEdBQUcsd0NBQXdDLENBQUM7QUFDaEUsTUFBTSwrQkFBK0IsR0FBRyxrQ0FBa0MsQ0FBQztBQUMzRSxNQUFNLG1CQUFtQixHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDdkMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ25DLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNwQyxNQUFNLG9DQUFvQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDdkQsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUM7QUFDakMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFDcEMsTUFBTSw4QkFBOEIsR0FBRyxFQUFFLENBQUM7QUFDMUMsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFDbEMsTUFBTSxrQkFBa0IsR0FBRyxFQUFF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