spine-framework 0.3.145 → 0.4.1

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 +5067 -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,55 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/035_rate_limits.sql:rate_limits:file" type="file" identity="rate_limits" parent="~/.framework/migrations/035_rate_limits.sql"]
2
+ -- CIL[DOC-MACRO purpose="DB-backed fixed-window rate limiting primitives"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Provide a rate_limits counter table and an atomic rate_limit_hit RPC used by _shared/rate-limit.ts"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/functions/_shared/rate-limit.ts"]
5
+ -- CIL[DOC-CONTRACT inputs="none" outputs="public.rate_limits table, public.rate_limit_hit function" errors="none" side_effects="Creates table, index, grants"]
6
+ -- CIL[DOC-MICRO logic_summary="Create rate_limits(key, window_start, count) with composite PK; rate_limit_hit upserts and increments the counter atomically inside one statement" notable_decisions="Atomic increment via INSERT ON CONFLICT so concurrent serverless invocations cannot double-spend a window"]
7
+ -- CIL[DOC-STABILITY stability="stable"]
8
+
9
+ -- Rate-limit counters are infrastructure state, not domain records — a plain
10
+ -- table, service-role only. Never readable by tenant principals.
11
+ CREATE TABLE IF NOT EXISTS public.rate_limits (
12
+ key text NOT NULL,
13
+ window_start timestamptz NOT NULL,
14
+ count integer NOT NULL DEFAULT 0,
15
+ updated_at timestamptz NOT NULL DEFAULT now(),
16
+ PRIMARY KEY (key, window_start)
17
+ );
18
+
19
+ ALTER TABLE public.rate_limits ENABLE ROW LEVEL SECURITY;
20
+
21
+ -- No policies: tenant principals get no access. All access is via the
22
+ -- SECURITY DEFINER function below or the service role.
23
+
24
+ -- Atomic hit: inserts or increments the counter for (key, window_start) and
25
+ -- returns the new count. One round-trip, safe under concurrency.
26
+ CREATE OR REPLACE FUNCTION public.rate_limit_hit(p_key text, p_window_start timestamptz)
27
+ RETURNS integer
28
+ LANGUAGE plpgsql
29
+ SECURITY DEFINER
30
+ SET search_path = public
31
+ AS $$
32
+ DECLARE
33
+ v_count integer;
34
+ BEGIN
35
+ INSERT INTO public.rate_limits (key, window_start, count)
36
+ VALUES (p_key, p_window_start, 1)
37
+ ON CONFLICT (key, window_start)
38
+ DO UPDATE SET count = public.rate_limits.count + 1,
39
+ updated_at = now()
40
+ RETURNING count INTO v_count;
41
+ RETURN v_count;
42
+ END;
43
+ $$;
44
+
45
+ REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM PUBLIC;
46
+ REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM anon;
47
+ REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM authenticated;
48
+ GRANT EXECUTE ON FUNCTION public.rate_limit_hit(text, timestamptz) TO service_role;
49
+ -- CIL[DOC-VECTOR type="context" content="purpose='DB-backed fixed-window rate limiting primitives'; No verified external callers; imports: none"]
50
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
51
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
52
+ -- CIL[DOC-VECTOR type="constraint" content="Table is RLS-enabled with no tenant policies; only the SECURITY DEFINER RPC or service role may touch it"]
53
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
54
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
55
+ -- CIL[END stable_id="~/.framework/migrations/035_rate_limits.sql:rate_limits:file"]
@@ -0,0 +1,72 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/036_demo_record_flags.sql:demo_record_flags:file" type="file" identity="demo_record_flags" parent="~/.framework/migrations/036_demo_record_flags.sql"]
2
+ -- CIL[DOC-MACRO purpose="Auto-stamp data.is_demo / data.demo_run_id on runtime records created under demo accounts"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Provide apply_demo_flag() trigger function and attach it to runtime tables so every write path (admin-data, adminDb, seeds) flags demo-owned records"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/functions/_shared/funnel.ts,.framework/functions/admin-data.ts"]
5
+ -- CIL[DOC-CONTRACT inputs="accounts.data.is_demo + accounts.data.demo_run_id on the row's account" outputs="NEW.data with reserved keys is_demo/demo_run_id set or stripped" errors="none — missing account defaults to non-demo" side_effects="Mutates NEW.data on INSERT/UPDATE"]
6
+ -- CIL[DOC-MICRO logic_summary="BEFORE INSERT OR UPDATE: look up NEW.account_id's account flag; demo accounts get is_demo=true + demo_run_id merged into data, non-demo accounts get the reserved keys stripped so clients cannot forge them" notable_decisions="DB trigger chosen over admin-data stamping so agent-runner/support-triage adminDb writes are flagged identically; strip on non-demo makes the flag unforgeable"]
7
+ -- CIL[DOC-STABILITY stability="stable"]
8
+
9
+ CREATE OR REPLACE FUNCTION public.apply_demo_flag()
10
+ RETURNS trigger
11
+ LANGUAGE plpgsql
12
+ SECURITY DEFINER
13
+ SET search_path = public
14
+ AS $$
15
+ DECLARE
16
+ v_is_demo boolean;
17
+ v_run_id text;
18
+ BEGIN
19
+ -- accounts has no account_id; nothing to derive from.
20
+ IF NEW.account_id IS NULL THEN
21
+ RETURN NEW;
22
+ END IF;
23
+
24
+ SELECT (a.data->>'is_demo')::boolean, a.data->>'demo_run_id'
25
+ INTO v_is_demo, v_run_id
26
+ FROM public.accounts a
27
+ WHERE a.id = NEW.account_id;
28
+
29
+ IF COALESCE(v_is_demo, false) THEN
30
+ NEW.data := COALESCE(NEW.data, '{}'::jsonb)
31
+ || jsonb_build_object('is_demo', true);
32
+ IF v_run_id IS NOT NULL THEN
33
+ NEW.data := NEW.data || jsonb_build_object('demo_run_id', v_run_id);
34
+ END IF;
35
+ ELSE
36
+ -- Reserved keys are server-owned; strip any client-supplied values.
37
+ NEW.data := COALESCE(NEW.data, '{}'::jsonb) - 'is_demo' - 'demo_run_id';
38
+ END IF;
39
+
40
+ RETURN NEW;
41
+ END;
42
+ $$;
43
+
44
+ -- Attach to every runtime entity that carries an account_id + data payload.
45
+ DO $$
46
+ DECLARE
47
+ t text;
48
+ BEGIN
49
+ FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
50
+ LOOP
51
+ EXECUTE format('DROP TRIGGER IF EXISTS trg_demo_flag ON public.%I', t);
52
+ EXECUTE format(
53
+ 'CREATE TRIGGER trg_demo_flag BEFORE INSERT OR UPDATE ON public.%I FOR EACH ROW EXECUTE FUNCTION public.apply_demo_flag()',
54
+ t
55
+ );
56
+ END LOOP;
57
+ END $$;
58
+
59
+ -- Backfill: flag existing rows belonging to demo accounts that predate the trigger.
60
+ UPDATE public.items i
61
+ SET data = i.data || jsonb_build_object('is_demo', true)
62
+ FROM public.accounts a
63
+ WHERE i.account_id = a.id
64
+ AND (a.data->>'is_demo')::boolean IS TRUE
65
+ AND COALESCE(i.data->>'is_demo', 'false') <> 'true';
66
+ -- CIL[DOC-VECTOR type="context" content="purpose='Auto-stamp data.is_demo / data.demo_run_id on runtime records created under demo accounts'; No verified external callers; imports: none"]
67
+ -- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
68
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
69
+ -- CIL[DOC-VECTOR type="constraint" content="Reserved keys is_demo/demo_run_id are server-owned on all runtime tables; clients cannot set or clear them"]
70
+ -- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
71
+ -- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
72
+ -- CIL[END stable_id="~/.framework/migrations/036_demo_record_flags.sql:demo_record_flags:file"]
@@ -0,0 +1,244 @@
1
+ -- 037_kb_types_canonical.sql
2
+ -- Canonical knowledge-base item types. kb-account and kb-spine-public were
3
+ -- previously created only by the archived 046_kb_types.sql consolidation, so
4
+ -- fresh installs never received them even though 007_kb_article_list.sql
5
+ -- references both slugs. This migration:
6
+ -- 1. Inserts the types when missing (idempotent).
7
+ -- 2. Merges demo-flag fields (is_demo, demo_run_id) and the member_admin
8
+ -- grant into existing design_schema rows without clobbering them.
9
+ -- 3. Adds source_ticket_id to kb-account for ticket→article candidate links.
10
+
11
+ -- ─── INSERT: kb-account (fresh installs) ────────────────────────────────────
12
+
13
+ INSERT INTO public.types (app_id, kind, slug, name, description, icon, color, design_schema, validation_schema, ownership, is_active)
14
+ VALUES (
15
+ NULL,
16
+ 'item',
17
+ 'kb-account',
18
+ 'KB Account',
19
+ 'Account-specific knowledge base articles',
20
+ 'briefcase',
21
+ '#3B82F6',
22
+ $DS$
23
+ {
24
+ "scope": "account",
25
+ "fields": {
26
+ "title": { "data_type": "text", "label": "Title", "required": true, "system": true },
27
+ "description": { "data_type": "textarea", "label": "Description", "required": false, "system": true },
28
+ "status": { "data_type": "select", "label": "Status", "required": true, "system": true, "options": ["draft", "published", "archived"] },
29
+ "content": { "data_type": "textarea", "label": "Content", "required": true },
30
+ "tags": { "data_type": "multiselect", "label": "Tags", "required": false, "options": ["support", "how-to", "faq", "tutorial"] },
31
+ "category": { "data_type": "multiselect", "label": "Category", "required": false, "options": ["how-to", "runbook", "policy", "faq", "tutorial"] },
32
+ "product": { "data_type": "multiselect", "label": "Product", "required": false, "options": ["spine-framework", "cortex", "workbench", "portal"] },
33
+ "version": { "data_type": "text", "label": "Version", "required": false },
34
+ "last_reviewed_at": { "data_type": "datetime", "label": "Last Reviewed", "required": false },
35
+ "reviewer_id": { "data_type": "text", "label": "Reviewer ID", "required": false },
36
+ "is_ai_generated": { "data_type": "boolean", "label": "AI Generated", "required": false },
37
+ "customer_segment": { "data_type": "multiselect", "label": "Customer Segment", "required": false, "options": ["enterprise", "startup", "all"] },
38
+ "feature_flag": { "data_type": "text", "label": "Feature Flag", "required": false },
39
+ "work_ticket_id": { "data_type": "text", "label": "Work Ticket ID", "required": false },
40
+ "source_ticket_id": { "data_type": "text", "label": "Source Ticket ID", "required": false },
41
+ "source_file": { "data_type": "text", "label": "Source File Path", "required": false },
42
+ "source_function": { "data_type": "text", "label": "Source Function", "required": false },
43
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
44
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
45
+ },
46
+ "views": {
47
+ "default_list": {
48
+ "type": "list",
49
+ "display": "table",
50
+ "label": "Account Articles",
51
+ "fields": {
52
+ "title": { "sortable": true, "display_type": "text" },
53
+ "status": { "sortable": true, "display_type": "badge" },
54
+ "product": { "sortable": true, "display_type": "text" },
55
+ "created_at": { "sortable": true, "display_type": "timestamp" }
56
+ },
57
+ "default_sort": { "field": "created_at", "direction": "desc" }
58
+ },
59
+ "default_detail": {
60
+ "type": "detail",
61
+ "label": "Article",
62
+ "sections": [
63
+ { "title": "Core", "fields": { "title": { "display_type": "input" }, "status": { "display_type": "select" }, "description": { "display_type": "textarea" }, "content": { "display_type": "textarea" } } },
64
+ { "title": "Categorization", "fields": { "tags": { "display_type": "multiselect" }, "category": { "display_type": "multiselect" }, "product": { "display_type": "multiselect" }, "version": { "display_type": "text" } } },
65
+ { "title": "Review", "fields": { "last_reviewed_at": { "display_type": "timestamp" }, "reviewer_id": { "display_type": "text" }, "is_ai_generated": { "display_type": "checkbox" } } },
66
+ { "title": "Context", "fields": { "work_ticket_id": { "display_type": "text" }, "source_ticket_id": { "display_type": "text" }, "source_file": { "display_type": "text" }, "source_function": { "display_type": "text" } } }
67
+ ]
68
+ }
69
+ },
70
+ "record_permissions": {
71
+ "system_admin": ["create", "read", "update", "delete"],
72
+ "support": ["create", "read", "update"],
73
+ "support_admin": ["create", "read", "update", "delete"],
74
+ "engineering_admin": ["create", "read", "update"],
75
+ "engineering": ["create", "read", "update"],
76
+ "devops": ["create", "read", "update"],
77
+ "incident_commander": ["create", "read", "update"],
78
+ "member": ["create", "read", "update"],
79
+ "member_admin": ["create", "read", "update", "delete"]
80
+ },
81
+ "functionality": {
82
+ "kb": {
83
+ "vector_fields": ["title", "description", "content", "tags"],
84
+ "chunk_field": "content",
85
+ "chunk_size": 800,
86
+ "chunk_overlap": 100
87
+ }
88
+ }
89
+ }
90
+ $DS$::jsonb,
91
+ '{}'::jsonb,
92
+ 'system',
93
+ true
94
+ )
95
+ ON CONFLICT (kind, slug) DO NOTHING;
96
+
97
+ -- ─── INSERT: kb-spine-public (fresh installs) ───────────────────────────────
98
+ -- Minimal canonical definition; deployed databases already carry the full
99
+ -- schema from 046 and take the UPDATE path below instead.
100
+
101
+ INSERT INTO public.types (app_id, kind, slug, name, description, icon, color, design_schema, validation_schema, ownership, is_active)
102
+ VALUES (
103
+ NULL,
104
+ 'item',
105
+ 'kb-spine-public',
106
+ 'Spine KB Public',
107
+ 'Public Spine knowledge base articles readable by all accounts',
108
+ 'book-open',
109
+ '#10B981',
110
+ $DS$
111
+ {
112
+ "scope": "platform",
113
+ "fields": {
114
+ "title": { "data_type": "text", "label": "Title", "required": true, "system": true },
115
+ "description": { "data_type": "textarea", "label": "Description", "required": false, "system": true },
116
+ "status": { "data_type": "select", "label": "Status", "required": true, "system": true, "options": ["draft", "published", "archived"] },
117
+ "content": { "data_type": "textarea", "label": "Content", "required": true },
118
+ "tags": { "data_type": "multiselect", "label": "Tags", "required": false, "options": ["support", "how-to", "faq", "tutorial"] },
119
+ "category": { "data_type": "multiselect", "label": "Category", "required": false, "options": ["how-to", "runbook", "policy", "faq", "tutorial"] },
120
+ "product": { "data_type": "multiselect", "label": "Product", "required": false, "options": ["spine-framework", "cortex", "workbench", "portal"] },
121
+ "version": { "data_type": "text", "label": "Version", "required": false },
122
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
123
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
124
+ },
125
+ "views": {
126
+ "default_list": {
127
+ "type": "list",
128
+ "display": "table",
129
+ "label": "Public Articles",
130
+ "fields": {
131
+ "title": { "sortable": true, "display_type": "text" },
132
+ "status": { "sortable": true, "display_type": "badge" },
133
+ "created_at": { "sortable": true, "display_type": "timestamp" }
134
+ },
135
+ "default_sort": { "field": "created_at", "direction": "desc" }
136
+ },
137
+ "default_detail": {
138
+ "type": "detail",
139
+ "label": "Article",
140
+ "sections": [
141
+ { "title": "Core", "fields": { "title": { "display_type": "input" }, "status": { "display_type": "select" }, "description": { "display_type": "textarea" }, "content": { "display_type": "textarea" } } }
142
+ ]
143
+ }
144
+ },
145
+ "record_permissions": {
146
+ "system_admin": ["create", "read", "update", "delete"],
147
+ "support": ["create", "read", "update"],
148
+ "support_admin": ["create", "read", "update", "delete"],
149
+ "engineering_admin": ["create", "read", "update"],
150
+ "engineering": ["create", "read", "update"],
151
+ "devops": ["create", "read", "update"],
152
+ "incident_commander": ["create", "read", "update"],
153
+ "member": ["read"],
154
+ "member_admin": ["read"]
155
+ },
156
+ "functionality": {
157
+ "kb": {
158
+ "vector_fields": ["title", "description", "content", "tags"],
159
+ "chunk_field": "content",
160
+ "chunk_size": 800,
161
+ "chunk_overlap": 100
162
+ }
163
+ }
164
+ }
165
+ $DS$::jsonb,
166
+ '{}'::jsonb,
167
+ 'system',
168
+ true
169
+ )
170
+ ON CONFLICT (kind, slug) DO NOTHING;
171
+
172
+ -- ─── UPDATE: converge existing rows ─────────────────────────────────────────
173
+ -- Merge demo-flag + linkage fields and the member_admin grant into existing
174
+ -- design_schema JSON without replacing fields added since 046.
175
+
176
+ UPDATE public.types
177
+ SET design_schema = jsonb_set(
178
+ jsonb_set(
179
+ design_schema,
180
+ '{fields}',
181
+ (design_schema->'fields') || $F${
182
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
183
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false },
184
+ "source_ticket_id": { "data_type": "text", "label": "Source Ticket ID", "required": false }
185
+ }$F$::jsonb,
186
+ true
187
+ ),
188
+ '{record_permissions}',
189
+ (design_schema->'record_permissions') || $P${
190
+ "member_admin": ["create", "read", "update", "delete"],
191
+ "member": ["create", "read", "update"]
192
+ }$P$::jsonb,
193
+ true
194
+ )
195
+ WHERE slug = 'kb-account' AND kind = 'item';
196
+
197
+ UPDATE public.types
198
+ SET design_schema = jsonb_set(
199
+ jsonb_set(
200
+ design_schema,
201
+ '{fields}',
202
+ (design_schema->'fields') || $F${
203
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
204
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
205
+ }$F$::jsonb,
206
+ true
207
+ ),
208
+ '{record_permissions}',
209
+ (design_schema->'record_permissions') || $P${
210
+ "member_admin": ["read"],
211
+ "member": ["read"]
212
+ }$P$::jsonb,
213
+ true
214
+ )
215
+ WHERE slug = 'kb-spine-public' AND kind = 'item';
216
+
217
+ -- Merge the same flag fields into the Portal-owned support types so the demo
218
+ -- flag survives sanitizeRecordData on reads. These UPDATEs are no-ops on
219
+ -- databases where the seed has not installed the slugs yet — the portal seed
220
+ -- types.json now carries the fields for fresh installs.
221
+ UPDATE public.types
222
+ SET design_schema = jsonb_set(
223
+ design_schema,
224
+ '{fields}',
225
+ (design_schema->'fields') || $F${
226
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
227
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
228
+ }$F$::jsonb,
229
+ true
230
+ )
231
+ WHERE (kind, slug) IN (('item', 'support_ticket'), ('thread', 'support_thread'));
232
+
233
+ UPDATE public.types
234
+ SET design_schema = jsonb_set(
235
+ design_schema,
236
+ '{fields}',
237
+ (design_schema->'fields') || $F${
238
+ "is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
239
+ "demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false },
240
+ "escalation_notice": { "data_type": "boolean", "label": "Escalation Notice", "required": false }
241
+ }$F$::jsonb,
242
+ true
243
+ )
244
+ WHERE kind = 'message' AND slug = 'support_reply';
@@ -0,0 +1,38 @@
1
+ -- CIL[BEGIN stable_id="~/.framework/migrations/038_drop_demo_record_flags.sql:drop_demo_record_flags:file" type="file" identity="drop_demo_record_flags" parent="~/.framework/migrations/038_drop_demo_record_flags.sql"]
2
+ -- CIL[DOC-MACRO purpose="Remove record-level is_demo flagging in favor of demo-specific types for content isolation"]
3
+ -- CIL[DOC-RESPONSIBILITY responsibility="Drop trg_demo_flag triggers and apply_demo_flag() (migration 036); strip is_demo/demo_run_id from existing runtime records. Record visibility is now isolated by demo_* types; accounts.data.is_demo remains a lifecycle-only marker (expiry, rate-limit policy, funnel tagging)"]
4
+ -- CIL[DOC-CONTEXT module="migrations" layer="data" related_files="custom/apps/demo/seed/types.json,custom/apps/demo/functions/custom_demo-journey.ts,custom/apps/portal/functions/custom_support-triage.ts"]
5
+ -- CIL[DOC-CONTRACT inputs="trg_demo_flag triggers + apply_demo_flag() from migration 036" outputs="triggers/function dropped; records unflagged" errors="none" side_effects="Runtime records can no longer be marked is_demo; accounts.data.is_demo is managed solely by demo provision"]
6
+ -- CIL[DOC-MICRO logic_summary="Demo content isolation moved to type-based scoping (demo_support_ticket, demo_support_thread). Accounts and people are never demo-flagged — they are real leads for Cortex." notable_decisions="Type isolation chosen over record flags so demo play can run inside shared accounts without hiding real records"]
7
+ -- CIL[DOC-STABILITY stability="stable"]
8
+
9
+ DO $$
10
+ DECLARE
11
+ t text;
12
+ BEGIN
13
+ FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
14
+ LOOP
15
+ EXECUTE format('DROP TRIGGER IF EXISTS trg_demo_flag ON public.%I', t);
16
+ END LOOP;
17
+ END $$;
18
+
19
+ DROP FUNCTION IF EXISTS public.apply_demo_flag();
20
+
21
+ -- Unflag any runtime records that were stamped while the trigger was active.
22
+ DO $$
23
+ DECLARE
24
+ t text;
25
+ BEGIN
26
+ FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
27
+ LOOP
28
+ EXECUTE format(
29
+ 'UPDATE public.%I SET data = data - ''is_demo'' - ''demo_run_id'' WHERE data ? ''is_demo'' OR data ? ''demo_run_id''',
30
+ t
31
+ );
32
+ END LOOP;
33
+ END $$;
34
+ -- CIL[DOC-VECTOR type="context" content="purpose='Remove record-level is_demo flagging in favor of demo-specific types'; No verified external callers; imports: none" status="ready"]
35
+ -- CIL[DOC-VECTOR type="blast_radius" content="admin-data demo_only/exclude_demo params become no-ops; demo visibility now enforced by type_slug scoping" status="ready"]
36
+ -- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
37
+ -- CIL[DOC-VECTOR type="constraint" content="accounts.data.is_demo is still written by demo provision for lifecycle (expiry/rate-limits); it is no longer propagated to records" status="ready"]
38
+ -- CIL[END stable_id="~/.framework/migrations/038_drop_demo_record_flags.sql:drop_demo_record_flags:file"]