@bevel-software/platform-core-backend 0.22.0 → 0.23.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 (325) hide show
  1. package/dist/core/core-ports.d.ts +11 -1
  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 +3 -3
  5. package/dist/core/create-core-server.d.ts.map +1 -1
  6. package/dist/core/create-core-server.js +30 -11
  7. package/dist/core/create-core-server.js.map +1 -1
  8. package/dist/core/create-core-services.d.ts +9 -2
  9. package/dist/core/create-core-services.d.ts.map +1 -1
  10. package/dist/core/create-core-services.js +112 -23
  11. package/dist/core/create-core-services.js.map +1 -1
  12. package/dist/core/lifecycle.d.ts +34 -1
  13. package/dist/core/lifecycle.d.ts.map +1 -1
  14. package/dist/core/lifecycle.js +89 -13
  15. package/dist/core/lifecycle.js.map +1 -1
  16. package/dist/core-config.d.ts +0 -12
  17. package/dist/core-config.d.ts.map +1 -1
  18. package/dist/core-config.js +11 -13
  19. package/dist/core-config.js.map +1 -1
  20. package/dist/index.d.ts +3 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/modules/access/access-control.interface.d.ts +42 -12
  25. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  26. package/dist/modules/access/access-control.service.d.ts +67 -10
  27. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  28. package/dist/modules/access/access-control.service.js +214 -35
  29. package/dist/modules/access/access-control.service.js.map +1 -1
  30. package/dist/modules/access/access.routes.d.ts.map +1 -1
  31. package/dist/modules/access/access.routes.js +13 -15
  32. package/dist/modules/access/access.routes.js.map +1 -1
  33. package/dist/modules/auth/account-admission.d.ts +58 -7
  34. package/dist/modules/auth/account-admission.d.ts.map +1 -1
  35. package/dist/modules/auth/account-admission.js +44 -1
  36. package/dist/modules/auth/account-admission.js.map +1 -1
  37. package/dist/modules/auth/account.routes.d.ts +1 -1
  38. package/dist/modules/auth/account.routes.d.ts.map +1 -1
  39. package/dist/modules/auth/account.routes.js +61 -5
  40. package/dist/modules/auth/account.routes.js.map +1 -1
  41. package/dist/modules/auth/auth.middleware.d.ts +1 -1
  42. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  43. package/dist/modules/auth/auth.middleware.js +18 -7
  44. package/dist/modules/auth/auth.middleware.js.map +1 -1
  45. package/dist/modules/auth/auth.routes.d.ts.map +1 -1
  46. package/dist/modules/auth/auth.routes.js +8 -0
  47. package/dist/modules/auth/auth.routes.js.map +1 -1
  48. package/dist/modules/auth/auth.service.d.ts +70 -2
  49. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  50. package/dist/modules/auth/auth.service.js +176 -7
  51. package/dist/modules/auth/auth.service.js.map +1 -1
  52. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  53. package/dist/modules/auth/oidc-auth-provider.js +7 -2
  54. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  55. package/dist/modules/database/core-schema.d.ts +41 -24
  56. package/dist/modules/database/core-schema.d.ts.map +1 -1
  57. package/dist/modules/database/core-schema.js +35 -27
  58. package/dist/modules/database/core-schema.js.map +1 -1
  59. package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
  60. package/dist/modules/kb-fs/branch-name.js +12 -2
  61. package/dist/modules/kb-fs/branch-name.js.map +1 -1
  62. package/dist/modules/kb-fs/repo-path.d.ts +11 -16
  63. package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
  64. package/dist/modules/kb-fs/repo-path.js +79 -0
  65. package/dist/modules/kb-fs/repo-path.js.map +1 -1
  66. package/dist/modules/kb-sync/kb-sync.routes.d.ts +2 -2
  67. package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -1
  68. package/dist/modules/kb-sync/kb-sync.routes.js +14 -3
  69. package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -1
  70. package/dist/modules/kb-sync/sync-auth.d.ts +3 -1
  71. package/dist/modules/kb-sync/sync-auth.d.ts.map +1 -1
  72. package/dist/modules/kb-sync/sync-auth.js +1 -1
  73. package/dist/modules/kb-sync/sync-auth.js.map +1 -1
  74. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  75. package/dist/modules/mcp/mcp-auth.middleware.js +21 -6
  76. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  77. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  78. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +3 -2
  79. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  80. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  81. package/dist/modules/settings/deployment-settings.service.js +8 -3
  82. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  83. package/dist/modules/settings/setup.routes.d.ts +52 -1
  84. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  85. package/dist/modules/settings/setup.routes.js +207 -19
  86. package/dist/modules/settings/setup.routes.js.map +1 -1
  87. package/dist/modules/skills/skills.contract.d.ts +90 -18
  88. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  89. package/dist/modules/skills/skills.contract.js +4 -1
  90. package/dist/modules/skills/skills.contract.js.map +1 -1
  91. package/dist/modules/skills/skills.service.d.ts +98 -9
  92. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  93. package/dist/modules/skills/skills.service.js +239 -37
  94. package/dist/modules/skills/skills.service.js.map +1 -1
  95. package/dist/modules/skills/skills.tools.d.ts +7 -0
  96. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  97. package/dist/modules/skills/skills.tools.js +71 -7
  98. package/dist/modules/skills/skills.tools.js.map +1 -1
  99. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  100. package/dist/modules/tool-auth/external-api-key.service.js +4 -2
  101. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  102. package/dist/modules/tool-auth/internal-token.service.d.ts +3 -3
  103. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +16 -7
  104. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  105. package/dist/modules/tool-auth/tool-auth.middleware.js +34 -12
  106. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  107. package/dist/modules/tool-helpers/tool-handler.d.ts +2 -1
  108. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  109. package/dist/modules/tool-helpers/tool-handler.js +25 -4
  110. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  111. package/dist/modules/tool-helpers/tool.contract.d.ts +3 -2
  112. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  113. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  114. package/dist/modules/tool-helpers/validate-token.js +1 -1
  115. package/dist/modules/tool-helpers/validate-token.js.map +1 -1
  116. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +98 -0
  117. package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -0
  118. package/dist/modules/workflow/agent-tools/change-request-summary.js +81 -0
  119. package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -0
  120. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  121. package/dist/modules/workflow/agent-tools/workflow.tools.js +75 -35
  122. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  123. package/dist/modules/workflow/file-lock.service.d.ts +24 -0
  124. package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
  125. package/dist/modules/workflow/file-lock.service.js +30 -0
  126. package/dist/modules/workflow/file-lock.service.js.map +1 -1
  127. package/dist/modules/workflow/git/git.service.d.ts +69 -0
  128. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  129. package/dist/modules/workflow/git/git.service.js +153 -2
  130. package/dist/modules/workflow/git/git.service.js.map +1 -1
  131. package/dist/modules/workflow/pending-commits.service.d.ts +38 -0
  132. package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
  133. package/dist/modules/workflow/pending-commits.service.js +55 -0
  134. package/dist/modules/workflow/pending-commits.service.js.map +1 -1
  135. package/dist/modules/workflow/workflow-hooks.d.ts +54 -32
  136. package/dist/modules/workflow/workflow-hooks.d.ts.map +1 -1
  137. package/dist/modules/workflow/workflow-hooks.js +16 -1
  138. package/dist/modules/workflow/workflow-hooks.js.map +1 -1
  139. package/dist/modules/workflow/workflow.service.d.ts +60 -6
  140. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  141. package/dist/modules/workflow/workflow.service.js +111 -4
  142. package/dist/modules/workflow/workflow.service.js.map +1 -1
  143. package/dist/modules/workspace/agent-access.gate.d.ts +94 -0
  144. package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -0
  145. package/dist/modules/workspace/agent-access.gate.js +123 -0
  146. package/dist/modules/workspace/agent-access.gate.js.map +1 -0
  147. package/dist/modules/workspace/routine-write-policy.d.ts +5 -6
  148. package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -1
  149. package/dist/modules/workspace/routine-write-policy.js +5 -6
  150. package/dist/modules/workspace/routine-write-policy.js.map +1 -1
  151. package/dist/modules/workspace/session-sink.d.ts +5 -5
  152. package/dist/modules/workspace/set-aside-clone.d.ts +46 -0
  153. package/dist/modules/workspace/set-aside-clone.d.ts.map +1 -0
  154. package/dist/modules/workspace/set-aside-clone.js +92 -0
  155. package/dist/modules/workspace/set-aside-clone.js.map +1 -0
  156. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +59 -9
  157. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  158. package/dist/modules/workspace/startup/kb-startup-runner.js +65 -24
  159. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  160. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  161. package/dist/modules/workspace/workspace.routes.js +92 -3
  162. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  163. package/dist/modules/workspace/workspace.service.d.ts +115 -5
  164. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  165. package/dist/modules/workspace/workspace.service.js +255 -25
  166. package/dist/modules/workspace/workspace.service.js.map +1 -1
  167. package/dist/modules/workspace/workspace.tools.d.ts +2 -2
  168. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  169. package/dist/modules/workspace/workspace.tools.js +309 -115
  170. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  171. package/dist/modules/write-access/write-access.d.ts +60 -0
  172. package/dist/modules/write-access/write-access.d.ts.map +1 -0
  173. package/dist/modules/write-access/write-access.js +129 -0
  174. package/dist/modules/write-access/write-access.js.map +1 -0
  175. package/dist/shared/domain-errors.d.ts +25 -0
  176. package/dist/shared/domain-errors.d.ts.map +1 -1
  177. package/dist/shared/domain-errors.js +28 -0
  178. package/dist/shared/domain-errors.js.map +1 -1
  179. package/dist/shared/git.contract.d.ts +20 -0
  180. package/dist/shared/git.contract.d.ts.map +1 -1
  181. package/dist/shared/git.contract.js +26 -0
  182. package/dist/shared/git.contract.js.map +1 -1
  183. package/dist/tenancy/static-tenant-source.d.ts +0 -1
  184. package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
  185. package/dist/tenancy/static-tenant-source.js +0 -2
  186. package/dist/tenancy/static-tenant-source.js.map +1 -1
  187. package/migrations/0014_change_request_closed_reason.sql +1 -0
  188. package/migrations/0015_account_deactivation.sql +3 -0
  189. package/migrations/meta/0014_snapshot.json +2265 -0
  190. package/migrations/meta/0015_snapshot.json +2271 -0
  191. package/migrations/meta/_journal.json +14 -0
  192. package/package.json +3 -3
  193. package/src/__tests__/kb-layout-config.test.ts +0 -2
  194. package/src/__tests__/retired-settings.test.ts +96 -0
  195. package/src/core/__tests__/gated-boot.test.ts +132 -0
  196. package/src/core/__tests__/lifecycle.test.ts +170 -1
  197. package/src/core/__tests__/set-aside-root-is-one-place.test.ts +63 -0
  198. package/src/core/core-ports.ts +11 -1
  199. package/src/core/create-core-server.ts +32 -14
  200. package/src/core/create-core-services.ts +129 -23
  201. package/src/core/lifecycle.ts +98 -13
  202. package/src/core-config.ts +13 -14
  203. package/src/index.ts +12 -1
  204. package/src/modules/access/__tests__/access-control.preview-relocation.test.ts +385 -0
  205. package/src/modules/access/__tests__/access-control.prospective.test.ts +94 -18
  206. package/src/modules/access/__tests__/access.routes.prospective.test.ts +6 -7
  207. package/src/modules/access/access-control.interface.ts +43 -12
  208. package/src/modules/access/access-control.service.ts +234 -36
  209. package/src/modules/access/access.routes.ts +13 -15
  210. package/src/modules/agent-instructions/__tests__/agent-instructions.route.test.ts +3 -1
  211. package/src/modules/auth/__tests__/account-deactivation.test.ts +252 -0
  212. package/src/modules/auth/__tests__/account.routes.test.ts +81 -3
  213. package/src/modules/auth/__tests__/auth.middleware.test.ts +45 -22
  214. package/src/modules/auth/__tests__/auth.service.test.ts +1 -1
  215. package/src/modules/auth/account-admission.ts +78 -9
  216. package/src/modules/auth/account.routes.ts +63 -7
  217. package/src/modules/auth/auth.middleware.ts +19 -8
  218. package/src/modules/auth/auth.routes.ts +8 -0
  219. package/src/modules/auth/auth.service.ts +179 -6
  220. package/src/modules/auth/oidc-auth-provider.ts +7 -2
  221. package/src/modules/database/core-schema.ts +35 -27
  222. package/src/modules/kb-fs/__tests__/branch-name.test.ts +10 -0
  223. package/src/modules/kb-fs/__tests__/repo-path.test.ts +123 -0
  224. package/src/modules/kb-fs/branch-name.ts +14 -1
  225. package/src/modules/kb-fs/repo-path.ts +85 -0
  226. package/src/modules/kb-sync/__tests__/kb-sync.routes.test.ts +26 -1
  227. package/src/modules/kb-sync/kb-sync.routes.ts +14 -4
  228. package/src/modules/kb-sync/sync-auth.ts +2 -2
  229. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +60 -3
  230. package/src/modules/mcp/__tests__/mcp.service.test.ts +68 -6
  231. package/src/modules/mcp/mcp-auth.middleware.ts +20 -6
  232. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +3 -1
  233. package/src/modules/plugins/__tests__/plugins.tools.test.ts +2 -1
  234. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +16 -0
  235. package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +91 -58
  236. package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +25 -8
  237. package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +14 -11
  238. package/src/modules/settings/__tests__/setup.routes.repository-change.test.ts +390 -0
  239. package/src/modules/settings/__tests__/setup.routes.test.ts +3 -0
  240. package/src/modules/settings/deployment-settings.service.ts +8 -3
  241. package/src/modules/settings/setup.routes.ts +263 -19
  242. package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +2 -1
  243. package/src/modules/skills/__tests__/branch-skills.tools.test.ts +218 -0
  244. package/src/modules/skills/__tests__/skills.service.test.ts +229 -5
  245. package/src/modules/skills/skills.contract.ts +91 -18
  246. package/src/modules/skills/skills.service.ts +278 -41
  247. package/src/modules/skills/skills.tools.ts +80 -8
  248. package/src/modules/tool-auth/__tests__/manual-auth.middleware.test.ts +14 -1
  249. package/src/modules/tool-auth/external-api-key.service.ts +4 -2
  250. package/src/modules/tool-auth/internal-token.service.ts +3 -3
  251. package/src/modules/tool-auth/tool-auth.middleware.ts +34 -11
  252. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +5 -3
  253. package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -3
  254. package/src/modules/tool-helpers/__tests__/validate-token.test.ts +11 -1
  255. package/src/modules/tool-helpers/tool-handler.ts +24 -4
  256. package/src/modules/tool-helpers/tool.contract.ts +3 -2
  257. package/src/modules/tool-helpers/validate-token.ts +1 -1
  258. package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +111 -0
  259. package/src/modules/workflow/__tests__/workflow.routes.history-read-gate.test.ts +25 -0
  260. package/src/modules/workflow/__tests__/workflow.service.repository-replaced.test.ts +249 -0
  261. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +264 -6
  262. package/src/modules/workflow/agent-tools/change-request-summary.ts +182 -0
  263. package/src/modules/workflow/agent-tools/workflow.tools.ts +86 -35
  264. package/src/modules/workflow/file-lock.service.ts +31 -0
  265. package/src/modules/workflow/git/__tests__/git.service.fileBytesAtCommit.test.ts +260 -0
  266. package/src/modules/workflow/git/git.service.ts +168 -0
  267. package/src/modules/workflow/pending-commits.service.ts +59 -1
  268. package/src/modules/workflow/workflow-hooks.ts +64 -26
  269. package/src/modules/workflow/workflow.service.ts +121 -4
  270. package/src/modules/workspace/__tests__/agent-access.gate.test.ts +208 -0
  271. package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +384 -0
  272. package/src/modules/workspace/__tests__/file-stat-access.test.ts +2 -1
  273. package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -1
  274. package/src/modules/workspace/__tests__/set-aside-clone.test.ts +52 -0
  275. package/src/modules/workspace/__tests__/workspace.routes.at-ref.test.ts +305 -0
  276. package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -0
  277. package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +147 -0
  278. package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +326 -0
  279. package/src/modules/workspace/__tests__/workspace.service.test.ts +20 -9
  280. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +2 -3
  281. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +2 -3
  282. package/src/modules/workspace/__tests__/workspace.tools.test.ts +685 -14
  283. package/src/modules/workspace/agent-access.gate.ts +164 -0
  284. package/src/modules/workspace/routine-write-policy.ts +5 -6
  285. package/src/modules/workspace/session-sink.ts +5 -5
  286. package/src/modules/workspace/set-aside-clone.ts +96 -0
  287. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +86 -0
  288. package/src/modules/workspace/startup/kb-startup-runner.ts +115 -34
  289. package/src/modules/workspace/workspace.routes.ts +95 -3
  290. package/src/modules/workspace/workspace.service.ts +256 -24
  291. package/src/modules/workspace/workspace.tools.ts +338 -119
  292. package/src/modules/write-access/__tests__/write-access.test.ts +248 -0
  293. package/src/modules/write-access/write-access.ts +153 -0
  294. package/src/shared/domain-errors.ts +31 -0
  295. package/src/shared/git.contract.ts +27 -0
  296. package/src/tenancy/__tests__/static-tenant-source.test.ts +0 -1
  297. package/src/tenancy/static-tenant-source.ts +0 -3
  298. package/dist/modules/workflow/session-ontology.policy.d.ts +0 -52
  299. package/dist/modules/workflow/session-ontology.policy.d.ts.map +0 -1
  300. package/dist/modules/workflow/session-ontology.policy.js +0 -62
  301. package/dist/modules/workflow/session-ontology.policy.js.map +0 -1
  302. package/dist/modules/workflow/session-ontology.service.d.ts +0 -105
  303. package/dist/modules/workflow/session-ontology.service.d.ts.map +0 -1
  304. package/dist/modules/workflow/session-ontology.service.js +0 -147
  305. package/dist/modules/workflow/session-ontology.service.js.map +0 -1
  306. package/dist/modules/workspace/session-ontology.gate.d.ts +0 -114
  307. package/dist/modules/workspace/session-ontology.gate.d.ts.map +0 -1
  308. package/dist/modules/workspace/session-ontology.gate.js +0 -161
  309. package/dist/modules/workspace/session-ontology.gate.js.map +0 -1
  310. package/dist/shared/kb-layout.d.ts +0 -39
  311. package/dist/shared/kb-layout.d.ts.map +0 -1
  312. package/dist/shared/kb-layout.js +0 -103
  313. package/dist/shared/kb-layout.js.map +0 -1
  314. package/dist/shared/kb-layout.test.d.ts +0 -2
  315. package/dist/shared/kb-layout.test.d.ts.map +0 -1
  316. package/dist/shared/kb-layout.test.js +0 -75
  317. package/dist/shared/kb-layout.test.js.map +0 -1
  318. package/src/modules/workflow/__tests__/session-ontology.policy.test.ts +0 -62
  319. package/src/modules/workflow/__tests__/session-ontology.service.test.ts +0 -201
  320. package/src/modules/workflow/session-ontology.policy.ts +0 -70
  321. package/src/modules/workflow/session-ontology.service.ts +0 -183
  322. package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +0 -239
  323. package/src/modules/workspace/session-ontology.gate.ts +0 -191
  324. package/src/shared/kb-layout.test.ts +0 -98
  325. package/src/shared/kb-layout.ts +0 -102
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Agent access gate — the per-call seam every gated agent tool runs through.
3
+ *
4
+ * It decides nothing of its own. It calls the hooks a DEPLOYMENT registered
5
+ * (`WorkflowHooks`): one before an agent read of a knowledge-base path, one
6
+ * before an agent write. A hook that throws refuses the operation and the
7
+ * caller sees that hook's own message and status. With no hook registered —
8
+ * every core-only deployment — nothing is refused and nothing is recorded, and
9
+ * a call that carries no `sessionId` is an ordinary call.
10
+ *
11
+ * The gate owns exactly two skips, and they are the ones core can decide on
12
+ * its own identity model: the caller is not an agent (a person in the app, a
13
+ * browser JWT), or the caller is the recovery/merge bot. Everything else —
14
+ * which paths matter, whether a session id is required, what the refusal says
15
+ * — belongs to the hook.
16
+ *
17
+ * Lives beside `assertCanRead` in the workspace tools; it does NOT touch
18
+ * `acquireLock` (that gate is protected-branch-only, and this one applies on
19
+ * all branches and to reads).
20
+ */
21
+ import type { JsonSchema } from '../tool-registry/tool.contract.js';
22
+ import type { ToolContext } from '../tool-helpers/tool.contract.js';
23
+ import type { WorkflowHooks } from '../workflow/workflow-hooks.js';
24
+ /**
25
+ * What the `sessionId` input says on its own, before any deployment note. The
26
+ * id is the CONVERSATION's id: the in-process agent supplies its thread id
27
+ * automatically (via its per-run internal token), and an external agent mints
28
+ * one with `start_session` and passes it explicitly, because the MCP proxy is
29
+ * a pure passthrough and never injects args. The same id is the one `ask`
30
+ * takes, so a run's reads and its questions share one conversation.
31
+ */
32
+ export declare const SESSION_ID_DESCRIPTION = "This conversation's id, so the server can tell one run's calls apart. External agents (direct MCP calls and `call_tool_chain` alike): call the `start_session` tool ONCE at the very start of your work to obtain it, then pass that id here \u2014 the same id `ask` takes. The in-process agent runtime supplies this automatically (do not set it yourself).";
33
+ /**
34
+ * The `sessionId` input every gated tool declares. The description a MOUNTED
35
+ * tool ends up advertising is {@link ToolDescriptionNotes.sessionIdDescription},
36
+ * which appends whatever note the deployment registered; this constant is the
37
+ * unadorned default the notes are applied on top of.
38
+ */
39
+ export declare const SESSION_ID_INPUT: JsonSchema;
40
+ /**
41
+ * The registration point for the wording a DEPLOYMENT wants agents to read
42
+ * about the gated tools — the counterpart of the hooks, which carry its rule.
43
+ * A deployment that refuses some calls can say so here; core registers
44
+ * nothing, so a core-only deployment advertises the plain descriptions.
45
+ *
46
+ * Registration may land AFTER the tools are mounted (an overlay registers from
47
+ * the tool-surface hook), so mounted tools subscribe with {@link onChange} and
48
+ * rewrite their own description and `sessionId` input when a note arrives.
49
+ */
50
+ export declare class ToolDescriptionNotes {
51
+ private gatedTool;
52
+ private sessionId;
53
+ private readonly listeners;
54
+ /** Append `note` to the description of every gated tool. */
55
+ registerGatedToolNote(note: string): void;
56
+ /** Append `note` to the description of the `sessionId` input. */
57
+ registerSessionIdNote(note: string): void;
58
+ /** The registered gated-tool note, `''` when none is registered. */
59
+ gatedToolNote(): string;
60
+ /** The `sessionId` input's description, with any registered note appended. */
61
+ sessionIdDescription(): string;
62
+ /** Re-run `listener` whenever a note is registered (mounted tools re-describe). */
63
+ onChange(listener: () => void): void;
64
+ private announce;
65
+ }
66
+ /** The per-deployment configuration the gate needs, built once in the composition root. */
67
+ export interface AgentAccessGate {
68
+ /** Lowercased email of the recovery/merge bot, which never reaches the hooks. */
69
+ recoveryBotEmail: string;
70
+ /**
71
+ * The workflow lifecycle-hook registry holding the BLOCKING `agentRead` and
72
+ * `preWrite` hooks. Core registers none; a deployment registers against
73
+ * `workflowService.hooks` — pass that same instance here.
74
+ */
75
+ hooks: WorkflowHooks;
76
+ /** The notes a deployment adds to what agents read about these tools. */
77
+ notes: ToolDescriptionNotes;
78
+ }
79
+ /**
80
+ * Tell the registered read hooks about an agent read of `wsPath`. A hook that
81
+ * throws refuses the read with its own message and status; with none
82
+ * registered this is a no-op.
83
+ */
84
+ export declare function notifyAgentRead(gate: AgentAccessGate, ctx: ToolContext, branch: string, wsPath: string): Promise<void>;
85
+ /**
86
+ * Ask the registered write hooks whether an agent write may proceed. A hook
87
+ * that throws refuses it with its own message and status; with none registered
88
+ * this is a no-op.
89
+ *
90
+ * `wsPath` is omitted by the one write-capable tool with no resolvable target,
91
+ * `execute_command` — the hook then decides at the coarser session level.
92
+ */
93
+ export declare function assertAgentWriteAllowed(gate: AgentAccessGate, ctx: ToolContext, branch: string, wsPath?: string): Promise<void>;
94
+ //# sourceMappingURL=agent-access.gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-access.gate.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/agent-access.gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,oWAC2T,CAAC;AAE/V;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,UAG9B,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD,4DAA4D;IAC5D,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzC,iEAAiE;IACjE,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzC,oEAAoE;IACpE,aAAa,IAAI,MAAM;IAIvB,8EAA8E;IAC9E,oBAAoB,IAAI,MAAM;IAI9B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAIpC,OAAO,CAAC,QAAQ;CAGjB;AAED,2FAA2F;AAC3F,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,KAAK,EAAE,aAAa,CAAC;IACrB,yEAAyE;IACzE,KAAK,EAAE,oBAAoB,CAAC;CAC7B;AAwBD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Agent access gate — the per-call seam every gated agent tool runs through.
3
+ *
4
+ * It decides nothing of its own. It calls the hooks a DEPLOYMENT registered
5
+ * (`WorkflowHooks`): one before an agent read of a knowledge-base path, one
6
+ * before an agent write. A hook that throws refuses the operation and the
7
+ * caller sees that hook's own message and status. With no hook registered —
8
+ * every core-only deployment — nothing is refused and nothing is recorded, and
9
+ * a call that carries no `sessionId` is an ordinary call.
10
+ *
11
+ * The gate owns exactly two skips, and they are the ones core can decide on
12
+ * its own identity model: the caller is not an agent (a person in the app, a
13
+ * browser JWT), or the caller is the recovery/merge bot. Everything else —
14
+ * which paths matter, whether a session id is required, what the refusal says
15
+ * — belongs to the hook.
16
+ *
17
+ * Lives beside `assertCanRead` in the workspace tools; it does NOT touch
18
+ * `acquireLock` (that gate is protected-branch-only, and this one applies on
19
+ * all branches and to reads).
20
+ */
21
+ /**
22
+ * What the `sessionId` input says on its own, before any deployment note. The
23
+ * id is the CONVERSATION's id: the in-process agent supplies its thread id
24
+ * automatically (via its per-run internal token), and an external agent mints
25
+ * one with `start_session` and passes it explicitly, because the MCP proxy is
26
+ * a pure passthrough and never injects args. The same id is the one `ask`
27
+ * takes, so a run's reads and its questions share one conversation.
28
+ */
29
+ export const SESSION_ID_DESCRIPTION = "This conversation's id, so the server can tell one run's calls apart. External agents (direct MCP calls and `call_tool_chain` alike): call the `start_session` tool ONCE at the very start of your work to obtain it, then pass that id here — the same id `ask` takes. The in-process agent runtime supplies this automatically (do not set it yourself).";
30
+ /**
31
+ * The `sessionId` input every gated tool declares. The description a MOUNTED
32
+ * tool ends up advertising is {@link ToolDescriptionNotes.sessionIdDescription},
33
+ * which appends whatever note the deployment registered; this constant is the
34
+ * unadorned default the notes are applied on top of.
35
+ */
36
+ export const SESSION_ID_INPUT = {
37
+ type: 'string',
38
+ description: SESSION_ID_DESCRIPTION,
39
+ };
40
+ /**
41
+ * The registration point for the wording a DEPLOYMENT wants agents to read
42
+ * about the gated tools — the counterpart of the hooks, which carry its rule.
43
+ * A deployment that refuses some calls can say so here; core registers
44
+ * nothing, so a core-only deployment advertises the plain descriptions.
45
+ *
46
+ * Registration may land AFTER the tools are mounted (an overlay registers from
47
+ * the tool-surface hook), so mounted tools subscribe with {@link onChange} and
48
+ * rewrite their own description and `sessionId` input when a note arrives.
49
+ */
50
+ export class ToolDescriptionNotes {
51
+ gatedTool = '';
52
+ sessionId = '';
53
+ listeners = new Set();
54
+ /** Append `note` to the description of every gated tool. */
55
+ registerGatedToolNote(note) {
56
+ this.gatedTool = note;
57
+ this.announce();
58
+ }
59
+ /** Append `note` to the description of the `sessionId` input. */
60
+ registerSessionIdNote(note) {
61
+ this.sessionId = note;
62
+ this.announce();
63
+ }
64
+ /** The registered gated-tool note, `''` when none is registered. */
65
+ gatedToolNote() {
66
+ return this.gatedTool;
67
+ }
68
+ /** The `sessionId` input's description, with any registered note appended. */
69
+ sessionIdDescription() {
70
+ return SESSION_ID_DESCRIPTION + this.sessionId;
71
+ }
72
+ /** Re-run `listener` whenever a note is registered (mounted tools re-describe). */
73
+ onChange(listener) {
74
+ this.listeners.add(listener);
75
+ }
76
+ announce() {
77
+ for (const listener of this.listeners)
78
+ listener();
79
+ }
80
+ }
81
+ /** Only agent callers are gated; `session` (browser JWT) and humans are not. */
82
+ function agentSourceOf(ctx) {
83
+ return ctx.source === 'internal' || ctx.source === 'external' ? ctx.source : null;
84
+ }
85
+ /**
86
+ * The hook context for this call, or `null` when the call never reaches a hook:
87
+ * the caller is a person rather than an agent, or is the recovery/merge bot,
88
+ * which legitimately spans everything.
89
+ */
90
+ function operationContext(gate, ctx, branch, wsPath) {
91
+ const source = agentSourceOf(ctx);
92
+ if (source === null)
93
+ return null;
94
+ if (ctx.user.email.toLowerCase() === gate.recoveryBotEmail)
95
+ return null;
96
+ return { sessionId: ctx.sessionId, wsPath, branch, user: ctx.user, source };
97
+ }
98
+ /**
99
+ * Tell the registered read hooks about an agent read of `wsPath`. A hook that
100
+ * throws refuses the read with its own message and status; with none
101
+ * registered this is a no-op.
102
+ */
103
+ export async function notifyAgentRead(gate, ctx, branch, wsPath) {
104
+ const op = operationContext(gate, ctx, branch, wsPath);
105
+ if (op === null)
106
+ return;
107
+ await gate.hooks.runAgentRead(op);
108
+ }
109
+ /**
110
+ * Ask the registered write hooks whether an agent write may proceed. A hook
111
+ * that throws refuses it with its own message and status; with none registered
112
+ * this is a no-op.
113
+ *
114
+ * `wsPath` is omitted by the one write-capable tool with no resolvable target,
115
+ * `execute_command` — the hook then decides at the coarser session level.
116
+ */
117
+ export async function assertAgentWriteAllowed(gate, ctx, branch, wsPath) {
118
+ const op = operationContext(gate, ctx, branch, wsPath);
119
+ if (op === null)
120
+ return;
121
+ await gate.hooks.runPreWrite(op);
122
+ }
123
+ //# sourceMappingURL=agent-access.gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-access.gate.js","sourceRoot":"","sources":["../../../src/modules/workspace/agent-access.gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,4VAA4V,CAAC;AAE/V;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,sBAAsB;CACpC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,OAAO,oBAAoB;IACvB,SAAS,GAAG,EAAE,CAAC;IACf,SAAS,GAAG,EAAE,CAAC;IACN,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IAEnD,4DAA4D;IAC5D,qBAAqB,CAAC,IAAY;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,iEAAiE;IACjE,qBAAqB,CAAC,IAAY;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,aAAa;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,8EAA8E;IAC9E,oBAAoB;QAClB,OAAO,sBAAsB,GAAG,IAAI,CAAC,SAAS,CAAC;IACjD,CAAC;IAED,mFAAmF;IACnF,QAAQ,CAAC,QAAoB;QAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAEO,QAAQ;QACd,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,EAAE,CAAC;IACpD,CAAC;CACF;AAgBD,gFAAgF;AAChF,SAAS,aAAa,CAAC,GAAgB;IACrC,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,IAAqB,EACrB,GAAgB,EAChB,MAAc,EACd,MAAe;IAEf,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAqB,EACrB,GAAgB,EAChB,MAAc,EACd,MAAc;IAEd,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO;IACxB,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAqB,EACrB,GAAgB,EAChB,MAAc,EACd,MAAe;IAEf,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO;IACxB,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Per-run write restriction for background/routine agents.
3
3
  *
