@bevel-software/platform-core-backend 0.20.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 (576) 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 +23 -105
  11. package/dist/core/create-core-server.js.map +1 -1
  12. package/dist/core/create-core-services.d.ts +30 -5
  13. package/dist/core/create-core-services.d.ts.map +1 -1
  14. package/dist/core/create-core-services.js +136 -81
  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/auth/account-admission.d.ts +40 -0
  53. package/dist/modules/auth/account-admission.d.ts.map +1 -0
  54. package/dist/modules/auth/account-admission.js +17 -0
  55. package/dist/modules/auth/account-admission.js.map +1 -0
  56. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  57. package/dist/modules/auth/account.routes.js +4 -1
  58. package/dist/modules/auth/account.routes.js.map +1 -1
  59. package/dist/modules/auth/auth.service.d.ts +19 -1
  60. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  61. package/dist/modules/auth/auth.service.js +33 -1
  62. package/dist/modules/auth/auth.service.js.map +1 -1
  63. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  64. package/dist/modules/auth/oidc-auth-provider.js +9 -0
  65. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  66. package/dist/modules/connection-probe/connection-probe.service.d.ts +13 -1
  67. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  68. package/dist/modules/connection-probe/connection-probe.service.js +10 -2
  69. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  70. package/dist/modules/database/advisory-lock.d.ts +17 -0
  71. package/dist/modules/database/advisory-lock.d.ts.map +1 -1
  72. package/dist/modules/database/advisory-lock.js +24 -3
  73. package/dist/modules/database/advisory-lock.js.map +1 -1
  74. package/dist/modules/database/connection.d.ts +67 -2
  75. package/dist/modules/database/connection.d.ts.map +1 -1
  76. package/dist/modules/database/connection.js +118 -12
  77. package/dist/modules/database/connection.js.map +1 -1
  78. package/dist/modules/database/migrate.d.ts +1 -1
  79. package/dist/modules/database/migrate.d.ts.map +1 -1
  80. package/dist/modules/database/migrate.js +27 -3
  81. package/dist/modules/database/migrate.js.map +1 -1
  82. package/dist/modules/kb-fs/branch-name.d.ts +0 -1
  83. package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
  84. package/dist/modules/kb-fs/branch-name.js +3 -3
  85. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  86. package/dist/modules/kb-fs/clone-config.d.ts +9 -8
  87. package/dist/modules/kb-fs/clone-config.d.ts.map +1 -1
  88. package/dist/modules/kb-fs/clone-config.js +14 -12
  89. package/dist/modules/kb-fs/clone-config.js.map +1 -1
  90. package/dist/modules/mcp/mcp.service.d.ts +7 -0
  91. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  92. package/dist/modules/mcp/mcp.service.js +4 -4
  93. package/dist/modules/mcp/mcp.service.js.map +1 -1
  94. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +4 -4
  95. package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
  96. package/dist/modules/plugins/compile/marketplace-compiler.service.js +7 -10
  97. package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -1
  98. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +4 -1
  99. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -1
  100. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +5 -3
  101. package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -1
  102. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +6 -1
  103. package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -1
  104. package/dist/modules/plugins/discovery/kb-plugin-source.js +14 -9
  105. package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -1
  106. package/dist/modules/plugins/discovery/native.source.d.ts +4 -1
  107. package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -1
  108. package/dist/modules/plugins/discovery/native.source.js +4 -2
  109. package/dist/modules/plugins/discovery/native.source.js.map +1 -1
  110. package/dist/modules/plugins/index.d.ts +1 -1
  111. package/dist/modules/plugins/index.d.ts.map +1 -1
  112. package/dist/modules/plugins/index.js +1 -1
  113. package/dist/modules/plugins/index.js.map +1 -1
  114. package/dist/modules/plugins/join-request-jobs.service.d.ts +3 -1
  115. package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
  116. package/dist/modules/plugins/join-request-jobs.service.js +6 -6
  117. package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
  118. package/dist/modules/plugins/join-requests.service.d.ts +3 -1
  119. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  120. package/dist/modules/plugins/join-requests.service.js +9 -8
  121. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  122. package/dist/modules/plugins/plugin-links.d.ts +65 -10
  123. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  124. package/dist/modules/plugins/plugin-links.js +136 -31
  125. package/dist/modules/plugins/plugin-links.js.map +1 -1
  126. package/dist/modules/plugins/plugin-links.service.d.ts +107 -5
  127. package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
  128. package/dist/modules/plugins/plugin-links.service.js +151 -21
  129. package/dist/modules/plugins/plugin-links.service.js.map +1 -1
  130. package/dist/modules/plugins/plugin-provision.service.d.ts +10 -3
  131. package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
  132. package/dist/modules/plugins/plugin-provision.service.js +33 -26
  133. package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
  134. package/dist/modules/plugins/plugin-rename.service.d.ts +4 -2
  135. package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
  136. package/dist/modules/plugins/plugin-rename.service.js +10 -12
  137. package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
  138. package/dist/modules/plugins/plugins.routes.d.ts +3 -0
  139. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  140. package/dist/modules/plugins/plugins.routes.js +45 -15
  141. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  142. package/dist/modules/plugins/plugins.service.d.ts +4 -4
  143. package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
  144. package/dist/modules/plugins/plugins.service.js +7 -10
  145. package/dist/modules/plugins/plugins.service.js.map +1 -1
  146. package/dist/modules/plugins/teams.routes.d.ts +4 -1
  147. package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
  148. package/dist/modules/plugins/teams.routes.js +11 -9
  149. package/dist/modules/plugins/teams.routes.js.map +1 -1
  150. package/dist/modules/secrets-vault/index.d.ts +1 -1
  151. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  152. package/dist/modules/secrets-vault/index.js +1 -1
  153. package/dist/modules/secrets-vault/index.js.map +1 -1
  154. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +29 -11
  155. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
  156. package/dist/modules/secrets-vault/secrets-variable-loader.js +46 -21
  157. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
  158. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +3 -0
  159. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  160. package/dist/modules/secrets-vault/secrets-vault.routes.js +4 -6
  161. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  162. package/dist/modules/settings/deployment-settings.service.d.ts +12 -8
  163. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  164. package/dist/modules/settings/deployment-settings.service.js +20 -22
  165. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  166. package/dist/modules/settings/setup.routes.d.ts +9 -2
  167. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  168. package/dist/modules/settings/setup.routes.js +20 -14
  169. package/dist/modules/settings/setup.routes.js.map +1 -1
  170. package/dist/modules/skills/allowed-tools-check.d.ts +4 -3
  171. package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
  172. package/dist/modules/skills/allowed-tools-check.js +8 -8
  173. package/dist/modules/skills/allowed-tools-check.js.map +1 -1
  174. package/dist/modules/skills/pending-skills.service.d.ts +3 -1
  175. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
  176. package/dist/modules/skills/pending-skills.service.js +9 -6
  177. package/dist/modules/skills/pending-skills.service.js.map +1 -1
  178. package/dist/modules/skills/skill-access-requests.routes.d.ts +2 -1
  179. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  180. package/dist/modules/skills/skill-access-requests.routes.js +6 -6
  181. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  182. package/dist/modules/skills/skills.routes.d.ts +4 -1
  183. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  184. package/dist/modules/skills/skills.routes.js +4 -4
  185. package/dist/modules/skills/skills.routes.js.map +1 -1
  186. package/dist/modules/skills/skills.service.d.ts +4 -2
  187. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  188. package/dist/modules/skills/skills.service.js +13 -11
  189. package/dist/modules/skills/skills.service.js.map +1 -1
  190. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +2 -1
  191. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  192. package/dist/modules/tool-manuals/mcp-json-discovery.js +6 -5
  193. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  194. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +4 -2
  195. package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
  196. package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -10
  197. package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
  198. package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -1
  199. package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
  200. package/dist/modules/tool-manuals/pending-tools.service.js +19 -16
  201. package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
  202. package/dist/modules/tool-manuals/tool-delete.service.d.ts +4 -2
  203. package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
  204. package/dist/modules/tool-manuals/tool-delete.service.js +14 -12
  205. package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
  206. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +3 -1
  207. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  208. package/dist/modules/tool-manuals/tool-manuals.routes.js +7 -7
  209. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  210. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -2
  211. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  212. package/dist/modules/tool-manuals/tool-manuals.service.js +15 -12
  213. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  214. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -0
  215. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  216. package/dist/modules/tool-manuals/tool-manuals.tools.js +4 -6
  217. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  218. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +3 -2
  219. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  220. package/dist/modules/workflow/agent-tools/workflow.tools.js +9 -9
  221. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  222. package/dist/modules/workflow/git/git.service.d.ts +11 -5
  223. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  224. package/dist/modules/workflow/git/git.service.js +23 -14
  225. package/dist/modules/workflow/git/git.service.js.map +1 -1
  226. package/dist/modules/workflow/git/node-git-runner.d.ts +26 -2
  227. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  228. package/dist/modules/workflow/git/node-git-runner.js +35 -5
  229. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  230. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  231. package/dist/modules/workflow/review-workflow/review-workflow.service.js +9 -4
  232. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  233. package/dist/modules/workflow/session-ontology.service.d.ts +6 -1
  234. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -1
  235. package/dist/modules/workflow/session-ontology.service.js +6 -2
  236. package/dist/modules/workflow/session-ontology.service.js.map +1 -1
  237. package/dist/modules/workflow/workflow.service.d.ts +8 -3
  238. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  239. package/dist/modules/workflow/workflow.service.js +33 -23
  240. package/dist/modules/workflow/workflow.service.js.map +1 -1
  241. package/dist/modules/workspace/session-ontology.gate.d.ts +3 -1
  242. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
  243. package/dist/modules/workspace/session-ontology.gate.js +3 -3
  244. package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
  245. package/dist/modules/workspace/startup/kb-git.d.ts +4 -3
  246. package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
  247. package/dist/modules/workspace/startup/kb-git.js +15 -13
  248. package/dist/modules/workspace/startup/kb-git.js.map +1 -1
  249. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +5 -8
  250. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  251. package/dist/modules/workspace/startup/kb-startup-runner.js +35 -38
  252. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  253. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +7 -1
  254. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
  255. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +23 -16
  256. package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
  257. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +7 -1
  258. package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -1
  259. package/dist/modules/workspace/startup/steps/personal-spaces.step.js +12 -5
  260. package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
  261. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +7 -1
  262. package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -1
  263. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +12 -5
  264. package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -1
  265. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +7 -1
  266. package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -1
  267. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +12 -5
  268. package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -1
  269. package/dist/modules/workspace/startup/steps/seed-tree.d.ts +4 -1
  270. package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
  271. package/dist/modules/workspace/startup/steps/seed-tree.js +14 -11
  272. package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
  273. package/dist/modules/workspace/startup/steps/template-files.step.d.ts +17 -3
  274. package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
  275. package/dist/modules/workspace/startup/steps/template-files.step.js +36 -30
  276. package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
  277. package/dist/modules/workspace/startup/steps/template-source.d.ts +6 -1
  278. package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
  279. package/dist/modules/workspace/startup/steps/template-source.js +10 -6
  280. package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
  281. package/dist/modules/workspace/workspace.routes.d.ts +2 -1
  282. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  283. package/dist/modules/workspace/workspace.routes.js +8 -7
  284. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  285. package/dist/modules/workspace/workspace.service.d.ts +18 -12
  286. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  287. package/dist/modules/workspace/workspace.service.js +32 -28
  288. package/dist/modules/workspace/workspace.service.js.map +1 -1
  289. package/dist/modules/workspace/workspace.tools.d.ts +2 -1
  290. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  291. package/dist/modules/workspace/workspace.tools.js +20 -18
  292. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  293. package/dist/modules/workspace/write-denial.d.ts +3 -2
  294. package/dist/modules/workspace/write-denial.d.ts.map +1 -1
  295. package/dist/modules/workspace/write-denial.js +6 -5
  296. package/dist/modules/workspace/write-denial.js.map +1 -1
  297. package/dist/shared/git.contract.d.ts +52 -7
  298. package/dist/shared/git.contract.d.ts.map +1 -1
  299. package/dist/shared/git.contract.js +30 -8
  300. package/dist/shared/git.contract.js.map +1 -1
  301. package/dist/shared/kb-context.d.ts +76 -0
  302. package/dist/shared/kb-context.d.ts.map +1 -0
  303. package/dist/shared/kb-context.js +108 -0
  304. package/dist/shared/kb-context.js.map +1 -0
  305. package/dist/shared/kb-layout.d.ts +3 -2
  306. package/dist/shared/kb-layout.d.ts.map +1 -1
  307. package/dist/shared/kb-layout.js +4 -3
  308. package/dist/shared/kb-layout.js.map +1 -1
  309. package/dist/shared/kb-layout.test.js +35 -27
  310. package/dist/shared/kb-layout.test.js.map +1 -1
  311. package/dist/shared/pending-proposals.d.ts +4 -1
  312. package/dist/shared/pending-proposals.d.ts.map +1 -1
  313. package/dist/shared/pending-proposals.js +3 -4
  314. package/dist/shared/pending-proposals.js.map +1 -1
  315. package/dist/shared/redact-secret.d.ts +5 -5
  316. package/dist/shared/redact-secret.js +5 -5
  317. package/dist/tenancy/index.d.ts +13 -0
  318. package/dist/tenancy/index.d.ts.map +1 -0
  319. package/dist/tenancy/index.js +13 -0
  320. package/dist/tenancy/index.js.map +1 -0
  321. package/dist/tenancy/static-tenant-source.d.ts +98 -0
  322. package/dist/tenancy/static-tenant-source.d.ts.map +1 -0
  323. package/dist/tenancy/static-tenant-source.js +220 -0
  324. package/dist/tenancy/static-tenant-source.js.map +1 -0
  325. package/dist/tenancy/tenant-host.d.ts +80 -0
  326. package/dist/tenancy/tenant-host.d.ts.map +1 -0
  327. package/dist/tenancy/tenant-host.js +217 -0
  328. package/dist/tenancy/tenant-host.js.map +1 -0
  329. package/dist/tenancy/tenant-runtime.d.ts +91 -0
  330. package/dist/tenancy/tenant-runtime.d.ts.map +1 -0
  331. package/dist/tenancy/tenant-runtime.js +174 -0
  332. package/dist/tenancy/tenant-runtime.js.map +1 -0
  333. package/dist/tenancy/tenant-secrets.d.ts +24 -0
  334. package/dist/tenancy/tenant-secrets.d.ts.map +1 -0
  335. package/dist/tenancy/tenant-secrets.js +30 -0
  336. package/dist/tenancy/tenant-secrets.js.map +1 -0
  337. package/dist/tenancy/tenant-source.contract.d.ts +45 -0
  338. package/dist/tenancy/tenant-source.contract.d.ts.map +1 -0
  339. package/dist/tenancy/tenant-source.contract.js +21 -0
  340. package/dist/tenancy/tenant-source.contract.js.map +1 -0
  341. package/migrations/0000_core_init.sql +14 -14
  342. package/migrations/0003_deployment_settings.sql +1 -1
  343. package/migrations/0005_github_facade.sql +1 -1
  344. package/migrations/0012_agent_audit.sql +6 -6
  345. package/package.json +3 -3
  346. package/src/__tests__/branch-model.test.ts +7 -6
  347. package/src/__tests__/kb-context.ts +30 -0
  348. package/src/__tests__/kb-layout-config.test.ts +35 -30
  349. package/src/core/__tests__/catalog-cache-invalidation.test.ts +2 -1
  350. package/src/core/__tests__/lifecycle.test.ts +78 -1
  351. package/src/core/__tests__/public-config.test.ts +5 -1
  352. package/src/core/catalog-cache-invalidation.ts +16 -11
  353. package/src/core/core-ports.ts +19 -0
  354. package/src/core/create-core-server.ts +27 -106
  355. package/src/core/create-core-services.ts +180 -95
  356. package/src/core/lifecycle.ts +214 -29
  357. package/src/core/public-config.ts +8 -5
  358. package/src/core-config.ts +107 -8
  359. package/src/index.ts +25 -2
  360. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +2 -1
  361. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -1
  362. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -1
  363. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +2 -1
  364. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  365. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +2 -1
  366. package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -1
  367. package/src/modules/access/__tests__/access.routes.revoke.test.ts +2 -1
  368. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -1
  369. package/src/modules/access/__tests__/change-read-gate.test.ts +13 -11
  370. package/src/modules/access/__tests__/creator-access.test.ts +3 -2
  371. package/src/modules/access/__tests__/roles.routes.test.ts +2 -1
  372. package/src/modules/access/access-control.service.ts +20 -6
  373. package/src/modules/access/access.routes.ts +10 -13
  374. package/src/modules/access/change-read-gate.ts +10 -4
  375. package/src/modules/access/creator-access.ts +7 -2
  376. package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +13 -12
  377. package/src/modules/agent-instructions/read-preamble.ts +10 -12
  378. package/src/modules/auth/__tests__/account.routes.test.ts +15 -0
  379. package/src/modules/auth/__tests__/auth.service.test.ts +60 -0
  380. package/src/modules/auth/account-admission.ts +44 -0
  381. package/src/modules/auth/account.routes.ts +4 -1
  382. package/src/modules/auth/auth.service.ts +33 -1
  383. package/src/modules/auth/oidc-auth-provider.ts +9 -0
  384. package/src/modules/connection-probe/connection-probe.service.ts +7 -1
  385. package/src/modules/database/__tests__/advisory-lock.test.ts +23 -1
  386. package/src/modules/database/__tests__/connection.test.ts +98 -0
  387. package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -0
  388. package/src/modules/database/advisory-lock.ts +28 -4
  389. package/src/modules/database/connection.ts +143 -13
  390. package/src/modules/database/migrate.ts +48 -14
  391. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
  392. package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
  393. package/src/modules/kb-fs/__tests__/branch-name.test.ts +6 -6
  394. package/src/modules/kb-fs/__tests__/clone-config.test.ts +24 -20
  395. package/src/modules/kb-fs/branch-name.ts +3 -3
  396. package/src/modules/kb-fs/clone-config.ts +15 -12
  397. package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +2 -1
  398. package/src/modules/mcp/mcp.service.ts +11 -4
  399. package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +12 -11
  400. package/src/modules/plugins/__tests__/bundle-dialect.test.ts +2 -1
  401. package/src/modules/plugins/__tests__/compile-marketplace.test.ts +6 -4
  402. package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +2 -1
  403. package/src/modules/plugins/__tests__/join-requests.service.test.ts +2 -1
  404. package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +4 -3
  405. package/src/modules/plugins/__tests__/plugin-index.service.test.ts +6 -4
  406. package/src/modules/plugins/__tests__/plugin-links.service.test.ts +220 -5
  407. package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +3 -1
  408. package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +7 -6
  409. package/src/modules/plugins/__tests__/plugins.routes.test.ts +11 -2
  410. package/src/modules/plugins/__tests__/teams.routes.test.ts +2 -1
  411. package/src/modules/plugins/compile/marketplace-compiler.service.ts +7 -9
  412. package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +20 -16
  413. package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +9 -2
  414. package/src/modules/plugins/discovery/kb-plugin-source.ts +15 -8
  415. package/src/modules/plugins/discovery/native.source.ts +4 -1
  416. package/src/modules/plugins/index.ts +1 -1
  417. package/src/modules/plugins/join-request-jobs.service.ts +8 -7
  418. package/src/modules/plugins/join-requests.service.ts +7 -7
  419. package/src/modules/plugins/plugin-links.service.ts +192 -19
  420. package/src/modules/plugins/plugin-links.ts +147 -27
  421. package/src/modules/plugins/plugin-provision.service.ts +54 -27
  422. package/src/modules/plugins/plugin-rename.service.ts +10 -10
  423. package/src/modules/plugins/plugins.routes.ts +45 -15
  424. package/src/modules/plugins/plugins.service.ts +7 -11
  425. package/src/modules/plugins/teams.routes.ts +16 -8
  426. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +7 -0
  427. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +40 -0
  428. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +2 -0
  429. package/src/modules/secrets-vault/index.ts +2 -0
  430. package/src/modules/secrets-vault/secrets-variable-loader.ts +51 -21
  431. package/src/modules/secrets-vault/secrets-vault.routes.ts +7 -6
  432. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +24 -11
  433. package/src/modules/settings/__tests__/git-root-folders.test.ts +2 -1
  434. package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +2 -1
  435. package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +7 -4
  436. package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +2 -0
  437. package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +2 -0
  438. package/src/modules/settings/__tests__/setup.routes.test.ts +33 -52
  439. package/src/modules/settings/deployment-settings.service.ts +21 -20
  440. package/src/modules/settings/setup.routes.ts +26 -16
  441. package/src/modules/skills/__tests__/allowed-tools-check.test.ts +11 -10
  442. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +4 -3
  443. package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -1
  444. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +2 -1
  445. package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +2 -1
  446. package/src/modules/skills/__tests__/skills.service.test.ts +3 -2
  447. package/src/modules/skills/allowed-tools-check.ts +7 -6
  448. package/src/modules/skills/pending-skills.service.ts +9 -8
  449. package/src/modules/skills/skill-access-requests.routes.ts +7 -7
  450. package/src/modules/skills/skills.routes.ts +4 -3
  451. package/src/modules/skills/skills.service.ts +13 -9
  452. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +3 -2
  453. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -2
  454. package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +17 -12
  455. package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
  456. package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +4 -1
  457. package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +2 -1
  458. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +2 -1
  459. package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +5 -4
  460. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +2 -1
  461. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +4 -2
  462. package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +13 -5
  463. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -1
  464. package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +9 -1
  465. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +3 -2
  466. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +2 -0
  467. package/src/modules/tool-manuals/mcp-json-discovery.ts +6 -4
  468. package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -11
  469. package/src/modules/tool-manuals/pending-tools.service.ts +19 -16
  470. package/src/modules/tool-manuals/tool-delete.service.ts +13 -10
  471. package/src/modules/tool-manuals/tool-manuals.routes.ts +10 -8
  472. package/src/modules/tool-manuals/tool-manuals.service.ts +15 -13
  473. package/src/modules/tool-manuals/tool-manuals.tools.ts +7 -6
  474. package/src/modules/workflow/__tests__/apply-failure.test.ts +2 -1
  475. package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +14 -26
  476. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +2 -1
  477. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +3 -2
  478. package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +2 -1
  479. package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +3 -10
  480. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +2 -1
  481. package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +3 -10
  482. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +28 -27
  483. package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +2 -1
  484. package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +2 -1
  485. package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +3 -2
  486. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +2 -1
  487. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +5 -4
  488. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +2 -1
  489. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +2 -1
  490. package/src/modules/workflow/agent-tools/workflow.tools.ts +11 -9
  491. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +5 -4
  492. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +12 -11
  493. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +9 -8
  494. package/src/modules/workflow/git/__tests__/git.service.commitFile.strayPath.test.ts +8 -7
  495. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +6 -5
  496. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +3 -2
  497. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +3 -2
  498. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +7 -6
  499. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +16 -15
  500. package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -2
  501. package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +2 -1
  502. package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +2 -1
  503. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +10 -9
  504. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +2 -1
  505. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +6 -5
  506. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +9 -8
  507. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +2 -1
  508. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +4 -3
  509. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +9 -8
  510. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +2 -1
  511. package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -1
  512. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +4 -3
  513. package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +8 -7
  514. package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +41 -3
  515. package/src/modules/workflow/git/git.service.ts +24 -13
  516. package/src/modules/workflow/git/node-git-runner.ts +37 -4
  517. package/src/modules/workflow/review-workflow/review-workflow.service.ts +9 -6
  518. package/src/modules/workflow/session-ontology.service.ts +7 -2
  519. package/src/modules/workflow/workflow.service.ts +31 -24
  520. package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -2
  521. package/src/modules/workspace/__tests__/git-internals.security.test.ts +10 -9
  522. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +4 -2
  523. package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
  524. package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +2 -1
  525. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +2 -1
  526. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +2 -1
  527. package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +2 -1
  528. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -1
  529. package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +2 -1
  530. package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +5 -4
  531. package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +2 -1
  532. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +2 -1
  533. package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
  534. package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -5
  535. package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
  536. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
  537. package/src/modules/workspace/__tests__/workspace.service.test.ts +84 -50
  538. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +2 -1
  539. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -7
  540. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +4 -3
  541. package/src/modules/workspace/__tests__/workspace.tools.test.ts +9 -8
  542. package/src/modules/workspace/__tests__/write-denial.test.ts +5 -4
  543. package/src/modules/workspace/session-ontology.gate.ts +6 -4
  544. package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +6 -2
  545. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +29 -21
  546. package/src/modules/workspace/startup/kb-git.ts +15 -22
  547. package/src/modules/workspace/startup/kb-startup-runner.ts +40 -46
  548. package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +104 -98
  549. package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +24 -16
  550. package/src/modules/workspace/startup/steps/personal-spaces.step.ts +14 -5
  551. package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +13 -5
  552. package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +14 -5
  553. package/src/modules/workspace/startup/steps/seed-tree.ts +11 -9
  554. package/src/modules/workspace/startup/steps/template-files.step.ts +43 -34
  555. package/src/modules/workspace/startup/steps/template-source.ts +8 -5
  556. package/src/modules/workspace/workspace.routes.ts +8 -7
  557. package/src/modules/workspace/workspace.service.ts +30 -27
  558. package/src/modules/workspace/workspace.tools.ts +21 -20
  559. package/src/modules/workspace/write-denial.ts +7 -5
  560. package/src/shared/__tests__/kb-layout.plugin.test.ts +19 -16
  561. package/src/shared/git.contract.ts +70 -8
  562. package/src/shared/kb-context.ts +130 -0
  563. package/src/shared/kb-layout.test.ts +37 -27
  564. package/src/shared/kb-layout.ts +4 -3
  565. package/src/shared/pending-proposals.ts +7 -4
  566. package/src/shared/redact-secret.ts +5 -5
  567. package/src/tenancy/__tests__/static-tenant-source.test.ts +177 -0
  568. package/src/tenancy/__tests__/tenant-host.test.ts +372 -0
  569. package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -0
  570. package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -0
  571. package/src/tenancy/index.ts +35 -0
  572. package/src/tenancy/static-tenant-source.ts +296 -0
  573. package/src/tenancy/tenant-host.ts +261 -0
  574. package/src/tenancy/tenant-runtime.ts +208 -0
  575. package/src/tenancy/tenant-secrets.ts +41 -0
  576. package/src/tenancy/tenant-source.contract.ts +59 -0
