@anchrd/intel 0.59.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 (364) hide show
  1. package/README.md +496 -0
  2. package/bin/intel.mjs +134 -0
  3. package/dist/adapters/cloudflare/cloudflare-flow-workflow.d.ts +42 -0
  4. package/dist/adapters/cloudflare/cloudflare-flow-workflow.js +89 -0
  5. package/dist/adapters/cloudflare/cloudflare.d.ts +29 -0
  6. package/dist/adapters/cloudflare/cloudflare.js +416 -0
  7. package/dist/adapters/cloudflare/cloudflare.types.d.ts +31 -0
  8. package/dist/adapters/cloudflare/cloudflare.types.js +1 -0
  9. package/dist/adapters/content/content.d.ts +3 -0
  10. package/dist/adapters/content/content.js +128 -0
  11. package/dist/adapters/content/content.types.d.ts +38 -0
  12. package/dist/adapters/content/content.types.js +1 -0
  13. package/dist/adapters/db/db-audit.d.ts +62 -0
  14. package/dist/adapters/db/db-audit.js +150 -0
  15. package/dist/adapters/db/db-boards.d.ts +6 -0
  16. package/dist/adapters/db/db-boards.js +324 -0
  17. package/dist/adapters/db/db-feed.d.ts +30 -0
  18. package/dist/adapters/db/db-feed.js +276 -0
  19. package/dist/adapters/db/db-flows.d.ts +42 -0
  20. package/dist/adapters/db/db-flows.js +1311 -0
  21. package/dist/adapters/db/db-grants.d.ts +133 -0
  22. package/dist/adapters/db/db-grants.js +269 -0
  23. package/dist/adapters/db/db-indexing.d.ts +3 -0
  24. package/dist/adapters/db/db-indexing.js +200 -0
  25. package/dist/adapters/db/db-oauth.d.ts +3 -0
  26. package/dist/adapters/db/db-oauth.js +26 -0
  27. package/dist/adapters/db/db-prompts.d.ts +46 -0
  28. package/dist/adapters/db/db-prompts.js +144 -0
  29. package/dist/adapters/db/db.d.ts +6 -0
  30. package/dist/adapters/db/db.js +1687 -0
  31. package/dist/adapters/db/db.types.d.ts +16 -0
  32. package/dist/adapters/db/db.types.js +1 -0
  33. package/dist/adapters/document-converter/document-converter.d.ts +2 -0
  34. package/dist/adapters/document-converter/document-converter.js +26 -0
  35. package/dist/adapters/document-converter/document-converter.types.d.ts +17 -0
  36. package/dist/adapters/document-converter/document-converter.types.js +1 -0
  37. package/dist/adapters/flow-runtime/flow-runtime.d.ts +3 -0
  38. package/dist/adapters/flow-runtime/flow-runtime.js +22 -0
  39. package/dist/adapters/flow-runtime/flow-runtime.types.d.ts +19 -0
  40. package/dist/adapters/flow-runtime/flow-runtime.types.js +1 -0
  41. package/dist/adapters/index-queue/index-queue.d.ts +10 -0
  42. package/dist/adapters/index-queue/index-queue.js +12 -0
  43. package/dist/adapters/index-queue/index-queue.types.d.ts +11 -0
  44. package/dist/adapters/index-queue/index-queue.types.js +1 -0
  45. package/dist/adapters/json-schema/json-schema.d.ts +2 -0
  46. package/dist/adapters/json-schema/json-schema.js +77 -0
  47. package/dist/adapters/openid/openid.d.ts +5 -0
  48. package/dist/adapters/openid/openid.js +301 -0
  49. package/dist/adapters/portal-tokens/portal-tokens.d.ts +8 -0
  50. package/dist/adapters/portal-tokens/portal-tokens.js +79 -0
  51. package/dist/adapters/remote-tools/remote-tools.d.ts +5 -0
  52. package/dist/adapters/remote-tools/remote-tools.js +129 -0
  53. package/dist/adapters/semantic-index/semantic-index.d.ts +2 -0
  54. package/dist/adapters/semantic-index/semantic-index.js +139 -0
  55. package/dist/adapters/semantic-index/semantic-index.types.d.ts +56 -0
  56. package/dist/adapters/semantic-index/semantic-index.types.js +1 -0
  57. package/dist/adapters/session-cookie/session-cookie.d.ts +5 -0
  58. package/dist/adapters/session-cookie/session-cookie.js +87 -0
  59. package/dist/adapters/tool-source-policy/tool-source-policy.d.ts +1 -0
  60. package/dist/adapters/tool-source-policy/tool-source-policy.js +22 -0
  61. package/dist/audit/audit.d.ts +2 -0
  62. package/dist/audit/audit.js +87 -0
  63. package/dist/audit/audit.types.d.ts +23 -0
  64. package/dist/audit/audit.types.js +1 -0
  65. package/dist/auth/auth.d.ts +2 -0
  66. package/dist/auth/auth.js +284 -0
  67. package/dist/auth/auth.types.d.ts +108 -0
  68. package/dist/auth/auth.types.js +1 -0
  69. package/dist/boards/boards.d.ts +44 -0
  70. package/dist/boards/boards.js +447 -0
  71. package/dist/boards/boards.types.d.ts +117 -0
  72. package/dist/boards/boards.types.js +1 -0
  73. package/dist/build/build.d.ts +2 -0
  74. package/dist/build/build.js +192 -0
  75. package/dist/build/build.types.d.ts +17 -0
  76. package/dist/build/build.types.js +1 -0
  77. package/dist/bundle/bundle.d.ts +4 -0
  78. package/dist/bundle/bundle.js +1194 -0
  79. package/dist/bundle/bundle.types.d.ts +33 -0
  80. package/dist/bundle/bundle.types.js +1 -0
  81. package/dist/cli/cli.d.ts +4 -0
  82. package/dist/cli/cli.js +262 -0
  83. package/dist/cli/cli.types.d.ts +14 -0
  84. package/dist/cli/cli.types.js +1 -0
  85. package/dist/contract/audit.d.ts +50 -0
  86. package/dist/contract/audit.js +72 -0
  87. package/dist/contract/board.d.ts +150 -0
  88. package/dist/contract/board.js +262 -0
  89. package/dist/contract/bundle.d.ts +147 -0
  90. package/dist/contract/bundle.js +139 -0
  91. package/dist/contract/contract.d.ts +112 -0
  92. package/dist/contract/contract.js +143 -0
  93. package/dist/contract/feed.d.ts +126 -0
  94. package/dist/contract/feed.js +149 -0
  95. package/dist/contract/flow-run.d.ts +346 -0
  96. package/dist/contract/flow-run.js +194 -0
  97. package/dist/contract/flow.d.ts +1057 -0
  98. package/dist/contract/flow.js +552 -0
  99. package/dist/contract/node.d.ts +551 -0
  100. package/dist/contract/node.js +456 -0
  101. package/dist/contract/share.d.ts +216 -0
  102. package/dist/contract/share.js +134 -0
  103. package/dist/contract/table.d.ts +171 -0
  104. package/dist/contract/table.js +117 -0
  105. package/dist/contract/tool.d.ts +122 -0
  106. package/dist/contract/tool.js +172 -0
  107. package/dist/feed/feed.d.ts +2 -0
  108. package/dist/feed/feed.js +77 -0
  109. package/dist/feed/feed.types.d.ts +23 -0
  110. package/dist/feed/feed.types.js +1 -0
  111. package/dist/flows/flows.d.ts +41 -0
  112. package/dist/flows/flows.js +2216 -0
  113. package/dist/flows/flows.types.d.ts +339 -0
  114. package/dist/flows/flows.types.js +1 -0
  115. package/dist/http/http.d.ts +9 -0
  116. package/dist/http/http.js +874 -0
  117. package/dist/http/http.types.d.ts +22 -0
  118. package/dist/http/http.types.js +1 -0
  119. package/dist/indexing/indexing.d.ts +6 -0
  120. package/dist/indexing/indexing.js +239 -0
  121. package/dist/indexing/indexing.types.d.ts +11 -0
  122. package/dist/indexing/indexing.types.js +1 -0
  123. package/dist/intel/intel.d.ts +3 -0
  124. package/dist/intel/intel.js +194 -0
  125. package/dist/intel/intel.types.d.ts +24 -0
  126. package/dist/intel/intel.types.js +1 -0
  127. package/dist/mcp/mcp.d.ts +2 -0
  128. package/dist/mcp/mcp.js +1292 -0
  129. package/dist/mcp/mcp.types.d.ts +25 -0
  130. package/dist/mcp/mcp.types.js +1 -0
  131. package/dist/nodes/document-links/document-links.d.ts +20 -0
  132. package/dist/nodes/document-links/document-links.js +57 -0
  133. package/dist/nodes/nodes.d.ts +2 -0
  134. package/dist/nodes/nodes.js +1667 -0
  135. package/dist/nodes/nodes.types.d.ts +511 -0
  136. package/dist/nodes/nodes.types.js +1 -0
  137. package/dist/prepare/prepare.d.ts +4 -0
  138. package/dist/prepare/prepare.js +16 -0
  139. package/dist/prepare/prepare.types.d.ts +9 -0
  140. package/dist/prepare/prepare.types.js +1 -0
  141. package/dist/prompts/prompts.d.ts +2 -0
  142. package/dist/prompts/prompts.js +65 -0
  143. package/dist/prompts/prompts.types.d.ts +71 -0
  144. package/dist/prompts/prompts.types.js +1 -0
  145. package/dist/shared/callers/callers.d.ts +28 -0
  146. package/dist/shared/callers/callers.js +30 -0
  147. package/dist/shared/csv/csv.d.ts +13 -0
  148. package/dist/shared/csv/csv.js +85 -0
  149. package/dist/shared/document-text/document-text.d.ts +21 -0
  150. package/dist/shared/document-text/document-text.js +31 -0
  151. package/dist/shared/gate-authorization/gate-authorization.d.ts +5 -0
  152. package/dist/shared/gate-authorization/gate-authorization.js +26 -0
  153. package/dist/shared/grant-expiry/grant-expiry.d.ts +19 -0
  154. package/dist/shared/grant-expiry/grant-expiry.js +26 -0
  155. package/dist/shared/intel-error/intel-error.d.ts +22 -0
  156. package/dist/shared/intel-error/intel-error.js +27 -0
  157. package/dist/shared/plain-title/plain-title.d.ts +16 -0
  158. package/dist/shared/plain-title/plain-title.js +45 -0
  159. package/dist/shared/problem-details/problem-details.d.ts +30 -0
  160. package/dist/shared/problem-details/problem-details.js +18 -0
  161. package/dist/shared/report-unexpected-error/report-unexpected-error.d.ts +1 -0
  162. package/dist/shared/report-unexpected-error/report-unexpected-error.js +37 -0
  163. package/dist/shared/safe-return-path/safe-return-path.d.ts +2 -0
  164. package/dist/shared/safe-return-path/safe-return-path.js +11 -0
  165. package/dist/shared/sha256/sha256.d.ts +2 -0
  166. package/dist/shared/sha256/sha256.js +14 -0
  167. package/dist/tools/tool-servers/tool-servers.d.ts +46 -0
  168. package/dist/tools/tool-servers/tool-servers.js +177 -0
  169. package/dist/tools/tools.d.ts +2 -0
  170. package/dist/tools/tools.js +207 -0
  171. package/dist/tools/tools.types.d.ts +56 -0
  172. package/dist/tools/tools.types.js +1 -0
  173. package/examples/branding/favicon.svg +5 -0
  174. package/examples/branding/logo.svg +5 -0
  175. package/examples/branding/theme.css +16 -0
  176. package/examples/dev.vars.example +7 -0
  177. package/examples/intel.json +9 -0
  178. package/migrations/0000_intel_foundation.sql +203 -0
  179. package/migrations/0001_portal_native_tools.sql +21 -0
  180. package/migrations/0002_flows_in_the_knowledge_tree.sql +34 -0
  181. package/migrations/0003_folder_permissions.sql +211 -0
  182. package/migrations/0004_subflow_runs.sql +14 -0
  183. package/migrations/0005_flow_node_cleanup.sql +28 -0
  184. package/migrations/0005_tables_in_the_knowledge_tree.sql +68 -0
  185. package/migrations/0006_links_are_written_in_the_text.sql +20 -0
  186. package/migrations/0007_no_node_waits.sql +69 -0
  187. package/migrations/0008_three_layers.sql +130 -0
  188. package/migrations/0009_no_context_policy.sql +48 -0
  189. package/migrations/0010_no_run_waits_a_year.sql +27 -0
  190. package/migrations/0011_one_name_for_the_tree.sql +53 -0
  191. package/migrations/0012_table_snapshots.sql +29 -0
  192. package/migrations/0017_a_vector_per_card.sql +38 -0
  193. package/migrations/0018_no_context_policy_at_last.sql +97 -0
  194. package/migrations/0019_one_name_for_the_grants.sql +52 -0
  195. package/migrations/0020_cascade_purge_replay.sql +11 -0
  196. package/migrations/0021_a_flow_carries_its_own_grant.sql +44 -0
  197. package/migrations/0022_a_cursor_over_the_journal.sql +14 -0
  198. package/migrations/0023_a_board_and_its_tasks.sql +116 -0
  199. package/migrations/0024_the_archive_is_a_column.sql +33 -0
  200. package/migrations/0025_archiving_takes_the_subtree.sql +29 -0
  201. package/migrations/0026_one_feed_over_two_kinds.sql +23 -0
  202. package/migrations/0027_the_runs_of_every_flow.sql +27 -0
  203. package/migrations/0028_a_prompt_name_over_two_kinds.sql +70 -0
  204. package/package.json +118 -0
  205. package/src/contract/CLAUDE.md +152 -0
  206. package/src/contract/README.md +102 -0
  207. package/src/contract/audit.ts +85 -0
  208. package/src/contract/board.ts +306 -0
  209. package/src/contract/bundle.ts +157 -0
  210. package/src/contract/contract.ts +161 -0
  211. package/src/contract/feed.ts +165 -0
  212. package/src/contract/flow-run.ts +241 -0
  213. package/src/contract/flow.ts +675 -0
  214. package/src/contract/node.ts +583 -0
  215. package/src/contract/share.ts +196 -0
  216. package/src/contract/table.ts +178 -0
  217. package/src/contract/tool.ts +202 -0
  218. package/ui/README.md +110 -0
  219. package/ui/components.json +21 -0
  220. package/ui/index.html +13 -0
  221. package/ui/package.json +11 -0
  222. package/ui/scripts/lint-tokens.mjs +187 -0
  223. package/ui/src/access-summary/access-summary.tsx +385 -0
  224. package/ui/src/app/action-slot/action-slot.tsx +27 -0
  225. package/ui/src/app/app-sidebar/app-sidebar.tsx +71 -0
  226. package/ui/src/app/app-tree/app-tree.tsx +1175 -0
  227. package/ui/src/app/app.tsx +87 -0
  228. package/ui/src/app/header-search/header-search.tsx +294 -0
  229. package/ui/src/app/reindex-dialog/reindex-dialog.tsx +79 -0
  230. package/ui/src/app/settings-dialog/settings-dialog.tsx +135 -0
  231. package/ui/src/app/sidebar-preferences/sidebar-preferences.ts +68 -0
  232. package/ui/src/app/sidebar-preferences/sidebar-preferences.types.ts +15 -0
  233. package/ui/src/app/sidebar-resize-handle/sidebar-resize-handle.tsx +86 -0
  234. package/ui/src/app/tree-expansion/tree-expansion.ts +107 -0
  235. package/ui/src/app/tree-expansion/tree-expansion.types.ts +31 -0
  236. package/ui/src/app/tree-move/tree-move.tsx +427 -0
  237. package/ui/src/app/tree-reveal/tree-reveal.ts +64 -0
  238. package/ui/src/app/tree-reveal/tree-reveal.types.ts +16 -0
  239. package/ui/src/app/user-footer/user-footer.tsx +188 -0
  240. package/ui/src/app/view-menu/view-menu.tsx +115 -0
  241. package/ui/src/app-root/app-root.tsx +109 -0
  242. package/ui/src/app-root/app-root.types.ts +27 -0
  243. package/ui/src/archive/archive.tsx +417 -0
  244. package/ui/src/attachment-detail/attachment-detail.ts +52 -0
  245. package/ui/src/attachment-viewer/attachment-viewer.tsx +166 -0
  246. package/ui/src/blocknote-view/blocknote-view.tsx +30 -0
  247. package/ui/src/board/board-assignee/board-assignee-picker.tsx +132 -0
  248. package/ui/src/board/board-assignee/board-assignee.ts +48 -0
  249. package/ui/src/board/board-assignee/board-assignee.tsx +75 -0
  250. package/ui/src/board/board-chip/board-chip.tsx +46 -0
  251. package/ui/src/board/board-crumbs/board-crumbs.ts +56 -0
  252. package/ui/src/board/board-crumbs/board-crumbs.tsx +111 -0
  253. package/ui/src/board/board-data/board-data.ts +195 -0
  254. package/ui/src/board/board-data/board-data.types.ts +38 -0
  255. package/ui/src/board/board-dates/board-dates.ts +40 -0
  256. package/ui/src/board/board-dates/board-dates.tsx +105 -0
  257. package/ui/src/board/board-kanban/board-kanban.ts +162 -0
  258. package/ui/src/board/board-kanban/board-kanban.tsx +680 -0
  259. package/ui/src/board/board-open-task/board-open-task.ts +32 -0
  260. package/ui/src/board/board-panel/board-panel.tsx +259 -0
  261. package/ui/src/board/board-settings/board-settings.tsx +226 -0
  262. package/ui/src/board/board-status/board-status.tsx +60 -0
  263. package/ui/src/board/board-stripes/board-stripes.ts +128 -0
  264. package/ui/src/board/board-table/board-table.ts +53 -0
  265. package/ui/src/board/board-table/board-table.tsx +610 -0
  266. package/ui/src/board/board-task/board-task.ts +108 -0
  267. package/ui/src/board/board-task/board-task.tsx +335 -0
  268. package/ui/src/board/board-title-row/board-title-row.tsx +66 -0
  269. package/ui/src/branding/branding.tsx +17 -0
  270. package/ui/src/branding/custom-logo.ts +1 -0
  271. package/ui/src/branding/favicon.default.svg +5 -0
  272. package/ui/src/branding/favicon.svg +5 -0
  273. package/ui/src/components/ui/avatar.tsx +39 -0
  274. package/ui/src/components/ui/button.tsx +64 -0
  275. package/ui/src/components/ui/collapsible.tsx +20 -0
  276. package/ui/src/components/ui/command.tsx +160 -0
  277. package/ui/src/components/ui/dialog.tsx +143 -0
  278. package/ui/src/components/ui/dropdown-menu.tsx +187 -0
  279. package/ui/src/components/ui/input.tsx +21 -0
  280. package/ui/src/components/ui/popover.tsx +41 -0
  281. package/ui/src/components/ui/select.tsx +163 -0
  282. package/ui/src/components/ui/separator.tsx +26 -0
  283. package/ui/src/components/ui/sheet.tsx +136 -0
  284. package/ui/src/components/ui/sidebar.tsx +693 -0
  285. package/ui/src/components/ui/skeleton.tsx +13 -0
  286. package/ui/src/components/ui/switch.tsx +25 -0
  287. package/ui/src/components/ui/table.tsx +82 -0
  288. package/ui/src/components/ui/tabs.tsx +52 -0
  289. package/ui/src/components/ui/tooltip.tsx +51 -0
  290. package/ui/src/data/intel-data-provider/intel-data-provider.ts +685 -0
  291. package/ui/src/data/intel-data-provider/intel-data-provider.types.ts +266 -0
  292. package/ui/src/data/query-client.ts +18 -0
  293. package/ui/src/data/request-refusal/refusal-notice.tsx +36 -0
  294. package/ui/src/data/request-refusal/request-refusal.ts +51 -0
  295. package/ui/src/data/sign-in/sign-in.ts +97 -0
  296. package/ui/src/data/sign-in/sign-in.types.ts +15 -0
  297. package/ui/src/document-link/document-link.tsx +114 -0
  298. package/ui/src/document-markdown/document-markdown.ts +195 -0
  299. package/ui/src/editor-schema/editor-schema.ts +23 -0
  300. package/ui/src/entry-picker/entry-picker.tsx +238 -0
  301. package/ui/src/feed/feed.tsx +344 -0
  302. package/ui/src/file-preview/file-preview-view.tsx +496 -0
  303. package/ui/src/file-preview/file-preview.tsx +28 -0
  304. package/ui/src/file-preview/pdf-file-preview.tsx +5 -0
  305. package/ui/src/file-preview/presentation-file-preview.tsx +21 -0
  306. package/ui/src/file-preview/spreadsheet-file-preview.tsx +5 -0
  307. package/ui/src/file-preview/word-file-preview.tsx +5 -0
  308. package/ui/src/flow-runs/flow-runs.tsx +238 -0
  309. package/ui/src/flows/flows.tsx +1646 -0
  310. package/ui/src/flows/node-icon/node-icon.ts +34 -0
  311. package/ui/src/flows/node-palette/node-palette.tsx +214 -0
  312. package/ui/src/flows/node-palette/node-palette.types.ts +15 -0
  313. package/ui/src/folder-contents/folder-contents.tsx +321 -0
  314. package/ui/src/folder-index/folder-index.ts +55 -0
  315. package/ui/src/frontmatter/frontmatter.tsx +193 -0
  316. package/ui/src/graph-pane/graph-pane.tsx +53 -0
  317. package/ui/src/hooks/use-mobile.ts +19 -0
  318. package/ui/src/i18n/custom.json +4 -0
  319. package/ui/src/i18n/de.json +609 -0
  320. package/ui/src/i18n/en.json +609 -0
  321. package/ui/src/i18n/es.json +609 -0
  322. package/ui/src/i18n/i18n-context.tsx +65 -0
  323. package/ui/src/i18n/i18n-languages/i18n-languages.ts +83 -0
  324. package/ui/src/i18n/i18n.ts +32 -0
  325. package/ui/src/i18n/i18n.types.ts +49 -0
  326. package/ui/src/kind-icon.ts +97 -0
  327. package/ui/src/lib/utils.ts +6 -0
  328. package/ui/src/main.tsx +68 -0
  329. package/ui/src/modal/modal.tsx +53 -0
  330. package/ui/src/node-details/node-details.tsx +545 -0
  331. package/ui/src/node-editor/node-editor.tsx +304 -0
  332. package/ui/src/node-graph/graph-notice.tsx +21 -0
  333. package/ui/src/node-graph/node-graph.ts +214 -0
  334. package/ui/src/node-graph/node-graph.tsx +295 -0
  335. package/ui/src/node-import/node-import.tsx +418 -0
  336. package/ui/src/node-save-error.ts +46 -0
  337. package/ui/src/node-source/node-source.tsx +128 -0
  338. package/ui/src/node-table/node-table.tsx +107 -0
  339. package/ui/src/nodes/nodes.tsx +240 -0
  340. package/ui/src/rename-resource/rename-resource.ts +80 -0
  341. package/ui/src/resolved-names/resolved-names.tsx +67 -0
  342. package/ui/src/resource-error.ts +33 -0
  343. package/ui/src/resource-menu/resource-menu.tsx +1156 -0
  344. package/ui/src/router/router-context.ts +6 -0
  345. package/ui/src/router/router.tsx +67 -0
  346. package/ui/src/router/router.types.ts +8 -0
  347. package/ui/src/router/selection-search.ts +88 -0
  348. package/ui/src/save-button/save-button.tsx +94 -0
  349. package/ui/src/section-hint/section-hint.tsx +40 -0
  350. package/ui/src/sign-in-refused/sign-in-refused.tsx +35 -0
  351. package/ui/src/styles.css +189 -0
  352. package/ui/src/table-columns/table-columns.tsx +379 -0
  353. package/ui/src/theme/custom.css +1 -0
  354. package/ui/src/theme/theme-context.tsx +89 -0
  355. package/ui/src/theme/theme.ts +70 -0
  356. package/ui/src/time/relative-time.tsx +41 -0
  357. package/ui/src/time/time-context.tsx +78 -0
  358. package/ui/src/time/time.ts +165 -0
  359. package/ui/src/title-row/title-row.tsx +185 -0
  360. package/ui/src/tools/tools.tsx +546 -0
  361. package/ui/src/user-name/user-name.ts +61 -0
  362. package/ui/src/verbatim/verbatim.tsx +68 -0
  363. package/ui/tsconfig.json +17 -0
  364. package/ui/vite.config.ts +129 -0
