@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
@@ -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';
@@ -59,15 +60,50 @@ function fileForms(name: string): Record<string, string> {
59
60
  'leading slash': `/${KB}/.git/${name}`,
60
61
  dotted: `${KB}/Notes/../.git/${name}`,
61
62
  'dot segments': `./${KB}/./.git/${name}`,
63
+ // The five families production measured answering the path rule's 400
64
+ // instead of this rule's 403 (parent-climb, dot-segment, backslash,
65
+ // climb-out, absolute). `dotted`, `dot segments` and `backslashed` above
66
+ // are three of them; these are the two the set was missing.
67
+ 'climb-out': `../${KB}/.git/${name}`,
68
+ // Production's own spelling, kept verbatim: it names a directory that
69
+ // exists on no test machine, so it is the LEXICAL half this covers.
70
+ absolute: `/app/apps/server/workspaces/main/${KB}/.git/${name}`,
71
+ // The same family pointed at this run's workspace, so the resolved half
72
+ // is exercised too — the folder it names is really there.
73
+ 'absolute, in workspace': `{{WORKSPACE_DIR}}/${KB}/.git/${name}`,
62
74
  encoded: `${KB}/%2egit/${name}`,
63
75
  'double-encoded': `${KB}/%252Egit/${name}`,
64
76
  'upper-case': `${KB}/.GIT/${name}`,
65
77
  'mixed-case': `${KB}/.Git/${name}`,
66
78
  backslashed: `${KB}\\.git\\${name}`,
67
79
  symlinked: `${KB}/gitlink/${name}`,
80
+ // A LINK into the folder, reached through each of those same five
81
+ // spellings. Nothing in these names is `.git`, so only the resolved half
82
+ // of the rule sees them — and while that half ran after the normaliser,
83
+ // every one of them was answered by the path rule instead. This is the
84
+ // shape that has now broken twice; it is spelled out per family so a
85
+ // failure names the one that regressed.
86
+ 'symlinked, parent-climb': `${KB}/Notes/../gitlink/${name}`,
87
+ 'symlinked, dot segments': `./${KB}/./gitlink/${name}`,
88
+ 'symlinked, backslashed': `${KB}\\gitlink\\${name}`,
89
+ 'symlinked, climb-out': `../${KB}/gitlink/${name}`,
90
+ 'symlinked, absolute': `{{WORKSPACE_DIR}}/${KB}/gitlink/${name}`,
91
+ 'symlinked, chained link': `${KB}/Notes/../chained/${name}`,
92
+ // A link named `..link` sitting in the WORKSPACE root: relative to the
93
+ // root this rule judges against, the spelling begins with `..`, which is
94
+ // the one shape a `startsWith('..')` climb test swallows. Spelled from
95
+ // anywhere else (`knowledge-base/..link/…`) it never begins with `..` and
96
+ // pins nothing.
97
+ 'symlinked, dotted name at the root': `..link/${name}`,
68
98
  };
69
99
  }
70
100
 
101
+ /**
102
+ * The absolute forms name the workspace on disk, which only exists once the
103
+ * temp root does — so they carry a placeholder until the test runs.
104
+ */
105
+ const resolved = (form: string): string => form.replace('{{WORKSPACE_DIR}}', workspaceDir);
106
+
71
107
  /** Every spelling of the git folder ITSELF, for the operations that take a directory. */