@@ -26,9 +26,8 @@ import {
26
26
  assertValidRelativePath,
27
27
  isBranchAuthoredBy,
28
28
  isOwnSuggestionsBranch,
29
- isProtectedBranch,
30
- PROTECTED_BRANCHES,
31
29
  } from '../../kb-fs/branch-name.js';
30
+ import type { KbContext } from '../../../shared/kb-context.js';
32
31
  import {
33
32
  BranchAuthorshipError,
34
33
  WorkflowDomainError,
@@ -42,6 +41,7 @@ import {
42
41
  GitRunError,
43
42
  isGitTimeout,
44
43
  redactGitToken,
44
+ type GitCredentials,
45
45
  type GitRunOptions,
46
46
  type GitRunResult,
47
47
  type IGitRunner,
@@ -296,7 +296,7 @@ export class GitService implements IGitService {
296
296
  * safe because validation is advisory and never blocks a commit.
297
297
  */
298
298
  private readonly hooks: WorkflowHooks,
299
- private readonly kbDirName: string,
299
+ private readonly kb: KbContext,
300
300
  private readonly mutex: WorkspaceMutex = new WorkspaceMutex(),
301
301
  private readonly accessControl: IAccessControl | null = null,
302
302
  /**
@@ -309,6 +309,18 @@ export class GitService implements IGitService {
309
309
  private readonly gitRunner: IGitRunner = new NodeGitRunner(),
310
310
  ) {}
311
311
 
312
+ private get kbDirName(): string {
313
+ return this.kb.kbDirName;
314
+ }
315
+
316
+ /**
317
+ * The credentials the runner authenticates with — for the services above
318
+ * this one that scrub a message git or the host echoed a token into.
319
+ */
320
+ get credentials(): GitCredentials {
321
+ return this.gitRunner.credentials;
322
+ }
323
+
312
324
  /**
313
325
  * "Does the pending-commits queue hold rows for this workspace?" — used by
314
326
  * `statusInternal` to tell an expected dirty tree (queued saves still
@@ -552,7 +564,7 @@ export class GitService implements IGitService {
552
564
  );
553
565
  infos[i] = {
554
566
  name: row.shortName,
555
- isProtected: isProtectedBranch(row.shortName),
567
+ isProtected: this.kb.isProtectedBranch(row.shortName),
556
568
  ahead,
557
569
  behind,
558
570
  hasRemote: row.hasRemote,
@@ -655,7 +667,7 @@ export class GitService implements IGitService {
655
667
  fromBase?: string,
656
668
  ): Promise<BranchInfo> {
657
669
  assertValidBranchName(name);
658
- if (isProtectedBranch(name)) {
670
+ if (this.kb.isProtectedBranch(name)) {
659
671
  throw new ProtectedBranchError(name, 'creating a protected branch');
660
672
  }
661
673
  if (fromBase) assertValidBranchName(fromBase);
@@ -731,7 +743,7 @@ export class GitService implements IGitService {
731
743
  opts: { onlyIfNoRemote?: boolean; systemCleanup?: boolean } = {},
732
744
  ): Promise<void> {
733
745
  assertValidBranchName(name);
734
- if (isProtectedBranch(name)) {
746
+ if (this.kb.isProtectedBranch(name)) {
735
747
  throw new ProtectedBranchError(name, 'deleting a protected branch');
736
748
  }
737
749
  return this.mutex.run(workspaceId, async () => {
@@ -895,7 +907,7 @@ export class GitService implements IGitService {
895
907
  // boundary. Without this guard, the standard "fork to draft then
896
908
  // propose" workflow would 403 for non-admins — they can't write
897
909
  // protected, can't write the draft they forked from it either.
898
- if (isProtectedBranch(branch)) {
910
+ if (this.kb.isProtectedBranch(branch)) {
899
911
  // Gate against the access tree as it exists at HEAD — the pre-commit
900
912
  // state. Reading from the working tree would let the user broaden
901
913
  // their own access by editing access.md alongside the change they're
@@ -1172,7 +1184,7 @@ export class GitService implements IGitService {
1172
1184
  // Protected-branch access gate (defence in depth — callers already gate at
1173
1185
  // lock-acquire / upload-mint, but this primitive is generic). Gate every
1174
1186
  // touched path against the access tree at HEAD, like `commit()`.
1175
- if (isProtectedBranch(branch)) {
1187
+ if (this.kb.isProtectedBranch(branch)) {
1176
1188
  await this.assertCanWriteAtRef(workspaceId, 'HEAD', user.email, touched);
1177
1189
  }
1178
1190
 
@@ -1292,7 +1304,7 @@ export class GitService implements IGitService {
1292
1304
  // decided the write is legitimate (unused name, exclusive create);
1293
1305
  // gating it here again just refuses every non-admin the product
1294
1306
  // promised a plugin to.
1295
- if (isProtectedBranch(branch) && !opts?.systemAuthorized) {
1307
+ if (this.kb.isProtectedBranch(branch) && !opts?.systemAuthorized) {
1296
1308
  const touched = await this.unpushedTouchedPaths(cwd);
1297
1309
  await this.assertCanWriteAtRef(
1298
1310
  workspaceId,
@@ -1542,6 +1554,7 @@ export class GitService implements IGitService {
1542
1554
  throw new Error(
1543
1555
  `git merge failed without detectable conflicts: ${redactGitToken(
1544
1556
  err instanceof Error ? err.message : String(err),
1557
+ this.credentials.token(),
1545
1558
  )}`,
1546
1559
  );
1547
1560
  }
@@ -2109,7 +2122,7 @@ export class GitService implements IGitService {
2109
2122
  return this.mutex.run(workspaceId, async () => {
2110
2123
  const cwd = await this.repoDir(workspaceId);
2111
2124
  let best: { base: string; ahead: number } | null = null;
2112
- for (const p of PROTECTED_BRANCHES) {
2125
+ for (const p of this.kb.protectedBranches) {
2113
2126
  if (p === branch) continue;
2114
2127
  const res = await this.tryAheadBehind(cwd, branch, `origin/${p}`);
2115
2128
  if (res && (best === null || res.ahead < best.ahead)) {
@@ -3133,7 +3146,7 @@ export class GitService implements IGitService {
3133
3146
  }
3134
3147
 
3135
3148
  let best: { ahead: number; behind: number } | null = null;
3136
- for (const p of PROTECTED_BRANCHES) {
3149
+ for (const p of this.kb.protectedBranches) {
3137
3150
  if (p === shortName) continue;
3138
3151
  const res = await this.tryAheadBehind(cwd, ref, `refs/remotes/origin/${p}`);
3139
3152
  if (res && (best === null || res.ahead < best.ahead)) best = res;
@@ -3447,5 +3460,3 @@ export function parseNumstatZ(out: string): NumstatEntry[] {
3447
3460
  }
3448
3461
  return entries;
3449
3462
  }
3450
-
3451
- export { PROTECTED_BRANCHES };
@@ -1,7 +1,10 @@
1
1
  import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process';
2
2
  import {
3
+ GIT_TOKEN_ENV,
3
4
  GitRunError,
5
+ NO_GIT_CREDENTIALS,
4
6
  redactGitToken,
7
+ type GitCredentials,
5
8
  type GitRunOptions,
6
9
  type GitRunResult,
7
10
  type IGitRunner,
@@ -212,7 +215,33 @@ function spawnGit(args: string[], options: SpawnOptions & { maxBuffer: number })
212
215
  * `WorkspaceMutex`'s job and stays the caller's to have done.
213
216
  */
214
217
  export class NodeGitRunner implements IGitRunner {
215
- constructor(readonly defaultTimeoutMs: number = DEFAULT_GIT_TIMEOUT_MS) {}
218
+ constructor(
219
+ readonly defaultTimeoutMs: number = DEFAULT_GIT_TIMEOUT_MS,
220
+ /**
221
+ * What every call authenticates with. The token goes into the CHILD's
222
+ * environment only (see {@link childEnv}); a runner built without one
223
+ * runs git unauthenticated, which is what a directly constructed service
224
+ * in a test gets.
225
+ */
226
+ readonly credentials: GitCredentials = NO_GIT_CREDENTIALS,
227
+ ) {}
228
+
229
+ /**
230
+ * The environment one invocation runs under. The token in effect goes in
231
+ * under {@link GIT_TOKEN_ENV}, and a stale one this process inherited from
232
+ * its own environment goes OUT: a server hosting several knowledge bases
233
+ * must never let one knowledge base's git call find another's token, or an
234
+ * operator's, lying in `process.env`. A caller's per-call entry still wins
235
+ * over the provider's (the setup probe runs with the token it is checking,
236
+ * not the one in effect), and the fixed entries win over everything.
237
+ */
238
+ private childEnv(overrides: NodeJS.ProcessEnv | undefined): NodeJS.ProcessEnv {
239
+ const env: NodeJS.ProcessEnv = { ...process.env };
240
+ delete env[GIT_TOKEN_ENV];
241
+ const token = this.credentials.token();
242
+ if (token) env[GIT_TOKEN_ENV] = token;
243
+ return { ...env, ...overrides, ...FIXED_ENV };
244
+ }
216
245
 
217
246
  run(cwd: string, args: string[], opts: GitRunOptions & { encoding: 'buffer' }): Promise<GitRunResult<Buffer>>;
218
247
  run(cwd: string, args: string[], opts?: GitRunOptions & { encoding?: 'utf8' }): Promise<GitRunResult>;
@@ -224,7 +253,7 @@ export class NodeGitRunner implements IGitRunner {
224
253
  try {
225
254
  const { promise: pending, child } = spawnGit(args, {
226
255
  cwd,
227
- env: { ...process.env, ...opts.env, ...FIXED_ENV },
256
+ env: this.childEnv(opts.env),
228
257
  maxBuffer: MAX_OUTPUT_BYTES,
229
258
  // Makes the child a process-group leader so that `killTree` can signal
230
259
  // the transport helpers it spawns, not just git itself. Not on Windows,
@@ -291,9 +320,13 @@ export class NodeGitRunner implements IGitRunner {
291
320
  : Buffer.isBuffer(original.stderr)
292
321
  ? original.stderr.toString()
293
322
  : undefined;
294
- throw new GitRunError(`git ${subcommand} failed: ${redactGitToken(message)}`, {
323
+ // Scrubbed with the token THIS runner handed the child, and the one a
324
+ // caller laid over it for the call: both can be echoed back by git.
325
+ const secrets = [this.credentials.token(), opts.env?.[GIT_TOKEN_ENV]];
326
+ const scrub = (text: string): string => secrets.reduce<string>((out, token) => redactGitToken(out, token), text);
327
+ throw new GitRunError(`git ${subcommand} failed: ${scrub(message)}`, {
295
328
  exitCode: typeof original.code === 'number' ? original.code : undefined,
296
- stderr: stderr === undefined ? undefined : redactGitToken(stderr),
329
+ stderr: stderr === undefined ? undefined : scrub(stderr),
297
330
  });
298
331
  } finally {
299
332
  // Every timer is cleared on every path. The later ones in particular
@@ -18,6 +18,7 @@ import { changeRequests, prComments, prFileApprovals, prMergeLog, users } from '
18
18
  import { AccessUnreadableError } from '../../access-model/access-errors.js';
19
19
  import type { IAccessControl } from '../../access/access-control.interface.js';
20
20
  import type { GitService } from '../git/git.service.js';
21
+ import { redactSecret } from '../../../shared/redact-secret.js';
21
22
  import {
22
23
  ChangeRequestConflictsError,
23
24
  WorkflowDomainError,
@@ -45,11 +46,13 @@ import {
45
46
  const MERGE_METHOD = 'merge' as const;
46
47
  const EVERYONE_CANONICAL = 'everyone';
47
48
 
48
- function redactTokens(msg: string): string {
49
- const tokens = [process.env.GITHUB_TOKEN, process.env.GH_TOKEN].filter(
50
- (t): t is string => !!t && t.length > 0,
51
- );
52
- return tokens.reduce((m, t) => m.replaceAll(t, '***'), msg);
49
+ /**
50
+ * Redact a git token from an error string before it is stored: the one the
51
+ * knowledge base's runner authenticates with, plus whatever the environment
52
+ * holds (`redactSecret` names those itself).
53
+ */
54
+ function redactTokens(msg: string, token: string | null | undefined): string {
55
+ return redactSecret(msg, [token]);
53
56
  }
54
57
 
55
58
  class CommentAuthError extends WorkflowDomainError {
@@ -743,7 +746,7 @@ export class ReviewWorkflowService implements IReviewWorkflowService {
743
746
  user,
744
747
  );
745
748
  } catch (err) {
746
- const redacted = redactTokens(err instanceof Error ? err.message : String(err));
749
+ const redacted = redactTokens(err instanceof Error ? err.message : String(err), this.git.credentials?.token());
747
750
  await this.db
748
751
  .update(prMergeLog)
749
752
  .set({ succeeded: false, completedAt: new Date(), error: redacted })
@@ -33,6 +33,7 @@
33
33
 
34
34
  import { eq, lt } from 'drizzle-orm';
35
35
  import { ontologyOf } from '../../shared/kb-layout.js';
36
+ import type { KbContext } from '../../shared/kb-context.js';
36
37
 
37
38
  import type { Database } from '../database/connection.js';
38
39
  import { sessionOntologyTouches } from '../database/schema.js';
@@ -77,7 +78,11 @@ export class SessionOntologyService implements ISessionOntologyService {
77
78
  */
78
79
  private readonly locks = new WorkspaceMutex();
79
80
 
80
- constructor(private readonly db: Database) {}
81
+ constructor(
82
+ private readonly db: Database,
83
+ /** Names the knowledge-base root a path is classified under; read per call. */
84
+ private readonly kb: Pick<KbContext, 'layout'>,
85
+ ) {}
81
86
 
82
87
  /**
83
88
  * Resolve `wsPath` to its ontology and evaluate/record the operation. Thin
@@ -89,7 +94,7 @@ export class SessionOntologyService implements ISessionOntologyService {
89
94
  isWrite: boolean,
90
95
  kbDirName?: string,
91
96
  ): Promise<OperationDecision> {
92
- return this.checkOntology(sessionId, ontologyOf(wsPath, kbDirName), isWrite);
97
+ return this.checkOntology(sessionId, ontologyOf(wsPath, this.kb.layout, kbDirName), isWrite);
93
98
  }
94
99
 
95
100
  /**
@@ -57,16 +57,16 @@ import type {
57
57
  RemoteSyncPullResult,
58
58
  } from '@bevel-software/platform-shared';
59
59
  import {
60
- isProtectedBranch,
61
- DEFAULT_BRANCH,
62
60
  isFolderPlaceholder,
63
61
  folderPlaceholderPath,
64
62
  isPlatformRestoreShape,
65
63
  } from '@bevel-software/platform-shared';
64
+ import type { KbContext } from '../../shared/kb-context.js';
66
65
  import { and, eq, inArray, isNotNull, isNull, lt, or } from 'drizzle-orm';
67
66
  import type { Database } from '../database/connection.js';
68
67
  import { changeRequests } from '../database/schema.js';
69
68
  import type { GitService } from './git/git.service.js';
69
+ import { redactSecret } from '../../shared/redact-secret.js';
70
70
  import type { PullRequestService } from './git/pull-request.service.js';
71
71
  import type { IReviewWorkflowService } from './review-workflow/review-workflow.interface.js';
72
72
  import type { WorkspaceService } from '../workspace/workspace.service.js';
@@ -156,12 +156,13 @@ export function syncConflictMessage(branch: string, conflictedPaths: string[]):
156
156
  /** How many conflicted files the sync-conflict sentence names before "and N more". */
157
157
  const SYNC_CONFLICT_FILES_NAMED = 3;
158
158
 
159
- /** Redact the shared GitHub token from any error string before surfacing it. */
160
- function redactTokens(msg: string): string {
161
- const tokens = [process.env.GITHUB_TOKEN, process.env.GH_TOKEN].filter(
162
- (t): t is string => !!t && t.length > 0,
163
- );
164
- return tokens.reduce((m, t) => m.replaceAll(t, '***'), msg);
159
+ /**
160
+ * Redact a git token from an error string before surfacing it: the one the
161
+ * knowledge base's runner authenticates with, plus whatever the environment
162
+ * holds (`redactSecret` names those itself).
163
+ */
164
+ function redactTokens(msg: string, token: string | null | undefined): string {
165
+ return redactSecret(msg, [token]);
165
166
  }
166
167
 
167
168
  /**
@@ -275,6 +276,10 @@ export class WorkflowService implements IWorkflowService {
275
276
  * implementation detail of the workflow auto-merge story; nothing outside
276
277
  * the facade should call it directly.
277
278
  */
279
+ private get kbDirName(): string {
280
+ return this.kb.kbDirName;
281
+ }
282
+
278
283
  constructor(
279
284
  private readonly db: Database,
280
285
  private readonly git: GitService,
@@ -291,7 +296,7 @@ export class WorkflowService implements IWorkflowService {
291
296
  * See `lock-decoupling-plan.md` for the full design.
292
297
  */
293
298
  private readonly pendingCommits: PendingCommitsService,
294
- private readonly kbDirName: string,
299
+ private readonly kb: KbContext,
295
300
  /**
296
301
  * The read-before-write gate `acquireLock` asks on every branch (see
297
302
  * `access-model/change-gate.ts`). Required, and checked at construction:
@@ -419,7 +424,7 @@ export class WorkflowService implements IWorkflowService {
419
424
  fn: () => Promise<T>,
420
425
  ): Promise<T> {
421
426
  const keys = [`branch:${source}`];
422
- if (!isProtectedBranch(target)) keys.push(`branch:${target}`);
427
+ if (!this.kb.isProtectedBranch(target)) keys.push(`branch:${target}`);
423
428
  return this.branchLifecycle.runAll(keys, fn);
424
429
  }
425
430
 
@@ -573,8 +578,9 @@ export class WorkflowService implements IWorkflowService {
573
578
  */
574
579
  private async pullWorkspace(workspaceId: string): Promise<boolean> {
575
580
  const { treeChanged } = await this.git.pull(workspaceId);
576
- if (treeChanged && branchForWorkspaceId(workspaceId) === DEFAULT_BRANCH) {
577
- this.events?.emit({ kind: 'fs-tree-changed', workspaceId, branch: DEFAULT_BRANCH });
581
+ const defaultBranch = this.kb.defaultBranch;
582
+ if (treeChanged && branchForWorkspaceId(workspaceId) === defaultBranch) {
583
+ this.events?.emit({ kind: 'fs-tree-changed', workspaceId, branch: defaultBranch });
578
584
  return true;
579
585
  }
580
586
  return false;
@@ -961,7 +967,7 @@ export class WorkflowService implements IWorkflowService {
961
967
  // future caller can make that claim by passing a flag.
962
968
  if (
963
969
  typeof platformRestore?.source === 'string' &&
964
- isPlatformRestoreShape(toRepoRelative(platformRestore.source), repoRelative) &&
970
+ isPlatformRestoreShape(toRepoRelative(platformRestore.source), repoRelative, this.kb.layout) &&
965
971
  (await this.accessControl.canRestorePlatformFile(workspaceId, userEmail, repoRelative))
966
972
  ) {
967
973
  return 'restore';
@@ -1037,7 +1043,7 @@ export class WorkflowService implements IWorkflowService {
1037
1043
  // coordination hold as write possession (see those methods).
1038
1044
  if (!opts?.coordination) {
1039
1045
  let via: 'granted' | 'restore' = 'granted';
1040
- if (isProtectedBranch(branch)) {
1046
+ if (this.kb.isProtectedBranch(branch)) {
1041
1047
  // `assertCanWriteAtPath` throws AccessDeniedError on denial, with the
1042
1048
  // eligible-writers payload so the frontend can render a useful refusal.
1043
1049
  via = await this.assertCanWriteAtPath(
@@ -1321,7 +1327,8 @@ export class WorkflowService implements IWorkflowService {
1321
1327
  branch: string,
1322
1328
  targetPath: string,
1323
1329
  user: AuthUser,
1324
- opts?: { systemAuthorized?: boolean; skipValidation?: boolean },
1330
+ /** `summary` overrides the path-derived commit subject; see `commitFile`. */
1331
+ opts?: { systemAuthorized?: boolean; skipValidation?: boolean; summary?: string },
1325
1332
  ): Promise<void> {
1326
1333
  // `skipValidation` is the worker telling us this commit is not the last of
1327
1334
  // a burst. The validator is advisory — it parses the whole KB to produce a
@@ -1332,7 +1339,7 @@ export class WorkflowService implements IWorkflowService {
1332
1339
  workspaceId,
1333
1340
  user,
1334
1341
  targetPath,
1335
- undefined,
1342
+ opts?.summary,
1336
1343
  opts?.skipValidation,
1337
1344
  );
1338
1345
  if (!change) {
@@ -1759,7 +1766,7 @@ export class WorkflowService implements IWorkflowService {
1759
1766
  throw new WorkflowValidationError('source and target branches must differ');
1760
1767
  }
1761
1768
  if (!input.title?.trim()) throw new WorkflowValidationError('title is required');
1762
- if (isProtectedBranch(input.sourceBranch)) {
1769
+ if (this.kb.isProtectedBranch(input.sourceBranch)) {
1763
1770
  throw new WorkflowValidationError(
1764
1771
  `Cannot open a change request *from* a protected branch ("${input.sourceBranch}").`,
1765
1772
  { kind: 'source-is-protected', sourceBranch: input.sourceBranch },
@@ -1897,7 +1904,7 @@ export class WorkflowService implements IWorkflowService {
1897
1904
  // up-to-date) auto-merge, and inserts the row.
1898
1905
  const rawMsg = err instanceof Error ? err.message : String(err);
1899
1906
  throw new WorkflowValidationError(
1900
- `Failed to open change request: ${redactTokens(rawMsg)}`,
1907
+ `Failed to open change request: ${redactTokens(rawMsg, this.git.credentials?.token())}`,
1901
1908
  { kind: 'open-change-request-failed' },
1902
1909
  );
1903
1910
  }
@@ -2851,7 +2858,7 @@ export class WorkflowService implements IWorkflowService {
2851
2858
 
2852
2859
  let live: Set<string>;
2853
2860
  try {
2854
- const branches = await this.git.listBranches(workspaceIdForBranch(DEFAULT_BRANCH), {
2861
+ const branches = await this.git.listBranches(this.kb.defaultWorkspaceId(), {
2855
2862
  freshFetch: true,
2856
2863
  // The list is used to PROVE absence, and the listing's normal
2857
2864
  // degrade-to-stale behaviour would report every branch created since
@@ -3166,8 +3173,8 @@ export class WorkflowService implements IWorkflowService {
3166
3173
  // outright if it disagrees with the request's own base.) The failure the
3167
3174
  // pull reports is about OTHER people's commits not arriving, which leaves
3168
3175
  // the catalogs no staler than they were.
3169
- if (!announced && targetWorkspaceId && targetBranch === DEFAULT_BRANCH) {
3170
- this.events?.emit({ kind: 'fs-tree-changed', workspaceId: targetWorkspaceId, branch: DEFAULT_BRANCH });
3176
+ if (!announced && targetWorkspaceId && targetBranch === this.kb.defaultBranch) {
3177
+ this.events?.emit({ kind: 'fs-tree-changed', workspaceId: targetWorkspaceId, branch: targetBranch });
3171
3178
  }
3172
3179
  }
3173
3180
 
@@ -3234,7 +3241,7 @@ export class WorkflowService implements IWorkflowService {
3234
3241
  // change request's merge, nothing strips it here — so its presence
3235
3242
  // is what the hook refuses on) and both sides of a rename, since the
3236
3243
  // old name is a file this merge deletes.
3237
- authorize: isProtectedBranch(targetBranch)
3244
+ authorize: this.kb.isProtectedBranch(targetBranch)
3238
3245
  ? async ({ sha, changedPaths }) => {
3239
3246
  if (changedPaths.length === 0) return;
3240
3247
  // roles.yaml never changes through a merge. A change request's
@@ -3445,7 +3452,7 @@ export class WorkflowService implements IWorkflowService {
3445
3452
  .where(eq(changeRequests.number, number))
3446
3453
  .limit(1);
3447
3454
  const sourceBranch = rows[0]?.sourceBranch;
3448
- if (!sourceBranch || isProtectedBranch(sourceBranch)) return;
3455
+ if (!sourceBranch || this.kb.isProtectedBranch(sourceBranch)) return;
3449
3456
  // The open-check and the deletion hold the branch's lifecycle lock
3450
3457
  // TOGETHER — `openChangeRequest` holds the same lock across its own
3451
3458
  // check-then-insert, so a request being opened from this branch either
@@ -3620,7 +3627,7 @@ export class WorkflowService implements IWorkflowService {
3620
3627
  return stdout.split('\n').map((s) => s.trim()).filter(Boolean);
3621
3628
  } catch (err) {
3622
3629
  log.warn('listChangedPathsBetweenBranches failed:', {
3623
- detail: redactTokens(err instanceof Error ? err.message : String(err)),
3630
+ detail: redactTokens(err instanceof Error ? err.message : String(err), this.git.credentials?.token()),
3624
3631
  });
3625
3632
  return [];
3626
3633
  }
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
4
4
  import { dirname, join } from 'node:path';
5
5
  import express from 'express';
6
6
  import { afterAll, beforeAll, describe, expect, it } from 'vitest';
7
+ import { testKbContext } from '../../../__tests__/kb-context.js';
7
8
  import { LocalFilesystem } from '@mastra/core/workspace';
8
9
  import { ToolRegistry } from '../../tool-registry/tool-registry.js';
9
10
  import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
@@ -86,8 +87,8 @@ beforeAll(async () => {
86
87
  new SpillStore(join(tmpdir(), 'bevel-test-spills')),
87
88
  new DocExtractService(docCache),
88
89
  service,
89
- KB,
90
- { service: {} as never, enabled: false, kbDirName: KB, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
90
+ testKbContext({ kbDirName: KB }),
91
+ { service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
91
92
  new RoutineWritePolicyService(),
92
93
  {} as never,
93
94
  );
@@ -6,6 +6,7 @@ import { join } from 'node:path';
6
6
  import AdmZip from 'adm-zip';
7
7
  import express from 'express';
8
8
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
9
+ import { testKbContext } from '../../../__tests__/kb-context.js';
9
10
  import type { IWorkflowService } from '@bevel-software/platform-shared';
10
11
  import { GIT_INTERNALS_MESSAGE, GitInternalsError } from '../../../shared/domain-errors.js';
11
12
  import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
@@ -241,7 +242,7 @@ describe('workspace tools refuse the git folder', () => {
241
242
 
242
243
  beforeEach(async () => {
243
244
  workflow = makeWorkflow();
244
- const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
245
+ const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
245
246
  unzipSpy = vi.spyOn(service, 'unzipFile');
246
247
  bootstrappedSpy = vi.spyOn(service, 'hasBootstrappedWorkspace');
247
248
  const lockingFs = new LockingFilesystem(
@@ -275,8 +276,8 @@ describe('workspace tools refuse the git folder', () => {
275
276
  new SpillStore(join(root, 'spills')),
276
277
  new DocExtractService(join(root, 'doc-cache')),
277
278
  allowAll,
278
- KB,
279
- { service: {} as never, enabled: false, kbDirName: KB, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
279
+ testKbContext({ kbDirName: KB }),
280
+ { service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
280
281
  new RoutineWritePolicyService(),
281
282
  {} as never,
282
283
  );
@@ -416,7 +417,7 @@ describe('workspace routes refuse the git folder', () => {
416
417
 
417
418
  beforeEach(async () => {
418
419
  workflow = makeWorkflow();
419
- service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
420
+ service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
420
421
  const app = express();
421
422
  app.use(express.json());
422
423
  app.use('/api', (req, _res, next) => {
@@ -436,7 +437,7 @@ describe('workspace routes refuse the git folder', () => {
436
437
  workflow as unknown as IWorkflowService,
437
438
  { emit: vi.fn() } as unknown as WorkflowEventBus,
438
439
  allowAll,
439
- KB,
440
+ testKbContext({ kbDirName: KB }),
440
441
  stubCreatorAccess,
441
442
  { isAdmin: async () => true } as unknown as IAdminAccessService,
442
443
  new NodeFs(),
@@ -563,7 +564,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
563
564
  let service: WorkspaceService;
564
565
 
565
566
  beforeEach(() => {
566
- service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
567
+ service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
567
568
  });
568
569
 
569
570
  afterEach(async () => {
@@ -620,7 +621,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
620
621
  return { stdout: '.git\n', stderr: '', code: 0 };
621
622
  }),
622
623
  };
623
- const refService = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs(), 'x-access-token', gitRunner as never);
624
+ const refService = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs(), gitRunner as never);
624
625
 
625
626
  for (const [form, raw] of Object.entries(fileForms('config'))) {
626
627
  if (!form.startsWith('symlinked')) continue;
@@ -674,7 +675,7 @@ describe('the route guard on its own', () => {
674
675
  beforeEach(async () => {
675
676
  reached = 0;
676
677
  userId = USER.id;
677
- const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
678
+ const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
678
679
  const app = express();
679
680
  // The server's own order: the guard ahead of the body parser, then again
680
681
  // on the parsed body, then again once the caller is known.
@@ -774,7 +775,7 @@ describe('DiffService refuses the git folder on its own', () => {
774
775
  let diffService: DiffService;
775
776
 
776
777
  beforeEach(() => {
777
- const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
778
+ const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
778
779
  diffService = new DiffService(service, new WorkspaceMutex(), root, join(root, 'backups'), KB, new NodeFs());
779
780
  });
780
781
 
@@ -11,8 +11,10 @@ import type { ToolContext } from '../../tool-helpers/tool.contract.js';
11
11
  import type { ISessionOntologyService, OperationDecision } from '../../workflow/session-ontology.service.js';
12
12
  import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
13
13
  import { ontologyOf } from '../../../shared/kb-layout.js';
14
+ import { testKbContext } from '../../../__tests__/kb-context.js';
14
15
 
15
16
  const KB = 'knowledge-base';
17
+ const kbContext = testKbContext({ kbDirName: KB });
16
18
  const P_FILE = 'KnowledgeBase/Product/Knowledge/Foo.md';
17
19
  const PL_FILE = 'KnowledgeBase/Platform/Knowledge/Bar.md';
18
20
  const NEUTRAL = 'access.md';
@@ -28,7 +30,7 @@ function makeFakeService(): ISessionOntologyService {
28
30
  const setFor = (s: string) => touched.get(s) ?? new Set<string>();
29
31
  return {
30
32
  async checkOperation(sessionId, wsPath, isWrite): Promise<OperationDecision> {
31
- const ont = ontologyOf(wsPath, KB);
33
+ const ont = ontologyOf(wsPath, kbContext.layout, KB);
32
34
  const set = setFor(sessionId);
33
35
  if (ont === null) return { allow: true, touched: [...set].sort() };
34
36
  if (isWrite) {
@@ -63,7 +65,7 @@ function makeFakeService(): ISessionOntologyService {
63
65
  function makeGate(): SessionOntologyGate {
64
66
  const service = makeFakeService();
65
67
  const hooks = new WorkflowHooks();
66
- return { service, enabled: true, kbDirName: KB, recoveryBotEmail: RECOVERY_EMAIL, hooks };
68
+ return { service, enabled: true, kb: kbContext, recoveryBotEmail: RECOVERY_EMAIL, hooks };
67
69
  }
68
70
 
69
71
  function ctx(overrides: Partial<ToolContext> = {}): ToolContext {
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'node:url';
7
7
  import AdmZip from 'adm-zip';
8
8
  import express from 'express';
9
9
  import { describe, it, expect, afterEach, vi } from 'vitest';
10
+ import { testKbContext } from '../../../__tests__/kb-context.js';
10
11
  import type { IWorkflowService } from '@bevel-software/platform-shared';
11
12
  import { NodeFs } from '../../kb-fs/node-fs.js';
12
13
  import type { IAccessControl } from '../../access/access-control.interface.js';
@@ -55,7 +56,7 @@ async function makeHarness(): Promise<Harness> {
55
56
  const workspaceDir = path.join(root, workspaceId);
56
57
  // The inner `.git` lets the service accept the workspace without cloning.
57
58
  await fs.mkdir(path.join(workspaceDir, KB, '.git'), { recursive: true });
58
- const workspaceService = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
59
+ const workspaceService = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
59
60
  await workspaceService.getWorkspacePath(workspaceId);
60
61
 
61
62
  const asked: string[] = [];
@@ -102,7 +103,7 @@ async function makeHarness(): Promise<Harness> {
102
103
  workflowService,
103
104
  { emit: vi.fn() } as unknown as WorkflowEventBus,
104
105
  accessControl,
105
- KB,
106
+ testKbContext({ kbDirName: KB }),
106
107
  stubCreatorAccess,
107
108
  { isAdmin: async () => false } as unknown as IAdminAccessService,
108
109
  new NodeFs(),
@@ -2,6 +2,7 @@ import type { Server } from 'node:http';
2
2
  import type { AddressInfo } from 'node:net';
3
3
  import express from 'express';
4
4
  import { describe, it, expect, afterEach, vi } from 'vitest';
5
+ import { testKbContext } from '../../../__tests__/kb-context.js';
5
6
  import { NodeFs } from '../../kb-fs/node-fs.js';
6
7
  import type { FileTreeEntry, IWorkflowService } from '@bevel-software/platform-shared';
7
8
  import type { IAccessControl } from '../../access/access-control.interface.js';
@@ -55,7 +56,7 @@ async function makeHarness(
55
56
  {} as unknown as IWorkflowService,
56
57
  { emit: vi.fn() } as unknown as WorkflowEventBus,
57
58
  accessControl,
58
- 'knowledge-base',
59
+ testKbContext(),
59
60
  stubCreatorAccess,
60
61
  { isAdmin: async () => false } as unknown as IAdminAccessService,
61
62
  new NodeFs(),
@@ -2,6 +2,7 @@ import type { Server } from 'node:http';
2
2
  import type { AddressInfo } from 'node:net';
3
3
  import express from 'express';
4
4
  import { describe, it, expect, afterEach, vi } from 'vitest';
5
+ import { testKbContext } from '../../../__tests__/kb-context.js';
5
6
  import { NodeFs } from '../../kb-fs/node-fs.js';
6
7
  import type { IWorkflowService } from '@bevel-software/platform-shared';
7
8
  import type { IAccessControl } from '../../access/access-control.interface.js';
@@ -99,7 +100,7 @@ async function makeHarness(opts: { extracted?: string[]; changeGate?: IChangeRea
99
100
  workflowService,
100
101
  eventBus,
101
102
  {} as unknown as IAccessControl,
102
- KB,
103
+ testKbContext({ kbDirName: KB }),
103
104
  creatorAccess as unknown as ICreatorAccess,
104
105
  // Not exercised here — only `.bevelignore`'s tree visibility consults it.
105
106
  { isAdmin: async () => false } as unknown as IAdminAccessService,
@@ -5,6 +5,7 @@ import path from 'node:path';
5
5
  import os from 'node:os';
6
6
  import express from 'express';
7
7
  import { describe, it, expect, afterEach, vi } from 'vitest';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
  import { NodeFs } from '../../kb-fs/node-fs.js';
9
10
  import type { IWorkflowService } from '@bevel-software/platform-shared';
10
11
  import type { IAccessControl } from '../../access/access-control.interface.js';
@@ -103,7 +104,7 @@ async function makeHarness(): Promise<Harness> {
103
104
  workflowService,
104
105
  eventBus,
105
106
  accessControl,
106
- KB,
107
+ testKbContext({ kbDirName: KB }),
107
108
  stubCreatorAccess,
108
109
  // Not exercised here — only `.bevelignore`'s tree visibility consults it.
109
110
  { isAdmin: async () => false } as unknown as IAdminAccessService,