@bevel-software/platform-core-backend 0.19.0 → 0.21.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 (799) 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 +45 -105
  11. package/dist/core/create-core-server.js.map +1 -1
  12. package/dist/core/create-core-services.d.ts +33 -5
  13. package/dist/core/create-core-services.d.ts.map +1 -1
  14. package/dist/core/create-core-services.js +146 -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.routes.d.ts +2 -1
  37. package/dist/modules/access/access.routes.d.ts.map +1 -1
  38. package/dist/modules/access/access.routes.js +10 -10
  39. package/dist/modules/access/access.routes.js.map +1 -1
  40. package/dist/modules/access/change-read-gate.d.ts +6 -3
  41. package/dist/modules/access/change-read-gate.d.ts.map +1 -1
  42. package/dist/modules/access/change-read-gate.js +9 -6
  43. package/dist/modules/access/change-read-gate.js.map +1 -1
  44. package/dist/modules/access/creator-access.d.ts +4 -2
  45. package/dist/modules/access/creator-access.d.ts.map +1 -1
  46. package/dist/modules/access/creator-access.js +7 -4
  47. package/dist/modules/access/creator-access.js.map +1 -1
  48. package/dist/modules/agent-instructions/read-preamble.d.ts +2 -1
  49. package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
  50. package/dist/modules/agent-instructions/read-preamble.js +6 -9
  51. package/dist/modules/agent-instructions/read-preamble.js.map +1 -1
  52. package/dist/modules/audit/agent-audit.service.d.ts +54 -0
  53. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -0
  54. package/dist/modules/audit/agent-audit.service.js +290 -0
  55. package/dist/modules/audit/agent-audit.service.js.map +1 -0
  56. package/dist/modules/audit/agent-rest-audit.middleware.d.ts +40 -0
  57. package/dist/modules/audit/agent-rest-audit.middleware.d.ts.map +1 -0
  58. package/dist/modules/audit/agent-rest-audit.middleware.js +75 -0
  59. package/dist/modules/audit/agent-rest-audit.middleware.js.map +1 -0
  60. package/dist/modules/audit/audit.contract.d.ts +145 -0
  61. package/dist/modules/audit/audit.contract.d.ts.map +1 -0
  62. package/dist/modules/audit/audit.contract.js +35 -0
  63. package/dist/modules/audit/audit.contract.js.map +1 -0
  64. package/dist/modules/audit/audit.routes.d.ts +21 -0
  65. package/dist/modules/audit/audit.routes.d.ts.map +1 -0
  66. package/dist/modules/audit/audit.routes.js +157 -0
  67. package/dist/modules/audit/audit.routes.js.map +1 -0
  68. package/dist/modules/audit/event-classifier.d.ts +52 -0
  69. package/dist/modules/audit/event-classifier.d.ts.map +1 -0
  70. package/dist/modules/audit/event-classifier.js +123 -0
  71. package/dist/modules/audit/event-classifier.js.map +1 -0
  72. package/dist/modules/audit/index.d.ts +7 -0
  73. package/dist/modules/audit/index.d.ts.map +1 -0
  74. package/dist/modules/audit/index.js +7 -0
  75. package/dist/modules/audit/index.js.map +1 -0
  76. package/dist/modules/audit/request-audit.d.ts +57 -0
  77. package/dist/modules/audit/request-audit.d.ts.map +1 -0
  78. package/dist/modules/audit/request-audit.js +117 -0
  79. package/dist/modules/audit/request-audit.js.map +1 -0
  80. package/dist/modules/auth/account-admission.d.ts +40 -0
  81. package/dist/modules/auth/account-admission.d.ts.map +1 -0
  82. package/dist/modules/auth/account-admission.js +17 -0
  83. package/dist/modules/auth/account-admission.js.map +1 -0
  84. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  85. package/dist/modules/auth/account.routes.js +4 -1
  86. package/dist/modules/auth/account.routes.js.map +1 -1
  87. package/dist/modules/auth/auth.service.d.ts +19 -1
  88. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  89. package/dist/modules/auth/auth.service.js +33 -1
  90. package/dist/modules/auth/auth.service.js.map +1 -1
  91. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  92. package/dist/modules/auth/oidc-auth-provider.js +9 -0
  93. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  94. package/dist/modules/connection-probe/connection-probe.service.d.ts +13 -1
  95. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  96. package/dist/modules/connection-probe/connection-probe.service.js +10 -2
  97. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  98. package/dist/modules/database/advisory-lock.d.ts +17 -0
  99. package/dist/modules/database/advisory-lock.d.ts.map +1 -1
  100. package/dist/modules/database/advisory-lock.js +24 -3
  101. package/dist/modules/database/advisory-lock.js.map +1 -1
  102. package/dist/modules/database/connection.d.ts +67 -2
  103. package/dist/modules/database/connection.d.ts.map +1 -1
  104. package/dist/modules/database/connection.js +118 -12
  105. package/dist/modules/database/connection.js.map +1 -1
  106. package/dist/modules/database/core-schema.d.ts +414 -0
  107. package/dist/modules/database/core-schema.d.ts.map +1 -1
  108. package/dist/modules/database/core-schema.js +99 -0
  109. package/dist/modules/database/core-schema.js.map +1 -1
  110. package/dist/modules/database/migrate.d.ts +1 -1
  111. package/dist/modules/database/migrate.d.ts.map +1 -1
  112. package/dist/modules/database/migrate.js +27 -3
  113. package/dist/modules/database/migrate.js.map +1 -1
  114. package/dist/modules/diff/diff.service.d.ts.map +1 -1
  115. package/dist/modules/diff/diff.service.js +6 -1
  116. package/dist/modules/diff/diff.service.js.map +1 -1
  117. package/dist/modules/kb-fs/branch-name.d.ts +0 -1
  118. package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
  119. package/dist/modules/kb-fs/branch-name.js +3 -3
  120. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  121. package/dist/modules/kb-fs/clone-config.d.ts +9 -8
  122. package/dist/modules/kb-fs/clone-config.d.ts.map +1 -1
  123. package/dist/modules/kb-fs/clone-config.js +14 -12
  124. package/dist/modules/kb-fs/clone-config.js.map +1 -1
  125. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts +9 -1
  126. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts.map +1 -1
  127. package/dist/modules/kb-fs/git-guarded-filesystem.js +16 -3
  128. package/dist/modules/kb-fs/git-guarded-filesystem.js.map +1 -1
  129. package/dist/modules/mcp/mcp-auth.middleware.d.ts +1 -0
  130. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  131. package/dist/modules/mcp/mcp-auth.middleware.js +32 -0
  132. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  133. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  134. package/dist/modules/mcp/mcp.routes.js +8 -1
  135. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  136. package/dist/modules/mcp/mcp.service.d.ts +16 -1
  137. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  138. package/dist/modules/mcp/mcp.service.js +52 -9
  139. package/dist/modules/mcp/mcp.service.js.map +1 -1
  140. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +59 -0
  141. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  142. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +180 -8
  143. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  144. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +4 -4
  145. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
  146. package/dist/modules/plugins/compile/marketplace-compiler.service.js +7 -10
  147. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -1
  148. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +4 -1
  149. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -1
  150. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +5 -3
  151. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -1
  152. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +6 -1
  153. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -1
  154. package/dist/modules/plugins/discovery/kb-plugin-source.js +14 -9
  155. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -1
  156. package/dist/modules/plugins/discovery/native.source.d.ts +4 -1
  157. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -1
  158. package/dist/modules/plugins/discovery/native.source.js +4 -2
  159. package/dist/modules/plugins/discovery/native.source.js.map +1 -1
  160. package/dist/modules/plugins/index.d.ts +1 -1
  161. package/dist/modules/plugins/index.d.ts.map +1 -1
  162. package/dist/modules/plugins/index.js +1 -1
  163. package/dist/modules/plugins/index.js.map +1 -1
  164. package/dist/modules/plugins/join-request-jobs.service.d.ts +3 -1
  165. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  166. package/dist/modules/plugins/join-request-jobs.service.js +6 -6
  167. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  168. package/dist/modules/plugins/join-requests.service.d.ts +3 -1
  169. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  170. package/dist/modules/plugins/join-requests.service.js +9 -8
  171. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  172. package/dist/modules/plugins/plugin-links.d.ts +65 -10
  173. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  174. package/dist/modules/plugins/plugin-links.js +136 -31
  175. package/dist/modules/plugins/plugin-links.js.map +1 -1
  176. package/dist/modules/plugins/plugin-links.service.d.ts +107 -5
  177. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
  178. package/dist/modules/plugins/plugin-links.service.js +151 -21
  179. package/dist/modules/plugins/plugin-links.service.js.map +1 -1
  180. package/dist/modules/plugins/plugin-provision.service.d.ts +10 -3
  181. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  182. package/dist/modules/plugins/plugin-provision.service.js +33 -26
  183. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  184. package/dist/modules/plugins/plugin-rename.service.d.ts +4 -2
  185. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
  186. package/dist/modules/plugins/plugin-rename.service.js +10 -12
  187. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  188. package/dist/modules/plugins/plugins.routes.d.ts +3 -0
  189. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  190. package/dist/modules/plugins/plugins.routes.js +45 -15
  191. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  192. package/dist/modules/plugins/plugins.service.d.ts +4 -4
  193. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  194. package/dist/modules/plugins/plugins.service.js +7 -10
  195. package/dist/modules/plugins/plugins.service.js.map +1 -1
  196. package/dist/modules/plugins/teams.routes.d.ts +4 -1
  197. package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
  198. package/dist/modules/plugins/teams.routes.js +11 -9
  199. package/dist/modules/plugins/teams.routes.js.map +1 -1
  200. package/dist/modules/secrets-vault/index.d.ts +1 -1
  201. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  202. package/dist/modules/secrets-vault/index.js +1 -1
  203. package/dist/modules/secrets-vault/index.js.map +1 -1
  204. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +29 -11
  205. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
  206. package/dist/modules/secrets-vault/secrets-variable-loader.js +46 -21
  207. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
  208. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +3 -0
  209. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  210. package/dist/modules/secrets-vault/secrets-vault.routes.js +4 -6
  211. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  212. package/dist/modules/settings/deployment-settings.service.d.ts +22 -10
  213. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  214. package/dist/modules/settings/deployment-settings.service.js +52 -28
  215. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  216. package/dist/modules/settings/setup.routes.d.ts +9 -2
  217. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  218. package/dist/modules/settings/setup.routes.js +20 -14
  219. package/dist/modules/settings/setup.routes.js.map +1 -1
  220. package/dist/modules/skills/allowed-tools-check.d.ts +4 -3
  221. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
  222. package/dist/modules/skills/allowed-tools-check.js +8 -8
  223. package/dist/modules/skills/allowed-tools-check.js.map +1 -1
  224. package/dist/modules/skills/pending-skills.service.d.ts +3 -1
  225. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  226. package/dist/modules/skills/pending-skills.service.js +9 -6
  227. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  228. package/dist/modules/skills/skill-access-requests.routes.d.ts +2 -1
  229. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  230. package/dist/modules/skills/skill-access-requests.routes.js +6 -6
  231. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  232. package/dist/modules/skills/skills.routes.d.ts +4 -1
  233. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  234. package/dist/modules/skills/skills.routes.js +4 -4
  235. package/dist/modules/skills/skills.routes.js.map +1 -1
  236. package/dist/modules/skills/skills.service.d.ts +4 -2
  237. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  238. package/dist/modules/skills/skills.service.js +13 -11
  239. package/dist/modules/skills/skills.service.js.map +1 -1
  240. package/dist/modules/tool-auth/external-api-key.interface.d.ts +21 -5
  241. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  242. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  243. package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -0
  244. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  245. package/dist/modules/tool-auth/external-api-key.service.js +22 -9
  246. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  247. package/dist/modules/tool-auth/internal-token.service.d.ts +10 -0
  248. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
  249. package/dist/modules/tool-auth/internal-token.service.js +1 -0
  250. package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
  251. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +8 -0
  252. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  253. package/dist/modules/tool-auth/tool-auth.middleware.js +9 -1
  254. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  255. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +2 -1
  256. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  257. package/dist/modules/tool-manuals/mcp-json-discovery.js +6 -5
  258. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  259. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +4 -2
  260. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  261. package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -10
  262. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  263. package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -1
  264. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  265. package/dist/modules/tool-manuals/pending-tools.service.js +19 -16
  266. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
  267. package/dist/modules/tool-manuals/tool-delete.service.d.ts +4 -2
  268. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
  269. package/dist/modules/tool-manuals/tool-delete.service.js +14 -12
  270. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  271. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +3 -1
  272. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  273. package/dist/modules/tool-manuals/tool-manuals.routes.js +7 -7
  274. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  275. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -2
  276. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  277. package/dist/modules/tool-manuals/tool-manuals.service.js +15 -12
  278. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  279. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -0
  280. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  281. package/dist/modules/tool-manuals/tool-manuals.tools.js +4 -6
  282. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  283. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +3 -2
  284. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  285. package/dist/modules/workflow/agent-tools/workflow.tools.js +9 -9
  286. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  287. package/dist/modules/workflow/git/git.service.d.ts +11 -5
  288. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  289. package/dist/modules/workflow/git/git.service.js +23 -14
  290. package/dist/modules/workflow/git/git.service.js.map +1 -1
  291. package/dist/modules/workflow/git/node-git-runner.d.ts +26 -2
  292. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  293. package/dist/modules/workflow/git/node-git-runner.js +35 -5
  294. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  295. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  296. package/dist/modules/workflow/review-workflow/review-workflow.service.js +9 -4
  297. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  298. package/dist/modules/workflow/session-ontology.service.d.ts +6 -1
  299. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -1
  300. package/dist/modules/workflow/session-ontology.service.js +6 -2
  301. package/dist/modules/workflow/session-ontology.service.js.map +1 -1
  302. package/dist/modules/workflow/workflow.service.d.ts +8 -3
  303. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  304. package/dist/modules/workflow/workflow.service.js +33 -23
  305. package/dist/modules/workflow/workflow.service.js.map +1 -1
  306. package/dist/modules/workspace/session-ontology.gate.d.ts +3 -1
  307. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
  308. package/dist/modules/workspace/session-ontology.gate.js +3 -3
  309. package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
  310. package/dist/modules/workspace/startup/kb-git.d.ts +4 -3
  311. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  312. package/dist/modules/workspace/startup/kb-git.js +15 -13
  313. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  314. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +5 -8
  315. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  316. package/dist/modules/workspace/startup/kb-startup-runner.js +35 -38
  317. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  318. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +7 -1
  319. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
  320. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +23 -16
  321. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  322. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +7 -1
  323. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -1
  324. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +12 -5
  325. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
  326. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +7 -1
  327. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -1
  328. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +12 -5
  329. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -1
  330. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +7 -1
  331. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -1
  332. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +12 -5
  333. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -1
  334. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +4 -1
  335. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  336. package/dist/modules/workspace/startup/steps/seed-tree.js +14 -11
  337. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  338. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +17 -3
  339. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  340. package/dist/modules/workspace/startup/steps/template-files.step.js +36 -30
  341. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  342. package/dist/modules/workspace/startup/steps/template-source.d.ts +6 -1
  343. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  344. package/dist/modules/workspace/startup/steps/template-source.js +10 -6
  345. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  346. package/dist/modules/workspace/workspace.routes.d.ts +2 -1
  347. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  348. package/dist/modules/workspace/workspace.routes.js +8 -7
  349. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  350. package/dist/modules/workspace/workspace.service.d.ts +26 -12
  351. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  352. package/dist/modules/workspace/workspace.service.js +41 -28
  353. package/dist/modules/workspace/workspace.service.js.map +1 -1
  354. package/dist/modules/workspace/workspace.tools.d.ts +2 -1
  355. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  356. package/dist/modules/workspace/workspace.tools.js +69 -31
  357. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  358. package/dist/modules/workspace/write-denial.d.ts +3 -2
  359. package/dist/modules/workspace/write-denial.d.ts.map +1 -1
  360. package/dist/modules/workspace/write-denial.js +6 -5
  361. package/dist/modules/workspace/write-denial.js.map +1 -1
  362. package/dist/shared/git-internals.d.ts +7 -1
  363. package/dist/shared/git-internals.d.ts.map +1 -1
  364. package/dist/shared/git-internals.js +67 -9
  365. package/dist/shared/git-internals.js.map +1 -1
  366. package/dist/shared/git.contract.d.ts +52 -7
  367. package/dist/shared/git.contract.d.ts.map +1 -1
  368. package/dist/shared/git.contract.js +30 -8
  369. package/dist/shared/git.contract.js.map +1 -1
  370. package/dist/shared/kb-context.d.ts +76 -0
  371. package/dist/shared/kb-context.d.ts.map +1 -0
  372. package/dist/shared/kb-context.js +108 -0
  373. package/dist/shared/kb-context.js.map +1 -0
  374. package/dist/shared/kb-layout.d.ts +3 -2
  375. package/dist/shared/kb-layout.d.ts.map +1 -1
  376. package/dist/shared/kb-layout.js +4 -3
  377. package/dist/shared/kb-layout.js.map +1 -1
  378. package/dist/shared/kb-layout.test.js +35 -27
  379. package/dist/shared/kb-layout.test.js.map +1 -1
  380. package/dist/shared/pending-proposals.d.ts +4 -1
  381. package/dist/shared/pending-proposals.d.ts.map +1 -1
  382. package/dist/shared/pending-proposals.js +3 -4
  383. package/dist/shared/pending-proposals.js.map +1 -1
  384. package/dist/shared/redact-secret.d.ts +5 -5
  385. package/dist/shared/redact-secret.js +5 -5
  386. package/dist/tenancy/index.d.ts +13 -0
  387. package/dist/tenancy/index.d.ts.map +1 -0
  388. package/dist/tenancy/index.js +13 -0
  389. package/dist/tenancy/index.js.map +1 -0
  390. package/dist/tenancy/static-tenant-source.d.ts +98 -0
  391. package/dist/tenancy/static-tenant-source.d.ts.map +1 -0
  392. package/dist/tenancy/static-tenant-source.js +220 -0
  393. package/dist/tenancy/static-tenant-source.js.map +1 -0
  394. package/dist/tenancy/tenant-host.d.ts +80 -0
  395. package/dist/tenancy/tenant-host.d.ts.map +1 -0
  396. package/dist/tenancy/tenant-host.js +217 -0
  397. package/dist/tenancy/tenant-host.js.map +1 -0
  398. package/dist/tenancy/tenant-runtime.d.ts +91 -0
  399. package/dist/tenancy/tenant-runtime.d.ts.map +1 -0
  400. package/dist/tenancy/tenant-runtime.js +174 -0
  401. package/dist/tenancy/tenant-runtime.js.map +1 -0
  402. package/dist/tenancy/tenant-secrets.d.ts +24 -0
  403. package/dist/tenancy/tenant-secrets.d.ts.map +1 -0
  404. package/dist/tenancy/tenant-secrets.js +30 -0
  405. package/dist/tenancy/tenant-secrets.js.map +1 -0
  406. package/dist/tenancy/tenant-source.contract.d.ts +45 -0
  407. package/dist/tenancy/tenant-source.contract.d.ts.map +1 -0
  408. package/dist/tenancy/tenant-source.contract.js +21 -0
  409. package/dist/tenancy/tenant-source.contract.js.map +1 -0
  410. package/migrations/0000_core_init.sql +14 -14
  411. package/migrations/0003_deployment_settings.sql +1 -1
  412. package/migrations/0005_github_facade.sql +1 -1
  413. package/migrations/0012_agent_audit.sql +41 -0
  414. package/migrations/0013_agent_identity_and_key_soft_delete.sql +29 -0
  415. package/migrations/meta/0012_snapshot.json +2247 -0
  416. package/migrations/meta/0013_snapshot.json +2259 -0
  417. package/migrations/meta/_journal.json +14 -0
  418. package/package.json +4 -4
  419. package/src/__tests__/branch-model.test.ts +7 -6
  420. package/src/__tests__/kb-context.ts +30 -0
  421. package/src/__tests__/kb-layout-config.test.ts +35 -30
  422. package/src/core/__tests__/catalog-cache-invalidation.test.ts +2 -1
  423. package/src/core/__tests__/lifecycle.test.ts +78 -1
  424. package/src/core/__tests__/public-config.test.ts +5 -1
  425. package/src/core/catalog-cache-invalidation.ts +16 -11
  426. package/src/core/core-ports.ts +19 -0
  427. package/src/core/create-core-server.ts +55 -106
  428. package/src/core/create-core-services.ts +193 -95
  429. package/src/core/lifecycle.ts +214 -29
  430. package/src/core/public-config.ts +8 -5
  431. package/src/core-config.ts +107 -8
  432. package/src/index.ts +25 -2
  433. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +2 -1
  434. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -1
  435. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -1
  436. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +2 -1
  437. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  438. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +2 -1
  439. package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -1
  440. package/src/modules/access/__tests__/access.routes.revoke.test.ts +2 -1
  441. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -1
  442. package/src/modules/access/__tests__/change-read-gate.test.ts +13 -11
  443. package/src/modules/access/__tests__/creator-access.test.ts +3 -2
  444. package/src/modules/access/__tests__/roles.routes.test.ts +2 -1
  445. package/src/modules/access/access-control.service.ts +20 -6
  446. package/src/modules/access/access.routes.ts +10 -13
  447. package/src/modules/access/change-read-gate.ts +10 -4
  448. package/src/modules/access/creator-access.ts +7 -2
  449. package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +13 -12
  450. package/src/modules/agent-instructions/read-preamble.ts +10 -12
  451. package/src/modules/audit/__tests__/agent-audit.service.test.ts +370 -0
  452. package/src/modules/audit/__tests__/agent-rest-audit.middleware.test.ts +113 -0
  453. package/src/modules/audit/__tests__/audit.routes.test.ts +201 -0
  454. package/src/modules/audit/__tests__/event-classifier.test.ts +121 -0
  455. package/src/modules/audit/agent-audit.service.ts +316 -0
  456. package/src/modules/audit/agent-rest-audit.middleware.ts +83 -0
  457. package/src/modules/audit/audit.contract.ts +164 -0
  458. package/src/modules/audit/audit.routes.ts +168 -0
  459. package/src/modules/audit/event-classifier.ts +155 -0
  460. package/src/modules/audit/index.ts +14 -0
  461. package/src/modules/audit/request-audit.ts +141 -0
  462. package/src/modules/auth/__tests__/account.routes.test.ts +15 -0
  463. package/src/modules/auth/__tests__/auth.service.test.ts +60 -0
  464. package/src/modules/auth/account-admission.ts +44 -0
  465. package/src/modules/auth/account.routes.ts +4 -1
  466. package/src/modules/auth/auth.service.ts +33 -1
  467. package/src/modules/auth/oidc-auth-provider.ts +9 -0
  468. package/src/modules/connection-probe/connection-probe.service.ts +7 -1
  469. package/src/modules/database/__tests__/advisory-lock.test.ts +23 -1
  470. package/src/modules/database/__tests__/connection.test.ts +98 -0
  471. package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -0
  472. package/src/modules/database/advisory-lock.ts +28 -4
  473. package/src/modules/database/connection.ts +143 -13
  474. package/src/modules/database/core-schema.ts +104 -0
  475. package/src/modules/database/migrate.ts +48 -14
  476. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
  477. package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
  478. package/src/modules/diff/diff.service.ts +6 -1
  479. package/src/modules/kb-fs/__tests__/branch-name.test.ts +6 -6
  480. package/src/modules/kb-fs/__tests__/clone-config.test.ts +24 -20
  481. package/src/modules/kb-fs/branch-name.ts +3 -3
  482. package/src/modules/kb-fs/clone-config.ts +15 -12
  483. package/src/modules/kb-fs/git-guarded-filesystem.ts +16 -3
  484. package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +2 -1
  485. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +183 -13
  486. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +60 -2
  487. package/src/modules/mcp/__tests__/mcp.routes.local-token.test.ts +24 -4
  488. package/src/modules/mcp/__tests__/mcp.routes.stateless.test.ts +1 -1
  489. package/src/modules/mcp/__tests__/mcp.service.test.ts +120 -3
  490. package/src/modules/mcp/mcp-auth.middleware.ts +31 -0
  491. package/src/modules/mcp/mcp.routes.ts +11 -1
  492. package/src/modules/mcp/mcp.service.ts +73 -8
  493. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +184 -6
  494. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +12 -11
  495. package/src/modules/plugins/__tests__/bundle-dialect.test.ts +2 -1
  496. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +6 -4
  497. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +2 -1
  498. package/src/modules/plugins/__tests__/join-requests.service.test.ts +2 -1
  499. package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +4 -3
  500. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +6 -4
  501. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +220 -5
  502. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +3 -1
  503. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +7 -6
  504. package/src/modules/plugins/__tests__/plugins.routes.test.ts +11 -2
  505. package/src/modules/plugins/__tests__/teams.routes.test.ts +2 -1
  506. package/src/modules/plugins/compile/marketplace-compiler.service.ts +7 -9
  507. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +20 -16
  508. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +9 -2
  509. package/src/modules/plugins/discovery/kb-plugin-source.ts +15 -8
  510. package/src/modules/plugins/discovery/native.source.ts +4 -1
  511. package/src/modules/plugins/index.ts +1 -1
  512. package/src/modules/plugins/join-request-jobs.service.ts +8 -7
  513. package/src/modules/plugins/join-requests.service.ts +7 -7
  514. package/src/modules/plugins/plugin-links.service.ts +192 -19
  515. package/src/modules/plugins/plugin-links.ts +147 -27
  516. package/src/modules/plugins/plugin-provision.service.ts +54 -27
  517. package/src/modules/plugins/plugin-rename.service.ts +10 -10
  518. package/src/modules/plugins/plugins.routes.ts +45 -15
  519. package/src/modules/plugins/plugins.service.ts +7 -11
  520. package/src/modules/plugins/teams.routes.ts +16 -8
  521. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +7 -0
  522. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +40 -0
  523. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +2 -0
  524. package/src/modules/secrets-vault/index.ts +2 -0
  525. package/src/modules/secrets-vault/secrets-variable-loader.ts +51 -21
  526. package/src/modules/secrets-vault/secrets-vault.routes.ts +7 -6
  527. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +59 -11
  528. package/src/modules/settings/__tests__/git-root-folders.test.ts +2 -1
  529. package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +2 -1
  530. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +7 -4
  531. package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +2 -0
  532. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +2 -0
  533. package/src/modules/settings/__tests__/setup.routes.test.ts +33 -52
  534. package/src/modules/settings/deployment-settings.service.ts +68 -28
  535. package/src/modules/settings/setup.routes.ts +26 -16
  536. package/src/modules/skills/__tests__/allowed-tools-check.test.ts +11 -10
  537. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +4 -3
  538. package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -1
  539. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +2 -1
  540. package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +2 -1
  541. package/src/modules/skills/__tests__/skills.service.test.ts +3 -2
  542. package/src/modules/skills/allowed-tools-check.ts +7 -6
  543. package/src/modules/skills/pending-skills.service.ts +9 -8
  544. package/src/modules/skills/skill-access-requests.routes.ts +7 -7
  545. package/src/modules/skills/skills.routes.ts +4 -3
  546. package/src/modules/skills/skills.service.ts +13 -9
  547. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +29 -8
  548. package/src/modules/tool-auth/__tests__/internal-token.service.test.ts +6 -0
  549. package/src/modules/tool-auth/external-api-key.interface.ts +22 -5
  550. package/src/modules/tool-auth/external-api-key.service.ts +25 -8
  551. package/src/modules/tool-auth/internal-token.service.ts +11 -0
  552. package/src/modules/tool-auth/tool-auth.middleware.ts +17 -1
  553. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +3 -2
  554. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -2
  555. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +17 -12
  556. package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
  557. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +4 -1
  558. package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +2 -1
  559. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +2 -1
  560. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +5 -4
  561. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +2 -1
  562. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +4 -2
  563. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +13 -5
  564. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -1
  565. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +9 -1
  566. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +3 -2
  567. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +2 -0
  568. package/src/modules/tool-manuals/mcp-json-discovery.ts +6 -4
  569. package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -11
  570. package/src/modules/tool-manuals/pending-tools.service.ts +19 -16
  571. package/src/modules/tool-manuals/tool-delete.service.ts +13 -10
  572. package/src/modules/tool-manuals/tool-manuals.routes.ts +10 -8
  573. package/src/modules/tool-manuals/tool-manuals.service.ts +15 -13
  574. package/src/modules/tool-manuals/tool-manuals.tools.ts +7 -6
  575. package/src/modules/workflow/__tests__/apply-failure.test.ts +2 -1
  576. package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +14 -26
  577. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +2 -1
  578. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +3 -2
  579. package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +2 -1
  580. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +3 -10
  581. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +2 -1
  582. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +3 -10
  583. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +28 -27
  584. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +2 -1
  585. package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +2 -1
  586. package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +3 -2
  587. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +2 -1
  588. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +5 -4
  589. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +2 -1
  590. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +2 -1
  591. package/src/modules/workflow/agent-tools/workflow.tools.ts +11 -9
  592. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +5 -4
  593. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +12 -11
  594. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +9 -8
  595. package/src/modules/workflow/git/__tests__/git.service.commitFile.strayPath.test.ts +8 -7
  596. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +6 -5
  597. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +3 -2
  598. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +3 -2
  599. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +7 -6
  600. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +16 -15
  601. package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -2
  602. package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +2 -1
  603. package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +2 -1
  604. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +10 -9
  605. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +2 -1
  606. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +6 -5
  607. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +9 -8
  608. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +2 -1
  609. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +4 -3
  610. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +9 -8
  611. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +2 -1
  612. package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -1
  613. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +4 -3
  614. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +8 -7
  615. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +41 -3
  616. package/src/modules/workflow/git/git.service.ts +24 -13
  617. package/src/modules/workflow/git/node-git-runner.ts +37 -4
  618. package/src/modules/workflow/review-workflow/review-workflow.service.ts +9 -6
  619. package/src/modules/workflow/session-ontology.service.ts +7 -2
  620. package/src/modules/workflow/workflow.service.ts +31 -24
  621. package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -2
  622. package/src/modules/workspace/__tests__/git-internals.security.test.ts +144 -52
  623. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +4 -2
  624. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
  625. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +2 -1
  626. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +2 -1
  627. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +2 -1
  628. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +2 -1
  629. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -1
  630. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +2 -1
  631. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +5 -4
  632. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +2 -1
  633. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +2 -1
  634. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
  635. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -5
  636. package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
  637. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
  638. package/src/modules/workspace/__tests__/workspace.service.test.ts +84 -50
  639. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +2 -1
  640. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -7
  641. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +4 -3
  642. package/src/modules/workspace/__tests__/workspace.tools.test.ts +9 -8
  643. package/src/modules/workspace/__tests__/write-denial.test.ts +5 -4
  644. package/src/modules/workspace/session-ontology.gate.ts +6 -4
  645. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +6 -2
  646. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +29 -21
  647. package/src/modules/workspace/startup/kb-git.ts +15 -22
  648. package/src/modules/workspace/startup/kb-startup-runner.ts +40 -46
  649. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +104 -98
  650. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +24 -16
  651. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +14 -5
  652. package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +13 -5
  653. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +14 -5
  654. package/src/modules/workspace/startup/steps/seed-tree.ts +11 -9
  655. package/src/modules/workspace/startup/steps/template-files.step.ts +43 -34
  656. package/src/modules/workspace/startup/steps/template-source.ts +8 -5
  657. package/src/modules/workspace/workspace.routes.ts +8 -7
  658. package/src/modules/workspace/workspace.service.ts +39 -27
  659. package/src/modules/workspace/workspace.tools.ts +68 -31
  660. package/src/modules/workspace/write-denial.ts +7 -5
  661. package/src/shared/__tests__/git-internals.test.ts +41 -0
  662. package/src/shared/__tests__/kb-layout.plugin.test.ts +19 -16
  663. package/src/shared/git-internals.ts +61 -6
  664. package/src/shared/git.contract.ts +70 -8
  665. package/src/shared/kb-context.ts +130 -0
  666. package/src/shared/kb-layout.test.ts +37 -27
  667. package/src/shared/kb-layout.ts +4 -3
  668. package/src/shared/pending-proposals.ts +7 -4
  669. package/src/shared/redact-secret.ts +5 -5
  670. package/src/tenancy/__tests__/static-tenant-source.test.ts +177 -0
  671. package/src/tenancy/__tests__/tenant-host.test.ts +372 -0
  672. package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -0
  673. package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -0
  674. package/src/tenancy/index.ts +35 -0
  675. package/src/tenancy/static-tenant-source.ts +296 -0
  676. package/src/tenancy/tenant-host.ts +261 -0
  677. package/src/tenancy/tenant-runtime.ts +208 -0
  678. package/src/tenancy/tenant-secrets.ts +41 -0
  679. package/src/tenancy/tenant-source.contract.ts +59 -0
  680. package/dist/modules/access/access-errors.d.ts +0 -34
  681. package/dist/modules/access/access-errors.d.ts.map +0 -1
  682. package/dist/modules/access/access-errors.js +0 -40
  683. package/dist/modules/access/access-errors.js.map +0 -1
  684. package/dist/modules/access/access-splice.d.ts +0 -140
  685. package/dist/modules/access/access-splice.d.ts.map +0 -1
  686. package/dist/modules/access/access-splice.js +0 -389
  687. package/dist/modules/access/access-splice.js.map +0 -1
  688. package/dist/modules/access/group-files.d.ts +0 -83
  689. package/dist/modules/access/group-files.d.ts.map +0 -1
  690. package/dist/modules/access/group-files.js +0 -167
  691. package/dist/modules/access/group-files.js.map +0 -1
  692. package/dist/modules/access/kb-read-filter.d.ts +0 -41
  693. package/dist/modules/access/kb-read-filter.d.ts.map +0 -1
  694. package/dist/modules/access/kb-read-filter.js +0 -60
  695. package/dist/modules/access/kb-read-filter.js.map +0 -1
  696. package/dist/modules/access/render-roles-yaml.d.ts +0 -22
  697. package/dist/modules/access/render-roles-yaml.d.ts.map +0 -1
  698. package/dist/modules/access/render-roles-yaml.js +0 -56
  699. package/dist/modules/access/render-roles-yaml.js.map +0 -1
  700. package/dist/modules/access/roles-yaml-guard.d.ts +0 -56
  701. package/dist/modules/access/roles-yaml-guard.d.ts.map +0 -1
  702. package/dist/modules/access/roles-yaml-guard.js +0 -79
  703. package/dist/modules/access/roles-yaml-guard.js.map +0 -1
  704. package/dist/modules/diff/diff-paths.d.ts +0 -2
  705. package/dist/modules/diff/diff-paths.d.ts.map +0 -1
  706. package/dist/modules/diff/diff-paths.js +0 -9
  707. package/dist/modules/diff/diff-paths.js.map +0 -1
  708. package/dist/modules/groups/group-provision.service.d.ts +0 -130
  709. package/dist/modules/groups/group-provision.service.d.ts.map +0 -1
  710. package/dist/modules/groups/group-provision.service.js +0 -288
  711. package/dist/modules/groups/group-provision.service.js.map +0 -1
  712. package/dist/modules/groups/groups.contract.d.ts +0 -106
  713. package/dist/modules/groups/groups.contract.d.ts.map +0 -1
  714. package/dist/modules/groups/groups.contract.js +0 -36
  715. package/dist/modules/groups/groups.contract.js.map +0 -1
  716. package/dist/modules/groups/groups.routes.d.ts +0 -42
  717. package/dist/modules/groups/groups.routes.d.ts.map +0 -1
  718. package/dist/modules/groups/groups.routes.js +0 -379
  719. package/dist/modules/groups/groups.routes.js.map +0 -1
  720. package/dist/modules/groups/groups.service.d.ts +0 -60
  721. package/dist/modules/groups/groups.service.d.ts.map +0 -1
  722. package/dist/modules/groups/groups.service.js +0 -172
  723. package/dist/modules/groups/groups.service.js.map +0 -1
  724. package/dist/modules/groups/index.d.ts +0 -7
  725. package/dist/modules/groups/index.d.ts.map +0 -1
  726. package/dist/modules/groups/index.js +0 -6
  727. package/dist/modules/groups/index.js.map +0 -1
  728. package/dist/modules/groups/join-proposals.d.ts +0 -53
  729. package/dist/modules/groups/join-proposals.d.ts.map +0 -1
  730. package/dist/modules/groups/join-proposals.js +0 -67
  731. package/dist/modules/groups/join-proposals.js.map +0 -1
  732. package/dist/modules/groups/join-requests.service.d.ts +0 -81
  733. package/dist/modules/groups/join-requests.service.d.ts.map +0 -1
  734. package/dist/modules/groups/join-requests.service.js +0 -135
  735. package/dist/modules/groups/join-requests.service.js.map +0 -1
  736. package/dist/modules/mcp/mcp-session-store.d.ts +0 -74
  737. package/dist/modules/mcp/mcp-session-store.d.ts.map +0 -1
  738. package/dist/modules/mcp/mcp-session-store.js +0 -131
  739. package/dist/modules/mcp/mcp-session-store.js.map +0 -1
  740. package/dist/modules/workflow/file-change-notifier.d.ts +0 -38
  741. package/dist/modules/workflow/file-change-notifier.d.ts.map +0 -1
  742. package/dist/modules/workflow/file-change-notifier.js +0 -22
  743. package/dist/modules/workflow/file-change-notifier.js.map +0 -1
  744. package/dist/modules/workflow/git/branch-name.d.ts +0 -10
  745. package/dist/modules/workflow/git/branch-name.d.ts.map +0 -1
  746. package/dist/modules/workflow/git/branch-name.js +0 -76
  747. package/dist/modules/workflow/git/branch-name.js.map +0 -1
  748. package/dist/modules/workflow/git/clone-config.d.ts +0 -61
  749. package/dist/modules/workflow/git/clone-config.d.ts.map +0 -1
  750. package/dist/modules/workflow/git/clone-config.js +0 -69
  751. package/dist/modules/workflow/git/clone-config.js.map +0 -1
  752. package/dist/modules/workflow/git/mutex.d.ts +0 -11
  753. package/dist/modules/workflow/git/mutex.d.ts.map +0 -1
  754. package/dist/modules/workflow/git/mutex.js +0 -23
  755. package/dist/modules/workflow/git/mutex.js.map +0 -1
  756. package/dist/modules/workflow/locking-filesystem.d.ts +0 -137
  757. package/dist/modules/workflow/locking-filesystem.d.ts.map +0 -1
  758. package/dist/modules/workflow/locking-filesystem.js +0 -553
  759. package/dist/modules/workflow/locking-filesystem.js.map +0 -1
  760. package/dist/modules/workflow/read-only-filesystem.d.ts +0 -24
  761. package/dist/modules/workflow/read-only-filesystem.d.ts.map +0 -1
  762. package/dist/modules/workflow/read-only-filesystem.js +0 -39
  763. package/dist/modules/workflow/read-only-filesystem.js.map +0 -1
  764. package/dist/modules/workflow/workflow.errors.d.ts +0 -197
  765. package/dist/modules/workflow/workflow.errors.d.ts.map +0 -1
  766. package/dist/modules/workflow/workflow.errors.js +0 -298
  767. package/dist/modules/workflow/workflow.errors.js.map +0 -1
  768. package/dist/modules/workspace/bevel-ignore.d.ts +0 -30
  769. package/dist/modules/workspace/bevel-ignore.d.ts.map +0 -1
  770. package/dist/modules/workspace/bevel-ignore.js +0 -61
  771. package/dist/modules/workspace/bevel-ignore.js.map +0 -1
  772. package/dist/modules/workspace/kb-seed.interface.d.ts +0 -36
  773. package/dist/modules/workspace/kb-seed.interface.d.ts.map +0 -1
  774. package/dist/modules/workspace/kb-seed.interface.js +0 -2
  775. package/dist/modules/workspace/kb-seed.interface.js.map +0 -1
  776. package/dist/modules/workspace/kb-seed.service.d.ts +0 -125
  777. package/dist/modules/workspace/kb-seed.service.d.ts.map +0 -1
  778. package/dist/modules/workspace/kb-seed.service.js +0 -535
  779. package/dist/modules/workspace/kb-seed.service.js.map +0 -1
  780. package/dist/modules/workspace/plugins-migration.d.ts +0 -50
  781. package/dist/modules/workspace/plugins-migration.d.ts.map +0 -1
  782. package/dist/modules/workspace/plugins-migration.js +0 -379
  783. package/dist/modules/workspace/plugins-migration.js.map +0 -1
  784. package/dist/shared/fs-errors.d.ts +0 -8
  785. package/dist/shared/fs-errors.d.ts.map +0 -1
  786. package/dist/shared/fs-errors.js +0 -11
  787. package/dist/shared/fs-errors.js.map +0 -1
  788. package/dist/shared/fs-walk.d.ts +0 -23
  789. package/dist/shared/fs-walk.d.ts.map +0 -1
  790. package/dist/shared/fs-walk.js +0 -42
  791. package/dist/shared/fs-walk.js.map +0 -1
  792. package/dist/shared/hash-email.d.ts +0 -11
  793. package/dist/shared/hash-email.d.ts.map +0 -1
  794. package/dist/shared/hash-email.js +0 -14
  795. package/dist/shared/hash-email.js.map +0 -1
  796. package/dist/shared/kb-walk.d.ts +0 -52
  797. package/dist/shared/kb-walk.d.ts.map +0 -1
  798. package/dist/shared/kb-walk.js +0 -76
  799. package/dist/shared/kb-walk.js.map +0 -1
