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,233 @@
1
+ /**
2
+ * @module functions/_shared
3
+ * @audience internal
4
+ * @layer rate-limit
5
+ * @stability stable
6
+ *
7
+ * Configurable DB-backed rate limiting for sensitive actions
8
+ *
9
+ * @seeAlso .framework/functions/_shared/db.ts (provides database access for rate limits).
10
+ * @seeAlso .framework/functions/_shared/audit.ts (emits security.rate_limit_exceeded audit events).
11
+ * @seeAlso .framework/functions/_shared/middleware.ts (contains context types used in this module).
12
+ *
13
+ * @cil-generated
14
+ */
15
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/rate-limit.ts"]
16
+ // CIL[DOC-MACRO purpose="Configurable DB-backed rate limiting for sensitive actions"]
17
+ // CIL[DOC-RESPONSIBILITY responsibility="Resolve rate-limit policy from accounts.data (override or named profile) falling back to apps.config.rate_limits, and enforce it via the atomic rate_limit_hit RPC"]
18
+ // CIL[DOC-CONTEXT module="functions/_shared" layer="rate-limit" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts,.framework/migrations/035_rate_limits.sql"]
19
+ // CIL[DOC-CONTRACT inputs="ctx, action name, optional identifier override" outputs="void or throws RateLimitError (429)" errors="RateLimitError when over policy; fail-closed policies throw on limiter outage" side_effects="Increments rate_limits counters"]
20
+ // CIL[DOC-MICRO logic_summary="accounts.data.rate_limits[action] wins; accounts.data.rate_limit_profile selects config.rate_limits.profiles[profile][action] before the app's base policy; each policy is a fixed window counter keyed action:identifier; over-limit throws 429 with retry_after" notable_decisions="Policy is data/config, not code — accounts and apps declare limits and Core enforces; window_seconds 0 means lifetime cap; fail_closed reserved for cost-bearing actions like agent_step"]
21
+ // CIL[DOC-STABILITY stability="stable"]
22
+ // CIL[DOC-AUDIENCE audience="internal"]
23
+ // CIL[DOC-VECTOR type="context" content="purpose='Configurable DB-backed rate limiting for sensitive actions'; No verified external callers; imports: .framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
24
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
25
+ // CIL[DOC-VECTOR type="configuration" content="Policies read from accounts.data.rate_limits / accounts.data.rate_limit_profile, falling back to apps.config.rate_limits (incl. named profiles) keyed by action name"]
26
+ // CIL[DOC-VECTOR type="constraint" content="Requires migration 035 (rate_limits table + rate_limit_hit RPC); fail-closed only for cost-bearing actions"]
27
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
28
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
29
+
30
+ import { adminDb } from './db'
31
+ import type { CoreContext, RequestContext } from './middleware'
32
+ import { emitAudit } from './audit'
33
+ // CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:module_header:module_header"]
34
+
35
+ // CIL[DOC-MACRO purpose="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window."]
36
+ // CIL[DOC-RESPONSIBILITY responsibility="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage."]
37
+ // CIL[DOC-CONTEXT module="rate-limit" layer="app-specific" related_files=".framework/functions/_shared/db,.framework/functions/_shared/middleware,.framework/functions/_shared/audit"]
38
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
39
+ // CIL[DOC-MICRO logic_summary="RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage." notable_decisions="none"]
40
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
41
+ // CIL[DOC-STABILITY stability="stable"]
42
+ /**
43
+ * RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window. It is used to enforce limits on the number of allowed actions to prevent abuse and manage resource usage.
44
+ *
45
+ * @sideEffects none
46
+ * @stability stable
47
+ * @cil-generated
48
+ */
49
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimitpolicy:type" type="type" identity="RateLimitPolicy" parent="~/.framework/functions/_shared/rate-limit.ts"]
50
+ // CIL[DOC-MACRO purpose="RateLimitPolicy type"]
51
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the RateLimitPolicy type."]
52
+ // CIL[DOC-CONTEXT module=".framework/functions/_shared/rate-limit.ts" layer="app-specific" related_files=""]
53
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
54
+ // CIL[DOC-MICRO logic_summary="Implements the RateLimitPolicy type." notable_decisions="[]"]
55
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
56
+ // CIL[DOC-STABILITY stability="stable"]
57
+ export type RateLimitPolicy = {
58
+ /** Max hits allowed inside the window. */
59
+ limit: number
60
+ /** Window size in seconds. 0 = lifetime cap (no reset). */
61
+ window_seconds: number
62
+ /** When true, an inability to check the limit denies the action. Use for cost-bearing actions (e.g. agent_step). Default false = fail-open. */
63
+ fail_closed?: boolean
64
+ }
65
+ // CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimitpolicy:type"]
66
+ // CIL[DOC-VECTOR type="context" content="purpose='RateLimitPolicy defines the parameters for controlling the rate of actions within a specified time window.'; No verified external callers" status="ready"]
67
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
68
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
69
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
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
+
73
+ // CIL[DOC-MACRO purpose="Custom error class for handling rate limit violations."]
74
+ // CIL[DOC-RESPONSIBILITY responsibility="RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action. It provides additional context such as the action, limit, and retry duration."]
75
+ // CIL[DOC-CONTEXT module="rate-limit" layer="app-specific" related_files=".framework/functions/_shared/db,.framework/functions/_shared/middleware,.framework/functions/_shared/audit"]
76
+ // CIL[DOC-CONTRACT inputs="action: string (required) — the action that triggered the rate limit.\\nlimit: number (required) — the maximum number of allowed requests.\\nretryAfter: number | null (optional|nullable) — the duration in seconds to wait before retrying." outputs="RateLimitError — an instance of RateLimitError with specific properties set." errors="none" side_effects="none"]
77
+ // CIL[DOC-MICRO logic_summary="Constructs an error message that includes the action for which the rate limit was exceeded." notable_decisions="none"]
78
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
79
+ // CIL[DOC-STABILITY stability="stable"]
80
+ /**
81
+ * RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action. It provides additional context such as the action, limit, and retry duration.
82
+ *
83
+ * @macro Custom error class for handling rate limit violations.
84
+ * @micro Constructs an error message that includes the action for which the rate limit was exceeded.
85
+ * @inputSpec
86
+ * action: string (required) — the action that triggered the rate limit.
87
+ * limit: number (required) — the maximum number of allowed requests.
88
+ * retryAfter: number | null (optional|nullable) — the duration in seconds to wait before retrying.
89
+ * @outputSpec RateLimitError — an instance of RateLimitError with specific properties set.
90
+ * @sideEffects none
91
+ * @stability stable
92
+ * @cil-generated
93
+ */
94
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimiterror:class" type="class" identity="RateLimitError" parent="~/.framework/functions/_shared/rate-limit.ts"]
95
+ // CIL[DOC-MACRO purpose="RateLimitError class"]
96
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the RateLimitError class."]
97
+ // CIL[DOC-CONTEXT module=".framework/functions/_shared/rate-limit.ts" layer="app-specific" related_files=""]
98
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
99
+ // CIL[DOC-MICRO logic_summary="Implements the RateLimitError class." notable_decisions="[]"]
100
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
101
+ // CIL[DOC-STABILITY stability="stable"]
102
+ export class RateLimitError extends Error {
103
+ statusCode = 429
104
+ action: string
105
+ limit: number
106
+ retryAfter: number | null
107
+
108
+ constructor(action: string, limit: number, retryAfter: number | null) {
109
+ super(`Rate limit exceeded for ${action}`)
110
+ this.name = 'RateLimitError'
111
+ this.action = action
112
+ this.limit = limit
113
+ this.retryAfter = retryAfter
114
+ }
115
+ }
116
+ // CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:ratelimiterror:class"]
117
+ // CIL[DOC-VECTOR type="context" content="purpose='RateLimitError is an error class that represents a situation where a rate limit has been exceeded for a specific action.'; No verified external callers" status="ready"]
118
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
119
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
120
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
121
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
122
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
123
+
124
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:resolveratelimitpolicies:function" type="function" identity="resolveRateLimitPolicies" parent="~/.framework/functions/_shared/rate-limit.ts"]
125
+ // CIL[DOC-MACRO purpose="Resolve the effective rate-limit policies for an action"]
126
+ // CIL[DOC-RESPONSIBILITY responsibility="Read accounts.data.rate_limits / rate_limit_profile for the request account, falling back to apps.config.rate_limits for the calling app"]
127
+ // CIL[DOC-CONTRACT inputs="ctx, action" outputs="RateLimitPolicy[] (empty = unlimited)" errors="returns [] on lookup failure" side_effects="accounts + apps table reads"]
128
+ // CIL[DOC-MICRO logic_summary="accounts.data.rate_limits[action] wins; accounts.data.rate_limit_profile selects config.rate_limits.profiles[profile][action] before the app's base config.rate_limits[action]" notable_decisions="Policy follows the account, not a named app — enforcement is identical no matter which URL the client hit; ctx.appId selects only the calling app's config"]
129
+ // CIL[DOC-STABILITY stability="stable"]
130
+ export async function resolveRateLimitPolicies(
131
+ ctx: CoreContext & { appId?: string | null },
132
+ action: string
133
+ ): Promise<RateLimitPolicy[]> {
134
+ const toPolicies = (raw: any): RateLimitPolicy[] =>
135
+ (Array.isArray(raw) ? raw : raw ? [raw] : []).filter(
136
+ (p: any) => typeof p?.limit === 'number' && typeof p?.window_seconds === 'number'
137
+ )
138
+
139
+ try {
140
+ // 1. Account-declared override wins.
141
+ let acctData: any = null
142
+ if (ctx.accountId) {
143
+ const { data: acct } = await adminDb
144
+ .from('accounts').select('data').eq('id', ctx.accountId).maybeSingle()
145
+ acctData = acct?.data || null
146
+ }
147
+ const acctPolicies = toPolicies(acctData?.rate_limits?.[action])
148
+ if (acctPolicies.length) return acctPolicies
149
+
150
+ // 2/3. Calling app's config only — no cross-app lookups.
151
+ let appCfg: any = null
152
+ if (ctx.appId) {
153
+ const { data: appRow } = await adminDb
154
+ .from('apps').select('config').eq('slug', ctx.appId).maybeSingle()
155
+ appCfg = appRow?.config || null
156
+ }
157
+
158
+ const profile = typeof acctData?.rate_limit_profile === 'string'
159
+ ? acctData.rate_limit_profile
160
+ : null
161
+ if (profile) {
162
+ const raw =
163
+ appCfg?.rate_limits?.profiles?.[profile]?.[action] ??
164
+ appCfg?.rate_limits?.[action]
165
+ return toPolicies(raw)
166
+ }
167
+ return toPolicies(appCfg?.rate_limits?.[action])
168
+ } catch {
169
+ return []
170
+ }
171
+ }
172
+ // CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:resolveratelimitpolicies:function"]
173
+
174
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/rate-limit.ts:checkratelimit:function" type="function" identity="checkRateLimit" parent="~/.framework/functions/_shared/rate-limit.ts"]
175
+ // CIL[DOC-MACRO purpose="Enforce rate-limit policies for an action"]
176
+ // CIL[DOC-RESPONSIBILITY responsibility="Atomically increment each policy's window counter and throw RateLimitError when any policy is exceeded"]
177
+ // CIL[DOC-CONTRACT inputs="ctx, action, opts.identifier (defaults to account or anonymous-ip)" outputs="void" errors="RateLimitError (429) over limit; Error (503) when a fail_closed policy cannot be checked" side_effects="rate_limits upsert via RPC"]
178
+ // CIL[DOC-MICRO logic_summary="For each resolved policy compute window_start (floored epoch or epoch-zero for lifetime), call rate_limit_hit, compare count to limit" notable_decisions="Counters always increment before the check so the first hit counts; retry_after is seconds until the window rolls"]
179
+ // CIL[DOC-STABILITY stability="stable"]
180
+ export async function checkRateLimit(
181
+ ctx: CoreContext,
182
+ action: string,
183
+ opts: { identifier?: string; policies?: RateLimitPolicy[] } = {}
184
+ ): Promise<void> {
185
+ const policies = opts.policies ?? await resolveRateLimitPolicies(ctx, action)
186
+ if (!policies.length) return
187
+
188
+ const identifier = opts.identifier || (ctx.accountId ? `acct:${ctx.accountId}` : 'anon')
189
+ const now = Date.now()
190
+
191
+ for (const policy of policies) {
192
+ const windowStart = policy.window_seconds > 0
193
+ ? new Date(Math.floor(now / (policy.window_seconds * 1000)) * policy.window_seconds * 1000)
194
+ : new Date(0)
195
+ const key = `${action}:${identifier}`
196
+
197
+ let count: number | null = null
198
+ try {
199
+ const { data, error } = await adminDb.rpc('rate_limit_hit', {
200
+ p_key: key,
201
+ p_window_start: windowStart.toISOString(),
202
+ })
203
+ if (error) throw error
204
+ count = typeof data === 'number' ? data : null
205
+ } catch (err: any) {
206
+ console.warn(`checkRateLimit(${action}) RPC failed:`, err?.message)
207
+ if (policy.fail_closed) {
208
+ const e: any = new Error(`Rate limit unavailable for ${action}`)
209
+ e.statusCode = 503
210
+ throw e
211
+ }
212
+ continue
213
+ }
214
+
215
+ if (count !== null && count > policy.limit) {
216
+ const retryAfter = policy.window_seconds > 0
217
+ ? Math.ceil((windowStart.getTime() + policy.window_seconds * 1000 - now) / 1000)
218
+ : null
219
+ // Security signal: the flagged-accounts report aggregates these.
220
+ void emitAudit({ ...ctx, db: adminDb } as any, 'security.rate_limit_exceeded', {
221
+ type: 'rate_limit', id: key, account_id: ctx.accountId
222
+ }, {
223
+ result: 'denied',
224
+ action_name: action,
225
+ identifier,
226
+ limit: policy.limit,
227
+ retry_after: retryAfter,
228
+ }).catch(() => {})
229
+ throw new RateLimitError(action, policy.limit, retryAfter)
230
+ }
231
+ }
232
+ }
233
+ // CIL[END stable_id="~/.framework/functions/_shared/rate-limit.ts:checkratelimit:function"]
@@ -1,32 +1,75 @@
1
- // CIL[BEGIN chunk_id="resolve_credentials_module_header_1784200002" type="module_header" identity="imports" parent="none"]
2
- // CIL[DOC-MACRO purpose="Resolve integration credentials from DB or environment variables"]
3
- // CIL[DOC-RESPONSIBILITY responsibility="Provide a single, auditable source for external API secrets"]
4
- // CIL[DOC-CONTEXT module="resolve_credentials" layer="infrastructure" related_files="[".framework/functions/integration-routes.ts",".framework/functions/integration-outbound.ts",".framework/functions/agent-runner.ts",".framework/functions/_shared/audit.ts"]"]
5
- // CIL[DOC-CONTRACT inputs="ctx, integration record, credential field name" outputs="{ value, source }" errors="missing_credential" side_effects="emits audit log"]
6
- // CIL[DOC-MICRO logic_summary="Reads integrations.credentials[field]. If source is env_var, reads process.env. Logs the source but never the secret value." notable_decisions="["Never logs the secret value.","Throws if neither DB nor env provides the credential.","Returns source so audit trail can show where the secret came from."]"]
7
- // CIL[DOC-CONFIDENCE pass="first" score="0.95" flags="none"]
8
- // CIL[DOC-STABILITY stability="experimental"]
9
- // CIL[DOC-AUDIENCE audience="developer"]
10
- // CIL[DOC-VECTOR type="context" content="Layer: infrastructure. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/integration-routes.ts, .framework/functions/integration-outbound.ts, .framework/functions/agent-runner.ts, .framework/functions/_shared/audit.ts."]
11
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
12
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
13
- // CIL[DOC-VECTOR type="constraint" content="Credential field must be defined in integrations.credentials."]
14
- // CIL[DOC-VECTOR type="implementation_pattern" content="Helper used by broker and core LLM callers."]
15
- // CIL[DOC-VECTOR type="user_journey" content="Runtime credential resolution for outbound calls."]
1
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
2
+ // CIL[DOC-MACRO purpose="Module header for resolve-credentials; imports shared dependencies."]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Declares module-level imports and identifies file scope."]
4
+ // CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Imports CoreContext from middleware and emitLog from audit." notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="developers"]
10
+
16
11
 