72
108
  const DIR_FORMS: Record<string, string> = {
73
109
  plain: `${KB}/.git`,
@@ -77,6 +113,20 @@ const DIR_FORMS: Record<string, string> = {
77
113
  'upper-case': `${KB}/.GIT`,
78
114
  symlinked: `${KB}/gitlink`,
79
115
  'symlinked, chained': `${KB}/chained`,
116
+ 'symlinked, parent-climb': `${KB}/Notes/../gitlink`,
117
+ 'symlinked, dot segments': `./${KB}/./gitlink`,
118
+ 'symlinked, backslashed': `${KB}\\gitlink`,
119
+ 'symlinked, climb-out': `../${KB}/gitlink`,
120
+ 'symlinked, absolute': `{{WORKSPACE_DIR}}/${KB}/gitlink`,
121
+ 'symlinked, dotted name at the root': `..link`,
122
+ // The folder ITSELF in the same five families the file forms carry, so every
123
+ // directory-taking operation — list, mkdir, delete, folder download, unzip
124
+ // destination — has a regression case for each of them too.
125
+ 'parent-climb': `${KB}/Notes/../.git`,
126
+ 'dot segments': `./${KB}/./.git`,
127
+ backslashed: `${KB}\\.git`,
128
+ 'climb-out': `../${KB}/.git`,
129
+ absolute: `{{WORKSPACE_DIR}}/${KB}/.git`,
80
130
  };
81
131
 
82
132
  const FILE_FORMS = { ...fileForms('config'), 'symlinked file': `${KB}/cfglink` };
@@ -107,6 +157,9 @@ beforeEach(async () => {
107
157
  await symlink('.git', join(kb, 'gitlink'));
108
158
  await symlink('.git/config', join(kb, 'cfglink'));
109
159
  await symlink('gitlink', join(kb, 'chained'));
160
+ // An ordinary name that merely BEGINS with dots — not a climb, and a link by
161
+ // that name reaches the folder like any other.
162
+ await symlink(join(KB, '.git'), join(workspaceDir, '..link'));
110
163
  const zip = new AdmZip();
111
164
  zip.addFile('extracted.md', Buffer.from('# extracted\n'));
112
165
  zip.writeZip(join(kb, 'archive.zip'));
@@ -153,28 +206,27 @@ async function listen(app: express.Express): Promise<{ server: Server; baseUrl:
153
206
  }
154
207
 
155
208
  /**
156
- * The spellings the PATH rule refuses before the git rule is ever consulted:
157
- * a `..` segment, a `.` segment below a leading `./`, a backslash. One
158
- * normaliser reads every accepted workspace path now, and it refuses these as
159
- * paths rather than as git paths — earlier, and with the 400 that says the path
160
- * could not be placed inside the repository. The git folder is unreachable
161
- * either way, which is what this file is about; only the sentence differs.
162
- */
163
- const UNSPELLABLE = new Set(['dotted', 'dot segments', 'backslashed']);
164
-
165
- /**
166
- * The refusal, whichever rule got there first. Pass the form's name and a
167
- * spelling the normaliser refuses is checked against ITS answer; leave it out
168
- * and only the git refusal will do.
209
+ * The ONE refusal, for every spelling.
210
+ *
211
+ * This used to make an exception: the path normaliser refuses a `..` segment,
212
+ * a `.` segment, a backslash and an absolute path as PATHS, and for a while
213
+ * that answer — a 400 quoting the spelling back — reached those spellings of a
214
+ * git path first. Production measured it on all thirteen file tools. The git
215
+ * rule now reads the caller's raw spelling before anything may rewrite or
216
+ * refuse it, so no form is answered by anything but the sanitized 403; the
217
+ * `form` argument is kept so a failure names the spelling that broke.
169
218
  */
170
219
  async function expectRefused(res: Response, form?: string): Promise<unknown> {
171
220
  const body = (await res.json()) as Record<string, unknown>;
172
- if (form !== undefined && UNSPELLABLE.has(form)) {
173
- expect({ status: res.status, outside: /is outside the knowledge base repository/.test(String(body.error)) }, form)
174
- .toEqual({ status: 400, outside: true });
175
- return body;
176
- }
177
- expect({ status: res.status, error: body.error }).toEqual({ status: 403, error: GIT_INTERNALS_MESSAGE });
221
+ expect(res.status, form).toBe(403);
222
+ // The WHOLE body, not a search through it: the sanitized message stands
223
+ // alone, and no field beside it can carry a spelling of the caller's path or
224
+ // a "use this instead" correction. Two shapes exist — the tool surface
225
+ // answers `{ error }`, the routes add the error's `kind` — so the one the
226
+ // answer claims is the one it is held to, exactly.
227
+ expect(body, form).toEqual(
228
+ 'kind' in body ? { kind: 'git-internals', error: GIT_INTERNALS_MESSAGE } : { error: GIT_INTERNALS_MESSAGE },
229
+ );
178
230
  return body;
179
231
  }
180
232
 
@@ -190,7 +242,7 @@ describe('workspace tools refuse the git folder', () => {
190
242
 
191
243
  beforeEach(async () => {
192
244
  workflow = makeWorkflow();
193
- 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());
194
246
  unzipSpy = vi.spyOn(service, 'unzipFile');
195
247
  bootstrappedSpy = vi.spyOn(service, 'hasBootstrappedWorkspace');
196
248
  const lockingFs = new LockingFilesystem(
@@ -224,8 +276,8 @@ describe('workspace tools refuse the git folder', () => {
224
276
  new SpillStore(join(root, 'spills')),
225
277
  new DocExtractService(join(root, 'doc-cache')),
226
278
  allowAll,
227
- KB,
228
- { 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() },
229
281
  new RoutineWritePolicyService(),
230
282
  {} as never,
231
283
  );
@@ -276,14 +328,15 @@ describe('workspace tools refuse the git folder', () => {
276
328
  for (const [op, args] of fileOps) {
277
329
  const tool = op.split(' ')[0];
278
330
  describe(op, () => {
279
- it.each(Object.entries(FILE_FORMS))('%s form', async (form, p) => {
331
+ it.each(Object.entries(FILE_FORMS))('%s form', async (form, raw) => {
332
+ const p = resolved(raw);
280
333
  await expectRefused(await call(tool, args(p)), form);
281
334
  });
282
335
 
283
336
  it('answers a missing path exactly as an existing one', async () => {
284
337
  for (const form of Object.keys(MISSING_FORMS)) {
285
- const existing = await call(tool, args(fileForms('config')[form]));
286
- const missing = await call(tool, args(MISSING_FORMS[form]));
338
+ const existing = await call(tool, args(resolved(fileForms('config')[form])));
339
+ const missing = await call(tool, args(resolved(MISSING_FORMS[form])));
287
340
  expect(missing.status, form).toBe(existing.status);
288
341
  // Compared with the file name put back. A spelling the PATH rule
289
342
  // refuses is answered on the spelling alone, and that answer QUOTES
@@ -301,7 +354,8 @@ describe('workspace tools refuse the git folder', () => {
301
354
 
302
355
  for (const [op, args] of dirOps) {
303
356
  const tool = op.split(' ')[0];
304
- it.each(Object.entries(DIR_FORMS))(`${op} — %s form`, async (form, p) => {
357
+ it.each(Object.entries(DIR_FORMS))(`${op} — %s form`, async (form, raw) => {
358
+ const p = resolved(raw);
305
359
  await expectRefused(await call(tool, args(p)), form);
306
360
  });
307
361
  }
@@ -363,7 +417,7 @@ describe('workspace routes refuse the git folder', () => {
363
417
 
364
418
  beforeEach(async () => {
365
419
  workflow = makeWorkflow();
366
- 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());
367
421
  const app = express();
368
422
  app.use(express.json());
369
423
  app.use('/api', (req, _res, next) => {
@@ -383,7 +437,7 @@ describe('workspace routes refuse the git folder', () => {
383
437
  workflow as unknown as IWorkflowService,
384
438
  { emit: vi.fn() } as unknown as WorkflowEventBus,
385
439
  allowAll,
386
- KB,
440
+ testKbContext({ kbDirName: KB }),
387
441
  stubCreatorAccess,
388
442
  { isAdmin: async () => true } as unknown as IAdminAccessService,
389
443
  new NodeFs(),
@@ -444,14 +498,15 @@ describe('workspace routes refuse the git folder', () => {
444
498
  // No form passed: on this surface the git guard is mounted ahead of every
445
499
  // handler on the `/workspace/:id` prefix, so it answers before the
446
500
  // normaliser is ever asked — the one 403, in every spelling, as before.
447
- it.each(Object.entries(FILE_FORMS))('%s form', async (_form, p) => {
501
+ it.each(Object.entries(FILE_FORMS))('%s form', async (_form, raw) => {
502
+ const p = resolved(raw);
448
503
  await expectRefused(await send(p));
449
504
  });
450
505
 
451
506
  it('answers a missing path exactly as an existing one', async () => {
452
507
  for (const form of Object.keys(MISSING_FORMS)) {
453
- const existing = await send(fileForms('config')[form]);
454
- const missing = await send(MISSING_FORMS[form]);
508
+ const existing = await send(resolved(fileForms('config')[form]));
509
+ const missing = await send(resolved(MISSING_FORMS[form]));
455
510
  expect(missing.status).toBe(existing.status);
456
511
  expect(await missing.json()).toEqual(await existing.json());
457
512
  }
@@ -460,7 +515,8 @@ describe('workspace routes refuse the git folder', () => {
460
515
  }
461
516
 
462
517
  for (const [name, send] of dirRoutes) {
463
- it.each(Object.entries(DIR_FORMS))(`${name} — %s form`, async (_form, p) => {
518
+ it.each(Object.entries(DIR_FORMS))(`${name} — %s form`, async (_form, raw) => {
519
+ const p = resolved(raw);
464
520
  await expectRefused(await send(p));
465
521
  });
466
522
  }
@@ -508,7 +564,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
508
564
  let service: WorkspaceService;
509
565
 
510
566
  beforeEach(() => {
511
- 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());
512
568
  });
513
569
 
514
570
  afterEach(async () => {
@@ -533,23 +589,58 @@ describe('WorkspaceService refuses the git folder on its own', () => {
533
589
  ];
534
590
 
535
591
  for (const [name, run] of ops) {
536
- it.each(Object.entries(fileForms('config')).filter(([form]) => !(name === 'readFileAtRef' && form === 'symlinked')))(
592
+ // `readFileAtRef` reads a path out of a git REF, never off the working
593
+ // tree, so no link on disk is followed and the link spellings do not
594
+ // apply to it — a ref read of a link's path yields the link's own blob
595
+ // (the target's NAME), never anything from inside the folder.
596
+ it.each(
597
+ Object.entries(fileForms('config')).filter(
598
+ ([form]) => !(name === 'readFileAtRef' && form.startsWith('symlinked')),
599
+ ),
600
+ )(
537
601
  `${name} — %s form`,
538
- async (form, p) => {
539
- const err = await run(p).catch((e: unknown) => e);
540
- // `readFileAtRef` takes a REPO-relative path (it strips the prefix
541
- // above), so it is not a workspace path and does not meet the
542
- // normaliser; every other op does, and for the spellings the path rule
543
- // refuses that refusal is the one that answers.
544
- if (UNSPELLABLE.has(form) && name !== 'readFileAtRef') {
545
- expect((err as Error).message, form).toMatch(/is outside the knowledge base repository/);
546
- return;
547
- }
548
- expect(err).toBeInstanceOf(GitInternalsError);
602
+ async (form, raw) => {
603
+ const err = await run(resolved(raw)).catch((e: unknown) => e);
604
+ expect(err, form).toBeInstanceOf(GitInternalsError);
549
605
  },
550
606
  );
551
607
  }
552
608
 
609
+ it('a ref read of a link path reads the REF, not the folder the link points into', async () => {
610
+ // The exception the matrix above excludes, asserted rather than assumed:
611
+ // `readFileAtRef` runs `git show <ref>:<path>`, which reads out of the
612
+ // object database and never follows a link on disk. A ref read of a link's
613
+ // path yields the link's own blob — the target's NAME — so there is
614
+ // nothing from inside the folder to refuse, and refusing it would take a
615
+ // legitimate read away. The git rule still refuses every LITERAL spelling.
616
+ const gitRunner = {
617
+ defaultTimeoutMs: 1000,
618
+ run: vi.fn(async (_cwd: string, args: string[]) => {
619
+ // What `git show` really answers for a link's path: its target name.
620
+ expect(args[0]).toBe('show');
621
+ return { stdout: '.git\n', stderr: '', code: 0 };
622
+ }),
623
+ };
624
+ const refService = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs(), gitRunner as never);
625
+
626
+ for (const [form, raw] of Object.entries(fileForms('config'))) {
627
+ if (!form.startsWith('symlinked')) continue;
628
+ // The service takes a repo-relative path here, as its callers pass it.
629
+ const repoPath = resolved(raw).replace(`${KB}/`, '');
630
+ const result = await refService.readFileAtRef(WS, 'main', repoPath).catch((e: unknown) => e);
631
+ expect(result, form).not.toBeInstanceOf(GitInternalsError);
632
+ }
633
+ expect(gitRunner.run).toHaveBeenCalled();
634
+
635
+ // …while a literal git path at a ref is still refused, whatever its form.
636
+ for (const [form, raw] of Object.entries(fileForms('config'))) {
637
+ if (form.startsWith('symlinked')) continue;
638
+ const repoPath = resolved(raw).replace(`${KB}/`, '');
639
+ const err = await refService.readFileAtRef(WS, 'main', repoPath).catch((e: unknown) => e);
640
+ expect(err, form).toBeInstanceOf(Error);
641
+ }
642
+ });
643
+
553
644
  it('a folder download leaves out a git folder spelled in another case', async () => {
554
645
  const upper = join(workspaceDir, KB, 'Notes', '.GIT');
555
646
  await mkdir(upper, { recursive: true });
@@ -584,7 +675,7 @@ describe('the route guard on its own', () => {
584
675
  beforeEach(async () => {
585
676
  reached = 0;
586
677
  userId = USER.id;
587
- 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());
588
679
  const app = express();
589
680
  // The server's own order: the guard ahead of the body parser, then again
590
681
  // on the parsed body, then again once the caller is known.
@@ -641,7 +732,7 @@ describe('the route guard on its own', () => {
641
732
 
642
733
  it('refuses every spelling before the route runs, even unauthenticated', async () => {
643
734
  userId = undefined;
644
- const spellings = Object.values(FILE_FORMS);
735
+ const spellings = Object.values(FILE_FORMS).map(resolved);
645
736
  for (const p of spellings) {
646
737
  const res = await fetch(`${baseUrl}/api/workspace/${WS}/anything?path=${encodeURIComponent(p)}`);
647
738
  // Every spelling that NAMES the folder is refused with no disk touched.
@@ -684,7 +775,7 @@ describe('DiffService refuses the git folder on its own', () => {
684
775
  let diffService: DiffService;
685
776
 
686
777
  beforeEach(() => {
687
- 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());
688
779
  diffService = new DiffService(service, new WorkspaceMutex(), root, join(root, 'backups'), KB, new NodeFs());
689
780
  });
690
781
 
@@ -702,7 +793,8 @@ describe('DiffService refuses the git folder on its own', () => {
702
793
  ];
703
794
 
704
795
  for (const [name, run] of ops) {
705
- it.each(Object.entries(FILE_FORMS))(`${name} — %s form`, async (_form, p) => {
796
+ it.each(Object.entries(FILE_FORMS))(`${name} — %s form`, async (_form, raw) => {
797
+ const p = resolved(raw);
706
798
  await expect(run(p)).rejects.toBeInstanceOf(GitInternalsError);
707
799
  });
708
800
  }
@@ -740,7 +832,7 @@ describe('agent filesystems refuse the git folder on their own', () => {
740
832
  { basePath: workspaceDir, contained: true },
741
833
  { workflow: workflow as unknown as IWorkflowService, workspaceId: WS, branch: BRANCH, user: USER, kbDirName: KB },
742
834
  );
743
- for (const p of Object.values(FILE_FORMS)) {
835
+ for (const p of Object.values(FILE_FORMS).map(resolved)) {
744
836
  await expect(lockingFs.readFile(p)).rejects.toBeInstanceOf(GitInternalsError);
745
837
  await expect(lockingFs.stat(p)).rejects.toBeInstanceOf(GitInternalsError);
746
838
  await expect(lockingFs.writeFile(p, 'x')).rejects.toBeInstanceOf(GitInternalsError);
@@ -750,7 +842,7 @@ describe('agent filesystems refuse the git folder on their own', () => {
750
842
  await expect(lockingFs.moveFile(p, `${KB}/Notes/b.md`)).rejects.toBeInstanceOf(GitInternalsError);
751
843
  await expect(lockingFs.writeFiles([{ path: p, content: 'x' }], 'batch')).rejects.toBeInstanceOf(GitInternalsError);
752
844
  }
753
- for (const p of Object.values(DIR_FORMS)) {
845
+ for (const p of Object.values(DIR_FORMS).map(resolved)) {
754
846
  await expect(lockingFs.readdir(p)).rejects.toBeInstanceOf(GitInternalsError);
755
847
  await expect(lockingFs.mkdir(`${p}/new`)).rejects.toBeInstanceOf(GitInternalsError);
756
848
  }
@@ -760,7 +852,7 @@ describe('agent filesystems refuse the git folder on their own', () => {
760
852
 
761
853
  it('ReadOnlyFilesystem answers a git path with the git refusal, not the read-only one', async () => {
762
854
  const readOnly = new ReadOnlyFilesystem({ basePath: workspaceDir, contained: true });
763
- for (const p of Object.values(FILE_FORMS)) {
855
+ for (const p of Object.values(FILE_FORMS).map(resolved)) {
764
856
  await expect(readOnly.readFile(p)).rejects.toBeInstanceOf(GitInternalsError);
765
857
  await expect(readOnly.exists(p)).rejects.toBeInstanceOf(GitInternalsError);
766
858
  await expect(readOnly.writeFile(p, 'x')).rejects.toBeInstanceOf(GitInternalsError);
@@ -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,
@@ -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, beforeEach, afterEach } from 'vitest';
8
+ import { testKbContext } from '../../../__tests__/kb-context.js';
8
9
 
9
10
  import { NodeFs } from '../../kb-fs/node-fs.js';
10
11
  import type { IWorkflowService } from '@bevel-software/platform-shared';
@@ -103,7 +104,7 @@ describe('GET /file/raw on a download-only path (real resolver)', () => {
103
104
  {} as unknown as IWorkflowService,
104
105
  {} as unknown as WorkflowEventBus,
105
106
  accessControl,
106
- KB,
107
+ testKbContext({ kbDirName: KB }),
107
108
  stubCreatorAccess,
108
109
  { isAdmin: async () => false } as unknown as IAdminAccessService,
109
110
  new NodeFs(),
@@ -2,6 +2,7 @@ import { get as httpGet, 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 { PathTraversalError } from '../../../shared/domain-errors.js';
7
8
  import type { IWorkflowService } from '@bevel-software/platform-shared';
@@ -129,7 +130,7 @@ async function makeHarness(opts: {
129
130
  workflowService,
130
131
  eventBus,
131
132
  accessControl,
132
- KB,
133
+ testKbContext({ kbDirName: KB }),
133
134
  stubCreatorAccess,
134
135
  // Not exercised here — only `.bevelignore`'s tree visibility consults it.
135
136
  { isAdmin: async () => false } as unknown as IAdminAccessService,
@@ -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 { PathTraversalError } from '../../../shared/domain-errors.js';
7
8
  import { EntryExistsError } from '../workspace.service.js';
@@ -149,7 +150,7 @@ async function makeHarness(opts: { canRead?: boolean; skillSaveCheck?: SkillSave
149
150
  workflowService,
150
151
  { emit: vi.fn() } as unknown as WorkflowEventBus,
151
152
  accessControl,
152
- KB,
153
+ testKbContext({ kbDirName: KB }),
153
154
  stubCreatorAccess,
154
155
  { isAdmin: async () => true } as unknown as IAdminAccessService,
155
156
  new NodeFs(),
@@ -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 type { FileTreeEntry, IWorkflowService } from '@bevel-software/platform-shared';
9
10
  import { NodeFs } from '../../kb-fs/node-fs.js';
10
11
  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 releaseLock = vi.fn<(...args: unknown[]) => Promise<never>>(async () => undefined as never);
@@ -85,7 +86,7 @@ async function makeHarness(): Promise<Harness> {
85
86
  workflowService,
86
87
  { emit } as unknown as WorkflowEventBus,
87
88
  allowAll,
88
- KB,
89
+ testKbContext({ kbDirName: KB }),
89
90
  stubCreatorAccess,
90
91
  { isAdmin: async () => false } as unknown as IAdminAccessService,
91
92
  new NodeFs(),
@@ -334,7 +335,7 @@ describe('WorkspaceService.writeFolderPlaceholder', () => {
334
335
  const workspaceId = workspaceIdForBranch('placeholders');
335
336
  const kbDir = path.join(root, workspaceId, KB);
336
337
  await fs.mkdir(path.join(kbDir, '.git'), { recursive: true });
337
- return { svc: new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs()), workspaceId, kbDir };
338
+ return { svc: new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs()), workspaceId, kbDir };
338
339
  }
339
340
 
340
341
  it('writes into an empty folder, and leaves a full or a vanished one alone', async () => {
@@ -377,7 +378,7 @@ describe('WorkspaceService.withFolderTurn', () => {
377
378
  root = await fs.mkdtemp(path.join(os.tmpdir(), 'folder-turn-'));
378
379
  const workspaceId = workspaceIdForBranch('turns');
379
380
  await fs.mkdir(path.join(root, workspaceId, KB, '.git'), { recursive: true });
380
- const svc = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
381
+ const svc = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
381
382
 
382
383
  const events: string[] = [];
383
384
  let open!: () => void;
@@ -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, beforeEach, 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';
@@ -95,7 +96,7 @@ async function makeHarness(): Promise<Harness> {
95
96
  workflowService,
96
97
  eventBus,
97
98
  accessControl,
98
- KB,
99
+ testKbContext({ kbDirName: KB }),
99
100
  creatorAccess,
100
101
  { isAdmin: async () => false } as unknown as IAdminAccessService,
101
102
  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';
@@ -93,7 +94,7 @@ async function makeHarness(opts: {
93
94
  {} as unknown as IWorkflowService,
94
95
  {} as unknown as WorkflowEventBus,
95
96
  accessControl,
96
- KB,
97
+ testKbContext({ kbDirName: KB }),
97
98
  stubCreatorAccess,
98
99
  { isAdmin: async () => opts.isAdmin === true } as unknown as IAdminAccessService,
99
100
  new NodeFs(),
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { testKbContext } from '../../../__tests__/kb-context.js';
2
3
  import fs from 'node:fs/promises';
3
4
  import path from 'node:path';
4
5
  import os from 'node:os';
@@ -44,9 +45,8 @@ describe('WorkspaceService.ensureRemotesFetched', () => {
44
45
  new WorkspaceService(
45
46
  root,
46
47
  'https://example.test/kb.git',
47
- 'knowledge-base',
48
+ testKbContext(),
48
49
  new NodeFs(),
49
- 'x-access-token',
50
50
  runner,
51
51
  );
52
52