spine-framework 0.3.145 → 0.4.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 (451) hide show
  1. package/.env.example +76 -0
  2. package/.framework/.spine-manifest.json +19 -0
  3. package/.framework/cli/commands/agents.ts +61 -33
  4. package/.framework/cli/commands/auth.ts +60 -28
  5. package/.framework/cli/commands/create-app.ts +212 -80
  6. package/.framework/cli/commands/dev.ts +184 -68
  7. package/.framework/cli/commands/doctor.ts +324 -152
  8. package/.framework/cli/commands/generate.ts +119 -68
  9. package/.framework/cli/commands/init.ts +141 -242
  10. package/.framework/cli/commands/install-app.ts +1336 -314
  11. package/.framework/cli/commands/items.ts +31 -29
  12. package/.framework/cli/commands/migrate.ts +299 -156
  13. package/.framework/cli/commands/migrations.ts +62 -30
  14. package/.framework/cli/commands/pipelines.ts +31 -29
  15. package/.framework/cli/commands/status.ts +105 -45
  16. package/.framework/cli/commands/system.ts +47 -42
  17. package/.framework/cli/commands/test.ts +161 -102
  18. package/.framework/cli/commands/upgrade.ts +260 -0
  19. package/.framework/cli/commands/validate-app.ts +517 -161
  20. package/.framework/cli/context.ts +117 -85
  21. package/.framework/cli/env-loader.ts +74 -43
  22. package/.framework/cli/index.ts +70 -46
  23. package/.framework/cli/lib/project-files.ts +404 -0
  24. package/.framework/docs/guides/testing-guide.md +1 -1
  25. package/.framework/docs/runtime-types.md +72 -72
  26. package/.framework/functions/_shared/access.ts +84 -0
  27. package/.framework/functions/_shared/agent-runner.ts +5051 -1026
  28. package/.framework/functions/_shared/app-manifest.ts +214 -94
  29. package/.framework/functions/_shared/ast.ts +214 -0
  30. package/.framework/functions/_shared/audit.ts +91 -55
  31. package/.framework/functions/_shared/cil.ts +368 -127
  32. package/.framework/functions/_shared/db.ts +337 -68
  33. package/.framework/functions/_shared/funnel.ts +228 -0
  34. package/.framework/functions/_shared/geo.ts +105 -0
  35. package/.framework/functions/_shared/hash-api-key.ts +94 -17
  36. package/.framework/functions/_shared/index.ts +22 -224
  37. package/.framework/functions/_shared/kb.ts +832 -58
  38. package/.framework/functions/_shared/llm.ts +118 -18
  39. package/.framework/functions/_shared/logging.ts +317 -19
  40. package/.framework/functions/_shared/middleware.ts +701 -131
  41. package/.framework/functions/_shared/notify.ts +70 -0
  42. package/.framework/functions/_shared/outcomes.ts +34 -19
  43. package/.framework/functions/_shared/permissions.ts +501 -315
  44. package/.framework/functions/_shared/pipeline-runner.ts +704 -155
  45. package/.framework/functions/_shared/principal.ts +436 -263
  46. package/.framework/functions/_shared/rate-limit.ts +233 -0
  47. package/.framework/functions/_shared/resolve-credentials.ts +86 -19
  48. package/.framework/functions/_shared/resolve-ids.ts +203 -139
  49. package/.framework/functions/_shared/retry-deliveries.ts +51 -16
  50. package/.framework/functions/_shared/schema-utils.ts +602 -521
  51. package/.framework/functions/_shared/security.ts +345 -0
  52. package/.framework/functions/_shared/testing.ts +197 -172
  53. package/.framework/functions/_shared/tracing.ts +351 -21
  54. package/.framework/functions/_shared/trigger-engine.ts +425 -136
  55. package/.framework/functions/_shared/webhook-registration.ts +71 -70
  56. package/.framework/functions/_shared/webhook-registry.ts +126 -83
  57. package/.framework/functions/account-nodes.ts +30 -30
  58. package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
  59. package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
  60. package/.framework/functions/adapters/openai-outbound.ts +15 -16
  61. package/.framework/functions/admin-data.ts +596 -173
  62. package/.framework/functions/admin-funnel.ts +64 -60
  63. package/.framework/functions/admin-install-funnel.ts +84 -66
  64. package/.framework/functions/admin-signals.ts +69 -51
  65. package/.framework/functions/ai-agents.ts +431 -106
  66. package/.framework/functions/ai-interactions.ts +186 -112
  67. package/.framework/functions/api-keys.ts +107 -107
  68. package/.framework/functions/apps.ts +154 -136
  69. package/.framework/functions/auth.ts +83 -65
  70. package/.framework/functions/cil-agent-ingest.ts +189 -232
  71. package/.framework/functions/cil-agent.ts +433 -177
  72. package/.framework/functions/cil-callmap.ts +642 -430
  73. package/.framework/functions/cil-config.ts +139 -135
  74. package/.framework/functions/cil-context.ts +214 -127
  75. package/.framework/functions/cil-doc.ts +587 -458
  76. package/.framework/functions/cil-embeddings.ts +453 -364
  77. package/.framework/functions/cil-graph.ts +427 -142
  78. package/.framework/functions/cil-ingest.ts +1418 -1154
  79. package/.framework/functions/cil-pipeline.ts +276 -21
  80. package/.framework/functions/cil-project.ts +659 -132
  81. package/.framework/functions/cil-validate.ts +198 -164
  82. package/.framework/functions/debug-auth.ts +57 -55
  83. package/.framework/functions/deliveries.ts +80 -21
  84. package/.framework/functions/embeddings.ts +1023 -318
  85. package/.framework/functions/eval-harness.ts +146 -108
  86. package/.framework/functions/integration-outbound.ts +205 -75
  87. package/.framework/functions/integration-routes.ts +128 -23
  88. package/.framework/functions/integrations.ts +125 -100
  89. package/.framework/functions/invites.ts +1095 -460
  90. package/.framework/functions/item-progress.ts +158 -102
  91. package/.framework/functions/kb.ts +34 -10
  92. package/.framework/functions/logs.ts +133 -133
  93. package/.framework/functions/observability.ts +152 -122
  94. package/.framework/functions/pipeline-executions.ts +147 -132
  95. package/.framework/functions/pipelines.ts +134 -119
  96. package/.framework/functions/prompt-configs.ts +96 -80
  97. package/.framework/functions/roles.ts +112 -82
  98. package/.framework/functions/security.ts +450 -0
  99. package/.framework/functions/system-cron.ts +117 -80
  100. package/.framework/functions/system.ts +158 -98
  101. package/.framework/functions/tests.ts +29 -29
  102. package/.framework/functions/timers.ts +94 -95
  103. package/.framework/functions/trigger-scheduler.ts +10 -0
  104. package/.framework/functions/triggers.ts +179 -149
  105. package/.framework/functions/types.ts +137 -125
  106. package/.framework/mcp/index.ts +133 -0
  107. package/.framework/mcp/load-env.ts +60 -0
  108. package/.framework/mcp/shared/app-manifest.ts +275 -0
  109. package/.framework/mcp/shared/db.ts +477 -0
  110. package/.framework/mcp/shared/kb.ts +118 -0
  111. package/.framework/mcp/tools/architect.ts +431 -0
  112. package/.framework/mcp/tools/cil/context.ts +345 -0
  113. package/.framework/mcp/tools/cil/graph.ts +242 -0
  114. package/.framework/mcp/tools/cil/ingest.ts +1217 -0
  115. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
  116. package/.framework/mcp/tools/cil/pipeline.ts +767 -0
  117. package/.framework/mcp/tools/cil/project.ts +791 -0
  118. package/.framework/mcp/tools/cil/retrieval.ts +336 -0
  119. package/.framework/mcp/tools/cil/search-core.ts +454 -0
  120. package/.framework/mcp/tools/cil/search.ts +97 -0
  121. package/.framework/mcp/tools/cil/suggest.ts +186 -0
  122. package/.framework/mcp/tools/cil/validate.ts +1369 -0
  123. package/.framework/mcp/tools/kb/delete.ts +139 -0
  124. package/.framework/mcp/tools/kb/index.ts +52 -0
  125. package/.framework/mcp/tools/kb/ingest.ts +84 -0
  126. package/.framework/mcp/tools/kb/list-types.ts +102 -0
  127. package/.framework/mcp/tools/kb/publish.ts +100 -0
  128. package/.framework/mcp/tools/kb/reindex.ts +86 -0
  129. package/.framework/mcp/tools/kb/revoke.ts +85 -0
  130. package/.framework/mcp/tools/kb/search.ts +101 -0
  131. package/.framework/mcp/tools/kb/upsert.ts +125 -0
  132. package/.framework/mcp/tools/observability.ts +510 -0
  133. package/.framework/migrations/001_core_schema.sql +15 -0
  134. package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
  135. package/.framework/migrations/003_core_system_data.sql +16 -1
  136. package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
  137. package/.framework/migrations/005_core_observability.sql +17 -1
  138. package/.framework/migrations/006_security_hardening_rls.sql +15 -0
  139. package/.framework/migrations/007_kb_article_list.sql +17 -1
  140. package/.framework/migrations/008_items_target.sql +15 -0
  141. package/.framework/migrations/009_roles_slug_unique.sql +15 -0
  142. package/.framework/migrations/010_auth_user_trigger.sql +15 -0
  143. package/.framework/migrations/011_spine_system_account.sql +16 -0
  144. package/.framework/migrations/012_service_role_grants.sql +16 -0
  145. package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
  146. package/.framework/migrations/014_apps_required_roles.sql +16 -0
  147. package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
  148. package/.framework/migrations/016_cil_types.sql +281 -0
  149. package/.framework/migrations/017_cil_stable_ids.sql +37 -0
  150. package/.framework/migrations/018_runtime_tables.sql +129 -0
  151. package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
  152. package/.framework/migrations/020_schema_reconciliation.sql +67 -0
  153. package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
  154. package/.framework/migrations/032_cil_status_migration.sql +73 -0
  155. package/.framework/migrations/033_cil_versioning.sql +73 -0
  156. package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
  157. package/.framework/migrations/035_rate_limits.sql +55 -0
  158. package/.framework/migrations/036_demo_record_flags.sql +72 -0
  159. package/.framework/migrations/037_kb_types_canonical.sql +244 -0
  160. package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
  161. package/.framework/migrations/042_registration_hierarchy.sql +309 -0
  162. package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
  163. package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
  164. package/.framework/migrations/045_security_critical_rls.sql +139 -0
  165. package/.framework/migrations/046_security_missing_rls.sql +79 -0
  166. package/.framework/migrations/047_people_updated_by.sql +27 -0
  167. package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
  168. package/.framework/migrations/049_security_blocklist.sql +148 -0
  169. package/.framework/migrations/050_notifications.sql +49 -0
  170. package/.framework/migrations/051_message_agent_fields.sql +74 -0
  171. package/.framework/migrations/052_registration_security.sql +421 -0
  172. package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
  173. package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
  174. package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
  175. package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
  176. package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
  177. package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
  178. package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
  179. package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
  180. package/.framework/migrations/061_fk_dedup.sql +32 -0
  181. package/.framework/public/spine-logo.svg +10 -3
  182. package/.framework/scripts/app-install-cli.ts +190 -93
  183. package/.framework/scripts/assemble-frontend.sh +127 -44
  184. package/.framework/scripts/assemble-functions.sh +128 -30
  185. package/.framework/scripts/boundary-check.sh +6 -2
  186. package/.framework/scripts/build-manifest.sh +24 -68
  187. package/.framework/scripts/check-core-integrity.sh +15 -76
  188. package/.framework/scripts/checksum-manifest.mts +343 -0
  189. package/.framework/scripts/cil-migrate-markers.ts +403 -0
  190. package/.framework/scripts/fix-cil-markers.mjs +176 -0
  191. package/.framework/scripts/verify-integrity.sh +21 -57
  192. package/.framework/scripts/verify-manifest.mts +305 -0
  193. package/.framework/seeds/types/funnel_signal_use.json +74 -21
  194. package/.framework/seeds/types/spine_instance.json +73 -21
  195. package/.framework/src/App.tsx +118 -72
  196. package/.framework/src/apps/admin/index.tsx +855 -58
  197. package/.framework/src/components/AppWrapper.tsx +43 -45
  198. package/.framework/src/components/CustomAppLoader.tsx +160 -116
  199. package/.framework/src/components/admin/AdminListPage.tsx +46 -44
  200. package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
  201. package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
  202. package/.framework/src/components/admin/PageInstructions.tsx +98 -2
  203. package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
  204. package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
  205. package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
  206. package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
  207. package/.framework/src/components/app-sidebar.tsx +42 -45
  208. package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
  209. package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
  210. package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
  211. package/.framework/src/components/kb/KBArticleList.tsx +251 -10
  212. package/.framework/src/components/layout/AppShell.tsx +51 -45
  213. package/.framework/src/components/layout/Header.tsx +42 -43
  214. package/.framework/src/components/layout/Layout.tsx +46 -46
  215. package/.framework/src/components/layout/Sidebar.tsx +196 -96
  216. package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
  217. package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
  218. package/.framework/src/components/runtime/DataFilters.tsx +49 -74
  219. package/.framework/src/components/runtime/DataHeader.tsx +53 -32
  220. package/.framework/src/components/runtime/DataListPage.tsx +51 -155
  221. package/.framework/src/components/runtime/DataStats.tsx +66 -44
  222. package/.framework/src/components/runtime/DataTable.tsx +49 -149
  223. package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
  224. package/.framework/src/components/runtime/index.ts +119 -16
  225. package/.framework/src/components/search-form.tsx +46 -29
  226. package/.framework/src/components/shared/AgentView.tsx +65 -48
  227. package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
  228. package/.framework/src/components/shared/InviteManager.tsx +207 -97
  229. package/.framework/src/components/shared/MemberList.tsx +97 -0
  230. package/.framework/src/components/shared/SchemaFields.tsx +107 -86
  231. package/.framework/src/components/ui/DataTable.tsx +80 -68
  232. package/.framework/src/components/ui/Form.tsx +157 -146
  233. package/.framework/src/components/ui/ItemCard.tsx +74 -67
  234. package/.framework/src/components/ui/ItemListView.tsx +73 -68
  235. package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
  236. package/.framework/src/components/ui/Modal.tsx +78 -68
  237. package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
  238. package/.framework/src/components/ui/accordion.tsx +85 -86
  239. package/.framework/src/components/ui/alert-dialog.tsx +197 -184
  240. package/.framework/src/components/ui/alert.tsx +105 -94
  241. package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
  242. package/.framework/src/components/ui/avatar.tsx +122 -107
  243. package/.framework/src/components/ui/badge.tsx +60 -55
  244. package/.framework/src/components/ui/breadcrumb.tsx +127 -128
  245. package/.framework/src/components/ui/button-group.tsx +86 -72
  246. package/.framework/src/components/ui/button.tsx +71 -50
  247. package/.framework/src/components/ui/calendar.tsx +72 -57
  248. package/.framework/src/components/ui/card.tsx +136 -129
  249. package/.framework/src/components/ui/carousel.tsx +226 -107
  250. package/.framework/src/components/ui/chart.tsx +252 -147
  251. package/.framework/src/components/ui/checkbox.tsx +43 -44
  252. package/.framework/src/components/ui/collapsible.tsx +86 -71
  253. package/.framework/src/components/ui/combobox.tsx +282 -249
  254. package/.framework/src/components/ui/command.tsx +158 -146
  255. package/.framework/src/components/ui/context-menu.tsx +239 -240
  256. package/.framework/src/components/ui/dialog.tsx +174 -157
  257. package/.framework/src/components/ui/direction.tsx +72 -56
  258. package/.framework/src/components/ui/drawer.tsx +168 -169
  259. package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
  260. package/.framework/src/components/ui/empty.tsx +131 -120
  261. package/.framework/src/components/ui/field.tsx +205 -173
  262. package/.framework/src/components/ui/hover-card.tsx +71 -72
  263. package/.framework/src/components/ui/input-group.tsx +148 -133
  264. package/.framework/src/components/ui/input-otp.tsx +99 -86
  265. package/.framework/src/components/ui/input.tsx +43 -41
  266. package/.framework/src/components/ui/item.tsx +207 -185
  267. package/.framework/src/components/ui/kbd.tsx +57 -56
  268. package/.framework/src/components/ui/label.tsx +45 -41
  269. package/.framework/src/components/ui/menubar.tsx +268 -236
  270. package/.framework/src/components/ui/native-select.tsx +85 -86
  271. package/.framework/src/components/ui/navigation-menu.tsx +166 -156
  272. package/.framework/src/components/ui/pagination.tsx +131 -141
  273. package/.framework/src/components/ui/popover.tsx +125 -128
  274. package/.framework/src/components/ui/progress.tsx +47 -44
  275. package/.framework/src/components/ui/radio-group.tsx +60 -55
  276. package/.framework/src/components/ui/resizable.tsx +85 -72
  277. package/.framework/src/components/ui/scroll-area.tsx +57 -58
  278. package/.framework/src/components/ui/select.tsx +182 -169
  279. package/.framework/src/components/ui/separator.tsx +42 -43
  280. package/.framework/src/components/ui/sheet.tsx +170 -159
  281. package/.framework/src/components/ui/sidebar.tsx +395 -398
  282. package/.framework/src/components/ui/skeleton.tsx +42 -43
  283. package/.framework/src/components/ui/slider.tsx +61 -44
  284. package/.framework/src/components/ui/sonner.tsx +44 -44
  285. package/.framework/src/components/ui/spinner.tsx +47 -42
  286. package/.framework/src/components/ui/switch.tsx +56 -42
  287. package/.framework/src/components/ui/table-primitives.tsx +272 -132
  288. package/.framework/src/components/ui/table.tsx +140 -142
  289. package/.framework/src/components/ui/tabs.tsx +110 -93
  290. package/.framework/src/components/ui/textarea.tsx +43 -44
  291. package/.framework/src/components/ui/toggle-group.tsx +87 -71
  292. package/.framework/src/components/ui/toggle.tsx +56 -56
  293. package/.framework/src/components/ui/tooltip.tsx +99 -85
  294. package/.framework/src/contexts/AppContext.tsx +166 -114
  295. package/.framework/src/contexts/AuthContext.tsx +232 -137
  296. package/.framework/src/hooks/use-mobile.ts +43 -44
  297. package/.framework/src/hooks/useApi.ts +185 -172
  298. package/.framework/src/hooks/useAppPath.ts +31 -29
  299. package/.framework/src/hooks/useApps.ts +77 -42
  300. package/.framework/src/hooks/useEntityList.ts +66 -29
  301. package/.framework/src/hooks/useEntityRecord.ts +76 -32
  302. package/.framework/src/hooks/useForm.ts +62 -30
  303. package/.framework/src/hooks/useListSchema.ts +60 -43
  304. package/.framework/src/hooks/useSchemaRecord.ts +115 -95
  305. package/.framework/src/lib/api.ts +258 -134
  306. package/.framework/src/lib/registration.ts +181 -0
  307. package/.framework/src/lib/supabase.ts +118 -81
  308. package/.framework/src/lib/utils.ts +266 -266
  309. package/.framework/src/main.tsx +43 -44
  310. package/.framework/src/pages/DashboardPage.tsx +44 -43
  311. package/.framework/src/pages/NoAppPage.tsx +50 -0
  312. package/.framework/src/pages/NotFoundPage.tsx +32 -29
  313. package/.framework/src/pages/SetupPage.tsx +34 -33
  314. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
  315. package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
  316. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
  317. package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
  318. package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
  319. package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
  320. package/.framework/src/pages/admin/AppsPage.tsx +45 -42
  321. package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
  322. package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
  323. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
  324. package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
  325. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
  326. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
  327. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
  328. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
  329. package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
  330. package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
  331. package/.framework/src/pages/admin/LogsPage.tsx +87 -137
  332. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
  333. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
  334. package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
  335. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
  336. package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
  337. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
  338. package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
  339. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
  340. package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
  341. package/.framework/src/pages/admin/RolesPage.tsx +47 -164
  342. package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
  343. package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
  344. package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
  345. package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
  346. package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
  347. package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
  348. package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
  349. package/.framework/src/pages/admin/TimersPage.tsx +44 -42
  350. package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
  351. package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
  352. package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
  353. package/.framework/src/pages/admin/TypesPage.tsx +45 -42
  354. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
  355. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
  356. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
  357. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
  358. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
  359. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
  360. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
  361. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
  362. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
  363. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
  364. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
  365. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
  366. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  367. package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
  368. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
  369. package/.framework/src/pages/auth/LoginPage.tsx +38 -32
  370. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
  371. package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
  372. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
  373. package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
  374. package/.framework/src/types/auth.ts +101 -93
  375. package/.framework/src/types/types.ts +283 -262
  376. package/.framework/templates/project.json +87 -0
  377. package/.framework/templates/spine.config.neutral.json +7 -0
  378. package/.framework/tests/api/api-surface.test.ts +381 -0
  379. package/.framework/tests/fixtures/seed.ts +427 -0
  380. package/.framework/tests/fixtures/teardown.ts +228 -0
  381. package/.framework/tests/reporter.ts +351 -0
  382. package/.framework/tests/setup.ts +135 -0
  383. package/.framework/tests/ui/ui-sweep.ts +278 -0
  384. package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
  385. package/.framework/tests/unit/agent-runner.test.ts +2389 -0
  386. package/.framework/tests/unit/ai-interactions.test.ts +81 -0
  387. package/.framework/tests/unit/app-manifest.test.ts +359 -0
  388. package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
  389. package/.framework/tests/unit/cil-determinism.test.ts +85 -0
  390. package/.framework/tests/unit/core-isolation.test.ts +153 -0
  391. package/.framework/tests/unit/funnel-signals.test.ts +135 -0
  392. package/.framework/tests/unit/install-app.test.ts +1759 -0
  393. package/.framework/tests/unit/invites-security.test.ts +572 -0
  394. package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
  395. package/.framework/tests/unit/kb-search.test.ts +119 -0
  396. package/.framework/tests/unit/migrate.test.ts +509 -0
  397. package/.framework/tests/unit/notify.test.ts +136 -0
  398. package/.framework/tests/unit/permissions.test.ts +269 -0
  399. package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
  400. package/.framework/tests/unit/principal-cache.test.ts +138 -0
  401. package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
  402. package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
  403. package/.framework/tests/unit/schema-utils.test.ts +225 -0
  404. package/.framework/tests/unit/trigger-engine.test.ts +513 -0
  405. package/.framework/tests/unit/validate-app.test.ts +527 -0
  406. package/README.md +34 -3
  407. package/bin/spine-framework.cjs +1 -0
  408. package/config/tailwind.config.cjs +7 -0
  409. package/config/tsconfig.functions.json +42 -0
  410. package/config/tsconfig.json +37 -9
  411. package/config/vite.config.ts +31 -2
  412. package/netlify.toml +31 -3
  413. package/package.json +46 -29
  414. package/scripts/assemble-frontend.sh +127 -44
  415. package/scripts/assemble-functions.sh +127 -29
  416. package/scripts/boundary-check.sh +6 -2
  417. package/scripts/build-manifest.sh +24 -68
  418. package/scripts/checksum-manifest.mts +345 -0
  419. package/scripts/dev-clean.sh +86 -0
  420. package/scripts/dev-netlify.sh +49 -0
  421. package/scripts/netlify-dev-wrapper.sh +2 -0
  422. package/scripts/verify-install.ts +358 -0
  423. package/scripts/verify-integrity.sh +21 -57
  424. package/scripts/verify-manifest.mts +305 -0
  425. package/templates/project/gitignore +45 -0
  426. package/{config → templates/project}/package-lock.json +22335 -9366
  427. package/vitest.config.ts +46 -0
  428. package/.framework/public/spine.config.json +0 -91
  429. package/config/deno.lock +0 -108
  430. package/config/tsconfig.node.tsbuildinfo +0 -1
  431. package/config/tsconfig.tsbuildinfo +0 -1
  432. package/config/vite.config.d.ts +0 -2
  433. package/custom/.devin/AGENT.md +0 -357
  434. package/custom/.devin/skills/install-app/SKILL.md +0 -39
  435. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
  436. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
  437. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
  438. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
  439. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
  440. package/custom/.devin/workflows/app-install.yaml +0 -83
  441. package/custom/README.md +0 -79
  442. package/docs/README.md +0 -15
  443. package/scripts/app-install-cli.ts +0 -286
  444. package/scripts/check-core-integrity.sh +0 -82
  445. package/scripts/ingest-chunks.cjs +0 -202
  446. package/scripts/kb-chunk-parser.cjs +0 -312
  447. package/scripts/kb-chunk-parser.ts +0 -330
  448. package/scripts/kb-ingest-docs.ts +0 -203
  449. package/scripts/load-test-app-install.ts +0 -484
  450. package/scripts/test-login.js +0 -33
  451. package/spine.config.json +0 -91