17
12
  import { CoreContext } from './middleware'
18
13
  import { emitLog } from './audit'
14
+ // CIL[DOC-VECTOR type="context" content="purpose='Module header for resolve-credentials; imports shared dependencies.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
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/functions/_shared/resolve-credentials.ts:module_header:module_header"]
21
+
19
22
 
23
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:CredentialEntry:interface" type="interface" identity="CredentialEntry" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
24
+ // CIL[DOC-MACRO purpose="Describes a single credential entry with source and raw value."]
25
+ // CIL[DOC-RESPONSIBILITY responsibility="Defines the shape of a credential configuration entry."]
26
+ // CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
27
+ // CIL[DOC-CONTRACT inputs="none" outputs="CredentialEntry type" errors="none" side_effects="none"]
28
+ // CIL[DOC-MICRO logic_summary="Interface with source and value fields; source is either 'value' or 'env_var'." notable_decisions="[]"]
29
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
30
+ // CIL[DOC-STABILITY stability="stable"]
20
31
  interface CredentialEntry {
21
32
  source: 'value' | 'env_var'
22
33
  value: string
23
34
  }
35
+ // CIL[DOC-VECTOR type="context" content="purpose='Describes a single credential entry with source and raw value.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
36
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
37
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
38
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
39
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
40
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
41
+ // CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:CredentialEntry:interface"]
42
+
24
43
 