@@ -0,0 +1,203 @@
1
+ PRAGMA foreign_keys = ON;
2
+
3
+ CREATE TABLE knowledge_nodes (
4
+ id TEXT PRIMARY KEY NOT NULL,
5
+ parent_id TEXT REFERENCES knowledge_nodes(id),
6
+ kind TEXT NOT NULL CHECK (kind IN ('folder', 'document', 'attachment')),
7
+ title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 240),
8
+ description TEXT CHECK (description IS NULL OR length(description) <= 2000),
9
+ context_policy TEXT NOT NULL CHECK (context_policy IN ('pinned', 'relevant', 'explicit')),
10
+ owner_id TEXT NOT NULL,
11
+ current_version_id TEXT,
12
+ created_at TEXT NOT NULL,
13
+ updated_at TEXT NOT NULL,
14
+ archived_at TEXT
15
+ );
16
+
17
+ CREATE INDEX knowledge_nodes_parent_idx ON knowledge_nodes(parent_id, archived_at, title);
18
+ CREATE INDEX knowledge_nodes_owner_idx ON knowledge_nodes(owner_id, archived_at);
19
+
20
+ CREATE TABLE knowledge_versions (
21
+ id TEXT PRIMARY KEY NOT NULL,
22
+ node_id TEXT NOT NULL REFERENCES knowledge_nodes(id),
23
+ sequence INTEGER NOT NULL CHECK (sequence > 0),
24
+ content_key TEXT NOT NULL UNIQUE,
25
+ media_type TEXT NOT NULL,
26
+ content_hash TEXT NOT NULL CHECK (length(content_hash) = 64),
27
+ size INTEGER NOT NULL CHECK (size >= 0),
28
+ created_by TEXT NOT NULL,
29
+ created_at TEXT NOT NULL,
30
+ UNIQUE (node_id, sequence)
31
+ );
32
+
33
+ CREATE INDEX knowledge_versions_node_idx ON knowledge_versions(node_id, sequence DESC);
34
+
35
+ CREATE TABLE knowledge_links (
36
+ id TEXT PRIMARY KEY NOT NULL,
37
+ source_node_id TEXT NOT NULL REFERENCES knowledge_nodes(id) ON DELETE CASCADE,
38
+ target_node_id TEXT NOT NULL REFERENCES knowledge_nodes(id) ON DELETE CASCADE,
39
+ relation TEXT NOT NULL CHECK (relation IN ('references', 'related', 'depends_on', 'implements')),
40
+ label TEXT CHECK (label IS NULL OR length(label) BETWEEN 1 AND 120),
41
+ created_by TEXT NOT NULL,
42
+ created_at TEXT NOT NULL,
43
+ CHECK (source_node_id <> target_node_id),
44
+ UNIQUE (source_node_id, target_node_id, relation)
45
+ );
46
+
47
+ CREATE INDEX knowledge_links_source_idx ON knowledge_links(source_node_id, created_at);
48
+ CREATE INDEX knowledge_links_target_idx ON knowledge_links(target_node_id, created_at);
49
+
50
+ CREATE TABLE knowledge_index_state (
51
+ version_id TEXT PRIMARY KEY NOT NULL REFERENCES knowledge_versions(id),
52
+ status TEXT NOT NULL CHECK (status IN ('pending', 'indexed', 'error')),
53
+ attempt_count INTEGER NOT NULL DEFAULT 0,
54
+ last_error TEXT,
55
+ updated_at TEXT NOT NULL
56
+ );
57
+
58
+ CREATE INDEX knowledge_index_state_status_idx ON knowledge_index_state(status, updated_at);
59
+
60
+ CREATE TABLE resource_grants (
61
+ id TEXT PRIMARY KEY NOT NULL,
62
+ resource_type TEXT NOT NULL CHECK (resource_type IN ('knowledge', 'flow', 'tool-source')),
63
+ resource_id TEXT NOT NULL,
64
+ principal_type TEXT NOT NULL CHECK (principal_type IN ('user', 'email', 'organization')),
65
+ principal_id TEXT NOT NULL,
66
+ role TEXT NOT NULL CHECK (role IN ('viewer', 'commenter', 'editor', 'manager')),
67
+ expires_at TEXT,
68
+ created_by TEXT NOT NULL,
69
+ created_at TEXT NOT NULL,
70
+ UNIQUE (resource_type, resource_id, principal_type, principal_id)
71
+ );
72
+
73
+ CREATE INDEX resource_grants_principal_idx ON resource_grants(
74
+ principal_type,
75
+ principal_id,
76
+ resource_type,
77
+ expires_at
78
+ );
79
+
80
+ CREATE TABLE idempotency_keys (
81
+ actor_id TEXT NOT NULL,
82
+ operation TEXT NOT NULL,
83
+ idempotency_key TEXT NOT NULL,
84
+ resource_id TEXT NOT NULL,
85
+ created_at TEXT NOT NULL,
86
+ PRIMARY KEY (actor_id, operation, idempotency_key)
87
+ );
88
+
89
+ CREATE INDEX idempotency_keys_created_idx ON idempotency_keys(created_at);
90
+
91
+ CREATE TABLE audit_events (
92
+ id TEXT PRIMARY KEY NOT NULL,
93
+ actor_id TEXT NOT NULL,
94
+ action TEXT NOT NULL,
95
+ resource_type TEXT NOT NULL,
96
+ resource_id TEXT NOT NULL,
97
+ metadata_json TEXT NOT NULL DEFAULT '{}',
98
+ occurred_at TEXT NOT NULL
99
+ );
100
+
101
+ CREATE INDEX audit_events_resource_idx ON audit_events(resource_type, resource_id, occurred_at DESC);
102
+ CREATE INDEX audit_events_actor_idx ON audit_events(actor_id, occurred_at DESC);
103
+
104
+ CREATE TABLE oauth_clients (
105
+ issuer TEXT NOT NULL,
106
+ redirect_uri TEXT NOT NULL,
107
+ client_id TEXT NOT NULL,
108
+ created_at TEXT NOT NULL,
109
+ PRIMARY KEY (issuer, redirect_uri)
110
+ );
111
+
112
+ CREATE TABLE tool_sources (
113
+ id TEXT PRIMARY KEY NOT NULL,
114
+ name TEXT NOT NULL,
115
+ url TEXT NOT NULL UNIQUE,
116
+ connection_handle TEXT NOT NULL,
117
+ enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
118
+ created_by TEXT NOT NULL,
119
+ created_at TEXT NOT NULL,
120
+ updated_at TEXT NOT NULL,
121
+ last_discovered_at TEXT
122
+ );
123
+
124
+ CREATE TABLE tool_catalog (
125
+ source_id TEXT NOT NULL REFERENCES tool_sources(id) ON DELETE CASCADE,
126
+ name TEXT NOT NULL,
127
+ title TEXT,
128
+ description TEXT,
129
+ input_schema_json TEXT NOT NULL,
130
+ output_schema_json TEXT,
131
+ annotations_json TEXT NOT NULL,
132
+ fingerprint TEXT NOT NULL,
133
+ discovered_at TEXT NOT NULL,
134
+ PRIMARY KEY (source_id, name)
135
+ );
136
+
137
+ CREATE INDEX tool_catalog_title_idx ON tool_catalog(source_id, title, name);
138
+
139
+ CREATE TABLE flows (
140
+ id TEXT PRIMARY KEY NOT NULL,
141
+ title TEXT NOT NULL,
142
+ description TEXT,
143
+ owner_id TEXT NOT NULL,
144
+ current_version_id TEXT,
145
+ published_version_id TEXT,
146
+ created_at TEXT NOT NULL,
147
+ updated_at TEXT NOT NULL,
148
+ archived_at TEXT
149
+ );
150
+
151
+ CREATE INDEX flows_owner_idx ON flows(owner_id, archived_at, updated_at DESC);
152
+
153
+ CREATE TABLE flow_versions (
154
+ id TEXT PRIMARY KEY NOT NULL,
155
+ flow_id TEXT NOT NULL REFERENCES flows(id),
156
+ sequence INTEGER NOT NULL CHECK (sequence > 0),
157
+ graph_json TEXT NOT NULL,
158
+ created_by TEXT NOT NULL,
159
+ created_at TEXT NOT NULL,
160
+ UNIQUE (flow_id, sequence)
161
+ );
162
+
163
+ CREATE INDEX flow_versions_flow_idx ON flow_versions(flow_id, sequence DESC);
164
+
165
+ CREATE TABLE flow_runs (
166
+ id TEXT PRIMARY KEY NOT NULL,
167
+ flow_id TEXT NOT NULL REFERENCES flows(id),
168
+ version_id TEXT NOT NULL REFERENCES flow_versions(id),
169
+ status TEXT NOT NULL CHECK (status IN ('queued', 'running', 'waiting', 'completed', 'failed', 'cancelled')),
170
+ current_node_id TEXT,
171
+ input_json TEXT NOT NULL,
172
+ output_json TEXT,
173
+ error TEXT,
174
+ initiated_by TEXT NOT NULL,
175
+ created_at TEXT NOT NULL,
176
+ updated_at TEXT NOT NULL,
177
+ completed_at TEXT,
178
+ transition_id TEXT
179
+ );
180
+
181
+ CREATE INDEX flow_runs_flow_idx ON flow_runs(flow_id, created_at DESC);
182
+ CREATE INDEX flow_runs_status_idx ON flow_runs(status, updated_at);
183
+
184
+ CREATE TABLE flow_run_steps (
185
+ id TEXT PRIMARY KEY NOT NULL,
186
+ run_id TEXT NOT NULL REFERENCES flow_runs(id),
187
+ node_id TEXT NOT NULL,
188
+ outcome TEXT NOT NULL CHECK (outcome IN ('completed', 'failed')),
189
+ branch TEXT,
190
+ output_json TEXT,
191
+ error TEXT,
192
+ completed_by TEXT NOT NULL,
193
+ completed_at TEXT NOT NULL,
194
+ UNIQUE (run_id, node_id)
195
+ );
196
+
197
+ CREATE VIRTUAL TABLE knowledge_fts USING fts5(
198
+ version_id UNINDEXED,
199
+ node_id UNINDEXED,
200
+ title,
201
+ content,
202
+ tokenize = 'unicode61 remove_diacritics 2'
203
+ );
@@ -0,0 +1,21 @@
1
+ -- ADR-0003: the Cloudflare MCP portal owns tool discovery, tool permissions and provider
2
+ -- credentials. Intel no longer registers sources, mirrors a catalog or grants access to tools.
3
+ -- 0.1.x shipped these tables, so they are dropped explicitly rather than removed from 0000.
4
+
5
+ DROP INDEX IF EXISTS tool_catalog_title_idx;
6
+ DROP TABLE IF EXISTS tool_catalog;
7
+ DROP TABLE IF EXISTS tool_sources;
8
+
9
+ -- Grants for a resource type that no longer exists would otherwise linger and keep matching the
10
+ -- ACL predicate shape used by knowledge and flows. The CHECK constraint still lists 'tool-source';
11
+ -- rebuilding the table to drop one unused enum value is not worth the migration risk.
12
+ DELETE FROM resource_grants WHERE resource_type = 'tool-source';
13
+
14
+ -- The only tool-related secret Intel stores: the per-user access token for its own portal
15
+ -- endpoint, sealed with the INTEL_SESSION_SECRET-derived key. No provider credential reaches D1.
16
+ CREATE TABLE portal_tokens (
17
+ user_id TEXT PRIMARY KEY NOT NULL,
18
+ sealed TEXT NOT NULL,
19
+ expires_at TEXT NOT NULL,
20
+ updated_at TEXT NOT NULL
21
+ );
@@ -0,0 +1,34 @@
1
+ -- ADR-0004: Knowledge and Flows share one folder tree. A flow gains `parent_id` into the existing
2
+ -- `knowledge_nodes` tree; the contents stay two tables, because versions, the R2 body and the
3
+ -- Vectorize entry belong to the document while the graph, runs and approvals belong to the flow.
4
+
5
+ -- SQLite only accepts an added REFERENCES column when its default is NULL, which is exactly what an
6
+ -- unfiled flow needs: `NULL` is the root of the same tree Knowledge uses.
7
+ ALTER TABLE flows ADD COLUMN parent_id TEXT REFERENCES knowledge_nodes(id);
8
+
9
+ CREATE INDEX flows_parent_idx ON flows(parent_id, archived_at, title);
10
+
11
+ -- Existing flows land in a defined folder rather than scattered across the root. One folder per
12
+ -- owner, with a derived ID so a re-run finds the same row: the narrow reading of an ambiguous case,
13
+ -- as the ADR requires. A single shared folder would have to belong to someone, and its owner would
14
+ -- gain sight of everyone else's flows — a migration must never widen access.
15
+ INSERT INTO knowledge_nodes (
16
+ id, parent_id, kind, title, description, context_policy, owner_id,
17
+ current_version_id, created_at, updated_at, archived_at
18
+ )
19
+ SELECT
20
+ 'folder-flows-' || flow.owner_id,
21
+ NULL,
22
+ 'folder',
23
+ 'Flows',
24
+ 'Flows that existed before Knowledge and Flows shared one tree.',
25
+ 'explicit',
26
+ flow.owner_id,
27
+ NULL,
28
+ '2026-08-01T00:00:00.000Z',
29
+ '2026-08-01T00:00:00.000Z',
30
+ NULL
31
+ FROM flows flow
32
+ GROUP BY flow.owner_id;
33
+
34
+ UPDATE flows SET parent_id = 'folder-flows-' || owner_id WHERE parent_id IS NULL;
@@ -0,0 +1,211 @@
1
+ -- ADR-0004 §2: a grant sits on a node of the shared tree and applies to everything beneath it, and
2
+ -- the verbs `read` / `write` / `execute` / `share` are granted independently. `role` could not carry
3
+ -- that: it is a ladder (viewer < editor < manager), and the case the ADR is built around — /crm is
4
+ -- readable for sales and executable only for billing — is not a rung on it.
5
+ --
6
+ -- `resource_grants` is deliberately left in place and untouched. The previous version of the Worker
7
+ -- reads it and keeps answering correctly until it is replaced; nothing in this version reads it any
8
+ -- more. Once no old Worker is left, the table holds only history and can be dropped.
9
+
10
+ CREATE TABLE tree_grants (
11
+ id TEXT PRIMARY KEY NOT NULL,
12
+ -- Any node of the shared tree, not only a folder: a grant that was migrated from a document has
13
+ -- to stay exactly where it was. Moving it up to the parent folder would hand its principal the
14
+ -- folder's other contents as well, and a migration must never widen access. A grant on a leaf is
15
+ -- simply a subtree of one.
16
+ node_id TEXT NOT NULL REFERENCES knowledge_nodes(id),
17
+ principal_type TEXT NOT NULL CHECK (principal_type IN ('user', 'email', 'organization')),
18
+ principal_id TEXT NOT NULL,
19
+ verb TEXT NOT NULL CHECK (verb IN ('read', 'write', 'execute', 'share')),
20
+ expires_at TEXT,
21
+ created_by TEXT NOT NULL,
22
+ created_at TEXT NOT NULL,
23
+ -- The verb belongs in the key. Without it one principal could hold only one verb per node, which
24
+ -- is the ladder again under a new name.
25
+ UNIQUE (node_id, principal_type, principal_id, verb)
26
+ );
27
+
28
+ CREATE INDEX tree_grants_principal_idx ON tree_grants(
29
+ principal_type,
30
+ principal_id,
31
+ verb,
32
+ expires_at
33
+ );
34
+
35
+ CREATE INDEX tree_grants_node_idx ON tree_grants(node_id, verb);
36
+
37
+ -- `principal_type` and `principal_id` are carried over verbatim, and that is a decision rather than
38
+ -- laziness. Both resolvers read a principal the same way: a user by ID, an email folded to lower
39
+ -- case on both sides, and the whole organization as the literal `*` that `setGrant` has always
40
+ -- written. Rewriting any of them here would be a migration changing who a grant means.
41
+ --
42
+ -- The one case worth naming is an `organization` row whose `principal_id` is not `*`. Nothing in
43
+ -- Intel writes such a row, but a repair or an import could have. It is copied as it stands, so it
44
+ -- matches nobody and the access is gone; normalizing it to `*` would turn a row of unknown scope
45
+ -- into a grant for everyone. Narrow is a lost grant somebody notices, wide is access nobody sees.
46
+
47
+ -- A flow grant has no folder to move to that would be honest. Its own parent folder holds other
48
+ -- things, so putting the grant there would show the principal everything else in that folder. The
49
+ -- narrow reading is a folder that contains exactly this one flow: the flow moves into it, the grant
50
+ -- lands on it, and nothing else is inside. The ID is derived from the flow so a re-run finds the
51
+ -- same row, the same way 0002 derived one folder per owner.
52
+ INSERT OR IGNORE INTO knowledge_nodes (
53
+ id, parent_id, kind, title, description, context_policy, owner_id,
54
+ current_version_id, created_at, updated_at, archived_at
55
+ )
56
+ SELECT
57
+ 'folder-flow-' || flow.id,
58
+ flow.parent_id,
59
+ 'folder',
60
+ flow.title,
61
+ 'Holds one flow that was shared on its own before shares moved to the folder.',
62
+ 'explicit',
63
+ flow.owner_id,
64
+ NULL,
65
+ '2026-08-01T00:00:00.000Z',
66
+ '2026-08-01T00:00:00.000Z',
67
+ NULL
68
+ FROM flows flow
69
+ WHERE EXISTS (
70
+ SELECT 1 FROM resource_grants grant_row
71
+ WHERE grant_row.resource_type = 'flow' AND grant_row.resource_id = flow.id
72
+ )
73
+ AND flow.parent_id IS NOT 'folder-flow-' || flow.id;
74
+
75
+ UPDATE flows SET parent_id = 'folder-flow-' || id
76
+ WHERE EXISTS (
77
+ SELECT 1 FROM resource_grants grant_row
78
+ WHERE grant_row.resource_type = 'flow' AND grant_row.resource_id = flows.id
79
+ )
80
+ AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || flows.id);
81
+
82
+ -- Seeing a flow and starting it were the same permission until now: any flow grant plus the Gate
83
+ -- `flows/run` capability could start a run. Splitting the two without carrying `execute` over would
84
+ -- quietly take away something people have today, so every migrated flow grant keeps it.
85
+ INSERT OR IGNORE INTO tree_grants (
86
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
87
+ )
88
+ SELECT
89
+ grant_row.id || ':read',
90
+ 'folder-flow-' || grant_row.resource_id,
91
+ grant_row.principal_type,
92
+ grant_row.principal_id,
93
+ 'read',
94
+ grant_row.expires_at,
95
+ grant_row.created_by,
96
+ grant_row.created_at
97
+ FROM resource_grants grant_row
98
+ WHERE grant_row.resource_type = 'flow'
99
+ AND EXISTS (
100
+ SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
101
+ );
102
+
103
+ INSERT OR IGNORE INTO tree_grants (
104
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
105
+ )
106
+ SELECT
107
+ grant_row.id || ':execute',
108
+ 'folder-flow-' || grant_row.resource_id,
109
+ grant_row.principal_type,
110
+ grant_row.principal_id,
111
+ 'execute',
112
+ grant_row.expires_at,
113
+ grant_row.created_by,
114
+ grant_row.created_at
115
+ FROM resource_grants grant_row
116
+ WHERE grant_row.resource_type = 'flow'
117
+ AND EXISTS (
118
+ SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
119
+ );
120
+
121
+ INSERT OR IGNORE INTO tree_grants (
122
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
123
+ )
124
+ SELECT
125
+ grant_row.id || ':write',
126
+ 'folder-flow-' || grant_row.resource_id,
127
+ grant_row.principal_type,
128
+ grant_row.principal_id,
129
+ 'write',
130
+ grant_row.expires_at,
131
+ grant_row.created_by,
132
+ grant_row.created_at
133
+ FROM resource_grants grant_row
134
+ WHERE grant_row.resource_type = 'flow'
135
+ AND grant_row.role IN ('editor', 'manager')
136
+ AND EXISTS (
137
+ SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
138
+ );
139
+
140
+ INSERT OR IGNORE INTO tree_grants (
141
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
142
+ )
143
+ SELECT
144
+ grant_row.id || ':share',
145
+ 'folder-flow-' || grant_row.resource_id,
146
+ grant_row.principal_type,
147
+ grant_row.principal_id,
148
+ 'share',
149
+ grant_row.expires_at,
150
+ grant_row.created_by,
151
+ grant_row.created_at
152
+ FROM resource_grants grant_row
153
+ WHERE grant_row.resource_type = 'flow'
154
+ AND grant_row.role = 'manager'
155
+ AND EXISTS (
156
+ SELECT 1 FROM knowledge_nodes node WHERE node.id = 'folder-flow-' || grant_row.resource_id
157
+ );
158
+
159
+ -- Knowledge grants stay on the node they were set on and keep exactly the verbs their role implied.
160
+ -- `execute` is not among them for any role: a Knowledge grant never allowed anyone to start a run,
161
+ -- and handing it out here would be the wide reading of an unambiguous case. `commenter` has no verb
162
+ -- of its own yet, so it maps to `read` — the least it could have meant.
163
+ INSERT OR IGNORE INTO tree_grants (
164
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
165
+ )
166
+ SELECT
167
+ grant_row.id || ':read',
168
+ grant_row.resource_id,
169
+ grant_row.principal_type,
170
+ grant_row.principal_id,
171
+ 'read',
172
+ grant_row.expires_at,
173
+ grant_row.created_by,
174
+ grant_row.created_at
175
+ FROM resource_grants grant_row
176
+ WHERE grant_row.resource_type = 'knowledge'
177
+ AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
178
+
179
+ INSERT OR IGNORE INTO tree_grants (
180
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
181
+ )
182
+ SELECT
183
+ grant_row.id || ':write',
184
+ grant_row.resource_id,
185
+ grant_row.principal_type,
186
+ grant_row.principal_id,
187
+ 'write',
188
+ grant_row.expires_at,
189
+ grant_row.created_by,
190
+ grant_row.created_at
191
+ FROM resource_grants grant_row
192
+ WHERE grant_row.resource_type = 'knowledge'
193
+ AND grant_row.role IN ('editor', 'manager')
194
+ AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
195
+
196
+ INSERT OR IGNORE INTO tree_grants (
197
+ id, node_id, principal_type, principal_id, verb, expires_at, created_by, created_at
198
+ )
199
+ SELECT
200
+ grant_row.id || ':share',
201
+ grant_row.resource_id,
202
+ grant_row.principal_type,
203
+ grant_row.principal_id,
204
+ 'share',
205
+ grant_row.expires_at,
206
+ grant_row.created_by,
207
+ grant_row.created_at
208
+ FROM resource_grants grant_row
209
+ WHERE grant_row.resource_type = 'knowledge'
210
+ AND grant_row.role = 'manager'
211
+ AND EXISTS (SELECT 1 FROM knowledge_nodes node WHERE node.id = grant_row.resource_id);
@@ -0,0 +1,14 @@
1
+ -- ADR-0004 §3/§4: a flow may call another flow. The called flow gets a run of its own — its own
2
+ -- immutable version, its own steps, its own authorization against the user — and these two columns
3
+ -- are the only thing that ties it back to the step that called it.
4
+ --
5
+ -- A single run row that "descends into" the callee was the alternative. It would have had to carry
6
+ -- two versions at once, and the step history would no longer say which graph a node belonged to.
7
+
8
+ ALTER TABLE flow_runs ADD COLUMN parent_run_id TEXT REFERENCES flow_runs(id);
9
+ ALTER TABLE flow_runs ADD COLUMN parent_node_id TEXT;
10
+
11
+ -- One call site starts at most one run: the index is unique so a retried start cannot leave two
12
+ -- results behind for the same step, with nothing to say which one flows back.
13
+ CREATE UNIQUE INDEX flow_runs_call_site_idx ON flow_runs(parent_run_id, parent_node_id)
14
+ WHERE parent_run_id IS NOT NULL;
@@ -0,0 +1,28 @@
1
+ -- #39. Two fields leave the flow graph, so the graphs already in the table are rewritten to match
2
+ -- the contract that will read them. Both are removals of things that never did anything, which is
3
+ -- why the rewrite can be unconditional rather than a decision per flow.
4
+ --
5
+ -- `description` on a node: a node has a title, and what it should do stands in the instruction. Two
6
+ -- free texts beside each other were both kept half up to date.
7
+ --
8
+ -- A trigger's mode: `webhook` and `schedule` triggered nothing and, after the decision in #32, never
9
+ -- will — a flow is carried out by an external agent that brings its own schedule. `manual` is the
10
+ -- honest reading of every trigger that is stored today, because manual is what all of them did.
11
+ --
12
+ -- ⚠️ Written as one pass over the node array rather than a targeted UPDATE: `json_remove` is a no-op
13
+ -- where the key is absent, so re-running this changes nothing. Only `flow_versions` holds a graph.
14
+ UPDATE flow_versions
15
+ SET graph_json = json_set(
16
+ graph_json,
17
+ '$.nodes',
18
+ (
19
+ SELECT json_group_array(
20
+ CASE
21
+ WHEN json_extract(node.value, '$.kind') = 'trigger'
22
+ THEN json_set(json_remove(node.value, '$.description'), '$.configuration', json_object('mode', 'manual'))
23
+ ELSE json_remove(node.value, '$.description')
24
+ END
25
+ )
26
+ FROM json_each(flow_versions.graph_json, '$.nodes') AS node
27
+ )
28
+ );
@@ -0,0 +1,68 @@
1
+ -- #40: a fourth kind in the shared tree — `table`. It is a node like the other three: same
2
+ -- `parent_id`, same folder grants, same immutable `knowledge_versions` rows, same R2 body
3
+ -- (ADR-0004 §1). Nothing here creates a second content model; only the CHECK has to learn the word.
4
+ --
5
+ -- SQLite cannot alter a CHECK constraint, so the table is rebuilt. The rebuild is written the long
6
+ -- way round, and both detours are here because the short way was tried and D1 rolled it back. The
7
+ -- table this migration leaves behind is the same one either way — same columns, same constraints,
8
+ -- same indexes — so an installation that already applied this file keeps exactly what it has.
9
+ --
10
+ -- ⚠️ First detour: the new table is created under the final name rather than built beside the old
11
+ -- one and renamed over it. `DROP TABLE` on a parent runs an implicit `DELETE FROM` first, so the
12
+ -- moment the old `knowledge_nodes` goes, every row of `knowledge_versions`, `tree_grants` and
13
+ -- `flows` pointing at a node is a foreign-key violation. `defer_foreign_keys` postpones the
14
+ -- complaint to COMMIT but does not withdraw it, and `ALTER TABLE ... RENAME` does not settle it
15
+ -- either: a rename puts the name back, not the rows. Only inserting the nodes again, under the name
16
+ -- the children have referenced all along, does. On an empty database none of this is visible —
17
+ -- nothing points at anything — which is precisely how the first version passed a green test suite
18
+ -- and then failed against the first database that had content in it.
19
+ --
20
+ -- ⚠️ Second detour: `knowledge_links` is the only child of `knowledge_nodes` declared ON DELETE
21
+ -- CASCADE, so that same implicit delete does not merely flag its rows, it removes them — the
22
+ -- migration would have committed with every relationship between two documents quietly gone. The
23
+ -- rows are carried out of the way first and put back afterwards. That is a rescue, not a decision
24
+ -- about the data: nothing is dropped, rewritten or reinterpreted here.
25
+ PRAGMA defer_foreign_keys = TRUE;
26
+
27
+ -- Plain holding tables on purpose: no keys, no CHECKs, no foreign keys, and the column set taken
28
+ -- from whatever the live table has. Anything enforced here would only be enforced a second time on
29
+ -- the way back in, and a holding table that can reject a row is a holding table that can lose one.
30
+ CREATE TABLE knowledge_nodes_carry AS SELECT * FROM knowledge_nodes;
31
+ CREATE TABLE knowledge_links_carry AS SELECT * FROM knowledge_links;
32
+
33
+ DROP TABLE knowledge_nodes;
34
+
35
+ CREATE TABLE knowledge_nodes (
36
+ id TEXT PRIMARY KEY NOT NULL,
37
+ parent_id TEXT REFERENCES knowledge_nodes(id),
38
+ kind TEXT NOT NULL CHECK (kind IN ('folder', 'document', 'attachment', 'table')),
39
+ title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 240),
40
+ description TEXT CHECK (description IS NULL OR length(description) <= 2000),
41
+ context_policy TEXT NOT NULL CHECK (context_policy IN ('pinned', 'relevant', 'explicit')),
42
+ owner_id TEXT NOT NULL,
43
+ current_version_id TEXT,
44
+ created_at TEXT NOT NULL,
45
+ updated_at TEXT NOT NULL,
46
+ archived_at TEXT
47
+ );
48
+
49
+ INSERT INTO knowledge_nodes (
50
+ id, parent_id, kind, title, description, context_policy, owner_id,
51
+ current_version_id, created_at, updated_at, archived_at
52
+ )
53
+ SELECT
54
+ id, parent_id, kind, title, description, context_policy, owner_id,
55
+ current_version_id, created_at, updated_at, archived_at
56
+ FROM knowledge_nodes_carry;
57
+
58
+ -- `OR IGNORE` because whether the cascade above actually fired is SQLite's business, not this
59
+ -- migration's: if it did, this puts the rows back; if it did not, each one is already present under
60
+ -- the same primary key and this is a no-op. Either way `knowledge_links` ends up holding exactly
61
+ -- what it held before, which is the only outcome this statement is permitted to have.
62
+ INSERT OR IGNORE INTO knowledge_links SELECT * FROM knowledge_links_carry;
63
+
64
+ DROP TABLE knowledge_nodes_carry;
65
+ DROP TABLE knowledge_links_carry;
66
+
67
+ CREATE INDEX knowledge_nodes_parent_idx ON knowledge_nodes(parent_id, archived_at, title);
68
+ CREATE INDEX knowledge_nodes_owner_idx ON knowledge_nodes(owner_id, archived_at);
@@ -0,0 +1,20 @@
1
+ -- #41: a relationship between two documents is written where it is meant — in the text — and the
2
+ -- dialog that used to create one is gone. Saving a document now rewrites the links it contains.
3
+ --
4
+ -- That rewrite must not touch the links people made in the dialog before there was another way, so
5
+ -- every link learns where it came from. Existing rows are `manual`: they are history, they stay
6
+ -- readable as outgoing links and as backlinks, and nothing writes another one.
7
+ --
8
+ -- Deliberately not a migration of the data. Rewriting the old `relation` values into one kind, or
9
+ -- deleting the rows outright, would throw away a distinction somebody chose on purpose; keeping the
10
+ -- column costs nothing and keeps every existing relationship exactly as it was.
11
+ --
12
+ -- SQLite cannot add a CHECK with ALTER TABLE, so the constraint on this column lives in the
13
+ -- contract (`KnowledgeLinkOrigin`) and in the one repository method that writes it. There is no
14
+ -- table rebuild for it: `knowledge_links` is the target of no foreign key, but it is the source of
15
+ -- two, and a rebuild would be a lot of risk for a constraint the only writer already enforces.
16
+ ALTER TABLE knowledge_links ADD COLUMN origin TEXT NOT NULL DEFAULT 'manual';
17
+
18
+ -- The reconciliation on save reads and deletes by source and origin, and the backlink list reads by
19
+ -- target; both existing indexes stay useful, and this one keeps the delete off a table scan.
20
+ CREATE INDEX knowledge_links_origin_idx ON knowledge_links(source_node_id, origin);
@@ -0,0 +1,69 @@
1
+ -- #73. The approval node leaves the contract, so the graphs already stored are rewritten to match
2
+ -- the schema that will read them. Without this an `approval` node makes `FlowGraph.parse` throw in
3
+ -- `db-flows.ts`, and the flow cannot be opened at all — not even to repair it. A removal that locks
4
+ -- people out of their own flows is worse than the node it removes.
5
+ --
6
+ -- ⚠️ Rewritten to a `condition`, not deleted. The node has two outgoing branches, and deleting it
7
+ -- would leave two edges pointing nowhere and a graph that fails `compileFlow` for a second reason.
8
+ -- A condition is the honest replacement: it branches the same way, and the question the approval
9
+ -- asked — "may this go ahead?" — is one the agent carrying out the run can answer. The prompt is
10
+ -- carried over into the instruction rather than dropped, so the author still reads what was meant.
11
+ -- `timeout` disappears with the waiting it configured (D24).
12
+ --
13
+ -- ⚠️ The branch handles are rewritten with it: an approval branched on `approved`/`rejected`, a
14
+ -- condition on `yes`/`no`. Left alone, `completeStep` would look for a handle that no edge carries
15
+ -- and every run through that node would answer 400.
16
+ --
17
+ -- ⚠️ One pass over the arrays rather than targeted updates, for the same reason as 0005: re-running
18
+ -- must change nothing. A graph with no approval node is written back identical to itself.
19
+ UPDATE flow_versions
20
+ SET graph_json = json_set(
21
+ json_set(
22
+ graph_json,
23
+ '$.nodes',
24
+ (
25
+ SELECT json_group_array(
26
+ CASE
27
+ WHEN json_extract(node.value, '$.kind') = 'approval'
28
+ THEN json_set(
29
+ json_set(node.value, '$.kind', 'condition'),
30
+ '$.configuration',
31
+ json_object(
32
+ 'mode', 'semantic',
33
+ 'instruction', json_extract(node.value, '$.configuration.prompt')
34
+ )
35
+ )
36
+ ELSE node.value
37
+ END
38
+ )
39
+ FROM json_each(flow_versions.graph_json, '$.nodes') AS node
40
+ )
41
+ ),
42
+ '$.edges',
43
+ (
44
+ SELECT json_group_array(
45
+ CASE json_extract(edge.value, '$.sourceHandle')
46
+ WHEN 'approved' THEN json_set(edge.value, '$.sourceHandle', 'yes')
47
+ WHEN 'rejected' THEN json_set(edge.value, '$.sourceHandle', 'no')
48
+ ELSE edge.value
49
+ END
50
+ )
51
+ FROM json_each(flow_versions.graph_json, '$.edges') AS edge
52
+ )
53
+ )
54
+ WHERE EXISTS (
55
+ SELECT 1 FROM json_each(flow_versions.graph_json, '$.nodes') AS node
56
+ WHERE json_extract(node.value, '$.kind') = 'approval'
57
+ );
58
+
59
+ -- `waiting` was written for the approval node and never set by anything: the two places that tested
60
+ -- for it only ever saw `running`. It leaves `FlowRunStatus`, so a row carrying it would become a
61
+ -- status the contract cannot parse. There should be none — this makes that true rather than hoped.
62
+ --
63
+ -- The column's CHECK constraint still allows the value, deliberately: changing it means rebuilding
64
+ -- the table in D1 for a value nothing writes.
65
+ UPDATE flow_runs
66
+ SET status = 'failed',
67
+ error = 'Flow run was waiting for an approval that no longer exists',
68
+ completed_at = COALESCE(completed_at, updated_at)
69
+ WHERE status = 'waiting';