@@ -0,0 +1,37 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/017_cil_stable_ids.sql:module_header:module_header" type="module_header" identity="module_header" parent="none"]
2
+ -- CIL[DOC-MACRO purpose="Deprecated migration header for CIL stable IDs"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Document the migration purpose and deprecation status"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/migrations/017_cil_stable_ids.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ -- CIL[DOC-MICRO logic_summary="Contains a deprecation notice and a no-op SELECT statement for applied databases" notable_decisions="[]"]
7
+ -- CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="deprecated"]
9
+ -- CIL[DOC-AUDIENCE audience="installer"]
10
+ -- 017_cil_stable_ids.sql
11
+ -- Deprecated: stable IDs and versions are now generated at ingest time.
12
+ -- The old hard-coded backfill is no longer run on new installs.
13
+ -- Existing databases that already applied this migration are unaffected.
14
+ -- CIL[DOC-VECTOR type="context" content="purpose='Deprecated migration header for CIL stable IDs'; No verified external callers; imports: none"]
15
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
16
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
17
+ -- CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
18
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
19
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
20
+ -- CIL[END stable_id="~/.framework/migrations/017_cil_stable_ids.sql:module_header:module_header"]
21
+
22
+ -- CIL[BEGIN stable_id="~/.framework/migrations/017_cil_stable_ids.sql:noop:statement" type="statement" identity="noop" parent="none"]
23
+ -- CIL[DOC-MACRO purpose="No-op migration placeholder statement"]
24
+ -- CIL[DOC-RESPONSIBILITY responsibility="Satisfy migration runner with a harmless SELECT"]
25
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/migrations/017_cil_stable_ids.sql"]
26
+ -- CIL[DOC-CONTRACT inputs="none" outputs="scalar 1" errors="none" side_effects="none"]
27
+ -- CIL[DOC-MICRO logic_summary="Executes SELECT 1 to mark the migration as applied" notable_decisions="[]"]
28
+ -- CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
29
+ -- CIL[DOC-STABILITY stability="deprecated"]
30
+ SELECT 1;
31
+ -- CIL[DOC-VECTOR type="context" content="purpose='No-op migration placeholder statement'; No verified external callers; imports: none"]
32
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
33
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
34
+ -- CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
35
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
36
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
37
+ -- CIL[END stable_id="~/.framework/migrations/017_cil_stable_ids.sql:noop:statement"]
@@ -0,0 +1,129 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/018_runtime_tables.sql:runtime_tables:file" type="file" identity="runtime_tables" parent="~/.framework/migrations/018_runtime_tables.sql"]
2
+ -- CIL[DOC-MACRO purpose="Create the runtime action/schedule/test-result tables that the live chain references but never created"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Create actions, schedules, schedule_executions, and test_results with foreign keys, indexes, and RLS enabled"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/functions/system-cron.ts,.framework/functions/trigger-scheduler.ts,.framework/functions/tests.ts,.framework/migrations/043_policy_actor_cleanup.sql,.framework/migrations/046_security_missing_rls.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="none" outputs="Four tables matching archive-era schema" errors="none — CREATE TABLE IF NOT EXISTS and guarded constraints are idempotent" side_effects="Enables RLS; 043/046 then attach policies"]
6
+ -- CIL[DOC-MICRO logic_summary="These tables existed only in archive migrations, so dev databases carry them but fresh installs did not — 043/046 failed on missing relations. Definitions are pulled verbatim from archive/002e_system_tables.sql, archive/003_foreign_keys.sql, and archive/008_test_runs.sql; FK constraints are guarded by pg_constraint checks so the file is a no-op where tables already exist" notable_decisions="numbered 018 to run before 043/046 which attach the RLS policies; test_results keeps its run_id FK to test_runs"]
7
+ -- CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+
10
+ -- Runtime tables that archive migrations created but the live chain only
11
+ -- referenced (043 policies, 046 RLS, system-cron/trigger-scheduler/agent-runner/
12
+ -- tests.ts consumers). IF NOT EXISTS makes this a no-op on databases that
13
+ -- already carry them.
14
+
15
+ CREATE TABLE IF NOT EXISTS public.actions (
16
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
17
+ account_id uuid, name text NOT NULL, slug text NOT NULL,
18
+ description text, handler text NOT NULL, handler_module text DEFAULT 'functions',
19
+ config jsonb DEFAULT '{}', input_schema jsonb DEFAULT '{}', output_schema jsonb DEFAULT '{}',
20
+ ownership text DEFAULT 'tenant', is_system boolean DEFAULT false,
21
+ default_machine_principal_id uuid, required_scopes text[] DEFAULT '{}',
22
+ is_active boolean DEFAULT true, timeout_seconds integer DEFAULT 300,
23
+ retry_count integer DEFAULT 3, created_by uuid, created_at timestamptz DEFAULT now()
24
+ );
25
+
26
+ CREATE TABLE IF NOT EXISTS public.schedules (
27
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
28
+ account_id uuid, action_id uuid NOT NULL, name text NOT NULL,
29
+ schedule_type text NOT NULL, cron_expression text,
30
+ next_run_at timestamptz, last_run_at timestamptz,
31
+ ownership text DEFAULT 'tenant', is_system boolean DEFAULT false,
32
+ is_active boolean DEFAULT true, machine_principal_id uuid,
33
+ created_by uuid, created_at timestamptz DEFAULT now(), updated_at timestamptz DEFAULT now()
34
+ );
35
+
36
+ CREATE TABLE IF NOT EXISTS public.schedule_executions (
37
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
38
+ schedule_id uuid NOT NULL, account_id uuid NOT NULL, machine_principal_id uuid,
39
+ status text DEFAULT 'pending', input_params jsonb DEFAULT '{}',
40
+ output_result jsonb DEFAULT '{}', error_message text, duration_ms integer,
41
+ created_at timestamptz DEFAULT now()
42
+ );
43
+
44
+ -- test_runs carries two historical shapes: the archive runner shape
45
+ -- (suite/status/counts, consumed by tests.ts) and the generic registry shape
46
+ -- created in 001. Add the runner columns additively so both consumers work
47
+ -- regardless of which lineage built the database.
48
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS suite text;
49
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS status text;
50
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS started_at timestamptz;
51
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS finished_at timestamptz;
52
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS duration_ms integer;
53
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS total integer;
54
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS passed integer;
55
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS failed integer;
56
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS skipped integer;
57
+ ALTER TABLE public.test_runs ADD COLUMN IF NOT EXISTS triggered_by text DEFAULT 'agent';
58
+
59
+ CREATE TABLE IF NOT EXISTS public.test_results (
60
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
61
+ run_id uuid NOT NULL REFERENCES public.test_runs(id) ON DELETE CASCADE,
62
+ suite text NOT NULL,
63
+ file text,
64
+ describe text,
65
+ name text NOT NULL,
66
+ status text NOT NULL,
67
+ duration_ms integer,
68
+ error text,
69
+ created_at timestamptz NOT NULL DEFAULT now()
70
+ );
71
+
72
+ CREATE INDEX IF NOT EXISTS idx_test_results_run_id ON public.test_results(run_id);
73
+ CREATE INDEX IF NOT EXISTS idx_test_runs_suite ON public.test_runs(suite);
74
+ CREATE INDEX IF NOT EXISTS idx_test_runs_started_at ON public.test_runs(started_at DESC);
75
+
76
+ -- Foreign keys from archive/003_foreign_keys.sql, guarded for idempotency
77
+ DO $$
78
+ BEGIN
79
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_actions_account') THEN
80
+ ALTER TABLE public.actions ADD CONSTRAINT fk_actions_account
81
+ FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE CASCADE;
82
+ END IF;
83
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_actions_machine_principal') THEN
84
+ ALTER TABLE public.actions ADD CONSTRAINT fk_actions_machine_principal
85
+ FOREIGN KEY (default_machine_principal_id) REFERENCES public.api_keys(id) ON DELETE SET NULL;
86
+ END IF;
87
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_actions_created_by') THEN
88
+ ALTER TABLE public.actions ADD CONSTRAINT fk_actions_created_by
89
+ FOREIGN KEY (created_by) REFERENCES public.people(id) ON DELETE SET NULL;
90
+ END IF;
91
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_schedules_account') THEN
92
+ ALTER TABLE public.schedules ADD CONSTRAINT fk_schedules_account
93
+ FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE CASCADE;
94
+ END IF;
95
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_schedules_action') THEN
96
+ ALTER TABLE public.schedules ADD CONSTRAINT fk_schedules_action
97
+ FOREIGN KEY (action_id) REFERENCES public.actions(id) ON DELETE CASCADE;
98
+ END IF;
99
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_schedules_machine') THEN
100
+ ALTER TABLE public.schedules ADD CONSTRAINT fk_schedules_machine
101
+ FOREIGN KEY (machine_principal_id) REFERENCES public.api_keys(id) ON DELETE SET NULL;
102
+ END IF;
103
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_schedules_created_by') THEN
104
+ ALTER TABLE public.schedules ADD CONSTRAINT fk_schedules_created_by
105
+ FOREIGN KEY (created_by) REFERENCES public.people(id) ON DELETE SET NULL;
106
+ END IF;
107
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_se_schedule') THEN
108
+ ALTER TABLE public.schedule_executions ADD CONSTRAINT fk_se_schedule
109
+ FOREIGN KEY (schedule_id) REFERENCES public.schedules(id) ON DELETE CASCADE;
110
+ END IF;
111
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_se_account') THEN
112
+ ALTER TABLE public.schedule_executions ADD CONSTRAINT fk_se_account
113
+ FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE CASCADE;
114
+ END IF;
115
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_se_machine') THEN
116
+ ALTER TABLE public.schedule_executions ADD CONSTRAINT fk_se_machine
117
+ FOREIGN KEY (machine_principal_id) REFERENCES public.api_keys(id) ON DELETE SET NULL;
118
+ END IF;
119
+ END $$;
120
+
121
+ -- RLS enabled here; 043/046 attach the actual policies
122
+ ALTER TABLE public.actions ENABLE ROW LEVEL SECURITY;
123
+ ALTER TABLE public.schedules ENABLE ROW LEVEL SECURITY;
124
+ ALTER TABLE public.schedule_executions ENABLE ROW LEVEL SECURITY;
125
+ ALTER TABLE public.test_results ENABLE ROW LEVEL SECURITY;
126
+ -- CIL[DOC-VECTOR type="context" content="purpose='Create runtime tables (actions/schedules/schedule_executions/test_results) that archive migrations owned but the live chain never created.'; No verified external callers; imports: none"]
127
+ -- CIL[DOC-VECTOR type="blast_radius" content="Fresh installs gain the tables that system-cron, trigger-scheduler, agent-runner, pipeline-runner, and tests.ts query; existing databases are untouched via IF NOT EXISTS" status="ready"]
128
+ -- CIL[DOC-VECTOR type="configuration" content="None — runs position 018 so 043/046 policy migrations apply cleanly after it" status="ready"]
129
+ -- CIL[END stable_id="~/.framework/migrations/018_runtime_tables.sql:runtime_tables:file"]
@@ -0,0 +1,56 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/019_agent_prompt_columns.sql:agent_prompt_columns:file" type="file" identity="agent_prompt_columns" parent="~/.framework/migrations/019_agent_prompt_columns.sql"]
2
+ -- CIL[DOC-MACRO purpose="Reconcile ai_agents/prompt_configs column divergence between archive-era and live-chain table shapes"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Add the rich agent/prompt columns the archive schema carried that the live generic registry shape lacks, plus the slug column and uniqueness index dev databases are missing"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/functions/_shared/agent-runner.ts,.framework/functions/ai-agents.ts,.framework/migrations/archive/002e_system_tables.sql,.framework/migrations/001_core_schema.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="none" outputs="Both tables carry the union of archive and live columns" errors="none — ADD COLUMN IF NOT EXISTS is idempotent" side_effects="Unique indexes enable seedApp upserts on (app_id,slug)"]
6
+ -- CIL[DOC-MICRO logic_summary="agent-runner.ts reads agent.system_prompt/model_config/agent_type and promptConfig.context_template/confidence_threshold/knowledge_sources/etc directly — columns the live 001 generic shape never created but dev databases carry via archive. Adds every archive column additively plus slug/unique-index on ai_agents (dev's table predates the slug convention; fresh installs get NOT NULL from 001 and skip this)" notable_decisions="columns added nullable because existing dev rows cannot retroactively satisfy NOT NULL; the (app_id,slug) unique index tolerates existing NULL slugs so it can be created on dev lineage"]
7
+ -- CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+
10
+ -- ai_agents: archive columns the live generic shape lacks.
11
+ -- slug is added nullable for dev lineage (existing rows have no slug);
12
+ -- fresh installs already have it NOT NULL from 001.
13
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS slug text;
14
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS type_id uuid;
15
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS agent_type text;
16
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS model_config jsonb DEFAULT '{}';
17
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS system_prompt text;
18
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS tools jsonb DEFAULT '[]';
19
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS capabilities jsonb DEFAULT '[]';
20
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS constraints jsonb DEFAULT '{}';
21
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
22
+ ALTER TABLE public.ai_agents ADD COLUMN IF NOT EXISTS updated_by uuid;
23
+
24
+ -- prompt_configs: archive columns the live generic shape lacks.
25
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS type_id uuid;
26
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS description text;
27
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS system_prompt text;
28
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS context_template text;
29
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS model text;
30
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS temperature numeric;
31
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS max_tokens integer;
32
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS is_multi_turn boolean DEFAULT false;
33
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS max_history_messages integer;
34
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS confidence_threshold numeric;
35
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS escalation_action text;
36
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS escalation_target text;
37
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS output_mode text;
38
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS output_field text;
39
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS requires_review boolean DEFAULT false;
40
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS knowledge_sources jsonb DEFAULT '[]';
41
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS available_tools jsonb DEFAULT '[]';
42
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS tool_constraints jsonb DEFAULT '{}';
43
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
44
+ ALTER TABLE public.prompt_configs ADD COLUMN IF NOT EXISTS updated_by uuid;
45
+
46
+ -- Uniqueness indexes so seedApp upserts on (app_id,slug) work on both lineages.
47
+ -- NULL slugs on dev lineage are allowed (NULLs are distinct) and get backfilled
48
+ -- by future seed writes.
49
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_ai_agents_app_slug
50
+ ON public.ai_agents (app_id, slug);
51
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_prompt_configs_app_slug
52
+ ON public.prompt_configs (app_id, slug);
53
+ -- CIL[DOC-VECTOR type="context" content="purpose='Add missing archive-shape columns to ai_agents and prompt_configs so agent-runner and seed upserts work on fresh installs.'; No verified external callers; imports: none"]
54
+ -- CIL[DOC-VECTOR type="blast_radius" content="Fresh installs gain the columns agent-runner.ts reads; dev databases gain slug/unique-index so the same seed files work on both" status="ready"]
55
+ -- CIL[DOC-VECTOR type="constraint" content="slug added nullable rather than NOT NULL because existing dev rows cannot satisfy the constraint retroactively" status="ready"]
56
+ -- CIL[END stable_id="~/.framework/migrations/019_agent_prompt_columns.sql:agent_prompt_columns:file"]
@@ -0,0 +1,67 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/020_schema_reconciliation.sql:schema_reconciliation:file" type="file" identity="schema_reconciliation" parent="~/.framework/migrations/020_schema_reconciliation.sql"]
2
+ -- CIL[DOC-MACRO purpose="Reconcile archive-era columns the live generic registry shape dropped from nine runtime tables"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Add dev-lineage columns to triggers, timers, pipelines, trigger_executions, pipeline_executions, api_keys, item_progress, logs, and messages so runtime functions work on live-chain schemas"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/functions/_shared/trigger-engine.ts,.framework/functions/trigger-scheduler.ts,.framework/functions/system-cron.ts,.framework/functions/_shared/pipeline-runner.ts,.framework/migrations/018_runtime_tables.sql,.framework/migrations/019_agent_prompt_columns.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="none" outputs="Nine tables carry the union of both lineage shapes" errors="none — ADD COLUMN IF NOT EXISTS is idempotent" side_effects="Trigger engine, pipeline runner, system cron, API-key auth, and admin-data PATCH can read/write the columns they expect"]
6
+ -- CIL[DOC-MICRO logic_summary="Dev databases were built by archive migrations whose rich table shapes (event_type/pipeline_id on triggers, timer_type/next_execution on timers, stages on pipelines, key_value on api_keys, etc.) were dropped when 001 re-created tables in the generic registry shape. Runtime code reads these columns directly, so fresh installs could not fire triggers, run pipelines, or auth machine principals. Column types are copied verbatim from a live dev information_schema dump" notable_decisions="integration_routes deliberately excluded — 004 drops it as dead schema; NOT NULL clauses preserved from dev types, safe because these tables are empty on fresh installs"]
7
+ -- CIL[DOC-CONFIDENCE pass="first" score="0.9" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+
10
+ -- triggers: columns the trigger engine reads/writes
11
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS trigger_type text NOT NULL;
12
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS event_type text;
13
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS pipeline_id uuid;
14
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
15
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS trigger_count integer DEFAULT 0;
16
+ ALTER TABLE public.triggers ADD COLUMN IF NOT EXISTS last_triggered timestamp with time zone;
17
+
18
+ -- timers: columns the scheduler/cron path reads/writes
19
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS timer_type text NOT NULL;
20
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS pipeline_id uuid;
21
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
22
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS last_execution timestamp with time zone;
23
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS next_execution timestamp with time zone;
24
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS execution_count integer DEFAULT 0;
25
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS success_count integer DEFAULT 0;
26
+ ALTER TABLE public.timers ADD COLUMN IF NOT EXISTS failure_count integer DEFAULT 0;
27
+
28
+ -- pipelines: columns the pipeline runner reads
29
+ ALTER TABLE public.pipelines ADD COLUMN IF NOT EXISTS trigger_type text;
30
+ ALTER TABLE public.pipelines ADD COLUMN IF NOT EXISTS stages jsonb DEFAULT '[]';
31
+ ALTER TABLE public.pipelines ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
32
+
33
+ -- trigger_executions / pipeline_executions: execution record fields
34
+ ALTER TABLE public.trigger_executions ADD COLUMN IF NOT EXISTS triggered_at timestamp with time zone DEFAULT now();
35
+ ALTER TABLE public.trigger_executions ADD COLUMN IF NOT EXISTS trigger_data jsonb DEFAULT '{}';
36
+ ALTER TABLE public.trigger_executions ADD COLUMN IF NOT EXISTS result jsonb DEFAULT '{}';
37
+ ALTER TABLE public.trigger_executions ADD COLUMN IF NOT EXISTS duration_ms integer;
38
+
39
+ ALTER TABLE public.pipeline_executions ADD COLUMN IF NOT EXISTS trigger_data jsonb DEFAULT '{}';
40
+ ALTER TABLE public.pipeline_executions ADD COLUMN IF NOT EXISTS result jsonb DEFAULT '{}';
41
+ ALTER TABLE public.pipeline_executions ADD COLUMN IF NOT EXISTS duration_ms integer;
42
+
43
+ -- api_keys: machine-principal credential
44
+ ALTER TABLE public.api_keys ADD COLUMN IF NOT EXISTS key_value text;
45
+
46
+ -- item_progress: runtime record columns
47
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS person_id uuid NOT NULL;
48
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS title text;
49
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS status text DEFAULT 'not_started' NOT NULL;
50
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS score integer;
51
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS data jsonb DEFAULT '{}' NOT NULL;
52
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS design_schema jsonb DEFAULT '{}' NOT NULL;
53
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS validation_schema jsonb DEFAULT '{}' NOT NULL;
54
+ ALTER TABLE public.item_progress ADD COLUMN IF NOT EXISTS updated_by uuid;
55
+
56
+ -- logs: source attribution
57
+ ALTER TABLE public.logs ADD COLUMN IF NOT EXISTS source text;
58
+ ALTER TABLE public.logs ADD COLUMN IF NOT EXISTS source_type text;
59
+ ALTER TABLE public.logs ADD COLUMN IF NOT EXISTS source_id uuid;
60
+ ALTER TABLE public.logs ADD COLUMN IF NOT EXISTS person_id uuid;
61
+
62
+ -- messages: same updated_by gap 047 fixed for people/watchers/attachments
63
+ ALTER TABLE public.messages ADD COLUMN IF NOT EXISTS updated_by uuid;
64
+ -- CIL[DOC-VECTOR type="context" content="purpose='Add archive-era columns missing from the live generic registry shape across nine runtime tables.'; No verified external callers; imports: none"]
65
+ -- CIL[DOC-VECTOR type="blast_radius" content="Trigger engine, pipeline runner, scheduler, API-key auth, item progress, logging, and message updates work on fresh installs; dev lineage is a no-op" status="ready"]
66
+ -- CIL[DOC-VECTOR type="constraint" content="Column types copied verbatim from dev information_schema — dev lineage keeps its NOT NULL constraints, fresh installs add identical definitions" status="ready"]
67
+ -- CIL[END stable_id="~/.framework/migrations/020_schema_reconciliation.sql:schema_reconciliation:file"]
@@ -0,0 +1,31 @@
1
+ -- ============================================================================
2
+ -- 021: KB embedding lifecycle RPC
3
+ -- ----------------------------------------------------------------------------
4
+ -- kbRevoke (functions/_shared/kb.ts) calls revoke_embeddings_for_item during
5
+ -- KB ingest/unpublish. The function existed in the dev database (created by the
6
+ -- archived embedding-lifecycle migration) but was never present in the live
7
+ -- chain, so fresh installs failed with "function not found in schema cache".
8
+ -- Definition copied verbatim from the working dev database.
9
+ -- ============================================================================
10
+
11
+ CREATE OR REPLACE FUNCTION public.revoke_embeddings_for_item(p_item_id uuid)
12
+ RETURNS integer
13
+ LANGUAGE plpgsql
14
+ SECURITY DEFINER
15
+ SET search_path TO 'public'
16
+ AS $function$
17
+ DECLARE
18
+ v_count integer;
19
+ BEGIN
20
+ UPDATE public.embeddings
21
+ SET revoked_at = now()
22
+ WHERE document_id = p_item_id::text
23
+ AND revoked_at IS NULL;
24
+
25
+ GET DIAGNOSTICS v_count = ROW_COUNT;
26
+ RETURN v_count;
27
+ END;
28
+ $function$;
29
+
30
+ GRANT EXECUTE ON FUNCTION public.revoke_embeddings_for_item(uuid)
31
+ TO service_role;
@@ -0,0 +1,73 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/032_cil_status_migration.sql:cil_status_migration:file" type="file" identity="cil_status_migration" parent="~/.framework/migrations/032_cil_status_migration.sql"]
2
+ -- CIL[DOC-MACRO purpose="One-time SQL migration: collapse legacy CIL file_statuses into the canonical 0-8 model."]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Remap legacy status aliases in items.data->file_statuses to canonical statuses."]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/migrations/032_cil_status_migration.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="items table rows with kb_type='cil_project' and active file_statuses JSONB" outputs="Updated items.data.file_statuses with canonical 0-8 statuses" errors="May leave unmapped statuses as 0-discovered; only affects active CIL project rows" side_effects="Updates items.data and sets updated_at to now()"]
6
+ -- CIL[DOC-MICRO logic_summary="Builds a CTE mapping each file_statuses key to canonical status, then updates items rows in place." notable_decisions="[]"]
7
+ -- CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+
10
+ -- 032_cil_status_migration.sql
11
+ -- One-time migration: collapse legacy CIL file_statuses into the canonical 0–8 model.
12
+ -- This removes the need for the code to carry legacy status aliases.
13
+
14
+ WITH mapped_statuses AS (
15
+ SELECT
16
+ i.id,
17
+ jsonb_object_agg(
18
+ kv.key,
19
+ CASE kv.value
20
+ WHEN '0-discovered' THEN '0-discovered'
21
+ WHEN '1-selected' THEN '1-selected'
22
+ WHEN '2-chunked' THEN '2-chunked'
23
+ WHEN '3-documented' THEN '3-documented'
24
+ WHEN '4-chunk-validated' THEN '4-chunk-validated'
25
+ WHEN '5-doc-validated' THEN '5-doc-validated'
26
+ WHEN '6-enriched' THEN '6-enriched'
27
+ WHEN '7-embedded-mapped' THEN '7-embedded-mapped'
28
+ WHEN '8-published' THEN '8-published'
29
+ -- Legacy aliases
30
+ WHEN '2-discovered' THEN '0-discovered'
31
+ WHEN '3-selected' THEN '1-selected'
32
+ WHEN '4-chunked' THEN '2-chunked'
33
+ WHEN '5-documented' THEN '3-documented'
34
+ WHEN '4-embedded' THEN '7-embedded-mapped'
35
+ WHEN '5-mapped' THEN '7-embedded-mapped'
36
+ WHEN '6-embedded' THEN '7-embedded-mapped'
37
+ WHEN '7-mapped' THEN '7-embedded-mapped'
38
+ WHEN '7-embedded' THEN '7-embedded-mapped'
39
+ WHEN '7-embedded-2' THEN '7-embedded-mapped'
40
+ WHEN '7.5-selected' THEN '1-selected'
41
+ WHEN '8-mapped' THEN '7-embedded-mapped'
42
+ WHEN '8-mapped-2' THEN '7-embedded-mapped'
43
+ WHEN '8-enriched' THEN '6-enriched'
44
+ WHEN '9-embedded' THEN '7-embedded-mapped'
45
+ WHEN '10-mapped' THEN '7-embedded-mapped'
46
+ -- Anything else (e.g. stale timestamps or _updated entries) becomes discovered
47
+ ELSE '0-discovered'
48
+ END
49
+ ) AS new_file_statuses
50
+ FROM items i
51
+ JOIN jsonb_each_text(i.data -> 'file_statuses') kv
52
+ ON kv.key NOT LIKE '%\\_updated'
53
+ WHERE i.data ->> 'kb_type' = 'cil_project'
54
+ AND i.is_active = true
55
+ GROUP BY i.id
56
+ )
57
+ UPDATE items
58
+ SET data = jsonb_set(
59
+ items.data,
60
+ '{file_statuses}',
61
+ mapped_statuses.new_file_statuses,
62
+ true
63
+ ),
64
+ updated_at = now()
65
+ FROM mapped_statuses
66
+ WHERE items.id = mapped_statuses.id;
67
+ -- CIL[DOC-VECTOR type="context" content="purpose='One-time SQL migration: collapse legacy CIL file_statuses into the canonical 0-8 model.'; No verified external callers; imports: none"]
68
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
69
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
70
+ -- CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
71
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
72
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
73
+ -- CIL[END stable_id="~/.framework/migrations/032_cil_status_migration.sql:cil_status_migration:file"]
@@ -0,0 +1,73 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/033_cil_versioning.sql:cil_versioning:file" type="file" identity="cil_versioning" parent="~/.framework/migrations/033_cil_versioning.sql"]
2
+ -- CIL[DOC-MACRO purpose="Add manifest, diff, and customer/version packaging fields to CIL versioning schema"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Applies design_schema metadata updates for cil_version, cil_project, cil_file, and cil_chunk types"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/migrations/033_cil_versioning.sql"]
5
+ -- CIL[DOC-CONTRACT inputs="spine-core app slug; existing public.types rows for cil_version, cil_project, cil_file, cil_chunk" outputs="updated design_schema with new fields" errors="app not found; type not found or missing design_schema fields" side_effects="modifies public.types.design_schema in place"]
6
+ -- CIL[DOC-MICRO logic_summary="Lookup the spine-core app id, then use jsonb_set to append new json/text/boolean fields to each target type's design_schema fields" notable_decisions="[]"]
7
+ -- CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+ -- CIL versioning schema: add manifest, diff, and customer/version packaging fields to existing CIL types.
10
+ -- This migration only updates design_schema metadata; runtime data is stored in items.data as jsonb.
11
+ DO $$
12
+ DECLARE
13
+ v_spine_core_app_id uuid;
14
+ BEGIN
15
+ SELECT id INTO v_spine_core_app_id FROM public.apps WHERE slug = 'spine-core' LIMIT 1;
16
+
17
+ -- Extend cil_version with manifest, diff, and packaging fields
18
+ UPDATE public.types
19
+ SET design_schema = jsonb_set(
20
+ design_schema,
21
+ '{fields}'::text[],
22
+ (design_schema->'fields') || '{
23
+ "manifest": {"data_type": "json", "label": "Version Manifest", "required": false},
24
+ "diff": {"data_type": "json", "label": "Version Diff", "required": false},
25
+ "parent_version_id": {"data_type": "text", "label": "Parent Version ID", "required": false},
26
+ "npm_name": {"data_type": "text", "label": "NPM Package Name", "required": false},
27
+ "npm_version": {"data_type": "text", "label": "NPM Version", "required": false},
28
+ "is_customer": {"data_type": "boolean", "label": "Is Customer Version", "required": false},
29
+ "base_spine_version_id": {"data_type": "text", "label": "Base Spine Version ID", "required": false},
30
+ "spine_source_version_id": {"data_type": "text", "label": "Spine Source Version ID", "required": false}
31
+ }'::jsonb
32
+ )
33
+ WHERE kind = 'item' AND slug = 'cil_version' AND app_id = v_spine_core_app_id;
34
+
35
+ -- Extend cil_project with customer versioning fields
36
+ UPDATE public.types
37
+ SET design_schema = jsonb_set(
38
+ design_schema,
39
+ '{fields}'::text[],
40
+ (design_schema->'fields') || '{
41
+ "installed_spine_version_id": {"data_type": "text", "label": "Installed Spine Version ID", "required": false},
42
+ "target_spine_version_id": {"data_type": "text", "label": "Target Spine Version ID", "required": false},
43
+ "customer_version_id": {"data_type": "text", "label": "Customer Version ID", "required": false},
44
+ "customer_npm_name": {"data_type": "text", "label": "Customer NPM Name", "required": false},
45
+ "customized_paths": {"data_type": "json", "label": "Customized Paths", "required": false},
46
+ "pending_merges": {"data_type": "json", "label": "Pending Merges", "required": false}
47
+ }'::jsonb
48
+ )
49
+ WHERE kind = 'item' AND slug = 'cil_project' AND app_id = v_spine_core_app_id;
50
+
51
+ -- Extend cil_file and cil_chunk with spine/customer version tracking fields
52
+ UPDATE public.types
53
+ SET design_schema = jsonb_set(
54
+ design_schema,
55
+ '{fields}'::text[],
56
+ (design_schema->'fields') || '{
57
+ "spine_version_id": {"data_type": "text", "label": "Spine Version ID", "required": false},
58
+ "customer_version_id": {"data_type": "text", "label": "Customer Version ID", "required": false},
59
+ "customized": {"data_type": "boolean", "label": "Customized", "required": false},
60
+ "pending_spine_version_id": {"data_type": "text", "label": "Pending Spine Version ID", "required": false},
61
+ "pending_spine_source_id": {"data_type": "text", "label": "Pending Spine Source ID", "required": false}
62
+ }'::jsonb
63
+ )
64
+ WHERE kind = 'item' AND slug IN ('cil_file', 'cil_chunk') AND app_id = v_spine_core_app_id;
65
+
66
+ END $$;
67
+ -- CIL[DOC-VECTOR type="context" content="purpose='Add manifest, diff, and customer/version packaging fields to CIL versioning schema'; No verified external callers; imports: none"]
68
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
69
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
70
+ -- CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
71
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
72
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
73
+ -- CIL[END stable_id="~/.framework/migrations/033_cil_versioning.sql:cil_versioning:file"]
@@ -0,0 +1,115 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/034_match_embeddings_knn.sql:match_embeddings_knn:file" type="file" identity="match_embeddings_knn" parent="~/.framework/migrations/034_match_embeddings_knn.sql"]
2
+ -- CIL[DOC-MACRO purpose="Rework match_embeddings to use KNN-first oversampling and a higher statement timeout"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Replace the match_embeddings RPC so filtered semantic search uses the HNSW index instead of a filtered btree scan + heapsort"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="database" related_files=".framework/migrations/005_core_observability.sql,.framework/functions/_shared/agent-runner.ts"]
5
+ -- CIL[DOC-CONTRACT inputs="existing public.match_embeddings function and embeddings table" outputs="replaced function with same signature and result shape" errors="requires pgvector >= 0.8 for hnsw.iterative_scan" side_effects="drops the superseded 5-arg overload; raises the function statement_timeout to 25s"]
6
+ -- CIL[DOC-MICRO logic_summary="When filter_document_ids is set, keep the filter-first query (document-targeted lookup). Otherwise oversample the HNSW KNN index (match_count*10, min 100) with hnsw.iterative_scan=strict_order, then apply account/vector_type/item_type/similarity filters outside the subquery" notable_decisions="Filters moved outside the ORDER BY subquery because the planner mis-estimates account_id selectivity (rows=23 vs ~3k actual) and picks embeddings_active_idx, scanning+sorting every matching row and intermittently exceeding the 8s PostgREST statement_timeout"]
7
+ -- CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ -- CIL[DOC-STABILITY stability="stable"]
9
+ -- CIL[DOC-LEARNING topic="filtered_knn" content="On Postgres + pgvector, putting a selective filter (account_id) in the same query as ORDER BY embedding <=> q lets the planner pick a btree + heapsort over the HNSW index; isolate the KNN ORDER BY/LIMIT in a subquery it cannot flatten, then post-filter. hnsw.iterative_scan=strict_order (pgvector 0.8) is required or the scan stops at ef_search (40) rows"]
10
+ -- CIL[DOC-VECTOR type="context" content="purpose='Rework match_embeddings to use KNN-first oversampling and a higher statement timeout'; no verified external callers; imports: none"]
11
+ -- CIL[DOC-VECTOR type="blast_radius" content="Affects all callers of the match_embeddings RPC: agent-runner retrieveKnowledge, kb.ts, cil-embeddings, embeddings.ts, eval-harness, custom_kb-embeddings"]
12
+ -- CIL[DOC-VECTOR type="configuration" content="Requires pgvector 0.8+; function statement_timeout set to 25s (under the 30s lambda cap)"]
13
+ -- CIL[DOC-VECTOR type="constraint" content="Result shape and parameter signature unchanged; empty filter_document_ids array returns no rows as before"]
14
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
15
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
16
+
17
+ -- match_embeddings was intermittently exceeding the 8s statement_timeout on
18
+ -- PostgREST roles: the planner mis-estimates the account_id filter
19
+ -- (rows=23 vs ~3k actual) and picks embeddings_active_idx, scanning and
20
+ -- sorting every matching row. Restructure so the KNN scan runs through the
21
+ -- HNSW index first (oversampled), with filters applied to the candidates.
22
+
23
+ DROP FUNCTION IF EXISTS public.match_embeddings(vector, integer, uuid[], text, double precision);
24
+ DROP FUNCTION IF EXISTS public.match_embeddings(vector, integer, uuid[], text, real);
25
+
26
+ CREATE OR REPLACE FUNCTION public.match_embeddings(
27
+ query_embedding vector(1536),
28
+ match_count int DEFAULT 10,
29
+ filter_account_ids uuid[] DEFAULT NULL,
30
+ filter_vector_type text DEFAULT NULL,
31
+ similarity_threshold float DEFAULT 0.15,
32
+ filter_item_types text[] DEFAULT NULL,
33
+ filter_document_ids text[] DEFAULT NULL
34
+ )
35
+ RETURNS TABLE (
36
+ id uuid,
37
+ document_id text,
38
+ content text,
39
+ metadata jsonb,
40
+ account_id uuid,
41
+ similarity float
42
+ )
43
+ LANGUAGE plpgsql
44
+ SECURITY DEFINER
45
+ SET search_path = public
46
+ SET statement_timeout = '25s'
47
+ AS $$
48
+ BEGIN
49
+ -- Document-targeted lookups stay filter-first: a global KNN oversample
50
+ -- would crowd out the requested documents before they can be scored.
51
+ IF filter_document_ids IS NOT NULL THEN
52
+ RETURN QUERY
53
+ SELECT
54
+ e.id,
55
+ e.document_id,
56
+ e.content,
57
+ e.metadata,
58
+ e.account_id,
59
+ 1 - (e.embedding <=> query_embedding) AS similarity
60
+ FROM public.embeddings e
61
+ WHERE
62
+ (filter_account_ids IS NULL OR e.account_id = ANY(filter_account_ids))
63
+ AND (filter_vector_type IS NULL OR e.metadata->>'vector_type' = filter_vector_type)
64
+ AND (filter_item_types IS NULL OR e.metadata->>'item_type' = ANY(filter_item_types))
65
+ AND e.document_id = ANY(filter_document_ids)
66
+ AND e.approved_at IS NOT NULL
67
+ AND e.revoked_at IS NULL
68
+ AND (1 - (e.embedding <=> query_embedding)) >= similarity_threshold
69
+ ORDER BY e.embedding <=> query_embedding
70
+ LIMIT match_count;
71
+ RETURN;
72
+ END IF;
73
+
74
+ -- KNN-first: oversample the HNSW index, then apply filters. Keeping the
75
+ -- filters out of the ORDER BY subquery stops the planner choosing the
76
+ -- account btree; strict_order lets the scan iterate past ef_search.
77
+ PERFORM set_config('hnsw.iterative_scan', 'strict_order', true);
78
+ RETURN QUERY
79
+ SELECT
80
+ t.id,
81
+ t.document_id,
82
+ t.content,
83
+ t.metadata,
84
+ t.account_id,
85
+ t.similarity
86
+ FROM (
87
+ SELECT
88
+ e.id,
89
+ e.document_id,
90
+ e.content,
91
+ e.metadata,
92
+ e.account_id,
93
+ e.approved_at,
94
+ e.revoked_at,
95
+ 1 - (e.embedding <=> query_embedding) AS similarity
96
+ FROM public.embeddings e
97
+ ORDER BY e.embedding <=> query_embedding
98
+ LIMIT GREATEST(match_count * 10, 100)
99
+ ) t
100
+ WHERE
101
+ (filter_account_ids IS NULL OR t.account_id = ANY(filter_account_ids))
102
+ AND (filter_vector_type IS NULL OR t.metadata->>'vector_type' = filter_vector_type)
103
+ AND (filter_item_types IS NULL OR t.metadata->>'item_type' = ANY(filter_item_types))
104
+ AND t.approved_at IS NOT NULL
105
+ AND t.revoked_at IS NULL
106
+ AND t.similarity >= similarity_threshold
107
+ ORDER BY t.similarity DESC
108
+ LIMIT match_count;
109
+ END
110
+ $$;
111
+
112
+ GRANT EXECUTE ON FUNCTION public.match_embeddings(
113
+ vector(1536), int, uuid[], text, float, text[], text[]
114
+ ) TO authenticated, service_role;
115
+ -- CIL[END stable_id="~/.framework/migrations/034_match_embeddings_knn.sql:match_embeddings_knn:file"]