@@ -4,7 +4,6 @@ import { logger } from '../../shared/logging.js';
4
4
  const log = logger('skills');
5
5
  import '../auth/auth.middleware.js'; // Express Request.userId / userEmail augmentation
6
6
  import {
7
- DEFAULT_BRANCH,
8
7
  joinBranchFor,
9
8
  type AuthUser,
10
9
  type IWorkflowService,
@@ -14,7 +13,7 @@ import { spliceGrant } from '../access-model/access-splice.js';
14
13
  import { WorkflowDomainError } from '../../shared/domain-errors.js';
15
14
  import { domainErrorBody } from '../../shared/http-errors.js';
16
15
  import { isAbsence } from '../../shared/fs.contract.js';
17
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
16
+ import type { KbContext } from '../../shared/kb-context.js';
18
17
  import type { WorkspaceService } from '../workspace/workspace.service.js';
19
18
  import type { JoinRequestsService } from '../plugins/join-requests.service.js';
20
19
  import type { ISkillService } from './skills.contract.js';
@@ -46,12 +45,13 @@ export function createSkillAccessRequestRoutes(deps: {
46
45
  workflow: IWorkflowService;
47
46
  workspaceService: WorkspaceService;
48
47
  joinRequests: JoinRequestsService;
49
- kbDirName: string;
48
+ kb: KbContext;
50
49
  resolveUser: (req: express.Request) => Promise<AuthUser | null>;
51
50
  }): express.Router {
52
- const { skillService, accessControl, workflow, workspaceService, joinRequests, kbDirName, resolveUser } = deps;
51
+ const { skillService, accessControl, workflow, workspaceService, joinRequests, kb, resolveUser } = deps;
52
+ const { kbDirName } = kb;
53
53
  const router = express.Router();
54
- const wsId = () => workspaceIdForBranch(DEFAULT_BRANCH);
54
+ const wsId = () => kb.defaultWorkspaceId();
55
55
  const rulesOf = (folder: string) => `${folder}/access.md`;
56
56
 
57
57
  /** The skill the caller may read, by name — or null after answering 404. */
@@ -108,7 +108,7 @@ export function createSkillAccessRequestRoutes(deps: {
108
108
  );
109
109
  if (!(await branchExists())) {
110
110
  try {
111
- await workflow.createBranch(wsId(), branch, DEFAULT_BRANCH);
111
+ await workflow.createBranch(wsId(), branch, kb.defaultBranch);
112
112
  } catch (err) {
113
113
  if (!(await branchExists())) throw err;
114
114
  }
@@ -133,7 +133,7 @@ export function createSkillAccessRequestRoutes(deps: {
133
133
  }
134
134
  const detail = await workflow.openChangeRequest(ws.id, user, {
135
135
  sourceBranch: branch,
136
- targetBranch: DEFAULT_BRANCH,
136
+ targetBranch: kb.defaultBranch,
137
137
  title: `Access request: ${name}`,
138
138
  description:
139
139
  `${user.name} asked to edit the skill ${name}. An editor of the skill accepts by ` +
@@ -1,7 +1,6 @@
1
1
  import express from 'express';
2
- import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
3
2
  import '../auth/auth.middleware.js'; // Express Request.userId / userEmail augmentation
4
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
3
+ import type { KbContext } from '../../shared/kb-context.js';
5
4
  import type { IPendingSkillService, ISkillService, PluginMembership } from './skills.contract.js';
6
5
  import type { IAllowedToolsChecker } from './allowed-tools-check.js';
7
6
 
@@ -37,6 +36,8 @@ export interface SkillMembershipGate {
37
36
  */
38
37
  export function createSkillsRoutes(
39
38
  skillService: ISkillService,
39
+ /** The released branch's clone — where the discoverability verdicts are read. */
40
+ kb: Pick<KbContext, 'defaultWorkspaceId'>,
40
41
  pendingSkills?: IPendingSkillService,
41
42
  links?: SkillMembershipSource,
42
43
  /**
@@ -75,7 +76,7 @@ export function createSkillsRoutes(
75
76
  const folders = [...membership.byPlugin.entries()];
76
77
  const verdicts = folders.length
77
78
  ? await gate.canReadBatch(
78
- workspaceIdForBranch(DEFAULT_BRANCH),
79
+ kb.defaultWorkspaceId(),
79
80
  email,
80
81
  folders.map(([, p]) => `${p.folder}/access.md`),
81
82
  )
@@ -4,9 +4,8 @@ import { logger } from '../../shared/logging.js';
4
4
  const log = logger('skills');
5
5
  import fs from 'node:fs/promises';
6
6
  import { parseDocument } from 'yaml';
7
- import { DEFAULT_BRANCH, PLUGINS_DIR, SKILLS_DIR } from '@bevel-software/platform-shared';
8
7
  import type { WorkspaceService } from '../workspace/workspace.service.js';
9
- import { workspaceIdForBranch } from '../../shared/workspace-id.js';
8
+ import type { KbContext } from '../../shared/kb-context.js';
10
9
  import type { IAccessControl } from '../access/access-control.interface.js';
11
10
  import { extractFrontmatter, resolveDeclaredId, dedupeById } from '../../shared/frontmatter-id.js';
12
11
  import type { IgnoreRules, ITreeWalker } from '../../shared/fs.contract.js';
@@ -54,13 +53,17 @@ export class SkillService implements ISkillService {
54
53
  constructor(
55
54
  private readonly workspaceService: WorkspaceService,
56
55
  private readonly accessControl: IAccessControl,
57
- private readonly kbDirName: string,
56
+ private readonly kb: KbContext,
58
57
  private readonly disk: ITreeWalker,
59
58
  now: () => number = Date.now,
60
59
  ) {
61
60
  this.cache = new TtlCache(CACHE_TTL_MS, now);
62
61
  }
63
62
 
63
+ private get kbDirName(): string {
64
+ return this.kb.kbDirName;
65
+ }
66
+
64
67
  /** Attach the history source a `version` is answered from. */
65
68
  setHistory(history: SkillHistorySource): void {
66
69
  this.history = history;
@@ -92,7 +95,7 @@ export class SkillService implements ISkillService {
92
95
  const found = (await this.scan()).find((s) => s.summary.name === name);
93
96
  if (!found) return { ok: false, error: 'not_found' };
94
97
 
95
- const wsId = workspaceIdForBranch(DEFAULT_BRANCH);
98
+ const wsId = this.kb.defaultWorkspaceId();
96
99
  // Through `readable`, not a bare `canRead`: the two gates must never
97
100
  // disagree. `canRead` reads a file's own frontmatter rules off disk on
98
101
  // every call while `canReadBatch` resolves them through a per-workspace
@@ -213,7 +216,7 @@ export class SkillService implements ISkillService {
213
216
  */
214
217
  private async readable(userEmail: string, skillFolders: string[]): Promise<Map<string, boolean>> {
215
218
  return this.accessControl.canReadBatch(
216
- workspaceIdForBranch(DEFAULT_BRANCH),
219
+ this.kb.defaultWorkspaceId(),
217
220
  userEmail,
218
221
  skillFolders.map((p) => `${p}/SKILL.md`),
219
222
  );
@@ -238,7 +241,7 @@ export class SkillService implements ISkillService {
238
241
  // be read.
239
242
  let wsId: string;
240
243
  try {
241
- wsId = (await this.workspaceService.getOrCreateForBranch(DEFAULT_BRANCH)).id;
244
+ wsId = (await this.workspaceService.getOrCreateForBranch(this.kb.defaultBranch)).id;
242
245
  } catch {
243
246
  return [];
244
247
  }
@@ -314,15 +317,16 @@ export class SkillService implements ISkillService {
314
317
  // Each root starts its own ignore stack (the walk extends it with the
315
318
  // root's own file first). Order is cosmetic: the sort below is by name
316
319
  // then path, so a same-named pair resolves the same way regardless.
317
- await walkRoot(SKILLS_DIR);
318
- await walkRoot(PLUGINS_DIR);
320
+ const { skillsDir, pluginsDir } = this.kb.layout;
321
+ await walkRoot(skillsDir);
322
+ await walkRoot(pluginsDir);
319
323
  // A skill's id (frontmatter `id`/`name`, else folder name) is how getSkill()
320
324
  // resolves it, so it must be unique. Sort by (name, root, path) for a
321
325
  // deterministic winner — the shared root FIRST, since `Skills/` is a
322
326
  // skill's canonical home and a same-named inline copy is the stale one —
323
327
  // then REFUSE later duplicates via the shared dedup — the same rule tools
324
328
  // use (no silent auto-suffix that would rebind an id under the caller).
325
- const rootRank = (p: string) => (p === SKILLS_DIR || p.startsWith(`${SKILLS_DIR}/`) ? 0 : 1);
329
+ const rootRank = (p: string) => (p === skillsDir || p.startsWith(`${skillsDir}/`) ? 0 : 1);
326
330
  out.sort(
327
331
  (a, b) =>
328
332
  a.summary.name.localeCompare(b.summary.name) ||
@@ -149,6 +149,7 @@ describe('ExternalApiKeyService', () => {
149
149
  lastUsedAt: null,
150
150
  revokedAt: null,
151
151
  revokedBy: null,
152
+ deletedAt: null,
152
153
  });
153
154
  });
154
155
 
@@ -303,6 +304,7 @@ describe('ExternalApiKeyService', () => {
303
304
  lastUsedAt: rows[0].lastUsedAt!.getTime(),
304
305
  revokedAt: null,
305
306
  revokedBy: null,
307
+ deletedAt: null,
306
308
  });
307
309
  expect(summaries[1].revokedAt).toBe(rows[1].revokedAt!.getTime());
308
310
  // sanity-check that ordering was requested (we can't introspect the
@@ -333,6 +335,7 @@ describe('ExternalApiKeyService', () => {
333
335
  lastUsedAt: aliceKey.lastUsedAt!.getTime(),
334
336
  revokedAt: null,
335
337
  revokedBy: null,
338
+ deletedAt: null,
336
339
  user: { id: 'u-alice', email: 'alice@example.com', name: 'Alice' },
337
340
  },
338
341
  {
@@ -343,6 +346,7 @@ describe('ExternalApiKeyService', () => {
343
346
  lastUsedAt: null,
344
347
  revokedAt: bobKey.revokedAt!.getTime(),
345
348
  revokedBy: null,
349
+ deletedAt: null,
346
350
  user: { id: 'u-bob', email: 'bob@example.com', name: 'Bob' },
347
351
  },
348
352
  ]);
@@ -439,9 +443,9 @@ describe('ExternalApiKeyService', () => {
439
443
  });
440
444
 
441
445
  describe('remove', () => {
442
- it('validates then deletes the key (dependents cascade at the DB layer)', async () => {
443
- // Queue: SELECT finds a revoked row; then the key delete consumes one.
444
- const { db } = makeFakeDb([
446
+ it('validates then marks the key deleted — the row stays, for the Audit log', async () => {
447
+ // Queue: SELECT finds a revoked row; then the marking update consumes one.
448
+ const { db, calls } = makeFakeDb([
445
449
  [{ revokedAt: new Date('2026-02-01T00:00:00Z') }],
446
450
  undefined,
447
451
  ]);
@@ -449,12 +453,29 @@ describe('ExternalApiKeyService', () => {
449
453
 
450
454
  await service.remove('tok-1', 'user-1');
451
455
 
452
- // Validation SELECT first, then ONE delete of the key row. Dependent
453
- // rows (e.g. llm_usage metering) are removed by ON DELETE CASCADE —
454
- // this service must not know those tables exist.
456
+ // Validation SELECT first, then ONE update of the key row and never a
457
+ // delete: the Audit log's events hang off this row, and a key's owner
458
+ // deleting it must not erase what it did. Only a revoked, not-yet-
459
+ // deleted row of the owner's is marked.
455
460
  expect((db as any).select).toHaveBeenCalledTimes(1);
456
- expect((db as any).delete).toHaveBeenCalledTimes(1);
457
- expect((db as any).delete).toHaveBeenCalledWith(externalApiKeys);
461
+ expect((db as any).delete).not.toHaveBeenCalled();
462
+ expect((db as any).update).toHaveBeenCalledTimes(1);
463
+ expect((db as any).update).toHaveBeenCalledWith(externalApiKeys);
464
+ expect(calls.set[0]![0].deletedAt).toBeInstanceOf(Date);
465
+ const mark = renderSql(calls.where[1]![0]).sql;
466
+ expect(mark).toMatch(/"api_tokens"."user_id" = \$2/);
467
+ expect(mark).toMatch(/"api_tokens"."revoked_at" is not null/);
468
+ expect(mark).toMatch(/"api_tokens"."deleted_at" is null/);
469
+ });
470
+
471
+ it('treats an already-deleted key as absent for its owner', async () => {
472
+ // The validation SELECT carries the not-deleted filter, so a deleted
473
+ // row answers nothing — and nothing is marked twice.
474
+ const { db, calls } = makeFakeDb([[]]);
475
+ const service = new ExternalApiKeyService(db, 'bevel_');
476
+ await expect(service.remove('tok-1', 'user-1')).rejects.toBeInstanceOf(TokenNotFoundError);
477
+ expect(renderSql(calls.where[0]![0]).sql).toMatch(/"api_tokens"."deleted_at" is null/);
478
+ expect((db as any).update).not.toHaveBeenCalled();
458
479
  });
459
480
 
460
481
  it('throws TokenStillActiveError when the token exists but was never disconnected', async () => {
@@ -22,6 +22,12 @@ describe('InternalTokenService', () => {
22
22
  expect(svc.verify(token)).toEqual({ userId: 'user-A', externalProxy: true });
23
23
  });
24
24
 
25
+ it('round-trips the connectionId claim (the agent behind an exchanged OAuth grant)', () => {
26
+ const svc = new InternalTokenService({ secret: 'test-secret' });
27
+ const token = svc.mint({ userId: 'user-A', externalProxy: true, connectionId: 'conn-1' });
28
+ expect(svc.verify(token)).toEqual({ userId: 'user-A', externalProxy: true, connectionId: 'conn-1' });
29
+ });
30
+
25
31
  it('round-trips the focusedBranch claim (the in-process agent workspace branch)', () => {
26
32
  const svc = new InternalTokenService({ secret: 'test-secret' });
27
33
  const token = svc.mint({ userId: 'user-A', sessionId: 'run-1', focusedBranch: 'main' });
@@ -37,6 +37,12 @@ export interface ExternalApiKeySummary {
37
37
  * before this was recorded, which read as the owner's doing).
38
38
  */
39
39
  revokedBy: RevokedBy | null;
40
+ /**
41
+ * When the owner deleted the key for good from their own pages. Such a
42
+ * key is absent from the owner's listings and shown to admins as deleted;
43
+ * its row stays so the Audit log's events keep their principal.
44
+ */
45
+ deletedAt: number | null;
40
46
  }
41
47
 
42
48
  /** Who revoked a key: its owner, or an admin acting across the deployment. */
@@ -137,6 +143,13 @@ export interface IExternalApiKeyService {
137
143
  /** Active + revoked tokens for the user, newest-first. */
138
144
  listForUser(userId: string): Promise<ExternalApiKeySummary[]>;
139
145
 
146
+ /**
147
+ * The account a key belongs to, live or revoked, or null when no such key
148
+ * exists. The ownership check behind a per-key read or revoke that is
149
+ * offered to owners and admins alike (the Audit log's).
150
+ */
151
+ ownerOf(id: string): Promise<string | null>;
152
+
140
153
  /**
141
154
  * Mark a token revoked. Idempotent — revoking an already-revoked token
142
155
  * is a no-op (the row's `revokedAt` is not overwritten). Throws
@@ -161,11 +174,15 @@ export interface IExternalApiKeyService {
161
174
  revokeAny(id: string): Promise<void>;
162
175
 
163
176
  /**
164
- * Permanently delete a token row, dropping its audit trail. Only permitted
165
- * on an already-revoked token — an active key must be disconnected first,
166
- * so a live agent's access is never yanked by a single click. Throws
167
- * TokenNotFoundError if the token doesn't belong to the user, and
168
- * TokenStillActiveError if it hasn't been revoked yet.
177
+ * Delete a token for good, from the owner's point of view: it leaves their
178
+ * listings and can never be used or reconnected. The row itself stays,
179
+ * marked deleted, so the Audit log keeps the key's events under their
180
+ * principal — a log its subject could erase would not be one. Only
181
+ * permitted on an already-revoked token — an active key must be
182
+ * disconnected first, so a live agent's access is never yanked by a single
183
+ * click. Throws TokenNotFoundError if the token doesn't belong to the user
184
+ * (or is already deleted), and TokenStillActiveError if it hasn't been
185
+ * revoked yet.
169
186
  */
170
187
  remove(id: string, userId: string): Promise<void>;
171
188
  }
@@ -144,14 +144,25 @@ export class ExternalApiKeyService implements IExternalApiKeyService {
144
144
  }
145
145
 
146
146
  async listForUser(userId: string): Promise<ExternalApiKeySummary[]> {
147
+ // A key the owner deleted for good is gone from THEIR listings — that is
148
+ // what the deletion means to them; the row lives on for the Audit log.
147
149
  const rows = await this.db
148
150
  .select()
149
151
  .from(externalApiKeys)
150
- .where(eq(externalApiKeys.userId, userId))
152
+ .where(and(eq(externalApiKeys.userId, userId), isNull(externalApiKeys.deletedAt)))
151
153
  .orderBy(desc(externalApiKeys.createdAt));
152
154
  return rows.map(toSummary);
153
155
  }
154
156
 
157
+ async ownerOf(id: string): Promise<string | null> {
158
+ const [row] = await this.db
159
+ .select({ userId: externalApiKeys.userId })
160
+ .from(externalApiKeys)
161
+ .where(eq(externalApiKeys.id, id))
162
+ .limit(1);
163
+ return row?.userId ?? null;
164
+ }
165
+
155
166
  async listForDeployment(): Promise<AdminExternalApiKeySummary[]> {
156
167
  // Owner joined in so the admin overview is one round-trip; ordered by
157
168
  // owner email so per-account grouping is a linear pass, newest key
@@ -219,14 +230,16 @@ export class ExternalApiKeyService implements IExternalApiKeyService {
219
230
  }
220
231
 
221
232
  async remove(id: string, userId: string): Promise<void> {
222
- // Only revoked rows may be hard-deleted — deleting an active key would
233
+ // Only revoked rows may be deleted — deleting an active key would
223
234
  // silently cut off a live agent. Scope by userId so a user can only
224
235
  // delete their own tokens. Validate first (so we can return a precise
225
- // not-found vs still-active error), then delete inside a transaction.
236
+ // not-found vs still-active error), then mark the row deleted.
226
237
  const [existing] = await this.db
227
238
  .select({ revokedAt: externalApiKeys.revokedAt })
228
239
  .from(externalApiKeys)
229
- .where(and(eq(externalApiKeys.id, id), eq(externalApiKeys.userId, userId)))
240
+ .where(
241
+ and(eq(externalApiKeys.id, id), eq(externalApiKeys.userId, userId), isNull(externalApiKeys.deletedAt)),
242
+ )
230
243
  .limit(1);
231
244
  if (!existing) {
232
245
  throw new TokenNotFoundError();
@@ -236,16 +249,19 @@ export class ExternalApiKeyService implements IExternalApiKeyService {
236
249
  throw new TokenStillActiveError();
237
250
  }
238
251
 
239
- // Dependents (e.g. the enterprise LLM-usage metering rows) hang off this
240
- // row via ON DELETE CASCADE foreign keys, so a bare delete takes any audit
241
- // trail with it — this service doesn't have to know those tables exist.
252
+ // A deletion in name: the row stays, marked, because the Audit log's
253
+ // events hang off it and the trail must outlive the key's owner's wish
254
+ // to be rid of it. The key was revoked already, so nothing can use it;
255
+ // deleting hides it from the owner and tells an admin it was deleted.
242
256
  await this.db
243
- .delete(externalApiKeys)
257
+ .update(externalApiKeys)
258
+ .set({ deletedAt: new Date() })
244
259
  .where(
245
260
  and(
246
261
  eq(externalApiKeys.id, id),
247
262
  eq(externalApiKeys.userId, userId),
248
263
  isNotNull(externalApiKeys.revokedAt),
264
+ isNull(externalApiKeys.deletedAt),
249
265
  ),
250
266
  );
251
267
  }
@@ -271,5 +287,6 @@ function toSummary(row: typeof externalApiKeys.$inferSelect): ExternalApiKeySumm
271
287
  lastUsedAt: row.lastUsedAt ? row.lastUsedAt.getTime() : null,
272
288
  revokedAt: row.revokedAt ? row.revokedAt.getTime() : null,
273
289
  revokedBy: (row.revokedBy as RevokedBy | null) ?? null,
290
+ deletedAt: row.deletedAt ? row.deletedAt.getTime() : null,
274
291
  };
275
292
  }
@@ -37,6 +37,16 @@ export interface InternalTokenClaim {
37
37
  * expected to carry `sessionId` on the tool body, not in the token.
38
38
  */
39
39
  externalProxy?: boolean;
40
+ /**
41
+ * The agent connection (`agent_connections.id`) an external-proxy token
42
+ * stands in for. The LOCAL MCP server swaps its OAuth grant for one of these
43
+ * at `/api/mcp/local-token` and presents it everywhere the grant would have
44
+ * gone, so without this claim every call it makes would arrive with a user
45
+ * and no agent — unattributable in the Audit log. Carried, never decided:
46
+ * the exchange copies it from the verified grant. Absent on every other
47
+ * internal token.
48
+ */
49
+ connectionId?: string;
40
50
  }
41
51
 
42
52
  interface SignedPayload extends InternalTokenClaim {
@@ -137,6 +147,7 @@ export class InternalTokenService {
137
147
  ...(typeof payload.sessionId === 'string' ? { sessionId: payload.sessionId } : {}),
138
148
  ...(typeof payload.focusedBranch === 'string' ? { focusedBranch: payload.focusedBranch } : {}),
139
149
  ...(payload.externalProxy === true ? { externalProxy: true } : {}),
150
+ ...(typeof payload.connectionId === 'string' ? { connectionId: payload.connectionId } : {}),
140
151
  };
141
152
  }
142
153
 
@@ -34,6 +34,14 @@ export interface ToolAuth {
34
34
  * never carries it and must name the branch explicitly.
35
35
  */
36
36
  focusedBranch?: string;
37
+ /**
38
+ * The agent connection an `externalProxy` token stands in for — the local
39
+ * server's exchanged grant names one (see `InternalTokenClaim.connectionId`).
40
+ * Only that grant carries it: the hosted proxy's own loopback tokens do
41
+ * not, and a connection key has a `tokenId` instead. What the REST audit
42
+ * recorder attributes a direct tool call to.
43
+ */
44
+ connectionId?: string;
37
45
  /** Always `'write'` now (the middleware sets it for both internal + external — neither credential carries scope). The read path is dormant until consumer agents are removed. */
38
46
  scope: 'read' | 'write';
39
47
  }
@@ -129,7 +137,15 @@ export function createTokenVerifier(
129
137
  const claim = internalTokenService.verify(token);
130
138
  if (!claim) return { ok: false, status: 401, message: 'Invalid or expired internal token' };
131
139
  return claim.externalProxy
132
- ? { ok: true, auth: { source: 'external', userId: claim.userId, scope: 'write' } }
140
+ ? {
141
+ ok: true,
142
+ auth: {
143
+ source: 'external',
144
+ userId: claim.userId,
145
+ ...(claim.connectionId ? { connectionId: claim.connectionId } : {}),
146
+ scope: 'write',
147
+ },
148
+ }
133
149
  : { ok: true, auth: { source: 'internal', userId: claim.userId, sessionId: claim.sessionId, focusedBranch: claim.focusedBranch, scope: 'write' } };
134
150
  }
135
151
 
@@ -16,6 +16,7 @@ import { SpillStore } from '../../workspace/spill-store.js';
16
16
  import { DocExtractService } from '../../workspace/file-readers/doc-extract.service.js';
17
17
  import { NEW_ROLE_GUIDANCE } from '../../access-model/roles-yaml-guard.js';
18
18
  import { loadActiveGroups } from '../../access/access-control.service.js';
19
+ import { testKbContext } from '../../../__tests__/kb-context.js';
19
20
 
20
21
  /**
21
22
  * The agent's file tools over the production context resolver and a real
@@ -68,10 +69,10 @@ async function start(): Promise<string> {
68
69
  canWriteBatchAtRef: async () => null,
69
70
  canReadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
70
71
  } as never;
71
- registerWorkspaceTools(registry, router, toolAuth, createToolHandlerFactory(resolve), new SpillStore(path.join(os.tmpdir(), 'bevel-test-spills')), new DocExtractService(docCache), allowAll, KB, {
72
+ registerWorkspaceTools(registry, router, toolAuth, createToolHandlerFactory(resolve), new SpillStore(path.join(os.tmpdir(), 'bevel-test-spills')), new DocExtractService(docCache), allowAll, testKbContext({ kbDirName: KB }), {
72
73
  service: {} as never,
73
74
  enabled: false, // ontology boundary not under test here
74
- kbDirName: KB,
75
+ kb: testKbContext({ kbDirName: KB }),
75
76
  recoveryBotEmail: 'recovery-bot@bevel.local',
76
77
  hooks: new WorkflowHooks(),
77
78
  }, new RoutineWritePolicyService(), {} as never);
@@ -12,6 +12,7 @@ import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.
12
12
  import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
13
13
  import { SpillStore } from '../../workspace/spill-store.js';
14
14
  import { DocExtractService } from '../../workspace/file-readers/doc-extract.service.js';
15
+ import { testKbContext } from '../../../__tests__/kb-context.js';
15
16
 
16
17
  const WS = 'target-company-state';
17
18
  let recorded: unknown[][] = [];
@@ -63,10 +64,10 @@ async function start(): Promise<string> {
63
64
  // kb (citation) tools alongside the workspace tools. Those registrations —
64
65
  // and their web_search / submit_feedback / cite_kb_node cases — moved to
65
66
  // the enterprise repo with their modules; core registers only core tools.
66
- registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), new DocExtractService('/tmp/bevel-test-doc-extract'), accessControl, 'knowledge-base', {
67
+ registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), new DocExtractService('/tmp/bevel-test-doc-extract'), accessControl, testKbContext(), {
67
68
  service: {} as never,
68
69
  enabled: false, // ontology boundary not under test here
69
- kbDirName: 'knowledge-base',
70
+ kb: testKbContext(),
70
71
  recoveryBotEmail: 'recovery-bot@bevel.local',
71
72
  hooks: new WorkflowHooks(),
72
73
  }, new RoutineWritePolicyService(), {} as never /* sessionSink — start_session not exercised here */);
@@ -1,8 +1,13 @@
1
1
  import { describe, expect, it, vi, afterEach } from 'vitest';
2
+ import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
2
3
  import { descriptorsFromMcpJson, judgeMcpServerEntry } from '../mcp-json-discovery.js';
3
4
 
4
5
  afterEach(() => vi.restoreAllMocks());
5
6
 
7
+ /** The reader under the default layout, which these cases are written against. */
8
+ const fromMcpJson = (folder: string, mcpJson: string, manifest: string | null) =>
9
+ descriptorsFromMcpJson(folder, mcpJson, manifest, DEFAULT_KB_LAYOUT);
10
+
6
11
  describe('judgeMcpServerEntry', () => {
7
12
  it('keeps every accepted header and env key — one spelled __proto__ included', () => {
8
13
  // Parsed from text, as a repository file is: JSON.parse makes `__proto__`
@@ -44,7 +49,7 @@ const MANIFEST = JSON.stringify({
44
49
 
45
50
  describe('descriptorsFromMcpJson', () => {
46
51
  it('synthesizes descriptors keyed by server name, path at mcp.json', () => {
47
- const out = descriptorsFromMcpJson(
52
+ const out = fromMcpJson(
48
53
  'GTM',
49
54
  JSON.stringify({ mcpServers: { notion: { type: 'streamable-http', url: 'https://mcp.notion.com/mcp' } } }),
50
55
  null,
@@ -63,7 +68,7 @@ describe('descriptorsFromMcpJson', () => {
63
68
  it('refuses an sse server rather than rebuilding it as a transport it is not', () => {
64
69
  // The pinned MCP client has no sse transport; emitting `http` for an sse
65
70
  // server configures a handshake the server does not speak.
66
- const out = descriptorsFromMcpJson(
71
+ const out = fromMcpJson(
67
72
  'GTM',
68
73
  JSON.stringify({ mcpServers: { legacy: { type: 'sse', url: 'https://mcp.legacy.example/sse' } } }),
69
74
  null,
@@ -72,7 +77,7 @@ describe('descriptorsFromMcpJson', () => {
72
77
  });
73
78
 
74
79
  it('merges extension auth over mcp.json literals and carries variables + description', () => {
75
- const out = descriptorsFromMcpJson(
80
+ const out = fromMcpJson(
76
81
  'GTM',
77
82
  JSON.stringify({
78
83
  mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp', headers: { 'X-V': '2' } } },
@@ -87,7 +92,7 @@ describe('descriptorsFromMcpJson', () => {
87
92
  });
88
93
 
89
94
  it('marks extension-flagged servers and every stdio server local-only', () => {
90
- const out = descriptorsFromMcpJson(
95
+ const out = fromMcpJson(
91
96
  'GTM',
92
97
  JSON.stringify({
93
98
  mcpServers: {
@@ -105,7 +110,7 @@ describe('descriptorsFromMcpJson', () => {
105
110
 
106
111
  it('skips a malformed entry without losing its siblings', () => {
107
112
  vi.spyOn(console, 'warn').mockImplementation(() => {});
108
- const out = descriptorsFromMcpJson(
113
+ const out = fromMcpJson(
109
114
  'GTM',
110
115
  JSON.stringify({
111
116
  mcpServers: {
@@ -123,7 +128,7 @@ describe('descriptorsFromMcpJson', () => {
123
128
  it('ignores malformed extension headers instead of spreading them into keys', () => {
124
129
  // A string spread into the merge would scatter its indices ('0', '1', …)
125
130
  // into header names; a malformed extension must cost its own data only.
126
- const out = descriptorsFromMcpJson(
131
+ const out = fromMcpJson(
127
132
  'GTM',
128
133
  JSON.stringify({
129
134
  mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp', headers: { 'X-V': '2' } } },
@@ -142,7 +147,7 @@ describe('descriptorsFromMcpJson', () => {
142
147
  // A dropped declaration would silently re-scope a credential (undeclared
143
148
  // defaults to the shared admin row), so a bad entry takes the SERVER
144
149
  // offline — never just the entry, and never its siblings.
145
- const out = descriptorsFromMcpJson(
150
+ const out = fromMcpJson(
146
151
  'GTM',
147
152
  JSON.stringify({
148
153
  mcpServers: {
@@ -165,7 +170,7 @@ describe('descriptorsFromMcpJson', () => {
165
170
  it('applies the .tool declaration rules: no reserved names, no duplicates, gated OAuth URLs, string authParams', () => {
166
171
  vi.spyOn(console, 'warn').mockImplementation(() => {});
167
172
  const declare = (variables: unknown) =>
168
- descriptorsFromMcpJson(
173
+ fromMcpJson(
169
174
  'GTM',
170
175
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
171
176
  JSON.stringify({
@@ -197,7 +202,7 @@ describe('descriptorsFromMcpJson', () => {
197
202
  });
198
203
 
199
204
  it('trims a padded oauth clientId like the .tool parser does', () => {
200
- const out = descriptorsFromMcpJson(
205
+ const out = fromMcpJson(
201
206
  'GTM',
202
207
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
203
208
  JSON.stringify({
@@ -225,7 +230,7 @@ describe('descriptorsFromMcpJson', () => {
225
230
  it('accepts a client-id-only sign-in (endpoints discovered later), refuses half a pair, carries pkce/resource', () => {
226
231
  vi.spyOn(console, 'warn').mockImplementation(() => {});
227
232
  const declare = (oauth: unknown) =>
228
- descriptorsFromMcpJson(
233
+ fromMcpJson(
229
234
  'GTM',
230
235
  JSON.stringify({ mcpServers: { vendor: { type: 'streamable-http', url: 'https://v.example/mcp' } } }),
231
236
  JSON.stringify({
@@ -262,9 +267,9 @@ describe('descriptorsFromMcpJson', () => {
262
267
 
263
268
  it('yields nothing for an unparsable file, quietly for an absent extensions block', () => {
264
269
  vi.spyOn(console, 'warn').mockImplementation(() => {});
265
- expect(descriptorsFromMcpJson('GTM', '{ not json', null)).toEqual([]);
270
+ expect(fromMcpJson('GTM', '{ not json', null)).toEqual([]);
266
271
  expect(
267
- descriptorsFromMcpJson('GTM', JSON.stringify({ mcpServers: {} }), '{ also not json'),
272
+ fromMcpJson('GTM', JSON.stringify({ mcpServers: {} }), '{ also not json'),
268
273
  ).toEqual([]);
269
274
  });
270
275
  });
@@ -9,6 +9,7 @@ import type { WorkspaceService } from '../../workspace/workspace.service.js';
9
9
  import type { IAccessControl } from '../../access/access-control.interface.js';
10
10
  import type { IToolManualService, ToolManualSummary } from '../tool-manuals.contract.js';
11
11
  import { McpServerEditService } from '../mcp-server-edit.service.js';
12
+ import { testKbContext } from '../../../__tests__/kb-context.js';
12
13
 
13
14
  const KB = 'knowledge-base';
14
15
  const USER: AuthUser = { id: 'u-1', email: 'ali@example.com', name: 'Ali' } as AuthUser;
@@ -77,7 +78,7 @@ beforeEach(async () => {
77
78
  }),
78
79
  } as unknown as IToolManualService;
79
80
 
80
- svc = new McpServerEditService(workspaceService, commits, accessControl, toolManuals, KB, new NodeFs());
81
+ svc = new McpServerEditService(workspaceService, commits, accessControl, toolManuals, testKbContext({ kbDirName: KB }), new NodeFs());
81
82
  });
82
83
 
83
84
  afterEach(async () => {
@@ -5,6 +5,7 @@ import { hashEmail } from '../../../shared/email-identity.js';
5
5
  import type { WorkspaceService } from '../../workspace/workspace.service.js';
6
6
  import type { IAccessControl } from '../../access/access-control.interface.js';
7
7
  import type { IToolManualService, ToolManualSummary } from '../tool-manuals.contract.js';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
 
9
10
  /**
10
11
  * The half of the tool catalog that is NOT on the default branch.
@@ -93,7 +94,7 @@ function harness(opts: {
93
94
  listChangeRequests: async () => opts.crs,
94
95
  } as unknown as IWorkflowService;
95
96
 
96
- return new PendingToolsService(workspaceService, accessControl, toolManuals, workflow);
97
+ return new PendingToolsService(workspaceService, accessControl, toolManuals, workflow, testKbContext());
97
98
  }
98
99
 
99
100
  const ADMIN_WRITES = { [TOOL_PATH]: [ADMIN] };
@@ -370,6 +371,7 @@ describe('PendingToolsService', () => {
370
371
  {} as unknown as IAccessControl,
371
372
  { listAllSummaries: async () => [] } as unknown as IToolManualService,
372
373
  workflow,
374
+ testKbContext(),
373
375
  );
374
376
  await expect(svc.listPendingTools(AUTHOR)).resolves.toEqual([]);
375
377
  });
@@ -384,6 +386,7 @@ describe('PendingToolsService', () => {
384
386
  },
385
387
  } as unknown as IToolManualService,
386
388
  { listChangeRequests: async () => [cr()] } as unknown as IWorkflowService,
389
+ testKbContext(),
387
390
  );
388
391
  await expect(svc.listPendingTools(AUTHOR)).resolves.toEqual([]);
389
392
  });