@bevel-software/platform-core-backend 0.4.0 → 0.5.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 (305) hide show
  1. package/dist/core/core-ports.d.ts +15 -0
  2. package/dist/core/core-ports.d.ts.map +1 -1
  3. package/dist/core/core-ports.js.map +1 -1
  4. package/dist/core/create-core-server.d.ts.map +1 -1
  5. package/dist/core/create-core-server.js +40 -6
  6. package/dist/core/create-core-server.js.map +1 -1
  7. package/dist/core/create-core-services.d.ts +17 -1
  8. package/dist/core/create-core-services.d.ts.map +1 -1
  9. package/dist/core/create-core-services.js +153 -29
  10. package/dist/core/create-core-services.js.map +1 -1
  11. package/dist/core-config.d.ts +70 -21
  12. package/dist/core-config.d.ts.map +1 -1
  13. package/dist/core-config.js +134 -58
  14. package/dist/core-config.js.map +1 -1
  15. package/dist/modules/access/access-control.interface.d.ts +6 -0
  16. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  17. package/dist/modules/access/access-control.service.d.ts +74 -5
  18. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  19. package/dist/modules/access/access-control.service.js +116 -15
  20. package/dist/modules/access/access-control.service.js.map +1 -1
  21. package/dist/modules/access/access-declarations.d.ts +93 -0
  22. package/dist/modules/access/access-declarations.d.ts.map +1 -0
  23. package/dist/modules/access/access-declarations.js +168 -0
  24. package/dist/modules/access/access-declarations.js.map +1 -0
  25. package/dist/modules/access/access-mutation.service.js +4 -4
  26. package/dist/modules/access/access-mutation.service.js.map +1 -1
  27. package/dist/modules/access/access-splice.d.ts +16 -1
  28. package/dist/modules/access/access-splice.d.ts.map +1 -1
  29. package/dist/modules/access/access-splice.js +40 -21
  30. package/dist/modules/access/access-splice.js.map +1 -1
  31. package/dist/modules/access/access.routes.d.ts.map +1 -1
  32. package/dist/modules/access/access.routes.js +51 -0
  33. package/dist/modules/access/access.routes.js.map +1 -1
  34. package/dist/modules/access/creator-access.d.ts +8 -0
  35. package/dist/modules/access/creator-access.d.ts.map +1 -1
  36. package/dist/modules/access/creator-access.js +21 -2
  37. package/dist/modules/access/creator-access.js.map +1 -1
  38. package/dist/modules/admin/admin-access.service.d.ts +1 -1
  39. package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
  40. package/dist/modules/admin/admin-access.service.js +3 -2
  41. package/dist/modules/admin/admin-access.service.js.map +1 -1
  42. package/dist/modules/auth/auth.routes.d.ts.map +1 -1
  43. package/dist/modules/auth/auth.routes.js +50 -1
  44. package/dist/modules/auth/auth.routes.js.map +1 -1
  45. package/dist/modules/auth/auth.service.d.ts +39 -10
  46. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  47. package/dist/modules/auth/auth.service.js +38 -16
  48. package/dist/modules/auth/auth.service.js.map +1 -1
  49. package/dist/modules/database/core-schema.d.ts +124 -0
  50. package/dist/modules/database/core-schema.d.ts.map +1 -1
  51. package/dist/modules/database/core-schema.js +45 -0
  52. package/dist/modules/database/core-schema.js.map +1 -1
  53. package/dist/modules/groups/group-provision.service.d.ts +130 -0
  54. package/dist/modules/groups/group-provision.service.d.ts.map +1 -0
  55. package/dist/modules/groups/group-provision.service.js +288 -0
  56. package/dist/modules/groups/group-provision.service.js.map +1 -0
  57. package/dist/modules/groups/groups.contract.d.ts +106 -0
  58. package/dist/modules/groups/groups.contract.d.ts.map +1 -0
  59. package/dist/modules/groups/groups.contract.js +36 -0
  60. package/dist/modules/groups/groups.contract.js.map +1 -0
  61. package/dist/modules/groups/groups.routes.d.ts +42 -0
  62. package/dist/modules/groups/groups.routes.d.ts.map +1 -0
  63. package/dist/modules/groups/groups.routes.js +379 -0
  64. package/dist/modules/groups/groups.routes.js.map +1 -0
  65. package/dist/modules/groups/groups.service.d.ts +60 -0
  66. package/dist/modules/groups/groups.service.d.ts.map +1 -0
  67. package/dist/modules/groups/groups.service.js +172 -0
  68. package/dist/modules/groups/groups.service.js.map +1 -0
  69. package/dist/modules/groups/index.d.ts +7 -0
  70. package/dist/modules/groups/index.d.ts.map +1 -0
  71. package/dist/modules/groups/index.js +6 -0
  72. package/dist/modules/groups/index.js.map +1 -0
  73. package/dist/modules/groups/join-proposals.d.ts +53 -0
  74. package/dist/modules/groups/join-proposals.d.ts.map +1 -0
  75. package/dist/modules/groups/join-proposals.js +67 -0
  76. package/dist/modules/groups/join-proposals.js.map +1 -0
  77. package/dist/modules/groups/join-requests.service.d.ts +81 -0
  78. package/dist/modules/groups/join-requests.service.d.ts.map +1 -0
  79. package/dist/modules/groups/join-requests.service.js +135 -0
  80. package/dist/modules/groups/join-requests.service.js.map +1 -0
  81. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +20 -0
  82. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  83. package/dist/modules/secrets-vault/secrets-vault.routes.js +59 -11
  84. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  85. package/dist/modules/settings/deployment-settings.service.d.ts +129 -0
  86. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -0
  87. package/dist/modules/settings/deployment-settings.service.js +368 -0
  88. package/dist/modules/settings/deployment-settings.service.js.map +1 -0
  89. package/dist/modules/settings/setup.routes.d.ts +49 -0
  90. package/dist/modules/settings/setup.routes.d.ts.map +1 -0
  91. package/dist/modules/settings/setup.routes.js +292 -0
  92. package/dist/modules/settings/setup.routes.js.map +1 -0
  93. package/dist/modules/skills/index.d.ts +2 -1
  94. package/dist/modules/skills/index.d.ts.map +1 -1
  95. package/dist/modules/skills/index.js +1 -0
  96. package/dist/modules/skills/index.js.map +1 -1
  97. package/dist/modules/skills/pending-skills.service.d.ts +40 -0
  98. package/dist/modules/skills/pending-skills.service.d.ts.map +1 -0
  99. package/dist/modules/skills/pending-skills.service.js +147 -0
  100. package/dist/modules/skills/pending-skills.service.js.map +1 -0
  101. package/dist/modules/skills/skills.contract.d.ts +32 -3
  102. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  103. package/dist/modules/skills/skills.contract.js +1 -1
  104. package/dist/modules/skills/skills.routes.d.ts +3 -2
  105. package/dist/modules/skills/skills.routes.d.ts.map +1 -1
  106. package/dist/modules/skills/skills.routes.js +18 -1
  107. package/dist/modules/skills/skills.routes.js.map +1 -1
  108. package/dist/modules/skills/skills.service.d.ts +22 -0
  109. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  110. package/dist/modules/skills/skills.service.js +24 -12
  111. package/dist/modules/skills/skills.service.js.map +1 -1
  112. package/dist/modules/tool-manuals/index.d.ts +1 -1
  113. package/dist/modules/tool-manuals/index.d.ts.map +1 -1
  114. package/dist/modules/tool-manuals/index.js.map +1 -1
  115. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +47 -2
  116. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  117. package/dist/modules/tool-manuals/tool-manuals.contract.js +1 -1
  118. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +4 -0
  119. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  120. package/dist/modules/tool-manuals/tool-manuals.routes.js +23 -0
  121. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  122. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +3 -1
  123. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  124. package/dist/modules/tool-manuals/tool-manuals.service.js +84 -17
  125. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  126. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  127. package/dist/modules/tool-manuals/tool-manuals.tools.js +6 -2
  128. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  129. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  130. package/dist/modules/workflow/agent-tools/workflow.tools.js +4 -2
  131. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  132. package/dist/modules/workflow/event-bus.d.ts +11 -0
  133. package/dist/modules/workflow/event-bus.d.ts.map +1 -1
  134. package/dist/modules/workflow/event-bus.js +22 -0
  135. package/dist/modules/workflow/event-bus.js.map +1 -1
  136. package/dist/modules/workflow/file-lock.service.d.ts +9 -0
  137. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  138. package/dist/modules/workflow/file-lock.service.js +16 -0
  139. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  140. package/dist/modules/workflow/git/branch-name.d.ts +1 -1
  141. package/dist/modules/workflow/git/branch-name.d.ts.map +1 -1
  142. package/dist/modules/workflow/git/branch-name.js +1 -1
  143. package/dist/modules/workflow/git/branch-name.js.map +1 -1
  144. package/dist/modules/workflow/git/git.service.d.ts +31 -2
  145. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  146. package/dist/modules/workflow/git/git.service.js +157 -54
  147. package/dist/modules/workflow/git/git.service.js.map +1 -1
  148. package/dist/modules/workflow/git/pull-request.service.d.ts +12 -6
  149. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  150. package/dist/modules/workflow/git/pull-request.service.js +19 -9
  151. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  152. package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
  153. package/dist/modules/workflow/review-workflow/review-workflow.service.js +12 -3
  154. package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
  155. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  156. package/dist/modules/workflow/workflow.routes.js +95 -14
  157. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  158. package/dist/modules/workflow/workflow.service.d.ts +97 -5
  159. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  160. package/dist/modules/workflow/workflow.service.js +393 -114
  161. package/dist/modules/workflow/workflow.service.js.map +1 -1
  162. package/dist/modules/workspace/bevel-ignore.d.ts +5 -0
  163. package/dist/modules/workspace/bevel-ignore.d.ts.map +1 -1
  164. package/dist/modules/workspace/bevel-ignore.js +5 -1
  165. package/dist/modules/workspace/bevel-ignore.js.map +1 -1
  166. package/dist/modules/workspace/kb-seed.interface.d.ts +1 -1
  167. package/dist/modules/workspace/kb-seed.service.d.ts +60 -5
  168. package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -1
  169. package/dist/modules/workspace/kb-seed.service.js +228 -51
  170. package/dist/modules/workspace/kb-seed.service.js.map +1 -1
  171. package/dist/modules/workspace/workspace.routes.d.ts +2 -1
  172. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  173. package/dist/modules/workspace/workspace.routes.js +51 -18
  174. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  175. package/dist/modules/workspace/workspace.service.d.ts +16 -4
  176. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  177. package/dist/modules/workspace/workspace.service.js +36 -9
  178. package/dist/modules/workspace/workspace.service.js.map +1 -1
  179. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  180. package/dist/modules/workspace/workspace.tools.js +8 -3
  181. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  182. package/dist/shared/kb-layout.test.js +2 -2
  183. package/dist/test-setup.d.ts +2 -0
  184. package/dist/test-setup.d.ts.map +1 -0
  185. package/dist/test-setup.js +18 -0
  186. package/dist/test-setup.js.map +1 -0
  187. package/kb-template/.bevelignore +6 -2
  188. package/kb-template/AGENTS.md +272 -0
  189. package/kb-template/KnowledgeBase/How to get started.md +65 -0
  190. package/kb-template/access.md +36 -36
  191. package/migrations/0002_user_onboarding_done.sql +1 -0
  192. package/migrations/0003_deployment_settings.sql +9 -0
  193. package/migrations/meta/0001_snapshot.json +1486 -0
  194. package/migrations/meta/0002_snapshot.json +1493 -0
  195. package/migrations/meta/0003_snapshot.json +1552 -0
  196. package/migrations/meta/_journal.json +15 -1
  197. package/package.json +3 -3
  198. package/src/__tests__/branch-model.test.ts +79 -0
  199. package/src/__tests__/core-config.admin.test.ts +114 -0
  200. package/src/__tests__/database-url.test.ts +70 -0
  201. package/src/core/core-ports.ts +15 -0
  202. package/src/core/create-core-server.ts +55 -6
  203. package/src/core/create-core-services.ts +201 -36
  204. package/src/core-config.ts +139 -59
  205. package/src/modules/access/__tests__/access-declarations.test.ts +195 -0
  206. package/src/modules/access/__tests__/access-md-format.test.ts +191 -0
  207. package/src/modules/access/__tests__/access-splice.test.ts +21 -0
  208. package/src/modules/access/__tests__/access.routes.overrides.test.ts +214 -0
  209. package/src/modules/access/access-control.interface.ts +11 -0
  210. package/src/modules/access/access-control.service.ts +113 -15
  211. package/src/modules/access/access-declarations.ts +251 -0
  212. package/src/modules/access/access-mutation.service.ts +4 -4
  213. package/src/modules/access/access-splice.ts +64 -21
  214. package/src/modules/access/access.routes.ts +61 -0
  215. package/src/modules/access/creator-access.ts +22 -2
  216. package/src/modules/admin/admin-access.service.ts +4 -3
  217. package/src/modules/auth/__tests__/auth.service.test.ts +57 -0
  218. package/src/modules/auth/__tests__/onboarding-done.route.test.ts +147 -0
  219. package/src/modules/auth/auth.routes.ts +50 -1
  220. package/src/modules/auth/auth.service.ts +55 -17
  221. package/src/modules/database/core-schema.ts +46 -0
  222. package/src/modules/groups/__tests__/group-index.service.test.ts +225 -0
  223. package/src/modules/groups/__tests__/group-provision.service.test.ts +247 -0
  224. package/src/modules/groups/__tests__/groups.routes.test.ts +493 -0
  225. package/src/modules/groups/__tests__/join-proposals.test.ts +101 -0
  226. package/src/modules/groups/__tests__/join-requests.service.test.ts +175 -0
  227. package/src/modules/groups/group-provision.service.ts +328 -0
  228. package/src/modules/groups/groups.contract.ts +107 -0
  229. package/src/modules/groups/groups.routes.ts +433 -0
  230. package/src/modules/groups/groups.service.ts +193 -0
  231. package/src/modules/groups/index.ts +17 -0
  232. package/src/modules/groups/join-proposals.ts +114 -0
  233. package/src/modules/groups/join-requests.service.ts +185 -0
  234. package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +283 -0
  235. package/src/modules/secrets-vault/secrets-vault.routes.ts +68 -12
  236. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +256 -0
  237. package/src/modules/settings/__tests__/setup.routes.test.ts +201 -0
  238. package/src/modules/settings/deployment-settings.service.ts +419 -0
  239. package/src/modules/settings/setup.routes.ts +317 -0
  240. package/src/modules/skills/__tests__/pending-skills.service.test.ts +240 -0
  241. package/src/modules/skills/__tests__/skills.service.test.ts +13 -13
  242. package/src/modules/skills/index.ts +3 -0
  243. package/src/modules/skills/pending-skills.service.ts +168 -0
  244. package/src/modules/skills/skills.contract.ts +34 -3
  245. package/src/modules/skills/skills.routes.ts +23 -2
  246. package/src/modules/skills/skills.service.ts +24 -16
  247. package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +262 -0
  248. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -2
  249. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +61 -23
  250. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +156 -156
  251. package/src/modules/tool-manuals/index.ts +2 -0
  252. package/src/modules/tool-manuals/tool-manuals.contract.ts +50 -2
  253. package/src/modules/tool-manuals/tool-manuals.routes.ts +21 -0
  254. package/src/modules/tool-manuals/tool-manuals.service.ts +86 -17
  255. package/src/modules/tool-manuals/tool-manuals.tools.ts +206 -202
  256. package/src/modules/workflow/__tests__/event-bus.test.ts +35 -0
  257. package/src/modules/workflow/__tests__/pending-commits.enqueue-if-absent.test.ts +82 -72
  258. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +295 -5
  259. package/src/modules/workflow/agent-tools/workflow.tools.ts +4 -2
  260. package/src/modules/workflow/event-bus.ts +25 -0
  261. package/src/modules/workflow/file-lock.service.ts +17 -0
  262. package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +9 -49
  263. package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +101 -0
  264. package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +219 -211
  265. package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +132 -0
  266. package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +4 -2
  267. package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +275 -272
  268. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +311 -306
  269. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +44 -0
  270. package/src/modules/workflow/git/branch-name.ts +5 -1
  271. package/src/modules/workflow/git/git.service.ts +172 -64
  272. package/src/modules/workflow/git/pull-request.service.ts +22 -11
  273. package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +4 -1
  274. package/src/modules/workflow/review-workflow/review-workflow.service.ts +12 -3
  275. package/src/modules/workflow/workflow.routes.ts +91 -13
  276. package/src/modules/workflow/workflow.service.ts +365 -19
  277. package/src/modules/workspace/__tests__/kb-seed.service.test.ts +255 -24
  278. package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +236 -233
  279. package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +179 -176
  280. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +320 -303
  281. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +337 -276
  282. package/src/modules/workspace/__tests__/workspace.tools.test.ts +14 -6
  283. package/src/modules/workspace/bevel-ignore.ts +66 -62
  284. package/src/modules/workspace/kb-seed.interface.ts +1 -1
  285. package/src/modules/workspace/kb-seed.service.ts +247 -53
  286. package/src/modules/workspace/workspace.routes.ts +54 -18
  287. package/src/modules/workspace/workspace.service.ts +45 -7
  288. package/src/modules/workspace/workspace.tools.ts +922 -917
  289. package/src/shared/__tests__/frontmatter-id.test.ts +53 -0
  290. package/src/shared/__tests__/join-request.test.ts +96 -0
  291. package/src/shared/__tests__/kb-layout.group.test.ts +45 -0
  292. package/src/shared/kb-layout.test.ts +2 -2
  293. package/src/test-setup.ts +18 -0
  294. package/kb-template/Agents/README.md +0 -38
  295. package/kb-template/CLAUDE.md +0 -419
  296. package/kb-template/Data/.gitkeep +0 -0
  297. package/kb-template/Data/README.md +0 -39
  298. package/kb-template/KnowledgeBase/README.md +0 -37
  299. package/kb-template/Pipelines/.gitkeep +0 -0
  300. package/kb-template/Pipelines/README.md +0 -38
  301. package/kb-template/Skills/.gitkeep +0 -0
  302. package/kb-template/Skills/README.md +0 -32
  303. package/kb-template/Tools/.gitkeep +0 -0
  304. package/kb-template/Tools/README.md +0 -42
  305. /package/kb-template/{Agents → Groups}/.gitkeep +0 -0