4
- * The ontology-session gate ({@link ../workflow/session-ontology.service}) bounds
5
- * WHICH ontology a run may write; this narrower gate bounds WHAT KIND of file a
6
- * run may write, by extension. It exists for the `watchlist_check` routine, which is
4
+ * The agent-access gate ({@link ./agent-access.gate}) lets a deployment decide
5
+ * WHETHER a run may write a path at all; this narrower gate bounds WHAT KIND of
6
+ * file a run may write, by extension. It exists for the `watchlist_check` routine, which is
7
7
  * allowed to refresh dashboard views (`.html`) but must never touch the
8
8
  * knowledge-graph nodes (`.md`) or any other file — a hard, code-level guarantee
9
9
  * rather than a prompt request (a prompt-only rule has already proven insufficient).
@@ -11,9 +11,8 @@
11
11
  * Keyed by the agent run's `sessionId` (the background agent passes its run id as
12
12
  * the session id, which the internal token then carries onto every loopback tool
13
13
  * call as `ctx.sessionId`). A restriction lives only for the duration of one
14
- * in-process run, so the store is a plain in-memory map — no durability needed,
15
- * unlike the ontology touched-set which must survive restarts and span the MCP
16
- * proxy. The executor sets the restriction before streaming and clears it after.
14
+ * in-process run, so the store is a plain in-memory map — no durability needed.
15
+ * The executor sets the restriction before streaming and clears it after.
17
16
  */
