@bevel-software/platform-core-backend 0.20.0 → 0.22.0

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 (666) hide show
  1. package/dist/core/catalog-cache-invalidation.d.ts +7 -2
  2. package/dist/core/catalog-cache-invalidation.d.ts.map +1 -1
  3. package/dist/core/catalog-cache-invalidation.js +8 -9
  4. package/dist/core/catalog-cache-invalidation.js.map +1 -1
  5. package/dist/core/core-ports.d.ts +19 -0
  6. package/dist/core/core-ports.d.ts.map +1 -1
  7. package/dist/core/core-ports.js.map +1 -1
  8. package/dist/core/create-core-server.d.ts +2 -0
  9. package/dist/core/create-core-server.d.ts.map +1 -1
  10. package/dist/core/create-core-server.js +55 -107
  11. package/dist/core/create-core-server.js.map +1 -1
  12. package/dist/core/create-core-services.d.ts +41 -4
  13. package/dist/core/create-core-services.d.ts.map +1 -1
  14. package/dist/core/create-core-services.js +183 -82
  15. package/dist/core/create-core-services.js.map +1 -1
  16. package/dist/core/lifecycle.d.ts +74 -28
  17. package/dist/core/lifecycle.d.ts.map +1 -1
  18. package/dist/core/lifecycle.js +157 -20
  19. package/dist/core/lifecycle.js.map +1 -1
  20. package/dist/core/public-config.d.ts +5 -1
  21. package/dist/core/public-config.d.ts.map +1 -1
  22. package/dist/core/public-config.js +7 -5
  23. package/dist/core/public-config.js.map +1 -1
  24. package/dist/core-config.d.ts +95 -1
  25. package/dist/core-config.d.ts.map +1 -1
  26. package/dist/core-config.js +24 -8
  27. package/dist/core-config.js.map +1 -1
  28. package/dist/index.d.ts +5 -3
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/modules/access/access-control.service.d.ts +18 -1
  33. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  34. package/dist/modules/access/access-control.service.js +19 -8
  35. package/dist/modules/access/access-control.service.js.map +1 -1
  36. package/dist/modules/access/access-requests.contract.d.ts +75 -0
  37. package/dist/modules/access/access-requests.contract.d.ts.map +1 -0
  38. package/dist/modules/access/access-requests.contract.js +20 -0
  39. package/dist/modules/access/access-requests.contract.js.map +1 -0
  40. package/dist/modules/access/access-requests.routes.d.ts +35 -0
  41. package/dist/modules/access/access-requests.routes.d.ts.map +1 -0
  42. package/dist/modules/access/access-requests.routes.js +237 -0
  43. package/dist/modules/access/access-requests.routes.js.map +1 -0
  44. package/dist/modules/access/access-requests.service.d.ts +123 -0
  45. package/dist/modules/access/access-requests.service.d.ts.map +1 -0
  46. package/dist/modules/access/access-requests.service.js +337 -0
  47. package/dist/modules/access/access-requests.service.js.map +1 -0
  48. package/dist/modules/access/access.routes.d.ts +2 -1
  49. package/dist/modules/access/access.routes.d.ts.map +1 -1
  50. package/dist/modules/access/access.routes.js +10 -10
  51. package/dist/modules/access/access.routes.js.map +1 -1
  52. package/dist/modules/access/change-read-gate.d.ts +6 -3
  53. package/dist/modules/access/change-read-gate.d.ts.map +1 -1
  54. package/dist/modules/access/change-read-gate.js +9 -6
  55. package/dist/modules/access/change-read-gate.js.map +1 -1
  56. package/dist/modules/access/creator-access.d.ts +4 -2
  57. package/dist/modules/access/creator-access.d.ts.map +1 -1
  58. package/dist/modules/access/creator-access.js +7 -4
  59. package/dist/modules/access/creator-access.js.map +1 -1
  60. package/dist/modules/access-model/access-grammar.d.ts +12 -0
  61. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  62. package/dist/modules/access-model/access-grammar.js +24 -0
  63. package/dist/modules/access-model/access-grammar.js.map +1 -1
  64. package/dist/modules/agent-instructions/read-preamble.d.ts +2 -1
  65. package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
  66. package/dist/modules/agent-instructions/read-preamble.js +6 -9
  67. package/dist/modules/agent-instructions/read-preamble.js.map +1 -1
  68. package/dist/modules/auth/account-admission.d.ts +40 -0
  69. package/dist/modules/auth/account-admission.d.ts.map +1 -0
  70. package/dist/modules/auth/account-admission.js +17 -0
  71. package/dist/modules/auth/account-admission.js.map +1 -0
  72. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  73. package/dist/modules/auth/account.routes.js +4 -1
  74. package/dist/modules/auth/account.routes.js.map +1 -1
  75. package/dist/modules/auth/auth.service.d.ts +45 -2
  76. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  77. package/dist/modules/auth/auth.service.js +44 -3
  78. package/dist/modules/auth/auth.service.js.map +1 -1
  79. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  80. package/dist/modules/auth/oidc-auth-provider.js +9 -0
  81. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  82. package/dist/modules/connection-probe/connection-probe.service.d.ts +13 -1
  83. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  84. package/dist/modules/connection-probe/connection-probe.service.js +10 -2
  85. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  86. package/dist/modules/database/advisory-lock.d.ts +17 -0
  87. package/dist/modules/database/advisory-lock.d.ts.map +1 -1
  88. package/dist/modules/database/advisory-lock.js +24 -3
  89. package/dist/modules/database/advisory-lock.js.map +1 -1
  90. package/dist/modules/database/connection.d.ts +67 -2
  91. package/dist/modules/database/connection.d.ts.map +1 -1
  92. package/dist/modules/database/connection.js +118 -12
  93. package/dist/modules/database/connection.js.map +1 -1
  94. package/dist/modules/database/migrate.d.ts +1 -1
  95. package/dist/modules/database/migrate.d.ts.map +1 -1
  96. package/dist/modules/database/migrate.js +27 -3
  97. package/dist/modules/database/migrate.js.map +1 -1
  98. package/dist/modules/github-app/github-app.client.d.ts +101 -0
  99. package/dist/modules/github-app/github-app.client.d.ts.map +1 -0
  100. package/dist/modules/github-app/github-app.client.js +222 -0
  101. package/dist/modules/github-app/github-app.client.js.map +1 -0
  102. package/dist/modules/github-app/github-app.connection.d.ts +102 -0
  103. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -0
  104. package/dist/modules/github-app/github-app.connection.js +185 -0
  105. package/dist/modules/github-app/github-app.connection.js.map +1 -0
  106. package/dist/modules/github-app/github-app.routes.d.ts +59 -0
  107. package/dist/modules/github-app/github-app.routes.d.ts.map +1 -0
  108. package/dist/modules/github-app/github-app.routes.js +323 -0
  109. package/dist/modules/github-app/github-app.routes.js.map +1 -0
  110. package/dist/modules/github-app/index.d.ts +4 -0
  111. package/dist/modules/github-app/index.d.ts.map +1 -0
  112. package/dist/modules/github-app/index.js +4 -0
  113. package/dist/modules/github-app/index.js.map +1 -0
  114. package/dist/modules/kb-fs/branch-name.d.ts +0 -1
  115. package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
  116. package/dist/modules/kb-fs/branch-name.js +3 -3
  117. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  118. package/dist/modules/kb-fs/clone-config.d.ts +9 -8
  119. package/dist/modules/kb-fs/clone-config.d.ts.map +1 -1
  120. package/dist/modules/kb-fs/clone-config.js +14 -12
  121. package/dist/modules/kb-fs/clone-config.js.map +1 -1
  122. package/dist/modules/kb-fs/remote-url.d.ts +22 -0
  123. package/dist/modules/kb-fs/remote-url.d.ts.map +1 -0
  124. package/dist/modules/kb-fs/remote-url.js +35 -0
  125. package/dist/modules/kb-fs/remote-url.js.map +1 -0
  126. package/dist/modules/mcp/mcp.service.d.ts +7 -0
  127. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  128. package/dist/modules/mcp/mcp.service.js +4 -4
  129. package/dist/modules/mcp/mcp.service.js.map +1 -1
  130. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +4 -4
  131. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
  132. package/dist/modules/plugins/compile/marketplace-compiler.service.js +7 -10
  133. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -1
  134. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +4 -1
  135. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -1
  136. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +5 -3
  137. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -1
  138. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +6 -1
  139. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -1
  140. package/dist/modules/plugins/discovery/kb-plugin-source.js +14 -9
  141. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -1
  142. package/dist/modules/plugins/discovery/native.source.d.ts +4 -1
  143. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -1
  144. package/dist/modules/plugins/discovery/native.source.js +4 -2
  145. package/dist/modules/plugins/discovery/native.source.js.map +1 -1
  146. package/dist/modules/plugins/index.d.ts +1 -1
  147. package/dist/modules/plugins/index.d.ts.map +1 -1
  148. package/dist/modules/plugins/index.js +1 -1
  149. package/dist/modules/plugins/index.js.map +1 -1
  150. package/dist/modules/plugins/join-proposals.d.ts +17 -5
  151. package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
  152. package/dist/modules/plugins/join-proposals.js +76 -22
  153. package/dist/modules/plugins/join-proposals.js.map +1 -1
  154. package/dist/modules/plugins/join-request-jobs.service.d.ts +3 -1
  155. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  156. package/dist/modules/plugins/join-request-jobs.service.js +6 -6
  157. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  158. package/dist/modules/plugins/join-requests.service.d.ts +113 -18
  159. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  160. package/dist/modules/plugins/join-requests.service.js +178 -33
  161. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  162. package/dist/modules/plugins/plugin-links.d.ts +65 -10
  163. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  164. package/dist/modules/plugins/plugin-links.js +136 -31
  165. package/dist/modules/plugins/plugin-links.js.map +1 -1
  166. package/dist/modules/plugins/plugin-links.service.d.ts +107 -5
  167. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
  168. package/dist/modules/plugins/plugin-links.service.js +151 -21
  169. package/dist/modules/plugins/plugin-links.service.js.map +1 -1
  170. package/dist/modules/plugins/plugin-provision.service.d.ts +10 -3
  171. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  172. package/dist/modules/plugins/plugin-provision.service.js +33 -26
  173. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  174. package/dist/modules/plugins/plugin-rename.service.d.ts +4 -2
  175. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
  176. package/dist/modules/plugins/plugin-rename.service.js +10 -12
  177. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  178. package/dist/modules/plugins/plugins.routes.d.ts +3 -0
  179. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  180. package/dist/modules/plugins/plugins.routes.js +48 -17
  181. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  182. package/dist/modules/plugins/plugins.service.d.ts +4 -4
  183. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  184. package/dist/modules/plugins/plugins.service.js +7 -10
  185. package/dist/modules/plugins/plugins.service.js.map +1 -1
  186. package/dist/modules/plugins/teams.routes.d.ts +4 -1
  187. package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
  188. package/dist/modules/plugins/teams.routes.js +11 -9
  189. package/dist/modules/plugins/teams.routes.js.map +1 -1
  190. package/dist/modules/secrets-vault/index.d.ts +1 -1
  191. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  192. package/dist/modules/secrets-vault/index.js +1 -1
  193. package/dist/modules/secrets-vault/index.js.map +1 -1
  194. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +29 -11
  195. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
  196. package/dist/modules/secrets-vault/secrets-variable-loader.js +46 -21
  197. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
  198. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +3 -0
  199. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  200. package/dist/modules/secrets-vault/secrets-vault.routes.js +4 -6
  201. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  202. package/dist/modules/settings/deployment-settings.service.d.ts +34 -9
  203. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  204. package/dist/modules/settings/deployment-settings.service.js +113 -26
  205. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  206. package/dist/modules/settings/managed-repository.d.ts +43 -0
  207. package/dist/modules/settings/managed-repository.d.ts.map +1 -0
  208. package/dist/modules/settings/managed-repository.js +60 -0
  209. package/dist/modules/settings/managed-repository.js.map +1 -0
  210. package/dist/modules/settings/repository-source.d.ts +128 -0
  211. package/dist/modules/settings/repository-source.d.ts.map +1 -0
  212. package/dist/modules/settings/repository-source.js +150 -0
  213. package/dist/modules/settings/repository-source.js.map +1 -0
  214. package/dist/modules/settings/setup.routes.d.ts +34 -4
  215. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  216. package/dist/modules/settings/setup.routes.js +198 -18
  217. package/dist/modules/settings/setup.routes.js.map +1 -1
  218. package/dist/modules/skills/allowed-tools-check.d.ts +4 -3
  219. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
  220. package/dist/modules/skills/allowed-tools-check.js +8 -8
  221. package/dist/modules/skills/allowed-tools-check.js.map +1 -1
  222. package/dist/modules/skills/pending-skills.service.d.ts +3 -1
  223. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  224. package/dist/modules/skills/pending-skills.service.js +9 -6
  225. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  226. package/dist/modules/skills/skill-access-requests.routes.d.ts +8 -9
  227. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  228. package/dist/modules/skills/skill-access-requests.routes.js +26 -65
  229. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  230. package/dist/modules/skills/skills.routes.d.ts +4 -1
  231. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  232. package/dist/modules/skills/skills.routes.js +4 -4
  233. package/dist/modules/skills/skills.routes.js.map +1 -1
  234. package/dist/modules/skills/skills.service.d.ts +4 -2
  235. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  236. package/dist/modules/skills/skills.service.js +13 -11
  237. package/dist/modules/skills/skills.service.js.map +1 -1
  238. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  239. package/dist/modules/tool-helpers/tool-context.js +15 -0
  240. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  241. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +2 -1
  242. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  243. package/dist/modules/tool-manuals/mcp-json-discovery.js +6 -5
  244. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  245. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +4 -2
  246. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  247. package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -10
  248. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  249. package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -1
  250. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  251. package/dist/modules/tool-manuals/pending-tools.service.js +19 -16
  252. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
  253. package/dist/modules/tool-manuals/tool-delete.service.d.ts +4 -2
  254. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
  255. package/dist/modules/tool-manuals/tool-delete.service.js +14 -12
  256. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  257. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +3 -1
  258. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  259. package/dist/modules/tool-manuals/tool-manuals.routes.js +7 -7
  260. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  261. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -2
  262. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  263. package/dist/modules/tool-manuals/tool-manuals.service.js +15 -12
  264. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  265. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -0
  266. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  267. package/dist/modules/tool-manuals/tool-manuals.tools.js +4 -6
  268. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  269. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +3 -2
  270. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  271. package/dist/modules/workflow/agent-tools/workflow.tools.js +47 -11
  272. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  273. package/dist/modules/workflow/git/git.service.d.ts +14 -6
  274. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  275. package/dist/modules/workflow/git/git.service.js +40 -18
  276. package/dist/modules/workflow/git/git.service.js.map +1 -1
  277. package/dist/modules/workflow/git/node-git-runner.d.ts +26 -2
  278. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  279. package/dist/modules/workflow/git/node-git-runner.js +40 -5
  280. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  281. package/dist/modules/workflow/git/pull-request.service.d.ts +45 -0
  282. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  283. package/dist/modules/workflow/git/pull-request.service.js +99 -0
  284. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  285. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  286. package/dist/modules/workflow/review-workflow/review-workflow.service.js +9 -4
  287. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  288. package/dist/modules/workflow/session-ontology.service.d.ts +6 -1
  289. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -1
  290. package/dist/modules/workflow/session-ontology.service.js +6 -2
  291. package/dist/modules/workflow/session-ontology.service.js.map +1 -1
  292. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  293. package/dist/modules/workflow/workflow.routes.js +3 -1
  294. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  295. package/dist/modules/workflow/workflow.service.d.ts +42 -10
  296. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  297. package/dist/modules/workflow/workflow.service.js +181 -71
  298. package/dist/modules/workflow/workflow.service.js.map +1 -1
  299. package/dist/modules/workspace/session-ontology.gate.d.ts +3 -1
  300. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
  301. package/dist/modules/workspace/session-ontology.gate.js +3 -3
  302. package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
  303. package/dist/modules/workspace/startup/kb-git.d.ts +4 -3
  304. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  305. package/dist/modules/workspace/startup/kb-git.js +15 -13
  306. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  307. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +70 -7
  308. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  309. package/dist/modules/workspace/startup/kb-startup-runner.js +183 -38
  310. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  311. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +7 -1
  312. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
  313. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +23 -16
  314. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  315. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +7 -1
  316. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -1
  317. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +12 -5
  318. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
  319. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +7 -1
  320. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -1
  321. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +12 -5
  322. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -1
  323. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +7 -1
  324. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -1
  325. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +12 -5
  326. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -1
  327. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +4 -1
  328. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  329. package/dist/modules/workspace/startup/steps/seed-tree.js +14 -11
  330. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  331. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +17 -3
  332. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  333. package/dist/modules/workspace/startup/steps/template-files.step.js +36 -30
  334. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  335. package/dist/modules/workspace/startup/steps/template-source.d.ts +6 -1
  336. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  337. package/dist/modules/workspace/startup/steps/template-source.js +10 -6
  338. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  339. package/dist/modules/workspace/workspace.routes.d.ts +2 -1
  340. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  341. package/dist/modules/workspace/workspace.routes.js +8 -7
  342. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  343. package/dist/modules/workspace/workspace.service.d.ts +18 -12
  344. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  345. package/dist/modules/workspace/workspace.service.js +49 -29
  346. package/dist/modules/workspace/workspace.service.js.map +1 -1
  347. package/dist/modules/workspace/workspace.tools.d.ts +2 -1
  348. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  349. package/dist/modules/workspace/workspace.tools.js +48 -20
  350. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  351. package/dist/modules/workspace/write-denial.d.ts +3 -2
  352. package/dist/modules/workspace/write-denial.d.ts.map +1 -1
  353. package/dist/modules/workspace/write-denial.js +6 -5
  354. package/dist/modules/workspace/write-denial.js.map +1 -1
  355. package/dist/shared/domain-errors.d.ts +39 -0
  356. package/dist/shared/domain-errors.d.ts.map +1 -1
  357. package/dist/shared/domain-errors.js +55 -0
  358. package/dist/shared/domain-errors.js.map +1 -1
  359. package/dist/shared/git.contract.d.ts +62 -7
  360. package/dist/shared/git.contract.d.ts.map +1 -1
  361. package/dist/shared/git.contract.js +30 -8
  362. package/dist/shared/git.contract.js.map +1 -1
  363. package/dist/shared/kb-context.d.ts +76 -0
  364. package/dist/shared/kb-context.d.ts.map +1 -0
  365. package/dist/shared/kb-context.js +108 -0
  366. package/dist/shared/kb-context.js.map +1 -0
  367. package/dist/shared/kb-layout.d.ts +3 -2
  368. package/dist/shared/kb-layout.d.ts.map +1 -1
  369. package/dist/shared/kb-layout.js +4 -3
  370. package/dist/shared/kb-layout.js.map +1 -1
  371. package/dist/shared/kb-layout.test.js +35 -27
  372. package/dist/shared/kb-layout.test.js.map +1 -1
  373. package/dist/shared/pending-proposals.d.ts +4 -1
  374. package/dist/shared/pending-proposals.d.ts.map +1 -1
  375. package/dist/shared/pending-proposals.js +3 -4
  376. package/dist/shared/pending-proposals.js.map +1 -1
  377. package/dist/shared/redact-secret.d.ts +5 -5
  378. package/dist/shared/redact-secret.js +5 -5
  379. package/dist/tenancy/index.d.ts +13 -0
  380. package/dist/tenancy/index.d.ts.map +1 -0
  381. package/dist/tenancy/index.js +13 -0
  382. package/dist/tenancy/index.js.map +1 -0
  383. package/dist/tenancy/static-tenant-source.d.ts +98 -0
  384. package/dist/tenancy/static-tenant-source.d.ts.map +1 -0
  385. package/dist/tenancy/static-tenant-source.js +220 -0
  386. package/dist/tenancy/static-tenant-source.js.map +1 -0
  387. package/dist/tenancy/tenant-host.d.ts +80 -0
  388. package/dist/tenancy/tenant-host.d.ts.map +1 -0
  389. package/dist/tenancy/tenant-host.js +217 -0
  390. package/dist/tenancy/tenant-host.js.map +1 -0
  391. package/dist/tenancy/tenant-runtime.d.ts +91 -0
  392. package/dist/tenancy/tenant-runtime.d.ts.map +1 -0
  393. package/dist/tenancy/tenant-runtime.js +174 -0
  394. package/dist/tenancy/tenant-runtime.js.map +1 -0
  395. package/dist/tenancy/tenant-secrets.d.ts +24 -0
  396. package/dist/tenancy/tenant-secrets.d.ts.map +1 -0
  397. package/dist/tenancy/tenant-secrets.js +30 -0
  398. package/dist/tenancy/tenant-secrets.js.map +1 -0
  399. package/dist/tenancy/tenant-source.contract.d.ts +45 -0
  400. package/dist/tenancy/tenant-source.contract.d.ts.map +1 -0
  401. package/dist/tenancy/tenant-source.contract.js +21 -0
  402. package/dist/tenancy/tenant-source.contract.js.map +1 -0
  403. package/migrations/0000_core_init.sql +14 -14
  404. package/migrations/0003_deployment_settings.sql +1 -1
  405. package/migrations/0005_github_facade.sql +1 -1
  406. package/migrations/0012_agent_audit.sql +6 -6
  407. package/package.json +3 -3
  408. package/src/__tests__/branch-model.test.ts +7 -6
  409. package/src/__tests__/kb-context.ts +30 -0
  410. package/src/__tests__/kb-layout-config.test.ts +35 -30
  411. package/src/core/__tests__/catalog-cache-invalidation.test.ts +2 -1
  412. package/src/core/__tests__/lifecycle.test.ts +78 -1
  413. package/src/core/__tests__/public-config.test.ts +5 -1
  414. package/src/core/catalog-cache-invalidation.ts +16 -11
  415. package/src/core/core-ports.ts +19 -0
  416. package/src/core/create-core-server.ts +64 -107
  417. package/src/core/create-core-services.ts +238 -96
  418. package/src/core/lifecycle.ts +214 -29
  419. package/src/core/public-config.ts +8 -5
  420. package/src/core-config.ts +107 -8
  421. package/src/index.ts +25 -2
  422. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +2 -1
  423. package/src/modules/access/__tests__/access-requests.recut.test.ts +134 -0
  424. package/src/modules/access/__tests__/access-requests.routes.test.ts +610 -0
  425. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -1
  426. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -1
  427. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +2 -1
  428. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  429. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +2 -1
  430. package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -1
  431. package/src/modules/access/__tests__/access.routes.revoke.test.ts +2 -1
  432. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -1
  433. package/src/modules/access/__tests__/change-read-gate.test.ts +13 -11
  434. package/src/modules/access/__tests__/creator-access.test.ts +3 -2
  435. package/src/modules/access/__tests__/roles.routes.test.ts +2 -1
  436. package/src/modules/access/access-control.service.ts +20 -6
  437. package/src/modules/access/access-requests.contract.ts +93 -0
  438. package/src/modules/access/access-requests.routes.ts +286 -0
  439. package/src/modules/access/access-requests.service.ts +420 -0
  440. package/src/modules/access/access.routes.ts +10 -13
  441. package/src/modules/access/change-read-gate.ts +10 -4
  442. package/src/modules/access/creator-access.ts +7 -2
  443. package/src/modules/access-model/access-grammar.ts +22 -0
  444. package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +13 -12
  445. package/src/modules/agent-instructions/read-preamble.ts +10 -12
  446. package/src/modules/auth/__tests__/account.routes.test.ts +15 -0
  447. package/src/modules/auth/__tests__/auth.service.test.ts +98 -0
  448. package/src/modules/auth/account-admission.ts +44 -0
  449. package/src/modules/auth/account.routes.ts +4 -1
  450. package/src/modules/auth/auth.service.ts +61 -2
  451. package/src/modules/auth/oidc-auth-provider.ts +9 -0
  452. package/src/modules/connection-probe/connection-probe.service.ts +7 -1
  453. package/src/modules/database/__tests__/advisory-lock.test.ts +23 -1
  454. package/src/modules/database/__tests__/connection.test.ts +98 -0
  455. package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -0
  456. package/src/modules/database/advisory-lock.ts +28 -4
  457. package/src/modules/database/connection.ts +143 -13
  458. package/src/modules/database/migrate.ts +48 -14
  459. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
  460. package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
  461. package/src/modules/github-app/__tests__/github-app.test.ts +848 -0
  462. package/src/modules/github-app/github-app.client.ts +268 -0
  463. package/src/modules/github-app/github-app.connection.ts +204 -0
  464. package/src/modules/github-app/github-app.routes.ts +359 -0
  465. package/src/modules/github-app/index.ts +19 -0
  466. package/src/modules/kb-fs/__tests__/branch-name.test.ts +6 -6
  467. package/src/modules/kb-fs/__tests__/clone-config.test.ts +24 -20
  468. package/src/modules/kb-fs/__tests__/remote-url.test.ts +38 -0
  469. package/src/modules/kb-fs/branch-name.ts +3 -3
  470. package/src/modules/kb-fs/clone-config.ts +15 -12
  471. package/src/modules/kb-fs/remote-url.ts +35 -0
  472. package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +2 -1
  473. package/src/modules/mcp/mcp.service.ts +11 -4
  474. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +12 -11
  475. package/src/modules/plugins/__tests__/bundle-dialect.test.ts +2 -1
  476. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +6 -4
  477. package/src/modules/plugins/__tests__/join-proposals.test.ts +100 -19
  478. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +2 -1
  479. package/src/modules/plugins/__tests__/join-requests.service.test.ts +28 -11
  480. package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +371 -0
  481. package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +4 -3
  482. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +6 -4
  483. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +220 -5
  484. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +3 -1
  485. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +7 -6
  486. package/src/modules/plugins/__tests__/plugins.routes.test.ts +12 -3
  487. package/src/modules/plugins/__tests__/teams.routes.test.ts +2 -1
  488. package/src/modules/plugins/compile/marketplace-compiler.service.ts +7 -9
  489. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +20 -16
  490. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +9 -2
  491. package/src/modules/plugins/discovery/kb-plugin-source.ts +15 -8
  492. package/src/modules/plugins/discovery/native.source.ts +4 -1
  493. package/src/modules/plugins/index.ts +1 -1
  494. package/src/modules/plugins/join-proposals.ts +87 -19
  495. package/src/modules/plugins/join-request-jobs.service.ts +8 -7
  496. package/src/modules/plugins/join-requests.service.ts +203 -43
  497. package/src/modules/plugins/plugin-links.service.ts +192 -19
  498. package/src/modules/plugins/plugin-links.ts +147 -27
  499. package/src/modules/plugins/plugin-provision.service.ts +54 -27
  500. package/src/modules/plugins/plugin-rename.service.ts +10 -10
  501. package/src/modules/plugins/plugins.routes.ts +48 -17
  502. package/src/modules/plugins/plugins.service.ts +7 -11
  503. package/src/modules/plugins/teams.routes.ts +16 -8
  504. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +7 -0
  505. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +40 -0
  506. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +2 -0
  507. package/src/modules/secrets-vault/index.ts +2 -0
  508. package/src/modules/secrets-vault/secrets-variable-loader.ts +51 -21
  509. package/src/modules/secrets-vault/secrets-vault.routes.ts +7 -6
  510. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +24 -11
  511. package/src/modules/settings/__tests__/git-root-folders.test.ts +2 -1
  512. package/src/modules/settings/__tests__/repository-source.test.ts +191 -0
  513. package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +2 -1
  514. package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +353 -0
  515. package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +282 -0
  516. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +7 -4
  517. package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +233 -0
  518. package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +2 -0
  519. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +2 -0
  520. package/src/modules/settings/__tests__/setup.routes.test.ts +33 -52
  521. package/src/modules/settings/deployment-settings.service.ts +130 -23
  522. package/src/modules/settings/managed-repository.ts +68 -0
  523. package/src/modules/settings/repository-source.ts +197 -0
  524. package/src/modules/settings/setup.routes.ts +233 -19
  525. package/src/modules/skills/__tests__/allowed-tools-check.test.ts +11 -10
  526. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +4 -3
  527. package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -1
  528. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +7 -2
  529. package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +2 -1
  530. package/src/modules/skills/__tests__/skills.service.test.ts +3 -2
  531. package/src/modules/skills/allowed-tools-check.ts +7 -6
  532. package/src/modules/skills/pending-skills.service.ts +9 -8
  533. package/src/modules/skills/skill-access-requests.routes.ts +29 -79
  534. package/src/modules/skills/skills.routes.ts +4 -3
  535. package/src/modules/skills/skills.service.ts +13 -9
  536. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +3 -2
  537. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -2
  538. package/src/modules/tool-helpers/tool-context.ts +15 -0
  539. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +17 -12
  540. package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
  541. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +4 -1
  542. package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +2 -1
  543. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +2 -1
  544. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +5 -4
  545. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +2 -1
  546. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +4 -2
  547. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +13 -5
  548. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -1
  549. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +9 -1
  550. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +3 -2
  551. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +2 -0
  552. package/src/modules/tool-manuals/mcp-json-discovery.ts +6 -4
  553. package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -11
  554. package/src/modules/tool-manuals/pending-tools.service.ts +19 -16
  555. package/src/modules/tool-manuals/tool-delete.service.ts +13 -10
  556. package/src/modules/tool-manuals/tool-manuals.routes.ts +10 -8
  557. package/src/modules/tool-manuals/tool-manuals.service.ts +15 -13
  558. package/src/modules/tool-manuals/tool-manuals.tools.ts +7 -6
  559. package/src/modules/workflow/__tests__/apply-failure.test.ts +11 -2
  560. package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +14 -26
  561. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +2 -1
  562. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +3 -2
  563. package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +2 -1
  564. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +3 -10
  565. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +2 -1
  566. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +3 -10
  567. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +187 -35
  568. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +2 -1
  569. package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +2 -1
  570. package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +3 -2
  571. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +2 -1
  572. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +5 -4
  573. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +148 -41
  574. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +143 -2
  575. package/src/modules/workflow/agent-tools/workflow.tools.ts +60 -12
  576. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +5 -4
  577. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +12 -11
  578. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +9 -8
  579. package/src/modules/workflow/git/__tests__/git.service.commitFile.strayPath.test.ts +8 -7
  580. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +6 -5
  581. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +3 -2
  582. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +3 -2
  583. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +7 -6
  584. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +16 -15
  585. package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -2
  586. package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +2 -1
  587. package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +2 -1
  588. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +10 -9
  589. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +2 -1
  590. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +6 -5
  591. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +9 -8
  592. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +2 -1
  593. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +4 -3
  594. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +130 -8
  595. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +2 -1
  596. package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -1
  597. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +4 -3
  598. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +8 -7
  599. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +41 -3
  600. package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +145 -2
  601. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-delete.test.ts +166 -0
  602. package/src/modules/workflow/git/git.service.ts +49 -17
  603. package/src/modules/workflow/git/node-git-runner.ts +43 -4
  604. package/src/modules/workflow/git/pull-request.service.ts +119 -0
  605. package/src/modules/workflow/review-workflow/review-workflow.service.ts +9 -6
  606. package/src/modules/workflow/session-ontology.service.ts +7 -2
  607. package/src/modules/workflow/workflow.routes.ts +3 -1
  608. package/src/modules/workflow/workflow.service.ts +201 -76
  609. package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -2
  610. package/src/modules/workspace/__tests__/git-internals.security.test.ts +10 -9
  611. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +4 -2
  612. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
  613. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +2 -1
  614. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +2 -1
  615. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +2 -1
  616. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +2 -1
  617. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -1
  618. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +2 -1
  619. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +5 -4
  620. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +2 -1
  621. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +2 -1
  622. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
  623. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -5
  624. package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
  625. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
  626. package/src/modules/workspace/__tests__/workspace.service.test.ts +84 -50
  627. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +45 -1
  628. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -7
  629. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +237 -10
  630. package/src/modules/workspace/__tests__/workspace.tools.test.ts +44 -11
  631. package/src/modules/workspace/__tests__/write-denial.test.ts +5 -4
  632. package/src/modules/workspace/session-ontology.gate.ts +6 -4
  633. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +6 -2
  634. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +240 -21
  635. package/src/modules/workspace/startup/kb-git.ts +15 -22
  636. package/src/modules/workspace/startup/kb-startup-runner.ts +198 -45
  637. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +104 -98
  638. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +24 -16
  639. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +14 -5
  640. package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +13 -5
  641. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +14 -5
  642. package/src/modules/workspace/startup/steps/seed-tree.ts +11 -9
  643. package/src/modules/workspace/startup/steps/template-files.step.ts +43 -34
  644. package/src/modules/workspace/startup/steps/template-source.ts +8 -5
  645. package/src/modules/workspace/workspace.routes.ts +8 -7
  646. package/src/modules/workspace/workspace.service.ts +47 -28
  647. package/src/modules/workspace/workspace.tools.ts +56 -20
  648. package/src/modules/workspace/write-denial.ts +7 -5
  649. package/src/shared/__tests__/kb-layout.plugin.test.ts +19 -16
  650. package/src/shared/domain-errors.ts +58 -0
  651. package/src/shared/git.contract.ts +80 -8
  652. package/src/shared/kb-context.ts +130 -0
  653. package/src/shared/kb-layout.test.ts +37 -27
  654. package/src/shared/kb-layout.ts +4 -3
  655. package/src/shared/pending-proposals.ts +7 -4
  656. package/src/shared/redact-secret.ts +5 -5
  657. package/src/tenancy/__tests__/static-tenant-source.test.ts +177 -0
  658. package/src/tenancy/__tests__/tenant-host.test.ts +372 -0
  659. package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -0
  660. package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -0
  661. package/src/tenancy/index.ts +35 -0
  662. package/src/tenancy/static-tenant-source.ts +296 -0
  663. package/src/tenancy/tenant-host.ts +261 -0
  664. package/src/tenancy/tenant-runtime.ts +208 -0
  665. package/src/tenancy/tenant-secrets.ts +41 -0
  666. package/src/tenancy/tenant-source.contract.ts +59 -0
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type {
3
4
  AuthUser,
4
5
  ChangeInput,
@@ -13,9 +14,10 @@ import { FileLockService } from '../file-lock.service.js';
13
14
  import { PendingCommitsService } from '../pending-commits.service.js';
14
15
  import { WorkflowService } from '../workflow.service.js';
15
16
  import { PullRebaseConflictError, WorkflowDomainError } from '../../../shared/domain-errors.js';
16
- import { DEFAULT_BRANCH, isProtectedBranch } from '@bevel-software/platform-shared';
17
+ import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
17
18
  import type { Database } from '../../database/connection.js';
18
19
  import { openChangeGate } from '../../../__tests__/open-change-gate.js';
20
+ import { hashEmail } from '../../../shared/email-identity.js';
19
21
 
20
22
  // `deleteBranch`'s open-request guard is the only DB touch these tests
21
23
  // exercise. The stub ANSWERS FROM THE WHERE-CLAUSE rather than returning the
@@ -238,7 +240,7 @@ describe('WorkflowService — branch delegation', () => {
238
240
  const branches = [{ name: 'main', isCurrent: true, isProtected: true, ahead: 0, behind: 0, hasRemote: true }];
239
241
  (git.listBranches as ReturnType<typeof vi.fn>).mockResolvedValue(branches);
240
242
 
241
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
243
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
242
244
  await expect(svc.listBranches('w1')).resolves.toBe(branches);
243
245
  // listBranches(workspaceId, opts?) forwards opts — undefined when omitted.
244
246
  expect(git.listBranches).toHaveBeenCalledWith('w1', undefined);
@@ -248,7 +250,7 @@ describe('WorkflowService — branch delegation', () => {
248
250
  const git = makeGit();
249
251
  (git.createBranch as ReturnType<typeof vi.fn>).mockResolvedValue({ name: 'feat' });
250
252
 
251
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
253
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
252
254
  await svc.createBranch('w1', 'feat', 'current-company-state');
253
255
  expect(git.createBranch).toHaveBeenCalledWith('w1', 'feat', 'current-company-state');
254
256
  });
@@ -258,7 +260,7 @@ describe('WorkflowService — branch delegation', () => {
258
260
  const status = { branch: 'main', isDirty: false, hasUpstream: true, unpushedCommits: 0, conflicted: [], unmergedFromUpstream: false };
259
261
  (git.status as ReturnType<typeof vi.fn>).mockResolvedValue(status);
260
262
 
261
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
263
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
262
264
  await expect(svc.branchStatus('w1')).resolves.toBe(status);
263
265
  expect(git.status).toHaveBeenCalledWith('w1');
264
266
  });
@@ -272,7 +274,7 @@ describe('WorkflowService — change delegation', () => {
272
274
  const commit = { sha: 'abc', authorName: 'Alice', authorEmail: 'alice@example.com', subject: 'tweak owner', committedAt: '2026-01-01T00:00:00Z' };
273
275
  (git.commit as ReturnType<typeof vi.fn>).mockResolvedValue(commit);
274
276
 
275
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
277
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
276
278
  await expect(svc.commitChange('w1', user, input)).resolves.toBe(commit);
277
279
  expect(git.commit).toHaveBeenCalledWith('w1', user, input);
278
280
  });
@@ -281,7 +283,7 @@ describe('WorkflowService — change delegation', () => {
281
283
  const git = makeGit();
282
284
  (git.logForFile as ReturnType<typeof vi.fn>).mockResolvedValue([]);
283
285
 
284
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
286
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
285
287
  await svc.listChangesForFile('w1', 'Knowledge/Foo.md', 5);
286
288
  expect(git.logForFile).toHaveBeenCalledWith('w1', 'Knowledge/Foo.md', 5);
287
289
  });
@@ -290,7 +292,7 @@ describe('WorkflowService — change delegation', () => {
290
292
  const git = makeGit();
291
293
  (git.diffFileBetweenBranches as ReturnType<typeof vi.fn>).mockResolvedValue('@@ diff');
292
294
 
293
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
295
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
294
296
  const diff = await svc.compareFile('w1', 'Foo.md', 'a', 'b');
295
297
  expect(diff).toBe('@@ diff');
296
298
  expect(git.diffFileBetweenBranches).toHaveBeenCalledWith('w1', 'Foo.md', 'a', 'b');
@@ -302,7 +304,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
302
304
  const prs = makePrs();
303
305
  (prs.listOpenPrs as ReturnType<typeof vi.fn>).mockResolvedValue([]);
304
306
 
305
- const svc = new WorkflowService(makeDb(), makeGit(), prs, makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
307
+ const svc = new WorkflowService(makeDb(), makeGit(), prs, makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
306
308
  await svc.listChangeRequests({ fresh: true });
307
309
  expect(prs.listOpenPrs).toHaveBeenCalledWith({ fresh: true });
308
310
  });
@@ -314,7 +316,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
314
316
  const input: PostChangeRequestCommentInput = { body: 'hi' };
315
317
  (reviewWorkflow.postComment as ReturnType<typeof vi.fn>).mockResolvedValue(comment);
316
318
 
317
- const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
319
+ const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
318
320
  const user = makeUser();
319
321
  await expect(svc.postComment(42, user, input, 'sha1')).resolves.toBe(comment);
320
322
  expect(reviewWorkflow.postComment).toHaveBeenCalledWith(42, user, input, 'sha1');
@@ -327,7 +329,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
327
329
  const reviewWorkflow = makeReviewWorkflow();
328
330
  (reviewWorkflow.approveFile as ReturnType<typeof vi.fn>).mockResolvedValue([]);
329
331
 
330
- const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
332
+ const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
331
333
  await svc.approveFile(7, 'Foo.md', makeUser(), [], 'sha', 'main', null, 'w1');
332
334
  expect(prs.invalidateDetailCache).toHaveBeenCalledWith(7);
333
335
  expect(prs.invalidateDetailCache).toHaveBeenCalledTimes(1);
@@ -338,7 +340,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
338
340
  const reviewWorkflow = makeReviewWorkflow();
339
341
  (reviewWorkflow.cancelPr as ReturnType<typeof vi.fn>).mockResolvedValue({ prNumber: 9, cancelledAt: 't' });
340
342
 
341
- const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
343
+ const svc = new WorkflowService(makeDb(), makeGit(), prs, reviewWorkflow, makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
342
344
  const user = makeUser();
343
345
  await svc.rejectChangeRequest(9, user, 'open', null, 'main', 'w1');
344
346
  expect(reviewWorkflow.cancelPr).toHaveBeenCalledWith(9, user, 'open', null, 'main', 'w1');
@@ -357,7 +359,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
357
359
 
358
360
  const git = makeGit();
359
361
  const workspaceService = makeWorkspaceService();
360
- const svc = new WorkflowService(makeDb(), git, prs, reviewWorkflow, workspaceService, makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
362
+ const svc = new WorkflowService(makeDb(), git, prs, reviewWorkflow, workspaceService, makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
361
363
  // Conflicts are surfaced by the local merge inside `reviewWorkflow.mergePr`
362
364
  // (mocked here), so there's no provider "mergeable" pre-check to stub.
363
365
  const outcome = await svc.mergeChangeRequest(
@@ -374,7 +376,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
374
376
  expect(outcome).toEqual({ kind: 'merged', result: mergeResult });
375
377
  // The target branch's workspace is pulled so it doesn't fall behind origin.
376
378
  expect(workspaceService.getOrCreateForBranch).toHaveBeenCalledWith('main');
377
- expect(git.pull).toHaveBeenCalledWith('main');
379
+ expect(git.pull).toHaveBeenCalledWith('main', {});
378
380
  expect(reviewWorkflow.mergePr).toHaveBeenCalledWith(
379
381
  4,
380
382
  expect.objectContaining({ email: 'alice@example.com' }),
@@ -412,7 +414,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
412
414
  id: 'resolved-target-ws',
413
415
  });
414
416
  const pending = makePendingCommits();
415
- const svc = new WorkflowService(makeDb(), git, prs, reviewWorkflow, workspaceService, makeAccessControl(), makeFileLockService(), pending, 'knowledge-base', openChangeGate());
417
+ const svc = new WorkflowService(makeDb(), git, prs, reviewWorkflow, workspaceService, makeAccessControl(), makeFileLockService(), pending, testKbContext(), openChangeGate());
416
418
 
417
419
  const outcome = await svc.mergeChangeRequest(
418
420
  4, makeUser(), 'sha', [], 'open', 'PR title', 'main', 'w1', { bypass: true },
@@ -435,7 +437,7 @@ describe('WorkflowService — change request delegation + cache invalidation', (
435
437
  describe('WorkflowService — file lock delegation', () => {
436
438
  it('acquireLock delegates to FileLockService.acquire', async () => {
437
439
  const fileLocks = makeFileLockService();
438
- const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), 'knowledge-base', openChangeGate());
440
+ const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
439
441
  await svc.acquireLock('w1', 'b', 'p', makeUser());
440
442
  expect(fileLocks.acquire).toHaveBeenCalledWith('w1', 'b', 'p', expect.objectContaining({ email: 'alice@example.com' }), undefined);
441
443
  });
@@ -445,7 +447,7 @@ describe('WorkflowService — file lock delegation', () => {
445
447
  // a coordination hold masquerade as an edit lock on the very next read
446
448
  // (which is how the write paths decide what the holder may do).
447
449
  const fileLocks = makeFileLockService();
448
- const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), 'knowledge-base', openChangeGate());
450
+ const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
449
451
  await svc.acquireLock('w1', 'b', 'p', makeUser(), { coordination: true });
450
452
  expect(fileLocks.acquire).toHaveBeenCalledWith(
451
453
  'w1', 'b', 'p', expect.objectContaining({ email: 'alice@example.com' }), { coordination: true },
@@ -454,7 +456,7 @@ describe('WorkflowService — file lock delegation', () => {
454
456
 
455
457
  it('getLock delegates to FileLockService.get', async () => {
456
458
  const fileLocks = makeFileLockService();
457
- const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), 'knowledge-base', openChangeGate());
459
+ const svc = new WorkflowService(makeDb(), makeGit(), makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
458
460
  await expect(svc.getLock('w1', 'b', 'p')).resolves.toBeNull();
459
461
  expect(fileLocks.get).toHaveBeenCalledWith('w1', 'b', 'p');
460
462
  });
@@ -469,7 +471,7 @@ describe('WorkflowService — file lock delegation', () => {
469
471
  acquiredAt: '', lastHeartbeatAt: '', expiresAt: '',
470
472
  });
471
473
  const pending = makePendingCommits();
472
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, pending, 'knowledge-base', openChangeGate());
474
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, pending, testKbContext(), openChangeGate());
473
475
  await expect(svc.releaseLock('w1', 'feat', 'Foo.md', makeUser())).resolves.toBeUndefined();
474
476
  // No inline git work — the worker handles that out of band.
475
477
  expect(git.commitFile).not.toHaveBeenCalled();
@@ -488,28 +490,28 @@ describe('WorkflowService — file lock delegation', () => {
488
490
  // One open request rides the branch — deleting it would strand the request.
489
491
  // `sourceBranch` matters to the guard now: it decides whether the refusal
490
492
  // says "withdraw yours" (source) or names the other request's actors (target).
491
- const svc = new WorkflowService(makeDb([{ number: 7, sourceBranch: 'feat/x', targetBranch: 'dev', state: 'open' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
493
+ const svc = new WorkflowService(makeDb([{ number: 7, sourceBranch: 'feat/x', targetBranch: 'dev', state: 'open' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
492
494
  await expect(svc.deleteBranch('w1', 'feat/x', makeUser())).rejects.toThrow(/open change request \(#7\)/);
493
495
  expect(git.deleteBranch).not.toHaveBeenCalled();
494
496
  });
495
497
 
496
498
  it('deleteBranch refuses when an open request proposes INTO the branch (target end)', async () => {
497
499
  const git = makeGit();
498
- const svc = new WorkflowService(makeDb([{ number: 9, sourceBranch: 'other/y', targetBranch: 'feat/x', state: 'open' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
500
+ const svc = new WorkflowService(makeDb([{ number: 9, sourceBranch: 'other/y', targetBranch: 'feat/x', state: 'open' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
499
501
  await expect(svc.deleteBranch('w1', 'feat/x', makeUser())).rejects.toThrow(/proposes changes into/);
500
502
  expect(git.deleteBranch).not.toHaveBeenCalled();
501
503
  });
502
504
 
503
505
  it('deleteBranch proceeds past a CLOSED request — the guard filters on state, not mere mention', async () => {
504
506
  const git = makeGit();
505
- const svc = new WorkflowService(makeDb([{ number: 7, sourceBranch: 'feat/x', targetBranch: 'dev', state: 'closed' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
507
+ const svc = new WorkflowService(makeDb([{ number: 7, sourceBranch: 'feat/x', targetBranch: 'dev', state: 'closed' }]), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
506
508
  await expect(svc.deleteBranch('w1', 'feat/x', makeUser())).resolves.toBeUndefined();
507
509
  expect(git.deleteBranch).toHaveBeenCalled();
508
510
  });
509
511
 
510
512
  it('deleteBranch deletes when the branch has no open change request', async () => {
511
513
  const git = makeGit();
512
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
514
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
513
515
  await expect(svc.deleteBranch('w1', 'feat/x', makeUser())).resolves.toBeUndefined();
514
516
  expect(git.deleteBranch).toHaveBeenCalledWith('w1', 'feat/x', expect.objectContaining({ email: 'alice@example.com' }), undefined);
515
517
  });
@@ -529,7 +531,7 @@ describe('WorkflowService — file lock delegation', () => {
529
531
  vi.mocked(git.deleteBranch)
530
532
  .mockImplementationOnce(async () => { order.push('first:start'); await gate; order.push('first:end'); })
531
533
  .mockImplementationOnce(async () => { order.push('second'); });
532
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
534
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
533
535
  const first = svc.deleteBranch('w1', 'feat/x', makeUser());
534
536
  const second = svc.deleteBranch('w1', 'feat/x', makeUser());
535
537
  // Only release the gate once the first operation is provably inside its
@@ -544,7 +546,7 @@ describe('WorkflowService — file lock delegation', () => {
544
546
  it('releaseLock refuses when the caller does not hold the lock', async () => {
545
547
  const git = makeGit();
546
548
  const fileLocks = makeFileLockService(); // default: get → null
547
- const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), 'knowledge-base', openChangeGate());
549
+ const svc = new WorkflowService(makeDb(), git, makePrs(), makeReviewWorkflow(), makeWorkspaceService(), makeAccessControl(), fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
548
550
  await expect(svc.releaseLock('w1', 'feat', 'Foo.md', makeUser())).rejects.toThrow(/not held by you/);
549
551
  // The commit must NOT run when the caller doesn't hold the lock —
550
552
  // otherwise a non-holder could trigger a commit attributed as them.
@@ -605,7 +607,7 @@ describe('WorkflowService — revertChangeRequestFile / closeEmptyChangeRequest'
605
607
  returning: vi.fn(async () => updateRows),
606
608
  });
607
609
  const db = chain as unknown as Database;
608
- const svc = new WorkflowService(db, git, prs, makeReviewWorkflow(), makeWorkspaceService(), access, fileLocks, makePendingCommits(), 'knowledge-base', openChangeGate());
610
+ const svc = new WorkflowService(db, git, prs, makeReviewWorkflow(), makeWorkspaceService(), access, fileLocks, makePendingCommits(), testKbContext(), openChangeGate());
609
611
  return { svc, git, prs, access, fileLocks, db: chain };
610
612
  }
611
613
 
@@ -783,8 +785,13 @@ describe('WorkflowService — revertChangeRequestFile / closeEmptyChangeRequest'
783
785
  });
784
786
  });
785
787
 
786
- describe('WorkflowService — deleteChangeRequest (admin moderation verb)', () => {
787
- function makeDeleteHarness(opts: { isAdmin?: boolean; prState?: string } = {}) {
788
+ describe('WorkflowService — deleteChangeRequest (the author’s and the admin’s verb)', () => {
789
+ const AUTHOR_EMAIL = 'alice@example.com'; // makeUser()'s default caller
790
+ const STRANGER_AUTHOR = 'mallory@example.com';
791
+
792
+ function makeDeleteHarness(
793
+ opts: { isAdmin?: boolean; prState?: string; authorEmail?: string | null } = {},
794
+ ) {
788
795
  const git = Object.assign(makeGit(), {
789
796
  changedPathsForPr: vi.fn().mockResolvedValue(['Docs/a.md']),
790
797
  }) as unknown as GitService;
@@ -794,26 +801,83 @@ describe('WorkflowService — deleteChangeRequest (admin moderation verb)', () =
794
801
  base: 'main',
795
802
  branch: 'mallory/spam',
796
803
  state: opts.prState ?? 'open',
804
+ // Authorship as the server reads it: the stored hash, never the caller's
805
+ // claim. Defaults to someone OTHER than makeUser(), so a test that says
806
+ // nothing about authorship is testing the admin grant alone.
807
+ // `null` means a request with no stored author (opened outside this
808
+ // backend); undefined means "someone, just not the caller".
809
+ authorId:
810
+ opts.authorEmail === null ? undefined : hashEmail(opts.authorEmail ?? STRANGER_AUTHOR),
797
811
  });
798
812
  const access = makeAccessControl();
799
813
  (access.canWriteAtRef as ReturnType<typeof vi.fn>).mockResolvedValue(opts.isAdmin ?? false);
800
814
  const chain: Record<string, unknown> = {};
815
+ // Two different selects run under one chain mock: the branch-retirement
816
+ // lookup asks for `{ sourceBranch }`, and `openChangeRequestOn` asks for
817
+ // `{ number, sourceBranch }`. Answer by projection rather than call order,
818
+ // so the retirement path is exercised (a branch to retire, and no other
819
+ // open request holding it) without the test depending on call sequence.
820
+ let projection: Record<string, unknown> = {};
801
821
  Object.assign(chain, {
802
- select: vi.fn(() => chain),
822
+ select: vi.fn((proj?: Record<string, unknown>) => {
823
+ projection = proj ?? {};
824
+ return chain;
825
+ }),
803
826
  from: vi.fn(() => chain),
804
827
  where: vi.fn(() => chain),
805
- limit: vi.fn(async () => []),
828
+ limit: vi.fn(async () =>
829
+ 'number' in projection ? [] : [{ sourceBranch: 'mallory/spam' }],
830
+ ),
806
831
  update: vi.fn(() => chain),
807
832
  set: vi.fn(() => chain),
808
833
  returning: vi.fn(async () => [{ id: 1 }]),
809
834
  });
810
835
  const workspaces = makeWorkspaceService();
811
- const svc = new WorkflowService(chain as unknown as Database, git, prs, makeReviewWorkflow(), workspaces, access, makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
812
- return { svc, prs, db: chain, access, workspaces };
836
+ const svc = new WorkflowService(chain as unknown as Database, git, prs, makeReviewWorkflow(), workspaces, access, makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
837
+ return { svc, prs, db: chain, access, workspaces, git };
813
838
  }
814
839
 
815
- it('refuses a non-admin with 403 and touches nothing', async () => {
816
- const { svc, db } = makeDeleteHarness({ isAdmin: false });
840
+ it('refuses a non-admin who is not the author, with 403 and the author-or-admin message', async () => {
841
+ const { svc, db, git } = makeDeleteHarness({ isAdmin: false });
842
+ await expect(svc.deleteChangeRequest(9, makeUser())).rejects.toMatchObject({
843
+ status: 403,
844
+ message: "Only the request's author or an admin can delete it.",
845
+ });
846
+ // "Changes nothing" is the whole promise of the refusal: no row flipped,
847
+ // no branch removed.
848
+ expect(db.update).not.toHaveBeenCalled();
849
+ expect(git.deleteBranch).not.toHaveBeenCalled();
850
+ });
851
+
852
+ it('lets the AUTHOR delete their own request without admin rights: closes it and retires the branch', async () => {
853
+ const { svc, prs, db, git } = makeDeleteHarness({
854
+ isAdmin: false,
855
+ authorEmail: AUTHOR_EMAIL,
856
+ });
857
+ await svc.deleteChangeRequest(9, makeUser());
858
+ expect(db.update).toHaveBeenCalled();
859
+ expect(prs.invalidateDetailCache).toHaveBeenCalledWith(9);
860
+ expect(git.deleteBranch).toHaveBeenCalledWith(
861
+ expect.any(String),
862
+ 'mallory/spam',
863
+ expect.objectContaining({ email: AUTHOR_EMAIL }),
864
+ expect.objectContaining({ systemCleanup: true }),
865
+ );
866
+ });
867
+
868
+ it('matches the author case-insensitively, as hashEmail does', async () => {
869
+ // The stored hash is of the normalized address; a caller signed in as
870
+ // `Alice@Example.com` is the same person and must not be refused.
871
+ const { svc, db } = makeDeleteHarness({ isAdmin: false, authorEmail: AUTHOR_EMAIL });
872
+ await svc.deleteChangeRequest(9, makeUser({ email: ' Alice@Example.com ' }));
873
+ expect(db.update).toHaveBeenCalled();
874
+ });
875
+
876
+ it('refuses a request with no stored author to a non-admin', async () => {
877
+ // Opened outside this backend: nobody can claim authorship of it, so the
878
+ // admin grant is the only one left. An absent hash must never read as a
879
+ // match.
880
+ const { svc, db } = makeDeleteHarness({ isAdmin: false, authorEmail: null });
817
881
  await expect(svc.deleteChangeRequest(9, makeUser())).rejects.toMatchObject({ status: 403 });
818
882
  expect(db.update).not.toHaveBeenCalled();
819
883
  });
@@ -831,6 +895,94 @@ describe('WorkflowService — deleteChangeRequest (admin moderation verb)', () =
831
895
  expect(db.update).not.toHaveBeenCalled();
832
896
  });
833
897
 
898
+ it('refuses the AUTHOR on an applied request with 422 and the applied message', async () => {
899
+ // Applied between opening the dialog and confirming. The author's new
900
+ // grant does not reach applied history either.
901
+ const { svc, db, git } = makeDeleteHarness({
902
+ isAdmin: false,
903
+ prState: 'merged',
904
+ authorEmail: AUTHOR_EMAIL,
905
+ });
906
+ await expect(svc.deleteChangeRequest(9, makeUser())).rejects.toMatchObject({
907
+ status: 422,
908
+ message: 'This change request has already been applied.',
909
+ });
910
+ expect(db.update).not.toHaveBeenCalled();
911
+ expect(git.deleteBranch).not.toHaveBeenCalled();
912
+ });
913
+
914
+ it('refuses the AUTHOR with 409 when the base cannot be verified, and changes nothing', async () => {
915
+ // The strict base fetch is NOT skipped for an author, even though their
916
+ // grant needs no roles.yaml read: an unreachable origin means the branch
917
+ // removal would fail silently, and the delete must refuse whole rather
918
+ // than close the request and leave the branch.
919
+ const { svc, db, git, workspaces } = makeDeleteHarness({
920
+ isAdmin: false,
921
+ authorEmail: AUTHOR_EMAIL,
922
+ });
923
+ (workspaces.ensureRemotesFetched as ReturnType<typeof vi.fn>).mockRejectedValue(
924
+ new Error('origin unreachable'),
925
+ );
926
+ await expect(svc.deleteChangeRequest(9, makeUser())).rejects.toMatchObject({
927
+ status: 409,
928
+ message: expect.stringContaining('Retry in a moment.'),
929
+ });
930
+ expect(db.update).not.toHaveBeenCalled();
931
+ expect(git.deleteBranch).not.toHaveBeenCalled();
932
+ });
933
+
934
+ it('refuses the AUTHOR with 409 when the base ref does not resolve', async () => {
935
+ const { svc, db, access } = makeDeleteHarness({
936
+ isAdmin: false,
937
+ authorEmail: AUTHOR_EMAIL,
938
+ });
939
+ (access.canWriteAtRef as ReturnType<typeof vi.fn>).mockResolvedValue(null);
940
+ await expect(svc.deleteChangeRequest(9, makeUser())).rejects.toMatchObject({ status: 409 });
941
+ expect(db.update).not.toHaveBeenCalled();
942
+ });
943
+
944
+ it('a request already closed elsewhere still has its branch retired', async () => {
945
+ // Withdrawn in another tab: the guarded update flips no row, the request
946
+ // is not merged, so the delete finishes the job the withdraw left undone.
947
+ const { svc, db, git } = makeDeleteHarness({
948
+ isAdmin: false,
949
+ prState: 'closed',
950
+ authorEmail: AUTHOR_EMAIL,
951
+ });
952
+ // The update is guarded on `state = 'open'`, so it flips nothing here.
953
+ (db.returning as ReturnType<typeof vi.fn>).mockResolvedValue([]);
954
+ await expect(svc.deleteChangeRequest(9, makeUser())).resolves.toBeUndefined();
955
+ expect(git.deleteBranch).toHaveBeenCalledWith(
956
+ expect.any(String),
957
+ 'mallory/spam',
958
+ expect.anything(),
959
+ expect.objectContaining({ systemCleanup: true }),
960
+ );
961
+ });
962
+
963
+ it('keeps a branch another open request still uses, and closes the request silently', async () => {
964
+ const { svc, db, git } = makeDeleteHarness({
965
+ isAdmin: false,
966
+ authorEmail: AUTHOR_EMAIL,
967
+ });
968
+ // `openChangeRequestOn` finds a live request on the branch (the
969
+ // `{ number, sourceBranch }` projection), so retirement backs off.
970
+ let projection: Record<string, unknown> = {};
971
+ (db.select as ReturnType<typeof vi.fn>).mockImplementation((proj?: Record<string, unknown>) => {
972
+ projection = proj ?? {};
973
+ return db;
974
+ });
975
+ (db.limit as ReturnType<typeof vi.fn>).mockImplementation(async () =>
976
+ 'number' in projection
977
+ ? [{ number: 11, sourceBranch: 'mallory/spam' }]
978
+ : [{ sourceBranch: 'mallory/spam' }],
979
+ );
980
+ // No throw, no message: the request closes and the branch survives.
981
+ await expect(svc.deleteChangeRequest(9, makeUser())).resolves.toBeUndefined();
982
+ expect(db.update).toHaveBeenCalled();
983
+ expect(git.deleteBranch).not.toHaveBeenCalled();
984
+ });
985
+
834
986
  it('kicks the deleted-branch sweep when the base workspace cannot be resolved', async () => {
835
987
  const { svc, db, workspaces } = makeDeleteHarness({ isAdmin: true });
836
988
  (workspaces.getOrCreateForBranch as ReturnType<typeof vi.fn>).mockRejectedValue(
@@ -916,7 +1068,7 @@ describe('WorkflowService.mergeBranch — an agent merges branches, never an ope
916
1068
  const access = makeAccessControl();
917
1069
  (access.canWriteBatchAtRef as ReturnType<typeof vi.fn>).mockResolvedValue(opts.canWrite === undefined ? null : opts.canWrite);
918
1070
  const workspaceService = makeWorkspaceService();
919
- const svc = new WorkflowService(makeDb([OPEN_REQUEST]), git, makePrs(), makeReviewWorkflow(), workspaceService, access, makeFileLockService(), makePendingCommits(), 'knowledge-base', openChangeGate());
1071
+ const svc = new WorkflowService(makeDb([OPEN_REQUEST]), git, makePrs(), makeReviewWorkflow(), workspaceService, access, makeFileLockService(), makePendingCommits(), testKbContext(), openChangeGate());
920
1072
  const merge = (git as unknown as { mergeChangeRequest: ReturnType<typeof vi.fn> }).mergeChangeRequest;
921
1073
  return { svc, git, access, merge };
922
1074
  }
@@ -956,7 +1108,7 @@ describe('WorkflowService.mergeBranch — an agent merges branches, never an ope
956
1108
  });
957
1109
 
958
1110
  it('refuses a protected target when the caller could not commit the changed files directly', async () => {
959
- expect(isProtectedBranch(PROTECTED)).toBe(true);
1111
+ expect(testKbContext().isProtectedBranch(PROTECTED)).toBe(true);
960
1112
  const { svc, git, access, merge } = harness({ canWrite: new Map([['Team/Process.md', false]]) });
961
1113
  const err = await svc.mergeBranch(makeUser(), 'alice/other', PROTECTED).catch((e: unknown) => e);
962
1114
  expect(err).toMatchObject({ status: 403, payload: { kind: 'protected-merge-target', deniedPaths: ['Team/Process.md'] } });
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type { AuthUser, PullRequestSummary } from '@bevel-software/platform-shared';
3
4
  import type { GitService } from '../git/git.service.js';
4
5
  import type { PullRequestService } from '../git/pull-request.service.js';
@@ -138,7 +139,7 @@ function makeHarness(requests: PullRequestSummary[], access: Access = {}) {
138
139
  accessControl,
139
140
  fileLocks,
140
141
  pendingCommits,
141
- 'knowledge-base',
142
+ testKbContext(),
142
143
  openChangeGate(),
143
144
  );
144
145
  // Which request an UPDATE is closing is not recoverable from the drizzle
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type { AuthUser } from '@bevel-software/platform-shared';
3
4
  import type { GitService } from '../git/git.service.js';
4
5
  import type { PullRequestService } from '../git/pull-request.service.js';
@@ -53,7 +54,7 @@ function makeService(canRestorePlatformFile: IAccessControl['canRestorePlatformF
53
54
  accessControl,
54
55
  { acquire, get: vi.fn(async () => null) } as unknown as FileLockService,
55
56
  {} as PendingCommitsService,
56
- KB,
57
+ testKbContext({ kbDirName: KB }),
57
58
  openChangeGate(),
58
59
  new WorkflowEventBus(),
59
60
  );
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type { AuthUser } from '@bevel-software/platform-shared';
3
4
  import type { GitService } from '../git/git.service.js';
4
5
  import type { PullRequestService } from '../git/pull-request.service.js';
@@ -61,7 +62,7 @@ function makeService(opts: {
61
62
  accessControl,
62
63
  { acquire, get: vi.fn(async () => null) } as unknown as FileLockService,
63
64
  {} as PendingCommitsService,
64
- KB,
65
+ testKbContext({ kbDirName: KB }),
65
66
  opts.gate ?? gateThat({ allowed: true, via: 'readable' }).gate,
66
67
  new WorkflowEventBus(),
67
68
  );
@@ -81,7 +82,7 @@ describe('WorkflowService cannot exist without the gate', () => {
81
82
  {} as IAccessControl,
82
83
  {} as FileLockService,
83
84
  {} as PendingCommitsService,
84
- KB,
85
+ testKbContext({ kbDirName: KB }),
85
86
  undefined as unknown as IChangeReadGate,
86
87
  ),
87
88
  ).toThrow(/requires a read-before-write gate/);
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, vi, beforeEach, type MockInstance } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type { AuthUser, Change } from '@bevel-software/platform-shared';
3
4
  import type { GitService } from '../git/git.service.js';
4
5
  import type { PullRequestService } from '../git/pull-request.service.js';
@@ -143,7 +144,7 @@ function makeFacade(
143
144
  {} as IAccessControl,
144
145
  locks,
145
146
  pending,
146
- 'knowledge-base',
147
+ testKbContext(),
147
148
  openChangeGate(),
148
149
  events,
149
150
  );
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import type { RemoteSyncPullResult } from '@bevel-software/platform-shared';
3
4
  import type { GitService } from '../git/git.service.js';
4
5
  import type { PullRequestService } from '../git/pull-request.service.js';
@@ -37,7 +38,7 @@ function build(opts: { sync: () => Promise<RemoteSyncPullResult> }) {
37
38
  {} as IAccessControl,
38
39
  {} as FileLockService,
39
40
  pendingCommits,
40
- 'knowledge-base',
41
+ testKbContext(),
41
42
  openChangeGate(),
42
43
  events,
43
44
  );
@@ -259,7 +260,7 @@ describe('WorkflowService.retireRemoteGoneClone', () => {
259
260
  const svc = new WorkflowService(
260
261
  {} as Database, git, {} as PullRequestService, {} as IReviewWorkflowService,
261
262
  workspaceService, {} as IAccessControl, {} as FileLockService, {} as PendingCommitsService,
262
- 'knowledge-base',
263
+ testKbContext(),
263
264
  openChangeGate(),
264
265
  );
265
266
  return { svc, git, workspaceService };
@@ -327,7 +328,7 @@ describe('WorkflowService.retireRemoteGoneClone — what can bring the branch ba
327
328
  const svc = new WorkflowService(
328
329
  {} as Database, git, {} as PullRequestService, {} as IReviewWorkflowService,
329
330
  workspaceService, {} as IAccessControl, {} as FileLockService, {} as PendingCommitsService,
330
- 'knowledge-base',
331
+ testKbContext(),
331
332
  openChangeGate(),
332
333
  );
333
334
  expect(await svc.retireRemoteGoneClone('ali%2Fx')).toBe(false);
@@ -356,7 +357,7 @@ describe('WorkflowService.retireRemoteGoneClone — what can bring the branch ba
356
357
  const svc = new WorkflowService(
357
358
  {} as Database, git, {} as PullRequestService, {} as IReviewWorkflowService,
358
359
  workspaceService, {} as IAccessControl, {} as FileLockService, {} as PendingCommitsService,
359
- 'knowledge-base',
360
+ testKbContext(),
360
361
  openChangeGate(),
361
362
  );
362
363
  // Retirement enters first; a createBranch for the same name arrives while