@@ -1,3 +1,21 @@
1
+ /**
2
+ * The Postgres connection string: `DATABASE_URL` if given, otherwise built
3
+ * from the `POSTGRES_*` parts.
4
+ *
5
+ * The composition lives HERE rather than in docker-compose because expressing
6
+ * it there needed a nested default — `${DATABASE_URL:-postgresql://${POSTGRES_USER:-…}…}`
7
+ * — and deployment UIs that scan compose with a regex rather than a YAML
8
+ * parser truncate that at the first closing brace, offering the operator a
9
+ * variable whose value is the fragment `postgresql://${POSTGRES_USER:-bevel`.
10
+ * A malformed connection string presented as configuration is worse than no
11
+ * configuration at all.
12
+ *
13
+ * It is also the better home for it: the parts are URL-ENCODED, which shell
14
+ * interpolation cannot do — a password containing `@`, `/` or `:` silently
15
+ * produced an unparseable URL, and "check your password" is not the error
16
+ * anyone got.
17
+ */
18
+ export declare function resolveDatabaseUrl(env?: NodeJS.ProcessEnv): string;
1
19
  /**
2
20
  * Configuration for the CORE platform: the git-backed workspace/workflow,
3
21
  * skills, tools, secrets vault, access control, and the MCP surface. Contains
@@ -36,16 +54,31 @@ export declare class CoreConfig {
36
54
  readonly spillRoot: string;
37
55
  readonly jwtSecret: string;
38
56
  /**
39
- * Bootstrap admin credential, checked directly against the environment at
40
- * login time (never stored). Lets a fresh deployment sign in before any
41
- * account exists; that admin (or any user with the Admin role in
42
- * `roles.yaml`) then creates per-user accounts from Roles & Members.
43
- * Remove EITHER variable and the credential stops working immediately —
44
- * accounts created in the database are unaffected. The email is also
45
- * always recognized as an admin (see AdminAccessService), so a fresh KB
46
- * whose `roles.yaml` doesn't list it yet is still administrable.
57
+ * The deployment's owner. REQUIRED — three separate jobs rest on it, and a
58
+ * deployment without one has no way to be administered:
59
+ *
60
+ * - always recognized as an admin (see AdminAccessService), whatever the
61
+ * sign-in method, so a KB whose `roles.yaml` does not list them yet is
62
+ * still administrable;
63
+ * - written as the sole Admin into the `roles.yaml` generated when an EMPTY
64
+ * KB remote is seeded (this replaced `SEED_ADMIN_EMAILS`, which asked for
65
+ * the same answer a second time);
66
+ * - half of the bootstrap password credential below.
47
67
  */