18
17
  export interface IRoutineWritePolicy {
19
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"routine-write-policy.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/routine-write-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7E,wDAAwD;IACxD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CACzD;AAED,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAE/D,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAI5E,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAcvE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAQxD"}
1
+ {"version":3,"file":"routine-write-policy.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/routine-write-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7E,wDAAwD;IACxD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CACzD;AAED,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAE/D,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAI5E,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAcvE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAQxD"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Per-run write restriction for background/routine agents.
3
3
  *
4
- * The ontology-session gate ({@link ../workflow/session-ontology.service}) bounds
5
- * WHICH ontology a run may write; this narrower gate bounds WHAT KIND of file a
6
- * run may write, by extension. It exists for the `watchlist_check` routine, which is
4
+ * The agent-access gate ({@link ./agent-access.gate}) lets a deployment decide
5
+ * WHETHER a run may write a path at all; this narrower gate bounds WHAT KIND of
6
+ * file a run may write, by extension. It exists for the `watchlist_check` routine, which is
7
7
  * allowed to refresh dashboard views (`.html`) but must never touch the
8
8
  * knowledge-graph nodes (`.md`) or any other file — a hard, code-level guarantee
9
9
  * rather than a prompt request (a prompt-only rule has already proven insufficient).
@@ -11,9 +11,8 @@
11
11
  * Keyed by the agent run's `sessionId` (the background agent passes its run id as
12
12
  * the session id, which the internal token then carries onto every loopback tool
13
13
  * call as `ctx.sessionId`). A restriction lives only for the duration of one
