@bevel-software/platform-core-backend 0.1.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 (720) hide show
  1. package/LICENSE +202 -0
  2. package/dist/assets.d.ts +5 -0
  3. package/dist/assets.d.ts.map +1 -0
  4. package/dist/assets.js +23 -0
  5. package/dist/assets.js.map +1 -0
  6. package/dist/core/core-ports.d.ts +83 -0
  7. package/dist/core/core-ports.d.ts.map +1 -0
  8. package/dist/core/core-ports.js +12 -0
  9. package/dist/core/core-ports.js.map +1 -0
  10. package/dist/core/create-core-server.d.ts +62 -0
  11. package/dist/core/create-core-server.d.ts.map +1 -0
  12. package/dist/core/create-core-server.js +204 -0
  13. package/dist/core/create-core-server.js.map +1 -0
  14. package/dist/core/create-core-services.d.ts +95 -0
  15. package/dist/core/create-core-services.d.ts.map +1 -0
  16. package/dist/core/create-core-services.js +352 -0
  17. package/dist/core/create-core-services.js.map +1 -0
  18. package/dist/core-config.d.ts +119 -0
  19. package/dist/core-config.d.ts.map +1 -0
  20. package/dist/core-config.js +240 -0
  21. package/dist/core-config.js.map +1 -0
  22. package/dist/index.d.ts +36 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +36 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/modules/access/access-control.interface.d.ts +348 -0
  27. package/dist/modules/access/access-control.interface.d.ts.map +1 -0
  28. package/dist/modules/access/access-control.interface.js +2 -0
  29. package/dist/modules/access/access-control.interface.js.map +1 -0
  30. package/dist/modules/access/access-control.service.d.ts +323 -0
  31. package/dist/modules/access/access-control.service.d.ts.map +1 -0
  32. package/dist/modules/access/access-control.service.js +1431 -0
  33. package/dist/modules/access/access-control.service.js.map +1 -0
  34. package/dist/modules/access/access-errors.d.ts +34 -0
  35. package/dist/modules/access/access-errors.d.ts.map +1 -0
  36. package/dist/modules/access/access-errors.js +40 -0
  37. package/dist/modules/access/access-errors.js.map +1 -0
  38. package/dist/modules/access/access-mutation.service.d.ts +176 -0
  39. package/dist/modules/access/access-mutation.service.d.ts.map +1 -0
  40. package/dist/modules/access/access-mutation.service.js +307 -0
  41. package/dist/modules/access/access-mutation.service.js.map +1 -0
  42. package/dist/modules/access/access-splice.d.ts +98 -0
  43. package/dist/modules/access/access-splice.d.ts.map +1 -0
  44. package/dist/modules/access/access-splice.js +346 -0
  45. package/dist/modules/access/access-splice.js.map +1 -0
  46. package/dist/modules/access/access.routes.d.ts +10 -0
  47. package/dist/modules/access/access.routes.d.ts.map +1 -0
  48. package/dist/modules/access/access.routes.js +757 -0
  49. package/dist/modules/access/access.routes.js.map +1 -0
  50. package/dist/modules/access/creator-access.d.ts +113 -0
  51. package/dist/modules/access/creator-access.d.ts.map +1 -0
  52. package/dist/modules/access/creator-access.js +212 -0
  53. package/dist/modules/access/creator-access.js.map +1 -0
  54. package/dist/modules/access/kb-read-filter.d.ts +41 -0
  55. package/dist/modules/access/kb-read-filter.d.ts.map +1 -0
  56. package/dist/modules/access/kb-read-filter.js +60 -0
  57. package/dist/modules/access/kb-read-filter.js.map +1 -0
  58. package/dist/modules/access/roles-admin.service.d.ts +240 -0
  59. package/dist/modules/access/roles-admin.service.d.ts.map +1 -0
  60. package/dist/modules/access/roles-admin.service.js +630 -0
  61. package/dist/modules/access/roles-admin.service.js.map +1 -0
  62. package/dist/modules/access/roles-edit.d.ts +91 -0
  63. package/dist/modules/access/roles-edit.d.ts.map +1 -0
  64. package/dist/modules/access/roles-edit.js +232 -0
  65. package/dist/modules/access/roles-edit.js.map +1 -0
  66. package/dist/modules/access/roles-yaml-guard.d.ts +56 -0
  67. package/dist/modules/access/roles-yaml-guard.d.ts.map +1 -0
  68. package/dist/modules/access/roles-yaml-guard.js +79 -0
  69. package/dist/modules/access/roles-yaml-guard.js.map +1 -0
  70. package/dist/modules/admin/admin-access.routes.d.ts +18 -0
  71. package/dist/modules/admin/admin-access.routes.d.ts.map +1 -0
  72. package/dist/modules/admin/admin-access.routes.js +26 -0
  73. package/dist/modules/admin/admin-access.routes.js.map +1 -0
  74. package/dist/modules/admin/admin-access.service.d.ts +24 -0
  75. package/dist/modules/admin/admin-access.service.d.ts.map +1 -0
  76. package/dist/modules/admin/admin-access.service.js +41 -0
  77. package/dist/modules/admin/admin-access.service.js.map +1 -0
  78. package/dist/modules/admin/admin.interface.d.ts +11 -0
  79. package/dist/modules/admin/admin.interface.d.ts.map +1 -0
  80. package/dist/modules/admin/admin.interface.js +2 -0
  81. package/dist/modules/admin/admin.interface.js.map +1 -0
  82. package/dist/modules/auth/account-erasure.service.d.ts +80 -0
  83. package/dist/modules/auth/account-erasure.service.d.ts.map +1 -0
  84. package/dist/modules/auth/account-erasure.service.js +91 -0
  85. package/dist/modules/auth/account-erasure.service.js.map +1 -0
  86. package/dist/modules/auth/auth.middleware.d.ts +23 -0
  87. package/dist/modules/auth/auth.middleware.d.ts.map +1 -0
  88. package/dist/modules/auth/auth.middleware.js +68 -0
  89. package/dist/modules/auth/auth.middleware.js.map +1 -0
  90. package/dist/modules/auth/auth.routes.d.ts +25 -0
  91. package/dist/modules/auth/auth.routes.d.ts.map +1 -0
  92. package/dist/modules/auth/auth.routes.js +72 -0
  93. package/dist/modules/auth/auth.routes.js.map +1 -0
  94. package/dist/modules/auth/auth.service.d.ts +76 -0
  95. package/dist/modules/auth/auth.service.d.ts.map +1 -0
  96. package/dist/modules/auth/auth.service.js +168 -0
  97. package/dist/modules/auth/auth.service.js.map +1 -0
  98. package/dist/modules/code-mode/code-mode-names.d.ts +16 -0
  99. package/dist/modules/code-mode/code-mode-names.d.ts.map +1 -0
  100. package/dist/modules/code-mode/code-mode-names.js +30 -0
  101. package/dist/modules/code-mode/code-mode-names.js.map +1 -0
  102. package/dist/modules/code-mode/code-mode.tool.d.ts +13 -0
  103. package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -0
  104. package/dist/modules/code-mode/code-mode.tool.js +112 -0
  105. package/dist/modules/code-mode/code-mode.tool.js.map +1 -0
  106. package/dist/modules/code-mode/index.d.ts +3 -0
  107. package/dist/modules/code-mode/index.d.ts.map +1 -0
  108. package/dist/modules/code-mode/index.js +3 -0
  109. package/dist/modules/code-mode/index.js.map +1 -0
  110. package/dist/modules/database/connection.d.ts +6 -0
  111. package/dist/modules/database/connection.d.ts.map +1 -0
  112. package/dist/modules/database/connection.js +12 -0
  113. package/dist/modules/database/connection.js.map +1 -0
  114. package/dist/modules/database/core-schema.d.ts +2273 -0
  115. package/dist/modules/database/core-schema.d.ts.map +1 -0
  116. package/dist/modules/database/core-schema.js +413 -0
  117. package/dist/modules/database/core-schema.js.map +1 -0
  118. package/dist/modules/database/migrate.d.ts +10 -0
  119. package/dist/modules/database/migrate.d.ts.map +1 -0
  120. package/dist/modules/database/migrate.js +40 -0
  121. package/dist/modules/database/migrate.js.map +1 -0
  122. package/dist/modules/database/schema.d.ts +12 -0
  123. package/dist/modules/database/schema.d.ts.map +1 -0
  124. package/dist/modules/database/schema.js +12 -0
  125. package/dist/modules/database/schema.js.map +1 -0
  126. package/dist/modules/diff/diff-paths.d.ts +2 -0
  127. package/dist/modules/diff/diff-paths.d.ts.map +1 -0
  128. package/dist/modules/diff/diff-paths.js +9 -0
  129. package/dist/modules/diff/diff-paths.js.map +1 -0
  130. package/dist/modules/diff/diff.config.d.ts +8 -0
  131. package/dist/modules/diff/diff.config.d.ts.map +1 -0
  132. package/dist/modules/diff/diff.config.js +13 -0
  133. package/dist/modules/diff/diff.config.js.map +1 -0
  134. package/dist/modules/diff/diff.interface.d.ts +73 -0
  135. package/dist/modules/diff/diff.interface.d.ts.map +1 -0
  136. package/dist/modules/diff/diff.interface.js +2 -0
  137. package/dist/modules/diff/diff.interface.js.map +1 -0
  138. package/dist/modules/diff/diff.routes.d.ts +35 -0
  139. package/dist/modules/diff/diff.routes.d.ts.map +1 -0
  140. package/dist/modules/diff/diff.routes.js +228 -0
  141. package/dist/modules/diff/diff.routes.js.map +1 -0
  142. package/dist/modules/diff/diff.service.d.ts +51 -0
  143. package/dist/modules/diff/diff.service.d.ts.map +1 -0
  144. package/dist/modules/diff/diff.service.js +489 -0
  145. package/dist/modules/diff/diff.service.js.map +1 -0
  146. package/dist/modules/diff/line-diff.d.ts +16 -0
  147. package/dist/modules/diff/line-diff.d.ts.map +1 -0
  148. package/dist/modules/diff/line-diff.js +67 -0
  149. package/dist/modules/diff/line-diff.js.map +1 -0
  150. package/dist/modules/mcp/mcp-auth.middleware.d.ts +27 -0
  151. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -0
  152. package/dist/modules/mcp/mcp-auth.middleware.js +116 -0
  153. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -0
  154. package/dist/modules/mcp/mcp-session-store.d.ts +74 -0
  155. package/dist/modules/mcp/mcp-session-store.d.ts.map +1 -0
  156. package/dist/modules/mcp/mcp-session-store.js +131 -0
  157. package/dist/modules/mcp/mcp-session-store.js.map +1 -0
  158. package/dist/modules/mcp/mcp.routes.d.ts +24 -0
  159. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -0
  160. package/dist/modules/mcp/mcp.routes.js +229 -0
  161. package/dist/modules/mcp/mcp.routes.js.map +1 -0
  162. package/dist/modules/mcp/mcp.service.d.ts +198 -0
  163. package/dist/modules/mcp/mcp.service.d.ts.map +1 -0
  164. package/dist/modules/mcp/mcp.service.js +840 -0
  165. package/dist/modules/mcp/mcp.service.js.map +1 -0
  166. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +76 -0
  167. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -0
  168. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +291 -0
  169. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -0
  170. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +18 -0
  171. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -0
  172. package/dist/modules/mcp/oauth/oauth-consent.routes.js +52 -0
  173. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -0
  174. package/dist/modules/mcp/oauth/oauth-state.d.ts +32 -0
  175. package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -0
  176. package/dist/modules/mcp/oauth/oauth-state.js +34 -0
  177. package/dist/modules/mcp/oauth/oauth-state.js.map +1 -0
  178. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +92 -0
  179. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -0
  180. package/dist/modules/secrets-vault/db-secrets-vault.service.js +728 -0
  181. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -0
  182. package/dist/modules/secrets-vault/index.d.ts +7 -0
  183. package/dist/modules/secrets-vault/index.d.ts.map +1 -0
  184. package/dist/modules/secrets-vault/index.js +6 -0
  185. package/dist/modules/secrets-vault/index.js.map +1 -0
  186. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts +63 -0
  187. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts.map +1 -0
  188. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js +269 -0
  189. package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js.map +1 -0
  190. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +46 -0
  191. package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -0
  192. package/dist/modules/secrets-vault/secrets-variable-loader.js +87 -0
  193. package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -0
  194. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +210 -0
  195. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -0
  196. package/dist/modules/secrets-vault/secrets-vault.contract.js +90 -0
  197. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -0
  198. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +30 -0
  199. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -0
  200. package/dist/modules/secrets-vault/secrets-vault.routes.js +490 -0
  201. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -0
  202. package/dist/modules/skills/index.d.ts +5 -0
  203. package/dist/modules/skills/index.d.ts.map +1 -0
  204. package/dist/modules/skills/index.js +4 -0
  205. package/dist/modules/skills/index.js.map +1 -0
  206. package/dist/modules/skills/skills.contract.d.ts +58 -0
  207. package/dist/modules/skills/skills.contract.d.ts.map +1 -0
  208. package/dist/modules/skills/skills.contract.js +10 -0
  209. package/dist/modules/skills/skills.contract.js.map +1 -0
  210. package/dist/modules/skills/skills.routes.d.ts +15 -0
  211. package/dist/modules/skills/skills.routes.d.ts.map +1 -0
  212. package/dist/modules/skills/skills.routes.js +34 -0
  213. package/dist/modules/skills/skills.routes.js.map +1 -0
  214. package/dist/modules/skills/skills.service.d.ts +21 -0
  215. package/dist/modules/skills/skills.service.d.ts.map +1 -0
  216. package/dist/modules/skills/skills.service.js +202 -0
  217. package/dist/modules/skills/skills.service.js.map +1 -0
  218. package/dist/modules/skills/skills.tools.d.ts +15 -0
  219. package/dist/modules/skills/skills.tools.d.ts.map +1 -0
  220. package/dist/modules/skills/skills.tools.js +96 -0
  221. package/dist/modules/skills/skills.tools.js.map +1 -0
  222. package/dist/modules/tool-auth/external-api-key.errors.d.ts +14 -0
  223. package/dist/modules/tool-auth/external-api-key.errors.d.ts.map +1 -0
  224. package/dist/modules/tool-auth/external-api-key.errors.js +23 -0
  225. package/dist/modules/tool-auth/external-api-key.errors.js.map +1 -0
  226. package/dist/modules/tool-auth/external-api-key.interface.d.ts +90 -0
  227. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -0
  228. package/dist/modules/tool-auth/external-api-key.interface.js +2 -0
  229. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -0
  230. package/dist/modules/tool-auth/external-api-key.service.d.ts +25 -0
  231. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -0
  232. package/dist/modules/tool-auth/external-api-key.service.js +164 -0
  233. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -0
  234. package/dist/modules/tool-auth/internal-token.service.d.ts +62 -0
  235. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -0
  236. package/dist/modules/tool-auth/internal-token.service.js +85 -0
  237. package/dist/modules/tool-auth/internal-token.service.js.map +1 -0
  238. package/dist/modules/tool-auth/llm-usage-meter.d.ts +16 -0
  239. package/dist/modules/tool-auth/llm-usage-meter.d.ts.map +1 -0
  240. package/dist/modules/tool-auth/llm-usage-meter.js +6 -0
  241. package/dist/modules/tool-auth/llm-usage-meter.js.map +1 -0
  242. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +101 -0
  243. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -0
  244. package/dist/modules/tool-auth/tool-auth.middleware.js +166 -0
  245. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -0
  246. package/dist/modules/tool-helpers/index.d.ts +19 -0
  247. package/dist/modules/tool-helpers/index.d.ts.map +1 -0
  248. package/dist/modules/tool-helpers/index.js +18 -0
  249. package/dist/modules/tool-helpers/index.js.map +1 -0
  250. package/dist/modules/tool-helpers/tool-context.d.ts +35 -0
  251. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -0
  252. package/dist/modules/tool-helpers/tool-context.js +66 -0
  253. package/dist/modules/tool-helpers/tool-context.js.map +1 -0
  254. package/dist/modules/tool-helpers/tool-def.d.ts +33 -0
  255. package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -0
  256. package/dist/modules/tool-helpers/tool-def.js +57 -0
  257. package/dist/modules/tool-helpers/tool-def.js.map +1 -0
  258. package/dist/modules/tool-helpers/tool-handler.d.ts +19 -0
  259. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -0
  260. package/dist/modules/tool-helpers/tool-handler.js +84 -0
  261. package/dist/modules/tool-helpers/tool-handler.js.map +1 -0
  262. package/dist/modules/tool-helpers/tool.contract.d.ts +64 -0
  263. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -0
  264. package/dist/modules/tool-helpers/tool.contract.js +24 -0
  265. package/dist/modules/tool-helpers/tool.contract.js.map +1 -0
  266. package/dist/modules/tool-helpers/validate-token.d.ts +31 -0
  267. package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -0
  268. package/dist/modules/tool-helpers/validate-token.js +20 -0
  269. package/dist/modules/tool-helpers/validate-token.js.map +1 -0
  270. package/dist/modules/tool-manuals/index.d.ts +5 -0
  271. package/dist/modules/tool-manuals/index.d.ts.map +1 -0
  272. package/dist/modules/tool-manuals/index.js +5 -0
  273. package/dist/modules/tool-manuals/index.js.map +1 -0
  274. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +182 -0
  275. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -0
  276. package/dist/modules/tool-manuals/tool-manuals.contract.js +19 -0
  277. package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -0
  278. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +24 -0
  279. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -0
  280. package/dist/modules/tool-manuals/tool-manuals.routes.js +102 -0
  281. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -0
  282. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +108 -0
  283. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -0
  284. package/dist/modules/tool-manuals/tool-manuals.service.js +710 -0
  285. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -0
  286. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +35 -0
  287. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -0
  288. package/dist/modules/tool-manuals/tool-manuals.tools.js +157 -0
  289. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -0
  290. package/dist/modules/tool-registry/manual.routes.d.ts +6 -0
  291. package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -0
  292. package/dist/modules/tool-registry/manual.routes.js +76 -0
  293. package/dist/modules/tool-registry/manual.routes.js.map +1 -0
  294. package/dist/modules/tool-registry/tool-registry.d.ts +23 -0
  295. package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -0
  296. package/dist/modules/tool-registry/tool-registry.js +46 -0
  297. package/dist/modules/tool-registry/tool-registry.js.map +1 -0
  298. package/dist/modules/tool-registry/tool.contract.d.ts +48 -0
  299. package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -0
  300. package/dist/modules/tool-registry/tool.contract.js +2 -0
  301. package/dist/modules/tool-registry/tool.contract.js.map +1 -0
  302. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +14 -0
  303. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -0
  304. package/dist/modules/workflow/agent-tools/workflow.tools.js +437 -0
  305. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -0
  306. package/dist/modules/workflow/event-bus.d.ts +107 -0
  307. package/dist/modules/workflow/event-bus.d.ts.map +1 -0
  308. package/dist/modules/workflow/event-bus.js +224 -0
  309. package/dist/modules/workflow/event-bus.js.map +1 -0
  310. package/dist/modules/workflow/events.routes.d.ts +80 -0
  311. package/dist/modules/workflow/events.routes.d.ts.map +1 -0
  312. package/dist/modules/workflow/events.routes.js +216 -0
  313. package/dist/modules/workflow/events.routes.js.map +1 -0
  314. package/dist/modules/workflow/file-change-notifier.d.ts +38 -0
  315. package/dist/modules/workflow/file-change-notifier.d.ts.map +1 -0
  316. package/dist/modules/workflow/file-change-notifier.js +22 -0
  317. package/dist/modules/workflow/file-change-notifier.js.map +1 -0
  318. package/dist/modules/workflow/file-lock.service.d.ts +57 -0
  319. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -0
  320. package/dist/modules/workflow/file-lock.service.js +202 -0
  321. package/dist/modules/workflow/file-lock.service.js.map +1 -0
  322. package/dist/modules/workflow/git/branch-name.d.ts +10 -0
  323. package/dist/modules/workflow/git/branch-name.d.ts.map +1 -0
  324. package/dist/modules/workflow/git/branch-name.js +76 -0
  325. package/dist/modules/workflow/git/branch-name.js.map +1 -0
  326. package/dist/modules/workflow/git/clone-config.d.ts +61 -0
  327. package/dist/modules/workflow/git/clone-config.d.ts.map +1 -0
  328. package/dist/modules/workflow/git/clone-config.js +69 -0
  329. package/dist/modules/workflow/git/clone-config.js.map +1 -0
  330. package/dist/modules/workflow/git/git-version.d.ts +34 -0
  331. package/dist/modules/workflow/git/git-version.d.ts.map +1 -0
  332. package/dist/modules/workflow/git/git-version.js +63 -0
  333. package/dist/modules/workflow/git/git-version.js.map +1 -0
  334. package/dist/modules/workflow/git/git.service.d.ts +427 -0
  335. package/dist/modules/workflow/git/git.service.d.ts.map +1 -0
  336. package/dist/modules/workflow/git/git.service.js +1987 -0
  337. package/dist/modules/workflow/git/git.service.js.map +1 -0
  338. package/dist/modules/workflow/git/mutex.d.ts +11 -0
  339. package/dist/modules/workflow/git/mutex.d.ts.map +1 -0
  340. package/dist/modules/workflow/git/mutex.js +23 -0
  341. package/dist/modules/workflow/git/mutex.js.map +1 -0
  342. package/dist/modules/workflow/git/pull-request.service.d.ts +124 -0
  343. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -0
  344. package/dist/modules/workflow/git/pull-request.service.js +328 -0
  345. package/dist/modules/workflow/git/pull-request.service.js.map +1 -0
  346. package/dist/modules/workflow/locking-filesystem.d.ts +133 -0
  347. package/dist/modules/workflow/locking-filesystem.d.ts.map +1 -0
  348. package/dist/modules/workflow/locking-filesystem.js +400 -0
  349. package/dist/modules/workflow/locking-filesystem.js.map +1 -0
  350. package/dist/modules/workflow/pending-commits.service.d.ts +221 -0
  351. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -0
  352. package/dist/modules/workflow/pending-commits.service.js +364 -0
  353. package/dist/modules/workflow/pending-commits.service.js.map +1 -0
  354. package/dist/modules/workflow/pending-commits.worker.d.ts +148 -0
  355. package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -0
  356. package/dist/modules/workflow/pending-commits.worker.js +245 -0
  357. package/dist/modules/workflow/pending-commits.worker.js.map +1 -0
  358. package/dist/modules/workflow/read-only-filesystem.d.ts +24 -0
  359. package/dist/modules/workflow/read-only-filesystem.d.ts.map +1 -0
  360. package/dist/modules/workflow/read-only-filesystem.js +39 -0
  361. package/dist/modules/workflow/read-only-filesystem.js.map +1 -0
  362. package/dist/modules/workflow/recovery-bot.d.ts +31 -0
  363. package/dist/modules/workflow/recovery-bot.d.ts.map +1 -0
  364. package/dist/modules/workflow/recovery-bot.js +64 -0
  365. package/dist/modules/workflow/recovery-bot.js.map +1 -0
  366. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +137 -0
  367. package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -0
  368. package/dist/modules/workflow/review-workflow/review-workflow.interface.js +2 -0
  369. package/dist/modules/workflow/review-workflow/review-workflow.interface.js.map +1 -0
  370. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +26 -0
  371. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -0
  372. package/dist/modules/workflow/review-workflow/review-workflow.service.js +636 -0
  373. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -0
  374. package/dist/modules/workflow/sanitize-error.d.ts +29 -0
  375. package/dist/modules/workflow/sanitize-error.d.ts.map +1 -0
  376. package/dist/modules/workflow/sanitize-error.js +60 -0
  377. package/dist/modules/workflow/sanitize-error.js.map +1 -0
  378. package/dist/modules/workflow/session-ontology.policy.d.ts +52 -0
  379. package/dist/modules/workflow/session-ontology.policy.d.ts.map +1 -0
  380. package/dist/modules/workflow/session-ontology.policy.js +62 -0
  381. package/dist/modules/workflow/session-ontology.policy.js.map +1 -0
  382. package/dist/modules/workflow/session-ontology.service.d.ts +100 -0
  383. package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -0
  384. package/dist/modules/workflow/session-ontology.service.js +143 -0
  385. package/dist/modules/workflow/session-ontology.service.js.map +1 -0
  386. package/dist/modules/workflow/workflow-hooks.d.ts +87 -0
  387. package/dist/modules/workflow/workflow-hooks.d.ts.map +1 -0
  388. package/dist/modules/workflow/workflow-hooks.js +35 -0
  389. package/dist/modules/workflow/workflow-hooks.js.map +1 -0
  390. package/dist/modules/workflow/workflow.errors.d.ts +171 -0
  391. package/dist/modules/workflow/workflow.errors.d.ts.map +1 -0
  392. package/dist/modules/workflow/workflow.errors.js +260 -0
  393. package/dist/modules/workflow/workflow.errors.js.map +1 -0
  394. package/dist/modules/workflow/workflow.routes.d.ts +26 -0
  395. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -0
  396. package/dist/modules/workflow/workflow.routes.js +804 -0
  397. package/dist/modules/workflow/workflow.routes.js.map +1 -0
  398. package/dist/modules/workflow/workflow.service.d.ts +385 -0
  399. package/dist/modules/workflow/workflow.service.d.ts.map +1 -0
  400. package/dist/modules/workflow/workflow.service.js +1155 -0
  401. package/dist/modules/workflow/workflow.service.js.map +1 -0
  402. package/dist/modules/workspace/bevel-ignore.d.ts +25 -0
  403. package/dist/modules/workspace/bevel-ignore.d.ts.map +1 -0
  404. package/dist/modules/workspace/bevel-ignore.js +57 -0
  405. package/dist/modules/workspace/bevel-ignore.js.map +1 -0
  406. package/dist/modules/workspace/kb-seed.interface.d.ts +36 -0
  407. package/dist/modules/workspace/kb-seed.interface.d.ts.map +1 -0
  408. package/dist/modules/workspace/kb-seed.interface.js +2 -0
  409. package/dist/modules/workspace/kb-seed.interface.js.map +1 -0
  410. package/dist/modules/workspace/kb-seed.service.d.ts +70 -0
  411. package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -0
  412. package/dist/modules/workspace/kb-seed.service.js +325 -0
  413. package/dist/modules/workspace/kb-seed.service.js.map +1 -0
  414. package/dist/modules/workspace/routine-write-policy.d.ts +49 -0
  415. package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -0
  416. package/dist/modules/workspace/routine-write-policy.js +46 -0
  417. package/dist/modules/workspace/routine-write-policy.js.map +1 -0
  418. package/dist/modules/workspace/session-ontology.gate.d.ts +112 -0
  419. package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -0
  420. package/dist/modules/workspace/session-ontology.gate.js +161 -0
  421. package/dist/modules/workspace/session-ontology.gate.js.map +1 -0
  422. package/dist/modules/workspace/session-sink.d.ts +25 -0
  423. package/dist/modules/workspace/session-sink.d.ts.map +1 -0
  424. package/dist/modules/workspace/session-sink.js +8 -0
  425. package/dist/modules/workspace/session-sink.js.map +1 -0
  426. package/dist/modules/workspace/spill-store.d.ts +24 -0
  427. package/dist/modules/workspace/spill-store.d.ts.map +1 -0
  428. package/dist/modules/workspace/spill-store.js +87 -0
  429. package/dist/modules/workspace/spill-store.js.map +1 -0
  430. package/dist/modules/workspace/workspace.routes.d.ts +25 -0
  431. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -0
  432. package/dist/modules/workspace/workspace.routes.js +1046 -0
  433. package/dist/modules/workspace/workspace.routes.js.map +1 -0
  434. package/dist/modules/workspace/workspace.service.d.ts +339 -0
  435. package/dist/modules/workspace/workspace.service.d.ts.map +1 -0
  436. package/dist/modules/workspace/workspace.service.js +1221 -0
  437. package/dist/modules/workspace/workspace.service.js.map +1 -0
  438. package/dist/modules/workspace/workspace.tools.d.ts +19 -0
  439. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -0
  440. package/dist/modules/workspace/workspace.tools.js +767 -0
  441. package/dist/modules/workspace/workspace.tools.js.map +1 -0
  442. package/dist/shared/frontmatter-id.d.ts +35 -0
  443. package/dist/shared/frontmatter-id.d.ts.map +1 -0
  444. package/dist/shared/frontmatter-id.js +68 -0
  445. package/dist/shared/frontmatter-id.js.map +1 -0
  446. package/dist/shared/fs-walk.d.ts +9 -0
  447. package/dist/shared/fs-walk.d.ts.map +1 -0
  448. package/dist/shared/fs-walk.js +34 -0
  449. package/dist/shared/fs-walk.js.map +1 -0
  450. package/dist/shared/hash-email.d.ts +11 -0
  451. package/dist/shared/hash-email.d.ts.map +1 -0
  452. package/dist/shared/hash-email.js +14 -0
  453. package/dist/shared/hash-email.js.map +1 -0
  454. package/dist/shared/kb-layout.d.ts +38 -0
  455. package/dist/shared/kb-layout.d.ts.map +1 -0
  456. package/dist/shared/kb-layout.js +102 -0
  457. package/dist/shared/kb-layout.js.map +1 -0
  458. package/dist/shared/kb-layout.test.d.ts +2 -0
  459. package/dist/shared/kb-layout.test.d.ts.map +1 -0
  460. package/dist/shared/kb-layout.test.js +67 -0
  461. package/dist/shared/kb-layout.test.js.map +1 -0
  462. package/dist/shared/ssrf.d.ts +20 -0
  463. package/dist/shared/ssrf.d.ts.map +1 -0
  464. package/dist/shared/ssrf.js +89 -0
  465. package/dist/shared/ssrf.js.map +1 -0
  466. package/dist/shared/token-crypto.d.ts +16 -0
  467. package/dist/shared/token-crypto.d.ts.map +1 -0
  468. package/dist/shared/token-crypto.js +49 -0
  469. package/dist/shared/token-crypto.js.map +1 -0
  470. package/dist/shared/ttl-cache.d.ts +16 -0
  471. package/dist/shared/ttl-cache.d.ts.map +1 -0
  472. package/dist/shared/ttl-cache.js +27 -0
  473. package/dist/shared/ttl-cache.js.map +1 -0
  474. package/dist/shared/utcp-namespace.d.ts +46 -0
  475. package/dist/shared/utcp-namespace.d.ts.map +1 -0
  476. package/dist/shared/utcp-namespace.js +82 -0
  477. package/dist/shared/utcp-namespace.js.map +1 -0
  478. package/dist/version.d.ts +17 -0
  479. package/dist/version.d.ts.map +1 -0
  480. package/dist/version.js +19 -0
  481. package/dist/version.js.map +1 -0
  482. package/kb-template/.bevelignore +21 -0
  483. package/kb-template/Agents/.gitkeep +0 -0
  484. package/kb-template/Agents/README.md +38 -0
  485. package/kb-template/CLAUDE.md +419 -0
  486. package/kb-template/Data/.gitkeep +0 -0
  487. package/kb-template/Data/README.md +39 -0
  488. package/kb-template/KnowledgeBase/.gitkeep +0 -0
  489. package/kb-template/KnowledgeBase/README.md +37 -0
  490. package/kb-template/Pipelines/.gitkeep +0 -0
  491. package/kb-template/Pipelines/README.md +38 -0
  492. package/kb-template/Skills/.gitkeep +0 -0
  493. package/kb-template/Skills/README.md +32 -0
  494. package/kb-template/Tools/.gitkeep +0 -0
  495. package/kb-template/Tools/README.md +42 -0
  496. package/kb-template/access.md +36 -0
  497. package/migrations/0000_core_init.sql +243 -0
  498. package/migrations/meta/0000_snapshot.json +1480 -0
  499. package/migrations/meta/_journal.json +13 -0
  500. package/package.json +80 -0
  501. package/src/assets.ts +25 -0
  502. package/src/core/core-ports.ts +91 -0
  503. package/src/core/create-core-server.ts +338 -0
  504. package/src/core/create-core-services.ts +501 -0
  505. package/src/core-config.ts +257 -0
  506. package/src/index.ts +69 -0
  507. package/src/modules/access/__tests__/access-control.atref-batch.test.ts +98 -0
  508. package/src/modules/access/__tests__/access-control.read-batch.test.ts +132 -0
  509. package/src/modules/access/__tests__/access-control.service.test.ts +1011 -0
  510. package/src/modules/access/__tests__/access-mutation.service.test.ts +439 -0
  511. package/src/modules/access/__tests__/access-splice.test.ts +247 -0
  512. package/src/modules/access/__tests__/access.routes.revoke.test.ts +407 -0
  513. package/src/modules/access/__tests__/creator-access.test.ts +217 -0
  514. package/src/modules/access/__tests__/grant-sources.test.ts +204 -0
  515. package/src/modules/access/__tests__/kb-read-filter.test.ts +70 -0
  516. package/src/modules/access/__tests__/roles-admin.service.test.ts +469 -0
  517. package/src/modules/access/__tests__/roles-edit.test.ts +138 -0
  518. package/src/modules/access/__tests__/roles-yaml-guard.test.ts +70 -0
  519. package/src/modules/access/__tests__/roles.routes.test.ts +234 -0
  520. package/src/modules/access/access-control.interface.ts +383 -0
  521. package/src/modules/access/access-control.service.ts +1794 -0
  522. package/src/modules/access/access-errors.ts +60 -0
  523. package/src/modules/access/access-mutation.service.ts +369 -0
  524. package/src/modules/access/access-splice.ts +413 -0
  525. package/src/modules/access/access.routes.ts +894 -0
  526. package/src/modules/access/creator-access.ts +270 -0
  527. package/src/modules/access/kb-read-filter.ts +76 -0
  528. package/src/modules/access/roles-admin.service.ts +741 -0
  529. package/src/modules/access/roles-edit.ts +248 -0
  530. package/src/modules/access/roles-yaml-guard.ts +89 -0
  531. package/src/modules/admin/admin-access.routes.ts +29 -0
  532. package/src/modules/admin/admin-access.service.ts +38 -0
  533. package/src/modules/admin/admin.interface.ts +10 -0
  534. package/src/modules/auth/account-erasure.service.ts +183 -0
  535. package/src/modules/auth/auth.middleware.ts +78 -0
  536. package/src/modules/auth/auth.routes.ts +97 -0
  537. package/src/modules/auth/auth.service.ts +199 -0
  538. package/src/modules/code-mode/code-mode-names.ts +38 -0
  539. package/src/modules/code-mode/code-mode.tool.ts +117 -0
  540. package/src/modules/code-mode/index.ts +6 -0
  541. package/src/modules/database/connection.ts +15 -0
  542. package/src/modules/database/core-schema.ts +431 -0
  543. package/src/modules/database/migrate.ts +43 -0
  544. package/src/modules/database/schema.ts +11 -0
  545. package/src/modules/diff/__tests__/diff.routes.read-gate.test.ts +87 -0
  546. package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +150 -0
  547. package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +184 -0
  548. package/src/modules/diff/__tests__/diff.service.test.ts +202 -0
  549. package/src/modules/diff/diff-paths.ts +9 -0
  550. package/src/modules/diff/diff.config.ts +12 -0
  551. package/src/modules/diff/diff.interface.ts +78 -0
  552. package/src/modules/diff/diff.routes.ts +277 -0
  553. package/src/modules/diff/diff.service.ts +508 -0
  554. package/src/modules/diff/line-diff.ts +79 -0
  555. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +287 -0
  556. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +249 -0
  557. package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +253 -0
  558. package/src/modules/mcp/__tests__/mcp-session-store.test.ts +151 -0
  559. package/src/modules/mcp/__tests__/mcp.e2e.test.ts +150 -0
  560. package/src/modules/mcp/__tests__/mcp.routes.delete.test.ts +92 -0
  561. package/src/modules/mcp/__tests__/mcp.service.test.ts +414 -0
  562. package/src/modules/mcp/mcp-auth.middleware.ts +126 -0
  563. package/src/modules/mcp/mcp-session-store.ts +162 -0
  564. package/src/modules/mcp/mcp.routes.ts +263 -0
  565. package/src/modules/mcp/mcp.service.ts +973 -0
  566. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +401 -0
  567. package/src/modules/mcp/oauth/oauth-consent.routes.ts +60 -0
  568. package/src/modules/mcp/oauth/oauth-state.ts +61 -0
  569. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +277 -0
  570. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +206 -0
  571. package/src/modules/secrets-vault/__tests__/mcp-oauth-discovery.service.test.ts +178 -0
  572. package/src/modules/secrets-vault/__tests__/scopes-covered.test.ts +101 -0
  573. package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +54 -0
  574. package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +143 -0
  575. package/src/modules/secrets-vault/db-secrets-vault.service.ts +792 -0
  576. package/src/modules/secrets-vault/index.ts +25 -0
  577. package/src/modules/secrets-vault/mcp-oauth-discovery.service.ts +289 -0
  578. package/src/modules/secrets-vault/secrets-variable-loader.ts +104 -0
  579. package/src/modules/secrets-vault/secrets-vault.contract.ts +270 -0
  580. package/src/modules/secrets-vault/secrets-vault.routes.ts +526 -0
  581. package/src/modules/skills/__tests__/skills.service.test.ts +176 -0
  582. package/src/modules/skills/index.ts +10 -0
  583. package/src/modules/skills/skills.contract.ts +54 -0
  584. package/src/modules/skills/skills.routes.ts +38 -0
  585. package/src/modules/skills/skills.service.ts +245 -0
  586. package/src/modules/skills/skills.tools.ts +121 -0
  587. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +358 -0
  588. package/src/modules/tool-auth/__tests__/internal-token.service.test.ts +79 -0
  589. package/src/modules/tool-auth/__tests__/manual-auth.middleware.test.ts +88 -0
  590. package/src/modules/tool-auth/external-api-key.errors.ts +25 -0
  591. package/src/modules/tool-auth/external-api-key.interface.ts +99 -0
  592. package/src/modules/tool-auth/external-api-key.service.ts +209 -0
  593. package/src/modules/tool-auth/internal-token.service.ts +124 -0
  594. package/src/modules/tool-auth/llm-usage-meter.ts +19 -0
  595. package/src/modules/tool-auth/tool-auth.middleware.ts +220 -0
  596. package/src/modules/tool-helpers/__tests__/phase0-loopback-spike.test.ts +129 -0
  597. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +95 -0
  598. package/src/modules/tool-helpers/__tests__/tools-surface.test.ts +146 -0
  599. package/src/modules/tool-helpers/__tests__/validate-token.test.ts +75 -0
  600. package/src/modules/tool-helpers/index.ts +18 -0
  601. package/src/modules/tool-helpers/tool-context.ts +98 -0
  602. package/src/modules/tool-helpers/tool-def.ts +73 -0
  603. package/src/modules/tool-helpers/tool-handler.ts +91 -0
  604. package/src/modules/tool-helpers/tool.contract.ts +85 -0
  605. package/src/modules/tool-helpers/validate-token.ts +50 -0
  606. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +200 -0
  607. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +499 -0
  608. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +156 -0
  609. package/src/modules/tool-manuals/index.ts +12 -0
  610. package/src/modules/tool-manuals/tool-manuals.contract.ts +183 -0
  611. package/src/modules/tool-manuals/tool-manuals.routes.ts +110 -0
  612. package/src/modules/tool-manuals/tool-manuals.service.ts +781 -0
  613. package/src/modules/tool-manuals/tool-manuals.tools.ts +202 -0
  614. package/src/modules/tool-registry/__tests__/tool-registry.test.ts +64 -0
  615. package/src/modules/tool-registry/manual.routes.ts +87 -0
  616. package/src/modules/tool-registry/tool-registry.ts +55 -0
  617. package/src/modules/tool-registry/tool.contract.ts +52 -0
  618. package/src/modules/workflow/__tests__/event-bus.test.ts +322 -0
  619. package/src/modules/workflow/__tests__/file-change-notifier.test.ts +51 -0
  620. package/src/modules/workflow/__tests__/format-affected-owners.test.ts +67 -0
  621. package/src/modules/workflow/__tests__/locking-filesystem.test.ts +445 -0
  622. package/src/modules/workflow/__tests__/pending-commits.canonical.test.ts +36 -0
  623. package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +243 -0
  624. package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +308 -0
  625. package/src/modules/workflow/__tests__/sanitize-error.test.ts +67 -0
  626. package/src/modules/workflow/__tests__/session-ontology.policy.test.ts +62 -0
  627. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +200 -0
  628. package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +232 -0
  629. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +380 -0
  630. package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +340 -0
  631. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +192 -0
  632. package/src/modules/workflow/agent-tools/workflow.tools.ts +502 -0
  633. package/src/modules/workflow/event-bus.ts +262 -0
  634. package/src/modules/workflow/events.routes.ts +266 -0
  635. package/src/modules/workflow/file-change-notifier.ts +54 -0
  636. package/src/modules/workflow/file-lock.service.ts +269 -0
  637. package/src/modules/workflow/git/__tests__/branch-name.test.ts +86 -0
  638. package/src/modules/workflow/git/__tests__/branchAuthor.test.ts +80 -0
  639. package/src/modules/workflow/git/__tests__/clone-config.test.ts +15 -0
  640. package/src/modules/workflow/git/__tests__/git-test-helpers.ts +47 -0
  641. package/src/modules/workflow/git/__tests__/git-version.failure.test.ts +24 -0
  642. package/src/modules/workflow/git/__tests__/git-version.test.ts +49 -0
  643. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +389 -0
  644. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
  645. package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +105 -0
  646. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +211 -0
  647. package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +154 -0
  648. package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +320 -0
  649. package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +202 -0
  650. package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +453 -0
  651. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +198 -0
  652. package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +125 -0
  653. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +219 -0
  654. package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +145 -0
  655. package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +240 -0
  656. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +272 -0
  657. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +232 -0
  658. package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +101 -0
  659. package/src/modules/workflow/git/__tests__/git.service.status.test.ts +127 -0
  660. package/src/modules/workflow/git/__tests__/mutex.test.ts +78 -0
  661. package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +225 -0
  662. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +101 -0
  663. package/src/modules/workflow/git/branch-name.ts +70 -0
  664. package/src/modules/workflow/git/clone-config.ts +71 -0
  665. package/src/modules/workflow/git/git-version.ts +70 -0
  666. package/src/modules/workflow/git/git.service.ts +2248 -0
  667. package/src/modules/workflow/git/mutex.ts +22 -0
  668. package/src/modules/workflow/git/pull-request.service.ts +447 -0
  669. package/src/modules/workflow/locking-filesystem.ts +489 -0
  670. package/src/modules/workflow/pending-commits.service.ts +444 -0
  671. package/src/modules/workflow/pending-commits.worker.ts +361 -0
  672. package/src/modules/workflow/read-only-filesystem.ts +54 -0
  673. package/src/modules/workflow/recovery-bot.ts +73 -0
  674. package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +560 -0
  675. package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +176 -0
  676. package/src/modules/workflow/review-workflow/__tests__/merge-gate.test.ts +258 -0
  677. package/src/modules/workflow/review-workflow/review-workflow.interface.ts +199 -0
  678. package/src/modules/workflow/review-workflow/review-workflow.service.ts +806 -0
  679. package/src/modules/workflow/sanitize-error.ts +62 -0
  680. package/src/modules/workflow/session-ontology.policy.ts +70 -0
  681. package/src/modules/workflow/session-ontology.service.ts +178 -0
  682. package/src/modules/workflow/workflow-hooks.ts +101 -0
  683. package/src/modules/workflow/workflow.errors.ts +285 -0
  684. package/src/modules/workflow/workflow.routes.ts +858 -0
  685. package/src/modules/workflow/workflow.service.ts +1555 -0
  686. package/src/modules/workspace/__tests__/kb-seed.service.test.ts +213 -0
  687. package/src/modules/workspace/__tests__/routine-write-policy.test.ts +68 -0
  688. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +237 -0
  689. package/src/modules/workspace/__tests__/spill-store.test.ts +43 -0
  690. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +233 -0
  691. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +176 -0
  692. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +303 -0
  693. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +276 -0
  694. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +120 -0
  695. package/src/modules/workspace/__tests__/workspace.service.test.ts +565 -0
  696. package/src/modules/workspace/__tests__/workspace.tools.test.ts +504 -0
  697. package/src/modules/workspace/bevel-ignore.ts +62 -0
  698. package/src/modules/workspace/kb-seed.interface.ts +36 -0
  699. package/src/modules/workspace/kb-seed.service.ts +361 -0
  700. package/src/modules/workspace/routine-write-policy.ts +79 -0
  701. package/src/modules/workspace/session-ontology.gate.ts +189 -0
  702. package/src/modules/workspace/session-sink.ts +25 -0
  703. package/src/modules/workspace/spill-store.ts +87 -0
  704. package/src/modules/workspace/workspace.routes.ts +1114 -0
  705. package/src/modules/workspace/workspace.service.ts +1343 -0
  706. package/src/modules/workspace/workspace.tools.ts +885 -0
  707. package/src/shared/__tests__/frontmatter-id.test.ts +88 -0
  708. package/src/shared/__tests__/fs-walk.test.ts +42 -0
  709. package/src/shared/__tests__/ssrf.test.ts +53 -0
  710. package/src/shared/__tests__/utcp-namespace.test.ts +19 -0
  711. package/src/shared/frontmatter-id.ts +72 -0
  712. package/src/shared/fs-walk.ts +30 -0
  713. package/src/shared/hash-email.ts +14 -0
  714. package/src/shared/kb-layout.test.ts +88 -0
  715. package/src/shared/kb-layout.ts +101 -0
  716. package/src/shared/ssrf.ts +78 -0
  717. package/src/shared/token-crypto.ts +54 -0
  718. package/src/shared/ttl-cache.ts +27 -0
  719. package/src/shared/utcp-namespace.ts +88 -0
  720. package/src/version.ts +19 -0