48
68
  readonly adminEmail: string;
69
+ /**
70
+ * Password half of the bootstrap credential, checked directly against the
71
+ * environment at login time (never stored) so a fresh deployment can sign in
72
+ * before any account exists. Captured ONCE here, so changing or unsetting it
73
+ * takes effect on the next restart rather than at once — accounts in the
74
+ * database are unaffected either way.
75
+ *
76
+ * Required only when password login is ENABLED. An SSO-only deployment
77
+ * (`LOGIN_PASSWORD=false`) would otherwise have to mint a shared password
78
+ * the server is configured to reject — an unused credential someone still
79
+ * has to store and rotate. The admin identity above is required either way,
80
+ * so "there is always an identifiable admin" holds regardless.
81
+ */
49
82
  readonly adminPassword: string;
50
83
  /**
51
84
  * Generic OIDC single sign-on (any spec-compliant provider: Entra, Okta,
@@ -81,13 +114,6 @@ export declare class CoreConfig {
81
114
  * existing one. Override with `KB_TEMPLATE_DIR`.
82
115
  */
83
116
  readonly kbTemplateDir: string;
84
- /**
85
- * Admin emails written into the generated `roles.yaml` when a fresh KB repo is
86
- * seeded. Comma/whitespace-separated. A freshly-seeded repo with no Admin is
87
- * unusable (access resolution requires ≥1 Admin), so seeding an EMPTY remote
88
- * fails fast when this is empty. Not needed once the remote is already seeded.
89
- */
90
- readonly seedAdminEmails: string[];
91
117
  /**
92
118
  * Ontology-session boundary kill-switch. When true (default), an agent run
93
119
  * that has read across more than one ontology can no longer write. A no-op on
@@ -107,10 +133,24 @@ export declare class CoreConfig {
107
133
  */