14
- * in-process run, so the store is a plain in-memory map — no durability needed,
15
- * unlike the ontology touched-set which must survive restarts and span the MCP
16
- * proxy. The executor sets the restriction before streaming and clears it after.
14
+ * in-process run, so the store is a plain in-memory map — no durability needed.
15
+ * The executor sets the restriction before streaming and clears it after.
17
16
  */
18
17
  import { ToolError } from '../tool-helpers/tool.contract.js';
19
18
  export class RoutineWritePolicyService {
@@ -1 +1 @@
1
- {"version":3,"file":"routine-write-policy.js","sourceRoot":"","sources":["../../../src/modules/workspace/routine-write-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AA0B7D,MAAM,OAAO,yBAAyB;IACpC,wEAAwE;IACvD,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE/D,oBAAoB,CAAC,SAAiB,EAAE,UAA6B;QACnE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,SAAiB;QACrB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,kBAAkB,CAAC,SAA6B,EAAE,MAAc;QAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACnC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO;QAClC,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,2BAA2B,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,MAAM,gBAAgB;YACpG,uEAAuE,EACzE,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,kBAAkB,CAAC,SAA6B;QAC9C,IAAI,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,SAAS,CACjB,sHAAsH,EACtH,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"routine-write-policy.js","sourceRoot":"","sources":["../../../src/modules/workspace/routine-write-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AA0B7D,MAAM,OAAO,yBAAyB;IACpC,wEAAwE;IACvD,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE/D,oBAAoB,CAAC,SAAiB,EAAE,UAA6B;QACnE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,SAAiB;QACrB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,kBAAkB,CAAC,SAA6B,EAAE,MAAc;QAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACnC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO;QAClC,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,2BAA2B,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,MAAM,gBAAgB;YACpG,uEAAuE,EACzE,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,kBAAkB,CAAC,SAA6B;QAC9C,IAAI,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,SAAS,CACjB,sHAAsH,EACtH,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Port behind `start_session` (workspace.tools.ts): mints the session id an
3
- * external agent scopes its ontology boundary under. The workspace module owns
4
- * the port; WHAT backs the id is the composition root's choice:
2
+ * Port behind `start_session` (workspace.tools.ts): mints the id an external
3
+ * agent names its conversation with. The workspace module owns the port; WHAT
4
+ * backs the id is the composition root's choice:
5
5
  *
6
- * - Core default ({@link UuidSessionSink}): a bare random id — sufficient for
7
- * the session-ontology gate, with no app-side session record.
6
+ * - Core default ({@link UuidSessionSink}): a bare random id — all the
7
+ * agent-access hooks need, with no app-side session record.
8
8
  * - The enterprise app substitutes a sink that mints a REAL chat thread, so the
9
9
  * same id also works end to end with `ask` (its sessionId IS a chat thread).
10
10
  * See the `start_session` comment in workspace.tools.ts for why that
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Moving a working copy of a repository that is no longer the configured one
3
+ * OUT OF THE WAY, rather than deleting it.
4
+ *
5
+ * Two places find such a clone: the KB startup phase, sweeping the whole
6
+ * workspaces root at boot and on the save that changes the address, and the
7
+ * workspace service, refusing to adopt one it finds on disk. Both must do the
8
+ * same thing with it, because what is in it is the same thing: commits that
9
+ * may exist nowhere else. A clone fetches and pushes through the address in
10
+ * its own `remote.origin.url`, and two repositories need not share a commit,
11
+ * so such a clone cannot be re-pointed — but that is a reason not to USE it,
12
+ * never a reason to destroy it.
13
+ */
14
+ /**
15
+ * Where working copies are set aside. NOT under the workspaces root: the
16
+ * workspace service's orphan sweep removes every folder there that is not a
17
+ * known branch's, and what is set aside has to outlive that sweep.
18
+ *
19
+ * PASS THE OVERRIDE, and pass BOTH CALLERS THE SAME ONE. The fallback is a
20
+ * sibling of the workspaces root, which is a lasting place only when that
21
+ * parent is itself a mounted volume — in the shipped compose file it is the
22
+ * container's own filesystem, so a copy left there is gone at the next
23
+ * recreate, having been kept on the promise that it would not be. The
24
+ * composition root therefore roots both the startup phase and the workspace
25
+ * service at one directory under the backups volume; the fallback is for a
26
+ * test, or a caller with no deployment layout to speak of.
27
+ */
28
+ export declare function setAsideRootFor(workspacesRoot: string, override?: string): string;
29
+ /**
30
+ * One folder per occasion, so what was set aside together stays together and
31
+ * two replacements never land in each other's folder.
32
+ */
33
+ export declare function setAsideStamp(at?: Date): string;
34
+ /**
35
+ * Move the clone at `repoDir` to `dest`. A rename when it can be one; a copy
36
+ * when it cannot (another volume, a handle held open on it), and only then is
37
+ * the original removed — so a copy that fails leaves the clone exactly where
38
+ * it was rather than half of it in each place.
39
+ *
40
+ * Throws with what to do about it. The caller decides how much that costs:
41
+ * the startup phase stops the boot (leaving the clone would fail a step later
42
+ * with git's words about a repository nobody configured), while a single
43
+ * branch open refuses that branch.
44
+ */
45
+ export declare function setAsideClone(repoDir: string, dest: string): Promise<void>;
46
+ //# sourceMappingURL=set-aside-clone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-aside-clone.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/set-aside-clone.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,GAAE,IAAiB,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyChF"}
@@ -0,0 +1,92 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Moving a working copy of a repository that is no longer the configured one
5
+ * OUT OF THE WAY, rather than deleting it.
6
+ *
7
+ * Two places find such a clone: the KB startup phase, sweeping the whole
8
+ * workspaces root at boot and on the save that changes the address, and the
9
+ * workspace service, refusing to adopt one it finds on disk. Both must do the
10
+ * same thing with it, because what is in it is the same thing: commits that
11
+ * may exist nowhere else. A clone fetches and pushes through the address in
12
+ * its own `remote.origin.url`, and two repositories need not share a commit,
13
+ * so such a clone cannot be re-pointed — but that is a reason not to USE it,
14
+ * never a reason to destroy it.
15
+ */
16
+ /**
17
+ * Where working copies are set aside. NOT under the workspaces root: the
18
+ * workspace service's orphan sweep removes every folder there that is not a
19
+ * known branch's, and what is set aside has to outlive that sweep.
20
+ *
21
+ * PASS THE OVERRIDE, and pass BOTH CALLERS THE SAME ONE. The fallback is a
22
+ * sibling of the workspaces root, which is a lasting place only when that
23
+ * parent is itself a mounted volume — in the shipped compose file it is the
24
+ * container's own filesystem, so a copy left there is gone at the next
25
+ * recreate, having been kept on the promise that it would not be. The
26
+ * composition root therefore roots both the startup phase and the workspace
27
+ * service at one directory under the backups volume; the fallback is for a
28
+ * test, or a caller with no deployment layout to speak of.
29
+ */
30
+ export function setAsideRootFor(workspacesRoot, override) {
31
+ return override ?? path.resolve(workspacesRoot, '..', 'replaced-working-copies');
32
+ }
33
+ /**
34
+ * One folder per occasion, so what was set aside together stays together and
35
+ * two replacements never land in each other's folder.
36
+ */
37
+ export function setAsideStamp(at = new Date()) {
38
+ return at.toISOString().replace(/[:.]/g, '-');
39
+ }
40
+ /**
41
+ * Move the clone at `repoDir` to `dest`. A rename when it can be one; a copy
42
+ * when it cannot (another volume, a handle held open on it), and only then is
43
+ * the original removed — so a copy that fails leaves the clone exactly where
44
+ * it was rather than half of it in each place.
45
+ *
46
+ * Throws with what to do about it. The caller decides how much that costs:
47
+ * the startup phase stops the boot (leaving the clone would fail a step later
48
+ * with git's words about a repository nobody configured), while a single
49
+ * branch open refuses that branch.
50
+ */
51
+ export async function setAsideClone(repoDir, dest) {
52
+ // A destination that is already there is somebody's set-aside work, and
53
+ // never this call's to touch: the copy below cleans up after itself by
54
+ // removing the destination, which must then be one this call made.
55
+ const taken = () => new Error(`Could not set aside the working copy at ${repoDir}: ${dest} already holds one. Nothing was deleted or ` +
56
+ 'moved. Try again; the folder is named for the moment it is made.');
57
+ if (await fs.access(dest).then(() => true, () => false))
58
+ throw taken();
59
+ await fs.mkdir(path.dirname(dest), { recursive: true });
60
+ try {
61
+ await fs.rename(repoDir, dest);
62
+ return;
63
+ }
64
+ catch {
65
+ // Another volume, or a handle held open on it: copy instead.
66
+ }
67
+ // The destination is MADE here, by the one call that will fill it. Two
68
+ // calls that both found it absent above cannot both make it: the second
69
+ // is refused by the filesystem, before the cleanup below could ever be
70
+ // about a folder it did not create.
71
+ try {
72
+ await fs.mkdir(dest);
73
+ }
74
+ catch (err) {
75
+ if (err.code === 'EEXIST')
76
+ throw taken();
77
+ throw err;
78
+ }
79
+ try {
80
+ // Into the empty folder made above, which is why an existing destination
81
+ // is not an error here; nothing is overwritten (`force: false`).
82
+ await fs.cp(repoDir, dest, { recursive: true, errorOnExist: false, force: false, verbatimSymlinks: true });
83
+ }
84
+ catch (err) {
85
+ await fs.rm(dest, { recursive: true, force: true }).catch(() => undefined);
86
+ throw new Error(`Could not set aside the working copy at ${repoDir}, a clone of a repository that is no longer the ` +
87
+ `configured one, into ${dest}: ${err instanceof Error ? err.message : String(err)}. Nothing was deleted. ` +
88
+ 'Make room there, or move that folder away by hand, and start again.', { cause: err });
89
+ }
90
+ await fs.rm(repoDir, { recursive: true, force: true });
91
+ }
92
+ //# sourceMappingURL=set-aside-clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-aside-clone.js","sourceRoot":"","sources":["../../../src/modules/workspace/set-aside-clone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB,EAAE,QAAiB;IACvE,OAAO,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,EAAE,yBAAyB,CAAC,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAW,IAAI,IAAI,EAAE;IACjD,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,IAAY;IAC/D,wEAAwE;IACxE,uEAAuE;IACvE,mEAAmE;IACnE,MAAM,KAAK,GAAG,GAAU,EAAE,CACxB,IAAI,KAAK,CACP,2CAA2C,OAAO,KAAK,IAAI,6CAA6C;QACtG,kEAAkE,CACrE,CAAC;IACJ,IAAI,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC;QAAE,MAAM,KAAK,EAAE,CAAC;IACvE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;IACD,uEAAuE;IACvE,wEAAwE;IACxE,uEAAuE;IACvE,oCAAoC;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,EAAE,CAAC;QACpE,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,yEAAyE;QACzE,iEAAiE;QACjE,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7G,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3E,MAAM,IAAI,KAAK,CACb,2CAA2C,OAAO,kDAAkD;YAClG,wBAAwB,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB;YAC1G,qEAAqE,EACvE,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC"}
@@ -10,7 +10,9 @@ import { ClassifiedFailure, type GitFailure } from '../../../shared/git-failure.
10
10
  *
11
11
  * Fully fail-closed: any failure this phase cannot DECLARE (an unhandled
12
12
  * step throw, an unreachable remote, a clone that will not come down, a
13
- * refused write) throws out of `runAll` and stops the boot. The container's
13
+ * refused write) throws out of `runAll`. The boot stops on it unless the
14
+ * host ANSWERED about the repository or the credentials, in which case it
15
+ * comes up gated instead — see `bootMaySurvive`. The container's
14
16
  * restart policy is the retry — each attempt at boot time on quiet trees —
15
17
  * so an environmental failure converges without a human the moment the
16
18
  * environment returns. The one carve-out: a push rejected because a
@@ -33,13 +35,12 @@ export interface KbStartupRunnerOptions {
33
35
  kbRepoUrl: () => string;
34
36
  workspacesRoot: string;
35
37
  /**
36
- * Where a working copy of a repository that is no longer the configured
37
- * one is moved to, under a folder named for the moment it happened — see
38
- * `reconcileClonesWithConfiguredRepository`. NOT under `workspacesRoot`:
39
- * the workspace service's orphan sweep removes every folder there that is
40
- * not a known branch's, and what is set aside has to outlive that sweep.
41
- * The composition root names a folder under the backups root, which is a
42
- * persistent volume of its own. Default: a sibling of `workspacesRoot`.
38
+ * Where a working copy of a repository that is no longer the configured one
39
+ * is moved to, under a folder named for the moment it happened — see
40
+ * `reconcileClonesWithConfiguredRepository`. THE SAME VALUE THE WORKSPACE
41
+ * SERVICE IS GIVEN.
42
+ *
43
+ * Why, in one place: `setAsideRootFor` in `set-aside-clone.ts`.
43
44
  */
44
45
  setAsideRoot?: string;
45
46
  kbDirName: string;
@@ -58,6 +59,47 @@ export interface KbStartupRunnerOptions {
58
59
  template `.gitignore` rule can never silently drop a required seed file
59
60
  from the commit. */
60
61
  buildSeedTree: (dir: string) => Promise<string[]>;
62
+ /**
63
+ * Called with the workspace id of each working copy the phase is ABOUT TO
64
+ * set aside for being a clone of another repository, and awaited first.
65
+ * Whatever is still queued to be committed into that copy was written
66
+ * against the repository that was left, so it must be held back before a
67
+ * fresh clone of another repository appears at the same path.
68
+ *
69
+ * A PRECONDITION, so a failure here STOPS THE PHASE with the copy still
70
+ * where it was. Carrying on would clone the replacement with the queue
71
+ * untouched, and the worker would then commit those bytes into a
72
+ * repository they were never meant for. Stopped before anything moved, the
73
+ * next run finds the same copy and asks again. Optional: a minimal graph
74
+ * has no queue.
75
+ */
76
+ beforeCloneSetAside?: (workspaceId: string) => Promise<void>;
77
+ /**
78
+ * Called with the workspace id of each working copy the phase SET ASIDE for
79
+ * being a clone of another repository. The workspace service keeps a
80
+ * branch→directory cache and adopts whatever is on disk, so on a RUNNING
81
+ * server (the save that moves the deployment to another repository) the
82
+ * copy would otherwise stay in that cache as a path to nothing. Optional:
83
+ * at boot nothing has been cached yet.
84
+ *
85
+ * Never throws into the phase: a listener that fails must not stop a boot.
86
+ */
87
+ onCloneDiscarded?: (workspaceId: string) => void | Promise<void>;
88
+ /**
89
+ * Called with the workspace id of each working copy the phase CLONED fresh.
90
+ * A clone has just downloaded every ref, which is a successful fetch by any
91
+ * measure — but the git layer keeps its own per-workspace record of the last
92
+ * fetch and whether it worked, and the one that drove the replacement is a
93
+ * FAILED fetch of the repository that is gone. Left standing, a strict
94
+ * branch listing inside that record's TTL refuses the new clone's refs as
95
+ * unproven, having never touched it.
96
+ *
97
+ * The ordinary path already says this (`WorkspaceService`'s cloned
98
+ * listener); the phase clones with git directly, so it has to say it itself.
99
+ *
100
+ * Never throws into the phase, for the same reason as above.
101
+ */
102
+ onCloneCreated?: (workspaceId: string) => void;
61
103
  }
62
104
  /**
63
105
  * The remote could not be reached or refused us: a host that is down, a DNS
@@ -81,6 +123,15 @@ export declare class KbRemoteUnreachableError extends ClassifiedFailure {
81
123
  cause?: unknown;
82
124
  });
83
125
  }
126
+ /**
127
+ * Whether the boot may come up GATED on this failure instead of stopping.
128
+ *
129
+ * {@link KbRemoteUnreachableError} says so by its type — it is raised where
130
+ * the remote is first contacted, before any step. A failure raised INSIDE the
131
+ * phase says so by its classification: the same fetch that stops a boot when
132
+ * it is the first contact must not stop one when a step happened to make it.
133
+ */
134
+ export declare function bootMaySurvive(err: unknown): boolean;
84
135
  export interface RetryOptions {
85
136
  /** First wait before trying again. Default 30s. */
86
137
  initialDelayMs?: number;
@@ -215,7 +266,6 @@ export declare class KbStartupRunner {
215
266
  * not (the backups root is a volume of its own in the shipped compose
216
267
  * files), with the original removed only once the copy is complete.
217
268
  */
218
- private setAside;
219
269
  /**
220
270
  * The branch's working copy at the runtime layout
221
271
  * (`<workspacesRoot>/<id>/<kbDirName>`), so the workspace service finds it
@@ -1 +1 @@
1
- {"version":3,"file":"kb-startup-runner.d.ts","sourceRoot":"","sources":["../../../../src/modules/workspace/startup/kb-startup-runner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAY,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAExF,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,iBAAiB,EAIjB,KAAK,UAAU,EAChB,MAAM,gCAAgC,CAAC;AAIxC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC3C,8EAA8E;IAC9E,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oFAAoF;IACpF,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC;;;;;;2BAMuB;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,wBAAyB,SAAQ,iBAAiB;gBACjD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQxD;AAED,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,sBAAsB;IAEzD,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAA8B;IAC9C,yEAAyE;IACzE,OAAO,CAAC,OAAO,CAAuB;IACtC,iEAAiE;IACjE,OAAO,CAAC,WAAW,CAA2B;IAC9C,+EAA+E;IAC/E,OAAO,CAAC,aAAa,CAA4C;IAEjE;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAId;;;;;OAKG;IACH,iBAAiB,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAIvD;;;;;OAKG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,iGAAiG;IACjG,eAAe,IAAI,UAAU,GAAG,IAAI;IAIpC;;;;;;;OAOG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvB;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,IAAI,GAAE,YAAiB,GAAG;QAAE,IAAI,IAAI,IAAI,CAAA;KAAE;YAgEjD,UAAU;IA+HxB;;;;;OAKG;YACW,YAAY;IA8F1B,OAAO,CAAC,YAAY;IAuBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;YACW,uCAAuC;IA4CrD;;;;;;;;;;OAUG;YACW,2BAA2B;IAyBzC;;;;;OAKG;YACW,QAAQ;IAsBtB;;;;;;;;OAQG;YACW,WAAW;IAyBzB,6EAA6E;YAC/D,QAAQ;CAkFvB"}
1
+ {"version":3,"file":"kb-startup-runner.d.ts","sourceRoot":"","sources":["../../../../src/modules/workspace/startup/kb-startup-runner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAY,aAAa,EAAsB,MAAM,sBAAsB,CAAC;AAExF,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,iBAAiB,EAIjB,KAAK,UAAU,EAEhB,MAAM,gCAAgC,CAAC;AAKxC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC3C,8EAA8E;IAC9E,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oFAAoF;IACpF,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC;;;;;;2BAMuB;IACvB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,wBAAyB,SAAQ,iBAAiB;gBACjD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQxD;AAyBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,sBAAsB;IAEzD,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAA8B;IAC9C,yEAAyE;IACzE,OAAO,CAAC,OAAO,CAAuB;IACtC,iEAAiE;IACjE,OAAO,CAAC,WAAW,CAA2B;IAC9C,+EAA+E;IAC/E,OAAO,CAAC,aAAa,CAA4C;IAEjE;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAId;;;;;OAKG;IACH,iBAAiB,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAIvD;;;;;OAKG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,iGAAiG;IACjG,eAAe,IAAI,UAAU,GAAG,IAAI;IAIpC;;;;;;;OAOG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvB;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,IAAI,GAAE,YAAiB,GAAG;QAAE,IAAI,IAAI,IAAI,CAAA;KAAE;YAgEjD,UAAU;IA+HxB;;;;;OAKG;YACW,YAAY;IA8F1B,OAAO,CAAC,YAAY;IAuBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;YACW,uCAAuC;IAwDrD;;;;;;;;;;OAUG;YACW,2BAA2B;IAyBzC;;;;;OAKG;IAEH;;;;;;;;OAQG;YACW,WAAW;IAmCzB,6EAA6E;YAC/D,QAAQ;CAkFvB"}