@@ -0,0 +1,234 @@
1
+ import type { Server } from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import express from 'express';
7
+ import { describe, it, expect, afterEach, vi } from 'vitest';
8
+
9
+ import type { IAccessControl } from '../access-control.interface.js';
10
+ import type { WorkspaceService } from '../../workspace/workspace.service.js';
11
+ import type { AuthService } from '../../auth/auth.service.js';
12
+ import type { WorkflowService } from '../../workflow/workflow.service.js';
13
+ import type { WorkflowEventBus } from '../../workflow/event-bus.js';
14
+ import type { Database } from '../../database/connection.js';
15
+ import type { FileTreeEntry } from '@bevel-software/platform-shared';
16
+ import { createAccessRoutes } from '../access.routes.js';
17
+
18
+ /**
19
+ * HTTP-level contract tests for the /api/access/roles routes: the admin gate
20
+ * (non-admin → 403), the GET roster shape, and that service-layer invariant
21
+ * errors (reserved name → 422, self-admin-removal → 409 { kind }) surface with
22
+ * the right status. The CRUD logic itself is covered by roles-admin.service.test;
23
+ * here we pin the route wiring + error mapping.
24
+ */
25
+
26
+ const KB = 'knowledge-base';
27
+ const ADMIN = { id: 'u-admin', email: 'razvan@bevel.software', name: 'Razvan' };
28
+
29
+ const ROLES = `roles:
30
+ Admin:
31
+ - razvan@bevel.software
32
+ - juan@bevel.software
33
+ Sales:
34
+ - felix@example.com
35
+ `;
36
+
37
+ /** Temp workspace dirs to clean up after each test. */
38
+ const tmpDirs: string[] = [];
39
+
40
+ async function makeHarness(opts: { isAdmin?: boolean } = {}): Promise<{ server: Server; baseUrl: string }> {
41
+ const isAdmin = opts.isAdmin ?? true;
42
+
43
+ // Back the harness with a REAL temp workspace dir: the service's single-file
44
+ // path writes through a real LockingFilesystem (LocalFilesystem → disk under
45
+ // getWorkspacePath), so an in-memory map would never see the write. The repo
46
+ // lives at <workspaceDir>/<KB>, mirroring production layout.
47
+ const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-roles-routes-'));
48
+ tmpDirs.push(workspaceDir);
49
+ const repoDir = path.join(workspaceDir, KB);
50
+ await fs.mkdir(repoDir, { recursive: true });
51
+ await fs.writeFile(path.join(repoDir, 'roles.yaml'), ROLES, 'utf-8');
52
+
53
+ // The roles routes gate on canWrite(..., 'roles.yaml'); the service reads the
54
+ // real file and edits it, but for these route tests we only need GET + error
55
+ // mapping, so a lightweight access stub backed by the real parser is enough.
56
+ const { AccessControlService } = await import('../access-control.service.js');
57
+ const realAccess = new AccessControlService(
58
+ { getWorkspacePath: async () => workspaceDir, readFile: async () => ROLES } as unknown as WorkspaceService,
59
+ KB,
60
+ );
61
+ const accessControl = {
62
+ // Admin gate: the route's assertCanMutate calls canWrite('roles.yaml').
63
+ canWrite: vi.fn(async () => isAdmin),
64
+ eligibleWriters: vi.fn(async () => ({ roles: ['Admin'], users: [] })),
65
+ invalidate: vi.fn(),
66
+ validateRolesYaml: (t: string) => realAccess.validateRolesYaml(t),
67
+ referencesToRole: vi.fn(async () => []),
68
+ } as unknown as IAccessControl;
69
+
70
+ const resolve = (wsRel: string) => path.join(workspaceDir, wsRel);
71
+ // Workspace-rooted file tree (paths workspace-relative, skipping `.git`) — the
72
+ // candidate source getRoster's reference scan walks. No `.md` in this fixture,
73
+ // so the scan finds nothing, which is what these route tests expect.
74
+ const buildTree = async (absDir: string): Promise<FileTreeEntry> => {
75
+ const rel = path.relative(workspaceDir, absDir).replace(/\\/g, '/');
76
+ const children: FileTreeEntry[] = [];
77
+ for (const e of await fs.readdir(absDir, { withFileTypes: true })) {
78
+ if (e.name === '.git') continue;
79
+ const childAbs = path.join(absDir, e.name);
80
+ if (e.isDirectory()) children.push(await buildTree(childAbs));
81
+ else if (e.isFile()) {
82
+ children.push({
83
+ name: e.name,
84
+ relativePath: path.relative(workspaceDir, childAbs).replace(/\\/g, '/'),
85
+ type: 'file',
86
+ });
87
+ }
88
+ }
89
+ return { name: path.basename(absDir), relativePath: rel || '.', type: 'directory', children };
90
+ };
91
+ const workspaceService = {
92
+ getOrCreateForBranch: vi.fn(async () => ({})),
93
+ getWorkspacePath: vi.fn(async () => workspaceDir),
94
+ listFiles: vi.fn(async () => buildTree(workspaceDir)),
95
+ readFile: vi.fn(async (_id: string, wsRel: string) => fs.readFile(resolve(wsRel), 'utf-8')),
96
+ writeFile: vi.fn(async (_id: string, wsRel: string, c: string) => {
97
+ await fs.mkdir(path.dirname(resolve(wsRel)), { recursive: true });
98
+ await fs.writeFile(resolve(wsRel), c, 'utf-8');
99
+ }),
100
+ } as unknown as WorkspaceService;
101
+
102
+ const authService = { getUserById: vi.fn(async () => ADMIN) } as unknown as AuthService;
103
+
104
+ // Lock holder tracked so the service's getLock pre-check passes; the single-
105
+ // file write itself lands on disk via LockingFilesystem → LocalFilesystem.
106
+ let holder: { id: string; name: string } | null = null;
107
+ const lockRow = (h: { id: string; name: string }) => ({ holderUserId: h.id, holderName: h.name });
108
+ const workflowService = {
109
+ getLock: vi.fn(async () => (holder ? lockRow(holder) : null)),
110
+ acquireLock: vi.fn(async (_w: string, _b: string, _p: string, user: { id: string; name: string }) =>
111
+ holder && holder.id !== user.id
112
+ ? { acquired: false, lock: lockRow(holder) }
113
+ : ((holder = user), { acquired: true, lock: lockRow(user) }),
114
+ ),
115
+ releaseLock: vi.fn(async () => void (holder = null)),
116
+ releaseLockNoCommit: vi.fn(async () => void (holder = null)),
117
+ // Write-free: the lock-aware filesystem writes to disk; this just commits the
118
+ // dirty tree. Not exercised by these route tests (no rename), but kept honest.
119
+ commitChanges: vi.fn(async () => ({})),
120
+ } as unknown as WorkflowService;
121
+
122
+ const eventBus = { emit: vi.fn() } as unknown as WorkflowEventBus;
123
+ const db = {} as unknown as Database;
124
+
125
+ const app = express();
126
+ app.use(express.json());
127
+ app.use('/api', (req, _res, next) => {
128
+ (req as unknown as { userId: string }).userId = ADMIN.id;
129
+ next();
130
+ });
131
+ app.use('/api', createAccessRoutes(accessControl, workspaceService, authService, workflowService, eventBus, db, KB));
132
+
133
+ const server = await new Promise<Server>((resolve) => {
134
+ const s = app.listen(0, () => resolve(s));
135
+ });
136
+ const addr = server.address() as AddressInfo;
137
+ return { server, baseUrl: `http://127.0.0.1:${addr.port}` };
138
+ }
139
+
140
+ function close(s: Server): Promise<void> {
141
+ return new Promise((resolve, reject) => s.close((e) => (e ? reject(e) : resolve())));
142
+ }
143
+
144
+ describe('/api/access/roles routes', () => {
145
+ let server: Server | null = null;
146
+ afterEach(async () => {
147
+ if (server) await close(server);
148
+ server = null;
149
+ await Promise.all(tmpDirs.splice(0).map((d) => fs.rm(d, { recursive: true, force: true })));
150
+ });
151
+
152
+ it('GET returns the roster with Admin marked', async () => {
153
+ const h = await makeHarness();
154
+ server = h.server;
155
+ const res = await fetch(`${h.baseUrl}/api/access/roles`);
156
+ expect(res.status).toBe(200);
157
+ const body = (await res.json()) as { roles: { canonical: string; isAdmin: boolean }[] };
158
+ expect(body.roles.map((r) => r.canonical)).toEqual(['admin', 'sales']);
159
+ expect(body.roles.find((r) => r.canonical === 'admin')!.isAdmin).toBe(true);
160
+ });
161
+
162
+ it('a non-admin is refused on GET roster too — roster is admin-only (CodeRabbit)', async () => {
163
+ const h = await makeHarness({ isAdmin: false });
164
+ server = h.server;
165
+ const res = await fetch(`${h.baseUrl}/api/access/roles`);
166
+ expect(res.status).toBe(403);
167
+ });
168
+
169
+ it('a non-admin is refused on every mutating route (403)', async () => {
170
+ const h = await makeHarness({ isAdmin: false });
171
+ server = h.server;
172
+ const post = await fetch(`${h.baseUrl}/api/access/roles`, {
173
+ method: 'POST',
174
+ headers: { 'Content-Type': 'application/json' },
175
+ body: JSON.stringify({ displayName: 'Marketing' }),
176
+ });
177
+ expect(post.status).toBe(403);
178
+ const del = await fetch(`${h.baseUrl}/api/access/roles/sales`, { method: 'DELETE' });
179
+ expect(del.status).toBe(403);
180
+ });
181
+
182
+ it('create with a reserved name → 422', async () => {
183
+ const h = await makeHarness();
184
+ server = h.server;
185
+ const res = await fetch(`${h.baseUrl}/api/access/roles`, {
186
+ method: 'POST',
187
+ headers: { 'Content-Type': 'application/json' },
188
+ body: JSON.stringify({ displayName: 'everyone' }),
189
+ });
190
+ expect(res.status).toBe(422);
191
+ });
192
+
193
+ it('delete Admin → 422', async () => {
194
+ const h = await makeHarness();
195
+ server = h.server;
196
+ const res = await fetch(`${h.baseUrl}/api/access/roles/admin`, { method: 'DELETE' });
197
+ expect(res.status).toBe(422);
198
+ });
199
+
200
+ it('removing own last Admin membership → 409 { kind: self-admin-removal }', async () => {
201
+ const h = await makeHarness();
202
+ server = h.server;
203
+ // Remove the OTHER admin first so razvan is the only one, then razvan
204
+ // removing himself trips the last-member guard (422). To hit the 409
205
+ // self-removal path we remove juan (razvan removing juan is not self) —
206
+ // instead razvan removing himself while juan remains is the self case:
207
+ const res = await fetch(
208
+ `${h.baseUrl}/api/access/roles/admin/members/${encodeURIComponent('razvan@bevel.software')}`,
209
+ { method: 'DELETE' },
210
+ );
211
+ expect(res.status).toBe(409);
212
+ const body = (await res.json()) as { kind?: string };
213
+ expect(body.kind).toBe('self-admin-removal');
214
+ });
215
+
216
+ it('create a role then add a member → 200 fresh roster', async () => {
217
+ const h = await makeHarness();
218
+ server = h.server;
219
+ const created = await fetch(`${h.baseUrl}/api/access/roles`, {
220
+ method: 'POST',
221
+ headers: { 'Content-Type': 'application/json' },
222
+ body: JSON.stringify({ displayName: 'Marketing' }),
223
+ });
224
+ expect(created.status).toBe(200);
225
+ const add = await fetch(`${h.baseUrl}/api/access/roles/marketing/members`, {
226
+ method: 'POST',
227
+ headers: { 'Content-Type': 'application/json' },
228
+ body: JSON.stringify({ email: 'mkt@example.com' }),
229
+ });
230
+ expect(add.status).toBe(200);
231
+ const body = (await add.json()) as { roles: { canonical: string; members: string[] }[] };
232
+ expect(body.roles.find((r) => r.canonical === 'marketing')!.members).toContain('mkt@example.com');
233
+ });
234
+ });
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Access-control service interface. The implementation reads `roles.yaml`
3
+ * and the `access.md` tree from the per-user `knowledge-base` clone and
4
+ * resolves write permissions against them.
5
+ *
6
+ * All `relativePath` arguments are repo-relative POSIX paths inside the KB
7
+ * repo (e.g. `Knowledge/Sales/Foo.md`, `roles.yaml`) — NOT workspace-relative
8
+ * (the workspace contains `knowledge-base/` and other reserved files).
9
+ */
10
+ /**
11
+ * ONE place a principal is NAMED for a verb — the unit a Remove acts on. The
12
+ * source answers exactly one question — WHICH FILE holds this entry — and is MECE
13
+ * over the two editable locations:
14
+ * - `direct` — the principal is named in the target's own access file (the
15
+ * file's frontmatter, or the folder's own `access.md`).
16
+ * Removable in place.
17
+ * - `ancestor` — the principal is named in a parent folder's `access.md` at
18
+ * `path` (repo-relative). Removable by editing that ancestor
19
+ * (cascade up) or by a `deny` at the target.
20
+ *
21
+ * Only a principal NAMED in a file (a direct user grant `Name <email>`, or a
22
+ * group/role token) produces sources. A USER who merely RESOLVES to access via a
23
+ * group they belong to, the built-in `everyone`, or admin-rescue is NOT a
24
+ * per-target file entry and produces NO source (the group itself shows as its own
25
+ * row instead).
26
+ */
27
+ export type GrantSource =
28
+ | { kind: 'direct' }
29
+ | { kind: 'ancestor'; path: string };
30
+
31
+ /**
32
+ * EVERY scope that grants a principal one verb, ordered **closest-first** — so
33
+ * `[0]` is the effective (winning) source and the rest are scopes that ALSO grant
34
+ * it. This is deliberately not collapsed to the winner: "can they?" needs only
35
+ * the closest scope, but "where would I edit to fully remove them?" needs all of
36
+ * them, and the share dialog needs to tell "granted here" apart from "granted
37
+ * here AND also inherited from a parent" (which a single winning source cannot —
38
+ * both would read `direct`). Callers collapse as they need: the winner is `[0]`,
39
+ * removability-here is `[0].kind === 'direct'`, the still-inherited remainder
40
+ * after removing a direct grant is the `ancestor` entries in the tail. Never
41
+ * empty (a verb with no grant is omitted from `GrantSources` entirely).
42
+ */
43
+ export type VerbSources = GrantSource[];
44
+
45
+ /** Whether the dialog target is a folder or a file — mirrors the mutation side. */
46
+ export type AccessTargetKind = 'folder' | 'file';
47
+
48
+ /** A principal in the resolver's canonical terms (mirrors `access-splice.ts`). */
49
+ export type GrantPrincipal =
50
+ | { kind: 'user'; email: string }
51
+ | { kind: 'role'; role: string };
52
+
53
+ /**
54
+ * Per-verb sources of a principal's access on a target. Only verbs the principal
55
+ * actually holds (via a named file entry) appear; each maps to the closest-first
56
+ * list of scopes that grant it (see `VerbSources`). A principal with no named
57
+ * grant at all yields an empty map.
58
+ */
59
+ export type GrantSources = Partial<Record<'read' | 'write' | 'download' | 'owner', VerbSources>>;
60
+
61
+ export interface IAccessControl {
62
+ /** True iff `userEmail` has `write` on `relativePath` per the current access tree. */
63
+ canWrite(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
64
+
65
+ /**
66
+ * True iff `userEmail` may READ `relativePath` per the current access tree.
67
+ *
68
+ * `read` is **default-deny**: a path with no effective `read:`, `write:`, or
69
+ * `owner:` grant is not readable. To make content public, declare the
70
+ * built-in role `everyone` under `read:`. Resolution is closeness-first then
71
+ * tier (email > role > everyone within a scope), folding `write:`/`owner:` in
72
+ * as implicit read grants (grant-only — a write/owner denial never strips a
73
+ * read grant). No admin rescue. The file viewer, embed surface, and the
74
+ * agent's read tools all gate on this.
75
+ */
76
+ canRead(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
77
+
78
+ /**
79
+ * Batched `canRead` — one config load per call, same default-deny semantics,
80
+ * INCLUDING each node's own frontmatter `read:` rules. Per-file frontmatter
81
+ * reads are memoized per workspace (dropped on `invalidate`, TTL-bounded),
82
+ * so the file-explorer tree — which resolves every KB file on each load —
83
+ * uses this too: a file the caller can't read (whether the rule lives in a
84
+ * folder `access.md` or in the file's own frontmatter) never appears in the
85
+ * tree, matching what the content routes will enforce on open.
86
+ */
87
+ canReadBatch(
88
+ workspaceId: string,
89
+ userEmail: string,
90
+ relativePaths: string[],
91
+ ): Promise<Map<string, boolean>>;
92
+
93
+ /**
94
+ * Batched canWrite for PR diffs and commit-time gating. Returns a map keyed
95
+ * by the input paths, with `true` / `false` for each. Reuses one config
96
+ * load per call.
97
+ */
98
+ canWriteBatch(
99
+ workspaceId: string,
100
+ userEmail: string,
101
+ relativePaths: string[],
102
+ ): Promise<Map<string, boolean>>;
103
+
104
+ /**
105
+ * True iff `userEmail` has `download` permission on `relativePath` per
106
+ * the current access tree. Resolution mirrors `canWrite`: walks repo
107
+ * root → file directory, accumulates per-principal state from each
108
+ * `access.md`'s `download:` list. Independent of `write` — granting
109
+ * write does NOT imply download, mirroring the way the verbs are
110
+ * separately listed in access.md. An `owner:` grant DOES imply download
111
+ * (owner is a superset of write + download).
112
+ *
113
+ * No admin override (unlike `canWrite` on `access.md` / `roles.yaml`,
114
+ * which admin-rescues). Admins are only granted download if an
115
+ * access.md explicitly lists them (directly or as an owner).
116
+ */
117
+ canDownload(
118
+ workspaceId: string,
119
+ userEmail: string,
120
+ relativePath: string,
121
+ ): Promise<boolean>;
122
+
123
+ /**
124
+ * True iff `userEmail` is an `owner` of `relativePath` per the current
125
+ * access tree, resolved from the `owner:` lists alone (the `write` /
126
+ * `download` lists do NOT confer ownership — only the reverse holds).
127
+ *
128
+ * Ownership is a superset of write + download AND a contact designation:
129
+ * owners can do everything writers can (edit, approve / reject change
130
+ * requests, appear in the affected-owners block) and are surfaced in the
131
+ * UI so users know who to contact for more information on a node.
132
+ */
133
+ canOwner(
134
+ workspaceId: string,
135
+ userEmail: string,
136
+ relativePath: string,
137
+ ): Promise<boolean>;
138
+
139
+ /**
140
+ * The set of principals (roles + direct users) that own this path — i.e.
141
+ * who to contact about it. Resolved from `owner:` lists only. Used by the
142
+ * file viewer to render the "owners / contact" affordance.
143
+ */
144
+ eligibleOwners(
145
+ workspaceId: string,
146
+ relativePath: string,
147
+ ): Promise<{ roles: string[]; users: { name: string; email: string }[] }>;
148
+
149
+ /**
150
+ * The set of principals (roles + direct users) with `write` on this path.
151
+ * Used by PR reviewer routing and the per-file approval UI to render
152
+ * "who can approve this file". Owners are included here — an `owner:`
153
+ * grant confers write, so owners can approve / reject the same files
154
+ * writers can.
155
+ */
156
+ eligibleWriters(
157
+ workspaceId: string,
158
+ relativePath: string,
159
+ ): Promise<{ roles: string[]; users: { name: string; email: string }[] }>;
160
+
161
+ /**
162
+ * Answers the file viewer's "who can see this?" affordance. `restricted` is
163
+ * false only when `read: everyone` applies without an effective user-level
164
+ * denial — the node is readable by all signed-in users, and the role/user
165
+ * lists are empty because their content would be meaningless. When
166
+ * `restricted` is true the lists name the principals (roles + direct users)
167
+ * that may read, with owners folded in (an `owner:` grant confers read). The
168
+ * lists may be empty for a default-denied path with no grants.
169
+ */
170
+ eligibleReaders(
171
+ workspaceId: string,
172
+ relativePath: string,
173
+ ): Promise<{ restricted: boolean; roles: string[]; users: { name: string; email: string }[] }>;
174
+
175
+ /**
176
+ * The set of principals (roles + direct users) with `download` on this path.
177
+ * Resolved from the `download:` lists with owners folded in — an `owner:`
178
+ * grant confers download (owner ⊇ download), but `write` does NOT (download
179
+ * is independent of write). The lists may be empty for a path with no
180
+ * download grant. Used by the share UI to render the per-principal download
181
+ * checkbox.
182
+ */
183
+ eligibleDownloaders(
184
+ workspaceId: string,
185
+ relativePath: string,
186
+ ): Promise<{ roles: string[]; users: { name: string; email: string }[] }>;
187
+
188
+ /**
189
+ * Finite expanded email set for configured users who could approve this path
190
+ * — role members + direct user grants, minus anyone denied. The built-in
191
+ * `everyone` role can grant arbitrary signed-in users and therefore cannot be
192
+ * fully enumerated here. Returns a map from email to display info (display
193
+ * name comes from direct user grants; role members have no name attached so
194
+ * the entry is `{ name: '', email }`). Used by PR reviewer routing in
195
+ * `createPr` to translate paths into a list of candidate GitHub logins.
196
+ */
197
+ eligibleWriterEmails(
198
+ workspaceId: string,
199
+ relativePath: string,
200
+ ): Promise<Map<string, { name: string; email: string }>>;
201
+
202
+ /**
203
+ * Finite expanded email set for configured users who own this path — role
204
+ * members + direct user grants, minus anyone denied. Mirrors
205
+ * `eligibleWriterEmails` but for the `owner:` verb. Used by KB citation
206
+ * revalidation to resolve who should refresh a section, expanding role-only
207
+ * ownership into concrete emails so the future notifier has someone to
208
+ * contact. As with `eligibleWriterEmails`, `everyone` is a valid `owner:`
209
+ * value but grants arbitrary signed-in users and therefore cannot be fully
210
+ * enumerated — this map may be incomplete when such a grant applies.
211
+ */
212
+ eligibleOwnerEmails(
213
+ workspaceId: string,
214
+ relativePath: string,
215
+ ): Promise<Map<string, { name: string; email: string }>>;
216
+
217
+ /**
218
+ * Resolve WHERE a principal's effective access on a target comes from, per
219
+ * verb. Powers the share dialog's inherited-vs-direct distinction and the
220
+ * revoke route's "is this revoke a no-op because it's inherited?" decision.
221
+ *
222
+ * `kind` selects the target semantics: a `file` target's most-specific scope
223
+ * is its own frontmatter; a `folder` target's is its own `access.md`. Both
224
+ * read the same closeness-first resolver, so the returned source for each
225
+ * verb reflects the SAME precedence every other access decision uses.
226
+ *
227
+ * Returns only the verbs the principal effectively holds; a verb with no
228
+ * access is omitted. A principal with no access anywhere yields an empty map.
229
+ */
230
+ grantSources(
231
+ workspaceId: string,
232
+ kind: AccessTargetKind,
233
+ relativePath: string,
234
+ principal: GrantPrincipal,
235
+ ): Promise<GrantSources>;
236
+
237
+ /**
238
+ * Drop a workspace's cached model. Call after operations that mutate
239
+ * `roles.yaml` / `access.md` (commit, push, pull) or change which copy of
240
+ * those files the working tree sees (branch switch).
241
+ */
242
+ invalidate(workspaceId: string): void;
243
+
244
+ /**
245
+ * Validate a candidate `roles.yaml` text against the resolver's OWN loader,
246
+ * WITHOUT writing it. The single safety gate behind the admin Roles & Members
247
+ * surface: `roles.yaml` has no admin-rescue and `loadModel` hard-throws on a
248
+ * parse failure (which `isAdmin` swallows into `false` for everyone), so a
249
+ * malformed write would be a permanent, app-wide, in-app-unrecoverable admin
250
+ * lockout. The roles-admin service runs this on every candidate file before
251
+ * the atomic commit; on any error it writes zero bytes. Because the gate IS the
252
+ * resolver's loader, any text that passes is provably loadable.
253
+ */
254
+ validateRolesYaml(text: string): { ok: true } | { ok: false; errors: string[] };
255
+
256
+ /**
257
+ * Find every folder-`access.md` reference to a role, by canonical name, in the
258
+ * cached model. ADVISORY ONLY — it powers the delete-confirmation "N rules
259
+ * will be ignored" warning, and it may UNDERCOUNT: `collectAccessFiles` only
260
+ * walks files literally named `access.md`, so a role granted in a node's OWN
261
+ * frontmatter is a real grant this scan misses. That is acceptable for a
262
+ * non-fatal warning. It must NOT be used to gate the rename rewrite — that
263
+ * needs the sound git-grep scan in `roles-admin.service.ts`, which also covers
264
+ * node frontmatter. An undercount there would silently orphan access.
265
+ */
266
+ referencesToRole(
267
+ workspaceId: string,
268
+ canonicalRole: string,
269
+ ): Promise<{ path: string; verb: string }[]>;
270
+
271
+ /**
272
+ * Enumerate the grantable principals known to the KB, for the share-dialog
273
+ * autocomplete. `groups` are the declared `roles.yaml` role display names
274
+ * (the built-in `everyone` is excluded — it isn't grantable from the UI).
275
+ * `people` are every email named in `roles.yaml` (name defaults to the local
276
+ * part) unioned with every `Name <email>` grant in any `access.md` (named).
277
+ * The login-only `users` table is unioned in by the caller — this method
278
+ * covers the KB-canonical people the users table misses.
279
+ */
280
+ kbPrincipals(
281
+ workspaceId: string,
282
+ ): Promise<{ groups: string[]; people: { name: string; email: string }[] }>;
283
+
284
+ /**
285
+ * Reverse-lookup an email by its SHA-256 hash (per `hashEmail` semantics)
286
+ * against the working-tree access tree. Scans every email mentioned in
287
+ * `roles.yaml` plus every direct user grant in any `access.md`.
288
+ *
289
+ * Used by PR author attribution as a fallback when the users-table lookup
290
+ * misses — a teammate listed in `roles.yaml` may not yet have a row in
291
+ * the `users` table (e.g. they haven't logged in since a DB reseed, but
292
+ * their JWT is still valid). Returns null when no hash matches.
293
+ */
294
+ findEmailByHash(
295
+ workspaceId: string,
296
+ hash: string,
297
+ ): Promise<{ email: string; displayName: string } | null>;
298
+
299
+ /**
300
+ * Resolve write permission for a path against the access tree **as it
301
+ * exists on a specific git ref** (typically a PR head SHA). Used by PR
302
+ * per-file approval so the gate reflects the access rules that would be
303
+ * in force post-merge, not the reviewer's working tree.
304
+ *
305
+ * Returns null when the ref doesn't resolve or required config files
306
+ * (`roles.yaml`) are absent at that ref — the caller treats null as
307
+ * "can't determine eligibility, fall through to deny".
308
+ */
309
+ canWriteAtRef(
310
+ workspaceId: string,
311
+ ref: string,
312
+ userEmail: string,
313
+ relativePath: string,
314
+ ): Promise<boolean | null>;
315
+
316
+ /**
317
+ * Resolve read permission for a path against the access tree **as it exists
318
+ * on a specific git ref**. Mirror of `canWriteAtRef` for parity — read gates
319
+ * that need post-merge semantics (rather than the reviewer's working tree)
320
+ * use this. Returns null with the same semantics as `canWriteAtRef` (ref
321
+ * unresolvable / required config absent → caller treats null as deny).
322
+ */
323
+ canReadAtRef(
324
+ workspaceId: string,
325
+ ref: string,
326
+ userEmail: string,
327
+ relativePath: string,
328
+ ): Promise<boolean | null>;
329
+
330
+ /**
331
+ * Batched variant of `canWriteAtRef`. Loads the access tree at `ref` once
332
+ * and checks every path against it. Returns null with the same semantics
333
+ * as `canWriteAtRef` — the whole call returns null if the ref can't be
334
+ * resolved. Used by `/pr/mine` so we don't fan out one `git ls-tree` per
335
+ * PR.
336
+ */
337
+ canWriteBatchAtRef(
338
+ workspaceId: string,
339
+ ref: string,
340
+ userEmail: string,
341
+ relativePaths: string[],
342
+ ): Promise<Map<string, boolean> | null>;
343
+
344
+ /**
345
+ * The set of principals with `write` on this path as of `ref`. Used by PR
346
+ * reviewer routing and the per-file approval UI rendered against the PR
347
+ * head. Returns null with the same null-semantics as `canWriteAtRef`.
348
+ */
349
+ eligibleWritersAtRef(
350
+ workspaceId: string,
351
+ ref: string,
352
+ relativePath: string,
353
+ ): Promise<{ roles: string[]; users: { name: string; email: string }[] } | null>;
354
+
355
+ /**
356
+ * Batched: resolve eligible writers + expanded emails for a list of paths
357
+ * at a specific ref in one model load. Returns null with the same
358
+ * semantics as `eligibleWritersAtRef` (ref unresolvable).
359
+ *
360
+ * Used by PR per-file approval (`getApprovalStates`) so a 10-file PR
361
+ * costs one `git ls-tree` round-trip instead of ten.
362
+ */
363
+ eligibleWritersForPathsAtRef(
364
+ workspaceId: string,
365
+ ref: string,
366
+ relativePaths: string[],
367
+ ): Promise<Map<
368
+ string,
369
+ {
370
+ roles: string[];
371
+ users: { name: string; email: string }[];
372
+ /** Expanded email set — role members + direct user grants minus denials. */
373
+ emails: Set<string>;
374
+ /**
375
+ * Named individuals (roles.yaml members + inline emails) who do NOT hold
376
+ * write here. Used to subtract from a blanket `everyone` grant: it
377
+ * catches exclusions at any tier — `deny email`, `deny role`, or a
378
+ * `deny everyone` carve-out — not just direct user denials.
379
+ */
380
+ excludedEmails?: Set<string>;
381
+ }
382
+ > | null>;
383
+ }