108
134
  readonly loginPasswordEnabled: boolean;
109
135
  /**
110
- * Optional allow-list of email domains. When non-empty, ONLY emails whose
111
- * domain matches (exactly, or as a subdomain) may log in via ANY method
112
- * (shared-password or SSO). Comma/whitespace-separated; empty (default)
113
- * allows any email. A leading `@` or `.` on an entry is tolerated, so
136
+ * Optional allow-list of email domains for SSO — part of the OIDC
137
+ * configuration, and only meaningful alongside it.
138
+ *
139
+ * SSO AUTO-PROVISIONS: `loginWithSso` upserts the account on first sign-in,
140
+ * with no admin approval step. Against a single-tenant issuer the issuer is
141
+ * already the boundary and this is belt-and-braces; against a multi-tenant
142
+ * one (Google, the Entra `common` endpoint, Auth0 with social connections)
143
+ * it is the ONLY boundary — without it, anyone the issuer will authenticate
144
+ * provisions themselves into the deployment.
145
+ *
146
+ * Deliberately NOT applied to the other two entry points. An account an
147
+ * admin created is vetted by the act of creating it, and password login can
148
+ * only reach an account that already exists — so a check there would gate
149
+ * nothing while being able to lock out a bootstrap admin whose own address
150
+ * sits outside the list.
151
+ *
152
+ * Comma/whitespace-separated; empty (default) allows any email. Matches the
153
+ * domain exactly or as a subdomain, and a leading `@` or `.` is tolerated:
114
154
  * `ALLOWED_EMAIL_DOMAINS=bevel.software, example.com` works as expected.
115
155
  */
116
156
  readonly allowedEmailDomains: string[];
@@ -119,8 +159,12 @@ export declare class CoreConfig {
119
159
  * secrets: the secrets-vault values and the MCP OAuth client secrets/tokens.
120
160
  * Read from `SECRETS_ENC_KEY`, falling back to the legacy
121
161
  * `CONNECTOR_CONFIG_ENC_KEY` → `SHAREPOINT_TOKEN_ENC_KEY` chain so existing
122
- * deploys keep decrypting without re-keying. Empty = secret values can't be
123
- * saved (a clear error surfaces only when a secret is actually written/read).
162
+ * deploys keep decrypting without re-keying.
163
+ *
164
+ * REQUIRED. It used to be optional, with the failure surfacing only when
165
+ * somebody wrote a secret — which now includes the git token typed into the
166
+ * setup screen, so an unset key turns the first-run flow into a dead end at
167
+ * the last step. Refusing to boot names the variable instead.
124
168
  */
125
169
  readonly secretsEncKey: string;
126
170
  /**
@@ -158,6 +202,11 @@ export declare class CoreConfig {
158
202
  get uploadTokenPrefix(): string;
159
203
  /** Prefix for MCP OAuth access tokens: `<tenant>-mcp_`. */
160
204
  get mcpOAuthTokenPrefix(): string;
205
+ /**
206
+ * Validate the KB-identity inputs THAT WERE SUPPLIED. Absent is fine — the
207
+ * setup screen collects them — but a present-and-malformed value fails at
208
+ * boot rather than later, as a clone error nobody can read.
209
+ */
161
210
  private validateKbIdentity;
162
211
  }
