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,2483 @@
1
+ import * as plugins from './plugins.js';
2
+ import { EmbeddedControllerDatabase } from './classes.embeddeddb.js';
3
+ import { AuthError, } from './interfaces.auth.js';
4
+ import { ControllerAuditEventModel, ControllerAuthModel, ControllerProjectModel, ControllerResourceModel, ControllerSessionGroupsModel, ControllerSessionStateModel, ControllerSettingsModel, ControllerTempPasswordModel, isProjectRelativePathName, WebAuthnCeremonyModel, controllerSessionStateId, } from './classes.authmodels.js';
5
+ import { controllerProjectLimit, controllerResourceLimit, controllerResourcesPerProjectLimit, } from './interfaces.projects.js';
6
+ import { controllerRuntimeIdKey } from '../dist_ts_interfaces/index.js';
7
+ import { PostDatabaseDocumentMigrationRunner, } from '../dist_ts_migration/classes.documentmigrationrunner.js';
8
+ import { filesystemIdentitiesEqual } from './functions.canonicaldirectory.js';
9
+ // The audit log is write-only telemetry with no reader; retention keeps the
10
+ // embedded engine's working set bounded. This is load-bearing on smartdb:
11
+ // the engine resolves indexed lookups and unique checks by scanning, so
12
+ // per-operation cost grows linearly with collection size — a hard count cap
13
+ // keeps every scan trivially small. Deletes run in limit-bounded id batches
14
+ // because broad deleteMany filters can exceed smartdb's per-operation
15
+ // materialization capacity on large collections.
16
+ const auditRetentionMs = 7 * 24 * 60 * 60 * 1000;
17
+ const auditRetentionMaxEvents = 2_000;
18
+ const auditRetentionCountSlack = 500;
19
+ const auditPruneBatchSize = 1000;
20
+ const auditPruneMaxBatchesPerSweep = 50;
21
+ // The count cap must be able to clear a large pre-existing backlog in one
22
+ // sweep; each batch is a bounded id page, so this stays cheap per round trip.
23
+ const auditCountPruneMaxBatchesPerSweep = 250;
24
+ const auditPruneIntervalMs = 30 * 60 * 1000;
25
+ const setupLifetimeMs = 30 * 60 * 1000;
26
+ // CLI-minted temporary passwords: a debugging credential, deliberately capped.
27
+ const tempPasswordTtlMinMs = 60 * 1000;
28
+ const tempPasswordTtlMaxMs = 24 * 60 * 60 * 1000;
29
+ const maxActiveTempPasswords = 8;
30
+ const tempPasswordPattern = /^[A-Za-z0-9_-]{32}$/;
31
+ const sessionModelChoiceClearTransitionMaxAttempts = 16;
32
+ // Operator-provided codes are allowed, so the accepted shape is any printable
33
+ // non-whitespace ASCII within DoS-safe length bounds; only the hash is stored.
34
+ const setupCodePattern = /^[\x21-\x7e]{4,256}$/;
35
+ const ceremonyIdPattern = /^[A-Za-z0-9_-]{43}$/;
36
+ const randomAuthorityValue = () => plugins.crypto.randomBytes(32).toString('base64url');
37
+ const randomResourceId = () => plugins.crypto.randomBytes(16).toString('base64url');
38
+ const randomResourceOperationId = () => plugins.crypto.randomBytes(16).toString('base64url');
39
+ const cloneSessionId = (sessionIdArg) => (sessionIdArg === null ? null : { ...sessionIdArg });
40
+ const isSessionId = (valueArg) => valueArg.harnessId === 'opencode' || valueArg.harnessId === 'flex';
41
+ const cloneResourceDocument = (resourceArg) => ({
42
+ ...resourceArg,
43
+ sessionId: cloneSessionId(resourceArg.sessionId),
44
+ ...(resourceArg.pendingAttachment === undefined ? {} : {
45
+ pendingAttachment: {
46
+ ...resourceArg.pendingAttachment,
47
+ sessionId: cloneSessionId(resourceArg.pendingAttachment.sessionId),
48
+ },
49
+ }),
50
+ ...(resourceArg.terminal === undefined ? {} : { terminal: { ...resourceArg.terminal } }),
51
+ });
52
+ const cloneModelChoice = (modelArg) => (modelArg.harnessId === 'opencode'
53
+ ? {
54
+ harnessId: 'opencode',
55
+ providerID: modelArg.providerID,
56
+ modelID: modelArg.modelID,
57
+ ...(modelArg.variant === undefined ? {} : { variant: modelArg.variant }),
58
+ }
59
+ : {
60
+ harnessId: 'flex',
61
+ providerConnectionId: modelArg.providerConnectionId,
62
+ providerID: modelArg.providerID,
63
+ modelID: modelArg.modelID,
64
+ ...(modelArg.variant === undefined ? {} : { variant: modelArg.variant }),
65
+ });
66
+ export const assertProvidedSetupCode = (setupCodeArg) => {
67
+ if (typeof setupCodeArg !== 'string' || !setupCodePattern.test(setupCodeArg)) {
68
+ throw new Error('A setup code must be 4-256 printable non-whitespace ASCII characters.');
69
+ }
70
+ return setupCodeArg;
71
+ };
72
+ const cloneRuntimeConfig = (runtimeConfigArg) => ({
73
+ controllerPort: runtimeConfigArg.controllerPort,
74
+ publicOrigin: runtimeConfigArg.publicOrigin,
75
+ rpId: runtimeConfigArg.rpId,
76
+ workspaceDirectory: runtimeConfigArg.workspaceDirectory,
77
+ // The key must be absent, not undefined-valued, for exact persistence.
78
+ ...(runtimeConfigArg.projectsRoot !== undefined
79
+ ? { projectsRoot: runtimeConfigArg.projectsRoot }
80
+ : {}),
81
+ opencodePort: runtimeConfigArg.opencodePort,
82
+ tlsMode: runtimeConfigArg.tlsMode,
83
+ });
84
+ const runtimeConfigsEqual = (leftArg, rightArg) => leftArg.controllerPort === rightArg.controllerPort
85
+ && leftArg.publicOrigin === rightArg.publicOrigin
86
+ && leftArg.rpId === rightArg.rpId
87
+ && leftArg.workspaceDirectory === rightArg.workspaceDirectory
88
+ && leftArg.projectsRoot === rightArg.projectsRoot
89
+ && leftArg.opencodePort === rightArg.opencodePort
90
+ && leftArg.tlsMode === rightArg.tlsMode;
91
+ const hashSetupCode = (setupCodeArg) => plugins.crypto.createHash('sha256').update(setupCodeArg, 'utf8').digest('base64url');
92
+ const hashesEqual = (leftArg, rightArg) => {
93
+ const left = Buffer.from(leftArg, 'base64url');
94
+ const right = Buffer.from(rightArg, 'base64url');
95
+ return left.byteLength === right.byteLength && plugins.crypto.timingSafeEqual(left, right);
96
+ };
97
+ const requireSafeCounter = (counterArg, labelArg) => {
98
+ if (!Number.isSafeInteger(counterArg) || counterArg < 0) {
99
+ throw new AuthError('counter_conflict', `${labelArg} must be a non-negative safe integer.`);
100
+ }
101
+ };
102
+ const requireCeremonyKind = (kindArg) => {
103
+ if (kindArg !== 'setup' && kindArg !== 'authentication') {
104
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony kind is invalid.');
105
+ }
106
+ return kindArg;
107
+ };
108
+ const requireCeremonyId = (ceremonyIdArg) => {
109
+ if (typeof ceremonyIdArg !== 'string' || !ceremonyIdPattern.test(ceremonyIdArg)) {
110
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony identifier is invalid.');
111
+ }
112
+ return ceremonyIdArg;
113
+ };
114
+ const requirePeerId = (peerIdArg) => {
115
+ if (typeof peerIdArg !== 'string'
116
+ || peerIdArg.length === 0
117
+ || peerIdArg.length > 512
118
+ || peerIdArg.trim() !== peerIdArg) {
119
+ throw new AuthError('peer_mismatch', 'The connection identity is malformed.');
120
+ }
121
+ return peerIdArg;
122
+ };
123
+ const requireOrigin = (originArg) => {
124
+ if (typeof originArg !== 'string' || originArg.length === 0 || originArg.length > 2048) {
125
+ throw new AuthError('origin_mismatch', 'The ceremony origin is malformed.');
126
+ }
127
+ try {
128
+ const origin = new URL(originArg);
129
+ if (origin.origin !== originArg
130
+ || (origin.protocol !== 'http:' && origin.protocol !== 'https:')
131
+ || origin.username.length > 0
132
+ || origin.password.length > 0
133
+ || origin.pathname !== '/'
134
+ || origin.search.length > 0
135
+ || origin.hash.length > 0) {
136
+ throw new Error('not an origin');
137
+ }
138
+ }
139
+ catch {
140
+ throw new AuthError('origin_mismatch', 'The ceremony origin is malformed.');
141
+ }
142
+ return originArg;
143
+ };
144
+ const rpIdPattern = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/;
145
+ const requireRpId = (rpIdArg) => {
146
+ if (typeof rpIdArg !== 'string' || !rpIdPattern.test(rpIdArg)) {
147
+ throw new AuthError('ceremony_invalid', 'The ceremony RP ID is malformed.');
148
+ }
149
+ return rpIdArg;
150
+ };
151
+ const requireUserId = (userIdArg) => {
152
+ if (typeof userIdArg !== 'string' || !ceremonyIdPattern.test(userIdArg)) {
153
+ throw new AuthError('ceremony_invalid', 'The ceremony user identifier is malformed.');
154
+ }
155
+ return userIdArg;
156
+ };
157
+ const requireValidDate = (dateArg, labelArg) => {
158
+ if (!(dateArg instanceof Date) || !Number.isFinite(dateArg.getTime())) {
159
+ throw new AuthError('ceremony_invalid', `${labelArg} must be a valid date.`);
160
+ }
161
+ return new Date(dateArg);
162
+ };
163
+ const isAmbiguousWrite = (errorArg) => errorArg instanceof plugins.smartdata.SmartdataExactPersistenceError
164
+ && errorArg.code === 'ambiguous_write';
165
+ const sessionStateRecoveryLimit = 500;
166
+ const sessionStateRetirementPageLimit = 100;
167
+ const maxSessionStateRetirementPages = 100;
168
+ const maxSessionStateExchanges = 8;
169
+ const maxSessionStateExchangeBytes = 256 * 1024;
170
+ const toPublicIntelligenceExchange = (exchangeArg) => ({
171
+ id: exchangeArg.id,
172
+ question: exchangeArg.question,
173
+ status: exchangeArg.status,
174
+ ...(exchangeArg.answer === undefined ? {} : { answer: exchangeArg.answer }),
175
+ ...(exchangeArg.error === undefined ? {} : { error: exchangeArg.error }),
176
+ ...(exchangeArg.model === undefined ? {} : { model: exchangeArg.model }),
177
+ ...(exchangeArg.scratchpadConflict === undefined
178
+ ? {}
179
+ : { scratchpadConflict: exchangeArg.scratchpadConflict }),
180
+ createdAt: exchangeArg.createdAt.getTime(),
181
+ ...(exchangeArg.completedAt === undefined
182
+ ? {}
183
+ : { completedAt: exchangeArg.completedAt.getTime() }),
184
+ });
185
+ const toPublicSessionState = (documentArg) => ({
186
+ scratchpad: {
187
+ id: documentArg.id,
188
+ text: documentArg.scratchpad.text,
189
+ revision: documentArg.scratchpad.revision,
190
+ ...(documentArg.scratchpad.updatedAt === undefined
191
+ ? {}
192
+ : { updatedAt: documentArg.scratchpad.updatedAt.getTime() }),
193
+ ...(documentArg.scratchpad.updatedBy === undefined
194
+ ? {}
195
+ : { updatedBy: documentArg.scratchpad.updatedBy }),
196
+ },
197
+ intelligenceExchanges: documentArg.intelligenceExchanges.map(toPublicIntelligenceExchange),
198
+ ...(documentArg.modelChoice === undefined
199
+ ? {}
200
+ : { modelChoice: cloneModelChoice(documentArg.modelChoice) }),
201
+ });
202
+ const trimSessionStateExchanges = (exchangesArg, protectedExchangeIdArg) => {
203
+ const exchanges = exchangesArg.slice(-maxSessionStateExchanges);
204
+ while (exchanges.length > 1
205
+ && Buffer.byteLength(JSON.stringify(exchanges), 'utf8') > maxSessionStateExchangeBytes) {
206
+ const removableIndex = exchanges.findIndex((exchange) => exchange.id !== protectedExchangeIdArg && exchange.status !== 'running');
207
+ if (removableIndex < 0)
208
+ break;
209
+ exchanges.splice(removableIndex, 1);
210
+ }
211
+ return exchanges;
212
+ };
213
+ const projectManagementStoreKey = (projectIdArg, sessionIdArg) => JSON.stringify([projectIdArg, sessionIdArg]);
214
+ const cloneProjectManagementRecord = (recordArg) => structuredClone(recordArg);
215
+ const sameProjectManagementGeneration = (leftArg, rightArg) => leftArg.sessionGenerationId === rightArg.sessionGenerationId
216
+ && leftArg.sessionGenerationSequence === rightArg.sessionGenerationSequence;
217
+ const canInitializeProjectManagementGeneration = (currentArg, nextArg, expectedRevisionArg) => Object.hasOwn(currentArg, 'deletedAt')
218
+ && expectedRevisionArg === 0
219
+ && nextArg.sessionGenerationId !== currentArg.sessionGenerationId
220
+ && nextArg.sessionGenerationSequence > currentArg.sessionGenerationSequence;
221
+ const assertFlexSessionGeneration = (generationArg) => {
222
+ if (!generationArg
223
+ || typeof generationArg.sessionGenerationId !== 'string'
224
+ || generationArg.sessionGenerationId.trim().length === 0
225
+ || Buffer.byteLength(generationArg.sessionGenerationId, 'utf8')
226
+ > plugins.flexharness.FLEX_SESSION_GENERATION_ID_MAX_BYTES
227
+ || !Number.isSafeInteger(generationArg.sessionGenerationSequence)
228
+ || generationArg.sessionGenerationSequence < 1) {
229
+ throw new plugins.flexharness.FlexHarnessStoreFormatError('The Flex project-management session generation is invalid.');
230
+ }
231
+ };
232
+ const assertProjectManagementWriteContext = (writeContextArg) => {
233
+ if (!writeContextArg
234
+ || typeof writeContextArg !== 'object'
235
+ || Array.isArray(writeContextArg)
236
+ || ![Object.prototype, null].includes(Object.getPrototypeOf(writeContextArg))
237
+ || Object.keys(writeContextArg).some((key) => !['actor', 'runId', 'agent', 'toolCallId'].includes(key))
238
+ || (writeContextArg.actor !== 'agent' && writeContextArg.actor !== 'application')
239
+ || ['runId', 'agent', 'toolCallId'].some((key) => {
240
+ const value = writeContextArg[key];
241
+ return value !== undefined && (typeof value !== 'string' || value.trim().length === 0);
242
+ })) {
243
+ throw new plugins.flexharness.FlexHarnessStoreFormatError('The Flex project-management write context is invalid.');
244
+ }
245
+ };
246
+ const assertProjectManagementNextRevision = (recordArg, expectedRevisionArg) => {
247
+ if (!Number.isSafeInteger(expectedRevisionArg) || expectedRevisionArg < 0) {
248
+ throw new plugins.flexharness.FlexHarnessStoreFormatError('The expected Flex project-management revision is invalid.');
249
+ }
250
+ if (recordArg.revision !== expectedRevisionArg + 1) {
251
+ throw new plugins.flexharness.FlexHarnessStoreFormatError('The Flex project-management revision must advance by exactly one.');
252
+ }
253
+ };
254
+ const projectManagementUpdater = (writeContextArg) => writeContextArg.actor;
255
+ export const assertControllerResourceCreationCapacity = (projectResourceCountArg, controllerResourceCountArg) => {
256
+ if (controllerResourceCountArg >= controllerResourceLimit) {
257
+ throw new AuthError('invalid_resource', `The controller supports at most ${controllerResourceLimit} resources.`);
258
+ }
259
+ if (projectResourceCountArg >= controllerResourcesPerProjectLimit) {
260
+ throw new AuthError('invalid_resource', `A project supports at most ${controllerResourcesPerProjectLimit} resources.`);
261
+ }
262
+ };
263
+ export class SmartDataAuthStore {
264
+ options;
265
+ database;
266
+ embeddedDatabase;
267
+ // smartdata resolves the manager's db lazily per operation, so the
268
+ // manager can be registered before init() constructs the database.
269
+ smartDataManager;
270
+ initialized = false;
271
+ initPromise;
272
+ controllerId;
273
+ resolvedMongoDbUrl;
274
+ closePromise;
275
+ closeStarted = false;
276
+ projectMutationAdmissionOpen = false;
277
+ projectMutationTail = Promise.resolve();
278
+ sessionStateMutationTail = Promise.resolve();
279
+ auditPruneTimer;
280
+ runSessionStateMutation(operationArg) {
281
+ if (this.closeStarted) {
282
+ return Promise.reject(new AuthError('not_initialized', 'The authentication store is shutting down.'));
283
+ }
284
+ const result = this.sessionStateMutationTail.then(operationArg);
285
+ this.sessionStateMutationTail = result.then(() => undefined, () => undefined);
286
+ return result;
287
+ }
288
+ constructor(options) {
289
+ this.options = options;
290
+ const hasExternalUrl = typeof options.mongoDbUrl === 'string'
291
+ && options.mongoDbUrl.trim().length > 0;
292
+ const hasEmbeddedDirectory = typeof options.embeddedDataDirectory === 'string'
293
+ && plugins.path.isAbsolute(options.embeddedDataDirectory);
294
+ if (!hasExternalUrl && !hasEmbeddedDirectory) {
295
+ throw new Error('Either mongoDbUrl or an absolute embeddedDataDirectory must be provided.');
296
+ }
297
+ if (!/^[A-Za-z0-9_-]{1,63}$/.test(options.mongoDbName)) {
298
+ throw new Error('mongoDbName must use 1-63 letters, digits, underscores, or dashes.');
299
+ }
300
+ const storeSelf = this;
301
+ this.smartDataManager = {
302
+ get db() {
303
+ return storeSelf.db;
304
+ },
305
+ };
306
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerAuthModel);
307
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, WebAuthnCeremonyModel);
308
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerAuditEventModel);
309
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerProjectModel);
310
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerResourceModel);
311
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerSettingsModel);
312
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerTempPasswordModel);
313
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerSessionGroupsModel);
314
+ plugins.smartdata.setDefaultManagerForDoc(this.smartDataManager, ControllerSessionStateModel);
315
+ }
316
+ get db() {
317
+ if (!this.database) {
318
+ throw new Error('The auth store database has not been initialized.');
319
+ }
320
+ return this.database;
321
+ }
322
+ async init() {
323
+ if (this.closeStarted) {
324
+ throw new Error('SmartDataAuthStore cannot initialize after shutdown has begun.');
325
+ }
326
+ if (this.initialized)
327
+ return;
328
+ if (this.initPromise)
329
+ return this.initPromise;
330
+ if (this.database || this.embeddedDatabase) {
331
+ throw new Error('SmartData cleanup must complete before initialization can be retried.');
332
+ }
333
+ const initPromise = this.initOnce();
334
+ this.initPromise = initPromise;
335
+ try {
336
+ await initPromise;
337
+ }
338
+ finally {
339
+ if (this.initPromise === initPromise)
340
+ this.initPromise = undefined;
341
+ }
342
+ }
343
+ async initOnce() {
344
+ try {
345
+ let mongoDbUrl = this.options.mongoDbUrl?.trim();
346
+ if (!mongoDbUrl) {
347
+ const embedded = new EmbeddedControllerDatabase({
348
+ dataDirectory: this.options.embeddedDataDirectory,
349
+ legacyDataDirectory: this.options.legacyEmbeddedDataDirectory,
350
+ });
351
+ this.embeddedDatabase = embedded;
352
+ mongoDbUrl = await embedded.start();
353
+ }
354
+ this.database = new plugins.smartdata.SmartdataDb({
355
+ mongoDbUrl,
356
+ mongoDbName: this.options.mongoDbName,
357
+ });
358
+ this.resolvedMongoDbUrl = mongoDbUrl;
359
+ await this.db.init();
360
+ await ControllerAuthModel.init();
361
+ await WebAuthnCeremonyModel.init();
362
+ await ControllerAuditEventModel.init();
363
+ await ControllerProjectModel.init();
364
+ await ControllerResourceModel.init();
365
+ await ControllerSettingsModel.init();
366
+ await ControllerTempPasswordModel.init();
367
+ await ControllerSessionGroupsModel.init();
368
+ await ControllerSessionStateModel.init();
369
+ await new PostDatabaseDocumentMigrationRunner(this.database).run();
370
+ this.initialized = true;
371
+ if (!this.closeStarted)
372
+ this.projectMutationAdmissionOpen = true;
373
+ }
374
+ catch (errorArg) {
375
+ const cleanupErrors = [];
376
+ if (this.database) {
377
+ try {
378
+ await this.database.close();
379
+ this.database = undefined;
380
+ this.resolvedMongoDbUrl = undefined;
381
+ }
382
+ catch (closeErrorArg) {
383
+ cleanupErrors.push(closeErrorArg);
384
+ }
385
+ }
386
+ try {
387
+ await this.stopEmbeddedDatabase();
388
+ }
389
+ catch (stopErrorArg) {
390
+ cleanupErrors.push(stopErrorArg);
391
+ }
392
+ if (cleanupErrors.length > 0) {
393
+ throw new AggregateError([errorArg, ...cleanupErrors], 'SmartData initialization failed and cleanup was incomplete.', { cause: errorArg });
394
+ }
395
+ throw errorArg;
396
+ }
397
+ // Retention is maintenance and must never gate readiness: clearing a
398
+ // large pre-existing backlog takes far longer than the controller's
399
+ // startup budget, so the first sweep runs detached like every later one.
400
+ void this.pruneAuditHistory();
401
+ this.auditPruneTimer = setInterval(() => {
402
+ void this.pruneAuditHistory();
403
+ }, auditPruneIntervalMs);
404
+ this.auditPruneTimer.unref?.();
405
+ }
406
+ async pruneAuditHistory() {
407
+ try {
408
+ const collection = ControllerAuditEventModel.collection.mongoDbCollection;
409
+ // Count cap first: it bounds the collection regardless of event rate,
410
+ // which the age rule alone cannot (heavy days produce tens of
411
+ // thousands of events).
412
+ const count = await collection.estimatedDocumentCount();
413
+ if (count > auditRetentionMaxEvents + auditRetentionCountSlack) {
414
+ // One bounded batch per round trip: a sorted find whose limit is the
415
+ // full excess exceeds the engine's per-operation materialization
416
+ // ceiling once the backlog is large (which is exactly when this
417
+ // runs). Re-reading the oldest page after each delete converges.
418
+ let remaining = count - auditRetentionMaxEvents;
419
+ for (let batch = 0; batch < auditCountPruneMaxBatchesPerSweep && remaining > 0; batch++) {
420
+ const pageSize = Math.min(auditPruneBatchSize, remaining);
421
+ const excess = await collection
422
+ .find({}, { projection: { _id: 1 } })
423
+ .sort({ timestamp: 1 })
424
+ .limit(pageSize)
425
+ .toArray();
426
+ if (excess.length === 0)
427
+ break;
428
+ await collection.deleteMany({ _id: { $in: excess.map((doc) => doc._id) } });
429
+ remaining -= excess.length;
430
+ }
431
+ }
432
+ const cutoffIso = new Date(Date.now() - auditRetentionMs).toISOString();
433
+ for (let batch = 0; batch < auditPruneMaxBatchesPerSweep; batch++) {
434
+ const expired = await collection
435
+ .find({ timestamp: { $lt: cutoffIso } }, { projection: { _id: 1 } })
436
+ .limit(auditPruneBatchSize)
437
+ .toArray();
438
+ if (expired.length === 0)
439
+ return;
440
+ await collection.deleteMany({ _id: { $in: expired.map((doc) => doc._id) } });
441
+ if (expired.length < auditPruneBatchSize)
442
+ return;
443
+ }
444
+ }
445
+ catch (errorArg) {
446
+ // Retention is maintenance; it must never take the controller down.
447
+ console.error('Audit history pruning failed.', errorArg);
448
+ }
449
+ }
450
+ async stopEmbeddedDatabase() {
451
+ const embedded = this.embeddedDatabase;
452
+ if (embedded) {
453
+ await embedded.stop();
454
+ if (this.embeddedDatabase === embedded)
455
+ this.embeddedDatabase = undefined;
456
+ }
457
+ }
458
+ async close() {
459
+ this.closeStarted = true;
460
+ this.projectMutationAdmissionOpen = false;
461
+ if (this.closePromise)
462
+ return this.closePromise;
463
+ const closePromise = (async () => {
464
+ if (this.initPromise)
465
+ await this.initPromise.catch(() => undefined);
466
+ await this.projectMutationTail;
467
+ await this.sessionStateMutationTail;
468
+ if (!this.database && !this.embeddedDatabase)
469
+ return;
470
+ if (this.auditPruneTimer) {
471
+ clearInterval(this.auditPruneTimer);
472
+ this.auditPruneTimer = undefined;
473
+ }
474
+ const cleanupErrors = [];
475
+ if (this.database) {
476
+ try {
477
+ await this.database.close();
478
+ this.database = undefined;
479
+ this.resolvedMongoDbUrl = undefined;
480
+ }
481
+ catch (errorArg) {
482
+ cleanupErrors.push(errorArg);
483
+ }
484
+ }
485
+ try {
486
+ await this.stopEmbeddedDatabase();
487
+ }
488
+ catch (errorArg) {
489
+ cleanupErrors.push(errorArg);
490
+ }
491
+ if (cleanupErrors.length === 1)
492
+ throw cleanupErrors[0];
493
+ if (cleanupErrors.length > 1) {
494
+ throw new AggregateError(cleanupErrors, 'SmartData shutdown was incomplete.');
495
+ }
496
+ })();
497
+ this.closePromise = closePromise;
498
+ try {
499
+ await closePromise;
500
+ this.initialized = false;
501
+ }
502
+ finally {
503
+ if (this.closePromise === closePromise)
504
+ this.closePromise = undefined;
505
+ }
506
+ }
507
+ async getRuntimeConfig(controllerPortArg) {
508
+ this.assertInitialized();
509
+ if (!Number.isSafeInteger(controllerPortArg)
510
+ || controllerPortArg < 1
511
+ || controllerPortArg > 65535) {
512
+ throw new Error('controllerPort must be an integer between 1 and 65535.');
513
+ }
514
+ this.controllerId = `controller:${controllerPortArg}`;
515
+ const stored = await ControllerAuthModel.exact.findStoredOne({ id: this.controllerId });
516
+ if (!stored)
517
+ return undefined;
518
+ return cloneRuntimeConfig(ControllerAuthModel.exact.toPersisted(stored).config);
519
+ }
520
+ /** Process-private connection data for the isolated Flex child and projection reader. */
521
+ getDatabaseDescriptor() {
522
+ this.assertInitialized();
523
+ if (!this.resolvedMongoDbUrl) {
524
+ throw new AuthError('not_initialized', 'The controller database connection is unavailable.');
525
+ }
526
+ return {
527
+ mongoDbUrl: this.resolvedMongoDbUrl,
528
+ mongoDbName: this.options.mongoDbName,
529
+ };
530
+ }
531
+ async resolveOrCreateRuntimeConfig(runtimeConfigArg) {
532
+ this.assertInitialized();
533
+ if (!Number.isSafeInteger(runtimeConfigArg.controllerPort)
534
+ || runtimeConfigArg.controllerPort < 1
535
+ || runtimeConfigArg.controllerPort > 65535) {
536
+ throw new Error('controllerPort must be an integer between 1 and 65535.');
537
+ }
538
+ const controllerId = `controller:${runtimeConfigArg.controllerPort}`;
539
+ this.controllerId = controllerId;
540
+ const existing = await ControllerAuthModel.exact.findStoredOne({ id: controllerId });
541
+ if (existing) {
542
+ const document = ControllerAuthModel.exact.toPersisted(existing);
543
+ if (document.config.projectsRoot === undefined
544
+ && runtimeConfigArg.projectsRoot !== undefined) {
545
+ // One-time v2 upgrade: adopt the resolved projects root into the
546
+ // stored document; every other field must still match exactly.
547
+ this.assertRuntimeConfigMatches({ ...document.config, projectsRoot: runtimeConfigArg.projectsRoot }, runtimeConfigArg);
548
+ const upgraded = cloneRuntimeConfig(runtimeConfigArg);
549
+ const result = await ControllerAuthModel.exact.transition({
550
+ current: existing,
551
+ change: (model) => {
552
+ model.config = upgraded;
553
+ },
554
+ });
555
+ if (result.status === 'transitioned') {
556
+ return this.finalizeRuntimeConfigDocument(ControllerAuthModel.exact.toPersisted(result.document), runtimeConfigArg);
557
+ }
558
+ const reconciled = await ControllerAuthModel.exact.findStoredOne({ id: controllerId });
559
+ if (!reconciled) {
560
+ throw new AuthError('ambiguous_write', 'Controller runtime configuration upgrade has an ambiguous outcome.');
561
+ }
562
+ const reconciledDocument = ControllerAuthModel.exact.toPersisted(reconciled);
563
+ return this.finalizeRuntimeConfigDocument(reconciledDocument, runtimeConfigArg);
564
+ }
565
+ return this.finalizeRuntimeConfigDocument(document, runtimeConfigArg);
566
+ }
567
+ const candidate = {
568
+ id: controllerId,
569
+ config: cloneRuntimeConfig(runtimeConfigArg),
570
+ authState: 'setupRequired',
571
+ setup: null,
572
+ webauthnUserId: randomAuthorityValue(),
573
+ credentials: [],
574
+ };
575
+ try {
576
+ const insertResult = await ControllerAuthModel.exact.insert(candidate);
577
+ const document = ControllerAuthModel.exact.toPersisted(insertResult.document);
578
+ return this.finalizeRuntimeConfigDocument(document, runtimeConfigArg);
579
+ }
580
+ catch (errorArg) {
581
+ if (!isAmbiguousWrite(errorArg))
582
+ throw errorArg;
583
+ const reconciled = await ControllerAuthModel.exact.findStoredOne({ id: controllerId });
584
+ if (!reconciled) {
585
+ throw new AuthError('ambiguous_write', 'Controller authentication initialization has an ambiguous outcome.', { cause: errorArg });
586
+ }
587
+ const document = ControllerAuthModel.exact.toPersisted(reconciled);
588
+ return this.finalizeRuntimeConfigDocument(document, runtimeConfigArg);
589
+ }
590
+ }
591
+ async finalizeRuntimeConfigDocument(documentArg, runtimeConfigArg) {
592
+ this.assertRuntimeConfigMatches(documentArg.config, runtimeConfigArg);
593
+ await new PostDatabaseDocumentMigrationRunner(this.database)
594
+ .runProjectFilesystemIdentity(documentArg.id);
595
+ return documentArg;
596
+ }
597
+ async rotateSetupAuthority(providedCodeArg) {
598
+ const current = await this.findStoredState();
599
+ const currentBody = ControllerAuthModel.exact.toPersisted(current);
600
+ if (currentBody.credentials.length > 0)
601
+ return null;
602
+ const setupCode = providedCodeArg === undefined
603
+ ? randomAuthorityValue()
604
+ : assertProvidedSetupCode(providedCodeArg);
605
+ const setupHash = hashSetupCode(setupCode);
606
+ const generation = randomAuthorityValue();
607
+ const expiresAt = new Date(Date.now() + setupLifetimeMs);
608
+ try {
609
+ const result = await ControllerAuthModel.exact.transition({
610
+ current,
611
+ change: (model) => {
612
+ model.authState = 'setupRequired';
613
+ model.setup = {
614
+ generation,
615
+ hash: setupHash,
616
+ expiresAt,
617
+ };
618
+ },
619
+ });
620
+ if (result.status !== 'transitioned') {
621
+ throw new AuthError('concurrent_change', 'Setup authority changed concurrently and was not rotated.');
622
+ }
623
+ return { setupCode, generation, expiresAt: new Date(expiresAt) };
624
+ }
625
+ catch (errorArg) {
626
+ if (!isAmbiguousWrite(errorArg))
627
+ throw errorArg;
628
+ const reconciled = await this.findStoredState();
629
+ const document = ControllerAuthModel.exact.toPersisted(reconciled);
630
+ if (document.setup?.generation === generation
631
+ && document.setup.hash === setupHash
632
+ && document.setup.expiresAt.getTime() === expiresAt.getTime()) {
633
+ return { setupCode, generation, expiresAt: new Date(expiresAt) };
634
+ }
635
+ throw new AuthError('ambiguous_write', 'Setup authority rotation has an ambiguous outcome.', { cause: errorArg });
636
+ }
637
+ }
638
+ async getState() {
639
+ const stored = await this.findStoredState();
640
+ return ControllerAuthModel.exact.toPersisted(stored);
641
+ }
642
+ async assertSetupAuthority(setupCodeArg, ceremonyArg, nowArg = new Date()) {
643
+ if (typeof setupCodeArg !== 'string'
644
+ || setupCodeArg.length > 256
645
+ || !setupCodePattern.test(setupCodeArg)) {
646
+ throw new AuthError('setup_invalid', 'The setup code is invalid or expired.');
647
+ }
648
+ if (!(nowArg instanceof Date) || !Number.isFinite(nowArg.getTime())) {
649
+ throw new AuthError('setup_invalid', 'The setup validation time is malformed.');
650
+ }
651
+ const state = await this.getState();
652
+ if (state.credentials.length > 0 || state.authState !== 'setupRequired' || !state.setup) {
653
+ throw new AuthError('setup_unavailable', 'Passkey setup is no longer available.');
654
+ }
655
+ if (state.setup.expiresAt.getTime() <= nowArg.getTime()) {
656
+ throw new AuthError('setup_expired', 'The setup code is invalid or expired.');
657
+ }
658
+ if (ceremonyArg
659
+ && (ceremonyArg.setupGeneration !== state.setup.generation
660
+ || ceremonyArg.setupHash !== state.setup.hash)) {
661
+ throw new AuthError('setup_invalid', 'The setup code is invalid or expired.');
662
+ }
663
+ const candidateHash = hashSetupCode(setupCodeArg);
664
+ if (!hashesEqual(candidateHash, state.setup.hash)) {
665
+ throw new AuthError('setup_invalid', 'The setup code is invalid or expired.');
666
+ }
667
+ return state;
668
+ }
669
+ async countActiveCeremonies(kindArg, nowArg) {
670
+ this.assertInitialized();
671
+ const kind = requireCeremonyKind(kindArg);
672
+ const now = requireValidDate(nowArg, 'Ceremony count time');
673
+ return WebAuthnCeremonyModel.exact.count({
674
+ kind,
675
+ state: 'pending',
676
+ expiresAt: { $gt: now },
677
+ });
678
+ }
679
+ async createCeremony(ceremonyArg) {
680
+ this.assertInitialized();
681
+ if (ceremonyArg.state !== 'pending') {
682
+ throw new AuthError('ceremony_invalid', 'A new WebAuthn ceremony must be pending.');
683
+ }
684
+ const result = await WebAuthnCeremonyModel.exact.insert(ceremonyArg);
685
+ if (result.status === 'conflict') {
686
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony identifier already exists.');
687
+ }
688
+ return WebAuthnCeremonyModel.exact.toPersisted(result.document);
689
+ }
690
+ async consumeCeremony(optionsArg) {
691
+ const { current, body, now } = await this.findPendingCeremony(optionsArg);
692
+ const consumedAt = now;
693
+ const consumedNonce = randomAuthorityValue();
694
+ try {
695
+ const result = await WebAuthnCeremonyModel.exact.transition({
696
+ current,
697
+ change: (model) => {
698
+ model.state = 'consumed';
699
+ model.consumedAt = consumedAt;
700
+ model.consumedNonce = consumedNonce;
701
+ },
702
+ });
703
+ if (result.status !== 'transitioned') {
704
+ throw new AuthError('ceremony_replayed', 'The WebAuthn ceremony was already consumed.');
705
+ }
706
+ return WebAuthnCeremonyModel.exact.toPersisted(result.document);
707
+ }
708
+ catch (errorArg) {
709
+ if (!isAmbiguousWrite(errorArg))
710
+ throw errorArg;
711
+ const reconciled = await WebAuthnCeremonyModel.exact.findStoredOne({
712
+ id: body.id,
713
+ });
714
+ if (reconciled) {
715
+ const document = WebAuthnCeremonyModel.exact.toPersisted(reconciled);
716
+ if (document.state === 'consumed' && document.consumedNonce === consumedNonce) {
717
+ return document;
718
+ }
719
+ }
720
+ throw new AuthError('ambiguous_write', 'WebAuthn ceremony consumption has an ambiguous outcome.', { cause: errorArg });
721
+ }
722
+ }
723
+ async assertPendingCeremony(optionsArg) {
724
+ const { body } = await this.findPendingCeremony(optionsArg);
725
+ return body;
726
+ }
727
+ async findPendingCeremony(optionsArg) {
728
+ this.assertInitialized();
729
+ const ceremonyId = requireCeremonyId(optionsArg.ceremonyId);
730
+ const kind = requireCeremonyKind(optionsArg.kind);
731
+ const peerId = requirePeerId(optionsArg.peerId);
732
+ const origin = requireOrigin(optionsArg.origin);
733
+ const rpId = requireRpId(optionsArg.rpId);
734
+ const userId = requireUserId(optionsArg.userId);
735
+ const now = requireValidDate(optionsArg.now, 'Ceremony validation time');
736
+ const current = await WebAuthnCeremonyModel.exact.findStoredOne({ id: ceremonyId });
737
+ if (optionsArg.ceremonyId !== ceremonyId
738
+ || optionsArg.kind !== kind
739
+ || optionsArg.peerId !== peerId
740
+ || optionsArg.origin !== origin
741
+ || optionsArg.rpId !== rpId
742
+ || optionsArg.userId !== userId
743
+ || !(optionsArg.now instanceof Date)
744
+ || optionsArg.now.getTime() !== now.getTime()) {
745
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony validation authority changed during lookup.');
746
+ }
747
+ if (!current)
748
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony is invalid.');
749
+ const body = WebAuthnCeremonyModel.exact.toPersisted(current);
750
+ if (body.kind !== kind) {
751
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony has the wrong kind.');
752
+ }
753
+ if (body.peerId !== peerId) {
754
+ throw new AuthError('peer_mismatch', 'The WebAuthn ceremony belongs to another connection.');
755
+ }
756
+ if (body.origin !== origin) {
757
+ throw new AuthError('origin_mismatch', 'The WebAuthn ceremony origin changed.');
758
+ }
759
+ if (body.rpId !== rpId || body.userId !== userId) {
760
+ throw new AuthError('ceremony_invalid', 'The WebAuthn ceremony authority changed.');
761
+ }
762
+ if (body.expiresAt.getTime() <= now.getTime()) {
763
+ throw new AuthError('ceremony_expired', 'The WebAuthn ceremony expired.');
764
+ }
765
+ if (body.state !== 'pending') {
766
+ throw new AuthError('ceremony_replayed', 'The WebAuthn ceremony was already consumed.');
767
+ }
768
+ return { current, body, now };
769
+ }
770
+ async commitFirstCredential(ceremonyArg, credentialArg) {
771
+ if (ceremonyArg.state !== 'consumed') {
772
+ throw new AuthError('ceremony_invalid', 'The setup ceremony has not been consumed.');
773
+ }
774
+ const current = await this.findStoredState();
775
+ const body = ControllerAuthModel.exact.toPersisted(current);
776
+ if (body.credentials.length > 0 || body.authState !== 'setupRequired' || !body.setup) {
777
+ throw new AuthError('concurrent_change', 'Another passkey won first enrollment.');
778
+ }
779
+ if (body.webauthnUserId !== ceremonyArg.userId
780
+ || body.config.publicOrigin !== ceremonyArg.origin
781
+ || body.config.rpId !== ceremonyArg.rpId
782
+ || body.setup.generation !== ceremonyArg.setupGeneration
783
+ || body.setup.hash !== ceremonyArg.setupHash) {
784
+ throw new AuthError('concurrent_change', 'Setup authority changed before enrollment.');
785
+ }
786
+ try {
787
+ const result = await ControllerAuthModel.exact.transition({
788
+ current,
789
+ change: (model) => {
790
+ model.authState = 'ready';
791
+ model.setup = null;
792
+ model.credentials = [structuredClone(credentialArg)];
793
+ },
794
+ });
795
+ if (result.status !== 'transitioned') {
796
+ throw new AuthError('concurrent_change', 'Another passkey won first enrollment.');
797
+ }
798
+ return ControllerAuthModel.exact.toPersisted(result.document);
799
+ }
800
+ catch (errorArg) {
801
+ if (!isAmbiguousWrite(errorArg))
802
+ throw errorArg;
803
+ const reconciled = await this.findStoredState();
804
+ const document = ControllerAuthModel.exact.toPersisted(reconciled);
805
+ if (document.credentials.length === 1
806
+ && document.credentials[0].id === credentialArg.id
807
+ && document.credentials[0].counterUpdateId === credentialArg.counterUpdateId
808
+ && document.authState === 'ready'
809
+ && document.setup === null) {
810
+ return document;
811
+ }
812
+ throw new AuthError('ambiguous_write', 'First passkey enrollment has an ambiguous outcome.', { cause: errorArg });
813
+ }
814
+ }
815
+ async updateCounter(credentialIdArg, expectedCounterArg, newCounterArg) {
816
+ if (typeof credentialIdArg !== 'string' || credentialIdArg.length === 0) {
817
+ throw new AuthError('credential_not_found', 'The passkey credential is malformed.');
818
+ }
819
+ requireSafeCounter(expectedCounterArg, 'expectedCounter');
820
+ requireSafeCounter(newCounterArg, 'newCounter');
821
+ const current = await this.findStoredState();
822
+ const body = ControllerAuthModel.exact.toPersisted(current);
823
+ const credentialIndex = body.credentials.findIndex((credential) => credential.id === credentialIdArg);
824
+ if (credentialIndex < 0) {
825
+ throw new AuthError('credential_not_found', 'The passkey credential is unknown.');
826
+ }
827
+ const credential = body.credentials[credentialIndex];
828
+ if (credential.counter !== expectedCounterArg) {
829
+ throw new AuthError('counter_conflict', 'The passkey counter changed concurrently.');
830
+ }
831
+ if ((expectedCounterArg === 0 && newCounterArg !== 0 && newCounterArg <= expectedCounterArg)
832
+ || (expectedCounterArg > 0 && newCounterArg <= expectedCounterArg)) {
833
+ throw new AuthError('counter_conflict', 'The passkey counter did not advance.');
834
+ }
835
+ const counterUpdateId = randomAuthorityValue();
836
+ try {
837
+ const result = await ControllerAuthModel.exact.transition({
838
+ current,
839
+ change: (model) => {
840
+ model.credentials = model.credentials.map((entry) => entry.id === credentialIdArg
841
+ ? { ...entry, counter: newCounterArg, counterUpdateId }
842
+ : entry);
843
+ },
844
+ });
845
+ if (result.status !== 'transitioned') {
846
+ throw new AuthError('counter_conflict', 'The passkey counter changed concurrently.');
847
+ }
848
+ const document = ControllerAuthModel.exact.toPersisted(result.document);
849
+ return document.credentials.find((entry) => entry.id === credentialIdArg);
850
+ }
851
+ catch (errorArg) {
852
+ if (!isAmbiguousWrite(errorArg))
853
+ throw errorArg;
854
+ const reconciled = await this.findStoredState();
855
+ const document = ControllerAuthModel.exact.toPersisted(reconciled);
856
+ const credentialAfter = document.credentials.find((entry) => entry.id === credentialIdArg);
857
+ if (credentialAfter?.counter === newCounterArg
858
+ && credentialAfter.counterUpdateId === counterUpdateId) {
859
+ return credentialAfter;
860
+ }
861
+ throw new AuthError('ambiguous_write', 'Passkey counter update has an ambiguous outcome.', { cause: errorArg });
862
+ }
863
+ }
864
+ async recordAuditEvent(eventArg) {
865
+ this.assertInitialized();
866
+ if (!this.controllerId) {
867
+ throw new AuthError('not_initialized', 'The controller runtime configuration is unresolved.');
868
+ }
869
+ const event = {
870
+ id: randomAuthorityValue(),
871
+ controllerId: this.controllerId,
872
+ timestamp: eventArg.timestamp === undefined
873
+ ? new Date()
874
+ : new Date(eventArg.timestamp),
875
+ type: eventArg.type,
876
+ outcome: eventArg.outcome,
877
+ ...(eventArg.operationId === undefined ? {} : { operationId: eventArg.operationId }),
878
+ ...(eventArg.peerId === undefined ? {} : { peerId: eventArg.peerId }),
879
+ ...(eventArg.credentialId === undefined ? {} : { credentialId: eventArg.credentialId }),
880
+ ...(eventArg.sessionId === undefined ? {} : { sessionId: { ...eventArg.sessionId } }),
881
+ ...(eventArg.requestId === undefined ? {} : { requestId: { ...eventArg.requestId } }),
882
+ };
883
+ try {
884
+ const result = await ControllerAuditEventModel.exact.insert(event);
885
+ if (result.status === 'conflict') {
886
+ throw new AuthError('concurrent_change', 'The audit event identifier conflicts.');
887
+ }
888
+ return ControllerAuditEventModel.exact.toPersisted(result.document);
889
+ }
890
+ catch (errorArg) {
891
+ if (!isAmbiguousWrite(errorArg))
892
+ throw errorArg;
893
+ const reconciled = await ControllerAuditEventModel.exact.findStoredOne({ id: event.id });
894
+ if (reconciled) {
895
+ const document = ControllerAuditEventModel.exact.toPersisted(reconciled);
896
+ if (this.auditEventsEqual(document, event))
897
+ return document;
898
+ }
899
+ throw new AuthError('ambiguous_write', 'Audit event persistence has an ambiguous outcome.', { cause: errorArg });
900
+ }
901
+ }
902
+ assertInitialized() {
903
+ if (!this.initialized) {
904
+ throw new AuthError('not_initialized', 'The authentication store is not initialized.');
905
+ }
906
+ }
907
+ async findStoredState() {
908
+ this.assertInitialized();
909
+ if (!this.controllerId) {
910
+ throw new AuthError('not_initialized', 'The controller runtime configuration is unresolved.');
911
+ }
912
+ const stored = await ControllerAuthModel.exact.findStoredOne({ id: this.controllerId });
913
+ if (!stored) {
914
+ throw new AuthError('not_initialized', 'The controller authentication document is missing.');
915
+ }
916
+ return stored;
917
+ }
918
+ requireControllerId() {
919
+ if (!this.controllerId) {
920
+ throw new AuthError('not_initialized', 'The controller identity has not been resolved yet.');
921
+ }
922
+ return this.controllerId;
923
+ }
924
+ async listProjects() {
925
+ this.assertInitialized();
926
+ const controllerId = this.requireControllerId();
927
+ const stored = await ControllerProjectModel.exact.findStored({
928
+ filter: {
929
+ controllerId,
930
+ removalStartedAt: { $exists: false },
931
+ removedAt: { $exists: false },
932
+ },
933
+ sort: { createdAt: 1 },
934
+ limit: controllerProjectLimit + 1,
935
+ });
936
+ if (stored.length > controllerProjectLimit) {
937
+ throw new AuthError('invalid_project', `The controller exceeds the ${controllerProjectLimit}-project limit.`);
938
+ }
939
+ return stored.map((entry) => ControllerProjectModel.exact.toPersisted(entry));
940
+ }
941
+ async createProject(nameArg, directoryArg, identityArg) {
942
+ this.assertInitialized();
943
+ const controllerId = this.requireControllerId();
944
+ if (!isProjectRelativePathName(nameArg)) {
945
+ throw new AuthError('invalid_project', 'Project names must be directory paths without dot navigation.');
946
+ }
947
+ if (typeof directoryArg !== 'string' || !plugins.path.isAbsolute(directoryArg)) {
948
+ throw new AuthError('invalid_project', 'The project directory must be an absolute path.');
949
+ }
950
+ return this.withProjectMutation(async () => {
951
+ const activeProjects = await this.listProjects();
952
+ const existing = activeProjects.find((entry) => entry.directory === directoryArg);
953
+ if (existing) {
954
+ if (existing.directoryIdentityState !== 'bound'
955
+ || existing.directoryIdentity === undefined
956
+ || !filesystemIdentitiesEqual(existing.directoryIdentity, identityArg)) {
957
+ throw new AuthError('concurrent_change', 'The registered project path has a different filesystem identity.');
958
+ }
959
+ return { project: existing, created: false };
960
+ }
961
+ const pendingRemovals = await this.listPendingProjectRemovals();
962
+ if (activeProjects.length + pendingRemovals.length >= controllerProjectLimit) {
963
+ throw new AuthError('invalid_project', `The controller supports at most ${controllerProjectLimit} active or pending-removal projects.`);
964
+ }
965
+ if (pendingRemovals.some((entry) => (entry.directory === directoryArg || entry.name === nameArg))) {
966
+ throw new AuthError('concurrent_change', 'The project path is still being removed and cannot be registered again.');
967
+ }
968
+ if (activeProjects.some((entry) => entry.name === nameArg)) {
969
+ throw new AuthError('invalid_project', 'A project with this name already exists.');
970
+ }
971
+ const candidate = {
972
+ id: plugins.crypto.randomBytes(16).toString('base64url'),
973
+ controllerId,
974
+ name: nameArg,
975
+ directory: directoryArg,
976
+ directoryIdentityState: 'bound',
977
+ directoryIdentity: structuredClone(identityArg),
978
+ createdAt: new Date(),
979
+ };
980
+ const result = await ControllerProjectModel.exact.insert(candidate);
981
+ if (result.status === 'conflict') {
982
+ throw new AuthError('concurrent_change', 'The project was created concurrently.');
983
+ }
984
+ return { project: ControllerProjectModel.exact.toPersisted(result.document), created: true };
985
+ });
986
+ }
987
+ async removeProject(projectIdArg) {
988
+ this.assertInitialized();
989
+ const controllerId = this.requireControllerId();
990
+ if (typeof projectIdArg !== 'string' || projectIdArg.length === 0 || projectIdArg.length > 64) {
991
+ throw new AuthError('invalid_project', 'The project identifier is malformed.');
992
+ }
993
+ return this.withProjectMutation(async () => {
994
+ const stored = await ControllerProjectModel.exact.findStoredOne({ id: projectIdArg });
995
+ if (!stored)
996
+ return false;
997
+ const document = ControllerProjectModel.exact.toPersisted(stored);
998
+ if (document.controllerId !== controllerId
999
+ || document.removedAt !== undefined
1000
+ || document.removalStartedAt === undefined) {
1001
+ return false;
1002
+ }
1003
+ const result = await ControllerProjectModel.exact.transition({
1004
+ current: stored,
1005
+ change: (model) => {
1006
+ delete model.removalStartedAt;
1007
+ model.removedAt = new Date();
1008
+ },
1009
+ });
1010
+ if (result.status !== 'transitioned') {
1011
+ throw new AuthError('concurrent_change', 'The project changed concurrently and was not removed.');
1012
+ }
1013
+ return true;
1014
+ });
1015
+ }
1016
+ async beginProjectRemoval(projectIdArg) {
1017
+ this.assertInitialized();
1018
+ const controllerId = this.requireControllerId();
1019
+ if (typeof projectIdArg !== 'string' || projectIdArg.length === 0 || projectIdArg.length > 64) {
1020
+ throw new AuthError('invalid_project', 'The project identifier is malformed.');
1021
+ }
1022
+ return this.withProjectMutation(async () => {
1023
+ const stored = await ControllerProjectModel.exact.findStoredOne({ id: projectIdArg });
1024
+ if (!stored)
1025
+ return undefined;
1026
+ const document = ControllerProjectModel.exact.toPersisted(stored);
1027
+ if (document.controllerId !== controllerId || document.removedAt !== undefined)
1028
+ return undefined;
1029
+ if (document.removalStartedAt !== undefined)
1030
+ return document;
1031
+ const result = await ControllerProjectModel.exact.transition({
1032
+ current: stored,
1033
+ change: (model) => {
1034
+ model.removalStartedAt = new Date();
1035
+ },
1036
+ });
1037
+ if (result.status !== 'transitioned') {
1038
+ throw new AuthError('concurrent_change', 'The project changed concurrently and was not retired.');
1039
+ }
1040
+ return ControllerProjectModel.exact.toPersisted(result.document);
1041
+ });
1042
+ }
1043
+ async listPendingProjectRemovals() {
1044
+ this.assertInitialized();
1045
+ const controllerId = this.requireControllerId();
1046
+ const stored = await ControllerProjectModel.exact.findStored({
1047
+ filter: {
1048
+ controllerId,
1049
+ removalStartedAt: { $exists: true },
1050
+ removedAt: { $exists: false },
1051
+ },
1052
+ sort: { removalStartedAt: 1 },
1053
+ limit: controllerProjectLimit + 1,
1054
+ });
1055
+ if (stored.length > controllerProjectLimit) {
1056
+ throw new AuthError('invalid_project', 'The pending project-removal limit was exceeded.');
1057
+ }
1058
+ return stored.map((entry) => ControllerProjectModel.exact.toPersisted(entry));
1059
+ }
1060
+ withProjectMutation(operationArg) {
1061
+ if (!this.projectMutationAdmissionOpen) {
1062
+ return Promise.reject(new AuthError('not_initialized', 'Project mutations are unavailable while the authentication store is closing.'));
1063
+ }
1064
+ const operation = this.projectMutationTail.then(async () => {
1065
+ if (!this.projectMutationAdmissionOpen) {
1066
+ throw new AuthError('not_initialized', 'Project mutations are unavailable while the authentication store is closing.');
1067
+ }
1068
+ return operationArg();
1069
+ });
1070
+ this.projectMutationTail = operation.then(() => undefined, () => undefined);
1071
+ return operation;
1072
+ }
1073
+ async insertResourceDocument(candidateArg) {
1074
+ try {
1075
+ const result = await ControllerResourceModel.exact.insert(candidateArg);
1076
+ if (result.status === 'conflict') {
1077
+ throw new AuthError('concurrent_change', 'The resource identifier conflicted.');
1078
+ }
1079
+ return cloneResourceDocument(ControllerResourceModel.exact.toPersisted(result.document));
1080
+ }
1081
+ catch (errorArg) {
1082
+ if (!isAmbiguousWrite(errorArg))
1083
+ throw errorArg;
1084
+ const reconciled = await ControllerResourceModel.exact.findStoredOne({ id: candidateArg.id });
1085
+ if (reconciled) {
1086
+ const document = ControllerResourceModel.exact.toPersisted(reconciled);
1087
+ if (document.updateId === candidateArg.updateId)
1088
+ return cloneResourceDocument(document);
1089
+ }
1090
+ throw new AuthError('ambiguous_write', 'The resource insertion has an ambiguous outcome.', { cause: errorArg });
1091
+ }
1092
+ }
1093
+ async transitionResourceDocument(currentArg, changeArg, concurrentMessageArg, ambiguousMessageArg) {
1094
+ const current = ControllerResourceModel.exact.toPersisted(currentArg);
1095
+ const updateId = randomAuthorityValue();
1096
+ try {
1097
+ const result = await ControllerResourceModel.exact.transition({
1098
+ current: currentArg,
1099
+ change: (model) => {
1100
+ changeArg(model);
1101
+ model.updateId = updateId;
1102
+ },
1103
+ });
1104
+ if (result.status !== 'transitioned') {
1105
+ throw new AuthError('concurrent_change', concurrentMessageArg);
1106
+ }
1107
+ return cloneResourceDocument(ControllerResourceModel.exact.toPersisted(result.document));
1108
+ }
1109
+ catch (errorArg) {
1110
+ if (!isAmbiguousWrite(errorArg))
1111
+ throw errorArg;
1112
+ const reconciled = await ControllerResourceModel.exact.findStoredOne({ id: current.id });
1113
+ if (reconciled) {
1114
+ const document = ControllerResourceModel.exact.toPersisted(reconciled);
1115
+ if (document.updateId === updateId)
1116
+ return cloneResourceDocument(document);
1117
+ }
1118
+ throw new AuthError('ambiguous_write', ambiguousMessageArg, { cause: errorArg });
1119
+ }
1120
+ }
1121
+ async getProject(projectIdArg) {
1122
+ this.assertInitialized();
1123
+ const controllerId = this.requireControllerId();
1124
+ if (typeof projectIdArg !== 'string' || projectIdArg.length === 0 || projectIdArg.length > 64) {
1125
+ return undefined;
1126
+ }
1127
+ const stored = await ControllerProjectModel.exact.findStoredOne({ id: projectIdArg });
1128
+ if (!stored)
1129
+ return undefined;
1130
+ const document = ControllerProjectModel.exact.toPersisted(stored);
1131
+ if (document.controllerId !== controllerId
1132
+ || document.removalStartedAt !== undefined
1133
+ || document.removedAt !== undefined) {
1134
+ return undefined;
1135
+ }
1136
+ return document;
1137
+ }
1138
+ async getPendingProjectRemoval(projectIdArg) {
1139
+ this.assertInitialized();
1140
+ const controllerId = this.requireControllerId();
1141
+ if (typeof projectIdArg !== 'string' || projectIdArg.length === 0 || projectIdArg.length > 64) {
1142
+ return undefined;
1143
+ }
1144
+ const stored = await ControllerProjectModel.exact.findStoredOne({ id: projectIdArg });
1145
+ if (!stored)
1146
+ return undefined;
1147
+ const document = ControllerProjectModel.exact.toPersisted(stored);
1148
+ if (document.controllerId !== controllerId
1149
+ || document.removalStartedAt === undefined
1150
+ || document.removedAt !== undefined)
1151
+ return undefined;
1152
+ return document;
1153
+ }
1154
+ async listResources(projectIdArg, optionsArg = {}) {
1155
+ this.assertInitialized();
1156
+ const controllerId = this.requireControllerId();
1157
+ const stored = await ControllerResourceModel.exact.findStored({
1158
+ filter: {
1159
+ controllerId,
1160
+ projectId: projectIdArg,
1161
+ ...(optionsArg.includeRetired ? {} : { retiredAt: { $exists: false } }),
1162
+ },
1163
+ sort: { createdAt: 1 },
1164
+ limit: controllerResourcesPerProjectLimit + 1,
1165
+ });
1166
+ if (stored.length > controllerResourcesPerProjectLimit) {
1167
+ throw new AuthError('invalid_resource', `The project exceeds the ${controllerResourcesPerProjectLimit}-resource limit.`);
1168
+ }
1169
+ return stored.map((entry) => cloneResourceDocument(ControllerResourceModel.exact.toPersisted(entry)));
1170
+ }
1171
+ async listRecoverableResources() {
1172
+ this.assertInitialized();
1173
+ const stored = await ControllerResourceModel.exact.findStored({
1174
+ filter: {
1175
+ controllerId: this.requireControllerId(),
1176
+ retiredAt: { $exists: false },
1177
+ },
1178
+ sort: { createdAt: 1 },
1179
+ limit: controllerResourceLimit + 1,
1180
+ });
1181
+ if (stored.length > controllerResourceLimit) {
1182
+ throw new AuthError('invalid_resource', 'The controller resource limit was exceeded.');
1183
+ }
1184
+ return stored.map((entry) => cloneResourceDocument(ControllerResourceModel.exact.toPersisted(entry)));
1185
+ }
1186
+ async getResource(projectIdArg, resourceIdArg, optionsArg = {}) {
1187
+ this.assertInitialized();
1188
+ const stored = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1189
+ if (!stored)
1190
+ return undefined;
1191
+ const resource = ControllerResourceModel.exact.toPersisted(stored);
1192
+ if (resource.controllerId !== this.requireControllerId()
1193
+ || resource.projectId !== projectIdArg
1194
+ || (!optionsArg.includeRetired && resource.lifecycle === 'retired'))
1195
+ return undefined;
1196
+ return cloneResourceDocument(resource);
1197
+ }
1198
+ async createResource(inputArg) {
1199
+ this.assertInitialized();
1200
+ return this.withProjectMutation(async () => {
1201
+ const project = await this.getProject(inputArg.projectId);
1202
+ if (!project)
1203
+ throw new AuthError('invalid_project', 'The resource project is unavailable.');
1204
+ const [existing, recoverable] = await Promise.all([
1205
+ this.listResources(inputArg.projectId),
1206
+ this.listRecoverableResources(),
1207
+ ]);
1208
+ assertControllerResourceCreationCapacity(existing.length, recoverable.length);
1209
+ const now = new Date();
1210
+ const candidate = {
1211
+ id: randomResourceId(),
1212
+ controllerId: this.requireControllerId(),
1213
+ projectId: inputArg.projectId,
1214
+ kind: inputArg.kind,
1215
+ title: inputArg.title,
1216
+ attachmentAuthorityId: randomAuthorityValue(),
1217
+ attachmentRevision: 0,
1218
+ sessionId: null,
1219
+ lifecycle: 'active',
1220
+ ...(inputArg.terminal === undefined ? {} : { terminal: { ...inputArg.terminal } }),
1221
+ createdAt: now,
1222
+ updatedAt: now,
1223
+ updateId: randomAuthorityValue(),
1224
+ };
1225
+ return this.insertResourceDocument(candidate);
1226
+ });
1227
+ }
1228
+ async renameResource(projectIdArg, resourceIdArg, titleArg) {
1229
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1230
+ if (!current)
1231
+ throw new AuthError('invalid_resource', 'The resource does not exist.');
1232
+ const before = ControllerResourceModel.exact.toPersisted(current);
1233
+ if (before.controllerId !== this.requireControllerId()
1234
+ || before.projectId !== projectIdArg
1235
+ || before.lifecycle !== 'active')
1236
+ throw new AuthError('invalid_resource', 'The resource is unavailable.');
1237
+ return this.transitionResourceDocument(current, (model) => {
1238
+ model.title = titleArg;
1239
+ model.updatedAt = new Date();
1240
+ }, 'The resource changed concurrently.', 'The resource rename has an ambiguous outcome.');
1241
+ }
1242
+ async beginResourceAttachmentTransition(projectIdArg, resourceIdArg, sessionIdArg, expectedAttachmentRevisionArg) {
1243
+ if (!Number.isSafeInteger(expectedAttachmentRevisionArg) || expectedAttachmentRevisionArg < 0) {
1244
+ throw new AuthError('invalid_resource', 'The expected attachment revision is malformed.');
1245
+ }
1246
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1247
+ if (!current)
1248
+ throw new AuthError('invalid_resource', 'The resource does not exist.');
1249
+ const before = ControllerResourceModel.exact.toPersisted(current);
1250
+ if (before.controllerId !== this.requireControllerId()
1251
+ || before.projectId !== projectIdArg
1252
+ || before.lifecycle !== 'active')
1253
+ throw new AuthError('invalid_resource', 'The resource is unavailable.');
1254
+ if (before.pendingAttachment) {
1255
+ throw new AuthError('concurrent_change', 'The resource attachment is already changing.');
1256
+ }
1257
+ if (before.attachmentRevision !== expectedAttachmentRevisionArg) {
1258
+ throw new AuthError('concurrent_change', 'The resource attachment changed concurrently.');
1259
+ }
1260
+ const operationId = randomResourceOperationId();
1261
+ return this.transitionResourceDocument(current, (model) => {
1262
+ model.pendingAttachment = {
1263
+ operationId,
1264
+ attachmentRevision: before.attachmentRevision + 1,
1265
+ sessionId: cloneSessionId(sessionIdArg),
1266
+ requestedAt: new Date(),
1267
+ };
1268
+ model.updatedAt = new Date();
1269
+ }, 'The resource attachment changed concurrently.', 'Preparing the resource attachment has an ambiguous outcome.');
1270
+ }
1271
+ async commitResourceAttachmentTransition(projectIdArg, resourceIdArg, operationIdArg) {
1272
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1273
+ if (!current)
1274
+ throw new AuthError('invalid_resource', 'The resource does not exist.');
1275
+ const before = ControllerResourceModel.exact.toPersisted(current);
1276
+ if (before.controllerId !== this.requireControllerId()
1277
+ || before.projectId !== projectIdArg
1278
+ || before.lifecycle !== 'active'
1279
+ || before.pendingAttachment?.operationId !== operationIdArg)
1280
+ throw new AuthError('concurrent_change', 'The pending resource attachment no longer matches.');
1281
+ const pending = before.pendingAttachment;
1282
+ return this.transitionResourceDocument(current, (model) => {
1283
+ model.attachmentRevision = pending.attachmentRevision;
1284
+ model.sessionId = cloneSessionId(pending.sessionId);
1285
+ delete model.pendingAttachment;
1286
+ model.updatedAt = new Date();
1287
+ }, 'The resource attachment changed concurrently.', 'Committing the resource attachment has an ambiguous outcome.');
1288
+ }
1289
+ async beginResourceRetirement(projectIdArg, resourceIdArg) {
1290
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1291
+ if (!current)
1292
+ throw new AuthError('invalid_resource', 'The resource does not exist.');
1293
+ const before = ControllerResourceModel.exact.toPersisted(current);
1294
+ if (before.controllerId !== this.requireControllerId() || before.projectId !== projectIdArg) {
1295
+ throw new AuthError('invalid_resource', 'The resource is unavailable.');
1296
+ }
1297
+ if (before.lifecycle !== 'active')
1298
+ return cloneResourceDocument(before);
1299
+ if (before.pendingAttachment) {
1300
+ throw new AuthError('concurrent_change', 'The resource attachment must settle before retirement.');
1301
+ }
1302
+ const now = new Date();
1303
+ return this.transitionResourceDocument(current, (model) => {
1304
+ model.lifecycle = 'retiring';
1305
+ model.retiringAt = now;
1306
+ model.updatedAt = now;
1307
+ }, 'The resource changed concurrently.', 'Preparing resource retirement has an ambiguous outcome.');
1308
+ }
1309
+ async completeResourceRetirement(projectIdArg, resourceIdArg) {
1310
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1311
+ if (!current)
1312
+ throw new AuthError('invalid_resource', 'The resource does not exist.');
1313
+ const before = ControllerResourceModel.exact.toPersisted(current);
1314
+ if (before.controllerId !== this.requireControllerId() || before.projectId !== projectIdArg) {
1315
+ throw new AuthError('invalid_resource', 'The resource is unavailable.');
1316
+ }
1317
+ if (before.lifecycle === 'retired')
1318
+ return cloneResourceDocument(before);
1319
+ if (before.lifecycle !== 'retiring') {
1320
+ throw new AuthError('concurrent_change', 'The resource is not retiring.');
1321
+ }
1322
+ const now = new Date();
1323
+ return this.transitionResourceDocument(current, (model) => {
1324
+ model.lifecycle = 'retired';
1325
+ model.retiredAt = now;
1326
+ model.updatedAt = now;
1327
+ }, 'The resource changed concurrently.', 'Completing resource retirement has an ambiguous outcome.');
1328
+ }
1329
+ async markTerminalResourceStopped(projectIdArg, resourceIdArg, outcomeArg = {}) {
1330
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1331
+ if (!current)
1332
+ throw new AuthError('invalid_resource', 'The terminal resource does not exist.');
1333
+ const before = ControllerResourceModel.exact.toPersisted(current);
1334
+ if (before.controllerId !== this.requireControllerId()
1335
+ || before.projectId !== projectIdArg
1336
+ || before.kind !== 'terminal'
1337
+ || !before.terminal
1338
+ || before.lifecycle === 'retired')
1339
+ throw new AuthError('invalid_resource', 'The terminal resource is unavailable.');
1340
+ const stoppedAt = outcomeArg.stoppedAt ?? new Date();
1341
+ return this.transitionResourceDocument(current, (model) => {
1342
+ model.terminal = {
1343
+ command: before.terminal.command,
1344
+ args: [...before.terminal.args],
1345
+ cwd: before.terminal.cwd,
1346
+ stoppedAt,
1347
+ ...(outcomeArg.lastExitCode === undefined ? {} : { lastExitCode: outcomeArg.lastExitCode }),
1348
+ };
1349
+ model.updatedAt = stoppedAt;
1350
+ }, 'The terminal resource changed concurrently.', 'Persisting the stopped terminal resource has an ambiguous outcome.');
1351
+ }
1352
+ async markTerminalResourceRunning(projectIdArg, resourceIdArg) {
1353
+ const current = await ControllerResourceModel.exact.findStoredOne({ id: resourceIdArg });
1354
+ if (!current)
1355
+ throw new AuthError('invalid_resource', 'The terminal resource does not exist.');
1356
+ const before = ControllerResourceModel.exact.toPersisted(current);
1357
+ if (before.controllerId !== this.requireControllerId()
1358
+ || before.projectId !== projectIdArg
1359
+ || before.kind !== 'terminal'
1360
+ || !before.terminal
1361
+ || before.lifecycle !== 'active')
1362
+ throw new AuthError('invalid_resource', 'The terminal resource is unavailable.');
1363
+ const now = new Date();
1364
+ return this.transitionResourceDocument(current, (model) => {
1365
+ model.terminal = {
1366
+ command: before.terminal.command,
1367
+ args: [...before.terminal.args],
1368
+ cwd: before.terminal.cwd,
1369
+ };
1370
+ model.updatedAt = now;
1371
+ }, 'The terminal resource changed concurrently.', 'Persisting the running terminal resource has an ambiguous outcome.');
1372
+ }
1373
+ async getSettings() {
1374
+ this.assertInitialized();
1375
+ const controllerId = this.requireControllerId();
1376
+ const stored = await ControllerSettingsModel.exact.findStoredOne({
1377
+ id: `${controllerId}:settings`,
1378
+ });
1379
+ if (stored) {
1380
+ const persisted = ControllerSettingsModel.exact.toPersisted(stored);
1381
+ return { ...persisted, defaultModels: persisted.defaultModels.map(cloneModelChoice) };
1382
+ }
1383
+ return { id: `${controllerId}:settings`, controllerId, defaultModels: [] };
1384
+ }
1385
+ async updateSettings(patchArg) {
1386
+ this.assertInitialized();
1387
+ const controllerId = this.requireControllerId();
1388
+ const settingsId = `${controllerId}:settings`;
1389
+ const defaultModelsUpdate = patchArg.defaultModels === undefined
1390
+ ? undefined
1391
+ : patchArg.defaultModels.map(cloneModelChoice);
1392
+ const applyPatch = (targetArg) => {
1393
+ if (defaultModelsUpdate !== undefined) {
1394
+ targetArg.defaultModels = defaultModelsUpdate;
1395
+ }
1396
+ if (patchArg.autoAcceptPermissions !== undefined) {
1397
+ if (patchArg.autoAcceptPermissions) {
1398
+ targetArg.autoAcceptPermissions = true;
1399
+ }
1400
+ else {
1401
+ // Disabled is an absent key; undefined values are dropped on write.
1402
+ delete targetArg.autoAcceptPermissions;
1403
+ }
1404
+ }
1405
+ if (patchArg.selectedOpenCodeProviderConnectionId !== undefined) {
1406
+ if (patchArg.selectedOpenCodeProviderConnectionId === null) {
1407
+ delete targetArg.selectedOpenCodeProviderConnectionId;
1408
+ }
1409
+ else {
1410
+ targetArg.selectedOpenCodeProviderConnectionId = patchArg.selectedOpenCodeProviderConnectionId;
1411
+ }
1412
+ }
1413
+ };
1414
+ const stored = await ControllerSettingsModel.exact.findStoredOne({ id: settingsId });
1415
+ if (!stored) {
1416
+ const candidate = {
1417
+ id: settingsId,
1418
+ controllerId,
1419
+ defaultModels: [],
1420
+ };
1421
+ applyPatch(candidate);
1422
+ const insertResult = await ControllerSettingsModel.exact.insert(candidate);
1423
+ if (insertResult.status !== 'conflict') {
1424
+ return ControllerSettingsModel.exact.toPersisted(insertResult.document);
1425
+ }
1426
+ // fall through to transition against the concurrently created document
1427
+ }
1428
+ const current = stored ?? await ControllerSettingsModel.exact.findStoredOne({ id: settingsId });
1429
+ if (!current) {
1430
+ throw new AuthError('ambiguous_write', 'The settings document has an ambiguous state.');
1431
+ }
1432
+ const result = await ControllerSettingsModel.exact.transition({
1433
+ current,
1434
+ change: (model) => {
1435
+ applyPatch(model);
1436
+ },
1437
+ });
1438
+ if (result.status !== 'transitioned') {
1439
+ throw new AuthError('concurrent_change', 'The settings changed concurrently and were not updated.');
1440
+ }
1441
+ const persisted = ControllerSettingsModel.exact.toPersisted(result.document);
1442
+ return { ...persisted, defaultModels: persisted.defaultModels.map(cloneModelChoice) };
1443
+ }
1444
+ async getSessionLayout(projectIdArg) {
1445
+ this.assertInitialized();
1446
+ const controllerId = this.requireControllerId();
1447
+ const stored = await ControllerSessionGroupsModel.exact.findStoredOne({
1448
+ id: `${controllerId}:groups:${projectIdArg}`,
1449
+ });
1450
+ if (!stored)
1451
+ return { groups: [], ungroupedSessionIds: [], revision: 0 };
1452
+ const persisted = ControllerSessionGroupsModel.exact.toPersisted(stored);
1453
+ return {
1454
+ groups: persisted.groups.map((group) => ({
1455
+ ...group,
1456
+ sessionIds: group.sessionIds.filter(isSessionId).map((sessionId) => ({ ...sessionId })),
1457
+ })),
1458
+ ungroupedSessionIds: (persisted.ungroupedSessionIds ?? []).filter(isSessionId).map((sessionId) => ({ ...sessionId })),
1459
+ revision: persisted.revision ?? 0,
1460
+ };
1461
+ }
1462
+ async updateSessionLayout(projectIdArg, groupsArg, ungroupedSessionIdsArg, expectedRevisionArg) {
1463
+ this.assertInitialized();
1464
+ const controllerId = this.requireControllerId();
1465
+ const documentId = `${controllerId}:groups:${projectIdArg}`;
1466
+ const stored = await ControllerSessionGroupsModel.exact.findStoredOne({ id: documentId });
1467
+ const groups = groupsArg.map((group) => ({
1468
+ id: group.id,
1469
+ name: group.name,
1470
+ sessionIds: group.sessionIds.map((sessionId) => ({ ...sessionId })),
1471
+ }));
1472
+ const groupedSessionIds = new Set(groups.flatMap((group) => group.sessionIds.map(controllerRuntimeIdKey)));
1473
+ const storedPersisted = stored
1474
+ ? ControllerSessionGroupsModel.exact.toPersisted(stored)
1475
+ : undefined;
1476
+ const storedRevision = storedPersisted?.revision ?? 0;
1477
+ if (expectedRevisionArg !== undefined && expectedRevisionArg !== storedRevision) {
1478
+ throw new AuthError('concurrent_change', 'The session layout changed in another client.');
1479
+ }
1480
+ const persistedUngroupedIds = storedPersisted?.ungroupedSessionIds ?? [];
1481
+ const ungroupedSessionIds = ungroupedSessionIdsArg === undefined
1482
+ ? persistedUngroupedIds.filter((sessionId) => !groupedSessionIds.has(controllerRuntimeIdKey(sessionId)))
1483
+ : ungroupedSessionIdsArg.map((sessionId) => ({ ...sessionId }));
1484
+ const candidate = {
1485
+ id: documentId,
1486
+ controllerId,
1487
+ projectId: projectIdArg,
1488
+ groups,
1489
+ ungroupedSessionIds,
1490
+ revision: storedRevision + 1,
1491
+ };
1492
+ if (!stored) {
1493
+ const insertResult = await ControllerSessionGroupsModel.exact.insert(candidate);
1494
+ if (insertResult.status !== 'conflict') {
1495
+ return { groups, ungroupedSessionIds: ungroupedSessionIds.filter(isSessionId), revision: candidate.revision };
1496
+ }
1497
+ if (expectedRevisionArg !== undefined) {
1498
+ throw new AuthError('concurrent_change', 'The session layout changed in another client.');
1499
+ }
1500
+ // A legacy client did not supply a revision, so preserve its prior
1501
+ // last-write behavior against the concurrently created document.
1502
+ }
1503
+ const current = stored ?? await ControllerSessionGroupsModel.exact.findStoredOne({ id: documentId });
1504
+ if (!current) {
1505
+ throw new AuthError('ambiguous_write', 'The session groups document has an ambiguous state.');
1506
+ }
1507
+ const currentPersisted = ControllerSessionGroupsModel.exact.toPersisted(current);
1508
+ const currentRevision = currentPersisted.revision ?? 0;
1509
+ if (expectedRevisionArg !== undefined && expectedRevisionArg !== currentRevision) {
1510
+ throw new AuthError('concurrent_change', 'The session layout changed in another client.');
1511
+ }
1512
+ const transitionUngroupedSessionIds = ungroupedSessionIdsArg === undefined
1513
+ ? (currentPersisted.ungroupedSessionIds ?? []).filter((sessionId) => !groupedSessionIds.has(controllerRuntimeIdKey(sessionId)))
1514
+ : candidate.ungroupedSessionIds;
1515
+ const result = await ControllerSessionGroupsModel.exact.transition({
1516
+ current,
1517
+ change: (model) => {
1518
+ model.groups = candidate.groups;
1519
+ model.ungroupedSessionIds = transitionUngroupedSessionIds;
1520
+ model.revision = currentRevision + 1;
1521
+ },
1522
+ });
1523
+ if (result.status !== 'transitioned') {
1524
+ throw new AuthError('concurrent_change', 'The session groups changed concurrently and were not updated.');
1525
+ }
1526
+ const persisted = ControllerSessionGroupsModel.exact.toPersisted(result.document);
1527
+ return {
1528
+ groups: persisted.groups.map((group) => ({
1529
+ ...group,
1530
+ sessionIds: group.sessionIds.filter(isSessionId),
1531
+ })),
1532
+ ungroupedSessionIds: (persisted.ungroupedSessionIds ?? []).filter(isSessionId),
1533
+ revision: persisted.revision ?? 0,
1534
+ };
1535
+ }
1536
+ async removeSessionFromLayout(projectIdArg, sessionIdArg) {
1537
+ const sessionKey = controllerRuntimeIdKey(sessionIdArg);
1538
+ return this.filterSessionLayout(projectIdArg, (sessionId) => controllerRuntimeIdKey(sessionId) !== sessionKey);
1539
+ }
1540
+ async pruneTerminalLayoutEntries(projectIdArg, liveTerminalIdsArg) {
1541
+ const liveTerminalKeys = new Set(liveTerminalIdsArg.map(controllerRuntimeIdKey));
1542
+ return this.filterSessionLayout(projectIdArg, (layoutItemId) => (layoutItemId.harnessId !== 'controller'
1543
+ || liveTerminalKeys.has(controllerRuntimeIdKey(layoutItemId))));
1544
+ }
1545
+ async pruneArchivedSessionLayoutEntries(projectIdArg, archivedSessionIdsArg) {
1546
+ const archivedSessionKeys = new Set(archivedSessionIdsArg.map(controllerRuntimeIdKey));
1547
+ return this.filterSessionLayout(projectIdArg, (sessionId) => !archivedSessionKeys.has(controllerRuntimeIdKey(sessionId)));
1548
+ }
1549
+ async filterSessionLayout(projectIdArg, keepSessionArg) {
1550
+ this.assertInitialized();
1551
+ const documentId = `${this.requireControllerId()}:groups:${projectIdArg}`;
1552
+ for (let attempt = 0; attempt < 3; attempt += 1) {
1553
+ const current = await ControllerSessionGroupsModel.exact.findStoredOne({ id: documentId });
1554
+ if (!current)
1555
+ return false;
1556
+ const persisted = ControllerSessionGroupsModel.exact.toPersisted(current);
1557
+ const groups = persisted.groups.map((group) => ({
1558
+ ...group,
1559
+ sessionIds: group.sessionIds.filter(keepSessionArg),
1560
+ }));
1561
+ const ungroupedSessionIds = (persisted.ungroupedSessionIds ?? []).filter(keepSessionArg);
1562
+ const changed = groups.some((group, index) => (group.sessionIds.length !== persisted.groups[index].sessionIds.length)) || ungroupedSessionIds.length !== (persisted.ungroupedSessionIds ?? []).length;
1563
+ if (!changed)
1564
+ return false;
1565
+ const result = await ControllerSessionGroupsModel.exact.transition({
1566
+ current,
1567
+ change: (model) => {
1568
+ model.groups = groups;
1569
+ model.ungroupedSessionIds = ungroupedSessionIds;
1570
+ model.revision = (persisted.revision ?? 0) + 1;
1571
+ },
1572
+ });
1573
+ if (result.status === 'transitioned')
1574
+ return true;
1575
+ }
1576
+ throw new AuthError('concurrent_change', 'The session layout changed concurrently and was not pruned.');
1577
+ }
1578
+ sessionStateIdentity(projectIdArg, sessionIdArg) {
1579
+ const controllerId = this.requireControllerId();
1580
+ if (typeof projectIdArg !== 'string'
1581
+ || projectIdArg.length === 0
1582
+ || projectIdArg.length > 64
1583
+ || typeof sessionIdArg?.nativeId !== 'string'
1584
+ || sessionIdArg.nativeId.length === 0
1585
+ || Buffer.byteLength(sessionIdArg.nativeId, 'utf8') > 512
1586
+ || (sessionIdArg.harnessId !== 'opencode' && sessionIdArg.harnessId !== 'flex')) {
1587
+ throw new AuthError('invalid_project', 'The session-state scope is malformed.');
1588
+ }
1589
+ const sessionId = { ...sessionIdArg };
1590
+ return {
1591
+ controllerId,
1592
+ projectId: projectIdArg,
1593
+ sessionId,
1594
+ id: controllerSessionStateId(controllerId, projectIdArg, sessionId),
1595
+ };
1596
+ }
1597
+ createEmptySessionStateDocument(projectIdArg, sessionIdArg, updateIdArg) {
1598
+ const identity = this.sessionStateIdentity(projectIdArg, sessionIdArg);
1599
+ return {
1600
+ ...identity,
1601
+ scratchpad: { text: '', revision: 0 },
1602
+ intelligenceExchanges: [],
1603
+ updateId: updateIdArg,
1604
+ };
1605
+ }
1606
+ async findStoredSessionState(projectIdArg, sessionIdArg) {
1607
+ this.assertInitialized();
1608
+ const { id } = this.sessionStateIdentity(projectIdArg, sessionIdArg);
1609
+ return (await ControllerSessionStateModel.exact.findStoredOne({ id })) ?? undefined;
1610
+ }
1611
+ async insertSessionState(candidateArg) {
1612
+ try {
1613
+ const result = await ControllerSessionStateModel.exact.insert(candidateArg);
1614
+ if (result.status === 'conflict') {
1615
+ throw new AuthError('concurrent_change', 'The session state was created concurrently.');
1616
+ }
1617
+ return ControllerSessionStateModel.exact.toPersisted(result.document);
1618
+ }
1619
+ catch (errorArg) {
1620
+ if (!isAmbiguousWrite(errorArg))
1621
+ throw errorArg;
1622
+ const reconciled = await ControllerSessionStateModel.exact.findStoredOne({ id: candidateArg.id });
1623
+ if (reconciled) {
1624
+ const document = ControllerSessionStateModel.exact.toPersisted(reconciled);
1625
+ if (document.updateId === candidateArg.updateId)
1626
+ return document;
1627
+ }
1628
+ throw new AuthError('ambiguous_write', 'The session-state insertion has an ambiguous outcome.', { cause: errorArg });
1629
+ }
1630
+ }
1631
+ async transitionSessionState(currentArg, changeArg) {
1632
+ const currentDocument = ControllerSessionStateModel.exact.toPersisted(currentArg);
1633
+ const updateId = randomAuthorityValue();
1634
+ try {
1635
+ const result = await ControllerSessionStateModel.exact.transition({
1636
+ current: currentArg,
1637
+ change: (model) => {
1638
+ changeArg(model);
1639
+ model.updateId = updateId;
1640
+ },
1641
+ });
1642
+ if (result.status !== 'transitioned') {
1643
+ throw new AuthError('concurrent_change', 'The session state changed concurrently.');
1644
+ }
1645
+ return ControllerSessionStateModel.exact.toPersisted(result.document);
1646
+ }
1647
+ catch (errorArg) {
1648
+ if (!isAmbiguousWrite(errorArg))
1649
+ throw errorArg;
1650
+ const reconciled = await ControllerSessionStateModel.exact.findStoredOne({
1651
+ id: currentDocument.id,
1652
+ });
1653
+ if (reconciled) {
1654
+ const document = ControllerSessionStateModel.exact.toPersisted(reconciled);
1655
+ if (document.updateId === updateId)
1656
+ return document;
1657
+ }
1658
+ throw new AuthError('ambiguous_write', 'The session-state transition has an ambiguous outcome.', { cause: errorArg });
1659
+ }
1660
+ }
1661
+ async getSessionState(projectIdArg, sessionIdArg) {
1662
+ const identity = this.sessionStateIdentity(projectIdArg, sessionIdArg);
1663
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
1664
+ if (!stored) {
1665
+ return {
1666
+ scratchpad: { id: identity.id, text: '', revision: 0 },
1667
+ intelligenceExchanges: [],
1668
+ };
1669
+ }
1670
+ return toPublicSessionState(ControllerSessionStateModel.exact.toPersisted(stored));
1671
+ }
1672
+ loadFlexProjectManagement(projectIdArg, sessionIdArg, sessionGenerationArg) {
1673
+ return this.runSessionStateMutation(async () => {
1674
+ assertFlexSessionGeneration(sessionGenerationArg);
1675
+ const runtimeId = { harnessId: 'flex', nativeId: sessionIdArg };
1676
+ for (let attempt = 0; attempt < 3; attempt += 1) {
1677
+ const stored = await this.findStoredSessionState(projectIdArg, runtimeId);
1678
+ if (!stored) {
1679
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, runtimeId, randomAuthorityValue());
1680
+ const snapshot = {
1681
+ schemaVersion: 1,
1682
+ revision: 0,
1683
+ ...sessionGenerationArg,
1684
+ scratchpad: '',
1685
+ tasks: [],
1686
+ };
1687
+ plugins.flexharness.assertFlexProjectManagementSnapshot(snapshot);
1688
+ candidate.flexProjectManagement = snapshot;
1689
+ try {
1690
+ const inserted = await this.insertSessionState(candidate);
1691
+ return cloneProjectManagementRecord(inserted.flexProjectManagement);
1692
+ }
1693
+ catch (errorArg) {
1694
+ if (!(errorArg instanceof AuthError) || errorArg.code !== 'concurrent_change') {
1695
+ throw errorArg;
1696
+ }
1697
+ continue;
1698
+ }
1699
+ }
1700
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1701
+ if (current.flexProjectManagement) {
1702
+ return cloneProjectManagementRecord(current.flexProjectManagement);
1703
+ }
1704
+ if (current.deletedAt)
1705
+ return undefined;
1706
+ const snapshot = {
1707
+ schemaVersion: 1,
1708
+ revision: 0,
1709
+ ...sessionGenerationArg,
1710
+ scratchpad: current.scratchpad.text,
1711
+ tasks: [],
1712
+ };
1713
+ plugins.flexharness.assertFlexProjectManagementSnapshot(snapshot);
1714
+ try {
1715
+ const transitioned = await this.transitionSessionState(stored, (document) => {
1716
+ document.flexProjectManagement = snapshot;
1717
+ });
1718
+ return cloneProjectManagementRecord(transitioned.flexProjectManagement);
1719
+ }
1720
+ catch (errorArg) {
1721
+ if (!(errorArg instanceof AuthError) || errorArg.code !== 'concurrent_change') {
1722
+ throw errorArg;
1723
+ }
1724
+ }
1725
+ }
1726
+ throw new AuthError('concurrent_change', 'The Flex project-management state remained busy during initialization.');
1727
+ });
1728
+ }
1729
+ saveFlexProjectManagement(projectIdArg, sessionIdArg, snapshotArg, expectedRevisionArg, writeContextArg) {
1730
+ return this.runSessionStateMutation(async () => {
1731
+ plugins.flexharness.assertFlexProjectManagementSnapshot(snapshotArg);
1732
+ assertProjectManagementNextRevision(snapshotArg, expectedRevisionArg);
1733
+ assertProjectManagementWriteContext(writeContextArg);
1734
+ const snapshot = cloneProjectManagementRecord(snapshotArg);
1735
+ const runtimeId = { harnessId: 'flex', nativeId: sessionIdArg };
1736
+ const stored = await this.findStoredSessionState(projectIdArg, runtimeId);
1737
+ if (!stored) {
1738
+ if (expectedRevisionArg !== 0) {
1739
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, 0);
1740
+ }
1741
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, runtimeId, randomAuthorityValue());
1742
+ candidate.flexProjectManagement = snapshot;
1743
+ if (snapshot.scratchpad !== '') {
1744
+ candidate.scratchpad = {
1745
+ text: snapshot.scratchpad,
1746
+ revision: 1,
1747
+ updatedAt: new Date(),
1748
+ updatedBy: projectManagementUpdater(writeContextArg),
1749
+ };
1750
+ }
1751
+ try {
1752
+ await this.insertSessionState(candidate);
1753
+ return;
1754
+ }
1755
+ catch (errorArg) {
1756
+ if (errorArg instanceof AuthError && errorArg.code === 'concurrent_change') {
1757
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, 0);
1758
+ }
1759
+ throw errorArg;
1760
+ }
1761
+ }
1762
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1763
+ const currentProjectManagement = current.flexProjectManagement;
1764
+ const actualRevision = currentProjectManagement?.revision ?? 0;
1765
+ const sameGeneration = currentProjectManagement
1766
+ ? sameProjectManagementGeneration(currentProjectManagement, snapshot)
1767
+ : false;
1768
+ const canInitialize = currentProjectManagement
1769
+ ? canInitializeProjectManagementGeneration(currentProjectManagement, snapshot, expectedRevisionArg)
1770
+ : expectedRevisionArg === 0;
1771
+ const conflicts = currentProjectManagement
1772
+ ? sameGeneration
1773
+ ? Object.hasOwn(currentProjectManagement, 'deletedAt')
1774
+ || actualRevision !== expectedRevisionArg
1775
+ : !canInitialize
1776
+ : !canInitialize || (!current.deletedAt && current.scratchpad.text !== snapshot.scratchpad);
1777
+ if (conflicts) {
1778
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, actualRevision);
1779
+ }
1780
+ const reviving = current.deletedAt !== undefined;
1781
+ await this.transitionSessionState(stored, (document) => {
1782
+ if (reviving) {
1783
+ delete document.deletedAt;
1784
+ document.intelligenceExchanges = [];
1785
+ delete document.modelChoice;
1786
+ }
1787
+ if (reviving || document.scratchpad.text !== snapshot.scratchpad) {
1788
+ document.scratchpad = {
1789
+ text: snapshot.scratchpad,
1790
+ revision: document.scratchpad.revision + 1,
1791
+ updatedAt: new Date(),
1792
+ updatedBy: projectManagementUpdater(writeContextArg),
1793
+ };
1794
+ }
1795
+ document.flexProjectManagement = snapshot;
1796
+ });
1797
+ });
1798
+ }
1799
+ tombstoneFlexProjectManagement(projectIdArg, sessionIdArg, tombstoneArg, expectedRevisionArg) {
1800
+ return this.runSessionStateMutation(async () => {
1801
+ plugins.flexharness.assertFlexProjectManagementTombstone(tombstoneArg);
1802
+ assertProjectManagementNextRevision(tombstoneArg, expectedRevisionArg);
1803
+ const tombstone = cloneProjectManagementRecord(tombstoneArg);
1804
+ const runtimeId = { harnessId: 'flex', nativeId: sessionIdArg };
1805
+ const stored = await this.findStoredSessionState(projectIdArg, runtimeId);
1806
+ const deletedAt = new Date(tombstone.deletedAt);
1807
+ if (!stored) {
1808
+ if (expectedRevisionArg !== 0) {
1809
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, 0);
1810
+ }
1811
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, runtimeId, randomAuthorityValue());
1812
+ candidate.flexProjectManagement = tombstone;
1813
+ this.applySessionStateTombstone(candidate, deletedAt);
1814
+ try {
1815
+ await this.insertSessionState(candidate);
1816
+ return;
1817
+ }
1818
+ catch (errorArg) {
1819
+ if (errorArg instanceof AuthError && errorArg.code === 'concurrent_change') {
1820
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, 0);
1821
+ }
1822
+ throw errorArg;
1823
+ }
1824
+ }
1825
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1826
+ const currentProjectManagement = current.flexProjectManagement;
1827
+ const actualRevision = currentProjectManagement?.revision ?? 0;
1828
+ if (currentProjectManagement && sameProjectManagementGeneration(currentProjectManagement, tombstone)) {
1829
+ if (Object.hasOwn(currentProjectManagement, 'deletedAt'))
1830
+ return;
1831
+ if (actualRevision !== expectedRevisionArg) {
1832
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, actualRevision);
1833
+ }
1834
+ }
1835
+ else if (currentProjectManagement
1836
+ ? !canInitializeProjectManagementGeneration(currentProjectManagement, tombstone, expectedRevisionArg)
1837
+ : expectedRevisionArg !== 0) {
1838
+ throw new plugins.flexharness.FlexHarnessStoreConflictError(projectManagementStoreKey(projectIdArg, sessionIdArg), expectedRevisionArg, actualRevision);
1839
+ }
1840
+ await this.transitionSessionState(stored, (document) => {
1841
+ document.flexProjectManagement = tombstone;
1842
+ this.applySessionStateTombstone(document, deletedAt);
1843
+ });
1844
+ });
1845
+ }
1846
+ purgeFlexProjectManagementNamespace(projectIdArg) {
1847
+ return this.runSessionStateMutation(async () => {
1848
+ this.assertInitialized();
1849
+ const controllerId = this.requireControllerId();
1850
+ this.sessionStateIdentity(projectIdArg, { harnessId: 'flex', nativeId: 'validation' });
1851
+ let lastStoredId;
1852
+ for (let pageIndex = 0; pageIndex < maxSessionStateRetirementPages; pageIndex += 1) {
1853
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
1854
+ filter: {
1855
+ controllerId,
1856
+ projectId: projectIdArg,
1857
+ flexProjectManagement: { $exists: true },
1858
+ ...(lastStoredId === undefined ? {} : { _id: { $gt: lastStoredId } }),
1859
+ },
1860
+ sort: { _id: 1 },
1861
+ limit: sessionStateRetirementPageLimit,
1862
+ });
1863
+ for (const stored of storedEntries) {
1864
+ await this.transitionSessionState(stored, (document) => {
1865
+ delete document.flexProjectManagement;
1866
+ });
1867
+ }
1868
+ const lastStored = storedEntries.at(-1);
1869
+ if (!lastStored || storedEntries.length < sessionStateRetirementPageLimit)
1870
+ return;
1871
+ lastStoredId = lastStored._id;
1872
+ }
1873
+ throw new Error('Flex project-management namespace purge exceeded its bounded scan.');
1874
+ });
1875
+ }
1876
+ async setSessionModelChoice(projectIdArg, sessionIdArg, modelChoiceArg) {
1877
+ if (modelChoiceArg.harnessId !== sessionIdArg.harnessId) {
1878
+ throw new Error('The session model choice belongs to a different harness.');
1879
+ }
1880
+ const modelChoice = cloneModelChoice(modelChoiceArg);
1881
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
1882
+ if (!stored) {
1883
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, sessionIdArg, randomAuthorityValue());
1884
+ candidate.modelChoice = modelChoice;
1885
+ return toPublicSessionState(await this.insertSessionState(candidate));
1886
+ }
1887
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1888
+ if (current.deletedAt) {
1889
+ throw new AuthError('concurrent_change', 'The deleted session state cannot be recreated.');
1890
+ }
1891
+ return toPublicSessionState(await this.transitionSessionState(stored, (document) => {
1892
+ document.modelChoice = modelChoice;
1893
+ }));
1894
+ }
1895
+ async clearStoredSessionModelChoiceForProviderConnection(storedArg, providerConnectionIdArg, signalArg) {
1896
+ let stored = storedArg;
1897
+ for (let attempt = 0; attempt < sessionModelChoiceClearTransitionMaxAttempts; attempt++) {
1898
+ signalArg?.throwIfAborted();
1899
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1900
+ if (current.deletedAt
1901
+ || current.modelChoice?.harnessId !== 'flex'
1902
+ || current.modelChoice.providerConnectionId !== providerConnectionIdArg)
1903
+ return false;
1904
+ try {
1905
+ await this.transitionSessionState(stored, (document) => {
1906
+ if (document.modelChoice?.harnessId === 'flex'
1907
+ && document.modelChoice.providerConnectionId === providerConnectionIdArg)
1908
+ delete document.modelChoice;
1909
+ });
1910
+ return true;
1911
+ }
1912
+ catch (errorArg) {
1913
+ if (!(errorArg instanceof AuthError)
1914
+ || (errorArg.code !== 'concurrent_change' && errorArg.code !== 'ambiguous_write'))
1915
+ throw errorArg;
1916
+ const latest = await this.findStoredSessionState(current.projectId, current.sessionId);
1917
+ if (!latest)
1918
+ return false;
1919
+ stored = latest;
1920
+ }
1921
+ }
1922
+ throw new AuthError('concurrent_change', 'The session model choice remained busy during provider cleanup.');
1923
+ }
1924
+ async clearSessionModelChoicesForProviderConnection(providerConnectionIdArg, signalArg) {
1925
+ this.assertInitialized();
1926
+ const controllerId = this.requireControllerId();
1927
+ if (typeof providerConnectionIdArg !== 'string'
1928
+ || providerConnectionIdArg.length === 0
1929
+ || Buffer.byteLength(providerConnectionIdArg, 'utf8') > 512) {
1930
+ throw new Error('The provider connection identifier is malformed.');
1931
+ }
1932
+ let clearedCount = 0;
1933
+ let lastStoredId;
1934
+ while (true) {
1935
+ signalArg?.throwIfAborted();
1936
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
1937
+ filter: {
1938
+ controllerId,
1939
+ deletedAt: { $exists: false },
1940
+ modelChoice: { $exists: true },
1941
+ ...(lastStoredId === undefined ? {} : { _id: { $gt: lastStoredId } }),
1942
+ },
1943
+ sort: { _id: 1 },
1944
+ limit: sessionStateRetirementPageLimit,
1945
+ });
1946
+ for (let index = 0; index < storedEntries.length; index += 8) {
1947
+ signalArg?.throwIfAborted();
1948
+ const page = storedEntries.slice(index, index + 8);
1949
+ await Promise.all(page.map(async (storedEntry) => {
1950
+ if (await this.clearStoredSessionModelChoiceForProviderConnection(storedEntry, providerConnectionIdArg, signalArg))
1951
+ clearedCount += 1;
1952
+ }));
1953
+ }
1954
+ const lastStored = storedEntries.at(-1);
1955
+ if (!lastStored || storedEntries.length < sessionStateRetirementPageLimit)
1956
+ return clearedCount;
1957
+ lastStoredId = lastStored._id;
1958
+ }
1959
+ }
1960
+ saveSessionScratchpad(projectIdArg, sessionIdArg, textArg, expectedRevisionArg) {
1961
+ return this.runSessionStateMutation(() => this.saveSessionScratchpadUnqueued(projectIdArg, sessionIdArg, textArg, expectedRevisionArg));
1962
+ }
1963
+ async saveSessionScratchpadUnqueued(projectIdArg, sessionIdArg, textArg, expectedRevisionArg) {
1964
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
1965
+ const now = new Date();
1966
+ if (!stored) {
1967
+ if (expectedRevisionArg !== 0) {
1968
+ throw new AuthError('concurrent_change', 'The scratchpad revision is stale.');
1969
+ }
1970
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, sessionIdArg, randomAuthorityValue());
1971
+ candidate.scratchpad = {
1972
+ text: textArg,
1973
+ revision: 1,
1974
+ updatedAt: now,
1975
+ updatedBy: 'user',
1976
+ };
1977
+ return toPublicSessionState(await this.insertSessionState(candidate));
1978
+ }
1979
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
1980
+ if (current.deletedAt) {
1981
+ throw new AuthError('concurrent_change', 'The deleted session state cannot be recreated.');
1982
+ }
1983
+ if (current.scratchpad.revision !== expectedRevisionArg) {
1984
+ throw new AuthError('concurrent_change', 'The scratchpad revision is stale.');
1985
+ }
1986
+ const next = await this.transitionSessionState(stored, (document) => {
1987
+ document.scratchpad = {
1988
+ text: textArg,
1989
+ revision: expectedRevisionArg + 1,
1990
+ updatedAt: now,
1991
+ updatedBy: 'user',
1992
+ };
1993
+ this.applyFlexProjectManagementScratchpad(document, textArg);
1994
+ });
1995
+ return toPublicSessionState(next);
1996
+ }
1997
+ admitSessionIntelligence(projectIdArg, sessionIdArg, questionArg) {
1998
+ return this.runSessionStateMutation(() => this.admitSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, questionArg));
1999
+ }
2000
+ async admitSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, questionArg) {
2001
+ const exchangeId = plugins.crypto.randomBytes(16).toString('base64url');
2002
+ const createdAt = new Date();
2003
+ let stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2004
+ if (!stored) {
2005
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, sessionIdArg, randomAuthorityValue());
2006
+ candidate.intelligenceExchanges = [{
2007
+ id: exchangeId,
2008
+ question: questionArg,
2009
+ status: 'running',
2010
+ scratchpadRevisionAtAdmission: 0,
2011
+ createdAt,
2012
+ }];
2013
+ const inserted = await this.insertSessionState(candidate);
2014
+ return {
2015
+ exchange: toPublicIntelligenceExchange(inserted.intelligenceExchanges[0]),
2016
+ scratchpadRevision: 0,
2017
+ scratchpadText: '',
2018
+ };
2019
+ }
2020
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2021
+ if (current.deletedAt) {
2022
+ throw new AuthError('concurrent_change', 'The deleted session state cannot be recreated.');
2023
+ }
2024
+ if (current.intelligenceExchanges.some((exchange) => exchange.status === 'running' || exchange.temporarySessionId !== undefined)) {
2025
+ throw new AuthError('concurrent_change', 'Session Intelligence is already running or its cleanup is still pending.');
2026
+ }
2027
+ const scratchpadRevision = current.scratchpad.revision;
2028
+ const next = await this.transitionSessionState(stored, (document) => {
2029
+ document.intelligenceExchanges = trimSessionStateExchanges([
2030
+ ...document.intelligenceExchanges,
2031
+ {
2032
+ id: exchangeId,
2033
+ question: questionArg,
2034
+ status: 'running',
2035
+ scratchpadRevisionAtAdmission: scratchpadRevision,
2036
+ createdAt,
2037
+ },
2038
+ ], exchangeId);
2039
+ });
2040
+ const exchange = next.intelligenceExchanges.find((entry) => entry.id === exchangeId);
2041
+ return {
2042
+ exchange: toPublicIntelligenceExchange(exchange),
2043
+ scratchpadRevision,
2044
+ scratchpadText: current.scratchpad.text,
2045
+ };
2046
+ }
2047
+ attachSessionIntelligenceTemporarySession(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg) {
2048
+ return this.runSessionStateMutation(() => this.attachSessionIntelligenceTemporarySessionUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg));
2049
+ }
2050
+ async attachSessionIntelligenceTemporarySessionUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg) {
2051
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2052
+ if (!stored)
2053
+ throw new AuthError('concurrent_change', 'The intelligence admission is missing.');
2054
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2055
+ const exchange = current.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2056
+ if (current.deletedAt || exchange?.status !== 'running') {
2057
+ throw new AuthError('concurrent_change', 'The intelligence admission is no longer active.');
2058
+ }
2059
+ await this.transitionSessionState(stored, (document) => {
2060
+ const target = document.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2061
+ target.temporarySessionId = temporarySessionIdArg;
2062
+ });
2063
+ }
2064
+ completeSessionIntelligence(projectIdArg, sessionIdArg, exchangeIdArg, answerArg, scratchpadTextArg, modelArg) {
2065
+ return this.runSessionStateMutation(() => this.completeSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, answerArg, scratchpadTextArg, modelArg));
2066
+ }
2067
+ async completeSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, answerArg, scratchpadTextArg, modelArg) {
2068
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2069
+ if (!stored)
2070
+ return undefined;
2071
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2072
+ const exchange = current.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2073
+ if (current.deletedAt || exchange?.status !== 'running')
2074
+ return undefined;
2075
+ const scratchpadConflict = current.scratchpad.revision !== exchange.scratchpadRevisionAtAdmission;
2076
+ const completedAt = new Date();
2077
+ const next = await this.transitionSessionState(stored, (document) => {
2078
+ const target = document.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2079
+ document.intelligenceExchanges = trimSessionStateExchanges(document.intelligenceExchanges.map((entry) => entry.id === exchangeIdArg
2080
+ ? {
2081
+ id: target.id,
2082
+ question: target.question,
2083
+ status: 'completed',
2084
+ answer: answerArg,
2085
+ model: modelArg,
2086
+ ...(scratchpadConflict ? { scratchpadConflict: true } : {}),
2087
+ ...(target.temporarySessionId === undefined
2088
+ ? {}
2089
+ : { temporarySessionId: target.temporarySessionId }),
2090
+ createdAt: target.createdAt,
2091
+ completedAt,
2092
+ }
2093
+ : entry), exchangeIdArg);
2094
+ if (!scratchpadConflict && document.scratchpad.text !== scratchpadTextArg) {
2095
+ document.scratchpad = {
2096
+ text: scratchpadTextArg,
2097
+ revision: document.scratchpad.revision + 1,
2098
+ updatedAt: completedAt,
2099
+ updatedBy: 'intelligence',
2100
+ };
2101
+ this.applyFlexProjectManagementScratchpad(document, scratchpadTextArg);
2102
+ }
2103
+ });
2104
+ return toPublicSessionState(next);
2105
+ }
2106
+ failSessionIntelligence(projectIdArg, sessionIdArg, exchangeIdArg, errorArg, modelArg) {
2107
+ return this.runSessionStateMutation(() => this.failSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, errorArg, modelArg));
2108
+ }
2109
+ async failSessionIntelligenceUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, errorArg, modelArg) {
2110
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2111
+ if (!stored)
2112
+ return undefined;
2113
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2114
+ const exchange = current.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2115
+ if (current.deletedAt || exchange?.status !== 'running')
2116
+ return undefined;
2117
+ const completedAt = new Date();
2118
+ const next = await this.transitionSessionState(stored, (document) => {
2119
+ const target = document.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2120
+ document.intelligenceExchanges = trimSessionStateExchanges(document.intelligenceExchanges.map((entry) => entry.id === exchangeIdArg
2121
+ ? {
2122
+ id: target.id,
2123
+ question: target.question,
2124
+ status: 'error',
2125
+ error: errorArg,
2126
+ ...(modelArg === undefined ? {} : { model: modelArg }),
2127
+ ...(target.temporarySessionId === undefined
2128
+ ? {}
2129
+ : { temporarySessionId: target.temporarySessionId }),
2130
+ createdAt: target.createdAt,
2131
+ completedAt,
2132
+ }
2133
+ : entry), exchangeIdArg);
2134
+ });
2135
+ return toPublicSessionState(next);
2136
+ }
2137
+ recoverInterruptedSessionIntelligence() {
2138
+ return this.runSessionStateMutation(() => this.recoverInterruptedSessionIntelligenceUnqueued());
2139
+ }
2140
+ async recoverInterruptedSessionIntelligenceUnqueued() {
2141
+ this.assertInitialized();
2142
+ const controllerId = this.requireControllerId();
2143
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
2144
+ filter: {
2145
+ controllerId,
2146
+ deletedAt: { $exists: false },
2147
+ intelligenceExchanges: { $elemMatch: { status: 'running' } },
2148
+ },
2149
+ limit: sessionStateRecoveryLimit,
2150
+ });
2151
+ const temporarySessionIds = [];
2152
+ let recoveredCount = 0;
2153
+ for (const stored of storedEntries) {
2154
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2155
+ for (const exchange of current.intelligenceExchanges) {
2156
+ if (exchange.status === 'running' && exchange.temporarySessionId) {
2157
+ temporarySessionIds.push({
2158
+ projectId: current.projectId,
2159
+ sessionId: current.sessionId,
2160
+ exchangeId: exchange.id,
2161
+ nativeId: exchange.temporarySessionId,
2162
+ });
2163
+ }
2164
+ }
2165
+ const completedAt = new Date();
2166
+ await this.transitionSessionState(stored, (document) => {
2167
+ document.intelligenceExchanges = document.intelligenceExchanges.map((exchange) => exchange.status === 'running'
2168
+ ? {
2169
+ id: exchange.id,
2170
+ question: exchange.question,
2171
+ status: 'error',
2172
+ error: 'Session Intelligence was interrupted by a controller restart.',
2173
+ ...(exchange.temporarySessionId === undefined
2174
+ ? {}
2175
+ : { temporarySessionId: exchange.temporarySessionId }),
2176
+ createdAt: exchange.createdAt,
2177
+ completedAt,
2178
+ }
2179
+ : exchange);
2180
+ });
2181
+ recoveredCount += 1;
2182
+ }
2183
+ return {
2184
+ recoveredCount,
2185
+ exhaustive: storedEntries.length < sessionStateRecoveryLimit,
2186
+ temporarySessionIds,
2187
+ };
2188
+ }
2189
+ async listProjectSessionIntelligenceCleanupObligations(projectIdArg) {
2190
+ this.assertInitialized();
2191
+ const controllerId = this.requireControllerId();
2192
+ if (typeof projectIdArg !== 'string'
2193
+ || projectIdArg.length === 0
2194
+ || projectIdArg.length > 64) {
2195
+ throw new AuthError('invalid_project', 'The project identifier is malformed.');
2196
+ }
2197
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
2198
+ filter: {
2199
+ controllerId,
2200
+ projectId: projectIdArg,
2201
+ deletedAt: { $exists: false },
2202
+ intelligenceExchanges: { $elemMatch: { temporarySessionId: { $exists: true } } },
2203
+ },
2204
+ limit: sessionStateRecoveryLimit,
2205
+ });
2206
+ return storedEntries.flatMap((stored) => {
2207
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2208
+ return current.intelligenceExchanges.flatMap((exchange) => exchange.temporarySessionId
2209
+ ? [{
2210
+ projectId: current.projectId,
2211
+ sessionId: current.sessionId,
2212
+ exchangeId: exchange.id,
2213
+ nativeId: exchange.temporarySessionId,
2214
+ }]
2215
+ : []);
2216
+ });
2217
+ }
2218
+ async getSessionIntelligenceCleanupObligations(projectIdArg, sessionIdArg) {
2219
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2220
+ if (!stored)
2221
+ return [];
2222
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2223
+ if (current.deletedAt)
2224
+ return [];
2225
+ return current.intelligenceExchanges.flatMap((exchange) => exchange.temporarySessionId
2226
+ ? [{
2227
+ projectId: current.projectId,
2228
+ sessionId: current.sessionId,
2229
+ exchangeId: exchange.id,
2230
+ nativeId: exchange.temporarySessionId,
2231
+ }]
2232
+ : []);
2233
+ }
2234
+ async findProjectSessionIntelligenceTemporarySessionIds(projectIdArg, candidateIdsArg, signalArg) {
2235
+ this.assertInitialized();
2236
+ const controllerId = this.requireControllerId();
2237
+ if (typeof projectIdArg !== 'string'
2238
+ || projectIdArg.length === 0
2239
+ || projectIdArg.length > 64
2240
+ || candidateIdsArg.length > 512
2241
+ || candidateIdsArg.some((id) => (typeof id !== 'string'
2242
+ || id.length === 0
2243
+ || Buffer.byteLength(id, 'utf8') > 512))) {
2244
+ throw new AuthError('invalid_project', 'The temporary-session lookup is malformed.');
2245
+ }
2246
+ const candidateIds = [...new Set(candidateIdsArg)];
2247
+ if (candidateIds.length === 0)
2248
+ return new Set();
2249
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
2250
+ filter: {
2251
+ controllerId,
2252
+ projectId: projectIdArg,
2253
+ deletedAt: { $exists: false },
2254
+ intelligenceExchanges: {
2255
+ $elemMatch: { temporarySessionId: { $in: candidateIds } },
2256
+ },
2257
+ },
2258
+ limit: candidateIds.length,
2259
+ signal: signalArg,
2260
+ });
2261
+ const candidateSet = new Set(candidateIds);
2262
+ return new Set(storedEntries.flatMap((stored) => ControllerSessionStateModel.exact.toPersisted(stored).intelligenceExchanges.flatMap((exchange) => exchange.temporarySessionId
2263
+ && candidateSet.has(exchange.temporarySessionId)
2264
+ ? [exchange.temporarySessionId]
2265
+ : [])));
2266
+ }
2267
+ async isSessionStateTombstoned(projectIdArg, sessionIdArg) {
2268
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2269
+ if (!stored)
2270
+ return false;
2271
+ return ControllerSessionStateModel.exact.toPersisted(stored).deletedAt !== undefined;
2272
+ }
2273
+ async retireProjectSessionStates(projectIdArg, cleanupTemporarySessionArg, signalArg) {
2274
+ this.assertInitialized();
2275
+ const controllerId = this.requireControllerId();
2276
+ if (typeof projectIdArg !== 'string'
2277
+ || projectIdArg.length === 0
2278
+ || projectIdArg.length > 64) {
2279
+ throw new AuthError('invalid_project', 'The project identifier is malformed.');
2280
+ }
2281
+ const temporarySessionIds = new Set();
2282
+ let retiredCount = 0;
2283
+ let lastStoredId;
2284
+ for (let pageIndex = 0; pageIndex < maxSessionStateRetirementPages; pageIndex += 1) {
2285
+ signalArg?.throwIfAborted();
2286
+ const storedEntries = await ControllerSessionStateModel.exact.findStored({
2287
+ filter: {
2288
+ controllerId,
2289
+ projectId: projectIdArg,
2290
+ deletedAt: { $exists: false },
2291
+ ...(lastStoredId === undefined ? {} : { _id: { $gt: lastStoredId } }),
2292
+ },
2293
+ sort: { _id: 1 },
2294
+ limit: sessionStateRetirementPageLimit,
2295
+ });
2296
+ signalArg?.throwIfAborted();
2297
+ for (const stored of storedEntries) {
2298
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2299
+ for (const exchange of current.intelligenceExchanges) {
2300
+ if (!exchange.temporarySessionId || temporarySessionIds.has(exchange.temporarySessionId)) {
2301
+ continue;
2302
+ }
2303
+ signalArg?.throwIfAborted();
2304
+ await cleanupTemporarySessionArg(exchange.temporarySessionId);
2305
+ temporarySessionIds.add(exchange.temporarySessionId);
2306
+ }
2307
+ signalArg?.throwIfAborted();
2308
+ const retired = await this.runSessionStateMutation(async () => {
2309
+ const latest = await this.findStoredSessionState(projectIdArg, current.sessionId);
2310
+ if (!latest || ControllerSessionStateModel.exact.toPersisted(latest).deletedAt)
2311
+ return false;
2312
+ await this.transitionSessionState(latest, (document) => {
2313
+ this.applySessionStateTombstone(document, new Date());
2314
+ });
2315
+ return true;
2316
+ });
2317
+ if (retired)
2318
+ retiredCount += 1;
2319
+ }
2320
+ const lastStored = storedEntries.at(-1);
2321
+ if (!lastStored || storedEntries.length < sessionStateRetirementPageLimit) {
2322
+ return { retiredCount, temporarySessionIds: [...temporarySessionIds] };
2323
+ }
2324
+ lastStoredId = lastStored._id;
2325
+ }
2326
+ throw new Error(`Project session-state retirement cleared ${retiredCount} state(s) before exceeding its bounded scan.`);
2327
+ }
2328
+ clearSessionIntelligenceTemporarySession(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg) {
2329
+ return this.runSessionStateMutation(() => this.clearSessionIntelligenceTemporarySessionUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg));
2330
+ }
2331
+ async clearSessionIntelligenceTemporarySessionUnqueued(projectIdArg, sessionIdArg, exchangeIdArg, temporarySessionIdArg) {
2332
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2333
+ if (!stored)
2334
+ return;
2335
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2336
+ const exchange = current.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2337
+ if (current.deletedAt || exchange?.temporarySessionId !== temporarySessionIdArg)
2338
+ return;
2339
+ await this.transitionSessionState(stored, (document) => {
2340
+ const target = document.intelligenceExchanges.find((entry) => entry.id === exchangeIdArg);
2341
+ if (target?.temporarySessionId === temporarySessionIdArg) {
2342
+ delete target.temporarySessionId;
2343
+ }
2344
+ });
2345
+ }
2346
+ tombstoneSessionState(projectIdArg, sessionIdArg) {
2347
+ return this.runSessionStateMutation(() => this.tombstoneSessionStateUnqueued(projectIdArg, sessionIdArg));
2348
+ }
2349
+ async tombstoneSessionStateUnqueued(projectIdArg, sessionIdArg) {
2350
+ const stored = await this.findStoredSessionState(projectIdArg, sessionIdArg);
2351
+ const deletedAt = new Date();
2352
+ if (!stored) {
2353
+ const candidate = this.createEmptySessionStateDocument(projectIdArg, sessionIdArg, randomAuthorityValue());
2354
+ candidate.deletedAt = deletedAt;
2355
+ await this.insertSessionState(candidate);
2356
+ return;
2357
+ }
2358
+ const current = ControllerSessionStateModel.exact.toPersisted(stored);
2359
+ if (current.deletedAt)
2360
+ return;
2361
+ await this.transitionSessionState(stored, (document) => {
2362
+ this.applySessionStateTombstone(document, deletedAt);
2363
+ });
2364
+ }
2365
+ applyFlexProjectManagementScratchpad(documentArg, textArg) {
2366
+ const current = documentArg.flexProjectManagement;
2367
+ if (!current || 'deletedAt' in current || current.scratchpad === textArg)
2368
+ return;
2369
+ const snapshot = {
2370
+ ...current,
2371
+ revision: current.revision + 1,
2372
+ scratchpad: textArg,
2373
+ };
2374
+ plugins.flexharness.assertFlexProjectManagementSnapshot(snapshot);
2375
+ documentArg.flexProjectManagement = snapshot;
2376
+ }
2377
+ applySessionStateTombstone(documentArg, deletedAtArg) {
2378
+ const projectManagement = documentArg.flexProjectManagement;
2379
+ if (projectManagement && !Object.hasOwn(projectManagement, 'deletedAt')) {
2380
+ const tombstone = {
2381
+ schemaVersion: 1,
2382
+ revision: projectManagement.revision + 1,
2383
+ sessionGenerationId: projectManagement.sessionGenerationId,
2384
+ sessionGenerationSequence: projectManagement.sessionGenerationSequence,
2385
+ deletedAt: deletedAtArg.toISOString(),
2386
+ };
2387
+ plugins.flexharness.assertFlexProjectManagementTombstone(tombstone);
2388
+ documentArg.flexProjectManagement = tombstone;
2389
+ }
2390
+ documentArg.scratchpad = {
2391
+ text: '',
2392
+ revision: documentArg.scratchpad.revision,
2393
+ ...(documentArg.scratchpad.updatedAt === undefined
2394
+ ? {}
2395
+ : { updatedAt: documentArg.scratchpad.updatedAt }),
2396
+ ...(documentArg.scratchpad.updatedBy === undefined
2397
+ ? {}
2398
+ : { updatedBy: documentArg.scratchpad.updatedBy }),
2399
+ };
2400
+ documentArg.intelligenceExchanges = [];
2401
+ delete documentArg.modelChoice;
2402
+ documentArg.deletedAt = deletedAtArg;
2403
+ }
2404
+ async createTempPassword(ttlMsArg) {
2405
+ this.assertInitialized();
2406
+ const controllerId = this.requireControllerId();
2407
+ if (!Number.isSafeInteger(ttlMsArg)
2408
+ || ttlMsArg < tempPasswordTtlMinMs
2409
+ || ttlMsArg > tempPasswordTtlMaxMs) {
2410
+ throw new AuthError('temp_password_invalid', 'A temporary password lifetime must be between one minute and 24 hours.');
2411
+ }
2412
+ const now = Date.now();
2413
+ const active = (await ControllerTempPasswordModel.exact.findStored({
2414
+ filter: { controllerId },
2415
+ limit: maxActiveTempPasswords * 4,
2416
+ }))
2417
+ .map((entry) => ControllerTempPasswordModel.exact.toPersisted(entry))
2418
+ .filter((entry) => entry.expiresAt.getTime() > now);
2419
+ if (active.length >= maxActiveTempPasswords) {
2420
+ throw new AuthError('temp_password_limit', `At most ${maxActiveTempPasswords} temporary passwords can be active; wait for one to expire.`);
2421
+ }
2422
+ const password = plugins.crypto.randomBytes(24).toString('base64url');
2423
+ const id = `${controllerId}:temppass:${randomAuthorityValue()}`;
2424
+ const insertResult = await ControllerTempPasswordModel.exact.insert({
2425
+ id,
2426
+ controllerId,
2427
+ secretHash: hashSetupCode(password),
2428
+ createdAt: new Date(now),
2429
+ expiresAt: new Date(now + ttlMsArg),
2430
+ });
2431
+ if (insertResult.status === 'conflict') {
2432
+ throw new AuthError('concurrent_change', 'The temporary password identifier conflicts.');
2433
+ }
2434
+ const persisted = ControllerTempPasswordModel.exact.toPersisted(insertResult.document);
2435
+ return { password, credentialId: `temp:${persisted.id}`, expiresAt: persisted.expiresAt };
2436
+ }
2437
+ async verifyTempPassword(passwordArg) {
2438
+ this.assertInitialized();
2439
+ const controllerId = this.requireControllerId();
2440
+ if (typeof passwordArg !== 'string' || !tempPasswordPattern.test(passwordArg)) {
2441
+ return undefined;
2442
+ }
2443
+ const candidateHash = hashSetupCode(passwordArg);
2444
+ const now = Date.now();
2445
+ const stored = await ControllerTempPasswordModel.exact.findStored({
2446
+ filter: { controllerId },
2447
+ limit: maxActiveTempPasswords * 4,
2448
+ });
2449
+ for (const entry of stored) {
2450
+ const persisted = ControllerTempPasswordModel.exact.toPersisted(entry);
2451
+ if (persisted.expiresAt.getTime() <= now)
2452
+ continue;
2453
+ if (hashesEqual(persisted.secretHash, candidateHash)) {
2454
+ return { credentialId: `temp:${persisted.id}`, expiresAt: persisted.expiresAt };
2455
+ }
2456
+ }
2457
+ return undefined;
2458
+ }
2459
+ assertRuntimeConfigMatches(storedArg, requestedArg) {
2460
+ if (!runtimeConfigsEqual(storedArg, requestedArg)) {
2461
+ throw new AuthError('config_mismatch', 'The stored controller runtime configuration is immutable and does not match.');
2462
+ }
2463
+ }
2464
+ auditEventsEqual(leftArg, rightArg) {
2465
+ return leftArg.id === rightArg.id
2466
+ && leftArg.controllerId === rightArg.controllerId
2467
+ && leftArg.timestamp.getTime() === rightArg.timestamp.getTime()
2468
+ && leftArg.type === rightArg.type
2469
+ && leftArg.outcome === rightArg.outcome
2470
+ && leftArg.operationId === rightArg.operationId
2471
+ && leftArg.peerId === rightArg.peerId
2472
+ && leftArg.credentialId === rightArg.credentialId
2473
+ && (leftArg.sessionId === undefined
2474
+ ? rightArg.sessionId === undefined
2475
+ : rightArg.sessionId !== undefined
2476
+ && controllerRuntimeIdKey(leftArg.sessionId) === controllerRuntimeIdKey(rightArg.sessionId))
2477
+ && (leftArg.requestId === undefined
2478
+ ? rightArg.requestId === undefined
2479
+ : rightArg.requestId !== undefined
2480
+ && controllerRuntimeIdKey(leftArg.requestId) === controllerRuntimeIdKey(rightArg.requestId));
2481
+ }
2482
+ }
2483
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRoc3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jbGFzc2VzLmF1dGhzdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsU0FBUyxHQVlWLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2Qiw0QkFBNEIsRUFDNUIsMkJBQTJCLEVBQzNCLHVCQUF1QixFQUN2QiwyQkFBMkIsRUFDM0IseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQix3QkFBd0IsR0FDekIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2QixrQ0FBa0MsR0FVbkMsTUFBTSwwQkFBMEIsQ0FBQztBQVlsQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNuRSxPQUFPLEVBQ0wsbUNBQW1DLEdBQ3BDLE1BQU0sb0RBQW9ELENBQUM7QUFFNUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFZOUUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSx3RUFBd0U7QUFDeEUsNEVBQTRFO0FBQzVFLDRFQUE0RTtBQUM1RSxzRUFBc0U7QUFDdEUsaURBQWlEO0FBQ2pELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNqRCxNQUFNLHVCQUF1QixHQUFHLEtBQUssQ0FBQztBQUN0QyxNQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQztBQUNyQyxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUNq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