@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,130 @@
1
+ -- #74. Three kinds change shape at once, so the stored graphs are rewritten before the schema that
2
+ -- reads them changes. Without this they stop parsing in `db-flows.ts` and the flows become
3
+ -- unopenable — the trap 0007 was written for, at a larger scale.
4
+ --
5
+ -- ⚠️ A `knowledge` node was BOTH a step and its material. Under D25 those are two layers, so it
6
+ -- becomes two nodes: the step stays exactly where it stood in the chain and turns into an
7
+ -- `instruction`, and each reference it held becomes a link hanging off it on a context edge.
8
+ --
9
+ -- ▶ ── knowledge[a,b] ── ▶ becomes ▶ ── instruction ── ▶
10
+ -- │ │
11
+ -- link a link b
12
+ --
13
+ -- Splitting this way rather than turning the node itself into a link is what keeps every existing
14
+ -- edge valid: nothing is re-pointed, nothing is deleted, and a knowledge node sitting directly
15
+ -- after the start still works — as a link it would have had to attach to the start, which is a
16
+ -- marker and holds nothing. It is also the honest reading. The old node WAS a step; what it lacked
17
+ -- was anything saying what to do with the material, which is exactly what the instruction now says.
18
+ --
19
+ -- ⚠️ The kind a reference points at was never stored in the graph — the node only held ids. The
20
+ -- knowledge tree knows, so the rewrite reads it there. A reference whose target is gone becomes
21
+ -- `document`, which is what the old node treated everything as.
22
+
23
+ -- ── The edges: every old edge, plus one context edge per reference ───────────────────────────────
24
+ -- ⚠️ Runs BEFORE the node rewrite, and that order is the whole reason it is readable: while the
25
+ -- knowledge nodes are still knowledge nodes, the id of the step and the list of references sit in
26
+ -- the same row, so the new edge can name both without taking anybody's id apart.
27
+ UPDATE flow_versions
28
+ SET graph_json = json_set(
29
+ graph_json,
30
+ '$.edges',
31
+ (
32
+ SELECT json_group_array(json(value)) FROM (
33
+ SELECT edge.key AS position, 0 AS tier, edge.value AS value
34
+ FROM json_each(flow_versions.graph_json, '$.edges') AS edge
35
+
36
+ UNION ALL
37
+
38
+ SELECT 1000000 + node.key AS position, reference.key + 1 AS tier,
39
+ json_object(
40
+ 'id', json_extract(node.value, '$.id') || '-link-' || reference.key || '-context',
41
+ 'source', json_extract(node.value, '$.id'),
42
+ 'target', json_extract(node.value, '$.id') || '-link-' || reference.key,
43
+ 'kind', 'context',
44
+ 'label', NULL,
45
+ 'sourceHandle', NULL
46
+ ) AS value
47
+ FROM json_each(flow_versions.graph_json, '$.nodes') AS node,
48
+ json_each(json_extract(node.value, '$.configuration.resourceIds')) AS reference
49
+ WHERE json_extract(node.value, '$.kind') = 'knowledge'
50
+ ORDER BY position, tier
51
+ )
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') = 'knowledge'
57
+ );
58
+
59
+ -- ── The nodes: every old node, plus one link per reference ───────────────────────────────────────
60
+ UPDATE flow_versions
61
+ SET graph_json = json_set(
62
+ graph_json,
63
+ '$.nodes',
64
+ (
65
+ SELECT json_group_array(json(value)) FROM (
66
+ -- The old nodes, in place and in order. A knowledge node becomes the instruction it always
67
+ -- half was; its retrieval hint becomes the prompt, because that is the only sentence the
68
+ -- author ever wrote about what should happen with the material.
69
+ SELECT node.key AS position, 0 AS tier,
70
+ CASE
71
+ WHEN json_extract(node.value, '$.kind') = 'knowledge'
72
+ THEN json_set(
73
+ json_set(node.value, '$.kind', 'instruction'),
74
+ '$.configuration',
75
+ json_object(
76
+ 'prompt',
77
+ COALESCE(
78
+ NULLIF(json_extract(node.value, '$.configuration.query'), ''),
79
+ 'Work with the attached material.'
80
+ )
81
+ )
82
+ )
83
+ -- The end marks and no longer makes: `template` was never read by anything.
84
+ WHEN json_extract(node.value, '$.kind') = 'output'
85
+ THEN json_set(node.value, '$.configuration', json_object())
86
+ ELSE node.value
87
+ END AS value
88
+ FROM json_each(flow_versions.graph_json, '$.nodes') AS node
89
+
90
+ UNION ALL
91
+
92
+ -- One link per reference, laid out below its step so the graph opens readable rather than
93
+ -- stacked. The id is derived from the node it came from, which keeps the rewrite idempotent:
94
+ -- running it twice produces the same ids, and there is no second knowledge node to expand.
95
+ SELECT node.key AS position, 1 AS tier,
96
+ json_object(
97
+ 'id', json_extract(node.value, '$.id') || '-link-' || reference.key,
98
+ 'kind', COALESCE(
99
+ (
100
+ SELECT CASE knowledge_nodes.kind
101
+ WHEN 'folder' THEN 'folder'
102
+ WHEN 'attachment' THEN 'upload'
103
+ WHEN 'table' THEN 'table'
104
+ ELSE 'document'
105
+ END
106
+ FROM knowledge_nodes WHERE knowledge_nodes.id = reference.value
107
+ ),
108
+ 'document'
109
+ ),
110
+ 'label', COALESCE(
111
+ (SELECT knowledge_nodes.title FROM knowledge_nodes WHERE knowledge_nodes.id = reference.value),
112
+ 'Missing reference'
113
+ ),
114
+ 'position', json_object(
115
+ 'x', json_extract(node.value, '$.position.x') + (reference.key * 200),
116
+ 'y', json_extract(node.value, '$.position.y') + 160
117
+ ),
118
+ 'configuration', json_object('resourceId', reference.value)
119
+ ) AS value
120
+ FROM json_each(flow_versions.graph_json, '$.nodes') AS node,
121
+ json_each(json_extract(node.value, '$.configuration.resourceIds')) AS reference
122
+ WHERE json_extract(node.value, '$.kind') = 'knowledge'
123
+ ORDER BY position, tier
124
+ )
125
+ )
126
+ )
127
+ WHERE EXISTS (
128
+ SELECT 1 FROM json_each(flow_versions.graph_json, '$.nodes') AS node
129
+ WHERE json_extract(node.value, '$.kind') IN ('knowledge', 'output')
130
+ );
@@ -0,0 +1,48 @@
1
+ -- #76. `context_policy` leaves the contract, the UI and every MCP answer. The COLUMN stays.
2
+ --
3
+ -- ⚠️ HISTORY, and no longer an explanation of what is possible. The column was finally dropped by
4
+ -- `0018_no_context_policy_at_last.sql` (#86), through an ordinary migration file — the very thing
5
+ -- the conclusion at the bottom of this file says cannot be done. What changed is not D1 but the
6
+ -- recipe: `0005`, `0013` and `0016` worked out that the new table has to be created under the FINAL
7
+ -- name instead of renamed into place, and that `node_links` has to be carried out of the way
8
+ -- because it is the one child declared ON DELETE CASCADE. Read on for the three failures that
9
+ -- produced the lessons; read `0018` for the shape that works.
10
+ --
11
+ -- ⚠️ That is not the intent, it is what D1 permits. SQLite cannot drop a column a CHECK names, and
12
+ -- this one names itself. The way around it is a table rebuild, and `knowledge_nodes` carries six
13
+ -- foreign keys, one of them from itself.
14
+ --
15
+ -- Three attempts against the real database, three failures, each with its own lesson:
16
+ --
17
+ -- 1. `PRAGMA foreign_keys = OFF` — **ignored** by D1 over its HTTP API. It works locally, because
18
+ -- miniflare honours it, so the integration test was green while production answered
19
+ -- `FOREIGN KEY constraint failed` on the DROP. ⚠️ A green migration test does not prove a D1
20
+ -- migration runs.
21
+ -- 2. `PRAGMA defer_foreign_keys = true` — it works, but the self-reference was written as
22
+ -- `REFERENCES knowledge_nodes(id)` and therefore pointed at the table this same migration was
23
+ -- about to drop. SQLite rewrites a self-reference along with the rename, so the temporary name
24
+ -- belongs there.
25
+ -- 3. Self-reference fixed → green through `wrangler d1 migrations apply --local`, still red
26
+ -- against `--remote`. The reason is the execution model: D1 commits the statements of a
27
+ -- migration file one at a time, and the deferral only lasts until the next COMMIT. After the
28
+ -- first statement the reprieve is gone and `DROP TABLE` runs unprotected.
29
+ --
30
+ -- A table rebuild with foreign keys is therefore not possible inside a migration file. It needs a
31
+ -- session that drives the transaction itself.
32
+ --
33
+ -- ⚠️ THAT CONCLUSION WAS WRONG, and the way it was wrong is worth more than the conclusion. The
34
+ -- three lessons above are all correct; what they did not contain was the fourth — do not RENAME at
35
+ -- all. Create the new table under the final name and insert the rows back under the name the
36
+ -- children have referenced the whole time, and there is nothing left for a deferred check to
37
+ -- complain about at COMMIT. `0005` found it, `0013` and `0016` repeated it, and `0018` used it to
38
+ -- drop this column at last (#86).
39
+ --
40
+ -- What holds instead: the column sits in D1, nothing reads it, and `db.ts` writes a fixed value on
41
+ -- insert because it is NOT NULL without a DEFAULT. The contract does not know it — for every
42
+ -- consumer it is gone. What remains is one dead column, and that is the price of Intel running.
43
+ --
44
+ -- How it disappears after all is anchrd/intel#86.
45
+ --
46
+ -- This file deliberately does nothing. It is where the above is written down; deleted, it would be
47
+ -- a gap in the numbering that nobody explains.
48
+ SELECT 1;
@@ -0,0 +1,27 @@
1
+ -- Runs that nobody is carrying forward, ended (#83).
2
+ --
3
+ -- The workflow used to wait `365 days` for the next step to be reported, so a run whose agent
4
+ -- stopped — context full, tab closed, session over — stood as "running" for a year and was
5
+ -- indistinguishable from one that really was running. The wait is now the stall timeout; this
6
+ -- clears the ones that were left behind before it existed.
7
+ --
8
+ -- ⚠️ The cut-off is deliberately far past the new timeout rather than equal to it. This runs once,
9
+ -- against rows whose `updated_at` is whatever it happened to be, and a run that is genuinely mid-
10
+ -- step when the migration is applied must not be swept up. A day is long enough that anything
11
+ -- older stopped for good; anything younger is left to the timeout, which measures properly.
12
+ --
13
+ -- ⚠️ `parent_run_id IS NULL OR the child is finished`: a caller standing on a sub-flow node looks
14
+ -- exactly like a stalled run. Ending a caller whose child is still going is the one way this could
15
+ -- destroy work, and it is the same rule the workflow applies at its timeout.
16
+ UPDATE flow_runs
17
+ SET status = 'failed',
18
+ error = 'Nothing has moved this run forward, so it was ended. Whatever was running it stopped without reporting a result — start it again if it is still needed.',
19
+ completed_at = datetime('now'),
20
+ updated_at = datetime('now')
21
+ WHERE status IN ('queued', 'running')
22
+ AND updated_at < datetime('now', '-1 day')
23
+ AND NOT EXISTS (
24
+ SELECT 1 FROM flow_runs child
25
+ WHERE child.parent_run_id = flow_runs.id
26
+ AND child.status IN ('queued', 'running')
27
+ );
@@ -0,0 +1,53 @@
1
+ -- #125: `knowledge` was the first draft's word for the shared tree. The product is called intel,
2
+ -- and a second name for one concept costs a translation in every session. The prefix goes: the tree
3
+ -- is `nodes`, and the four tables around it are named after the node they belong to.
4
+ --
5
+ -- Nothing is rebuilt here, and that is the whole point of the file. `ALTER TABLE ... RENAME TO` is
6
+ -- the one way to change a table's name without a `DROP TABLE`, and `DROP TABLE` is what made the
7
+ -- two migrations that touched this table difficult:
8
+ --
9
+ -- - 0005 had to carry `knowledge_links` out of the way and put it back afterwards, because the
10
+ -- implicit `DELETE FROM` behind `DROP TABLE` fires the ON DELETE CASCADE those rows hang on.
11
+ -- Without the rescue the migration would have committed with every relationship between two
12
+ -- documents quietly gone.
13
+ -- - 0009 gave up on a rebuild altogether. D1 commits the statements of a migration file one at a
14
+ -- time, so `PRAGMA defer_foreign_keys` is spent before the DROP arrives, and
15
+ -- `PRAGMA foreign_keys = OFF` is ignored by D1 over its HTTP API while miniflare honours it —
16
+ -- which is how a green local test can accompany a red remote migration.
17
+ --
18
+ -- A rename touches no row, so neither trap is reachable from here. SQLite rewrites the REFERENCES
19
+ -- clauses of every table pointing at the renamed one — `node_versions`, `node_links` (twice),
20
+ -- `tree_grants`, `flows`, and the tree's reference to itself — so all six foreign keys survive under
21
+ -- the new name and no cascade has anything to fire on. That rewriting is conditional on foreign keys
22
+ -- being enabled, which is exactly what 0005 established the hard way when the cascade took its link
23
+ -- rows: D1 has them on.
24
+ --
25
+ -- ⚠️ Indexes do not follow a rename. They keep working, because an index is bound to its table
26
+ -- rather than to its table's name, but they keep the old name in `sqlite_master` and would be the
27
+ -- last place `knowledge` survives. Dropping and recreating one is free of everything above: an
28
+ -- index holds no rows of its own, and no foreign key points at it.
29
+ --
30
+ -- `node_fts` is a derived FTS5 index and is renamed along with the rest rather than rebuilt; FTS5
31
+ -- renames its own shadow tables. If it ever did come out empty, `intel reindex` builds it back from
32
+ -- D1 and R2 — but nothing here asks it to.
33
+ ALTER TABLE knowledge_nodes RENAME TO nodes;
34
+ ALTER TABLE knowledge_versions RENAME TO node_versions;
35
+ ALTER TABLE knowledge_links RENAME TO node_links;
36
+ ALTER TABLE knowledge_index_state RENAME TO node_index_state;
37
+ ALTER TABLE knowledge_fts RENAME TO node_fts;
38
+
39
+ DROP INDEX knowledge_nodes_parent_idx;
40
+ DROP INDEX knowledge_nodes_owner_idx;
41
+ DROP INDEX knowledge_versions_node_idx;
42
+ DROP INDEX knowledge_links_source_idx;
43
+ DROP INDEX knowledge_links_target_idx;
44
+ DROP INDEX knowledge_links_origin_idx;
45
+ DROP INDEX knowledge_index_state_status_idx;
46
+
47
+ CREATE INDEX nodes_parent_idx ON nodes(parent_id, archived_at, title);
48
+ CREATE INDEX nodes_owner_idx ON nodes(owner_id, archived_at);
49
+ CREATE INDEX node_versions_node_idx ON node_versions(node_id, sequence DESC);
50
+ CREATE INDEX node_links_source_idx ON node_links(source_node_id, created_at);
51
+ CREATE INDEX node_links_target_idx ON node_links(target_node_id, created_at);
52
+ CREATE INDEX node_links_origin_idx ON node_links(source_node_id, origin);
53
+ CREATE INDEX node_index_state_status_idx ON node_index_state(status, updated_at);
@@ -0,0 +1,29 @@
1
+ -- #135: a table version says what it carries. An 'append' holds only the rows one write added; a
2
+ -- 'snapshot' holds the complete table — header and every row — so reading starts at the newest
3
+ -- snapshot and everything before it stays history. Update, delete, and redefine write snapshots;
4
+ -- append keeps writing appends; documents and attachments stay NULL because each of their versions
5
+ -- is complete by construction and the word would say nothing about them.
6
+ --
7
+ -- A plain ADD COLUMN, deliberately: unlike 0005 this touches no CHECK an existing column carries,
8
+ -- so nothing has to be rebuilt and no foreign key is ever in flight.
9
+ ALTER TABLE node_versions ADD COLUMN segment TEXT
10
+ CHECK (segment IS NULL OR segment IN ('append', 'snapshot'));
11
+
12
+ -- Every table that exists was defined through `defineTable`, so its first version is the header
13
+ -- segment — the complete state of the moment it was written, which is exactly what a snapshot is.
14
+ -- Marking it so is what lets "read from the newest snapshot" answer for old tables without a
15
+ -- special case for "no snapshot yet". Every later segment of an existing table is an append.
16
+ UPDATE node_versions
17
+ SET segment = CASE
18
+ WHEN sequence = (
19
+ SELECT MIN(inner_version.sequence) FROM node_versions inner_version
20
+ WHERE inner_version.node_id = node_versions.node_id
21
+ ) THEN 'snapshot'
22
+ ELSE 'append'
23
+ END
24
+ WHERE node_id IN (SELECT id FROM nodes WHERE kind = 'table');
25
+
26
+ -- The two questions every table read asks — "where is the newest snapshot" and "which segments
27
+ -- follow it" — must not scan the whole history to be answered (#30).
28
+ CREATE INDEX node_versions_segment_idx
29
+ ON node_versions(node_id, segment, sequence DESC);
@@ -0,0 +1,38 @@
1
+ -- anchrd/intel#301: one vector per board card, and the record of which vectors a node has.
2
+ --
3
+ -- Vectorize is keyed by node id (`adapters/semantic-index`), so a board was ONE vector holding the
4
+ -- whole document while the full-text half had held one row per card since #285. "Where do I stand
5
+ -- with X" is the question a board exists to answer and it is an imprecise one: lexically it reaches
6
+ -- a card only where the searched word is written on it verbatim. A vector id therefore becomes
7
+ -- `<node id>#<task id>` for a board card and stays the bare node id for every other kind — no
8
+ -- existing vector changes its name, so no installation re-embeds its whole tree to get this.
9
+ --
10
+ -- This table is the D1 side of that index and nothing more: which vectors a node has, what text
11
+ -- each one was made from, and the passage a searcher is shown when that vector is the hit. It is
12
+ -- DERIVED like `node_fts` beside it, and `reindex` empties it so that a rebuild really rebuilds.
13
+ --
14
+ -- ⚠️ `fingerprint` is what keeps a board of three hundred cards from costing three hundred
15
+ -- embeddings per save. The indexing pass compares it against the text it is about to embed and
16
+ -- upserts only what changed; a row is written ONLY AFTER the upsert it describes succeeded. That is
17
+ -- why a fingerprint is stored rather than a timestamp: a pass that dies between the two leaves a
18
+ -- row missing, never a row claiming a vector that was never written, so the next pass repairs
19
+ -- itself instead of trusting a lie.
20
+ --
21
+ -- ⚠️ `chunk_key` is `''` for a node that has exactly one vector — every kind but `board`. NULL
22
+ -- would be the honest spelling and is the wrong one: NULLs are distinct from one another inside a
23
+ -- SQLite primary key, so two rows for the same node could both exist and neither would be found by
24
+ -- the other's write.
25
+ --
26
+ -- ⚠️ No foreign key on `node_id`, deliberately, and for the same reason `node_fts` has none: a
27
+ -- derived index must not be able to make a write to `nodes` fail, and every rebuild of `nodes`
28
+ -- (0005, 0013, 0016, 0018) has to carry each declared child through the detour those files describe.
29
+ -- A row that outlives its node is invisible anyway — hydration joins `nodes` and drops what is
30
+ -- archived or gone, exactly as it does for `node_fts`.
31
+ CREATE TABLE node_vectors (
32
+ node_id TEXT NOT NULL,
33
+ chunk_key TEXT NOT NULL,
34
+ version_id TEXT NOT NULL,
35
+ fingerprint TEXT NOT NULL,
36
+ passage TEXT NOT NULL,
37
+ PRIMARY KEY (node_id, chunk_key)
38
+ );
@@ -0,0 +1,97 @@
1
+ -- #86: `context_policy` leaves `nodes` for good.
2
+ --
3
+ -- #76 removed it from the contract, the UI and every MCP answer — for every consumer it has been
4
+ -- gone since. The COLUMN stayed because SQLite cannot drop one a CHECK names, and `db.ts` has been
5
+ -- writing the fixed value `'relevant'` into it ever since so that inserting a node works at all.
6
+ -- A dead column plus a line of code serving it: harmless, and ballast the next reader has to be
7
+ -- told about.
8
+ --
9
+ -- ⚠️ THE reason this ticket sat open for weeks is that three earlier attempts failed against
10
+ -- `--remote` while passing locally, and the file that recorded them (`0009_no_context_policy.sql`)
11
+ -- concluded that a table rebuild with foreign keys needs "a session that runs the transaction
12
+ -- itself, not a migration file". That conclusion is out of date: `0005`, `0013` and `0016` each
13
+ -- rebuilt this very table through an ordinary migration file, and `0016` did it against the live
14
+ -- database on 2026-08-08 with 120 nodes, every referencing table coming out with the count it went
15
+ -- in with.
16
+ --
17
+ -- ⚠️ `0013` and `0016` are GONE since #392 — they were the Agent and Board rebuilds, and the
18
+ -- feature was parked (#385). What they worked out is not gone with them: the recipe is in
19
+ -- `packages/intel/CLAUDE.md`, which is where the next rebuild reads it, and the three points below
20
+ -- are this file's own copy of it.
21
+ --
22
+ -- ⚠️ One thing about that run is worth knowing before it is quoted as a precedent: the installation
23
+ -- held ZERO `node_links` rows, so the rescue below would have had nothing to rescue and the run
24
+ -- would have passed without exercising it at all. The one row it did carry was created for the
25
+ -- purpose, minutes before, by linking two throwaway documents. The proof was arranged, not found —
26
+ -- and the next person rebuilding this table has to arrange it again, because the installation still
27
+ -- has almost no links.
28
+ --
29
+ -- What the three of them worked out, and what this file copies rather than rediscovers:
30
+ --
31
+ -- 1. `PRAGMA foreign_keys = OFF` is IGNORED by D1 over the HTTP API. Locally miniflare obeys it,
32
+ -- so the integration test was green while the real database answered `FOREIGN KEY constraint
33
+ -- failed`. That is why the proof of a migration here is a run against `--remote`.
34
+ -- 2. The new table is created under the FINAL name rather than built beside the old one and
35
+ -- renamed over it. `ALTER TABLE ... RENAME` makes references FOLLOW the rename, so renaming
36
+ -- the old table out of the way quietly re-points every other table at a table about to be
37
+ -- dropped. Inserting the rows again under the name the children have referenced all along is
38
+ -- what settles them.
39
+ -- 3. `DROP TABLE` on a parent runs an implicit `DELETE FROM` first, and `node_links` is the one
40
+ -- child declared ON DELETE CASCADE — so that delete does not merely flag its rows, it REMOVES
41
+ -- them. They are carried out of the way and put back. That is a rescue, not a decision about
42
+ -- the data. ⚠️ The list of children is in `packages/intel/CLAUDE.md` and is READ FROM THE
43
+ -- DATABASE, not from these files: `0011` renamed the tree and SQLite rewrote the `REFERENCES`
44
+ -- clauses of tables older than it, so their current shape is written down nowhere here.
45
+ --
46
+ -- ⚠️ On an empty database neither detour is visible, because nothing points at anything. That is
47
+ -- how `0005`'s first version passed a green suite and then failed against the first database with
48
+ -- content in it, and why the proof for this file is a row count of every referencing table before
49
+ -- and after rather than a migration that merely ran.
50
+ PRAGMA defer_foreign_keys = TRUE;
51
+
52
+ -- Plain holding tables on purpose: no keys, no CHECKs, no foreign keys, and the column set taken
53
+ -- from whatever the live table has. Anything enforced here would only be enforced a second time on
54
+ -- the way back in, and a holding table that can reject a row is a holding table that can lose one.
55
+ CREATE TABLE nodes_carry AS SELECT * FROM nodes;
56
+ CREATE TABLE node_links_carry AS SELECT * FROM node_links;
57
+
58
+ DROP TABLE nodes;
59
+
60
+ -- The same table as `0016` left it, minus one column. Nothing else about it changes: same keys,
61
+ -- same CHECKs, same six kinds — a rebuild is the only way to drop the column, not an invitation to
62
+ -- change anything else while the table is open.
63
+ CREATE TABLE nodes (
64
+ id TEXT PRIMARY KEY NOT NULL,
65
+ parent_id TEXT REFERENCES nodes(id),
66
+ kind TEXT NOT NULL CHECK (kind IN ('folder', 'document', 'attachment', 'table')),
67
+ title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 240),
68
+ description TEXT CHECK (description IS NULL OR length(description) <= 2000),
69
+ owner_id TEXT NOT NULL,
70
+ current_version_id TEXT,
71
+ created_at TEXT NOT NULL,
72
+ updated_at TEXT NOT NULL,
73
+ archived_at TEXT
74
+ );
75
+
76
+ -- Columns named on both sides rather than `SELECT *`: the holding table still HAS `context_policy`,
77
+ -- and a positional insert would either fail or, worse, shift every value one place to the left.
78
+ INSERT INTO nodes (
79
+ id, parent_id, kind, title, description, owner_id,
80
+ current_version_id, created_at, updated_at, archived_at
81
+ )
82
+ SELECT
83
+ id, parent_id, kind, title, description, owner_id,
84
+ current_version_id, created_at, updated_at, archived_at
85
+ FROM nodes_carry;
86
+
87
+ -- `OR IGNORE` because whether the cascade above actually fired is SQLite's business, not this
88
+ -- migration's: if it did, this puts the rows back; if it did not, each one is already present under
89
+ -- the same primary key and this is a no-op. Either way `node_links` ends up holding exactly what it
90
+ -- held before, which is the only outcome this statement is permitted to have.
91
+ INSERT OR IGNORE INTO node_links SELECT * FROM node_links_carry;
92
+
93
+ DROP TABLE nodes_carry;
94
+ DROP TABLE node_links_carry;
95
+
96
+ CREATE INDEX nodes_parent_idx ON nodes(parent_id, archived_at, title);
97
+ CREATE INDEX nodes_owner_idx ON nodes(owner_id, archived_at);
@@ -0,0 +1,52 @@
1
+ -- #392: the grant table takes the tree's name, and the table nobody reads goes.
2
+ --
3
+ -- Two changes to the same subject, in one file because they are one subject. After Agents and Board
4
+ -- were parked (#385) `tree_grants` is the ONLY grant table left, and it stands beside
5
+ -- `node_versions`, `node_links`, `node_vectors` and `node_index_state` under a name from a different
6
+ -- vocabulary. `node_grants` is the name somebody would guess without looking.
7
+ --
8
+ -- ⚠️ It also closes a split that ran through four layers. D1 said `grants`, the contract says
9
+ -- `ListGrantsInput`/`RevokeGrantInput`, HTTP says `/nodes/:nodeId/grants` — and the MCP surface
10
+ -- alone said `share`. anchrd/intel#396 pulls the tools onto `grant`; this is the other half of the
11
+ -- same move, and afterwards the same thing has the same name everywhere.
12
+ --
13
+ -- ⚠️ A rename is safe HERE and would not be one table up. `ALTER TABLE ... RENAME` makes every
14
+ -- `REFERENCES` clause pointing AT the renamed table follow it — which is the trap the `nodes`
15
+ -- rebuild exists to avoid (see `packages/intel/CLAUDE.md`). `tree_grants` is a child: nothing points
16
+ -- at it, so nothing can follow it anywhere. The direction is what makes the difference, not the
17
+ -- statement.
18
+ --
19
+ -- ⚠️ Indexes do NOT follow a rename. They keep working — an index is bound to its table, not to its
20
+ -- table's name — but they keep the old name in `sqlite_master` and would be the last place
21
+ -- `tree_` survives. That is the lesson `0011` wrote down, and dropping and recreating one is free:
22
+ -- an index holds no rows of its own and nothing points at it.
23
+ ALTER TABLE tree_grants RENAME TO node_grants;
24
+
25
+ DROP INDEX tree_grants_principal_idx;
26
+ DROP INDEX tree_grants_node_idx;
27
+
28
+ CREATE INDEX node_grants_principal_idx ON node_grants(
29
+ principal_type,
30
+ principal_id,
31
+ verb,
32
+ expires_at
33
+ );
34
+
35
+ CREATE INDEX node_grants_node_idx ON node_grants(node_id, verb);
36
+
37
+ -- `resource_grants` has been dead since `0003`, which said so in its own header:
38
+ --
39
+ -- > `resource_grants` is deliberately left in place and untouched. The previous version of the
40
+ -- > Worker reads it and keeps answering correctly until it is replaced; nothing in this version
41
+ -- > reads it any more. Once no old Worker is left, the table holds only history and can be
42
+ -- > dropped.
43
+ --
44
+ -- There is no old Worker. The condition has been met for five migrations and nobody announced the
45
+ -- moment, because nothing forced one — and a customer should not receive a schema carrying a table
46
+ -- no code has read since `0003`.
47
+ --
48
+ -- ⚠️ Dropped here rather than removed from `0000`, and that is deliberate. `0003` reads it: it is
49
+ -- the source every `tree_grants` row was migrated FROM. Taking it out of `0000` would leave `0003`
50
+ -- selecting from a table that never existed, so the history has to keep it and the end of the chain
51
+ -- is where it can go. `0001` also deletes rows from it — same reason, same answer.
52
+ DROP TABLE resource_grants;
@@ -0,0 +1,11 @@
1
+ -- #492: D1 commits before irreversible R2 deletion. This receipt keeps every object key reachable
2
+ -- when an R2 call fails, and also makes a repeated purge key return the original result.
3
+ CREATE TABLE node_purge_receipts (
4
+ actor_id TEXT NOT NULL,
5
+ idempotency_key TEXT NOT NULL,
6
+ node_id TEXT NOT NULL,
7
+ title TEXT NOT NULL,
8
+ content_keys_json TEXT NOT NULL,
9
+ completed_at TEXT,
10
+ PRIMARY KEY (actor_id, idempotency_key)
11
+ );
@@ -0,0 +1,44 @@
1
+ -- #530: a flow is shared on its own again, the way a document and a table are.
2
+ --
3
+ -- `0003` moved every per-flow grant onto a folder because ADR-0004 §3 promised something a narrower
4
+ -- grant would have broken: "everything A calls is covered by the same grant — automatically, and
5
+ -- for all time". The word that carried the promise was *automatically*. A grant on the flow alone
6
+ -- does not reach the sub-flow filed beside it, and in 2026-08 the run would simply have stopped at
7
+ -- that step, without anyone having been told beforehand.
8
+ --
9
+ -- Being told beforehand is what has been built since: `flow_validate` gathers everything standing
10
+ -- between one person and one run — missing `execute`, an unreachable sub-flow, an unreachable tool,
11
+ -- an unreadable tree link — and answers it per person and per moment, on all three surfaces. The
12
+ -- promise is therefore not restored here; it is replaced by a question anybody can ask. ADR-0004 §2
13
+ -- carries the dated amendment, D49 the reason.
14
+ --
15
+ -- ⚠️ A table of its own, not a widened `node_grants`. A flow is not a node — that is the one thing
16
+ -- ADR-0004 §1 was most explicit about — and `node_grants.node_id` carries a REFERENCES clause into
17
+ -- `nodes`. Making the column polymorphic would mean dropping that clause, and an ACL table whose
18
+ -- rows can outlive their subject is precisely where a stale row keeps handing out access.
19
+ --
20
+ -- Everything else is deliberately identical to `node_grants`, down to the index shape: the two are
21
+ -- read by one predicate builder (`db-grants.ts`), and a difference here would become a difference
22
+ -- in the questions it can ask.
23
+ CREATE TABLE flow_grants (
24
+ id TEXT PRIMARY KEY NOT NULL,
25
+ flow_id TEXT NOT NULL REFERENCES flows(id),
26
+ principal_type TEXT NOT NULL CHECK (principal_type IN ('user', 'email', 'organization')),
27
+ principal_id TEXT NOT NULL,
28
+ verb TEXT NOT NULL CHECK (verb IN ('read', 'write', 'execute', 'share')),
29
+ expires_at TEXT,
30
+ created_by TEXT NOT NULL,
31
+ created_at TEXT NOT NULL,
32
+ -- The verb belongs in the key, for the reason `0003` gives: without it one principal holds one
33
+ -- verb per flow, which is the ladder the four independent verbs exist instead of.
34
+ UNIQUE (flow_id, principal_type, principal_id, verb)
35
+ );
36
+
37
+ CREATE INDEX flow_grants_principal_idx ON flow_grants(
38
+ principal_type,
39
+ principal_id,
40
+ verb,
41
+ expires_at
42
+ );
43
+
44
+ CREATE INDEX flow_grants_flow_idx ON flow_grants(flow_id, verb);
@@ -0,0 +1,14 @@
1
+ -- A change feed reads the journal in the order it happened, not by resource. The two indexes from
2
+ -- 0000 both lead with a resource or an actor, so neither can serve "everything since position X":
3
+ -- SQLite would have to scan and sort the whole table on every poll.
4
+ --
5
+ -- ⚠️ Both columns, in the order the cursor compares them. `occurred_at` alone is not enough and the
6
+ -- shortfall is invisible: two events written in the same millisecond — the normal case inside one
7
+ -- batch, not the exception — are indistinguishable, and a reader continuing past the timestamp
8
+ -- skips the second one with no error and no log. The tie-break on `id` is what makes the position
9
+ -- stable, and the index has to carry it or the sort falls back to a scan (anchrd/intel#620).
10
+ --
11
+ -- `resource_type` leads because every query names exactly one kind: today only node events can be
12
+ -- listed at all, and flow events need a different visibility check before they could be.
13
+ CREATE INDEX audit_events_feed_idx
14
+ ON audit_events(resource_type, occurred_at, id);