163
212
  //# sourceMappingURL=core-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"core-config.d.ts","sourceRoot":"","sources":["../src/core-config.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,iHAAiH;IACjH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IACnC;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IACvC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;;IAiHnC,mEAAmE;IACnE,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED,mEAAmE;IACnE,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,uEAAuE;IACvE,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,2DAA2D;IAC3D,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,OAAO,CAAC,kBAAkB;CA4B3B"}
1
+ {"version":3,"file":"core-config.d.ts","sourceRoot":"","sources":["../src/core-config.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAU/E;AAED;;;;;;GAMG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,iHAAiH;IACjH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IACvC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IACvC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;;IAuInC,mEAAmE;IACnE,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED,mEAAmE;IACnE,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,uEAAuE;IACvE,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,2DAA2D;IAC3D,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CA0B3B"}
@@ -4,6 +4,35 @@ import { fileURLToPath } from 'node:url';
4
4
  import { defaultKbTemplateDir } from './assets.js';
5
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
6
  dotenv.config({ path: path.resolve(__dirname, '../../../.env') });
7
+ /**
8
+ * The Postgres connection string: `DATABASE_URL` if given, otherwise built
9
+ * from the `POSTGRES_*` parts.
10
+ *
11
+ * The composition lives HERE rather than in docker-compose because expressing
12
+ * it there needed a nested default — `${DATABASE_URL:-postgresql://${POSTGRES_USER:-…}…}`
13
+ * — and deployment UIs that scan compose with a regex rather than a YAML
14
+ * parser truncate that at the first closing brace, offering the operator a
15
+ * variable whose value is the fragment `postgresql://${POSTGRES_USER:-bevel`.
16
+ * A malformed connection string presented as configuration is worse than no
17
+ * configuration at all.
18
+ *
19
+ * It is also the better home for it: the parts are URL-ENCODED, which shell
20
+ * interpolation cannot do — a password containing `@`, `/` or `:` silently
21
+ * produced an unparseable URL, and "check your password" is not the error
22
+ * anyone got.
23
+ */
24
+ export function resolveDatabaseUrl(env = process.env) {
25
+ const explicit = (env.DATABASE_URL || '').trim();
26
+ if (explicit)
27
+ return explicit;
28
+ const user = encodeURIComponent(env.POSTGRES_USER || 'bevel');
29
+ const password = encodeURIComponent(env.POSTGRES_PASSWORD || 'bevel');
30
+ // `localhost` suits a local `pnpm dev`; compose passes the service name.
31
+ const host = (env.POSTGRES_HOST || 'localhost').trim();
32
+ const port = (env.POSTGRES_PORT || '5432').trim();
33
+ const database = encodeURIComponent(env.POSTGRES_DB || 'bevel');
34
+ return `postgresql://${user}:${password}@${host}:${port}/${database}`;
35
+ }
7
36
  /**
8
37
  * Configuration for the CORE platform: the git-backed workspace/workflow,
9
38
  * skills, tools, secrets vault, access control, and the MCP surface. Contains
@@ -42,16 +71,31 @@ export class CoreConfig {
42
71
  spillRoot;
43
72
  jwtSecret;
44
73
  /**
45
- * Bootstrap admin credential, checked directly against the environment at
46
- * login time (never stored). Lets a fresh deployment sign in before any
47
- * account exists; that admin (or any user with the Admin role in
48
- * `roles.yaml`) then creates per-user accounts from Roles & Members.
49
- * Remove EITHER variable and the credential stops working immediately —
50
- * accounts created in the database are unaffected. The email is also
51
- * always recognized as an admin (see AdminAccessService), so a fresh KB
52
- * whose `roles.yaml` doesn't list it yet is still administrable.
74
+ * The deployment's owner. REQUIRED — three separate jobs rest on it, and a
75
+ * deployment without one has no way to be administered:
76
+ *
77
+ * - always recognized as an admin (see AdminAccessService), whatever the
78
+ * sign-in method, so a KB whose `roles.yaml` does not list them yet is
79
+ * still administrable;
80
+ * - written as the sole Admin into the `roles.yaml` generated when an EMPTY
81
+ * KB remote is seeded (this replaced `SEED_ADMIN_EMAILS`, which asked for
82
+ * the same answer a second time);
83
+ * - half of the bootstrap password credential below.
53
84
  */
54
85
  adminEmail;
86
+ /**
87
+ * Password half of the bootstrap credential, checked directly against the
88
+ * environment at login time (never stored) so a fresh deployment can sign in
89
+ * before any account exists. Captured ONCE here, so changing or unsetting it
90
+ * takes effect on the next restart rather than at once — accounts in the
91
+ * database are unaffected either way.
92
+ *
93
+ * Required only when password login is ENABLED. An SSO-only deployment
94
+ * (`LOGIN_PASSWORD=false`) would otherwise have to mint a shared password
95
+ * the server is configured to reject — an unused credential someone still
96
+ * has to store and rotate. The admin identity above is required either way,
97
+ * so "there is always an identifiable admin" holds regardless.
98
+ */
55
99
  adminPassword;
56
100
  /**
57
101
  * Generic OIDC single sign-on (any spec-compliant provider: Entra, Okta,
@@ -87,13 +131,6 @@ export class CoreConfig {
87
131
  * existing one. Override with `KB_TEMPLATE_DIR`.
88
132
  */
89
133
  kbTemplateDir;
90
- /**
91
- * Admin emails written into the generated `roles.yaml` when a fresh KB repo is
92
- * seeded. Comma/whitespace-separated. A freshly-seeded repo with no Admin is
93
- * unusable (access resolution requires ≥1 Admin), so seeding an EMPTY remote
94
- * fails fast when this is empty. Not needed once the remote is already seeded.
95
- */
96
- seedAdminEmails;
97
134
  /**
98
135
  * Ontology-session boundary kill-switch. When true (default), an agent run
99
136
  * that has read across more than one ontology can no longer write. A no-op on
@@ -113,10 +150,24 @@ export class CoreConfig {
113
150
  */
114
151
  loginPasswordEnabled;
115
152
  /**
116
- * Optional allow-list of email domains. When non-empty, ONLY emails whose
117
- * domain matches (exactly, or as a subdomain) may log in via ANY method
118
- * (shared-password or SSO). Comma/whitespace-separated; empty (default)
119
- * allows any email. A leading `@` or `.` on an entry is tolerated, so
153
+ * Optional allow-list of email domains for SSO — part of the OIDC
154
+ * configuration, and only meaningful alongside it.
155
+ *
156
+ * SSO AUTO-PROVISIONS: `loginWithSso` upserts the account on first sign-in,
157
+ * with no admin approval step. Against a single-tenant issuer the issuer is
158
+ * already the boundary and this is belt-and-braces; against a multi-tenant
159
+ * one (Google, the Entra `common` endpoint, Auth0 with social connections)
160
+ * it is the ONLY boundary — without it, anyone the issuer will authenticate
161
+ * provisions themselves into the deployment.
162
+ *
163
+ * Deliberately NOT applied to the other two entry points. An account an
164
+ * admin created is vetted by the act of creating it, and password login can
165
+ * only reach an account that already exists — so a check there would gate
166
+ * nothing while being able to lock out a bootstrap admin whose own address
167
+ * sits outside the list.
168
+ *
169
+ * Comma/whitespace-separated; empty (default) allows any email. Matches the
170
+ * domain exactly or as a subdomain, and a leading `@` or `.` is tolerated:
120
171
  * `ALLOWED_EMAIL_DOMAINS=bevel.software, example.com` works as expected.
121
172
  */
122
173
  allowedEmailDomains;
@@ -125,8 +176,12 @@ export class CoreConfig {
125
176
  * secrets: the secrets-vault values and the MCP OAuth client secrets/tokens.
126
177
  * Read from `SECRETS_ENC_KEY`, falling back to the legacy
127
178
  * `CONNECTOR_CONFIG_ENC_KEY` → `SHAREPOINT_TOKEN_ENC_KEY` chain so existing
128
- * deploys keep decrypting without re-keying. Empty = secret values can't be
129
- * saved (a clear error surfaces only when a secret is actually written/read).
179
+ * deploys keep decrypting without re-keying.
180
+ *
181
+ * REQUIRED. It used to be optional, with the failure surfacing only when
182
+ * somebody wrote a secret — which now includes the git token typed into the
183
+ * setup screen, so an unset key turns the first-run flow into a dead end at
184
+ * the last step. Refusing to boot names the variable instead.
130
185
  */
131
186
  secretsEncKey;
132
187
  /**
@@ -157,7 +212,7 @@ export class CoreConfig {
157
212
  publicFrontendUrl;
158
213
  constructor() {
159
214
  this.port = parseInt(process.env.PORT || '3001', 10);
160
- this.databaseUrl = process.env.DATABASE_URL || 'postgresql://bevel:bevel@localhost:5432/bevel';
215
+ this.databaseUrl = resolveDatabaseUrl();
161
216
  this.nodeEnv = process.env.NODE_ENV || 'development';
162
217
  this.tenantId = (process.env.TENANT_ID || 'bevel').trim().toLowerCase();
163
218
  if (!/^[a-z0-9]+$/.test(this.tenantId)) {
@@ -166,12 +221,36 @@ export class CoreConfig {
166
221
  this.workspacesRoot = process.env.WORKSPACES_ROOT || path.resolve(process.cwd(), 'workspaces');
167
222
  this.backupsRoot = process.env.BACKUPS_ROOT || path.resolve(this.workspacesRoot, '..', 'backups');
168
223
  this.spillRoot = process.env.SPILL_ROOT || path.resolve(this.workspacesRoot, '..', 'tool-chain-spills');
169
- this.jwtSecret = process.env.JWT_SECRET || '';
224
+ // Required, and checked BEFORE the auth routes it signs for are ever
225
+ // mounted. Empty, the first login attempt fails deep inside the JWT library
226
+ // with a message about a missing key — a boot error naming the variable is
227
+ // the same information, hours earlier.
228
+ this.jwtSecret = (process.env.JWT_SECRET || '').trim();
229
+ if (!this.jwtSecret) {
230
+ throw new Error('JWT_SECRET is required — it signs login sessions. Generate one with: ' +
231
+ `node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"`);
232
+ }
233
+ // Parsed here rather than beside the other toggles below: whether the
234
+ // bootstrap PASSWORD is required depends on it.
235
+ this.loginPasswordEnabled =
236
+ (process.env.LOGIN_PASSWORD ?? 'true').trim().toLowerCase() !== 'false';
170
237
  this.adminEmail = (process.env.ADMIN_EMAIL || '').trim().toLowerCase();
171
238
  this.adminPassword = process.env.ADMIN_PASSWORD || '';
172
- if (this.adminEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.adminEmail)) {
239
+ if (!this.adminEmail) {
240
+ throw new Error('ADMIN_EMAIL is required — the address that owns this deployment. It is ' +
241
+ 'always treated as an admin (whatever the sign-in method) and is written ' +
242
+ 'as the initial Admin when an empty knowledge-base repo is seeded.');
243
+ }
244
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.adminEmail)) {
173
245
  throw new Error(`ADMIN_EMAIL is not a valid email: "${this.adminEmail}"`);
174
246
  }
247
+ // Only when password login can actually be used. An SSO-only deployment
248
+ // has no use for this value and should not have to hold one.
249
+ if (this.loginPasswordEnabled && !this.adminPassword) {
250
+ throw new Error('ADMIN_PASSWORD is required while password login is enabled — it is the ' +
251
+ 'credential that signs in before any account exists. Set it, or set ' +
252
+ 'LOGIN_PASSWORD=false if this deployment signs in through SSO only.');
253
+ }
175
254
  this.oidcIssuerUrl = (process.env.OIDC_ISSUER_URL || '').trim().replace(/\/+$/, '');
176
255
  this.oidcClientId = (process.env.OIDC_CLIENT_ID || '').trim();
177
256
  this.oidcClientSecret = (process.env.OIDC_CLIENT_SECRET || '').trim();
@@ -186,13 +265,14 @@ export class CoreConfig {
186
265
  throw new Error(`OIDC_ISSUER_URL is not a valid URL: "${this.oidcIssuerUrl}"`);
187
266
  }
188
267
  }
189
- // No default: the KB repo is deployment-specific, and a wrong fallback
190
- // would surface much later as a confusing clone failure. Fail at boot.
268
+ // No default, and no longer fatal when absent: an unconfigured deployment
269
+ // boots into the setup screen, where an admin supplies it (and where the
270
+ // value can be verified against the real remote before it is saved). What
271
+ // stays fatal is a value that is present and WRONG — see
272
+ // `validateKbIdentity` — because that surfaces later as a confusing clone
273
+ // failure instead of a clear one now.
191
274
  this.kbRepoUrl = (process.env.KB_REPO_URL || '').trim();
192
- if (this.kbRepoUrl === '') {
193
- throw new Error('KB_REPO_URL is required — the https clone/push URL of the git repository that stores your knowledge base.');
194
- }
195
- this.kbDirName = process.env.KB_DIR_NAME || 'knowledge-base';
275
+ this.kbDirName = (process.env.KB_DIR_NAME || '').trim();
196
276
  // Provider-neutral git token: operators can set GIT_TOKEN (or the legacy
197
277
  // GITHUB_TOKEN / GH_TOKEN). Normalize onto GITHUB_TOKEN — the name the
198
278
  // credential helper and every `$GITHUB_TOKEN` read + redaction use — so all
@@ -211,14 +291,8 @@ export class CoreConfig {
211
291
  // Default: the `kb-template/` folder shipped inside this package (works
212
292
  // both from src/ and compiled dist/ — see assets.ts).
213
293
  this.kbTemplateDir = process.env.KB_TEMPLATE_DIR || defaultKbTemplateDir();
214
- this.seedAdminEmails = (process.env.SEED_ADMIN_EMAILS || '')
215
- .split(/[\s,]+/)
216
- .map((e) => e.trim().toLowerCase())
217
- .filter((e) => e.length > 0);
218
294
  this.ontologySessionBlock =
219
295
  (process.env.ONTOLOGY_SESSION_BLOCK ?? 'true').trim().toLowerCase() !== 'false';
220
- this.loginPasswordEnabled =
221
- (process.env.LOGIN_PASSWORD ?? 'true').trim().toLowerCase() !== 'false';
222
296
  this.allowedEmailDomains = (process.env.ALLOWED_EMAIL_DOMAINS || '')
223
297
  .split(/[\s,]+/)
224
298
  .map((d) => d.trim().toLowerCase().replace(/^[@.]+/, ''))
@@ -227,6 +301,11 @@ export class CoreConfig {
227
301
  process.env.CONNECTOR_CONFIG_ENC_KEY ||
228
302
  process.env.SHAREPOINT_TOKEN_ENC_KEY ||
229
303
  '').trim();
304
+ if (!this.secretsEncKey) {
305
+ throw new Error('SECRETS_ENC_KEY is required — it encrypts the secrets vault, the MCP OAuth ' +
306
+ 'tokens and the git credential saved from the setup screen. Generate one ' +
307
+ `with: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"`);
308
+ }
230
309
  this.internalTokenSecret = (process.env.INTERNAL_TOKEN_SECRET || '').trim();
231
310
  this.trustProxy = (process.env.TRUST_PROXY || '').trim();
232
311
  this.publicBackendUrl = (process.env.PUBLIC_BACKEND_URL || `http://localhost:${this.port}`)
@@ -249,13 +328,6 @@ export class CoreConfig {
249
328
  throw new Error(`${name} is not a valid URL: "${value}"`);
250
329
  }
251
330
  }
252
- // Validate format now so a typo surfaces at boot, not at first-seed time.
253
- // Emptiness is NOT an error here: an already-seeded remote never needs it.
254
- for (const email of this.seedAdminEmails) {
255
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
256
- throw new Error(`SEED_ADMIN_EMAILS contains an invalid email: "${email}"`);
257
- }
258
- }
259
331
  this.validateKbIdentity();
260
332
  }
261
333
  /** Prefix for external API keys (connection keys): `<tenant>_`. */
@@ -274,25 +346,29 @@ export class CoreConfig {
274
346
  get mcpOAuthTokenPrefix() {
275
347
  return `${this.tenantId}-mcp_`;
276
348
  }
349
+ /**
350
+ * Validate the KB-identity inputs THAT WERE SUPPLIED. Absent is fine — the
351
+ * setup screen collects them — but a present-and-malformed value fails at
352
+ * boot rather than later, as a clone error nobody can read.
353
+ */
277
354
  validateKbIdentity() {
278
- // Validate the two KB-identity inputs up front: `kbRepoUrl` (the clone/push
279
- // URL) must be a valid https URL, and `kbDirName` (the dir the clone lives
280
- // under in each workspace) must be a single safe path segment. A bad value
281
- // in either otherwise surfaces much later as a confusing clone/path failure.
282
- let parsed;
283
- try {
284
- parsed = new URL(this.kbRepoUrl);
285
- }
286
- catch {
287
- throw new Error(`KB_REPO_URL is not a valid URL: ${this.kbRepoUrl}`);
288
- }
289
- if (parsed.protocol !== 'https:') {
290
- throw new Error(`KB_REPO_URL must use https://: ${this.kbRepoUrl}`);
355
+ if (this.kbRepoUrl) {
356
+ let parsed;
357
+ try {
358
+ parsed = new URL(this.kbRepoUrl);
359
+ }
360
+ catch {
361
+ throw new Error(`KB_REPO_URL is not a valid URL: ${this.kbRepoUrl}`);
362
+ }
363
+ if (parsed.protocol !== 'https:') {
364
+ throw new Error(`KB_REPO_URL must use https://: ${this.kbRepoUrl}`);
365
+ }
291
366
  }
292
367
  // Joined with workspace paths via path.join — separators or ".." would let it
293
368
  // escape the workspace dir.
294
- if (!this.kbDirName ||
295
- this.kbDirName === '.' ||
369
+ if (!this.kbDirName)
370
+ return;
371
+ if (this.kbDirName === '.' ||
296
372
  this.kbDirName === '..' ||
297
373
  this.kbDirName.includes('/') ||
298
374
  this.kbDirName.includes('\\') ||
@@ -1 +1 @@
1
- {"version":3,"file":"core-config.js","sourceRoot":"","sources":["../src/core-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core-config.js","sourceRoot":"","sources":["../src/core-config.ts"],"names":[],"mappings":"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"}
@@ -116,6 +116,12 @@ export interface IAccessControl {
116
116
  * UI so users know who to contact for more information on a node.
117
117
  */
118
118
  canOwner(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
119
+ /**
120
+ * Batched `canOwner` — one config load per call, same `owner:`-lists-only
121
+ * resolution (no admin rescue). Used by group enumeration to answer "which
122
+ * of these folders does the caller own?" without one model load per group.
123
+ */
124
+ canOwnerBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
119
125
  /**
120
126
  * The set of principals (roles + direct users) that own this path — i.e.
121
127
  * who to contact about it. Resolved from `owner:` lists only. Used by the
@@ -1 +1 @@
1
- {"version":3,"file":"access-control.interface.d.ts","sourceRoot":"","sources":["../../../src/modules/access/access-control.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"access-control.interface.d.ts","sourceRoot":"","sources":["../../../src/modules/access/access-control.interface.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,18 @@ export interface UserEntry {
53
53
  deny: boolean;
54
54
  }
55
55
  export type ParsedEntry = RoleEntry | UserEntry;
56
+ export interface AccessFile {
57
+ /** repo-relative POSIX path — e.g. `access.md`, `Knowledge/Sales/access.md`. */
58
+ path: string;
59
+ /** repo-relative POSIX directory — `''` for root. */
60
+ dir: string;
61
+ /**
62
+ * Verb → list of grants/denials. Always carries an entry for every
63
+ * known verb (empty array when the verb wasn't declared in the file) so
64
+ * the resolver doesn't need to null-check at every chain step.
65
+ */
66
+ entries: Record<Verb, ParsedEntry[]>;
67
+ }
56
68
  export declare function isAccessMdPath(p: string): boolean;
57
69
  interface RolesIndex {
58
70
  byCanonical: Map<string, {
@@ -80,6 +92,8 @@ export declare function extractFrontmatter(text: string): {
80
92
  ok: false;
81
93
  error: string;
82
94
  };
95
+ /** The text AFTER the closing frontmatter fence ('' when there is no fence). */
96
+ export declare function bodyAfterFrontmatter(text: string): string;
83
97
  export declare function canonicalRoleName(name: string): string;
84
98
  export declare function canonicalEmail(email: string): string;
85
99
  export declare function parseAccessEntry(raw: unknown): {
@@ -96,6 +110,59 @@ export declare function parseRolesYaml(text: string): {
96
110
  ok: false;
97
111
  errors: string[];
98
112
  };
113
+ /**
114
+ * Does an `access.md` body declare access rules — i.e. is the file in the NEW
115
+ * (body-governs-the-folder) format?
116
+ *
117
+ * The two-format story: historically the FRONTMATTER carried the folder's
118
+ * rules and the file could not govern itself. The new format follows the
119
+ * convention every other file uses — frontmatter is about the FILE (who may
120
+ * read/write `access.md` itself), and the content (the body) is the folder's
121
+ * rules. The compat rule, applied per file: **when the body is not parsable as
122
+ * rules, the frontmatter is resolved for the folder as before.**
123
+ *
124
+ * "Parsable as rules" is deliberately shallow — the body YAML-parses to a
125
+ * mapping that names at least one known verb. A prose body (the repo-root
126
+ * README-style file) fails the YAML parse or carries no verb key and stays
127
+ * legacy. A body that DOES name a verb has claimed to be rules: shape errors
128
+ * inside it (a scalar verb, a malformed entry) are then hard parse ERRORS of
129
+ * the file, never a silent fallback to the frontmatter — falling back would
130
+ * let a typo in the body hand the folder to the frontmatter's (possibly
131
+ * `read: everyone`) self-rules.
132
+ */
133
+ export declare function accessMdDeclaresBodyRules(text: string): boolean;
134
+ /**
135
+ * The access verbs an `access.md` declares FOR ITSELF — its frontmatter, and
136
+ * only in the new format (body-governed). A legacy file cannot govern itself:
137
+ * its frontmatter IS the folder's rules, so returning them as own-entries
138
+ * would double-apply them at the file scope.
139
+ *
140
+ * Parsed forgivingly (like node frontmatter): the new-format frontmatter may
141
+ * carry non-access keys, and a typo there must not make the file unreadable.
142
+ */
143
+ export declare function accessMdSelfEntries(text: string): Record<Verb, ParsedEntry[]> | null;
144
+ /**
145
+ * Parse one `access.md`'s FOLDER rules into its per-verb entry lists.
146
+ *
147
+ * Two formats (see {@link accessMdDeclaresBodyRules}): when the body declares
148
+ * rules, the body is parsed (new format — frontmatter then governs the file
149
+ * itself via {@link accessMdSelfEntries}); otherwise the frontmatter is parsed
150
+ * (legacy format), exactly as before.
151
+ *
152
+ * Exported so read-only surfaces can report WHERE rules are declared without
153
+ * reimplementing the parse (see `access-declarations.ts`). Exporting changes
154
+ * nothing about resolution — this is the same function the resolver builds its
155
+ * model from, so a display of declarations can never drift from the rules that
156
+ * are actually enforced.
157
+ */
158
+ export declare function parseAccessFile(text: string, relativePath: string): {
159
+ ok: true;
160
+ file: AccessFile;
161
+ warnings: string[];
162
+ } | {
163
+ ok: false;
164
+ errors: string[];
165
+ };
99
166
  /**
100
167
  * Per-verb access entries declared in a single node file's *own* frontmatter
101
168
  * (the same YAML block that carries `nodeType:`). This is the most-specific
@@ -187,6 +254,7 @@ export declare class AccessControlService implements IAccessControl {
187
254
  canReadBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
188
255
  canWriteBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
189
256
  canDownload(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
257
+ canOwnerBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
190
258
  canOwner(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
191
259
  eligibleOwners(workspaceId: string, relativePath: string): Promise<{
192
260
  roles: string[];
@@ -260,11 +328,12 @@ export declare class AccessControlService implements IAccessControl {
260
328
  private collectAccessFiles;
261
329
  private repoDir;
262
330
  /**
263
- * Read the access verbs a node file declares in its own frontmatter from the
264
- * working tree. Returns null when the file has no per-file access config
265
- * (the common case). `access.md` and `roles.yaml` are skipped — `access.md`
266
- * frontmatter governs its directory (handled by the dir chain), not itself,
267
- * and `roles.yaml` is not a node.
331
+ * Read the access verbs a file declares FOR ITSELF from the working tree.
332
+ * Returns null when the file has no per-file access config (the common
333
+ * case). `roles.yaml` is never a node; an `access.md` governs itself only
334
+ * in the new (body-governed) format, where its frontmatter is self-access —
335
+ * see {@link accessMdSelfEntries}. A legacy `access.md` still yields null:
336
+ * its frontmatter IS the folder rules the dir chain already applies.
268
337
  */
269
338
  private readOwnEntries;
270
339
  /**