44
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:ResolvedCredential:interface" type="interface" identity="ResolvedCredential" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
45
+ // CIL[DOC-MACRO purpose="Describes a resolved credential with final value and source."]
46
+ // CIL[DOC-RESPONSIBILITY responsibility="Defines the return type for resolved credentials."]
47
+ // CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
48
+ // CIL[DOC-CONTRACT inputs="none" outputs="ResolvedCredential type" errors="none" side_effects="none"]
49
+ // CIL[DOC-MICRO logic_summary="Exported interface with value and source fields representing a resolved credential." notable_decisions="[]"]
50
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
51
+ // CIL[DOC-STABILITY stability="stable"]
25
52
  export interface ResolvedCredential {
26
53
  value: string
27
54
  source: 'value' | 'env_var'
28
55
  }
56
+ // CIL[DOC-VECTOR type="context" content="purpose='Describes a resolved credential with final value and source.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
57
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
58
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
59
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
60
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
61
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
62
+ // CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:ResolvedCredential:interface"]
29
63
 
64
+
65
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredential:function" type="function" identity="resolveCredential" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
66
+ // CIL[DOC-MACRO purpose="Resolves a single credential from a literal value or an environment variable, validating and auditing the result."]
67
+ // CIL[DOC-RESPONSIBILITY responsibility="Read the credential entry for the given field, validate its configuration, resolve env_var values from process.env, audit each outcome, and return the resolved credential."]
68
+ // CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
69
+ // CIL[DOC-CONTRACT inputs="ctx: CoreContext, integration: any, fieldName: string" outputs="ResolvedCredential" errors="Missing credential configuration, missing environment variable, empty credential value" side_effects="Emits audit log events via emitLog"]
70
+ // CIL[DOC-MICRO logic_summary="Extracts the credential entry from integration.credentials; validates that source and value are present; for env_var reads process.env and throws if unset; for literal value throws if empty; audits resolution and returns the resolved credential." notable_decisions="[\"Environment variables are read from process.env\",\"Credential source is either 'value' or 'env_var'\"]"]
71
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
72
+ // CIL[DOC-STABILITY stability="stable"]
30
73
  export async function resolveCredential(
31
74
  ctx: CoreContext,
32
75
  integration: any,
@@ -56,7 +99,10 @@ export async function resolveCredential(
56
99
  throw new Error(`Environment variable ${entry.value} for ${fieldName} is not set`)
57
100
  }
58
101
 
59
- await emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
102
+ // Success audit is fire-and-forget — the resolved credential is already
103
+ // in hand and the outbound call shouldn't wait on a logs insert. Failure
104
+ // paths above stay awaited so the audit row is durable before the throw.
105
+ void emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
60
106
  field: fieldName,
61
107
  source: 'env_var',
62
108
  env_var: entry.value,
@@ -77,7 +123,7 @@ export async function resolveCredential(
77
123
  throw new Error(`Credential ${fieldName} on integration ${integration?.id} is empty`)
78
124
  }
79
125
 
80
- await emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
126
+ void emitLog(ctx, 'integration.credential_resolved', { type: 'integration', id: integration?.id }, undefined, {
81
127
  field: fieldName,
82
128
  source: 'value',
83
129
  integration_id: integration?.id,
@@ -86,7 +132,23 @@ export async function resolveCredential(
86
132
 
87
133
  return { value: entry.value, source: 'value' }
88
134
  }
135
+ // CIL[DOC-VECTOR type="context" content="purpose='Resolves a single credential from a literal value or an environment variable, validating and auditing the result.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
136
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
137
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
138
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
139
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
140
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
141
+ // CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredential:function"]
142
+
89
143
 
144
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredentials:function" type="function" identity="resolveCredentials" parent="~/.framework/functions/_shared/resolve-credentials.ts"]
145
+ // CIL[DOC-MACRO purpose="Resolves multiple credentials for a list of field names."]
146
+ // CIL[DOC-RESPONSIBILITY responsibility="Iterates the requested field names and resolves each one via resolveCredential, accumulating the results."]
147
+ // CIL[DOC-CONTEXT module="resolve-credentials" layer="shared" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/resolve-credentials.ts"]
148
+ // CIL[DOC-CONTRACT inputs="ctx: CoreContext, integration: any, fieldNames: string[]" outputs="Record<string, ResolvedCredential>" errors="Propagates any error thrown by resolveCredential" side_effects="none"]
149
+ // CIL[DOC-MICRO logic_summary="Loops over fieldNames, awaits resolveCredential for each, and stores results in a record keyed by field name." notable_decisions="[]"]
150
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
151
+ // CIL[DOC-STABILITY stability="stable"]
90
152
  export async function resolveCredentials(
91
153
  ctx: CoreContext,
92
154
  integration: any,
@@ -98,5 +160,10 @@ export async function resolveCredentials(
98
160
  }
99
161
  return result
100
162
  }
101
-
102
- // CIL[END chunk_id="resolve_credentials_module_header_1784200002"]
163
+ // CIL[DOC-VECTOR type="context" content="purpose='Resolves multiple credentials for a list of field names.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/audit.ts"]
164
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
165
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
166
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
167
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
168
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
169
+ // CIL[END stable_id="~/.framework/functions/_shared/resolve-credentials.ts:resolveCredentials:function"]